epoc32/include/stdapis/boost/iterator/iterator_facade.hpp
author William Roberts <williamr@symbian.org>
Tue, 16 Mar 2010 16:12:26 +0000
branchSymbian2
changeset 2 2fe1408b6811
permissions -rw-r--r--
Final list of Symbian^2 public API header files
     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             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 R1, class D1             \
   437       , class Derived2, class V2, class TC2, class R2, class D2             \
   438     >                                                                       \
   439     prefix typename mpl::apply2<result_type,Derived1,Derived2>::type \
   440     operator op(                                                            \
   441         iterator_facade<Derived1, V1, TC1, R1, D1> const& lhs               \
   442       , iterator_facade<Derived2, V2, TC2, R2, D2> 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 R1, class D1         \
   447       , class Derived2, class V2, class TC2, class R2, class D2         \
   448     >                                                                   \
   449     prefix typename 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, R1, D1> const& lhs           \
   455       , iterator_facade<Derived2, V2, TC2, R2, D2> 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     || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
   475       // Tasteless as this may seem, making all members public allows member templates
   476       // to work in the absence of member template friends.
   477    public:
   478 # else
   479       
   480       template <class I, class V, class TC, class R, class D> friend class iterator_facade;
   481 
   482 #  define BOOST_ITERATOR_FACADE_RELATION(op)                                \
   483       BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, detail::always_bool2);
   484 
   485       BOOST_ITERATOR_FACADE_RELATION(==)
   486       BOOST_ITERATOR_FACADE_RELATION(!=)
   487 
   488       BOOST_ITERATOR_FACADE_RELATION(<)
   489       BOOST_ITERATOR_FACADE_RELATION(>)
   490       BOOST_ITERATOR_FACADE_RELATION(<=)
   491       BOOST_ITERATOR_FACADE_RELATION(>=)
   492 #  undef BOOST_ITERATOR_FACADE_RELATION
   493 
   494       BOOST_ITERATOR_FACADE_INTEROP_HEAD(
   495           friend, -, detail::choose_difference_type)
   496       ;
   497 
   498       BOOST_ITERATOR_FACADE_PLUS_HEAD(
   499           friend inline
   500           , (iterator_facade<Derived, V, TC, R, D> const&
   501            , typename Derived::difference_type)
   502       )
   503       ;
   504 
   505       BOOST_ITERATOR_FACADE_PLUS_HEAD(
   506           friend inline
   507         , (typename Derived::difference_type
   508            , iterator_facade<Derived, V, TC, R, D> const&)
   509       )
   510       ;
   511 
   512 # endif
   513 
   514       template <class Facade>
   515       static typename Facade::reference dereference(Facade const& f)
   516       {
   517           return f.dereference();
   518       }
   519 
   520       template <class Facade>
   521       static void increment(Facade& f)
   522       {
   523           f.increment();
   524       }
   525 
   526       template <class Facade>
   527       static void decrement(Facade& f)
   528       {
   529           f.decrement();
   530       }
   531 
   532       template <class Facade1, class Facade2>
   533       static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::true_)
   534       {
   535           return f1.equal(f2);
   536       }
   537 
   538       template <class Facade1, class Facade2>
   539       static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::false_)
   540       {
   541           return f2.equal(f1);
   542       }
   543 
   544       template <class Facade>
   545       static void advance(Facade& f, typename Facade::difference_type n)
   546       {
   547           f.advance(n);
   548       }
   549 
   550       template <class Facade1, class Facade2>
   551       static typename Facade1::difference_type distance_from(
   552           Facade1 const& f1, Facade2 const& f2, mpl::true_)
   553       {
   554           return -f1.distance_to(f2);
   555       }
   556 
   557       template <class Facade1, class Facade2>
   558       static typename Facade2::difference_type distance_from(
   559           Facade1 const& f1, Facade2 const& f2, mpl::false_)
   560       {
   561           return f2.distance_to(f1);
   562       }
   563 
   564       //
   565       // Curiously Recurring Template interface.
   566       //
   567       template <class I, class V, class TC, class R, class D>
   568       static I& derived(iterator_facade<I,V,TC,R,D>& facade)
   569       {
   570           return *static_cast<I*>(&facade);
   571       }
   572 
   573       template <class I, class V, class TC, class R, class D>
   574       static I const& derived(iterator_facade<I,V,TC,R,D> const& facade)
   575       {
   576           return *static_cast<I const*>(&facade);
   577       }
   578 
   579    private:
   580       // objects of this class are useless
   581       iterator_core_access(); //undefined
   582   };
   583 
   584   //
   585   // iterator_facade - use as a public base class for defining new
   586   // standard-conforming iterators.
   587   //
   588   template <
   589       class Derived             // The derived iterator type being constructed
   590     , class Value
   591     , class CategoryOrTraversal
   592     , class Reference   = Value&
   593     , class Difference  = std::ptrdiff_t
   594   >
   595   class iterator_facade
   596 # ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
   597     : public detail::iterator_facade_types<
   598          Value, CategoryOrTraversal, Reference, Difference
   599       >::base
   600 #  undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
   601 # endif
   602   {
   603    private:
   604       //
   605       // Curiously Recurring Template interface.
   606       //
   607       Derived& derived()
   608       {
   609           return *static_cast<Derived*>(this);
   610       }
   611 
   612       Derived const& derived() const
   613       {
   614           return *static_cast<Derived const*>(this);
   615       }
   616 
   617       typedef detail::iterator_facade_types<
   618          Value, CategoryOrTraversal, Reference, Difference
   619       > associated_types;
   620 
   621    protected:
   622       // For use by derived classes
   623       typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_;
   624       
   625    public:
   626 
   627       typedef typename associated_types::value_type value_type;
   628       typedef Reference reference;
   629       typedef Difference difference_type;
   630       typedef typename associated_types::pointer pointer;
   631       typedef typename associated_types::iterator_category iterator_category;
   632 
   633       reference operator*() const
   634       {
   635           return iterator_core_access::dereference(this->derived());
   636       }
   637 
   638       typename detail::operator_arrow_result<
   639           value_type
   640         , reference
   641         , pointer
   642       >::type
   643       operator->() const
   644       {
   645           return detail::operator_arrow_result<
   646               value_type
   647             , reference
   648             , pointer
   649           >::make(*this->derived());
   650       }
   651         
   652       typename detail::operator_brackets_result<Derived,Value,reference>::type
   653       operator[](difference_type n) const
   654       {
   655           typedef detail::use_operator_brackets_proxy<Value,Reference> use_proxy;
   656           
   657           return detail::make_operator_brackets_result<Derived>(
   658               this->derived() + n
   659             , use_proxy()
   660           );
   661       }
   662 
   663       Derived& operator++()
   664       {
   665           iterator_core_access::increment(this->derived());
   666           return this->derived();
   667       }
   668 
   669 # if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
   670       typename detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
   671       operator++(int)
   672       {
   673           typename detail::postfix_increment_result<Derived,Value,Reference,CategoryOrTraversal>::type
   674           tmp(this->derived());
   675           ++*this;
   676           return tmp;
   677       }
   678 # endif
   679       
   680       Derived& operator--()
   681       {
   682           iterator_core_access::decrement(this->derived());
   683           return this->derived();
   684       }
   685 
   686       Derived operator--(int)
   687       {
   688           Derived tmp(this->derived());
   689           --*this;
   690           return tmp;
   691       }
   692 
   693       Derived& operator+=(difference_type n)
   694       {
   695           iterator_core_access::advance(this->derived(), n);
   696           return this->derived();
   697       }
   698 
   699       Derived& operator-=(difference_type n)
   700       {
   701           iterator_core_access::advance(this->derived(), -n);
   702           return this->derived();
   703       }
   704 
   705       Derived operator-(difference_type x) const
   706       {
   707           Derived result(this->derived());
   708           return result -= x;
   709       }
   710 
   711 # if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
   712       // There appears to be a bug which trashes the data of classes
   713       // derived from iterator_facade when they are assigned unless we
   714       // define this assignment operator.  This bug is only revealed
   715       // (so far) in STLPort debug mode, but it's clearly a codegen
   716       // problem so we apply the workaround for all MSVC6.
   717       iterator_facade& operator=(iterator_facade const&)
   718       {
   719           return *this;
   720       }
   721 # endif
   722   };
   723 
   724 # if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
   725   template <class I, class V, class TC, class R, class D>
   726   inline typename detail::postfix_increment_result<I,V,R,TC>::type
   727   operator++(
   728       iterator_facade<I,V,TC,R,D>& i
   729     , int
   730   )
   731   {
   732       typename detail::postfix_increment_result<I,V,R,TC>::type
   733           tmp(*static_cast<I*>(&i));
   734       
   735       ++i;
   736       
   737       return tmp;
   738   }
   739 # endif 
   740 
   741   
   742   //
   743   // Comparison operator implementation. The library supplied operators
   744   // enables the user to provide fully interoperable constant/mutable
   745   // iterator types. I.e. the library provides all operators
   746   // for all mutable/constant iterator combinations.
   747   //
   748   // Note though that this kind of interoperability for constant/mutable
   749   // iterators is not required by the standard for container iterators.
   750   // All the standard asks for is a conversion mutable -> constant.
   751   // Most standard library implementations nowadays provide fully interoperable
   752   // iterator implementations, but there are still heavily used implementations
   753   // that do not provide them. (Actually it's even worse, they do not provide
   754   // them for only a few iterators.)
   755   //
   756   // ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should
   757   //    enable the user to turn off mixed type operators
   758   //
   759   // The library takes care to provide only the right operator overloads.
   760   // I.e.
   761   //
   762   // bool operator==(Iterator,      Iterator);
   763   // bool operator==(ConstIterator, Iterator);
   764   // bool operator==(Iterator,      ConstIterator);
   765   // bool operator==(ConstIterator, ConstIterator);
   766   //
   767   //   ...
   768   //
   769   // In order to do so it uses c++ idioms that are not yet widely supported
   770   // by current compiler releases. The library is designed to degrade gracefully
   771   // in the face of compiler deficiencies. In general compiler
   772   // deficiencies result in less strict error checking and more obscure
   773   // error messages, functionality is not affected.
   774   //
   775   // For full operation compiler support for "Substitution Failure Is Not An Error"
   776   // (aka. enable_if) and boost::is_convertible is required.
   777   //
   778   // The following problems occur if support is lacking.
   779   //
   780   // Pseudo code
   781   //
   782   // ---------------
   783   // AdaptorA<Iterator1> a1;
   784   // AdaptorA<Iterator2> a2;
   785   //
   786   // // This will result in a no such overload error in full operation
   787   // // If enable_if or is_convertible is not supported
   788   // // The instantiation will fail with an error hopefully indicating that
   789   // // there is no operator== for Iterator1, Iterator2
   790   // // The same will happen if no enable_if is used to remove
   791   // // false overloads from the templated conversion constructor
   792   // // of AdaptorA.
   793   //
   794   // a1 == a2;
   795   // ----------------
   796   //
   797   // AdaptorA<Iterator> a;
   798   // AdaptorB<Iterator> b;
   799   //
   800   // // This will result in a no such overload error in full operation
   801   // // If enable_if is not supported the static assert used
   802   // // in the operator implementation will fail.
   803   // // This will accidently work if is_convertible is not supported.
   804   //
   805   // a == b;
   806   // ----------------
   807   //
   808 
   809 # ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
   810 #  define BOOST_ITERATOR_CONVERTIBLE(a,b) mpl::true_()
   811 # else
   812 #  define BOOST_ITERATOR_CONVERTIBLE(a,b) is_convertible<a,b>()
   813 # endif
   814 
   815 # define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op) \
   816   BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type)                   \
   817   {                                                                             \
   818       /* For those compilers that do not support enable_if */                   \
   819       BOOST_STATIC_ASSERT((                                                     \
   820           is_interoperable< Derived1, Derived2 >::value                         \
   821       ));                                                                       \
   822       return_prefix iterator_core_access::base_op(                              \
   823           *static_cast<Derived1 const*>(&lhs)                                   \
   824         , *static_cast<Derived2 const*>(&rhs)                                   \
   825         , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1)                         \
   826       );                                                                        \
   827   }
   828 
   829 # define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
   830   BOOST_ITERATOR_FACADE_INTEROP(                                    \
   831       op                                                            \
   832     , detail::always_bool2                                          \
   833     , return_prefix                                                 \
   834     , base_op                                                       \
   835   )
   836 
   837   BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
   838   BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
   839 
   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   BOOST_ITERATOR_FACADE_RELATION(>=, return 0 <=, distance_from)
   844 # undef BOOST_ITERATOR_FACADE_RELATION
   845 
   846   // operator- requires an additional part in the static assertion
   847   BOOST_ITERATOR_FACADE_INTEROP(
   848       -
   849     , detail::choose_difference_type
   850     , return
   851     , distance_from
   852   )
   853 # undef BOOST_ITERATOR_FACADE_INTEROP
   854 # undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
   855 
   856 # define BOOST_ITERATOR_FACADE_PLUS(args)           \
   857   BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args)     \
   858   {                                                 \
   859       Derived tmp(static_cast<Derived const&>(i));  \
   860       return tmp += n;                              \
   861   }
   862 
   863 BOOST_ITERATOR_FACADE_PLUS((
   864   iterator_facade<Derived, V, TC, R, D> const& i
   865   , typename Derived::difference_type n
   866 ))
   867 
   868 BOOST_ITERATOR_FACADE_PLUS((
   869     typename Derived::difference_type n
   870     , iterator_facade<Derived, V, TC, R, D> const& i
   871 ))
   872 # undef BOOST_ITERATOR_FACADE_PLUS
   873 # undef BOOST_ITERATOR_FACADE_PLUS_HEAD
   874 
   875 } // namespace boost
   876 
   877 #include <boost/iterator/detail/config_undef.hpp>
   878 
   879 #endif // BOOST_ITERATOR_FACADE_23022003THW_HPP