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