epoc32/include/stdapis/boost/multi_index/detail/iter_adaptor.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100
branchSymbian2
changeset 3 e1b950c65cb4
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
     1 /* Copyright 2003-2005 Joaquín M López Muñoz.
     2  * Distributed under the Boost Software License, Version 1.0.
     3  * (See accompanying file LICENSE_1_0.txt or copy at
     4  * http://www.boost.org/LICENSE_1_0.txt)
     5  *
     6  * See http://www.boost.org/libs/multi_index for library home page.
     7  */
     8 
     9 #ifndef BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP
    10 #define BOOST_MULTI_INDEX_DETAIL_ITER_ADAPTOR_HPP
    11 
    12 #if defined(_MSC_VER)&&(_MSC_VER>=1200)
    13 #pragma once
    14 #endif
    15 
    16 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
    17 #include <boost/mpl/apply.hpp>
    18 #include <boost/multi_index/detail/prevent_eti.hpp>
    19 #include <boost/operators.hpp>
    20 
    21 namespace boost{
    22 
    23 namespace multi_index{
    24 
    25 namespace detail{
    26 
    27 /* Poor man's version of boost::iterator_adaptor. Used instead of the
    28  * original as compile times for the latter are significantly higher.
    29  * The interface is not replicated exactly, only to the extent necessary
    30  * for internal consumption.
    31  */
    32 
    33 class iter_adaptor_access
    34 {
    35 public:
    36   template<class Class>
    37     static typename Class::reference dereference(const Class& x)
    38   {
    39     return x.dereference();
    40   }
    41 
    42   template<class Class>
    43   static bool equal(const Class& x,const Class& y)
    44   {
    45     return x.equal(y);
    46   }
    47 
    48   template<class Class>
    49   static void increment(Class& x)
    50   {
    51     x.increment();
    52   }
    53 
    54   template<class Class>
    55   static void decrement(Class& x)
    56   {
    57     x.decrement();
    58   }
    59 
    60   template<class Class>
    61   static void advance(Class& x,typename Class::difference_type n)
    62   {
    63     x.advance(n);
    64   }
    65 
    66   template<class Class>
    67   static typename Class::difference_type distance_to(
    68     const Class& x,const Class& y)
    69   {
    70     return x.distance_to(y);
    71   }
    72 };
    73 
    74 template<typename Category>
    75 struct iter_adaptor_selector;
    76 
    77 template<class Derived,class Base>
    78 class forward_iter_adaptor_base:
    79   public forward_iterator_helper<
    80     Derived,
    81     typename Base::value_type,
    82     typename Base::difference_type,
    83     typename Base::pointer,
    84     typename Base::reference>
    85 {
    86 public:
    87   typedef typename Base::reference reference;
    88 
    89   reference operator*()const
    90   {
    91     return iter_adaptor_access::dereference(final());
    92   }
    93 
    94   friend bool operator==(const Derived& x,const Derived& y)
    95   {
    96     return iter_adaptor_access::equal(x,y);
    97   }
    98 
    99   Derived& operator++()
   100   {
   101     iter_adaptor_access::increment(final());
   102     return final();
   103   }
   104 
   105 private:
   106   Derived& final(){return *static_cast<Derived*>(this);}
   107   const Derived& final()const{return *static_cast<const Derived*>(this);}
   108 };
   109 
   110 template<>
   111 struct iter_adaptor_selector<std::forward_iterator_tag>
   112 {
   113   template<class Derived,class Base>
   114   struct apply
   115   {
   116     typedef forward_iter_adaptor_base<Derived,Base> type;
   117   };
   118 };
   119 
   120 template<class Derived,class Base>
   121 class bidirectional_iter_adaptor_base:
   122   public bidirectional_iterator_helper<
   123     Derived,
   124     typename Base::value_type,
   125     typename Base::difference_type,
   126     typename Base::pointer,
   127     typename Base::reference>
   128 {
   129 public:
   130   typedef typename Base::reference reference;
   131 
   132   reference operator*()const
   133   {
   134     return iter_adaptor_access::dereference(final());
   135   }
   136 
   137   friend bool operator==(const Derived& x,const Derived& y)
   138   {
   139     return iter_adaptor_access::equal(x,y);
   140   }
   141 
   142   Derived& operator++()
   143   {
   144     iter_adaptor_access::increment(final());
   145     return final();
   146   }
   147 
   148   Derived& operator--()
   149   {
   150     iter_adaptor_access::decrement(final());
   151     return final();
   152   }
   153 
   154 private:
   155   Derived& final(){return *static_cast<Derived*>(this);}
   156   const Derived& final()const{return *static_cast<const Derived*>(this);}
   157 };
   158 
   159 template<>
   160 struct iter_adaptor_selector<std::bidirectional_iterator_tag>
   161 {
   162   template<class Derived,class Base>
   163   struct apply
   164   {
   165     typedef bidirectional_iter_adaptor_base<Derived,Base> type;
   166   };
   167 };
   168 
   169 template<class Derived,class Base>
   170 class random_access_iter_adaptor_base:
   171   public random_access_iterator_helper<
   172     Derived,
   173     typename Base::value_type,
   174     typename Base::difference_type,
   175     typename Base::pointer,
   176     typename Base::reference>
   177 {
   178 public:
   179   typedef typename Base::reference       reference;
   180   typedef typename Base::difference_type difference_type;
   181 
   182   reference operator*()const
   183   {
   184     return iter_adaptor_access::dereference(final());
   185   }
   186 
   187   friend bool operator==(const Derived& x,const Derived& y)
   188   {
   189     return iter_adaptor_access::equal(x,y);
   190   }
   191 
   192   friend bool operator<(const Derived& x,const Derived& y)
   193   {
   194     return iter_adaptor_access::distance_to(x,y)>0;
   195   }
   196 
   197   Derived& operator++()
   198   {
   199     iter_adaptor_access::increment(final());
   200     return final();
   201   }
   202 
   203   Derived& operator--()
   204   {
   205     iter_adaptor_access::decrement(final());
   206     return final();
   207   }
   208 
   209   Derived& operator+=(difference_type n)
   210   {
   211     iter_adaptor_access::advance(final(),n);
   212     return final();
   213   }
   214 
   215   Derived& operator-=(difference_type n)
   216   {
   217     iter_adaptor_access::advance(final(),-n);
   218     return final();
   219   }
   220 
   221   friend difference_type operator-(const Derived& x,const Derived& y)
   222   {
   223     return iter_adaptor_access::distance_to(y,x);
   224   }
   225 
   226 private:
   227   Derived& final(){return *static_cast<Derived*>(this);}
   228   const Derived& final()const{return *static_cast<const Derived*>(this);}
   229 };
   230 
   231 template<>
   232 struct iter_adaptor_selector<std::random_access_iterator_tag>
   233 {
   234   template<class Derived,class Base>
   235   struct apply
   236   {
   237     typedef random_access_iter_adaptor_base<Derived,Base> type;
   238   };
   239 };
   240 
   241 template<class Derived,class Base>
   242 struct iter_adaptor_base
   243 {
   244   typedef iter_adaptor_selector<
   245     typename Base::iterator_category>        selector;
   246   typedef typename prevent_eti<
   247     selector,
   248     typename mpl::apply2<
   249       selector,Derived,Base>::type
   250   >::type                                    type;
   251 };
   252 
   253 template<class Derived,class Base>
   254 class iter_adaptor:public iter_adaptor_base<Derived,Base>::type
   255 {
   256 protected:
   257   iter_adaptor(){}
   258   explicit iter_adaptor(const Base& b_):b(b_){}
   259 
   260   const Base& base_reference()const{return b;}
   261   Base&       base_reference(){return b;}
   262 
   263 private:
   264   Base b;
   265 };
   266 
   267 } /* namespace multi_index::detail */
   268 
   269 } /* namespace multi_index */
   270 
   271 } /* namespace boost */
   272 
   273 #endif