epoc32/include/stdapis/boost/iterator/iterator_adaptor.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
     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_ADAPTOR_23022003THW_HPP
     8 #define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
     9 
    10 #include <boost/static_assert.hpp>
    11 #include <boost/iterator.hpp>
    12 #include <boost/detail/iterator.hpp>
    13 
    14 #include <boost/iterator/iterator_categories.hpp>
    15 #include <boost/iterator/iterator_facade.hpp>
    16 #include <boost/iterator/detail/enable_if.hpp>
    17 
    18 #include <boost/mpl/and.hpp>
    19 #include <boost/mpl/not.hpp>
    20 #include <boost/mpl/or.hpp>
    21 
    22 #include <boost/type_traits/is_same.hpp>
    23 #include <boost/type_traits/is_convertible.hpp>
    24 
    25 #ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
    26 # include <boost/type_traits/remove_reference.hpp>
    27 #else 
    28 # include <boost/type_traits/add_reference.hpp>
    29 #endif 
    30 
    31 #include <boost/iterator/detail/config_def.hpp>
    32 
    33 #include <boost/iterator/iterator_traits.hpp>
    34 
    35 namespace boost
    36 {
    37   // Used as a default template argument internally, merely to
    38   // indicate "use the default", this can also be passed by users
    39   // explicitly in order to specify that the default should be used.
    40   struct use_default;
    41   
    42 # ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
    43   // the incompleteness of use_default causes massive problems for
    44   // is_convertible (naturally).  This workaround is fortunately not
    45   // needed for vc6/vc7.
    46   template<class To>
    47   struct is_convertible<use_default,To>
    48     : mpl::false_ {};
    49 # endif 
    50   
    51   namespace detail
    52   {
    53 
    54     // 
    55     // Result type used in enable_if_convertible meta function.
    56     // This can be an incomplete type, as only pointers to 
    57     // enable_if_convertible< ... >::type are used.
    58     // We could have used void for this, but conversion to
    59     // void* is just to easy.
    60     //
    61     struct enable_type;
    62   }
    63 
    64 
    65   //
    66   // enable_if for use in adapted iterators constructors.
    67   //
    68   // In order to provide interoperability between adapted constant and
    69   // mutable iterators, adapted iterators will usually provide templated
    70   // conversion constructors of the following form
    71   //
    72   // template <class BaseIterator>
    73   // class adapted_iterator :
    74   //   public iterator_adaptor< adapted_iterator<Iterator>, Iterator >
    75   // {
    76   // public:
    77   //   
    78   //   ...
    79   //
    80   //   template <class OtherIterator>
    81   //   adapted_iterator(
    82   //       OtherIterator const& it
    83   //     , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0);
    84   //
    85   //   ...
    86   // };
    87   //
    88   // enable_if_convertible is used to remove those overloads from the overload
    89   // set that cannot be instantiated. For all practical purposes only overloads
    90   // for constant/mutable interaction will remain. This has the advantage that
    91   // meta functions like boost::is_convertible do not return false positives,
    92   // as they can only look at the signature of the conversion constructor
    93   // and not at the actual instantiation.
    94   //
    95   // enable_if_interoperable can be safely used in user code. It falls back to
    96   // always enabled for compilers that don't support enable_if or is_convertible. 
    97   // There is no need for compiler specific workarounds in user code. 
    98   //
    99   // The operators implementation relies on boost::is_convertible not returning
   100   // false positives for user/library defined iterator types. See comments
   101   // on operator implementation for consequences.
   102   //
   103 #  if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
   104   
   105   template<typename From, typename To>
   106   struct enable_if_convertible
   107   {
   108      typedef typename mpl::if_<
   109          mpl::or_<
   110              is_same<From,To>
   111            , is_convertible<From, To>
   112          >
   113       , detail::enable_type
   114       , int&
   115      >::type type;
   116   };
   117   
   118 #  elif defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE)
   119   
   120   template <class From, class To>
   121   struct enable_if_convertible
   122   {
   123       typedef detail::enable_type type;
   124   };
   125   
   126 #  elif BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292)) && BOOST_MSVC > 1300
   127   
   128   // For some reason vc7.1 needs us to "cut off" instantiation
   129   // of is_convertible in a few cases.
   130   template<typename From, typename To>
   131   struct enable_if_convertible
   132     : iterators::enable_if<
   133         mpl::or_<
   134             is_same<From,To>
   135           , is_convertible<From, To>
   136         >
   137       , detail::enable_type
   138     >
   139   {};
   140   
   141 #  else 
   142   
   143   template<typename From, typename To>
   144   struct enable_if_convertible
   145     : iterators::enable_if<
   146           is_convertible<From, To>
   147         , detail::enable_type
   148       >
   149   {};
   150       
   151 # endif
   152   
   153   //
   154   // Default template argument handling for iterator_adaptor
   155   //
   156   namespace detail
   157   {
   158     // If T is use_default, return the result of invoking
   159     // DefaultNullaryFn, otherwise return T.
   160     template <class T, class DefaultNullaryFn>
   161     struct ia_dflt_help
   162       : mpl::eval_if<
   163             is_same<T, use_default>
   164           , DefaultNullaryFn
   165           , mpl::identity<T>
   166         >
   167     {
   168     };
   169 
   170     // A metafunction which computes an iterator_adaptor's base class,
   171     // a specialization of iterator_facade.
   172     template <
   173         class Derived
   174       , class Base
   175       , class Value
   176       , class Traversal
   177       , class Reference
   178       , class Difference
   179     >
   180     struct iterator_adaptor_base
   181     {
   182         typedef iterator_facade<
   183             Derived
   184             
   185 # ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
   186           , typename detail::ia_dflt_help<
   187                 Value
   188               , mpl::eval_if<
   189                     is_same<Reference,use_default>
   190                   , iterator_value<Base>
   191                   , remove_reference<Reference>
   192                 >
   193             >::type
   194 # else
   195           , typename detail::ia_dflt_help<
   196                 Value, iterator_value<Base>
   197             >::type
   198 # endif
   199             
   200           , typename detail::ia_dflt_help<
   201                 Traversal
   202               , iterator_traversal<Base>
   203             >::type
   204 
   205           , typename detail::ia_dflt_help<
   206                 Reference
   207               , mpl::eval_if<
   208                     is_same<Value,use_default>
   209                   , iterator_reference<Base>
   210                   , add_reference<Value>
   211                 >
   212             >::type
   213 
   214           , typename detail::ia_dflt_help<
   215                 Difference, iterator_difference<Base>
   216             >::type
   217         >
   218         type;
   219     };
   220   
   221     // workaround for aC++ CR JAGaf33512
   222     template <class Tr1, class Tr2>
   223     inline void iterator_adaptor_assert_traversal ()
   224     {
   225       BOOST_STATIC_ASSERT((is_convertible<Tr1, Tr2>::value));
   226     }
   227   }
   228   
   229   //
   230   // Iterator Adaptor
   231   //
   232   // The parameter ordering changed slightly with respect to former
   233   // versions of iterator_adaptor The idea is that when the user needs
   234   // to fiddle with the reference type it is highly likely that the
   235   // iterator category has to be adjusted as well.  Any of the
   236   // following four template arguments may be ommitted or explicitly
   237   // replaced by use_default.
   238   //
   239   //   Value - if supplied, the value_type of the resulting iterator, unless
   240   //      const. If const, a conforming compiler strips constness for the
   241   //      value_type. If not supplied, iterator_traits<Base>::value_type is used
   242   //
   243   //   Category - the traversal category of the resulting iterator. If not
   244   //      supplied, iterator_traversal<Base>::type is used.
   245   //
   246   //   Reference - the reference type of the resulting iterator, and in
   247   //      particular, the result type of operator*(). If not supplied but
   248   //      Value is supplied, Value& is used. Otherwise
   249   //      iterator_traits<Base>::reference is used.
   250   //
   251   //   Difference - the difference_type of the resulting iterator. If not
   252   //      supplied, iterator_traits<Base>::difference_type is used.
   253   //
   254   template <
   255       class Derived
   256     , class Base
   257     , class Value        = use_default
   258     , class Traversal    = use_default
   259     , class Reference    = use_default
   260     , class Difference   = use_default
   261   >
   262   class iterator_adaptor
   263     : public detail::iterator_adaptor_base<
   264         Derived, Base, Value, Traversal, Reference, Difference
   265       >::type
   266   {
   267       friend class iterator_core_access;
   268 
   269    protected:
   270       typedef typename detail::iterator_adaptor_base<
   271           Derived, Base, Value, Traversal, Reference, Difference
   272       >::type super_t;
   273    public:
   274       iterator_adaptor() {}
   275 
   276       explicit iterator_adaptor(Base const &iter)
   277           : m_iterator(iter)
   278       {
   279       }
   280 
   281       typedef Base base_type;
   282 
   283       Base const& base() const
   284         { return m_iterator; }
   285 
   286    protected:
   287       // for convenience in derived classes
   288       typedef iterator_adaptor<Derived,Base,Value,Traversal,Reference,Difference> iterator_adaptor_;
   289       
   290       //
   291       // lvalue access to the Base object for Derived
   292       //
   293       Base const& base_reference() const
   294         { return m_iterator; }
   295 
   296       Base& base_reference()
   297         { return m_iterator; }
   298 
   299    private:
   300       //
   301       // Core iterator interface for iterator_facade.  This is private
   302       // to prevent temptation for Derived classes to use it, which
   303       // will often result in an error.  Derived classes should use
   304       // base_reference(), above, to get direct access to m_iterator.
   305       // 
   306       typename super_t::reference dereference() const
   307         { return *m_iterator; }
   308 
   309       template <
   310       class OtherDerived, class OtherIterator, class V, class C, class R, class D
   311       >   
   312       bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const
   313       {
   314         // Maybe readd with same_distance
   315         //           BOOST_STATIC_ASSERT(
   316         //               (detail::same_category_and_difference<Derived,OtherDerived>::value)
   317         //               );
   318           return m_iterator == x.base();
   319       }
   320 
   321       typedef typename iterator_category_to_traversal<
   322           typename super_t::iterator_category
   323       >::type my_traversal;
   324 
   325 # define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \
   326       detail::iterator_adaptor_assert_traversal<my_traversal, cat>();
   327 
   328       void advance(typename super_t::difference_type n)
   329       {
   330           BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
   331           m_iterator += n;
   332       }
   333   
   334       void increment() { ++m_iterator; }
   335 
   336       void decrement() 
   337       {
   338           BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag)
   339            --m_iterator;
   340       }
   341 
   342       template <
   343           class OtherDerived, class OtherIterator, class V, class C, class R, class D
   344       >   
   345       typename super_t::difference_type distance_to(
   346           iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const
   347       {
   348           BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
   349           // Maybe readd with same_distance
   350           //           BOOST_STATIC_ASSERT(
   351           //               (detail::same_category_and_difference<Derived,OtherDerived>::value)
   352           //               );
   353           return y.base() - m_iterator;
   354       }
   355 
   356 # undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL
   357       
   358    private: // data members
   359       Base m_iterator;
   360   };
   361 
   362 } // namespace boost
   363 
   364 #include <boost/iterator/detail/config_undef.hpp>
   365 
   366 #endif // BOOST_ITERATOR_ADAPTOR_23022003THW_HPP