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 | : m_iit() |
813 | {} |
814 | |
815 | BOOST_CONTAINER_FORCEINLINE explicit iterator_from_iiterator(IIterator iit) BOOST_NOEXCEPT_OR_NOTHROW |
816 | : m_iit(iit) |
817 | {} |
818 | |
819 | BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator(iterator_from_iiterator<IIterator, false> const& other) BOOST_NOEXCEPT_OR_NOTHROW |
820 | : m_iit(other.get()) |
821 | {} |
822 | |
823 | BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW |
824 | { ++this->m_iit; return *this; } |
825 | |
826 | BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW |
827 | { |
828 | iterator_from_iiterator result (*this); |
829 | ++this->m_iit; |
830 | return result; |
831 | } |
832 | |
833 | BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW |
834 | { |
835 | //If the iterator_from_iiterator is not a bidirectional iterator, operator-- should not exist |
836 | BOOST_STATIC_ASSERT((is_bidirectional_iterator<iterator_from_iiterator>::value)); |
837 | --this->m_iit; return *this; |
838 | } |
839 | |
840 | BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW |
841 | { |
842 | iterator_from_iiterator result (*this); |
843 | --this->m_iit; |
844 | return result; |
845 | } |
846 | |
847 | BOOST_CONTAINER_FORCEINLINE friend bool operator== (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW |
848 | { return l.m_iit == r.m_iit; } |
849 | |
850 | BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW |
851 | { return !(l == r); } |
852 | |
853 | BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW |
854 | { return this->m_iit->get_data(); } |
855 | |
856 | BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW |
857 | { return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*()); } |
858 | |
859 | BOOST_CONTAINER_FORCEINLINE const IIterator &get() const BOOST_NOEXCEPT_OR_NOTHROW |
860 | { return this->m_iit; } |
861 | |
862 | private: |
863 | IIterator m_iit; |
864 | }; |
865 | |
866 | } //namespace container_detail { |
867 | |
868 | using ::boost::intrusive::reverse_iterator; |
869 | |
870 | } //namespace container { |
871 | } //namespace boost { |
872 | |
873 | #include <boost/container/detail/config_end.hpp> |
874 | |
875 | #endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP |
876 | |