]>
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: | |
52 | explicit constant_iterator(const T &ref, Difference range_size) | |
53 | : m_ptr(&ref), m_num(range_size){} | |
54 | ||
55 | //Constructors | |
56 | constant_iterator() | |
57 | : m_ptr(0), m_num(0){} | |
58 | ||
59 | constant_iterator& operator++() | |
60 | { increment(); return *this; } | |
61 | ||
62 | constant_iterator operator++(int) | |
63 | { | |
64 | constant_iterator result (*this); | |
65 | increment(); | |
66 | return result; | |
67 | } | |
68 | ||
69 | constant_iterator& operator--() | |
70 | { decrement(); return *this; } | |
71 | ||
72 | constant_iterator operator--(int) | |
73 | { | |
74 | constant_iterator result (*this); | |
75 | decrement(); | |
76 | return result; | |
77 | } | |
78 | ||
79 | friend bool operator== (const constant_iterator& i, const constant_iterator& i2) | |
80 | { return i.equal(i2); } | |
81 | ||
82 | friend bool operator!= (const constant_iterator& i, const constant_iterator& i2) | |
83 | { return !(i == i2); } | |
84 | ||
85 | friend bool operator< (const constant_iterator& i, const constant_iterator& i2) | |
86 | { return i.less(i2); } | |
87 | ||
88 | friend bool operator> (const constant_iterator& i, const constant_iterator& i2) | |
89 | { return i2 < i; } | |
90 | ||
91 | friend bool operator<= (const constant_iterator& i, const constant_iterator& i2) | |
92 | { return !(i > i2); } | |
93 | ||
94 | friend bool operator>= (const constant_iterator& i, const constant_iterator& i2) | |
95 | { return !(i < i2); } | |
96 | ||
97 | friend Difference operator- (const constant_iterator& i, const constant_iterator& i2) | |
98 | { return i2.distance_to(i); } | |
99 | ||
100 | //Arithmetic | |
101 | constant_iterator& operator+=(Difference off) | |
102 | { this->advance(off); return *this; } | |
103 | ||
104 | constant_iterator operator+(Difference off) const | |
105 | { | |
106 | constant_iterator other(*this); | |
107 | other.advance(off); | |
108 | return other; | |
109 | } | |
110 | ||
111 | friend constant_iterator operator+(Difference off, const constant_iterator& right) | |
112 | { return right + off; } | |
113 | ||
114 | constant_iterator& operator-=(Difference off) | |
115 | { this->advance(-off); return *this; } | |
116 | ||
117 | constant_iterator operator-(Difference off) const | |
118 | { return *this + (-off); } | |
119 | ||
120 | const T& operator*() const | |
121 | { return dereference(); } | |
122 | ||
123 | const T& operator[] (Difference ) const | |
124 | { return dereference(); } | |
125 | ||
126 | const T* operator->() const | |
127 | { return &(dereference()); } | |
128 | ||
129 | private: | |
130 | const T * m_ptr; | |
131 | Difference m_num; | |
132 | ||
133 | void increment() | |
134 | { --m_num; } | |
135 | ||
136 | void decrement() | |
137 | { ++m_num; } | |
138 | ||
139 | bool equal(const this_type &other) const | |
140 | { return m_num == other.m_num; } | |
141 | ||
142 | bool less(const this_type &other) const | |
143 | { return other.m_num < m_num; } | |
144 | ||
145 | const T & dereference() const | |
146 | { return *m_ptr; } | |
147 | ||
148 | void advance(Difference n) | |
149 | { m_num -= n; } | |
150 | ||
151 | Difference distance_to(const this_type &other)const | |
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: | |
163 | explicit value_init_construct_iterator(Difference range_size) | |
164 | : m_num(range_size){} | |
165 | ||
166 | //Constructors | |
167 | value_init_construct_iterator() | |
168 | : m_num(0){} | |
169 | ||
170 | value_init_construct_iterator& operator++() | |
171 | { increment(); return *this; } | |
172 | ||
173 | value_init_construct_iterator operator++(int) | |
174 | { | |
175 | value_init_construct_iterator result (*this); | |
176 | increment(); | |
177 | return result; | |
178 | } | |
179 | ||
180 | value_init_construct_iterator& operator--() | |
181 | { decrement(); return *this; } | |
182 | ||
183 | value_init_construct_iterator operator--(int) | |
184 | { | |
185 | value_init_construct_iterator result (*this); | |
186 | decrement(); | |
187 | return result; | |
188 | } | |
189 | ||
190 | friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) | |
191 | { return i.equal(i2); } | |
192 | ||
193 | friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) | |
194 | { return !(i == i2); } | |
195 | ||
196 | friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) | |
197 | { return i.less(i2); } | |
198 | ||
199 | friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) | |
200 | { return i2 < i; } | |
201 | ||
202 | friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) | |
203 | { return !(i > i2); } | |
204 | ||
205 | friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) | |
206 | { return !(i < i2); } | |
207 | ||
208 | friend Difference operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) | |
209 | { return i2.distance_to(i); } | |
210 | ||
211 | //Arithmetic | |
212 | value_init_construct_iterator& operator+=(Difference off) | |
213 | { this->advance(off); return *this; } | |
214 | ||
215 | value_init_construct_iterator operator+(Difference off) const | |
216 | { | |
217 | value_init_construct_iterator other(*this); | |
218 | other.advance(off); | |
219 | return other; | |
220 | } | |
221 | ||
222 | friend value_init_construct_iterator operator+(Difference off, const value_init_construct_iterator& right) | |
223 | { return right + off; } | |
224 | ||
225 | value_init_construct_iterator& operator-=(Difference off) | |
226 | { this->advance(-off); return *this; } | |
227 | ||
228 | value_init_construct_iterator operator-(Difference off) const | |
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 | ||
241 | void increment() | |
242 | { --m_num; } | |
243 | ||
244 | void decrement() | |
245 | { ++m_num; } | |
246 | ||
247 | bool equal(const this_type &other) const | |
248 | { return m_num == other.m_num; } | |
249 | ||
250 | bool less(const this_type &other) const | |
251 | { return other.m_num < m_num; } | |
252 | ||
253 | const T & dereference() const | |
254 | { | |
255 | static T dummy; | |
256 | return dummy; | |
257 | } | |
258 | ||
259 | void advance(Difference n) | |
260 | { m_num -= n; } | |
261 | ||
262 | Difference distance_to(const this_type &other)const | |
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: | |
274 | explicit default_init_construct_iterator(Difference range_size) | |
275 | : m_num(range_size){} | |
276 | ||
277 | //Constructors | |
278 | default_init_construct_iterator() | |
279 | : m_num(0){} | |
280 | ||
281 | default_init_construct_iterator& operator++() | |
282 | { increment(); return *this; } | |
283 | ||
284 | default_init_construct_iterator operator++(int) | |
285 | { | |
286 | default_init_construct_iterator result (*this); | |
287 | increment(); | |
288 | return result; | |
289 | } | |
290 | ||
291 | default_init_construct_iterator& operator--() | |
292 | { decrement(); return *this; } | |
293 | ||
294 | default_init_construct_iterator operator--(int) | |
295 | { | |
296 | default_init_construct_iterator result (*this); | |
297 | decrement(); | |
298 | return result; | |
299 | } | |
300 | ||
301 | friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) | |
302 | { return i.equal(i2); } | |
303 | ||
304 | friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) | |
305 | { return !(i == i2); } | |
306 | ||
307 | friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) | |
308 | { return i.less(i2); } | |
309 | ||
310 | friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) | |
311 | { return i2 < i; } | |
312 | ||
313 | friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) | |
314 | { return !(i > i2); } | |
315 | ||
316 | friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) | |
317 | { return !(i < i2); } | |
318 | ||
319 | friend Difference operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) | |
320 | { return i2.distance_to(i); } | |
321 | ||
322 | //Arithmetic | |
323 | default_init_construct_iterator& operator+=(Difference off) | |
324 | { this->advance(off); return *this; } | |
325 | ||
326 | default_init_construct_iterator operator+(Difference off) const | |
327 | { | |
328 | default_init_construct_iterator other(*this); | |
329 | other.advance(off); | |
330 | return other; | |
331 | } | |
332 | ||
333 | friend default_init_construct_iterator operator+(Difference off, const default_init_construct_iterator& right) | |
334 | { return right + off; } | |
335 | ||
336 | default_init_construct_iterator& operator-=(Difference off) | |
337 | { this->advance(-off); return *this; } | |
338 | ||
339 | default_init_construct_iterator operator-(Difference off) const | |
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 | ||
352 | void increment() | |
353 | { --m_num; } | |
354 | ||
355 | void decrement() | |
356 | { ++m_num; } | |
357 | ||
358 | bool equal(const this_type &other) const | |
359 | { return m_num == other.m_num; } | |
360 | ||
361 | bool less(const this_type &other) const | |
362 | { return other.m_num < m_num; } | |
363 | ||
364 | const T & dereference() const | |
365 | { | |
366 | static T dummy; | |
367 | return dummy; | |
368 | } | |
369 | ||
370 | void advance(Difference n) | |
371 | { m_num -= n; } | |
372 | ||
373 | Difference distance_to(const this_type &other)const | |
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: | |
385 | explicit repeat_iterator(T &ref, Difference range_size) | |
386 | : m_ptr(&ref), m_num(range_size){} | |
387 | ||
388 | //Constructors | |
389 | repeat_iterator() | |
390 | : m_ptr(0), m_num(0){} | |
391 | ||
392 | this_type& operator++() | |
393 | { increment(); return *this; } | |
394 | ||
395 | this_type operator++(int) | |
396 | { | |
397 | this_type result (*this); | |
398 | increment(); | |
399 | return result; | |
400 | } | |
401 | ||
402 | this_type& operator--() | |
403 | { increment(); return *this; } | |
404 | ||
405 | this_type operator--(int) | |
406 | { | |
407 | this_type result (*this); | |
408 | increment(); | |
409 | return result; | |
410 | } | |
411 | ||
412 | friend bool operator== (const this_type& i, const this_type& i2) | |
413 | { return i.equal(i2); } | |
414 | ||
415 | friend bool operator!= (const this_type& i, const this_type& i2) | |
416 | { return !(i == i2); } | |
417 | ||
418 | friend bool operator< (const this_type& i, const this_type& i2) | |
419 | { return i.less(i2); } | |
420 | ||
421 | friend bool operator> (const this_type& i, const this_type& i2) | |
422 | { return i2 < i; } | |
423 | ||
424 | friend bool operator<= (const this_type& i, const this_type& i2) | |
425 | { return !(i > i2); } | |
426 | ||
427 | friend bool operator>= (const this_type& i, const this_type& i2) | |
428 | { return !(i < i2); } | |
429 | ||
430 | friend Difference operator- (const this_type& i, const this_type& i2) | |
431 | { return i2.distance_to(i); } | |
432 | ||
433 | //Arithmetic | |
434 | this_type& operator+=(Difference off) | |
435 | { this->advance(off); return *this; } | |
436 | ||
437 | this_type operator+(Difference off) const | |
438 | { | |
439 | this_type other(*this); | |
440 | other.advance(off); | |
441 | return other; | |
442 | } | |
443 | ||
444 | friend this_type operator+(Difference off, const this_type& right) | |
445 | { return right + off; } | |
446 | ||
447 | this_type& operator-=(Difference off) | |
448 | { this->advance(-off); return *this; } | |
449 | ||
450 | this_type operator-(Difference off) const | |
451 | { return *this + (-off); } | |
452 | ||
453 | T& operator*() const | |
454 | { return dereference(); } | |
455 | ||
456 | T& operator[] (Difference ) const | |
457 | { return dereference(); } | |
458 | ||
459 | T *operator->() const | |
460 | { return &(dereference()); } | |
461 | ||
462 | private: | |
463 | T * m_ptr; | |
464 | Difference m_num; | |
465 | ||
466 | void increment() | |
467 | { --m_num; } | |
468 | ||
469 | void decrement() | |
470 | { ++m_num; } | |
471 | ||
472 | bool equal(const this_type &other) const | |
473 | { return m_num == other.m_num; } | |
474 | ||
475 | bool less(const this_type &other) const | |
476 | { return other.m_num < m_num; } | |
477 | ||
478 | T & dereference() const | |
479 | { return *m_ptr; } | |
480 | ||
481 | void advance(Difference n) | |
482 | { m_num -= n; } | |
483 | ||
484 | Difference distance_to(const this_type &other)const | |
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 | ||
506 | this_type operator++(int) | |
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 | ||
516 | this_type operator--(int) | |
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 | ||
548 | this_type operator+(difference_type off) const | |
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> | |
574 | void construct_in_place(Allocator &a, T* ptr) | |
575 | { (*m_pe)(a, ptr); } | |
576 | ||
577 | template<class DestIt> | |
578 | void assign_in_place(DestIt dest) | |
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 | { | |
615 | typedef typename container_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t; | |
616 | ||
617 | emplace_functor(BOOST_FWD_REF(Args)... args) | |
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> | |
631 | BOOST_CONTAINER_FORCEINLINE void inplace_impl(Allocator &a, T* ptr, const container_detail::index_tuple<IdxPack...>&) | |
632 | { | |
633 | allocator_traits<Allocator>::construct | |
634 | (a, ptr, ::boost::forward<Args>(container_detail::get<IdxPack>(args_))...); | |
635 | } | |
636 | ||
637 | template<class DestIt, std::size_t ...IdxPack> | |
638 | BOOST_CONTAINER_FORCEINLINE void inplace_impl(DestIt dest, const container_detail::index_tuple<IdxPack...>&) | |
639 | { | |
640 | typedef typename boost::container::iterator_traits<DestIt>::value_type value_type; | |
641 | value_type && tmp= value_type(::boost::forward<Args>(container_detail::get<IdxPack>(args_))...); | |
642 | *dest = ::boost::move(tmp); | |
643 | } | |
644 | ||
645 | container_detail::tuple<Args&...> args_; | |
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 | {\ | |
664 | explicit emplace_functor##N( BOOST_MOVE_UREF##N )\ | |
665 | BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\ | |
666 | \ | |
667 | template<class Allocator, class T>\ | |
668 | void operator()(Allocator &a, T *ptr)\ | |
669 | { allocator_traits<Allocator>::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N); }\ | |
670 | \ | |
671 | template<class DestIt>\ | |
672 | void operator()(DestIt dest)\ | |
673 | {\ | |
674 | typedef typename boost::container::iterator_traits<DestIt>::value_type value_type;\ | |
675 | BOOST_MOVE_IF(N, value_type tmp(BOOST_MOVE_MFWD##N), container_detail::value_init<value_type> tmp) ;\ | |
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 | ||
695 | namespace container_detail { | |
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 | { | |
802 | typedef typename iterator_types<IIterator, IsConst>::type types_t; | |
803 | ||
804 | public: | |
805 | typedef typename types_t::pointer pointer; | |
806 | typedef typename types_t::reference reference; | |
807 | typedef typename types_t::difference_type difference_type; | |
808 | typedef typename types_t::iterator_category iterator_category; | |
809 | typedef typename types_t::value_type value_type; | |
810 | ||
811 | BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator() | |
812 | {} | |
813 | ||
814 | BOOST_CONTAINER_FORCEINLINE explicit iterator_from_iiterator(IIterator iit) BOOST_NOEXCEPT_OR_NOTHROW | |
815 | : m_iit(iit) | |
816 | {} | |
817 | ||
818 | BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator(iterator_from_iiterator<IIterator, false> const& other) BOOST_NOEXCEPT_OR_NOTHROW | |
819 | : m_iit(other.get()) | |
820 | {} | |
821 | ||
822 | BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW | |
823 | { ++this->m_iit; return *this; } | |
824 | ||
825 | BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW | |
826 | { | |
827 | iterator_from_iiterator result (*this); | |
828 | ++this->m_iit; | |
829 | return result; | |
830 | } | |
831 | ||
832 | BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW | |
833 | { | |
834 | //If the iterator_from_iiterator is not a bidirectional iterator, operator-- should not exist | |
835 | BOOST_STATIC_ASSERT((is_bidirectional_iterator<iterator_from_iiterator>::value)); | |
836 | --this->m_iit; return *this; | |
837 | } | |
838 | ||
839 | BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW | |
840 | { | |
841 | iterator_from_iiterator result (*this); | |
842 | --this->m_iit; | |
843 | return result; | |
844 | } | |
845 | ||
846 | BOOST_CONTAINER_FORCEINLINE friend bool operator== (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW | |
847 | { return l.m_iit == r.m_iit; } | |
848 | ||
849 | BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW | |
850 | { return !(l == r); } | |
851 | ||
852 | BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW | |
853 | { return this->m_iit->get_data(); } | |
854 | ||
855 | BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW | |
856 | { return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*()); } | |
857 | ||
858 | BOOST_CONTAINER_FORCEINLINE const IIterator &get() const BOOST_NOEXCEPT_OR_NOTHROW | |
859 | { return this->m_iit; } | |
860 | ||
861 | private: | |
862 | IIterator m_iit; | |
863 | }; | |
864 | ||
865 | } //namespace container_detail { | |
866 | ||
867 | using ::boost::intrusive::reverse_iterator; | |
868 | ||
869 | } //namespace container { | |
870 | } //namespace boost { | |
871 | ||
872 | #include <boost/container/detail/config_end.hpp> | |
873 | ||
874 | #endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP |