]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/container/detail/iterators.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / container / detail / iterators.hpp
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