| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890 |
- // (C) Copyright David Abrahams 2002.
- // (C) Copyright Jeremy Siek 2002.
- // (C) Copyright Thomas Witt 2002.
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
- #define BOOST_ITERATOR_FACADE_23022003THW_HPP
- #include <cstddef>
- #include <memory>
- #include <utility>
- #include <type_traits>
- #include <boost/config.hpp>
- #include <boost/mp11/utility.hpp>
- #include <boost/iterator/interoperable.hpp>
- #include <boost/iterator/iterator_traits.hpp>
- #include <boost/iterator/iterator_categories.hpp>
- #include <boost/iterator/detail/facade_iterator_category.hpp>
- #include <boost/iterator/detail/type_traits/conjunction.hpp>
- #include <boost/iterator/detail/type_traits/negation.hpp>
- namespace boost {
- namespace iterators {
- // This forward declaration is required for the friend declaration
- // in iterator_core_access
- template<
- typename Derived,
- typename Value,
- typename CategoryOrTraversal,
- typename Reference = Value&,
- typename Difference = std::ptrdiff_t
- >
- class iterator_facade;
- namespace detail {
- // The type trait checks if the category or traversal is at least as advanced as the specified required traversal
- template< typename CategoryOrTraversal, typename Required >
- struct is_traversal_at_least :
- public std::is_convertible< typename iterator_category_to_traversal< CategoryOrTraversal >::type, Required >
- {};
- //
- // enable if for use in operator implementation.
- //
- template<
- typename Facade1,
- typename Facade2,
- typename Return
- >
- struct enable_if_interoperable :
- public std::enable_if<
- is_interoperable< Facade1, Facade2 >::value,
- Return
- >
- {};
- //
- // enable if for use in implementation of operators specific for random access traversal.
- //
- template<
- typename Facade1,
- typename Facade2,
- typename Return
- >
- struct enable_if_interoperable_and_random_access_traversal :
- public std::enable_if<
- detail::conjunction<
- is_interoperable< Facade1, Facade2 >,
- is_traversal_at_least< typename iterator_category< Facade1 >::type, random_access_traversal_tag >,
- is_traversal_at_least< typename iterator_category< Facade2 >::type, random_access_traversal_tag >
- >::value,
- Return
- >
- {};
- //
- // Generates associated types for an iterator_facade with the
- // given parameters.
- //
- template<
- typename ValueParam,
- typename CategoryOrTraversal,
- typename Reference,
- typename Difference
- >
- struct iterator_facade_types
- {
- using iterator_category = typename facade_iterator_category<
- CategoryOrTraversal, ValueParam, Reference
- >::type;
- using value_type = typename std::remove_const< ValueParam >::type;
- // Not the real associated pointer type
- using pointer = typename std::add_pointer<
- typename std::conditional<
- boost::iterators::detail::iterator_writability_disabled< ValueParam, Reference >::value,
- const value_type,
- value_type
- >::type
- >::type;
- };
- // iterators whose dereference operators reference the same value
- // for all iterators into the same sequence (like many input
- // iterators) need help with their postfix ++: the referenced
- // value must be read and stored away before the increment occurs
- // so that *a++ yields the originally referenced element and not
- // the next one.
- template< typename Iterator >
- class postfix_increment_proxy
- {
- using value_type = typename iterator_value< Iterator >::type;
- public:
- explicit postfix_increment_proxy(Iterator const& x) :
- stored_iterator(x),
- stored_value(*x)
- {}
- // Returning a mutable reference allows nonsense like
- // (*r++).mutate(), but it imposes fewer assumptions about the
- // behavior of the value_type. In particular, recall that
- // (*r).mutate() is legal if operator* returns by value.
- // Provides readability of *r++
- value_type& operator*() const
- {
- return stored_value;
- }
- // Provides X(r++)
- operator Iterator const&() const
- {
- return stored_iterator;
- }
- // Provides (r++)->foo()
- value_type* operator->() const
- {
- return std::addressof(stored_value);
- }
- private:
- Iterator stored_iterator;
- mutable value_type stored_value;
- };
- template< typename Iterator >
- class writable_postfix_increment_dereference_proxy;
- template< typename T >
- struct is_not_writable_postfix_increment_dereference_proxy :
- public std::true_type
- {};
- template< typename Iterator >
- struct is_not_writable_postfix_increment_dereference_proxy<
- writable_postfix_increment_dereference_proxy< Iterator >
- > :
- public std::false_type
- {};
- template< typename Iterator >
- class writable_postfix_increment_proxy;
- //
- // In general, we can't determine that such an iterator isn't
- // writable -- we also need to store a copy of the old iterator so
- // that it can be written into.
- template< typename Iterator >
- class writable_postfix_increment_dereference_proxy
- {
- friend class writable_postfix_increment_proxy< Iterator >;
- using value_type = typename iterator_value< Iterator >::type;
- public:
- explicit writable_postfix_increment_dereference_proxy(Iterator const& x) :
- stored_iterator(x),
- stored_value(*x)
- {}
- // Provides readability of *r++
- operator value_type&() const
- {
- return this->stored_value;
- }
- template< typename OtherIterator >
- writable_postfix_increment_dereference_proxy const&
- operator=(writable_postfix_increment_dereference_proxy< OtherIterator > const& x) const
- {
- typedef typename iterator_value< OtherIterator >::type other_value_type;
- *this->stored_iterator = static_cast< other_value_type& >(x);
- return *this;
- }
- // Provides writability of *r++
- template< typename T >
- typename std::enable_if<
- is_not_writable_postfix_increment_dereference_proxy< T >::value,
- writable_postfix_increment_dereference_proxy const&
- >::type operator=(T&& x) const
- {
- *this->stored_iterator = static_cast< T&& >(x);
- return *this;
- }
- private:
- Iterator stored_iterator;
- mutable value_type stored_value;
- };
- template< typename Iterator >
- class writable_postfix_increment_proxy
- {
- using value_type = typename iterator_value< Iterator >::type;
- public:
- explicit writable_postfix_increment_proxy(Iterator const& x) :
- dereference_proxy(x)
- {}
- writable_postfix_increment_dereference_proxy< Iterator > const&
- operator*() const
- {
- return dereference_proxy;
- }
- // Provides X(r++)
- operator Iterator const&() const
- {
- return dereference_proxy.stored_iterator;
- }
- // Provides (r++)->foo()
- value_type* operator->() const
- {
- return std::addressof(dereference_proxy.stored_value);
- }
- private:
- writable_postfix_increment_dereference_proxy< Iterator > dereference_proxy;
- };
- template< typename Reference, typename Value >
- struct is_non_proxy_reference :
- public std::is_convertible<
- typename std::remove_reference< Reference >::type const volatile*,
- Value const volatile*
- >
- {};
- // A metafunction to choose the result type of postfix ++
- //
- // Because the C++98 input iterator requirements say that *r++ has
- // type T (value_type), implementations of some standard
- // algorithms like lexicographical_compare may use constructions
- // like:
- //
- // *r++ < *s++
- //
- // If *r++ returns a proxy (as required if r is writable but not
- // multipass), this sort of expression will fail unless the proxy
- // supports the operator<. Since there are any number of such
- // operations, we're not going to try to support them. Therefore,
- // even if r++ returns a proxy, *r++ will only return a proxy if
- // *r also returns a proxy.
- template< typename Iterator, typename Value, typename Reference, typename CategoryOrTraversal >
- struct postfix_increment_result
- {
- using type = mp11::mp_eval_if_not<
- detail::conjunction<
- // A proxy is only needed for readable iterators
- std::is_convertible<
- Reference,
- // Use add_lvalue_reference to form `reference to Value` due to
- // some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject
- // 'reference-to-reference' in the template which described in CWG
- // DR106.
- // http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106
- typename std::add_lvalue_reference< Value const >::type
- >,
- // No multipass iterator can have values that disappear
- // before positions can be re-visited
- detail::negation<
- detail::is_traversal_at_least< CategoryOrTraversal, forward_traversal_tag >
- >
- >,
- Iterator,
- mp11::mp_if,
- is_non_proxy_reference< Reference, Value >,
- postfix_increment_proxy< Iterator >,
- writable_postfix_increment_proxy< Iterator >
- >;
- };
- // operator->() needs special support for input iterators to strictly meet the
- // standard's requirements. If *i is not a reference type, we must still
- // produce an lvalue to which a pointer can be formed. We do that by
- // returning a proxy object containing an instance of the reference object.
- template< typename Reference, typename Pointer >
- struct operator_arrow_dispatch // proxy references
- {
- struct proxy
- {
- explicit proxy(Reference const& x) : m_ref(x) {}
- Reference* operator->() { return std::addressof(m_ref); }
- // This function is needed for MWCW and BCC, which won't call
- // operator-> again automatically per 13.3.1.2 para 8
- operator Reference*() { return std::addressof(m_ref); }
- Reference m_ref;
- };
- using result_type = proxy;
- static result_type apply(Reference const& x)
- {
- return result_type(x);
- }
- };
- template< typename T, typename Pointer >
- struct operator_arrow_dispatch< T&, Pointer > // "real" references
- {
- using result_type = Pointer;
- static result_type apply(T& x)
- {
- return std::addressof(x);
- }
- };
- // A proxy return type for operator[], needed to deal with
- // iterators that may invalidate referents upon destruction.
- // Consider the temporary iterator in *(a + n)
- template< typename Iterator >
- class operator_brackets_proxy
- {
- // Iterator is actually an iterator_facade, so we do not have to
- // go through iterator_traits to access the traits.
- using reference = typename Iterator::reference;
- public:
- explicit operator_brackets_proxy(Iterator const& iter) noexcept(std::is_nothrow_copy_constructible< Iterator >::value) :
- m_iter(iter)
- {}
- operator reference() const noexcept(noexcept(*std::declval< Iterator const& >()))
- {
- return *m_iter;
- }
- template< typename T >
- typename std::enable_if<
- detail::conjunction<
- detail::negation<
- std::is_same<
- operator_brackets_proxy< Iterator >,
- typename std::remove_cv< typename std::remove_reference< T >::type >::type
- >
- >,
- std::is_assignable< reference, T&& >
- >::value,
- operator_brackets_proxy&
- >::type operator= (T&& val) noexcept(noexcept(*std::declval< Iterator& >() = std::declval< T&& >()))
- {
- *m_iter = static_cast< T&& >(val);
- return *this;
- }
- // Provides it[n]->foo(). Leverages chaining of operator->.
- reference operator->() const noexcept(noexcept(*std::declval< Iterator const& >()))
- {
- return *m_iter;
- }
- // Provides (*it[n]).foo()
- template< typename Ref = reference, typename Result = decltype(*std::declval< Ref >()) >
- Result operator*() const noexcept(noexcept(**std::declval< Iterator const& >()))
- {
- return **m_iter;
- }
- private:
- Iterator m_iter;
- };
- // A binary metafunction class that always returns bool.
- template< typename Iterator1, typename Iterator2 >
- using always_bool_t = bool;
- template< typename Iterator1, typename Iterator2 >
- using choose_difference_type_t = typename std::conditional<
- std::is_convertible< Iterator2, Iterator1 >::value,
- iterator_difference< Iterator1 >,
- iterator_difference< Iterator2 >
- >::type::type;
- template<
- typename Derived,
- typename Value,
- typename CategoryOrTraversal,
- typename Reference,
- typename Difference,
- bool IsBidirectionalTraversal,
- bool IsRandomAccessTraversal
- >
- class iterator_facade_base;
- } // namespace detail
- // Macros which describe the declarations of binary operators
- #define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler) \
- template< \
- typename Derived1, typename V1, typename TC1, typename Reference1, typename Difference1, \
- typename Derived2, typename V2, typename TC2, typename Reference2, typename Difference2 \
- > \
- prefix typename enabler< \
- Derived1, Derived2, \
- result_type< Derived1, Derived2 > \
- >::type \
- operator op( \
- iterator_facade< Derived1, V1, TC1, Reference1, Difference1 > const& lhs, \
- iterator_facade< Derived2, V2, TC2, Reference2, Difference2 > const& rhs)
- #define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
- BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable)
- #define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(prefix, op, result_type) \
- BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable_and_random_access_traversal)
- #define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
- template< typename Derived, typename V, typename TC, typename R, typename D > \
- prefix typename std::enable_if< \
- boost::iterators::detail::is_traversal_at_least< \
- TC, \
- boost::iterators::random_access_traversal_tag \
- >::value, \
- Derived \
- >::type operator+ args
- //
- // Helper class for granting access to the iterator core interface.
- //
- // The simple core interface is used by iterator_facade. The core
- // interface of a user/library defined iterator type should not be made public
- // so that it does not clutter the public interface. Instead iterator_core_access
- // should be made friend so that iterator_facade can access the core
- // interface through iterator_core_access.
- //
- class iterator_core_access
- {
- template< typename I, typename V, typename TC, typename R, typename D >
- friend class iterator_facade;
- template< typename I, typename V, typename TC, typename R, typename D, bool IsBidirectionalTraversal, bool IsRandomAccessTraversal >
- friend class detail::iterator_facade_base;
- #define BOOST_ITERATOR_FACADE_RELATION(op) \
- BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend, op, boost::iterators::detail::always_bool_t);
- BOOST_ITERATOR_FACADE_RELATION(==)
- BOOST_ITERATOR_FACADE_RELATION(!=)
- #undef BOOST_ITERATOR_FACADE_RELATION
- #define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op) \
- BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend, op, boost::iterators::detail::always_bool_t);
- BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<)
- BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>)
- BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=)
- BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=)
- #undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
- BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend, -, boost::iterators::detail::choose_difference_type_t);
- BOOST_ITERATOR_FACADE_PLUS_HEAD(
- friend inline,
- (iterator_facade< Derived, V, TC, R, D > const&, typename Derived::difference_type)
- );
- BOOST_ITERATOR_FACADE_PLUS_HEAD(
- friend inline,
- (typename Derived::difference_type, iterator_facade< Derived, V, TC, R, D > const&)
- );
- template< typename Facade >
- static typename Facade::reference dereference(Facade const& f)
- {
- return f.dereference();
- }
- template< typename Facade >
- static void increment(Facade& f)
- {
- f.increment();
- }
- template< typename Facade >
- static void decrement(Facade& f)
- {
- f.decrement();
- }
- template< typename Facade1, typename Facade2 >
- static bool equal(Facade1 const& f1, Facade2 const& f2, std::true_type)
- {
- return f1.equal(f2);
- }
- template< typename Facade1, typename Facade2 >
- static bool equal(Facade1 const& f1, Facade2 const& f2, std::false_type)
- {
- return f2.equal(f1);
- }
- template< typename Facade >
- static void advance(Facade& f, typename Facade::difference_type n)
- {
- f.advance(n);
- }
- template< typename Facade1, typename Facade2 >
- static typename Facade1::difference_type distance_from(Facade1 const& f1, Facade2 const& f2, std::true_type)
- {
- return -f1.distance_to(f2);
- }
- template< typename Facade1, typename Facade2 >
- static typename Facade2::difference_type distance_from(Facade1 const& f1, Facade2 const& f2, std::false_type)
- {
- return f2.distance_to(f1);
- }
- //
- // Curiously Recurring Template interface.
- //
- template< typename I, typename V, typename TC, typename R, typename D >
- static I& derived(iterator_facade< I, V, TC, R, D >& facade)
- {
- return *static_cast< I* >(&facade);
- }
- template< typename I, typename V, typename TC, typename R, typename D >
- static I const& derived(iterator_facade< I, V, TC, R, D > const& facade)
- {
- return *static_cast< I const* >(&facade);
- }
- // objects of this class are useless
- iterator_core_access() = delete;
- };
- namespace detail {
- // Implementation for forward traversal iterators
- template<
- typename Derived,
- typename Value,
- typename CategoryOrTraversal,
- typename Reference,
- typename Difference
- >
- class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
- {
- private:
- using associated_types = boost::iterators::detail::iterator_facade_types<
- Value, CategoryOrTraversal, Reference, Difference
- >;
- using operator_arrow_dispatch_ = boost::iterators::detail::operator_arrow_dispatch<
- Reference,
- typename associated_types::pointer
- >;
- public:
- using value_type = typename associated_types::value_type;
- using reference = Reference;
- using difference_type = Difference;
- using pointer = typename operator_arrow_dispatch_::result_type;
- using iterator_category = typename associated_types::iterator_category;
- public:
- reference operator*() const
- {
- return iterator_core_access::dereference(this->derived());
- }
- pointer operator->() const
- {
- return operator_arrow_dispatch_::apply(*this->derived());
- }
- Derived& operator++()
- {
- iterator_core_access::increment(this->derived());
- return this->derived();
- }
- protected:
- //
- // Curiously Recurring Template interface.
- //
- Derived& derived()
- {
- return *static_cast< Derived* >(this);
- }
- Derived const& derived() const
- {
- return *static_cast< Derived const* >(this);
- }
- };
- // Implementation for bidirectional traversal iterators
- template<
- typename Derived,
- typename Value,
- typename CategoryOrTraversal,
- typename Reference,
- typename Difference
- >
- class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > :
- public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
- {
- public:
- Derived& operator--()
- {
- iterator_core_access::decrement(this->derived());
- return this->derived();
- }
- Derived operator--(int)
- {
- Derived tmp(this->derived());
- --*this;
- return tmp;
- }
- };
- // Implementation for random access traversal iterators
- template<
- typename Derived,
- typename Value,
- typename CategoryOrTraversal,
- typename Reference,
- typename Difference
- >
- class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, true > :
- public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >
- {
- private:
- using base_type = iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >;
- public:
- using reference = typename base_type::reference;
- using difference_type = typename base_type::difference_type;
- public:
- operator_brackets_proxy< Derived > operator[](difference_type n) const
- {
- return operator_brackets_proxy< Derived >(this->derived() + n);
- }
- Derived& operator+=(difference_type n)
- {
- iterator_core_access::advance(this->derived(), n);
- return this->derived();
- }
- Derived& operator-=(difference_type n)
- {
- iterator_core_access::advance(this->derived(), -n);
- return this->derived();
- }
- Derived operator-(difference_type x) const
- {
- Derived result(this->derived());
- return result -= x;
- }
- };
- } // namespace detail
- //
- // iterator_facade - use as a public base class for defining new
- // standard-conforming iterators.
- //
- template<
- typename Derived, // The derived iterator type being constructed
- typename Value,
- typename CategoryOrTraversal,
- typename Reference,
- typename Difference
- >
- class iterator_facade :
- public detail::iterator_facade_base<
- Derived,
- Value,
- CategoryOrTraversal,
- Reference,
- Difference,
- detail::is_traversal_at_least< CategoryOrTraversal, bidirectional_traversal_tag >::value,
- detail::is_traversal_at_least< CategoryOrTraversal, random_access_traversal_tag >::value
- >
- {
- protected:
- // For use by derived classes
- using iterator_facade_ = iterator_facade< Derived, Value, CategoryOrTraversal, Reference, Difference >;
- };
- template< typename I, typename V, typename TC, typename R, typename D >
- inline typename boost::iterators::detail::postfix_increment_result< I, V, R, TC >::type
- operator++(iterator_facade< I, V, TC, R, D >& i, int)
- {
- typename boost::iterators::detail::postfix_increment_result< I, V, R, TC >::type
- tmp(*static_cast< I* >(&i));
- ++i;
- return tmp;
- }
- //
- // Comparison operator implementation. The library supplied operators
- // enables the user to provide fully interoperable constant/mutable
- // iterator types. I.e. the library provides all operators
- // for all mutable/constant iterator combinations.
- //
- // Note though that this kind of interoperability for constant/mutable
- // iterators is not required by the standard for container iterators.
- // All the standard asks for is a conversion mutable -> constant.
- // Most standard library implementations nowadays provide fully interoperable
- // iterator implementations, but there are still heavily used implementations
- // that do not provide them. (Actually it's even worse, they do not provide
- // them for only a few iterators.)
- //
- // ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should
- // enable the user to turn off mixed type operators
- //
- // The library takes care to provide only the right operator overloads.
- // I.e.
- //
- // bool operator==(Iterator, Iterator);
- // bool operator==(ConstIterator, Iterator);
- // bool operator==(Iterator, ConstIterator);
- // bool operator==(ConstIterator, ConstIterator);
- //
- // ...
- //
- // In order to do so it uses c++ idioms that are not yet widely supported
- // by current compiler releases. The library is designed to degrade gracefully
- // in the face of compiler deficiencies. In general compiler
- // deficiencies result in less strict error checking and more obscure
- // error messages, functionality is not affected.
- //
- // For full operation compiler support for "Substitution Failure Is Not An Error"
- // (aka. enable_if) and boost::is_convertible is required.
- //
- // The following problems occur if support is lacking.
- //
- // Pseudo code
- //
- // ---------------
- // AdaptorA<Iterator1> a1;
- // AdaptorA<Iterator2> a2;
- //
- // // This will result in a no such overload error in full operation
- // // If enable_if or is_convertible is not supported
- // // The instantiation will fail with an error hopefully indicating that
- // // there is no operator== for Iterator1, Iterator2
- // // The same will happen if no enable_if is used to remove
- // // false overloads from the templated conversion constructor
- // // of AdaptorA.
- //
- // a1 == a2;
- // ----------------
- //
- // AdaptorA<Iterator> a;
- // AdaptorB<Iterator> b;
- //
- // // This will result in a no such overload error in full operation
- // // If enable_if is not supported the static assert used
- // // in the operator implementation will fail.
- // // This will accidently work if is_convertible is not supported.
- //
- // a == b;
- // ----------------
- //
- #define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op) \
- BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type) \
- { \
- return_prefix iterator_core_access::base_op( \
- *static_cast< Derived1 const* >(&lhs), \
- *static_cast< Derived2 const* >(&rhs), \
- std::integral_constant< bool, std::is_convertible< Derived2, Derived1 >::value >() \
- ); \
- }
- #define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
- BOOST_ITERATOR_FACADE_INTEROP( \
- op, \
- boost::iterators::detail::always_bool_t, \
- return_prefix, \
- base_op \
- )
- BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
- BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
- #undef BOOST_ITERATOR_FACADE_RELATION
- #define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(op, result_type, return_prefix, base_op) \
- BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(inline, op, result_type) \
- { \
- return_prefix iterator_core_access::base_op( \
- *static_cast< Derived1 const* >(&lhs), \
- *static_cast< Derived2 const* >(&rhs), \
- std::integral_constant< bool, std::is_convertible< Derived2, Derived1 >::value >() \
- ); \
- }
- #define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op, return_prefix, base_op) \
- BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS( \
- op, \
- boost::iterators::detail::always_bool_t, \
- return_prefix, \
- base_op \
- )
- BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<, return 0 >, distance_from)
- BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>, return 0 <, distance_from)
- BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=, return 0 >=, distance_from)
- BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=, return 0 <=, distance_from)
- #undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
- // operator- requires an additional part in the static assertion
- BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(
- -,
- boost::iterators::detail::choose_difference_type_t,
- return,
- distance_from
- )
- #undef BOOST_ITERATOR_FACADE_INTEROP
- #undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS
- #define BOOST_ITERATOR_FACADE_PLUS(args) \
- BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args) \
- { \
- Derived tmp(static_cast< Derived const& >(i)); \
- return tmp += n; \
- }
- BOOST_ITERATOR_FACADE_PLUS((iterator_facade< Derived, V, TC, R, D > const& i, typename Derived::difference_type n))
- BOOST_ITERATOR_FACADE_PLUS((typename Derived::difference_type n, iterator_facade< Derived, V, TC, R, D > const& i))
- #undef BOOST_ITERATOR_FACADE_PLUS
- #undef BOOST_ITERATOR_FACADE_PLUS_HEAD
- #undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
- #undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD
- #undef BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL
- } // namespace iterators
- using iterators::iterator_core_access;
- using iterators::iterator_facade;
- } // namespace boost
- #endif // BOOST_ITERATOR_FACADE_23022003THW_HPP
|