Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:53:55

0001 // (C) Copyright David Abrahams 2002.
0002 // (C) Copyright Jeremy Siek    2002.
0003 // (C) Copyright Thomas Witt    2002.
0004 // Distributed under the Boost Software License, Version 1.0. (See
0005 // accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt)
0007 #ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
0008 #define BOOST_ITERATOR_FACADE_23022003THW_HPP
0009 
0010 #include <cstddef>
0011 #include <memory>
0012 #include <type_traits>
0013 
0014 #include <boost/config.hpp>
0015 #include <boost/mp11/utility.hpp>
0016 
0017 #include <boost/iterator/interoperable.hpp>
0018 #include <boost/iterator/iterator_traits.hpp>
0019 #include <boost/iterator/iterator_categories.hpp>
0020 #include <boost/iterator/detail/facade_iterator_category.hpp>
0021 #include <boost/iterator/detail/type_traits/conjunction.hpp>
0022 #include <boost/iterator/detail/type_traits/negation.hpp>
0023 
0024 namespace boost {
0025 namespace iterators {
0026 
0027 // This forward declaration is required for the friend declaration
0028 // in iterator_core_access
0029 template<
0030     typename Derived,
0031     typename Value,
0032     typename CategoryOrTraversal,
0033     typename Reference   = Value&,
0034     typename Difference  = std::ptrdiff_t
0035 >
0036 class iterator_facade;
0037 
0038 namespace detail {
0039 
0040 // The type trait checks if the category or traversal is at least as advanced as the specified required traversal
0041 template< typename CategoryOrTraversal, typename Required >
0042 struct is_traversal_at_least :
0043     public std::is_convertible< typename iterator_category_to_traversal< CategoryOrTraversal >::type, Required >
0044 {};
0045 
0046 //
0047 // enable if for use in operator implementation.
0048 //
0049 template<
0050     typename Facade1,
0051     typename Facade2,
0052     typename Return
0053 >
0054 struct enable_if_interoperable :
0055     public std::enable_if<
0056         is_interoperable< Facade1, Facade2 >::value,
0057         Return
0058     >
0059 {};
0060 
0061 //
0062 // enable if for use in implementation of operators specific for random access traversal.
0063 //
0064 template<
0065     typename Facade1,
0066     typename Facade2,
0067     typename Return
0068 >
0069 struct enable_if_interoperable_and_random_access_traversal :
0070     public std::enable_if<
0071         detail::conjunction<
0072             is_interoperable< Facade1, Facade2 >,
0073             is_traversal_at_least< typename iterator_category< Facade1 >::type, random_access_traversal_tag >,
0074             is_traversal_at_least< typename iterator_category< Facade2 >::type, random_access_traversal_tag >
0075         >::value,
0076         Return
0077     >
0078 {};
0079 
0080 //
0081 // Generates associated types for an iterator_facade with the
0082 // given parameters.
0083 //
0084 template<
0085     typename ValueParam,
0086     typename CategoryOrTraversal,
0087     typename Reference,
0088     typename Difference
0089 >
0090 struct iterator_facade_types
0091 {
0092     using iterator_category = typename facade_iterator_category<
0093         CategoryOrTraversal, ValueParam, Reference
0094     >::type;
0095 
0096     using value_type = typename std::remove_const< ValueParam >::type;
0097 
0098     // Not the real associated pointer type
0099     using pointer = typename std::add_pointer<
0100         typename std::conditional<
0101             boost::iterators::detail::iterator_writability_disabled< ValueParam, Reference >::value,
0102             const value_type,
0103             value_type
0104         >::type
0105     >::type;
0106 };
0107 
0108 // iterators whose dereference operators reference the same value
0109 // for all iterators into the same sequence (like many input
0110 // iterators) need help with their postfix ++: the referenced
0111 // value must be read and stored away before the increment occurs
0112 // so that *a++ yields the originally referenced element and not
0113 // the next one.
0114 template< typename Iterator >
0115 class postfix_increment_proxy
0116 {
0117     using value_type = typename iterator_value< Iterator >::type;
0118 
0119 public:
0120     explicit postfix_increment_proxy(Iterator const& x) :
0121         stored_iterator(x),
0122         stored_value(*x)
0123     {}
0124 
0125     // Returning a mutable reference allows nonsense like
0126     // (*r++).mutate(), but it imposes fewer assumptions about the
0127     // behavior of the value_type.  In particular, recall that
0128     // (*r).mutate() is legal if operator* returns by value.
0129     // Provides readability of *r++
0130     value_type& operator*() const
0131     {
0132         return stored_value;
0133     }
0134 
0135     // Provides X(r++)
0136     operator Iterator const&() const
0137     {
0138         return stored_iterator;
0139     }
0140 
0141     // Provides (r++)->foo()
0142     value_type* operator->() const
0143     {
0144         return std::addressof(stored_value);
0145     }
0146 
0147 private:
0148     Iterator stored_iterator;
0149     mutable value_type stored_value;
0150 };
0151 
0152 
0153 template< typename Iterator >
0154 class writable_postfix_increment_dereference_proxy;
0155 
0156 template< typename T >
0157 struct is_not_writable_postfix_increment_dereference_proxy :
0158     public std::true_type
0159 {};
0160 
0161 template< typename Iterator >
0162 struct is_not_writable_postfix_increment_dereference_proxy<
0163     writable_postfix_increment_dereference_proxy< Iterator >
0164 > :
0165     public std::false_type
0166 {};
0167 
0168 template< typename Iterator >
0169 class writable_postfix_increment_proxy;
0170 
0171 //
0172 // In general, we can't determine that such an iterator isn't
0173 // writable -- we also need to store a copy of the old iterator so
0174 // that it can be written into.
0175 template< typename Iterator >
0176 class writable_postfix_increment_dereference_proxy
0177 {
0178     friend class writable_postfix_increment_proxy< Iterator >;
0179 
0180     using value_type = typename iterator_value< Iterator >::type;
0181 
0182 public:
0183     explicit writable_postfix_increment_dereference_proxy(Iterator const& x) :
0184         stored_iterator(x),
0185         stored_value(*x)
0186     {}
0187 
0188     // Provides readability of *r++
0189     operator value_type&() const
0190     {
0191         return this->stored_value;
0192     }
0193 
0194     template< typename OtherIterator >
0195     writable_postfix_increment_dereference_proxy const&
0196     operator=(writable_postfix_increment_dereference_proxy< OtherIterator > const& x) const
0197     {
0198         typedef typename iterator_value< OtherIterator >::type other_value_type;
0199         *this->stored_iterator = static_cast< other_value_type& >(x);
0200         return *this;
0201     }
0202 
0203     // Provides writability of *r++
0204     template< typename T >
0205     typename std::enable_if<
0206         is_not_writable_postfix_increment_dereference_proxy< T >::value,
0207         writable_postfix_increment_dereference_proxy const&
0208     >::type operator=(T&& x) const
0209     {
0210         *this->stored_iterator = static_cast< T&& >(x);
0211         return *this;
0212     }
0213 
0214 private:
0215     Iterator stored_iterator;
0216     mutable value_type stored_value;
0217 };
0218 
0219 template< typename Iterator >
0220 class writable_postfix_increment_proxy
0221 {
0222     using value_type = typename iterator_value< Iterator >::type;
0223 
0224 public:
0225     explicit writable_postfix_increment_proxy(Iterator const& x) :
0226         dereference_proxy(x)
0227     {}
0228 
0229     writable_postfix_increment_dereference_proxy< Iterator > const&
0230     operator*() const
0231     {
0232         return dereference_proxy;
0233     }
0234 
0235     // Provides X(r++)
0236     operator Iterator const&() const
0237     {
0238         return dereference_proxy.stored_iterator;
0239     }
0240 
0241     // Provides (r++)->foo()
0242     value_type* operator->() const
0243     {
0244         return std::addressof(dereference_proxy.stored_value);
0245     }
0246 
0247 private:
0248     writable_postfix_increment_dereference_proxy< Iterator > dereference_proxy;
0249 };
0250 
0251 template< typename Reference, typename Value >
0252 struct is_non_proxy_reference :
0253     public std::is_convertible<
0254         typename std::remove_reference< Reference >::type const volatile*,
0255         Value const volatile*
0256     >
0257 {};
0258 
0259 // A metafunction to choose the result type of postfix ++
0260 //
0261 // Because the C++98 input iterator requirements say that *r++ has
0262 // type T (value_type), implementations of some standard
0263 // algorithms like lexicographical_compare may use constructions
0264 // like:
0265 //
0266 //          *r++ < *s++
0267 //
0268 // If *r++ returns a proxy (as required if r is writable but not
0269 // multipass), this sort of expression will fail unless the proxy
0270 // supports the operator<.  Since there are any number of such
0271 // operations, we're not going to try to support them.  Therefore,
0272 // even if r++ returns a proxy, *r++ will only return a proxy if
0273 // *r also returns a proxy.
0274 template< typename Iterator, typename Value, typename Reference, typename CategoryOrTraversal >
0275 struct postfix_increment_result
0276 {
0277     using type = mp11::mp_eval_if_not<
0278         detail::conjunction<
0279             // A proxy is only needed for readable iterators
0280             std::is_convertible<
0281                 Reference,
0282                 // Use add_lvalue_reference to form `reference to Value` due to
0283                 // some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject
0284                 // 'reference-to-reference' in the template which described in CWG
0285                 // DR106.
0286                 // http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106
0287                 typename std::add_lvalue_reference< Value const >::type
0288             >,
0289 
0290             // No multipass iterator can have values that disappear
0291             // before positions can be re-visited
0292             detail::negation<
0293                 detail::is_traversal_at_least< CategoryOrTraversal, forward_traversal_tag >
0294             >
0295         >,
0296         Iterator,
0297         mp11::mp_if,
0298             is_non_proxy_reference< Reference, Value >,
0299             postfix_increment_proxy< Iterator >,
0300             writable_postfix_increment_proxy< Iterator >
0301     >;
0302 };
0303 
0304 // operator->() needs special support for input iterators to strictly meet the
0305 // standard's requirements. If *i is not a reference type, we must still
0306 // produce an lvalue to which a pointer can be formed.  We do that by
0307 // returning a proxy object containing an instance of the reference object.
0308 template< typename Reference, typename Pointer >
0309 struct operator_arrow_dispatch // proxy references
0310 {
0311     struct proxy
0312     {
0313         explicit proxy(Reference const& x) : m_ref(x) {}
0314         Reference* operator->() { return std::addressof(m_ref); }
0315         // This function is needed for MWCW and BCC, which won't call
0316         // operator-> again automatically per 13.3.1.2 para 8
0317         operator Reference*() { return std::addressof(m_ref); }
0318         Reference m_ref;
0319     };
0320 
0321     using result_type = proxy;
0322 
0323     static result_type apply(Reference const& x)
0324     {
0325         return result_type(x);
0326     }
0327 };
0328 
0329 template< typename T, typename Pointer >
0330 struct operator_arrow_dispatch< T&, Pointer > // "real" references
0331 {
0332     using result_type = Pointer;
0333 
0334     static result_type apply(T& x)
0335     {
0336         return std::addressof(x);
0337     }
0338 };
0339 
0340 // A proxy return type for operator[], needed to deal with
0341 // iterators that may invalidate referents upon destruction.
0342 // Consider the temporary iterator in *(a + n)
0343 template< typename Iterator >
0344 class operator_brackets_proxy
0345 {
0346     // Iterator is actually an iterator_facade, so we do not have to
0347     // go through iterator_traits to access the traits.
0348     using reference = typename Iterator::reference;
0349     using value_type = typename Iterator::value_type;
0350 
0351 public:
0352     operator_brackets_proxy(Iterator const& iter) :
0353         m_iter(iter)
0354     {}
0355 
0356     operator reference() const
0357     {
0358         return *m_iter;
0359     }
0360 
0361     operator_brackets_proxy& operator=(value_type const& val)
0362     {
0363         *m_iter = val;
0364         return *this;
0365     }
0366 
0367 private:
0368     Iterator m_iter;
0369 };
0370 
0371 // A metafunction that determines whether operator[] must return a
0372 // proxy, or whether it can simply return a copy of the value_type.
0373 template< typename ValueType, typename Reference >
0374 struct use_operator_brackets_proxy :
0375     public detail::negation<
0376         detail::conjunction<
0377             std::is_copy_constructible< ValueType >,
0378             std::is_trivial< ValueType >,
0379             iterator_writability_disabled< ValueType, Reference >
0380         >
0381     >
0382 {};
0383 
0384 template< typename Iterator, typename Value, typename Reference >
0385 struct operator_brackets_result
0386 {
0387     using type = typename std::conditional<
0388         use_operator_brackets_proxy<Value, Reference>::value,
0389         operator_brackets_proxy<Iterator>,
0390         Value
0391     >::type;
0392 };
0393 
0394 template< typename Iterator >
0395 inline operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, std::true_type)
0396 {
0397     return operator_brackets_proxy< Iterator >(iter);
0398 }
0399 
0400 template< typename Iterator >
0401 inline typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, std::false_type)
0402 {
0403     return *iter;
0404 }
0405 
0406 // A binary metafunction class that always returns bool.
0407 template< typename Iterator1, typename Iterator2 >
0408 using always_bool_t = bool;
0409 
0410 template< typename Iterator1, typename Iterator2 >
0411 using choose_difference_type_t = typename std::conditional<
0412     std::is_convertible< Iterator2, Iterator1 >::value,
0413     iterator_difference< Iterator1 >,
0414     iterator_difference< Iterator2 >
0415 >::type::type;
0416 
0417 template<
0418     typename Derived,
0419     typename Value,
0420     typename CategoryOrTraversal,
0421     typename Reference,
0422     typename Difference,
0423     bool IsBidirectionalTraversal,
0424     bool IsRandomAccessTraversal
0425 >
0426 class iterator_facade_base;
0427 
0428 } // namespace detail
0429 
0430 
0431 // Macros which describe the declarations of binary operators
0432 #define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler)   \
0433     template<                                                           \
0434         typename Derived1, typename V1, typename TC1, typename Reference1, typename Difference1, \
0435         typename Derived2, typename V2, typename TC2, typename Reference2, typename Difference2  \
0436     >                                                                   \
0437     prefix typename enabler<                                            \
0438         Derived1, Derived2,                                             \
0439         result_type< Derived1, Derived2 >                               \
0440     >::type                                                             \
0441     operator op(                                                        \
0442         iterator_facade< Derived1, V1, TC1, Reference1, Difference1 > const& lhs,   \
0443         iterator_facade< Derived2, V2, TC2, Reference2, Difference2 > const& rhs)
0444 
0445 #define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type)       \
0446     BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable)
0447 
0448 #define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(prefix, op, result_type)       \
0449     BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable_and_random_access_traversal)
0450 
0451 #define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args)                \
0452     template< typename Derived, typename V, typename TC, typename R, typename D >   \
0453     prefix typename std::enable_if<                                 \
0454         boost::iterators::detail::is_traversal_at_least<            \
0455             TC,                                                     \
0456             boost::iterators::random_access_traversal_tag           \
0457         >::value,                                                   \
0458         Derived                                                     \
0459     >::type operator+ args
0460 
0461 //
0462 // Helper class for granting access to the iterator core interface.
0463 //
0464 // The simple core interface is used by iterator_facade. The core
0465 // interface of a user/library defined iterator type should not be made public
0466 // so that it does not clutter the public interface. Instead iterator_core_access
0467 // should be made friend so that iterator_facade can access the core
0468 // interface through iterator_core_access.
0469 //
0470 class iterator_core_access
0471 {
0472     template< typename I, typename V, typename TC, typename R, typename D >
0473     friend class iterator_facade;
0474     template< typename I, typename V, typename TC, typename R, typename D, bool IsBidirectionalTraversal, bool IsRandomAccessTraversal >
0475     friend class detail::iterator_facade_base;
0476 
0477 #define BOOST_ITERATOR_FACADE_RELATION(op)                                \
0478     BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend, op, boost::iterators::detail::always_bool_t);
0479 
0480     BOOST_ITERATOR_FACADE_RELATION(==)
0481     BOOST_ITERATOR_FACADE_RELATION(!=)
0482 
0483 #undef BOOST_ITERATOR_FACADE_RELATION
0484 
0485 #define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op)                                \
0486     BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend, op, boost::iterators::detail::always_bool_t);
0487 
0488     BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<)
0489     BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>)
0490     BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=)
0491     BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=)
0492 
0493 #undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
0494 
0495     BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend, -, boost::iterators::detail::choose_difference_type_t);
0496 
0497     BOOST_ITERATOR_FACADE_PLUS_HEAD(
0498         friend inline,
0499         (iterator_facade< Derived, V, TC, R, D > const&, typename Derived::difference_type)
0500     );
0501 
0502     BOOST_ITERATOR_FACADE_PLUS_HEAD(
0503         friend inline,
0504         (typename Derived::difference_type, iterator_facade< Derived, V, TC, R, D > const&)
0505     );
0506 
0507     template< typename Facade >
0508     static typename Facade::reference dereference(Facade const& f)
0509     {
0510         return f.dereference();
0511     }
0512 
0513     template< typename Facade >
0514     static void increment(Facade& f)
0515     {
0516         f.increment();
0517     }
0518 
0519     template< typename Facade >
0520     static void decrement(Facade& f)
0521     {
0522         f.decrement();
0523     }
0524 
0525     template< typename Facade1, typename Facade2 >
0526     static bool equal(Facade1 const& f1, Facade2 const& f2, std::true_type)
0527     {
0528         return f1.equal(f2);
0529     }
0530 
0531     template< typename Facade1, typename Facade2 >
0532     static bool equal(Facade1 const& f1, Facade2 const& f2, std::false_type)
0533     {
0534         return f2.equal(f1);
0535     }
0536 
0537     template< typename Facade >
0538     static void advance(Facade& f, typename Facade::difference_type n)
0539     {
0540         f.advance(n);
0541     }
0542 
0543     template< typename Facade1, typename Facade2 >
0544     static typename Facade1::difference_type distance_from(Facade1 const& f1, Facade2 const& f2, std::true_type)
0545     {
0546         return -f1.distance_to(f2);
0547     }
0548 
0549     template< typename Facade1, typename Facade2 >
0550     static typename Facade2::difference_type distance_from(Facade1 const& f1, Facade2 const& f2, std::false_type)
0551     {
0552         return f2.distance_to(f1);
0553     }
0554 
0555     //
0556     // Curiously Recurring Template interface.
0557     //
0558     template< typename I, typename V, typename TC, typename R, typename D >
0559     static I& derived(iterator_facade< I, V, TC, R, D >& facade)
0560     {
0561         return *static_cast< I* >(&facade);
0562     }
0563 
0564     template< typename I, typename V, typename TC, typename R, typename D >
0565     static I const& derived(iterator_facade< I, V, TC, R, D > const& facade)
0566     {
0567         return *static_cast< I const* >(&facade);
0568     }
0569 
0570     // objects of this class are useless
0571     iterator_core_access() = delete;
0572 };
0573 
0574 namespace detail {
0575 
0576 // Implementation for forward traversal iterators
0577 template<
0578     typename Derived,
0579     typename Value,
0580     typename CategoryOrTraversal,
0581     typename Reference,
0582     typename Difference
0583 >
0584 class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
0585 {
0586 private:
0587     using associated_types = boost::iterators::detail::iterator_facade_types<
0588         Value, CategoryOrTraversal, Reference, Difference
0589     >;
0590 
0591     using operator_arrow_dispatch_ = boost::iterators::detail::operator_arrow_dispatch<
0592         Reference,
0593         typename associated_types::pointer
0594     >;
0595 
0596 public:
0597     using value_type = typename associated_types::value_type;
0598     using reference = Reference;
0599     using difference_type = Difference;
0600 
0601     using pointer = typename operator_arrow_dispatch_::result_type;
0602 
0603     using iterator_category = typename associated_types::iterator_category;
0604 
0605 public:
0606     reference operator*() const
0607     {
0608         return iterator_core_access::dereference(this->derived());
0609     }
0610 
0611     pointer operator->() const
0612     {
0613         return operator_arrow_dispatch_::apply(*this->derived());
0614     }
0615 
0616     Derived& operator++()
0617     {
0618         iterator_core_access::increment(this->derived());
0619         return this->derived();
0620     }
0621 
0622 protected:
0623     //
0624     // Curiously Recurring Template interface.
0625     //
0626     Derived& derived()
0627     {
0628         return *static_cast< Derived* >(this);
0629     }
0630 
0631     Derived const& derived() const
0632     {
0633         return *static_cast< Derived const* >(this);
0634     }
0635 };
0636 
0637 // Implementation for bidirectional traversal iterators
0638 template<
0639     typename Derived,
0640     typename Value,
0641     typename CategoryOrTraversal,
0642     typename Reference,
0643     typename Difference
0644 >
0645 class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > :
0646     public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
0647 {
0648 public:
0649     Derived& operator--()
0650     {
0651         iterator_core_access::decrement(this->derived());
0652         return this->derived();
0653     }
0654 
0655     Derived operator--(int)
0656     {
0657         Derived tmp(this->derived());
0658         --*this;
0659         return tmp;
0660     }
0661 };
0662 
0663 // Implementation for random access traversal iterators
0664 template<
0665     typename Derived,
0666     typename Value,
0667     typename CategoryOrTraversal,
0668     typename Reference,
0669     typename Difference
0670 >
0671 class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, true > :
0672     public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >
0673 {
0674 private:
0675     using base_type = iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >;
0676 
0677 public:
0678     using reference = typename base_type::reference;
0679     using difference_type = typename base_type::difference_type;
0680 
0681 public:
0682     typename boost::iterators::detail::operator_brackets_result< Derived, Value, reference >::type
0683     operator[](difference_type n) const
0684     {
0685         return boost::iterators::detail::make_operator_brackets_result< Derived >(
0686             this->derived() + n,
0687             std::integral_constant< bool, boost::iterators::detail::use_operator_brackets_proxy< Value, Reference >::value >{}
0688         );
0689     }
0690 
0691     Derived& operator+=(difference_type n)
0692     {
0693         iterator_core_access::advance(this->derived(), n);
0694         return this->derived();
0695     }
0696 
0697     Derived& operator-=(difference_type n)
0698     {
0699         iterator_core_access::advance(this->derived(), -n);
0700         return this->derived();
0701     }
0702 
0703     Derived operator-(difference_type x) const
0704     {
0705         Derived result(this->derived());
0706         return result -= x;
0707     }
0708 };
0709 
0710 } // namespace detail
0711 
0712 //
0713 // iterator_facade - use as a public base class for defining new
0714 // standard-conforming iterators.
0715 //
0716 template<
0717     typename Derived,             // The derived iterator type being constructed
0718     typename Value,
0719     typename CategoryOrTraversal,
0720     typename Reference,
0721     typename Difference
0722 >
0723 class iterator_facade :
0724     public detail::iterator_facade_base<
0725         Derived,
0726         Value,
0727         CategoryOrTraversal,
0728         Reference,
0729         Difference,
0730         detail::is_traversal_at_least< CategoryOrTraversal, bidirectional_traversal_tag >::value,
0731         detail::is_traversal_at_least< CategoryOrTraversal, random_access_traversal_tag >::value
0732     >
0733 {
0734 protected:
0735     // For use by derived classes
0736     using iterator_facade_ = iterator_facade< Derived, Value, CategoryOrTraversal, Reference, Difference >;
0737 };
0738 
0739 template< typename I, typename V, typename TC, typename R, typename D >
0740 inline typename boost::iterators::detail::postfix_increment_result< I, V, R, TC >::type
0741 operator++(iterator_facade< I, V, TC, R, D >& i, int)
0742 {
0743     typename boost::iterators::detail::postfix_increment_result< I, V, R, TC >::type
0744         tmp(*static_cast< I* >(&i));
0745 
0746     ++i;
0747 
0748     return tmp;
0749 }
0750 
0751 
0752 //
0753 // Comparison operator implementation. The library supplied operators
0754 // enables the user to provide fully interoperable constant/mutable
0755 // iterator types. I.e. the library provides all operators
0756 // for all mutable/constant iterator combinations.
0757 //
0758 // Note though that this kind of interoperability for constant/mutable
0759 // iterators is not required by the standard for container iterators.
0760 // All the standard asks for is a conversion mutable -> constant.
0761 // Most standard library implementations nowadays provide fully interoperable
0762 // iterator implementations, but there are still heavily used implementations
0763 // that do not provide them. (Actually it's even worse, they do not provide
0764 // them for only a few iterators.)
0765 //
0766 // ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should
0767 //    enable the user to turn off mixed type operators
0768 //
0769 // The library takes care to provide only the right operator overloads.
0770 // I.e.
0771 //
0772 // bool operator==(Iterator,      Iterator);
0773 // bool operator==(ConstIterator, Iterator);
0774 // bool operator==(Iterator,      ConstIterator);
0775 // bool operator==(ConstIterator, ConstIterator);
0776 //
0777 //   ...
0778 //
0779 // In order to do so it uses c++ idioms that are not yet widely supported
0780 // by current compiler releases. The library is designed to degrade gracefully
0781 // in the face of compiler deficiencies. In general compiler
0782 // deficiencies result in less strict error checking and more obscure
0783 // error messages, functionality is not affected.
0784 //
0785 // For full operation compiler support for "Substitution Failure Is Not An Error"
0786 // (aka. enable_if) and boost::is_convertible is required.
0787 //
0788 // The following problems occur if support is lacking.
0789 //
0790 // Pseudo code
0791 //
0792 // ---------------
0793 // AdaptorA<Iterator1> a1;
0794 // AdaptorA<Iterator2> a2;
0795 //
0796 // // This will result in a no such overload error in full operation
0797 // // If enable_if or is_convertible is not supported
0798 // // The instantiation will fail with an error hopefully indicating that
0799 // // there is no operator== for Iterator1, Iterator2
0800 // // The same will happen if no enable_if is used to remove
0801 // // false overloads from the templated conversion constructor
0802 // // of AdaptorA.
0803 //
0804 // a1 == a2;
0805 // ----------------
0806 //
0807 // AdaptorA<Iterator> a;
0808 // AdaptorB<Iterator> b;
0809 //
0810 // // This will result in a no such overload error in full operation
0811 // // If enable_if is not supported the static assert used
0812 // // in the operator implementation will fail.
0813 // // This will accidently work if is_convertible is not supported.
0814 //
0815 // a == b;
0816 // ----------------
0817 //
0818 
0819 #define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op)                 \
0820     BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type)                                \
0821     {                                                                                          \
0822         return_prefix iterator_core_access::base_op(                                           \
0823             *static_cast< Derived1 const* >(&lhs),                                             \
0824             *static_cast< Derived2 const* >(&rhs),                                             \
0825             std::integral_constant< bool, std::is_convertible< Derived2, Derived1 >::value >() \
0826         );                                                                                     \
0827     }
0828 
0829 #define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
0830     BOOST_ITERATOR_FACADE_INTEROP(                                 \
0831         op,                                                        \
0832         boost::iterators::detail::always_bool_t,                   \
0833         return_prefix,                                             \
0834         base_op                                                    \
0835     )
0836 
0837 BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
0838 BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
0839 
0840 #undef BOOST_ITERATOR_FACADE_RELATION
0841 
0842 
0843 #define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(op, result_type, return_prefix, base_op)   \
0844     BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(inline, op, result_type)                  \
0845     {                                                                                          \
0846         return_prefix iterator_core_access::base_op(                                           \
0847             *static_cast< Derived1 const* >(&lhs),                                             \
0848             *static_cast< Derived2 const* >(&rhs),                                             \
0849             std::integral_constant< bool, std::is_convertible< Derived2, Derived1 >::value >() \
0850         );                                                                                     \
0851     }
0852 
0853 #define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op, return_prefix, base_op) \
0854     BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(                                 \
0855         op,                                                                      \
0856         boost::iterators::detail::always_bool_t,                                 \
0857         return_prefix,                                                           \
0858         base_op                                                                  \
0859     )
0860 
0861 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<, return 0 >, distance_from)
0862 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>, return 0 <, distance_from)
0863 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=, return 0 >=, distance_from)
0864 BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=, return 0 <=, distance_from)
0865 
0866 #undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
0867 
0868 // operator- requires an additional part in the static assertion
0869 BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(
0870     -,
0871     boost::iterators::detail::choose_difference_type_t,
0872     return,
0873     distance_from
0874 )
0875 
0876 #undef BOOST_ITERATOR_FACADE_INTEROP
0877 #undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS
0878 
0879 #define BOOST_ITERATOR_FACADE_PLUS(args)               \
0880     BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args)      \
0881     {                                                  \
0882         Derived tmp(static_cast< Derived const& >(i)); \
0883         return tmp += n;                               \
0884     }
0885 
0886 BOOST_ITERATOR_FACADE_PLUS((iterator_facade< Derived, V, TC, R, D > const& i, typename Derived::difference_type n))
0887 BOOST_ITERATOR_FACADE_PLUS((typename Derived::difference_type n, iterator_facade< Derived, V, TC, R, D > const& i))
0888 
0889 #undef BOOST_ITERATOR_FACADE_PLUS
0890 #undef BOOST_ITERATOR_FACADE_PLUS_HEAD
0891 
0892 #undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
0893 #undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD
0894 #undef BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL
0895 
0896 } // namespace iterators
0897 
0898 using iterators::iterator_core_access;
0899 using iterators::iterator_facade;
0900 
0901 } // namespace boost
0902 
0903 #endif // BOOST_ITERATOR_FACADE_23022003THW_HPP