PageRenderTime 58ms CodeModel.GetById 17ms app.highlight 37ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Dependencies/Boost/boost/multi_index/detail/iter_adaptor.hpp

http://hadesmem.googlecode.com/
C++ Header | 325 lines | 256 code | 52 blank | 17 comment | 0 complexity | 50263d03f3c839da2ae0435c96250f46 MD5 | raw file
  1/* Copyright 2003-2008 Joaquin M Lopez Munoz.
  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
 21namespace boost{
 22
 23namespace multi_index{
 24
 25namespace 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/* NB. The purpose of the (non-inclass) global operators ==, < and - defined
 34 * above is to partially alleviate a problem of MSVC++ 6.0 by * which
 35 * friend-injected operators on T are not visible if T is instantiated only
 36 * in template code where T is a dependent type.
 37 */
 38
 39class iter_adaptor_access
 40{
 41public:
 42  template<class Class>
 43    static typename Class::reference dereference(const Class& x)
 44  {
 45    return x.dereference();
 46  }
 47
 48  template<class Class>
 49  static bool equal(const Class& x,const Class& y)
 50  {
 51    return x.equal(y);
 52  }
 53
 54  template<class Class>
 55  static void increment(Class& x)
 56  {
 57    x.increment();
 58  }
 59
 60  template<class Class>
 61  static void decrement(Class& x)
 62  {
 63    x.decrement();
 64  }
 65
 66  template<class Class>
 67  static void advance(Class& x,typename Class::difference_type n)
 68  {
 69    x.advance(n);
 70  }
 71
 72  template<class Class>
 73  static typename Class::difference_type distance_to(
 74    const Class& x,const Class& y)
 75  {
 76    return x.distance_to(y);
 77  }
 78};
 79
 80template<typename Category>
 81struct iter_adaptor_selector;
 82
 83template<class Derived,class Base>
 84class forward_iter_adaptor_base:
 85  public forward_iterator_helper<
 86    Derived,
 87    typename Base::value_type,
 88    typename Base::difference_type,
 89    typename Base::pointer,
 90    typename Base::reference>
 91{
 92public:
 93  typedef typename Base::reference reference;
 94
 95  reference operator*()const
 96  {
 97    return iter_adaptor_access::dereference(final());
 98  }
 99
100  friend bool operator==(const Derived& x,const Derived& y)
101  {
102    return iter_adaptor_access::equal(x,y);
103  }
104
105  Derived& operator++()
106  {
107    iter_adaptor_access::increment(final());
108    return final();
109  }
110
111private:
112  Derived& final(){return *static_cast<Derived*>(this);}
113  const Derived& final()const{return *static_cast<const Derived*>(this);}
114};
115
116template<class Derived,class Base>
117bool operator==(
118  const forward_iter_adaptor_base<Derived,Base>& x,
119  const forward_iter_adaptor_base<Derived,Base>& y)
120{
121  return iter_adaptor_access::equal(
122    static_cast<const Derived&>(x),static_cast<const Derived&>(y));
123}
124
125template<>
126struct iter_adaptor_selector<std::forward_iterator_tag>
127{
128  template<class Derived,class Base>
129  struct apply
130  {
131    typedef forward_iter_adaptor_base<Derived,Base> type;
132  };
133};
134
135template<class Derived,class Base>
136class bidirectional_iter_adaptor_base:
137  public bidirectional_iterator_helper<
138    Derived,
139    typename Base::value_type,
140    typename Base::difference_type,
141    typename Base::pointer,
142    typename Base::reference>
143{
144public:
145  typedef typename Base::reference reference;
146
147  reference operator*()const
148  {
149    return iter_adaptor_access::dereference(final());
150  }
151
152  friend bool operator==(const Derived& x,const Derived& y)
153  {
154    return iter_adaptor_access::equal(x,y);
155  }
156
157  Derived& operator++()
158  {
159    iter_adaptor_access::increment(final());
160    return final();
161  }
162
163  Derived& operator--()
164  {
165    iter_adaptor_access::decrement(final());
166    return final();
167  }
168
169private:
170  Derived& final(){return *static_cast<Derived*>(this);}
171  const Derived& final()const{return *static_cast<const Derived*>(this);}
172};
173
174template<class Derived,class Base>
175bool operator==(
176  const bidirectional_iter_adaptor_base<Derived,Base>& x,
177  const bidirectional_iter_adaptor_base<Derived,Base>& y)
178{
179  return iter_adaptor_access::equal(
180    static_cast<const Derived&>(x),static_cast<const Derived&>(y));
181}
182
183template<>
184struct iter_adaptor_selector<std::bidirectional_iterator_tag>
185{
186  template<class Derived,class Base>
187  struct apply
188  {
189    typedef bidirectional_iter_adaptor_base<Derived,Base> type;
190  };
191};
192
193template<class Derived,class Base>
194class random_access_iter_adaptor_base:
195  public random_access_iterator_helper<
196    Derived,
197    typename Base::value_type,
198    typename Base::difference_type,
199    typename Base::pointer,
200    typename Base::reference>
201{
202public:
203  typedef typename Base::reference       reference;
204  typedef typename Base::difference_type difference_type;
205
206  reference operator*()const
207  {
208    return iter_adaptor_access::dereference(final());
209  }
210
211  friend bool operator==(const Derived& x,const Derived& y)
212  {
213    return iter_adaptor_access::equal(x,y);
214  }
215
216  friend bool operator<(const Derived& x,const Derived& y)
217  {
218    return iter_adaptor_access::distance_to(x,y)>0;
219  }
220
221  Derived& operator++()
222  {
223    iter_adaptor_access::increment(final());
224    return final();
225  }
226
227  Derived& operator--()
228  {
229    iter_adaptor_access::decrement(final());
230    return final();
231  }
232
233  Derived& operator+=(difference_type n)
234  {
235    iter_adaptor_access::advance(final(),n);
236    return final();
237  }
238
239  Derived& operator-=(difference_type n)
240  {
241    iter_adaptor_access::advance(final(),-n);
242    return final();
243  }
244
245  friend difference_type operator-(const Derived& x,const Derived& y)
246  {
247    return iter_adaptor_access::distance_to(y,x);
248  }
249
250private:
251  Derived& final(){return *static_cast<Derived*>(this);}
252  const Derived& final()const{return *static_cast<const Derived*>(this);}
253};
254
255template<class Derived,class Base>
256bool operator==(
257  const random_access_iter_adaptor_base<Derived,Base>& x,
258  const random_access_iter_adaptor_base<Derived,Base>& y)
259{
260  return iter_adaptor_access::equal(
261    static_cast<const Derived&>(x),static_cast<const Derived&>(y));
262}
263
264template<class Derived,class Base>
265bool operator<(
266  const random_access_iter_adaptor_base<Derived,Base>& x,
267  const random_access_iter_adaptor_base<Derived,Base>& y)
268{
269  return iter_adaptor_access::distance_to(
270    static_cast<const Derived&>(x),static_cast<const Derived&>(y))>0;
271}
272
273template<class Derived,class Base>
274typename random_access_iter_adaptor_base<Derived,Base>::difference_type
275operator-(
276  const random_access_iter_adaptor_base<Derived,Base>& x,
277  const random_access_iter_adaptor_base<Derived,Base>& y)
278{
279  return iter_adaptor_access::distance_to(
280    static_cast<const Derived&>(y),static_cast<const Derived&>(x));
281}
282
283template<>
284struct iter_adaptor_selector<std::random_access_iterator_tag>
285{
286  template<class Derived,class Base>
287  struct apply
288  {
289    typedef random_access_iter_adaptor_base<Derived,Base> type;
290  };
291};
292
293template<class Derived,class Base>
294struct iter_adaptor_base
295{
296  typedef iter_adaptor_selector<
297    typename Base::iterator_category>        selector;
298  typedef typename prevent_eti<
299    selector,
300    typename mpl::apply2<
301      selector,Derived,Base>::type
302  >::type                                    type;
303};
304
305template<class Derived,class Base>
306class iter_adaptor:public iter_adaptor_base<Derived,Base>::type
307{
308protected:
309  iter_adaptor(){}
310  explicit iter_adaptor(const Base& b_):b(b_){}
311
312  const Base& base_reference()const{return b;}
313  Base&       base_reference(){return b;}
314
315private:
316  Base b;
317};
318
319} /* namespace multi_index::detail */
320
321} /* namespace multi_index */
322
323} /* namespace boost */
324
325#endif