New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
iterator_facade.hpp in vendors/XIOS/current/extern/boost/include/boost/iterator – NEMO

source: vendors/XIOS/current/extern/boost/include/boost/iterator/iterator_facade.hpp @ 3408

Last change on this file since 3408 was 3408, checked in by rblod, 12 years ago

importing initial XIOS vendor drop

  • Property svn:keywords set to Id
File size: 28.5 KB
Line 
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
39namespace 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
862BOOST_ITERATOR_FACADE_PLUS((
863  iterator_facade<Derived, V, TC, R, D> const& i
864  , typename Derived::difference_type n
865))
866
867BOOST_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
Note: See TracBrowser for help on using the repository browser.