Add Boost.Test karmic valgrind suppressions
[senf.git] / boost / multi_index / detail / iter_adaptor.hpp
1 /* Copyright 2003-2007 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 /* 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
39 class iter_adaptor_access
40 {
41 public:
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
80 template<typename Category>
81 struct iter_adaptor_selector;
82
83 template<class Derived,class Base>
84 class 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 {
92 public:
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
111 private:
112   Derived& final(){return *static_cast<Derived*>(this);}
113   const Derived& final()const{return *static_cast<const Derived*>(this);}
114 };
115
116 template<class Derived,class Base>
117 bool 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
125 template<>
126 struct 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
135 template<class Derived,class Base>
136 class 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 {
144 public:
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
169 private:
170   Derived& final(){return *static_cast<Derived*>(this);}
171   const Derived& final()const{return *static_cast<const Derived*>(this);}
172 };
173
174 template<class Derived,class Base>
175 bool 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
183 template<>
184 struct 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
193 template<class Derived,class Base>
194 class 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 {
202 public:
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
250 private:
251   Derived& final(){return *static_cast<Derived*>(this);}
252   const Derived& final()const{return *static_cast<const Derived*>(this);}
253 };
254
255 template<class Derived,class Base>
256 bool 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
264 template<class Derived,class Base>
265 bool 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
273 template<class Derived,class Base>
274 typename random_access_iter_adaptor_base<Derived,Base>::difference_type
275 operator-(
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
283 template<>
284 struct 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
293 template<class Derived,class Base>
294 struct 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
305 template<class Derived,class Base>
306 class iter_adaptor:public iter_adaptor_base<Derived,Base>::type
307 {
308 protected:
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
315 private:
316   Base b;
317 };
318
319 } /* namespace multi_index::detail */
320
321 } /* namespace multi_index */
322
323 } /* namespace boost */
324
325 #endif