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