]> git.lyx.org Git - lyx.git/blob - 3rdparty/boost/boost/iterator/iterator_facade.hpp
Update to boost 1.72
[lyx.git] / 3rdparty / boost / boost / iterator / iterator_facade.hpp
1 // (C) Copyright David Abrahams 2002.
2 // (C) Copyright Jeremy Siek    2002.
3 // (C) Copyright Thomas Witt    2002.
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 #ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
8 #define BOOST_ITERATOR_FACADE_23022003THW_HPP
9
10 #include <boost/config.hpp>
11 #include <boost/iterator/interoperable.hpp>
12 #include <boost/iterator/iterator_traits.hpp>
13 #include <boost/iterator/iterator_categories.hpp>
14
15 #include <boost/iterator/detail/facade_iterator_category.hpp>
16 #include <boost/iterator/detail/enable_if.hpp>
17
18 #include <boost/static_assert.hpp>
19 #include <boost/core/addressof.hpp>
20
21 #include <boost/type_traits/is_same.hpp>
22 #include <boost/type_traits/add_const.hpp>
23 #include <boost/type_traits/add_pointer.hpp>
24 #include <boost/type_traits/add_lvalue_reference.hpp>
25 #include <boost/type_traits/remove_const.hpp>
26 #include <boost/type_traits/remove_reference.hpp>
27 #include <boost/type_traits/is_convertible.hpp>
28 #include <boost/type_traits/is_pod.hpp>
29
30 #include <boost/mpl/eval_if.hpp>
31 #include <boost/mpl/if.hpp>
32 #include <boost/mpl/or.hpp>
33 #include <boost/mpl/and.hpp>
34 #include <boost/mpl/not.hpp>
35 #include <boost/mpl/always.hpp>
36 #include <boost/mpl/apply.hpp>
37 #include <boost/mpl/identity.hpp>
38
39 #include <cstddef>
40
41 #include <boost/iterator/detail/config_def.hpp> // this goes last
42
43 namespace boost {
44 namespace iterators {
45
46   // This forward declaration is required for the friend declaration
47   // in iterator_core_access
48   template <class I, class V, class TC, class R, class D> class iterator_facade;
49
50   namespace detail
51   {
52     // A binary metafunction class that always returns bool.  VC6
53     // ICEs on mpl::always<bool>, probably because of the default
54     // parameters.
55     struct always_bool2
56     {
57         template <class T, class U>
58         struct apply
59         {
60             typedef bool type;
61         };
62     };
63
64     // The type trait checks if the category or traversal is at least as advanced as the specified required traversal
65     template< typename CategoryOrTraversal, typename Required >
66     struct is_traversal_at_least :
67         public boost::is_convertible< typename iterator_category_to_traversal< CategoryOrTraversal >::type, Required >
68     {};
69
70     //
71     // enable if for use in operator implementation.
72     //
73     template <
74         class Facade1
75       , class Facade2
76       , class Return
77     >
78     struct enable_if_interoperable :
79         public boost::iterators::enable_if<
80             is_interoperable< Facade1, Facade2 >
81           , Return
82         >
83     {};
84
85     //
86     // enable if for use in implementation of operators specific for random access traversal.
87     //
88     template <
89         class Facade1
90       , class Facade2
91       , class Return
92     >
93     struct enable_if_interoperable_and_random_access_traversal :
94         public boost::iterators::enable_if<
95             mpl::and_<
96                 is_interoperable< Facade1, Facade2 >
97               , is_traversal_at_least< typename iterator_category< Facade1 >::type, random_access_traversal_tag >
98               , is_traversal_at_least< typename iterator_category< Facade2 >::type, random_access_traversal_tag >
99             >
100           , Return
101         >
102     {};
103
104     //
105     // Generates associated types for an iterator_facade with the
106     // given parameters.
107     //
108     template <
109         class ValueParam
110       , class CategoryOrTraversal
111       , class Reference
112       , class Difference
113     >
114     struct iterator_facade_types
115     {
116         typedef typename facade_iterator_category<
117             CategoryOrTraversal, ValueParam, Reference
118         >::type iterator_category;
119
120         typedef typename remove_const<ValueParam>::type value_type;
121
122         // Not the real associated pointer type
123         typedef typename mpl::eval_if<
124             boost::iterators::detail::iterator_writability_disabled<ValueParam,Reference>
125           , add_pointer<const value_type>
126           , add_pointer<value_type>
127         >::type pointer;
128
129 # if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)                          \
130     && (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452))              \
131         || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310)))     \
132     || BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101))              \
133     || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 310)
134
135         // To interoperate with some broken library/compiler
136         // combinations, user-defined iterators must be derived from
137         // std::iterator.  It is possible to implement a standard
138         // library for broken compilers without this limitation.
139 #  define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1
140
141         typedef
142            iterator<iterator_category, value_type, Difference, pointer, Reference>
143         base;
144 # endif
145     };
146
147     // iterators whose dereference operators reference the same value
148     // for all iterators into the same sequence (like many input
149     // iterators) need help with their postfix ++: the referenced
150     // value must be read and stored away before the increment occurs
151     // so that *a++ yields the originally referenced element and not
152     // the next one.
153     template <class Iterator>
154     class postfix_increment_proxy
155     {
156         typedef typename iterator_value<Iterator>::type value_type;
157      public:
158         explicit postfix_increment_proxy(Iterator const& x)
159           : stored_value(*x)
160         {}
161
162         // Returning a mutable reference allows nonsense like
163         // (*r++).mutate(), but it imposes fewer assumptions about the
164         // behavior of the value_type.  In particular, recall that
165         // (*r).mutate() is legal if operator* returns by value.
166         value_type&
167         operator*() const
168         {
169             return this->stored_value;
170         }
171      private:
172         mutable value_type stored_value;
173     };
174
175     //
176     // In general, we can't determine that such an iterator isn't
177     // writable -- we also need to store a copy of the old iterator so
178     // that it can be written into.
179     template <class Iterator>
180     class writable_postfix_increment_proxy
181     {
182         typedef typename iterator_value<Iterator>::type value_type;
183      public:
184         explicit writable_postfix_increment_proxy(Iterator const& x)
185           : stored_value(*x)
186           , stored_iterator(x)
187         {}
188
189         // Dereferencing must return a proxy so that both *r++ = o and
190         // value_type(*r++) can work.  In this case, *r is the same as
191         // *r++, and the conversion operator below is used to ensure
192         // readability.
193         writable_postfix_increment_proxy const&
194         operator*() const
195         {
196             return *this;
197         }
198
199         // Provides readability of *r++
200         operator value_type&() const
201         {
202             return stored_value;
203         }
204
205         // Provides writability of *r++
206         template <class T>
207         T const& operator=(T const& x) const
208         {
209             *this->stored_iterator = x;
210             return x;
211         }
212
213         // This overload just in case only non-const objects are writable
214         template <class T>
215         T& operator=(T& x) const
216         {
217             *this->stored_iterator = x;
218             return x;
219         }
220
221         // Provides X(r++)
222         operator Iterator const&() const
223         {
224             return stored_iterator;
225         }
226
227      private:
228         mutable value_type stored_value;
229         Iterator stored_iterator;
230     };
231
232 # ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
233
234     template <class Reference, class Value>
235     struct is_non_proxy_reference_impl
236     {
237         static Reference r;
238
239         template <class R>
240         static typename mpl::if_<
241             is_convertible<
242                 R const volatile*
243               , Value const volatile*
244             >
245           , char[1]
246           , char[2]
247         >::type& helper(R const&);
248
249         BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1);
250     };
251
252     template <class Reference, class Value>
253     struct is_non_proxy_reference
254       : mpl::bool_<
255             is_non_proxy_reference_impl<Reference, Value>::value
256         >
257     {};
258 # else
259     template <class Reference, class Value>
260     struct is_non_proxy_reference
261       : is_convertible<
262             typename remove_reference<Reference>::type
263             const volatile*
264           , Value const volatile*
265         >
266     {};
267 # endif
268
269     // A metafunction to choose the result type of postfix ++
270     //
271     // Because the C++98 input iterator requirements say that *r++ has
272     // type T (value_type), implementations of some standard
273     // algorithms like lexicographical_compare may use constructions
274     // like:
275     //
276     //          *r++ < *s++
277     //
278     // If *r++ returns a proxy (as required if r is writable but not
279     // multipass), this sort of expression will fail unless the proxy
280     // supports the operator<.  Since there are any number of such
281     // operations, we're not going to try to support them.  Therefore,
282     // even if r++ returns a proxy, *r++ will only return a proxy if
283     // *r also returns a proxy.
284     template <class Iterator, class Value, class Reference, class CategoryOrTraversal>
285     struct postfix_increment_result
286       : mpl::eval_if<
287             mpl::and_<
288                 // A proxy is only needed for readable iterators
289                 is_convertible<
290                     Reference
291                     // Use add_lvalue_reference to form `reference to Value` due to
292                     // some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject
293                     // 'reference-to-reference' in the template which described in CWG
294                     // DR106.
295                     // http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106
296                   , typename add_lvalue_reference<Value const>::type
297                 >
298
299                 // No multipass iterator can have values that disappear
300                 // before positions can be re-visited
301               , mpl::not_<
302                     is_convertible<
303                         typename iterator_category_to_traversal<CategoryOrTraversal>::type
304                       , forward_traversal_tag
305                     >
306                 >
307             >
308           , mpl::if_<
309                 is_non_proxy_reference<Reference,Value>
310               , postfix_increment_proxy<Iterator>
311               , writable_postfix_increment_proxy<Iterator>
312             >
313           , mpl::identity<Iterator>
314         >
315     {};
316
317     // operator->() needs special support for input iterators to strictly meet the
318     // standard's requirements. If *i is not a reference type, we must still
319     // produce an lvalue to which a pointer can be formed.  We do that by
320     // returning a proxy object containing an instance of the reference object.
321     template <class Reference, class Pointer>
322     struct operator_arrow_dispatch // proxy references
323     {
324         struct proxy
325         {
326             explicit proxy(Reference const & x) : m_ref(x) {}
327             Reference* operator->() { return boost::addressof(m_ref); }
328             // This function is needed for MWCW and BCC, which won't call
329             // operator-> again automatically per 13.3.1.2 para 8
330             operator Reference*() { return boost::addressof(m_ref); }
331             Reference m_ref;
332         };
333         typedef proxy result_type;
334         static result_type apply(Reference const & x)
335         {
336             return result_type(x);
337         }
338     };
339
340     template <class T, class Pointer>
341     struct operator_arrow_dispatch<T&, Pointer> // "real" references
342     {
343         typedef Pointer result_type;
344         static result_type apply(T& x)
345         {
346             return boost::addressof(x);
347         }
348     };
349
350     // A proxy return type for operator[], needed to deal with
351     // iterators that may invalidate referents upon destruction.
352     // Consider the temporary iterator in *(a + n)
353     template <class Iterator>
354     class operator_brackets_proxy
355     {
356         // Iterator is actually an iterator_facade, so we do not have to
357         // go through iterator_traits to access the traits.
358         typedef typename Iterator::reference  reference;
359         typedef typename Iterator::value_type value_type;
360
361      public:
362         operator_brackets_proxy(Iterator const& iter)
363           : m_iter(iter)
364         {}
365
366         operator reference() const
367         {
368             return *m_iter;
369         }
370
371         operator_brackets_proxy& operator=(value_type const& val)
372         {
373             *m_iter = val;
374             return *this;
375         }
376
377      private:
378         Iterator m_iter;
379     };
380
381     // A metafunction that determines whether operator[] must return a
382     // proxy, or whether it can simply return a copy of the value_type.
383     template <class ValueType, class Reference>
384     struct use_operator_brackets_proxy
385       : mpl::not_<
386             mpl::and_<
387                 // Really we want an is_copy_constructible trait here,
388                 // but is_POD will have to suffice in the meantime.
389                 boost::is_POD<ValueType>
390               , iterator_writability_disabled<ValueType,Reference>
391             >
392         >
393     {};
394
395     template <class Iterator, class Value, class Reference>
396     struct operator_brackets_result
397     {
398         typedef typename mpl::if_<
399             use_operator_brackets_proxy<Value,Reference>
400           , operator_brackets_proxy<Iterator>
401           , Value
402         >::type type;
403     };
404
405     template <class Iterator>
406     operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::true_)
407     {
408         return operator_brackets_proxy<Iterator>(iter);
409     }
410
411     template <class Iterator>
412     typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_)
413     {
414       return *iter;
415     }
416
417     struct choose_difference_type
418     {
419         template <class I1, class I2>
420         struct apply
421           :
422 # ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
423           iterator_difference<I1>
424 # else
425           mpl::eval_if<
426               is_convertible<I2,I1>
427             , iterator_difference<I1>
428             , iterator_difference<I2>
429           >
430 # endif
431         {};
432
433     };
434
435     template <
436         class Derived
437       , class Value
438       , class CategoryOrTraversal
439       , class Reference
440       , class Difference
441       , bool IsBidirectionalTraversal
442       , bool IsRandomAccessTraversal
443     >
444     class iterator_facade_base;
445
446   } // namespace detail
447
448
449   // Macros which describe the declarations of binary operators
450 # ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
451 #  define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler)       \
452     template <                                                              \
453         class Derived1, class V1, class TC1, class Reference1, class Difference1 \
454       , class Derived2, class V2, class TC2, class Reference2, class Difference2 \
455     >                                                                       \
456     prefix typename mpl::apply2<result_type,Derived1,Derived2>::type \
457     operator op(                                                            \
458         iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs   \
459       , iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
460 # else
461 #  define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler)   \
462     template <                                                          \
463         class Derived1, class V1, class TC1, class Reference1, class Difference1 \
464       , class Derived2, class V2, class TC2, class Reference2, class Difference2 \
465     >                                                                   \
466     prefix typename enabler<                                            \
467         Derived1, Derived2                                              \
468       , typename mpl::apply2<result_type,Derived1,Derived2>::type       \
469     >::type                                                             \
470     operator op(                                                        \
471         iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs   \
472       , iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
473 # endif
474
475 #  define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type)       \
476     BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable)
477
478 #  define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(prefix, op, result_type)       \
479     BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable_and_random_access_traversal)
480
481 #  define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args)              \
482     template <class Derived, class V, class TC, class R, class D>   \
483     prefix typename boost::iterators::enable_if<                    \
484         boost::iterators::detail::is_traversal_at_least< TC, boost::iterators::random_access_traversal_tag >,  \
485         Derived                                                     \
486     >::type operator+ args
487
488   //
489   // Helper class for granting access to the iterator core interface.
490   //
491   // The simple core interface is used by iterator_facade. The core
492   // interface of a user/library defined iterator type should not be made public
493   // so that it does not clutter the public interface. Instead iterator_core_access
494   // should be made friend so that iterator_facade can access the core
495   // interface through iterator_core_access.
496   //
497   class iterator_core_access
498   {
499 # if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
500       // Tasteless as this may seem, making all members public allows member templates
501       // to work in the absence of member template friends.
502    public:
503 # else
504
505       template <class I, class V, class TC, class R, class D> friend class iterator_facade;
506       template <class I, class V, class TC, class R, class D, bool IsBidirectionalTraversal, bool IsRandomAccessTraversal>
507       friend class detail::iterator_facade_base;
508
509 #  define BOOST_ITERATOR_FACADE_RELATION(op)                                \
510       BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, boost::iterators::detail::always_bool2);
511
512       BOOST_ITERATOR_FACADE_RELATION(==)
513       BOOST_ITERATOR_FACADE_RELATION(!=)
514
515 #  undef BOOST_ITERATOR_FACADE_RELATION
516
517 #  define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op)                                \
518       BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend,op, boost::iterators::detail::always_bool2);
519
520       BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<)
521       BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>)
522       BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=)
523       BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=)
524
525 #  undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
526
527       BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(
528           friend, -, boost::iterators::detail::choose_difference_type)
529       ;
530
531       BOOST_ITERATOR_FACADE_PLUS_HEAD(
532           friend inline
533         , (iterator_facade<Derived, V, TC, R, D> const&
534         , typename Derived::difference_type)
535       )
536       ;
537
538       BOOST_ITERATOR_FACADE_PLUS_HEAD(
539           friend inline
540         , (typename Derived::difference_type
541         , iterator_facade<Derived, V, TC, R, D> const&)
542       )
543       ;
544
545 # endif
546
547       template <class Facade>
548       static typename Facade::reference dereference(Facade const& f)
549       {
550           return f.dereference();
551       }
552
553       template <class Facade>
554       static void increment(Facade& f)
555       {
556           f.increment();
557       }
558
559       template <class Facade>
560       static void decrement(Facade& f)
561       {
562           f.decrement();
563       }
564
565       template <class Facade1, class Facade2>
566       static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::true_)
567       {
568           return f1.equal(f2);
569       }
570
571       template <class Facade1, class Facade2>
572       static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::false_)
573       {
574           return f2.equal(f1);
575       }
576
577       template <class Facade>
578       static void advance(Facade& f, typename Facade::difference_type n)
579       {
580           f.advance(n);
581       }
582
583       template <class Facade1, class Facade2>
584       static typename Facade1::difference_type distance_from(
585           Facade1 const& f1, Facade2 const& f2, mpl::true_)
586       {
587           return -f1.distance_to(f2);
588       }
589
590       template <class Facade1, class Facade2>
591       static typename Facade2::difference_type distance_from(
592           Facade1 const& f1, Facade2 const& f2, mpl::false_)
593       {
594           return f2.distance_to(f1);
595       }
596
597       //
598       // Curiously Recurring Template interface.
599       //
600       template <class I, class V, class TC, class R, class D>
601       static I& derived(iterator_facade<I,V,TC,R,D>& facade)
602       {
603           return *static_cast<I*>(&facade);
604       }
605
606       template <class I, class V, class TC, class R, class D>
607       static I const& derived(iterator_facade<I,V,TC,R,D> const& facade)
608       {
609           return *static_cast<I const*>(&facade);
610       }
611
612       // objects of this class are useless
613       BOOST_DELETED_FUNCTION(iterator_core_access())
614   };
615
616   namespace detail {
617
618     // Implementation for forward traversal iterators
619     template <
620         class Derived
621       , class Value
622       , class CategoryOrTraversal
623       , class Reference
624       , class Difference
625     >
626     class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
627 # ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
628         : public boost::iterators::detail::iterator_facade_types<
629              Value, CategoryOrTraversal, Reference, Difference
630           >::base
631 #  undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
632 # endif
633     {
634     private:
635         typedef boost::iterators::detail::iterator_facade_types<
636             Value, CategoryOrTraversal, Reference, Difference
637         > associated_types;
638
639         typedef boost::iterators::detail::operator_arrow_dispatch<
640             Reference
641           , typename associated_types::pointer
642         > operator_arrow_dispatch_;
643
644     public:
645         typedef typename associated_types::value_type value_type;
646         typedef Reference reference;
647         typedef Difference difference_type;
648
649         typedef typename operator_arrow_dispatch_::result_type pointer;
650
651         typedef typename associated_types::iterator_category iterator_category;
652
653     public:
654         reference operator*() const
655         {
656             return iterator_core_access::dereference(this->derived());
657         }
658
659         pointer operator->() const
660         {
661             return operator_arrow_dispatch_::apply(*this->derived());
662         }
663
664         Derived& operator++()
665         {
666             iterator_core_access::increment(this->derived());
667             return this->derived();
668         }
669
670     protected:
671         //
672         // Curiously Recurring Template interface.
673         //
674         Derived& derived()
675         {
676             return *static_cast<Derived*>(this);
677         }
678
679         Derived const& derived() const
680         {
681             return *static_cast<Derived const*>(this);
682         }
683     };
684
685     // Implementation for bidirectional traversal iterators
686     template <
687         class Derived
688       , class Value
689       , class CategoryOrTraversal
690       , class Reference
691       , class Difference
692     >
693     class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > :
694         public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
695     {
696     public:
697         Derived& operator--()
698         {
699             iterator_core_access::decrement(this->derived());
700             return this->derived();
701         }
702
703         Derived operator--(int)
704         {
705             Derived tmp(this->derived());
706             --*this;
707             return tmp;
708         }
709     };
710
711     // Implementation for random access traversal iterators
712     template <
713         class Derived
714       , class Value
715       , class CategoryOrTraversal
716       , class Reference
717       , class Difference
718     >
719     class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, true > :
720         public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >
721     {
722     private:
723         typedef iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > base_type;
724
725     public:
726         typedef typename base_type::reference reference;
727         typedef typename base_type::difference_type difference_type;
728
729     public:
730         typename boost::iterators::detail::operator_brackets_result<Derived, Value, reference>::type
731         operator[](difference_type n) const
732         {
733             typedef boost::iterators::detail::use_operator_brackets_proxy<Value, Reference> use_proxy;
734
735             return boost::iterators::detail::make_operator_brackets_result<Derived>(
736                 this->derived() + n
737               , use_proxy()
738             );
739         }
740
741         Derived& operator+=(difference_type n)
742         {
743             iterator_core_access::advance(this->derived(), n);
744             return this->derived();
745         }
746
747         Derived& operator-=(difference_type n)
748         {
749             iterator_core_access::advance(this->derived(), -n);
750             return this->derived();
751         }
752
753         Derived operator-(difference_type x) const
754         {
755             Derived result(this->derived());
756             return result -= x;
757         }
758     };
759
760   } // namespace detail
761
762   //
763   // iterator_facade - use as a public base class for defining new
764   // standard-conforming iterators.
765   //
766   template <
767       class Derived             // The derived iterator type being constructed
768     , class Value
769     , class CategoryOrTraversal
770     , class Reference   = Value&
771     , class Difference  = std::ptrdiff_t
772   >
773   class iterator_facade :
774       public detail::iterator_facade_base<
775           Derived,
776           Value,
777           CategoryOrTraversal,
778           Reference,
779           Difference,
780           detail::is_traversal_at_least< CategoryOrTraversal, bidirectional_traversal_tag >::value,
781           detail::is_traversal_at_least< CategoryOrTraversal, random_access_traversal_tag >::value
782       >
783   {
784   protected:
785       // For use by derived classes
786       typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_;
787   };
788
789   template <class I, class V, class TC, class R, class D>
790   inline typename boost::iterators::detail::postfix_increment_result<I,V,R,TC>::type
791   operator++(
792       iterator_facade<I,V,TC,R,D>& i
793     , int
794   )
795   {
796       typename boost::iterators::detail::postfix_increment_result<I,V,R,TC>::type
797           tmp(*static_cast<I*>(&i));
798
799       ++i;
800
801       return tmp;
802   }
803
804
805   //
806   // Comparison operator implementation. The library supplied operators
807   // enables the user to provide fully interoperable constant/mutable
808   // iterator types. I.e. the library provides all operators
809   // for all mutable/constant iterator combinations.
810   //
811   // Note though that this kind of interoperability for constant/mutable
812   // iterators is not required by the standard for container iterators.
813   // All the standard asks for is a conversion mutable -> constant.
814   // Most standard library implementations nowadays provide fully interoperable
815   // iterator implementations, but there are still heavily used implementations
816   // that do not provide them. (Actually it's even worse, they do not provide
817   // them for only a few iterators.)
818   //
819   // ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should
820   //    enable the user to turn off mixed type operators
821   //
822   // The library takes care to provide only the right operator overloads.
823   // I.e.
824   //
825   // bool operator==(Iterator,      Iterator);
826   // bool operator==(ConstIterator, Iterator);
827   // bool operator==(Iterator,      ConstIterator);
828   // bool operator==(ConstIterator, ConstIterator);
829   //
830   //   ...
831   //
832   // In order to do so it uses c++ idioms that are not yet widely supported
833   // by current compiler releases. The library is designed to degrade gracefully
834   // in the face of compiler deficiencies. In general compiler
835   // deficiencies result in less strict error checking and more obscure
836   // error messages, functionality is not affected.
837   //
838   // For full operation compiler support for "Substitution Failure Is Not An Error"
839   // (aka. enable_if) and boost::is_convertible is required.
840   //
841   // The following problems occur if support is lacking.
842   //
843   // Pseudo code
844   //
845   // ---------------
846   // AdaptorA<Iterator1> a1;
847   // AdaptorA<Iterator2> a2;
848   //
849   // // This will result in a no such overload error in full operation
850   // // If enable_if or is_convertible is not supported
851   // // The instantiation will fail with an error hopefully indicating that
852   // // there is no operator== for Iterator1, Iterator2
853   // // The same will happen if no enable_if is used to remove
854   // // false overloads from the templated conversion constructor
855   // // of AdaptorA.
856   //
857   // a1 == a2;
858   // ----------------
859   //
860   // AdaptorA<Iterator> a;
861   // AdaptorB<Iterator> b;
862   //
863   // // This will result in a no such overload error in full operation
864   // // If enable_if is not supported the static assert used
865   // // in the operator implementation will fail.
866   // // This will accidently work if is_convertible is not supported.
867   //
868   // a == b;
869   // ----------------
870   //
871
872 # ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
873 #  define BOOST_ITERATOR_CONVERTIBLE(a,b) mpl::true_()
874 # else
875 #  define BOOST_ITERATOR_CONVERTIBLE(a,b) is_convertible<a,b>()
876 # endif
877
878 # define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op) \
879   BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type)                   \
880   {                                                                             \
881       /* For those compilers that do not support enable_if */                   \
882       BOOST_STATIC_ASSERT((                                                     \
883           is_interoperable< Derived1, Derived2 >::value                         \
884       ));                                                                       \
885       return_prefix iterator_core_access::base_op(                              \
886           *static_cast<Derived1 const*>(&lhs)                                   \
887         , *static_cast<Derived2 const*>(&rhs)                                   \
888         , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1)                         \
889       );                                                                        \
890   }
891
892 # define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
893   BOOST_ITERATOR_FACADE_INTEROP(                                    \
894       op                                                            \
895     , boost::iterators::detail::always_bool2                                   \
896     , return_prefix                                                 \
897     , base_op                                                       \
898   )
899
900   BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
901   BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
902
903 # undef BOOST_ITERATOR_FACADE_RELATION
904
905
906 # define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(op, result_type, return_prefix, base_op) \
907   BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(inline, op, result_type)                   \
908   {                                                                             \
909       /* For those compilers that do not support enable_if */                   \
910       BOOST_STATIC_ASSERT((                                                     \
911           is_interoperable< Derived1, Derived2 >::value &&                      \
912           boost::iterators::detail::is_traversal_at_least< typename iterator_category< Derived1 >::type, random_access_traversal_tag >::value && \
913           boost::iterators::detail::is_traversal_at_least< typename iterator_category< Derived2 >::type, random_access_traversal_tag >::value \
914       ));                                                                       \
915       return_prefix iterator_core_access::base_op(                              \
916           *static_cast<Derived1 const*>(&lhs)                                   \
917         , *static_cast<Derived2 const*>(&rhs)                                   \
918         , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1)                         \
919       );                                                                        \
920   }
921
922 # define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op, return_prefix, base_op) \
923   BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(                                    \
924       op                                                            \
925     , boost::iterators::detail::always_bool2                                   \
926     , return_prefix                                                 \
927     , base_op                                                       \
928   )
929
930   BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<, return 0 >, distance_from)
931   BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>, return 0 <, distance_from)
932   BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=, return 0 >=, distance_from)
933   BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=, return 0 <=, distance_from)
934
935 # undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
936
937   // operator- requires an additional part in the static assertion
938   BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(
939       -
940     , boost::iterators::detail::choose_difference_type
941     , return
942     , distance_from
943   )
944
945 # undef BOOST_ITERATOR_FACADE_INTEROP
946 # undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS
947
948 # define BOOST_ITERATOR_FACADE_PLUS(args)           \
949   BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args)     \
950   {                                                 \
951       Derived tmp(static_cast<Derived const&>(i));  \
952       return tmp += n;                              \
953   }
954
955   BOOST_ITERATOR_FACADE_PLUS((
956       iterator_facade<Derived, V, TC, R, D> const& i
957     , typename Derived::difference_type n
958   ))
959
960   BOOST_ITERATOR_FACADE_PLUS((
961       typename Derived::difference_type n
962     , iterator_facade<Derived, V, TC, R, D> const& i
963   ))
964
965 # undef BOOST_ITERATOR_FACADE_PLUS
966 # undef BOOST_ITERATOR_FACADE_PLUS_HEAD
967
968 # undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
969 # undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD
970 # undef BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL
971
972 } // namespace iterators
973
974 using iterators::iterator_core_access;
975 using iterators::iterator_facade;
976
977 } // namespace boost
978
979 #include <boost/iterator/detail/config_undef.hpp>
980
981 #endif // BOOST_ITERATOR_FACADE_23022003THW_HPP