1 // (C) Copyright David Abrahams 2002.
\r
2 // (C) Copyright Jeremy Siek 2002.
\r
3 // (C) Copyright Thomas Witt 2002.
\r
4 // Distributed under the Boost Software License, Version 1.0. (See
\r
5 // accompanying file LICENSE_1_0.txt or copy at
\r
6 // http://www.boost.org/LICENSE_1_0.txt)
\r
7 #ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
\r
8 #define BOOST_ITERATOR_FACADE_23022003THW_HPP
\r
10 #include <boost/iterator.hpp>
\r
11 #include <boost/iterator/interoperable.hpp>
\r
12 #include <boost/iterator/iterator_traits.hpp>
\r
14 #include <boost/iterator/detail/facade_iterator_category.hpp>
\r
15 #include <boost/iterator/detail/enable_if.hpp>
\r
17 #include <boost/implicit_cast.hpp>
\r
18 #include <boost/static_assert.hpp>
\r
20 #include <boost/type_traits/is_same.hpp>
\r
21 #include <boost/type_traits/add_const.hpp>
\r
22 #include <boost/type_traits/add_pointer.hpp>
\r
23 #include <boost/type_traits/remove_const.hpp>
\r
24 #include <boost/type_traits/remove_reference.hpp>
\r
25 #include <boost/type_traits/is_convertible.hpp>
\r
26 #include <boost/type_traits/is_pod.hpp>
\r
28 #include <boost/mpl/eval_if.hpp>
\r
29 #include <boost/mpl/if.hpp>
\r
30 #include <boost/mpl/or.hpp>
\r
31 #include <boost/mpl/and.hpp>
\r
32 #include <boost/mpl/not.hpp>
\r
33 #include <boost/mpl/always.hpp>
\r
34 #include <boost/mpl/apply.hpp>
\r
35 #include <boost/mpl/identity.hpp>
\r
37 #include <boost/iterator/detail/config_def.hpp> // this goes last
\r
41 // This forward declaration is required for the friend declaration
\r
42 // in iterator_core_access
\r
43 template <class I, class V, class TC, class R, class D> class iterator_facade;
\r
47 // A binary metafunction class that always returns bool. VC6
\r
48 // ICEs on mpl::always<bool>, probably because of the default
\r
52 template <class T, class U>
\r
60 // enable if for use in operator implementation.
\r
67 struct enable_if_interoperable
\r
68 #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
\r
70 typedef typename mpl::if_<
\r
72 is_convertible<Facade1, Facade2>
\r
73 , is_convertible<Facade2, Facade1>
\r
80 : ::boost::iterators::enable_if<
\r
82 is_convertible<Facade1, Facade2>
\r
83 , is_convertible<Facade2, Facade1>
\r
91 // Generates associated types for an iterator_facade with the
\r
92 // given parameters.
\r
96 , class CategoryOrTraversal
\r
100 struct iterator_facade_types
\r
102 typedef typename facade_iterator_category<
\r
103 CategoryOrTraversal, ValueParam, Reference
\r
104 >::type iterator_category;
\r
106 typedef typename remove_const<ValueParam>::type value_type;
\r
108 typedef typename mpl::eval_if<
\r
109 boost::detail::iterator_writability_disabled<ValueParam,Reference>
\r
110 , add_pointer<const value_type>
\r
111 , add_pointer<value_type>
\r
114 # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
\r
115 && (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452)) \
\r
116 || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310))) \
\r
117 || BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101)) \
\r
118 || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 310)
\r
120 // To interoperate with some broken library/compiler
\r
121 // combinations, user-defined iterators must be derived from
\r
122 // std::iterator. It is possible to implement a standard
\r
123 // library for broken compilers without this limitation.
\r
124 # define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1
\r
127 iterator<iterator_category, value_type, Difference, pointer, Reference>
\r
132 // iterators whose dereference operators reference the same value
\r
133 // for all iterators into the same sequence (like many input
\r
134 // iterators) need help with their postfix ++: the referenced
\r
135 // value must be read and stored away before the increment occurs
\r
136 // so that *a++ yields the originally referenced element and not
\r
138 template <class Iterator>
\r
139 class postfix_increment_proxy
\r
141 typedef typename iterator_value<Iterator>::type value_type;
\r
143 explicit postfix_increment_proxy(Iterator const& x)
\r
147 // Returning a mutable reference allows nonsense like
\r
148 // (*r++).mutate(), but it imposes fewer assumptions about the
\r
149 // behavior of the value_type. In particular, recall taht
\r
150 // (*r).mutate() is legal if operator* returns by value.
\r
154 return this->stored_value;
\r
157 mutable value_type stored_value;
\r
161 // In general, we can't determine that such an iterator isn't
\r
162 // writable -- we also need to store a copy of the old iterator so
\r
163 // that it can be written into.
\r
164 template <class Iterator>
\r
165 class writable_postfix_increment_proxy
\r
167 typedef typename iterator_value<Iterator>::type value_type;
\r
169 explicit writable_postfix_increment_proxy(Iterator const& x)
\r
171 , stored_iterator(x)
\r
174 // Dereferencing must return a proxy so that both *r++ = o and
\r
175 // value_type(*r++) can work. In this case, *r is the same as
\r
176 // *r++, and the conversion operator below is used to ensure
\r
178 writable_postfix_increment_proxy const&
\r
184 // Provides readability of *r++
\r
185 operator value_type&() const
\r
187 return stored_value;
\r
190 // Provides writability of *r++
\r
192 T const& operator=(T const& x) const
\r
194 *this->stored_iterator = x;
\r
198 // This overload just in case only non-const objects are writable
\r
200 T& operator=(T& x) const
\r
202 *this->stored_iterator = x;
\r
207 operator Iterator const&() const
\r
209 return stored_iterator;
\r
213 mutable value_type stored_value;
\r
214 Iterator stored_iterator;
\r
217 # ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
\r
219 template <class Reference, class Value>
\r
220 struct is_non_proxy_reference_impl
\r
222 static Reference r;
\r
225 static typename mpl::if_<
\r
228 , Value const volatile*
\r
232 >::type& helper(R const&);
\r
234 BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1);
\r
237 template <class Reference, class Value>
\r
238 struct is_non_proxy_reference
\r
240 is_non_proxy_reference_impl<Reference, Value>::value
\r
244 template <class Reference, class Value>
\r
245 struct is_non_proxy_reference
\r
247 typename remove_reference<Reference>::type
\r
249 , Value const volatile*
\r
254 // A metafunction to choose the result type of postfix ++
\r
256 // Because the C++98 input iterator requirements say that *r++ has
\r
257 // type T (value_type), implementations of some standard
\r
258 // algorithms like lexicographical_compare may use constructions
\r
263 // If *r++ returns a proxy (as required if r is writable but not
\r
264 // multipass), this sort of expression will fail unless the proxy
\r
265 // supports the operator<. Since there are any number of such
\r
266 // operations, we're not going to try to support them. Therefore,
\r
267 // even if r++ returns a proxy, *r++ will only return a proxy if
\r
268 // *r also returns a proxy.
\r
269 template <class Iterator, class Value, class Reference, class CategoryOrTraversal>
\r
270 struct postfix_increment_result
\r
273 // A proxy is only needed for readable iterators
\r
274 is_convertible<Reference,Value const&>
\r
276 // No multipass iterator can have values that disappear
\r
277 // before positions can be re-visited
\r
280 typename iterator_category_to_traversal<CategoryOrTraversal>::type
\r
281 , forward_traversal_tag
\r
286 is_non_proxy_reference<Reference,Value>
\r
287 , postfix_increment_proxy<Iterator>
\r
288 , writable_postfix_increment_proxy<Iterator>
\r
290 , mpl::identity<Iterator>
\r
294 // operator->() needs special support for input iterators to strictly meet the
\r
295 // standard's requirements. If *i is not a reference type, we must still
\r
296 // produce a lvalue to which a pointer can be formed. We do that by
\r
297 // returning an instantiation of this special proxy class template.
\r
299 struct operator_arrow_proxy
\r
301 operator_arrow_proxy(T const* px) : m_value(*px) {}
\r
302 T* operator->() const { return &m_value; }
\r
303 // This function is needed for MWCW and BCC, which won't call operator->
\r
304 // again automatically per 13.3.1.2 para 8
\r
305 operator T*() const { return &m_value; }
\r
309 // A metafunction that gets the result type for operator->. Also
\r
310 // has a static function make() which builds the result from a
\r
312 template <class ValueType, class Reference, class Pointer>
\r
313 struct operator_arrow_result
\r
315 // CWPro8.3 won't accept "operator_arrow_result::type", and we
\r
316 // need that type below, so metafunction forwarding would be a
\r
317 // losing proposition here.
\r
318 typedef typename mpl::if_<
\r
319 is_reference<Reference>
\r
321 , operator_arrow_proxy<ValueType>
\r
324 static type make(Reference x)
\r
326 return implicit_cast<type>(&x);
\r
330 # if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
\r
333 struct operator_arrow_result<int, int, int>
\r
339 // A proxy return type for operator[], needed to deal with
\r
340 // iterators that may invalidate referents upon destruction.
\r
341 // Consider the temporary iterator in *(a + n)
\r
342 template <class Iterator>
\r
343 class operator_brackets_proxy
\r
345 // Iterator is actually an iterator_facade, so we do not have to
\r
346 // go through iterator_traits to access the traits.
\r
347 typedef typename Iterator::reference reference;
\r
348 typedef typename Iterator::value_type value_type;
\r
351 operator_brackets_proxy(Iterator const& iter)
\r
355 operator reference() const
\r
360 operator_brackets_proxy& operator=(value_type const& val)
\r
370 // A metafunction that determines whether operator[] must return a
\r
371 // proxy, or whether it can simply return a copy of the value_type.
\r
372 template <class ValueType, class Reference>
\r
373 struct use_operator_brackets_proxy
\r
376 // Really we want an is_copy_constructible trait here,
\r
377 // but is_POD will have to suffice in the meantime.
\r
378 boost::is_POD<ValueType>
\r
379 , iterator_writability_disabled<ValueType,Reference>
\r
384 template <class Iterator, class Value, class Reference>
\r
385 struct operator_brackets_result
\r
387 typedef typename mpl::if_<
\r
388 use_operator_brackets_proxy<Value,Reference>
\r
389 , operator_brackets_proxy<Iterator>
\r
394 template <class Iterator>
\r
395 operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::true_)
\r
397 return operator_brackets_proxy<Iterator>(iter);
\r
400 template <class Iterator>
\r
401 typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_)
\r
406 struct choose_difference_type
\r
408 template <class I1, class I2>
\r
411 # ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
\r
412 iterator_difference<I1>
\r
413 # elif BOOST_WORKAROUND(BOOST_MSVC, < 1300)
\r
415 is_convertible<I2,I1>
\r
416 , typename I1::difference_type
\r
417 , typename I2::difference_type
\r
421 is_convertible<I2,I1>
\r
422 , iterator_difference<I1>
\r
423 , iterator_difference<I2>
\r
429 } // namespace detail
\r
432 // Macros which describe the declarations of binary operators
\r
433 # ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
\r
434 # define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
\r
436 class Derived1, class V1, class TC1, class Reference1, class Difference1 \
\r
437 , class Derived2, class V2, class TC2, class Reference2, class Difference2 \
\r
439 prefix typename mpl::apply2<result_type,Derived1,Derived2>::type \
\r
441 iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs \
\r
442 , iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
\r
444 # define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type) \
\r
446 class Derived1, class V1, class TC1, class Reference1, class Difference1 \
\r
447 , class Derived2, class V2, class TC2, class Reference2, class Difference2 \
\r
449 prefix typename boost::detail::enable_if_interoperable< \
\r
450 Derived1, Derived2 \
\r
451 , typename mpl::apply2<result_type,Derived1,Derived2>::type \
\r
454 iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs \
\r
455 , iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
\r
458 # define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args) \
\r
459 template <class Derived, class V, class TC, class R, class D> \
\r
460 prefix Derived operator+ args
\r
463 // Helper class for granting access to the iterator core interface.
\r
465 // The simple core interface is used by iterator_facade. The core
\r
466 // interface of a user/library defined iterator type should not be made public
\r
467 // so that it does not clutter the public interface. Instead iterator_core_access
\r
468 // should be made friend so that iterator_facade can access the core
\r
469 // interface through iterator_core_access.
\r
471 class iterator_core_access
\r
473 # if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
\r
474 // Tasteless as this may seem, making all members public allows member templates
\r
475 // to work in the absence of member template friends.
\r
479 template <class I, class V, class TC, class R, class D> friend class iterator_facade;
\r
481 # define BOOST_ITERATOR_FACADE_RELATION(op) \
\r
482 BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, boost::detail::always_bool2);
\r
484 BOOST_ITERATOR_FACADE_RELATION(==)
\r
485 BOOST_ITERATOR_FACADE_RELATION(!=)
\r
487 BOOST_ITERATOR_FACADE_RELATION(<)
\r
488 BOOST_ITERATOR_FACADE_RELATION(>)
\r
489 BOOST_ITERATOR_FACADE_RELATION(<=)
\r
490 BOOST_ITERATOR_FACADE_RELATION(>=)
\r
491 # undef BOOST_ITERATOR_FACADE_RELATION
\r
493 BOOST_ITERATOR_FACADE_INTEROP_HEAD(
\r
494 friend, -, boost::detail::choose_difference_type)
\r
497 BOOST_ITERATOR_FACADE_PLUS_HEAD(
\r
499 , (iterator_facade<Derived, V, TC, R, D> const&
\r
500 , typename Derived::difference_type)
\r
504 BOOST_ITERATOR_FACADE_PLUS_HEAD(
\r
506 , (typename Derived::difference_type
\r
507 , iterator_facade<Derived, V, TC, R, D> const&)
\r
513 template <class Facade>
\r
514 static typename Facade::reference dereference(Facade const& f)
\r
516 return f.dereference();
\r
519 template <class Facade>
\r
520 static void increment(Facade& f)
\r
525 template <class Facade>
\r
526 static void decrement(Facade& f)
\r
531 template <class Facade1, class Facade2>
\r
532 static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::true_)
\r
534 return f1.equal(f2);
\r
537 template <class Facade1, class Facade2>
\r
538 static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::false_)
\r
540 return f2.equal(f1);
\r
543 template <class Facade>
\r
544 static void advance(Facade& f, typename Facade::difference_type n)
\r
549 template <class Facade1, class Facade2>
\r
550 static typename Facade1::difference_type distance_from(
\r
551 Facade1 const& f1, Facade2 const& f2, mpl::true_)
\r
553 return -f1.distance_to(f2);
\r
556 template <class Facade1, class Facade2>
\r
557 static typename Facade2::difference_type distance_from(
\r
558 Facade1 const& f1, Facade2 const& f2, mpl::false_)
\r
560 return f2.distance_to(f1);
\r
564 // Curiously Recurring Template interface.
\r
566 template <class I, class V, class TC, class R, class D>
\r
567 static I& derived(iterator_facade<I,V,TC,R,D>& facade)
\r
569 return *static_cast<I*>(&facade);
\r
572 template <class I, class V, class TC, class R, class D>
\r
573 static I const& derived(iterator_facade<I,V,TC,R,D> const& facade)
\r
575 return *static_cast<I const*>(&facade);
\r
579 // objects of this class are useless
\r
580 iterator_core_access(); //undefined
\r
584 // iterator_facade - use as a public base class for defining new
\r
585 // standard-conforming iterators.
\r
588 class Derived // The derived iterator type being constructed
\r
590 , class CategoryOrTraversal
\r
591 , class Reference = Value&
\r
592 , class Difference = std::ptrdiff_t
\r
594 class iterator_facade
\r
595 # ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
\r
596 : public boost::detail::iterator_facade_types<
\r
597 Value, CategoryOrTraversal, Reference, Difference
\r
599 # undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
\r
604 // Curiously Recurring Template interface.
\r
608 return *static_cast<Derived*>(this);
\r
611 Derived const& derived() const
\r
613 return *static_cast<Derived const*>(this);
\r
616 typedef boost::detail::iterator_facade_types<
\r
617 Value, CategoryOrTraversal, Reference, Difference
\r
618 > associated_types;
\r
621 // For use by derived classes
\r
622 typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_;
\r
626 typedef typename associated_types::value_type value_type;
\r
627 typedef Reference reference;
\r
628 typedef Difference difference_type;
\r
629 typedef typename associated_types::pointer pointer;
\r
630 typedef typename associated_types::iterator_category iterator_category;
\r
632 reference operator*() const
\r
634 return iterator_core_access::dereference(this->derived());
\r
637 typename boost::detail::operator_arrow_result<
\r
644 return boost::detail::operator_arrow_result<
\r
648 >::make(*this->derived());
\r
651 typename boost::detail::operator_brackets_result<Derived,Value,reference>::type
\r
652 operator[](difference_type n) const
\r
654 typedef boost::detail::use_operator_brackets_proxy<Value,Reference> use_proxy;
\r
656 return boost::detail::make_operator_brackets_result<Derived>(
\r
657 this->derived() + n
\r
662 Derived& operator++()
\r
664 iterator_core_access::increment(this->derived());
\r
665 return this->derived();
\r
668 # if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
\r
669 typename boost::detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
\r
672 typename boost::detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
\r
673 tmp(this->derived());
\r
679 Derived& operator--()
\r
681 iterator_core_access::decrement(this->derived());
\r
682 return this->derived();
\r
685 Derived operator--(int)
\r
687 Derived tmp(this->derived());
\r
692 Derived& operator+=(difference_type n)
\r
694 iterator_core_access::advance(this->derived(), n);
\r
695 return this->derived();
\r
698 Derived& operator-=(difference_type n)
\r
700 iterator_core_access::advance(this->derived(), -n);
\r
701 return this->derived();
\r
704 Derived operator-(difference_type x) const
\r
706 Derived result(this->derived());
\r
707 return result -= x;
\r
710 # if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
\r
711 // There appears to be a bug which trashes the data of classes
\r
712 // derived from iterator_facade when they are assigned unless we
\r
713 // define this assignment operator. This bug is only revealed
\r
714 // (so far) in STLPort debug mode, but it's clearly a codegen
\r
715 // problem so we apply the workaround for all MSVC6.
\r
716 iterator_facade& operator=(iterator_facade const&)
\r
723 # if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
\r
724 template <class I, class V, class TC, class R, class D>
\r
725 inline typename boost::detail::postfix_increment_result<I,V,R,TC>::type
\r
727 iterator_facade<I,V,TC,R,D>& i
\r
731 typename boost::detail::postfix_increment_result<I,V,R,TC>::type
\r
732 tmp(*static_cast<I*>(&i));
\r
742 // Comparison operator implementation. The library supplied operators
\r
743 // enables the user to provide fully interoperable constant/mutable
\r
744 // iterator types. I.e. the library provides all operators
\r
745 // for all mutable/constant iterator combinations.
\r
747 // Note though that this kind of interoperability for constant/mutable
\r
748 // iterators is not required by the standard for container iterators.
\r
749 // All the standard asks for is a conversion mutable -> constant.
\r
750 // Most standard library implementations nowadays provide fully interoperable
\r
751 // iterator implementations, but there are still heavily used implementations
\r
752 // that do not provide them. (Actually it's even worse, they do not provide
\r
753 // them for only a few iterators.)
\r
755 // ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should
\r
756 // enable the user to turn off mixed type operators
\r
758 // The library takes care to provide only the right operator overloads.
\r
761 // bool operator==(Iterator, Iterator);
\r
762 // bool operator==(ConstIterator, Iterator);
\r
763 // bool operator==(Iterator, ConstIterator);
\r
764 // bool operator==(ConstIterator, ConstIterator);
\r
768 // In order to do so it uses c++ idioms that are not yet widely supported
\r
769 // by current compiler releases. The library is designed to degrade gracefully
\r
770 // in the face of compiler deficiencies. In general compiler
\r
771 // deficiencies result in less strict error checking and more obscure
\r
772 // error messages, functionality is not affected.
\r
774 // For full operation compiler support for "Substitution Failure Is Not An Error"
\r
775 // (aka. enable_if) and boost::is_convertible is required.
\r
777 // The following problems occur if support is lacking.
\r
782 // AdaptorA<Iterator1> a1;
\r
783 // AdaptorA<Iterator2> a2;
\r
785 // // This will result in a no such overload error in full operation
\r
786 // // If enable_if or is_convertible is not supported
\r
787 // // The instantiation will fail with an error hopefully indicating that
\r
788 // // there is no operator== for Iterator1, Iterator2
\r
789 // // The same will happen if no enable_if is used to remove
\r
790 // // false overloads from the templated conversion constructor
\r
794 // ----------------
\r
796 // AdaptorA<Iterator> a;
\r
797 // AdaptorB<Iterator> b;
\r
799 // // This will result in a no such overload error in full operation
\r
800 // // If enable_if is not supported the static assert used
\r
801 // // in the operator implementation will fail.
\r
802 // // This will accidently work if is_convertible is not supported.
\r
805 // ----------------
\r
808 # ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
\r
809 # define BOOST_ITERATOR_CONVERTIBLE(a,b) mpl::true_()
\r
811 # define BOOST_ITERATOR_CONVERTIBLE(a,b) is_convertible<a,b>()
\r
814 # define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op) \
\r
815 BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type) \
\r
817 /* For those compilers that do not support enable_if */ \
\r
818 BOOST_STATIC_ASSERT(( \
\r
819 is_interoperable< Derived1, Derived2 >::value \
\r
821 return_prefix iterator_core_access::base_op( \
\r
822 *static_cast<Derived1 const*>(&lhs) \
\r
823 , *static_cast<Derived2 const*>(&rhs) \
\r
824 , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1) \
\r
828 # define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
\r
829 BOOST_ITERATOR_FACADE_INTEROP( \
\r
831 , boost::detail::always_bool2 \
\r
836 BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
\r
837 BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
\r
839 BOOST_ITERATOR_FACADE_RELATION(<, return 0 >, distance_from)
\r
840 BOOST_ITERATOR_FACADE_RELATION(>, return 0 <, distance_from)
\r
841 BOOST_ITERATOR_FACADE_RELATION(<=, return 0 >=, distance_from)
\r
842 BOOST_ITERATOR_FACADE_RELATION(>=, return 0 <=, distance_from)
\r
843 # undef BOOST_ITERATOR_FACADE_RELATION
\r
845 // operator- requires an additional part in the static assertion
\r
846 BOOST_ITERATOR_FACADE_INTEROP(
\r
848 , boost::detail::choose_difference_type
\r
852 # undef BOOST_ITERATOR_FACADE_INTEROP
\r
853 # undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
\r
855 # define BOOST_ITERATOR_FACADE_PLUS(args) \
\r
856 BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args) \
\r
858 Derived tmp(static_cast<Derived const&>(i)); \
\r
862 BOOST_ITERATOR_FACADE_PLUS((
\r
863 iterator_facade<Derived, V, TC, R, D> const& i
\r
864 , typename Derived::difference_type n
\r
867 BOOST_ITERATOR_FACADE_PLUS((
\r
868 typename Derived::difference_type n
\r
869 , iterator_facade<Derived, V, TC, R, D> const& i
\r
871 # undef BOOST_ITERATOR_FACADE_PLUS
\r
872 # undef BOOST_ITERATOR_FACADE_PLUS_HEAD
\r
874 } // namespace boost
\r
876 #include <boost/iterator/detail/config_undef.hpp>
\r
878 #endif // BOOST_ITERATOR_FACADE_23022003THW_HPP
\r