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