Chris@16
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 //
|
Chris@16
|
3 // (C) Copyright Ion Gaztanaga 2005-2012.
|
Chris@16
|
4 // (C) Copyright Gennaro Prota 2003 - 2004.
|
Chris@16
|
5 //
|
Chris@16
|
6 // Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
7 // (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
8 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
9 //
|
Chris@16
|
10 // See http://www.boost.org/libs/container for documentation.
|
Chris@16
|
11 //
|
Chris@16
|
12 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
13
|
Chris@16
|
14 #ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|
Chris@16
|
15 #define BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|
Chris@16
|
16
|
Chris@16
|
17 #if defined(_MSC_VER)
|
Chris@16
|
18 # pragma once
|
Chris@16
|
19 #endif
|
Chris@16
|
20
|
Chris@16
|
21 #include "config_begin.hpp"
|
Chris@16
|
22 #include <boost/container/detail/workaround.hpp>
|
Chris@16
|
23 #include <boost/move/utility.hpp>
|
Chris@16
|
24 #include <boost/container/allocator_traits.hpp>
|
Chris@16
|
25 #include <boost/container/detail/type_traits.hpp>
|
Chris@16
|
26 #include <boost/static_assert.hpp>
|
Chris@16
|
27
|
Chris@16
|
28 #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
Chris@16
|
29 #include <boost/container/detail/variadic_templates_tools.hpp>
|
Chris@16
|
30 #else
|
Chris@16
|
31 #include <boost/container/detail/preprocessor.hpp>
|
Chris@16
|
32 #endif
|
Chris@16
|
33
|
Chris@16
|
34 #include <iterator>
|
Chris@16
|
35
|
Chris@16
|
36 namespace boost {
|
Chris@16
|
37 namespace container {
|
Chris@16
|
38
|
Chris@16
|
39 template <class T, class Difference = std::ptrdiff_t>
|
Chris@16
|
40 class constant_iterator
|
Chris@16
|
41 : public std::iterator
|
Chris@16
|
42 <std::random_access_iterator_tag, T, Difference, const T*, const T &>
|
Chris@16
|
43 {
|
Chris@16
|
44 typedef constant_iterator<T, Difference> this_type;
|
Chris@16
|
45
|
Chris@16
|
46 public:
|
Chris@16
|
47 explicit constant_iterator(const T &ref, Difference range_size)
|
Chris@16
|
48 : m_ptr(&ref), m_num(range_size){}
|
Chris@16
|
49
|
Chris@16
|
50 //Constructors
|
Chris@16
|
51 constant_iterator()
|
Chris@16
|
52 : m_ptr(0), m_num(0){}
|
Chris@16
|
53
|
Chris@16
|
54 constant_iterator& operator++()
|
Chris@16
|
55 { increment(); return *this; }
|
Chris@16
|
56
|
Chris@16
|
57 constant_iterator operator++(int)
|
Chris@16
|
58 {
|
Chris@16
|
59 constant_iterator result (*this);
|
Chris@16
|
60 increment();
|
Chris@16
|
61 return result;
|
Chris@16
|
62 }
|
Chris@16
|
63
|
Chris@16
|
64 constant_iterator& operator--()
|
Chris@16
|
65 { decrement(); return *this; }
|
Chris@16
|
66
|
Chris@16
|
67 constant_iterator operator--(int)
|
Chris@16
|
68 {
|
Chris@16
|
69 constant_iterator result (*this);
|
Chris@16
|
70 decrement();
|
Chris@16
|
71 return result;
|
Chris@16
|
72 }
|
Chris@16
|
73
|
Chris@16
|
74 friend bool operator== (const constant_iterator& i, const constant_iterator& i2)
|
Chris@16
|
75 { return i.equal(i2); }
|
Chris@16
|
76
|
Chris@16
|
77 friend bool operator!= (const constant_iterator& i, const constant_iterator& i2)
|
Chris@16
|
78 { return !(i == i2); }
|
Chris@16
|
79
|
Chris@16
|
80 friend bool operator< (const constant_iterator& i, const constant_iterator& i2)
|
Chris@16
|
81 { return i.less(i2); }
|
Chris@16
|
82
|
Chris@16
|
83 friend bool operator> (const constant_iterator& i, const constant_iterator& i2)
|
Chris@16
|
84 { return i2 < i; }
|
Chris@16
|
85
|
Chris@16
|
86 friend bool operator<= (const constant_iterator& i, const constant_iterator& i2)
|
Chris@16
|
87 { return !(i > i2); }
|
Chris@16
|
88
|
Chris@16
|
89 friend bool operator>= (const constant_iterator& i, const constant_iterator& i2)
|
Chris@16
|
90 { return !(i < i2); }
|
Chris@16
|
91
|
Chris@16
|
92 friend Difference operator- (const constant_iterator& i, const constant_iterator& i2)
|
Chris@16
|
93 { return i2.distance_to(i); }
|
Chris@16
|
94
|
Chris@16
|
95 //Arithmetic
|
Chris@16
|
96 constant_iterator& operator+=(Difference off)
|
Chris@16
|
97 { this->advance(off); return *this; }
|
Chris@16
|
98
|
Chris@16
|
99 constant_iterator operator+(Difference off) const
|
Chris@16
|
100 {
|
Chris@16
|
101 constant_iterator other(*this);
|
Chris@16
|
102 other.advance(off);
|
Chris@16
|
103 return other;
|
Chris@16
|
104 }
|
Chris@16
|
105
|
Chris@16
|
106 friend constant_iterator operator+(Difference off, const constant_iterator& right)
|
Chris@16
|
107 { return right + off; }
|
Chris@16
|
108
|
Chris@16
|
109 constant_iterator& operator-=(Difference off)
|
Chris@16
|
110 { this->advance(-off); return *this; }
|
Chris@16
|
111
|
Chris@16
|
112 constant_iterator operator-(Difference off) const
|
Chris@16
|
113 { return *this + (-off); }
|
Chris@16
|
114
|
Chris@16
|
115 const T& operator*() const
|
Chris@16
|
116 { return dereference(); }
|
Chris@16
|
117
|
Chris@16
|
118 const T& operator[] (Difference ) const
|
Chris@16
|
119 { return dereference(); }
|
Chris@16
|
120
|
Chris@16
|
121 const T* operator->() const
|
Chris@16
|
122 { return &(dereference()); }
|
Chris@16
|
123
|
Chris@16
|
124 private:
|
Chris@16
|
125 const T * m_ptr;
|
Chris@16
|
126 Difference m_num;
|
Chris@16
|
127
|
Chris@16
|
128 void increment()
|
Chris@16
|
129 { --m_num; }
|
Chris@16
|
130
|
Chris@16
|
131 void decrement()
|
Chris@16
|
132 { ++m_num; }
|
Chris@16
|
133
|
Chris@16
|
134 bool equal(const this_type &other) const
|
Chris@16
|
135 { return m_num == other.m_num; }
|
Chris@16
|
136
|
Chris@16
|
137 bool less(const this_type &other) const
|
Chris@16
|
138 { return other.m_num < m_num; }
|
Chris@16
|
139
|
Chris@16
|
140 const T & dereference() const
|
Chris@16
|
141 { return *m_ptr; }
|
Chris@16
|
142
|
Chris@16
|
143 void advance(Difference n)
|
Chris@16
|
144 { m_num -= n; }
|
Chris@16
|
145
|
Chris@16
|
146 Difference distance_to(const this_type &other)const
|
Chris@16
|
147 { return m_num - other.m_num; }
|
Chris@16
|
148 };
|
Chris@16
|
149
|
Chris@16
|
150 template <class T, class Difference = std::ptrdiff_t>
|
Chris@16
|
151 class value_init_construct_iterator
|
Chris@16
|
152 : public std::iterator
|
Chris@16
|
153 <std::random_access_iterator_tag, T, Difference, const T*, const T &>
|
Chris@16
|
154 {
|
Chris@16
|
155 typedef value_init_construct_iterator<T, Difference> this_type;
|
Chris@16
|
156
|
Chris@16
|
157 public:
|
Chris@16
|
158 explicit value_init_construct_iterator(Difference range_size)
|
Chris@16
|
159 : m_num(range_size){}
|
Chris@16
|
160
|
Chris@16
|
161 //Constructors
|
Chris@16
|
162 value_init_construct_iterator()
|
Chris@16
|
163 : m_num(0){}
|
Chris@16
|
164
|
Chris@16
|
165 value_init_construct_iterator& operator++()
|
Chris@16
|
166 { increment(); return *this; }
|
Chris@16
|
167
|
Chris@16
|
168 value_init_construct_iterator operator++(int)
|
Chris@16
|
169 {
|
Chris@16
|
170 value_init_construct_iterator result (*this);
|
Chris@16
|
171 increment();
|
Chris@16
|
172 return result;
|
Chris@16
|
173 }
|
Chris@16
|
174
|
Chris@16
|
175 value_init_construct_iterator& operator--()
|
Chris@16
|
176 { decrement(); return *this; }
|
Chris@16
|
177
|
Chris@16
|
178 value_init_construct_iterator operator--(int)
|
Chris@16
|
179 {
|
Chris@16
|
180 value_init_construct_iterator result (*this);
|
Chris@16
|
181 decrement();
|
Chris@16
|
182 return result;
|
Chris@16
|
183 }
|
Chris@16
|
184
|
Chris@16
|
185 friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
Chris@16
|
186 { return i.equal(i2); }
|
Chris@16
|
187
|
Chris@16
|
188 friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
Chris@16
|
189 { return !(i == i2); }
|
Chris@16
|
190
|
Chris@16
|
191 friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
Chris@16
|
192 { return i.less(i2); }
|
Chris@16
|
193
|
Chris@16
|
194 friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
Chris@16
|
195 { return i2 < i; }
|
Chris@16
|
196
|
Chris@16
|
197 friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
Chris@16
|
198 { return !(i > i2); }
|
Chris@16
|
199
|
Chris@16
|
200 friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
Chris@16
|
201 { return !(i < i2); }
|
Chris@16
|
202
|
Chris@16
|
203 friend Difference operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
|
Chris@16
|
204 { return i2.distance_to(i); }
|
Chris@16
|
205
|
Chris@16
|
206 //Arithmetic
|
Chris@16
|
207 value_init_construct_iterator& operator+=(Difference off)
|
Chris@16
|
208 { this->advance(off); return *this; }
|
Chris@16
|
209
|
Chris@16
|
210 value_init_construct_iterator operator+(Difference off) const
|
Chris@16
|
211 {
|
Chris@16
|
212 value_init_construct_iterator other(*this);
|
Chris@16
|
213 other.advance(off);
|
Chris@16
|
214 return other;
|
Chris@16
|
215 }
|
Chris@16
|
216
|
Chris@16
|
217 friend value_init_construct_iterator operator+(Difference off, const value_init_construct_iterator& right)
|
Chris@16
|
218 { return right + off; }
|
Chris@16
|
219
|
Chris@16
|
220 value_init_construct_iterator& operator-=(Difference off)
|
Chris@16
|
221 { this->advance(-off); return *this; }
|
Chris@16
|
222
|
Chris@16
|
223 value_init_construct_iterator operator-(Difference off) const
|
Chris@16
|
224 { return *this + (-off); }
|
Chris@16
|
225
|
Chris@16
|
226 //This pseudo-iterator's dereference operations have no sense since value is not
|
Chris@16
|
227 //constructed until ::boost::container::construct_in_place is called.
|
Chris@16
|
228 //So comment them to catch bad uses
|
Chris@16
|
229 //const T& operator*() const;
|
Chris@16
|
230 //const T& operator[](difference_type) const;
|
Chris@16
|
231 //const T* operator->() const;
|
Chris@16
|
232
|
Chris@16
|
233 private:
|
Chris@16
|
234 Difference m_num;
|
Chris@16
|
235
|
Chris@16
|
236 void increment()
|
Chris@16
|
237 { --m_num; }
|
Chris@16
|
238
|
Chris@16
|
239 void decrement()
|
Chris@16
|
240 { ++m_num; }
|
Chris@16
|
241
|
Chris@16
|
242 bool equal(const this_type &other) const
|
Chris@16
|
243 { return m_num == other.m_num; }
|
Chris@16
|
244
|
Chris@16
|
245 bool less(const this_type &other) const
|
Chris@16
|
246 { return other.m_num < m_num; }
|
Chris@16
|
247
|
Chris@16
|
248 const T & dereference() const
|
Chris@16
|
249 {
|
Chris@16
|
250 static T dummy;
|
Chris@16
|
251 return dummy;
|
Chris@16
|
252 }
|
Chris@16
|
253
|
Chris@16
|
254 void advance(Difference n)
|
Chris@16
|
255 { m_num -= n; }
|
Chris@16
|
256
|
Chris@16
|
257 Difference distance_to(const this_type &other)const
|
Chris@16
|
258 { return m_num - other.m_num; }
|
Chris@16
|
259 };
|
Chris@16
|
260
|
Chris@16
|
261 template <class T, class Difference = std::ptrdiff_t>
|
Chris@16
|
262 class default_init_construct_iterator
|
Chris@16
|
263 : public std::iterator
|
Chris@16
|
264 <std::random_access_iterator_tag, T, Difference, const T*, const T &>
|
Chris@16
|
265 {
|
Chris@16
|
266 typedef default_init_construct_iterator<T, Difference> this_type;
|
Chris@16
|
267
|
Chris@16
|
268 public:
|
Chris@16
|
269 explicit default_init_construct_iterator(Difference range_size)
|
Chris@16
|
270 : m_num(range_size){}
|
Chris@16
|
271
|
Chris@16
|
272 //Constructors
|
Chris@16
|
273 default_init_construct_iterator()
|
Chris@16
|
274 : m_num(0){}
|
Chris@16
|
275
|
Chris@16
|
276 default_init_construct_iterator& operator++()
|
Chris@16
|
277 { increment(); return *this; }
|
Chris@16
|
278
|
Chris@16
|
279 default_init_construct_iterator operator++(int)
|
Chris@16
|
280 {
|
Chris@16
|
281 default_init_construct_iterator result (*this);
|
Chris@16
|
282 increment();
|
Chris@16
|
283 return result;
|
Chris@16
|
284 }
|
Chris@16
|
285
|
Chris@16
|
286 default_init_construct_iterator& operator--()
|
Chris@16
|
287 { decrement(); return *this; }
|
Chris@16
|
288
|
Chris@16
|
289 default_init_construct_iterator operator--(int)
|
Chris@16
|
290 {
|
Chris@16
|
291 default_init_construct_iterator result (*this);
|
Chris@16
|
292 decrement();
|
Chris@16
|
293 return result;
|
Chris@16
|
294 }
|
Chris@16
|
295
|
Chris@16
|
296 friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
Chris@16
|
297 { return i.equal(i2); }
|
Chris@16
|
298
|
Chris@16
|
299 friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
Chris@16
|
300 { return !(i == i2); }
|
Chris@16
|
301
|
Chris@16
|
302 friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
Chris@16
|
303 { return i.less(i2); }
|
Chris@16
|
304
|
Chris@16
|
305 friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
Chris@16
|
306 { return i2 < i; }
|
Chris@16
|
307
|
Chris@16
|
308 friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
Chris@16
|
309 { return !(i > i2); }
|
Chris@16
|
310
|
Chris@16
|
311 friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
Chris@16
|
312 { return !(i < i2); }
|
Chris@16
|
313
|
Chris@16
|
314 friend Difference operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
|
Chris@16
|
315 { return i2.distance_to(i); }
|
Chris@16
|
316
|
Chris@16
|
317 //Arithmetic
|
Chris@16
|
318 default_init_construct_iterator& operator+=(Difference off)
|
Chris@16
|
319 { this->advance(off); return *this; }
|
Chris@16
|
320
|
Chris@16
|
321 default_init_construct_iterator operator+(Difference off) const
|
Chris@16
|
322 {
|
Chris@16
|
323 default_init_construct_iterator other(*this);
|
Chris@16
|
324 other.advance(off);
|
Chris@16
|
325 return other;
|
Chris@16
|
326 }
|
Chris@16
|
327
|
Chris@16
|
328 friend default_init_construct_iterator operator+(Difference off, const default_init_construct_iterator& right)
|
Chris@16
|
329 { return right + off; }
|
Chris@16
|
330
|
Chris@16
|
331 default_init_construct_iterator& operator-=(Difference off)
|
Chris@16
|
332 { this->advance(-off); return *this; }
|
Chris@16
|
333
|
Chris@16
|
334 default_init_construct_iterator operator-(Difference off) const
|
Chris@16
|
335 { return *this + (-off); }
|
Chris@16
|
336
|
Chris@16
|
337 //This pseudo-iterator's dereference operations have no sense since value is not
|
Chris@16
|
338 //constructed until ::boost::container::construct_in_place is called.
|
Chris@16
|
339 //So comment them to catch bad uses
|
Chris@16
|
340 //const T& operator*() const;
|
Chris@16
|
341 //const T& operator[](difference_type) const;
|
Chris@16
|
342 //const T* operator->() const;
|
Chris@16
|
343
|
Chris@16
|
344 private:
|
Chris@16
|
345 Difference m_num;
|
Chris@16
|
346
|
Chris@16
|
347 void increment()
|
Chris@16
|
348 { --m_num; }
|
Chris@16
|
349
|
Chris@16
|
350 void decrement()
|
Chris@16
|
351 { ++m_num; }
|
Chris@16
|
352
|
Chris@16
|
353 bool equal(const this_type &other) const
|
Chris@16
|
354 { return m_num == other.m_num; }
|
Chris@16
|
355
|
Chris@16
|
356 bool less(const this_type &other) const
|
Chris@16
|
357 { return other.m_num < m_num; }
|
Chris@16
|
358
|
Chris@16
|
359 const T & dereference() const
|
Chris@16
|
360 {
|
Chris@16
|
361 static T dummy;
|
Chris@16
|
362 return dummy;
|
Chris@16
|
363 }
|
Chris@16
|
364
|
Chris@16
|
365 void advance(Difference n)
|
Chris@16
|
366 { m_num -= n; }
|
Chris@16
|
367
|
Chris@16
|
368 Difference distance_to(const this_type &other)const
|
Chris@16
|
369 { return m_num - other.m_num; }
|
Chris@16
|
370 };
|
Chris@16
|
371
|
Chris@16
|
372
|
Chris@16
|
373 template <class T, class Difference = std::ptrdiff_t>
|
Chris@16
|
374 class repeat_iterator
|
Chris@16
|
375 : public std::iterator
|
Chris@16
|
376 <std::random_access_iterator_tag, T, Difference>
|
Chris@16
|
377 {
|
Chris@16
|
378 typedef repeat_iterator<T, Difference> this_type;
|
Chris@16
|
379 public:
|
Chris@16
|
380 explicit repeat_iterator(T &ref, Difference range_size)
|
Chris@16
|
381 : m_ptr(&ref), m_num(range_size){}
|
Chris@16
|
382
|
Chris@16
|
383 //Constructors
|
Chris@16
|
384 repeat_iterator()
|
Chris@16
|
385 : m_ptr(0), m_num(0){}
|
Chris@16
|
386
|
Chris@16
|
387 this_type& operator++()
|
Chris@16
|
388 { increment(); return *this; }
|
Chris@16
|
389
|
Chris@16
|
390 this_type operator++(int)
|
Chris@16
|
391 {
|
Chris@16
|
392 this_type result (*this);
|
Chris@16
|
393 increment();
|
Chris@16
|
394 return result;
|
Chris@16
|
395 }
|
Chris@16
|
396
|
Chris@16
|
397 this_type& operator--()
|
Chris@16
|
398 { increment(); return *this; }
|
Chris@16
|
399
|
Chris@16
|
400 this_type operator--(int)
|
Chris@16
|
401 {
|
Chris@16
|
402 this_type result (*this);
|
Chris@16
|
403 increment();
|
Chris@16
|
404 return result;
|
Chris@16
|
405 }
|
Chris@16
|
406
|
Chris@16
|
407 friend bool operator== (const this_type& i, const this_type& i2)
|
Chris@16
|
408 { return i.equal(i2); }
|
Chris@16
|
409
|
Chris@16
|
410 friend bool operator!= (const this_type& i, const this_type& i2)
|
Chris@16
|
411 { return !(i == i2); }
|
Chris@16
|
412
|
Chris@16
|
413 friend bool operator< (const this_type& i, const this_type& i2)
|
Chris@16
|
414 { return i.less(i2); }
|
Chris@16
|
415
|
Chris@16
|
416 friend bool operator> (const this_type& i, const this_type& i2)
|
Chris@16
|
417 { return i2 < i; }
|
Chris@16
|
418
|
Chris@16
|
419 friend bool operator<= (const this_type& i, const this_type& i2)
|
Chris@16
|
420 { return !(i > i2); }
|
Chris@16
|
421
|
Chris@16
|
422 friend bool operator>= (const this_type& i, const this_type& i2)
|
Chris@16
|
423 { return !(i < i2); }
|
Chris@16
|
424
|
Chris@16
|
425 friend Difference operator- (const this_type& i, const this_type& i2)
|
Chris@16
|
426 { return i2.distance_to(i); }
|
Chris@16
|
427
|
Chris@16
|
428 //Arithmetic
|
Chris@16
|
429 this_type& operator+=(Difference off)
|
Chris@16
|
430 { this->advance(off); return *this; }
|
Chris@16
|
431
|
Chris@16
|
432 this_type operator+(Difference off) const
|
Chris@16
|
433 {
|
Chris@16
|
434 this_type other(*this);
|
Chris@16
|
435 other.advance(off);
|
Chris@16
|
436 return other;
|
Chris@16
|
437 }
|
Chris@16
|
438
|
Chris@16
|
439 friend this_type operator+(Difference off, const this_type& right)
|
Chris@16
|
440 { return right + off; }
|
Chris@16
|
441
|
Chris@16
|
442 this_type& operator-=(Difference off)
|
Chris@16
|
443 { this->advance(-off); return *this; }
|
Chris@16
|
444
|
Chris@16
|
445 this_type operator-(Difference off) const
|
Chris@16
|
446 { return *this + (-off); }
|
Chris@16
|
447
|
Chris@16
|
448 T& operator*() const
|
Chris@16
|
449 { return dereference(); }
|
Chris@16
|
450
|
Chris@16
|
451 T& operator[] (Difference ) const
|
Chris@16
|
452 { return dereference(); }
|
Chris@16
|
453
|
Chris@16
|
454 T *operator->() const
|
Chris@16
|
455 { return &(dereference()); }
|
Chris@16
|
456
|
Chris@16
|
457 private:
|
Chris@16
|
458 T * m_ptr;
|
Chris@16
|
459 Difference m_num;
|
Chris@16
|
460
|
Chris@16
|
461 void increment()
|
Chris@16
|
462 { --m_num; }
|
Chris@16
|
463
|
Chris@16
|
464 void decrement()
|
Chris@16
|
465 { ++m_num; }
|
Chris@16
|
466
|
Chris@16
|
467 bool equal(const this_type &other) const
|
Chris@16
|
468 { return m_num == other.m_num; }
|
Chris@16
|
469
|
Chris@16
|
470 bool less(const this_type &other) const
|
Chris@16
|
471 { return other.m_num < m_num; }
|
Chris@16
|
472
|
Chris@16
|
473 T & dereference() const
|
Chris@16
|
474 { return *m_ptr; }
|
Chris@16
|
475
|
Chris@16
|
476 void advance(Difference n)
|
Chris@16
|
477 { m_num -= n; }
|
Chris@16
|
478
|
Chris@16
|
479 Difference distance_to(const this_type &other)const
|
Chris@16
|
480 { return m_num - other.m_num; }
|
Chris@16
|
481 };
|
Chris@16
|
482
|
Chris@16
|
483 template <class T, class EmplaceFunctor, class Difference /*= std::ptrdiff_t*/>
|
Chris@16
|
484 class emplace_iterator
|
Chris@16
|
485 : public std::iterator
|
Chris@16
|
486 <std::random_access_iterator_tag, T, Difference, const T*, const T &>
|
Chris@16
|
487 {
|
Chris@16
|
488 typedef emplace_iterator this_type;
|
Chris@16
|
489
|
Chris@16
|
490 public:
|
Chris@16
|
491 typedef Difference difference_type;
|
Chris@16
|
492 explicit emplace_iterator(EmplaceFunctor&e)
|
Chris@16
|
493 : m_num(1), m_pe(&e){}
|
Chris@16
|
494
|
Chris@16
|
495 emplace_iterator()
|
Chris@16
|
496 : m_num(0), m_pe(0){}
|
Chris@16
|
497
|
Chris@16
|
498 this_type& operator++()
|
Chris@16
|
499 { increment(); return *this; }
|
Chris@16
|
500
|
Chris@16
|
501 this_type operator++(int)
|
Chris@16
|
502 {
|
Chris@16
|
503 this_type result (*this);
|
Chris@16
|
504 increment();
|
Chris@16
|
505 return result;
|
Chris@16
|
506 }
|
Chris@16
|
507
|
Chris@16
|
508 this_type& operator--()
|
Chris@16
|
509 { decrement(); return *this; }
|
Chris@16
|
510
|
Chris@16
|
511 this_type operator--(int)
|
Chris@16
|
512 {
|
Chris@16
|
513 this_type result (*this);
|
Chris@16
|
514 decrement();
|
Chris@16
|
515 return result;
|
Chris@16
|
516 }
|
Chris@16
|
517
|
Chris@16
|
518 friend bool operator== (const this_type& i, const this_type& i2)
|
Chris@16
|
519 { return i.equal(i2); }
|
Chris@16
|
520
|
Chris@16
|
521 friend bool operator!= (const this_type& i, const this_type& i2)
|
Chris@16
|
522 { return !(i == i2); }
|
Chris@16
|
523
|
Chris@16
|
524 friend bool operator< (const this_type& i, const this_type& i2)
|
Chris@16
|
525 { return i.less(i2); }
|
Chris@16
|
526
|
Chris@16
|
527 friend bool operator> (const this_type& i, const this_type& i2)
|
Chris@16
|
528 { return i2 < i; }
|
Chris@16
|
529
|
Chris@16
|
530 friend bool operator<= (const this_type& i, const this_type& i2)
|
Chris@16
|
531 { return !(i > i2); }
|
Chris@16
|
532
|
Chris@16
|
533 friend bool operator>= (const this_type& i, const this_type& i2)
|
Chris@16
|
534 { return !(i < i2); }
|
Chris@16
|
535
|
Chris@16
|
536 friend difference_type operator- (const this_type& i, const this_type& i2)
|
Chris@16
|
537 { return i2.distance_to(i); }
|
Chris@16
|
538
|
Chris@16
|
539 //Arithmetic
|
Chris@16
|
540 this_type& operator+=(difference_type off)
|
Chris@16
|
541 { this->advance(off); return *this; }
|
Chris@16
|
542
|
Chris@16
|
543 this_type operator+(difference_type off) const
|
Chris@16
|
544 {
|
Chris@16
|
545 this_type other(*this);
|
Chris@16
|
546 other.advance(off);
|
Chris@16
|
547 return other;
|
Chris@16
|
548 }
|
Chris@16
|
549
|
Chris@16
|
550 friend this_type operator+(difference_type off, const this_type& right)
|
Chris@16
|
551 { return right + off; }
|
Chris@16
|
552
|
Chris@16
|
553 this_type& operator-=(difference_type off)
|
Chris@16
|
554 { this->advance(-off); return *this; }
|
Chris@16
|
555
|
Chris@16
|
556 this_type operator-(difference_type off) const
|
Chris@16
|
557 { return *this + (-off); }
|
Chris@16
|
558
|
Chris@16
|
559 //This pseudo-iterator's dereference operations have no sense since value is not
|
Chris@16
|
560 //constructed until ::boost::container::construct_in_place is called.
|
Chris@16
|
561 //So comment them to catch bad uses
|
Chris@16
|
562 //const T& operator*() const;
|
Chris@16
|
563 //const T& operator[](difference_type) const;
|
Chris@16
|
564 //const T* operator->() const;
|
Chris@16
|
565
|
Chris@16
|
566 template<class A>
|
Chris@16
|
567 void construct_in_place(A &a, T* ptr)
|
Chris@16
|
568 { (*m_pe)(a, ptr); }
|
Chris@16
|
569
|
Chris@16
|
570 private:
|
Chris@16
|
571 difference_type m_num;
|
Chris@16
|
572 EmplaceFunctor * m_pe;
|
Chris@16
|
573
|
Chris@16
|
574 void increment()
|
Chris@16
|
575 { --m_num; }
|
Chris@16
|
576
|
Chris@16
|
577 void decrement()
|
Chris@16
|
578 { ++m_num; }
|
Chris@16
|
579
|
Chris@16
|
580 bool equal(const this_type &other) const
|
Chris@16
|
581 { return m_num == other.m_num; }
|
Chris@16
|
582
|
Chris@16
|
583 bool less(const this_type &other) const
|
Chris@16
|
584 { return other.m_num < m_num; }
|
Chris@16
|
585
|
Chris@16
|
586 const T & dereference() const
|
Chris@16
|
587 {
|
Chris@16
|
588 static T dummy;
|
Chris@16
|
589 return dummy;
|
Chris@16
|
590 }
|
Chris@16
|
591
|
Chris@16
|
592 void advance(difference_type n)
|
Chris@16
|
593 { m_num -= n; }
|
Chris@16
|
594
|
Chris@16
|
595 difference_type distance_to(const this_type &other)const
|
Chris@16
|
596 { return difference_type(m_num - other.m_num); }
|
Chris@16
|
597 };
|
Chris@16
|
598
|
Chris@16
|
599 #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
Chris@16
|
600
|
Chris@16
|
601 template<class ...Args>
|
Chris@16
|
602 struct emplace_functor
|
Chris@16
|
603 {
|
Chris@16
|
604 typedef typename container_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t;
|
Chris@16
|
605
|
Chris@16
|
606 emplace_functor(Args&&... args)
|
Chris@16
|
607 : args_(args...)
|
Chris@16
|
608 {}
|
Chris@16
|
609
|
Chris@16
|
610 template<class A, class T>
|
Chris@16
|
611 void operator()(A &a, T *ptr)
|
Chris@16
|
612 { emplace_functor::inplace_impl(a, ptr, index_tuple_t()); }
|
Chris@16
|
613
|
Chris@16
|
614 template<class A, class T, int ...IdxPack>
|
Chris@16
|
615 void inplace_impl(A &a, T* ptr, const container_detail::index_tuple<IdxPack...>&)
|
Chris@16
|
616 {
|
Chris@16
|
617 allocator_traits<A>::construct
|
Chris@16
|
618 (a, ptr, ::boost::forward<Args>(container_detail::get<IdxPack>(args_))...);
|
Chris@16
|
619 }
|
Chris@16
|
620
|
Chris@16
|
621 container_detail::tuple<Args&...> args_;
|
Chris@16
|
622 };
|
Chris@16
|
623
|
Chris@16
|
624 #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
|
Chris@16
|
625
|
Chris@16
|
626 #define BOOST_PP_LOCAL_MACRO(n) \
|
Chris@16
|
627 BOOST_PP_EXPR_IF(n, template <) \
|
Chris@16
|
628 BOOST_PP_ENUM_PARAMS(n, class P) \
|
Chris@16
|
629 BOOST_PP_EXPR_IF(n, >) \
|
Chris@16
|
630 struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
|
Chris@16
|
631 { \
|
Chris@16
|
632 BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \
|
Chris@16
|
633 ( BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _) ) \
|
Chris@16
|
634 BOOST_PP_EXPR_IF(n, :) BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_INIT, _){} \
|
Chris@16
|
635 \
|
Chris@16
|
636 template<class A, class T> \
|
Chris@16
|
637 void operator()(A &a, T *ptr) \
|
Chris@16
|
638 { \
|
Chris@16
|
639 allocator_traits<A>::construct \
|
Chris@16
|
640 (a, ptr BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_MEMBER_FORWARD, _) ); \
|
Chris@16
|
641 } \
|
Chris@16
|
642 BOOST_PP_REPEAT(n, BOOST_CONTAINER_PP_PARAM_DEFINE, _) \
|
Chris@16
|
643 }; \
|
Chris@16
|
644 //!
|
Chris@16
|
645 #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
|
Chris@16
|
646 #include BOOST_PP_LOCAL_ITERATE()
|
Chris@16
|
647
|
Chris@16
|
648 #endif
|
Chris@16
|
649
|
Chris@16
|
650 namespace container_detail {
|
Chris@16
|
651
|
Chris@16
|
652 template<class T>
|
Chris@16
|
653 struct has_iterator_category
|
Chris@16
|
654 {
|
Chris@16
|
655 template <typename X>
|
Chris@16
|
656 static char test(int, typename X::iterator_category*);
|
Chris@16
|
657
|
Chris@16
|
658 template <typename X>
|
Chris@16
|
659 static int test(int, ...);
|
Chris@16
|
660
|
Chris@16
|
661 static const bool value = (1 == sizeof(test<T>(0, 0)));
|
Chris@16
|
662 };
|
Chris@16
|
663
|
Chris@16
|
664
|
Chris@16
|
665 template<class T, bool = has_iterator_category<T>::value >
|
Chris@16
|
666 struct is_input_iterator
|
Chris@16
|
667 {
|
Chris@16
|
668 static const bool value = is_same<typename T::iterator_category, std::input_iterator_tag>::value;
|
Chris@16
|
669 };
|
Chris@16
|
670
|
Chris@16
|
671 template<class T>
|
Chris@16
|
672 struct is_input_iterator<T, false>
|
Chris@16
|
673 {
|
Chris@16
|
674 static const bool value = false;
|
Chris@16
|
675 };
|
Chris@16
|
676
|
Chris@16
|
677 template<class T, bool = has_iterator_category<T>::value >
|
Chris@16
|
678 struct is_forward_iterator
|
Chris@16
|
679 {
|
Chris@16
|
680 static const bool value = is_same<typename T::iterator_category, std::forward_iterator_tag>::value;
|
Chris@16
|
681 };
|
Chris@16
|
682
|
Chris@16
|
683 template<class T>
|
Chris@16
|
684 struct is_forward_iterator<T, false>
|
Chris@16
|
685 {
|
Chris@16
|
686 static const bool value = false;
|
Chris@16
|
687 };
|
Chris@16
|
688
|
Chris@16
|
689 template<class T, bool = has_iterator_category<T>::value >
|
Chris@16
|
690 struct is_bidirectional_iterator
|
Chris@16
|
691 {
|
Chris@16
|
692 static const bool value = is_same<typename T::iterator_category, std::bidirectional_iterator_tag>::value;
|
Chris@16
|
693 };
|
Chris@16
|
694
|
Chris@16
|
695 template<class T>
|
Chris@16
|
696 struct is_bidirectional_iterator<T, false>
|
Chris@16
|
697 {
|
Chris@16
|
698 static const bool value = false;
|
Chris@16
|
699 };
|
Chris@16
|
700
|
Chris@16
|
701 template<class IIterator>
|
Chris@16
|
702 struct iiterator_types
|
Chris@16
|
703 {
|
Chris@16
|
704 typedef typename IIterator::value_type it_value_type;
|
Chris@16
|
705 typedef typename it_value_type::value_type value_type;
|
Chris@16
|
706 typedef typename std::iterator_traits<IIterator>::pointer it_pointer;
|
Chris@16
|
707 typedef typename std::iterator_traits<IIterator>::difference_type difference_type;
|
Chris@16
|
708 typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
|
Chris@16
|
709 template rebind_pointer<value_type>::type pointer;
|
Chris@16
|
710 typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
|
Chris@16
|
711 template rebind_pointer<const value_type>::type const_pointer;
|
Chris@16
|
712 typedef typename ::boost::intrusive::
|
Chris@16
|
713 pointer_traits<pointer>::reference reference;
|
Chris@16
|
714 typedef typename ::boost::intrusive::
|
Chris@16
|
715 pointer_traits<const_pointer>::reference const_reference;
|
Chris@16
|
716 typedef typename IIterator::iterator_category iterator_category;
|
Chris@16
|
717 };
|
Chris@16
|
718
|
Chris@16
|
719 template<class IIterator, bool IsConst>
|
Chris@16
|
720 struct std_iterator
|
Chris@16
|
721 {
|
Chris@16
|
722 typedef typename std::iterator
|
Chris@16
|
723 < typename iiterator_types<IIterator>::iterator_category
|
Chris@16
|
724 , typename iiterator_types<IIterator>::value_type
|
Chris@16
|
725 , typename iiterator_types<IIterator>::difference_type
|
Chris@16
|
726 , typename iiterator_types<IIterator>::const_pointer
|
Chris@16
|
727 , typename iiterator_types<IIterator>::const_reference> type;
|
Chris@16
|
728 };
|
Chris@16
|
729
|
Chris@16
|
730 template<class IIterator>
|
Chris@16
|
731 struct std_iterator<IIterator, false>
|
Chris@16
|
732 {
|
Chris@16
|
733 typedef typename std::iterator
|
Chris@16
|
734 < typename iiterator_types<IIterator>::iterator_category
|
Chris@16
|
735 , typename iiterator_types<IIterator>::value_type
|
Chris@16
|
736 , typename iiterator_types<IIterator>::difference_type
|
Chris@16
|
737 , typename iiterator_types<IIterator>::pointer
|
Chris@16
|
738 , typename iiterator_types<IIterator>::reference> type;
|
Chris@16
|
739 };
|
Chris@16
|
740
|
Chris@16
|
741 template<class IIterator, bool IsConst>
|
Chris@16
|
742 class iterator
|
Chris@16
|
743 : public std_iterator<IIterator, IsConst>::type
|
Chris@16
|
744 {
|
Chris@16
|
745 typedef typename std_iterator<IIterator, IsConst>::type types_t;
|
Chris@16
|
746
|
Chris@16
|
747 public:
|
Chris@16
|
748 typedef typename types_t::value_type value_type;
|
Chris@16
|
749 typedef typename types_t::pointer pointer;
|
Chris@16
|
750 typedef typename types_t::reference reference;
|
Chris@16
|
751
|
Chris@16
|
752 iterator()
|
Chris@16
|
753 {}
|
Chris@16
|
754
|
Chris@16
|
755 explicit iterator(IIterator iit) BOOST_CONTAINER_NOEXCEPT
|
Chris@16
|
756 : m_iit(iit)
|
Chris@16
|
757 {}
|
Chris@16
|
758
|
Chris@16
|
759 iterator(iterator<IIterator, false> const& other) BOOST_CONTAINER_NOEXCEPT
|
Chris@16
|
760 : m_iit(other.get())
|
Chris@16
|
761 {}
|
Chris@16
|
762
|
Chris@16
|
763 iterator& operator++() BOOST_CONTAINER_NOEXCEPT
|
Chris@16
|
764 { ++this->m_iit; return *this; }
|
Chris@16
|
765
|
Chris@16
|
766 iterator operator++(int) BOOST_CONTAINER_NOEXCEPT
|
Chris@16
|
767 {
|
Chris@16
|
768 iterator result (*this);
|
Chris@16
|
769 ++this->m_iit;
|
Chris@16
|
770 return result;
|
Chris@16
|
771 }
|
Chris@16
|
772
|
Chris@16
|
773 iterator& operator--() BOOST_CONTAINER_NOEXCEPT
|
Chris@16
|
774 {
|
Chris@16
|
775 //If the iterator is not a bidirectional iterator, operator-- should not exist
|
Chris@16
|
776 BOOST_STATIC_ASSERT((is_bidirectional_iterator<iterator>::value));
|
Chris@16
|
777 --this->m_iit; return *this;
|
Chris@16
|
778 }
|
Chris@16
|
779
|
Chris@16
|
780 iterator operator--(int) BOOST_CONTAINER_NOEXCEPT
|
Chris@16
|
781 {
|
Chris@16
|
782 iterator result (*this);
|
Chris@16
|
783 --this->m_iit;
|
Chris@16
|
784 return result;
|
Chris@16
|
785 }
|
Chris@16
|
786
|
Chris@16
|
787 friend bool operator== (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT
|
Chris@16
|
788 { return l.m_iit == r.m_iit; }
|
Chris@16
|
789
|
Chris@16
|
790 friend bool operator!= (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT
|
Chris@16
|
791 { return !(l == r); }
|
Chris@16
|
792
|
Chris@16
|
793 reference operator*() const BOOST_CONTAINER_NOEXCEPT
|
Chris@16
|
794 { return (*this->m_iit).get_data(); }
|
Chris@16
|
795
|
Chris@16
|
796 pointer operator->() const BOOST_CONTAINER_NOEXCEPT
|
Chris@16
|
797 { return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*()); }
|
Chris@16
|
798
|
Chris@16
|
799 const IIterator &get() const BOOST_CONTAINER_NOEXCEPT
|
Chris@16
|
800 { return this->m_iit; }
|
Chris@16
|
801
|
Chris@16
|
802 private:
|
Chris@16
|
803 IIterator m_iit;
|
Chris@16
|
804 };
|
Chris@16
|
805
|
Chris@16
|
806 } //namespace container_detail {
|
Chris@16
|
807 } //namespace container {
|
Chris@16
|
808 } //namespace boost {
|
Chris@16
|
809
|
Chris@16
|
810 #include <boost/container/detail/config_end.hpp>
|
Chris@16
|
811
|
Chris@16
|
812 #endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
|