/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2010-2018 Danny Robson <danny@nerdcruft.net> */ #pragma once namespace cruft::iterator { /////////////////////////////////////////////////////////////////////////// /// an iterator that can be infinitely incremented but never assigned. /// /// useful for iterator ranges where the begin iterator is an output /// iterator and hence never reaches an end point (and where we don't want /// to engineer the client code to account for this). template < typename ValueT, typename CategoryT, typename DistanceT, typename PointerT, typename ReferenceT > struct unequal_iterator { using value_type = ValueT; using iterator_category = CategoryT; using difference_type = DistanceT; using pointer = PointerT; using reference = ReferenceT; unequal_iterator& operator++ ( ) { return *this; } unequal_iterator operator++ (int) { return *this; } }; //------------------------------------------------------------------------- template <typename ContainerT> auto make_unequal_iterator (const ContainerT&) { using t = typename std::iterator_traits<typename ContainerT::iterator>; return unequal_iterator< typename t::value_type, typename t::iterator_category, typename t::difference_type, typename t::pointer, typename t::reference > {}; }; //------------------------------------------------------------------------- template < typename OtherT, typename ValueT, typename CategoryT, typename DistanceT, typename PointerT, typename ReferenceT> constexpr bool operator== ( const unequal_iterator<ValueT,CategoryT,DistanceT,PointerT,ReferenceT>&, const OtherT& ) { return false; } //------------------------------------------------------------------------- template < typename OtherT, typename ValueT, typename CategoryT, typename DistanceT, typename PointerT, typename ReferenceT> constexpr bool operator== ( const OtherT&, const unequal_iterator<ValueT,CategoryT,DistanceT,PointerT,ReferenceT>& ) { return false; } }