1 //////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2005-2013.
4 // (C) Copyright Gennaro Prota 2003 - 2004.
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)
10 // See http://www.boost.org/libs/container for documentation.
12 //////////////////////////////////////////////////////////////////////////////
14 #ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
15 #define BOOST_CONTAINER_DETAIL_ITERATORS_HPP
17 #ifndef BOOST_CONFIG_HPP
18 # include <boost/config.hpp>
21 #if defined(BOOST_HAS_PRAGMA_ONCE)
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>
34 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
35 #include <boost/move/detail/fwd_macros.hpp>
37 #include <boost/container/detail/variadic_templates_tools.hpp>
39 #include <boost/container/detail/iterator.hpp>
45 class constant_iterator
46 : public ::boost::container::iterator
47 <std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &>
49 typedef constant_iterator<T> this_type;
52 BOOST_CONTAINER_FORCEINLINE explicit constant_iterator(const T &ref, std::size_t range_size)
53 : m_ptr(&ref), m_num(range_size){}
56 BOOST_CONTAINER_FORCEINLINE constant_iterator()
57 : m_ptr(0), m_num(0){}
59 BOOST_CONTAINER_FORCEINLINE constant_iterator& operator++()
60 { increment(); return *this; }
62 BOOST_CONTAINER_FORCEINLINE constant_iterator operator++(int)
64 constant_iterator result (*this);
69 BOOST_CONTAINER_FORCEINLINE constant_iterator& operator--()
70 { decrement(); return *this; }
72 BOOST_CONTAINER_FORCEINLINE constant_iterator operator--(int)
74 constant_iterator result (*this);
79 BOOST_CONTAINER_FORCEINLINE friend bool operator== (const constant_iterator& i, const constant_iterator& i2)
80 { return i.equal(i2); }
82 BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const constant_iterator& i, const constant_iterator& i2)
83 { return !(i == i2); }
85 BOOST_CONTAINER_FORCEINLINE friend bool operator< (const constant_iterator& i, const constant_iterator& i2)
86 { return i.less(i2); }
88 BOOST_CONTAINER_FORCEINLINE friend bool operator> (const constant_iterator& i, const constant_iterator& i2)
91 BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const constant_iterator& i, const constant_iterator& i2)
94 BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const constant_iterator& i, const constant_iterator& i2)
97 BOOST_CONTAINER_FORCEINLINE friend std::ptrdiff_t operator- (const constant_iterator& i, const constant_iterator& i2)
98 { return i2.distance_to(i); }
101 BOOST_CONTAINER_FORCEINLINE constant_iterator& operator+=(std::ptrdiff_t off)
102 { this->advance(off); return *this; }
104 BOOST_CONTAINER_FORCEINLINE constant_iterator operator+(std::ptrdiff_t off) const
106 constant_iterator other(*this);
111 BOOST_CONTAINER_FORCEINLINE friend constant_iterator operator+(std::ptrdiff_t off, const constant_iterator& right)
112 { return right + off; }
114 BOOST_CONTAINER_FORCEINLINE constant_iterator& operator-=(std::ptrdiff_t off)
115 { this->advance(-off); return *this; }
117 BOOST_CONTAINER_FORCEINLINE constant_iterator operator-(std::ptrdiff_t off) const
118 { return *this + (-off); }
120 BOOST_CONTAINER_FORCEINLINE const T& operator[] (std::ptrdiff_t ) const
121 { return dereference(); }
123 BOOST_CONTAINER_FORCEINLINE const T& operator*() const
124 { return dereference(); }
126 BOOST_CONTAINER_FORCEINLINE const T* operator->() const
127 { return &(dereference()); }
129 //Arithmetic unsigned
130 BOOST_CONTAINER_FORCEINLINE constant_iterator& operator+=(std::size_t off)
131 { return *this += std::ptrdiff_t(off); }
133 BOOST_CONTAINER_FORCEINLINE constant_iterator operator+(std::size_t off) const
134 { return *this + std::ptrdiff_t(off); }
136 BOOST_CONTAINER_FORCEINLINE friend constant_iterator operator+(std::size_t off, const constant_iterator& right)
137 { return std::ptrdiff_t(off) + right; }
139 BOOST_CONTAINER_FORCEINLINE constant_iterator& operator-=(std::size_t off)
140 { return *this -= std::ptrdiff_t(off); }
142 BOOST_CONTAINER_FORCEINLINE constant_iterator operator-(std::size_t off) const
143 { return *this - std::ptrdiff_t(off); }
145 BOOST_CONTAINER_FORCEINLINE const T& operator[] (std::size_t off) const
146 { return (*this)[std::ptrdiff_t(off)]; }
152 BOOST_CONTAINER_FORCEINLINE void increment()
155 BOOST_CONTAINER_FORCEINLINE void decrement()
158 BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const
159 { return m_num == other.m_num; }
161 BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const
162 { return other.m_num < m_num; }
164 BOOST_CONTAINER_FORCEINLINE const T & dereference() const
167 BOOST_CONTAINER_FORCEINLINE void advance(std::ptrdiff_t n)
168 { m_num = std::size_t(std::ptrdiff_t(m_num) - n); }
170 BOOST_CONTAINER_FORCEINLINE std::ptrdiff_t distance_to(const this_type &other)const
171 { return std::ptrdiff_t(m_num - other.m_num); }
175 class value_init_construct_iterator
176 : public ::boost::container::iterator
177 <std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &>
179 typedef value_init_construct_iterator<T> this_type;
182 BOOST_CONTAINER_FORCEINLINE explicit value_init_construct_iterator(std::size_t range_size)
183 : m_num(range_size){}
186 BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator()
189 BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator++()
190 { increment(); return *this; }
192 BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator++(int)
194 value_init_construct_iterator result (*this);
199 BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator--()
200 { decrement(); return *this; }
202 BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator--(int)
204 value_init_construct_iterator result (*this);
209 BOOST_CONTAINER_FORCEINLINE friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
210 { return i.equal(i2); }
212 BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
213 { return !(i == i2); }
215 BOOST_CONTAINER_FORCEINLINE friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
216 { return i.less(i2); }
218 BOOST_CONTAINER_FORCEINLINE friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
221 BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
222 { return !(i > i2); }
224 BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
225 { return !(i < i2); }
227 BOOST_CONTAINER_FORCEINLINE friend std::ptrdiff_t operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
228 { return i2.distance_to(i); }
231 BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator+=(std::ptrdiff_t off)
232 { this->advance(off); return *this; }
234 BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator+(std::ptrdiff_t off) const
236 value_init_construct_iterator other(*this);
241 BOOST_CONTAINER_FORCEINLINE friend value_init_construct_iterator operator+(std::ptrdiff_t off, const value_init_construct_iterator& right)
242 { return right + off; }
244 BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator-=(std::ptrdiff_t off)
245 { this->advance(-off); return *this; }
247 BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator-(std::ptrdiff_t off) const
248 { return *this + (-off); }
250 //This pseudo-iterator's dereference operations have no sense since value is not
251 //constructed until ::boost::container::construct_in_place is called.
252 //So comment them to catch bad uses
253 //const T& operator*() const;
254 //const T& operator[](difference_type) const;
255 //const T* operator->() const;
260 BOOST_CONTAINER_FORCEINLINE void increment()
263 BOOST_CONTAINER_FORCEINLINE void decrement()
266 BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const
267 { return m_num == other.m_num; }
269 BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const
270 { return other.m_num < m_num; }
272 BOOST_CONTAINER_FORCEINLINE const T & dereference() const
278 BOOST_CONTAINER_FORCEINLINE void advance(std::ptrdiff_t n)
279 { m_num = std::size_t(std::ptrdiff_t(m_num) - n); }
281 BOOST_CONTAINER_FORCEINLINE std::ptrdiff_t distance_to(const this_type &other)const
282 { return std::ptrdiff_t(m_num - other.m_num); }
286 class default_init_construct_iterator
287 : public ::boost::container::iterator
288 <std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &>
290 typedef default_init_construct_iterator<T> this_type;
293 BOOST_CONTAINER_FORCEINLINE explicit default_init_construct_iterator(std::size_t range_size)
294 : m_num(range_size){}
297 BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator()
300 BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator++()
301 { increment(); return *this; }
303 BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator++(int)
305 default_init_construct_iterator result (*this);
310 BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator--()
311 { decrement(); return *this; }
313 BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator--(int)
315 default_init_construct_iterator result (*this);
320 BOOST_CONTAINER_FORCEINLINE friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
321 { return i.equal(i2); }
323 BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
324 { return !(i == i2); }
326 BOOST_CONTAINER_FORCEINLINE friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
327 { return i.less(i2); }
329 BOOST_CONTAINER_FORCEINLINE friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
332 BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
333 { return !(i > i2); }
335 BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
336 { return !(i < i2); }
338 BOOST_CONTAINER_FORCEINLINE friend std::ptrdiff_t operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
339 { return i2.distance_to(i); }
342 BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator+=(std::ptrdiff_t off)
343 { this->advance(off); return *this; }
345 BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator+(std::ptrdiff_t off) const
347 default_init_construct_iterator other(*this);
352 BOOST_CONTAINER_FORCEINLINE friend default_init_construct_iterator operator+(std::ptrdiff_t off, const default_init_construct_iterator& right)
353 { return right + off; }
355 BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator-=(std::ptrdiff_t off)
356 { this->advance(-off); return *this; }
358 BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator-(std::ptrdiff_t off) const
359 { return *this + (-off); }
361 //This pseudo-iterator's dereference operations have no sense since value is not
362 //constructed until ::boost::container::construct_in_place is called.
363 //So comment them to catch bad uses
364 //const T& operator*() const;
365 //const T& operator[](difference_type) const;
366 //const T* operator->() const;
371 BOOST_CONTAINER_FORCEINLINE void increment()
374 BOOST_CONTAINER_FORCEINLINE void decrement()
377 BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const
378 { return m_num == other.m_num; }
380 BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const
381 { return other.m_num < m_num; }
383 BOOST_CONTAINER_FORCEINLINE const T & dereference() const
389 BOOST_CONTAINER_FORCEINLINE void advance(std::ptrdiff_t n)
390 { m_num = std::size_t(std::ptrdiff_t(m_num) - n); }
392 BOOST_CONTAINER_FORCEINLINE std::ptrdiff_t distance_to(const this_type &other) const
393 { return std::ptrdiff_t(m_num - other.m_num); }
398 class repeat_iterator
399 : public ::boost::container::iterator
400 <std::random_access_iterator_tag, T, std::ptrdiff_t, T*, T&>
402 typedef repeat_iterator<T> this_type;
404 BOOST_CONTAINER_FORCEINLINE explicit repeat_iterator(T &ref, std::size_t range_size)
405 : m_ptr(&ref), m_num(range_size){}
408 BOOST_CONTAINER_FORCEINLINE repeat_iterator()
409 : m_ptr(0), m_num(0){}
411 BOOST_CONTAINER_FORCEINLINE this_type& operator++()
412 { increment(); return *this; }
414 BOOST_CONTAINER_FORCEINLINE this_type operator++(int)
416 this_type result (*this);
421 BOOST_CONTAINER_FORCEINLINE this_type& operator--()
422 { increment(); return *this; }
424 BOOST_CONTAINER_FORCEINLINE this_type operator--(int)
426 this_type result (*this);
431 BOOST_CONTAINER_FORCEINLINE friend bool operator== (const this_type& i, const this_type& i2)
432 { return i.equal(i2); }
434 BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const this_type& i, const this_type& i2)
435 { return !(i == i2); }
437 BOOST_CONTAINER_FORCEINLINE friend bool operator< (const this_type& i, const this_type& i2)
438 { return i.less(i2); }
440 BOOST_CONTAINER_FORCEINLINE friend bool operator> (const this_type& i, const this_type& i2)
443 BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const this_type& i, const this_type& i2)
444 { return !(i > i2); }
446 BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const this_type& i, const this_type& i2)
447 { return !(i < i2); }
449 BOOST_CONTAINER_FORCEINLINE friend std::ptrdiff_t operator- (const this_type& i, const this_type& i2)
450 { return i2.distance_to(i); }
453 BOOST_CONTAINER_FORCEINLINE this_type& operator+=(std::ptrdiff_t off)
454 { this->advance(off); return *this; }
456 BOOST_CONTAINER_FORCEINLINE this_type operator+(std::ptrdiff_t off) const
458 this_type other(*this);
463 BOOST_CONTAINER_FORCEINLINE friend this_type operator+(std::ptrdiff_t off, const this_type& right)
464 { return right + off; }
466 BOOST_CONTAINER_FORCEINLINE this_type& operator-=(std::ptrdiff_t off)
467 { this->advance(-off); return *this; }
469 BOOST_CONTAINER_FORCEINLINE this_type operator-(std::ptrdiff_t off) const
470 { return *this + (-off); }
472 BOOST_CONTAINER_FORCEINLINE T& operator*() const
473 { return dereference(); }
475 BOOST_CONTAINER_FORCEINLINE T& operator[] (std::ptrdiff_t ) const
476 { return dereference(); }
478 BOOST_CONTAINER_FORCEINLINE T *operator->() const
479 { return &(dereference()); }
485 BOOST_CONTAINER_FORCEINLINE void increment()
488 BOOST_CONTAINER_FORCEINLINE void decrement()
491 BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const
492 { return m_num == other.m_num; }
494 BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const
495 { return other.m_num < m_num; }
497 BOOST_CONTAINER_FORCEINLINE T & dereference() const
500 BOOST_CONTAINER_FORCEINLINE void advance(std::ptrdiff_t n)
501 { m_num = std::size_t(std::ptrdiff_t(m_num - n)); }
503 BOOST_CONTAINER_FORCEINLINE std::ptrdiff_t distance_to(const this_type &other)const
504 { return std::ptrdiff_t(m_num - other.m_num); }
507 template <class T, class EmplaceFunctor>
508 class emplace_iterator
509 : public ::boost::container::iterator
510 <std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &>
512 typedef emplace_iterator this_type;
515 typedef std::ptrdiff_t difference_type;
516 BOOST_CONTAINER_FORCEINLINE explicit emplace_iterator(EmplaceFunctor&e)
517 : m_num(1), m_pe(&e){}
519 BOOST_CONTAINER_FORCEINLINE emplace_iterator()
520 : m_num(0), m_pe(0){}
522 BOOST_CONTAINER_FORCEINLINE this_type& operator++()
523 { increment(); return *this; }
525 BOOST_CONTAINER_FORCEINLINE this_type operator++(int)
527 this_type result (*this);
532 BOOST_CONTAINER_FORCEINLINE this_type& operator--()
533 { decrement(); return *this; }
535 BOOST_CONTAINER_FORCEINLINE this_type operator--(int)
537 this_type result (*this);
542 BOOST_CONTAINER_FORCEINLINE friend bool operator== (const this_type& i, const this_type& i2)
543 { return i.equal(i2); }
545 BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const this_type& i, const this_type& i2)
546 { return !(i == i2); }
548 BOOST_CONTAINER_FORCEINLINE friend bool operator< (const this_type& i, const this_type& i2)
549 { return i.less(i2); }
551 BOOST_CONTAINER_FORCEINLINE friend bool operator> (const this_type& i, const this_type& i2)
554 BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const this_type& i, const this_type& i2)
555 { return !(i > i2); }
557 BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const this_type& i, const this_type& i2)
558 { return !(i < i2); }
560 BOOST_CONTAINER_FORCEINLINE friend difference_type operator- (const this_type& i, const this_type& i2)
561 { return i2.distance_to(i); }
564 BOOST_CONTAINER_FORCEINLINE this_type& operator+=(difference_type off)
565 { this->advance(off); return *this; }
567 BOOST_CONTAINER_FORCEINLINE this_type operator+(difference_type off) const
569 this_type other(*this);
574 BOOST_CONTAINER_FORCEINLINE friend this_type operator+(difference_type off, const this_type& right)
575 { return right + off; }
577 BOOST_CONTAINER_FORCEINLINE this_type& operator-=(difference_type off)
578 { this->advance(-off); return *this; }
580 BOOST_CONTAINER_FORCEINLINE this_type operator-(difference_type off) const
581 { return *this + (-off); }
584 //This pseudo-iterator's dereference operations have no sense since value is not
585 //constructed until ::boost::container::construct_in_place is called.
586 //So comment them to catch bad uses
587 const T& operator*() const;
588 const T& operator[](difference_type) const;
589 const T* operator->() const;
592 template<class Allocator>
593 BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T* ptr)
596 template<class DestIt>
597 BOOST_CONTAINER_FORCEINLINE void assign_in_place(DestIt dest)
602 EmplaceFunctor * m_pe;
604 BOOST_CONTAINER_FORCEINLINE void increment()
607 BOOST_CONTAINER_FORCEINLINE void decrement()
610 BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const
611 { return m_num == other.m_num; }
613 BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const
614 { return other.m_num < m_num; }
616 BOOST_CONTAINER_FORCEINLINE const T & dereference() const
622 BOOST_CONTAINER_FORCEINLINE void advance(difference_type n)
625 BOOST_CONTAINER_FORCEINLINE difference_type distance_to(const this_type &other)const
626 { return difference_type(m_num - other.m_num); }
629 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
631 template<class ...Args>
632 struct emplace_functor
634 typedef typename dtl::build_number_seq<sizeof...(Args)>::type index_tuple_t;
636 BOOST_CONTAINER_FORCEINLINE emplace_functor(BOOST_FWD_REF(Args)... args)
640 template<class Allocator, class T>
641 BOOST_CONTAINER_FORCEINLINE void operator()(Allocator &a, T *ptr)
642 { emplace_functor::inplace_impl(a, ptr, index_tuple_t()); }
644 template<class DestIt>
645 BOOST_CONTAINER_FORCEINLINE void operator()(DestIt dest)
646 { emplace_functor::inplace_impl(dest, index_tuple_t()); }
649 template<class Allocator, class T, std::size_t ...IdxPack>
650 BOOST_CONTAINER_FORCEINLINE void inplace_impl(Allocator &a, T* ptr, const dtl::index_tuple<IdxPack...>&)
652 allocator_traits<Allocator>::construct
653 (a, ptr, ::boost::forward<Args>(dtl::get<IdxPack>(args_))...);
656 template<class DestIt, std::size_t ...IdxPack>
657 BOOST_CONTAINER_FORCEINLINE void inplace_impl(DestIt dest, const dtl::index_tuple<IdxPack...>&)
659 typedef typename boost::container::iterator_traits<DestIt>::value_type value_type;
660 value_type && tmp= value_type(::boost::forward<Args>(dtl::get<IdxPack>(args_))...);
661 *dest = ::boost::move(tmp);
664 dtl::tuple<Args&...> args_;
667 template<class ...Args>
668 struct emplace_functor_type
670 typedef emplace_functor<Args...> type;
673 #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
675 //Partial specializations cannot match argument list for primary template, so add an extra argument
676 template <BOOST_MOVE_CLASSDFLT9, class Dummy = void>
677 struct emplace_functor_type;
679 #define BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE(N) \
680 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
681 struct emplace_functor##N\
683 BOOST_CONTAINER_FORCEINLINE explicit emplace_functor##N( BOOST_MOVE_UREF##N )\
684 BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\
686 template<class Allocator, class T>\
687 BOOST_CONTAINER_FORCEINLINE void operator()(Allocator &a, T *ptr)\
688 { allocator_traits<Allocator>::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N); }\
690 template<class DestIt>\
691 BOOST_CONTAINER_FORCEINLINE void operator()(DestIt dest)\
693 typedef typename boost::container::iterator_traits<DestIt>::value_type value_type;\
694 BOOST_MOVE_IF(N, value_type tmp(BOOST_MOVE_MFWD##N), dtl::value_init<value_type> tmp) ;\
695 *dest = ::boost::move(const_cast<value_type &>(BOOST_MOVE_IF(N, tmp, tmp.get())));\
701 template <BOOST_MOVE_CLASS##N>\
702 struct emplace_functor_type<BOOST_MOVE_TARG##N>\
704 typedef emplace_functor##N BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N type;\
708 BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE)
710 #undef BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE
717 struct has_iterator_category
719 struct two { char _[2]; };
721 template <typename X>
722 static char test(int, typename X::iterator_category*);
724 template <typename X>
725 static two test(int, ...);
727 static const bool value = (1 == sizeof(test<T>(0, 0)));
731 template<class T, bool = has_iterator_category<T>::value >
732 struct is_input_iterator
734 static const bool value = is_same<typename T::iterator_category, std::input_iterator_tag>::value;
738 struct is_input_iterator<T, false>
740 static const bool value = false;
744 struct is_not_input_iterator
746 static const bool value = !is_input_iterator<T>::value;
749 template<class T, bool = has_iterator_category<T>::value >
750 struct is_forward_iterator
752 static const bool value = is_same<typename T::iterator_category, std::forward_iterator_tag>::value;
756 struct is_forward_iterator<T, false>
758 static const bool value = false;
761 template<class T, bool = has_iterator_category<T>::value >
762 struct is_bidirectional_iterator
764 static const bool value = is_same<typename T::iterator_category, std::bidirectional_iterator_tag>::value;
768 struct is_bidirectional_iterator<T, false>
770 static const bool value = false;
773 template<class IINodeType>
774 struct iiterator_node_value_type {
775 typedef typename IINodeType::value_type type;
778 template<class IIterator>
779 struct iiterator_types
781 typedef typename IIterator::value_type it_value_type;
782 typedef typename iiterator_node_value_type<it_value_type>::type value_type;
783 typedef typename boost::container::iterator_traits<IIterator>::pointer it_pointer;
784 typedef typename boost::container::iterator_traits<IIterator>::difference_type difference_type;
785 typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
786 template rebind_pointer<value_type>::type pointer;
787 typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
788 template rebind_pointer<const value_type>::type const_pointer;
789 typedef typename ::boost::intrusive::
790 pointer_traits<pointer>::reference reference;
791 typedef typename ::boost::intrusive::
792 pointer_traits<const_pointer>::reference const_reference;
793 typedef typename IIterator::iterator_category iterator_category;
796 template<class IIterator, bool IsConst>
797 struct iterator_types
799 typedef typename ::boost::container::iterator
800 < typename iiterator_types<IIterator>::iterator_category
801 , typename iiterator_types<IIterator>::value_type
802 , typename iiterator_types<IIterator>::difference_type
803 , typename iiterator_types<IIterator>::const_pointer
804 , typename iiterator_types<IIterator>::const_reference> type;
807 template<class IIterator>
808 struct iterator_types<IIterator, false>
810 typedef typename ::boost::container::iterator
811 < typename iiterator_types<IIterator>::iterator_category
812 , typename iiterator_types<IIterator>::value_type
813 , typename iiterator_types<IIterator>::difference_type
814 , typename iiterator_types<IIterator>::pointer
815 , typename iiterator_types<IIterator>::reference> type;
818 template<class IIterator, bool IsConst>
819 class iterator_from_iiterator
821 typedef typename iterator_types<IIterator, IsConst>::type types_t;
825 IIterator get() const
826 { return IIterator(); }
828 typedef typename dtl::if_c< IsConst
829 , iterator_from_iiterator<IIterator, false>
830 , nat>::type nonconst_iterator;
833 typedef typename types_t::pointer pointer;
834 typedef typename types_t::reference reference;
835 typedef typename types_t::difference_type difference_type;
836 typedef typename types_t::iterator_category iterator_category;
837 typedef typename types_t::value_type value_type;
839 BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator()
843 BOOST_CONTAINER_FORCEINLINE explicit iterator_from_iiterator(IIterator iit) BOOST_NOEXCEPT_OR_NOTHROW
847 BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator(const iterator_from_iiterator& other) BOOST_NOEXCEPT_OR_NOTHROW
851 BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator(const nonconst_iterator& other) BOOST_NOEXCEPT_OR_NOTHROW
855 BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator=(const iterator_from_iiterator& other) BOOST_NOEXCEPT_OR_NOTHROW
856 { m_iit = other.get(); return *this; }
858 BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
859 { ++this->m_iit; return *this; }
861 BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
863 iterator_from_iiterator result (*this);
868 BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
870 //If the iterator_from_iiterator is not a bidirectional iterator, operator-- should not exist
871 BOOST_STATIC_ASSERT((is_bidirectional_iterator<iterator_from_iiterator>::value));
872 --this->m_iit; return *this;
875 BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
877 iterator_from_iiterator result (*this);
882 BOOST_CONTAINER_FORCEINLINE friend bool operator== (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW
883 { return l.m_iit == r.m_iit; }
885 BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW
886 { return !(l == r); }
888 BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
889 { return this->m_iit->get_data(); }
891 BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
892 { return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*()); }
894 BOOST_CONTAINER_FORCEINLINE const IIterator &get() const BOOST_NOEXCEPT_OR_NOTHROW
895 { return this->m_iit; }
903 using ::boost::intrusive::reverse_iterator;
905 } //namespace container {
906 } //namespace boost {
908 #include <boost/container/detail/config_end.hpp>
910 #endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP