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/static_assert.hpp>
30 #include <boost/move/utility_core.hpp>
31 #include <boost/intrusive/detail/reverse_iterator.hpp>
32 
33 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
34 #include <boost/move/detail/fwd_macros.hpp>
35 #else
36 #include <boost/container/detail/variadic_templates_tools.hpp>
37 #endif
38 #include <boost/container/detail/iterator.hpp>
39 
40 namespace boost {
41 namespace container {
42 
43 template <class T, class Difference = std::ptrdiff_t>
44 class constant_iterator
45   : public ::boost::container::iterator
46       <std::random_access_iterator_tag, T, Difference, const T*, const T &>
47 {
48    typedef  constant_iterator<T, Difference> this_type;
49 
50    public:
constant_iterator(const T & ref,Difference range_size)51    explicit constant_iterator(const T &ref, Difference range_size)
52       :  m_ptr(&ref), m_num(range_size){}
53 
54    //Constructors
constant_iterator()55    constant_iterator()
56       :  m_ptr(0), m_num(0){}
57 
operator ++()58    constant_iterator& operator++()
59    { increment();   return *this;   }
60 
operator ++(int)61    constant_iterator operator++(int)
62    {
63       constant_iterator result (*this);
64       increment();
65       return result;
66    }
67 
operator --()68    constant_iterator& operator--()
69    { decrement();   return *this;   }
70 
operator --(int)71    constant_iterator operator--(int)
72    {
73       constant_iterator result (*this);
74       decrement();
75       return result;
76    }
77 
operator ==(const constant_iterator & i,const constant_iterator & i2)78    friend bool operator== (const constant_iterator& i, const constant_iterator& i2)
79    { return i.equal(i2); }
80 
operator !=(const constant_iterator & i,const constant_iterator & i2)81    friend bool operator!= (const constant_iterator& i, const constant_iterator& i2)
82    { return !(i == i2); }
83 
operator <(const constant_iterator & i,const constant_iterator & i2)84    friend bool operator< (const constant_iterator& i, const constant_iterator& i2)
85    { return i.less(i2); }
86 
operator >(const constant_iterator & i,const constant_iterator & i2)87    friend bool operator> (const constant_iterator& i, const constant_iterator& i2)
88    { return i2 < i; }
89 
operator <=(const constant_iterator & i,const constant_iterator & i2)90    friend bool operator<= (const constant_iterator& i, const constant_iterator& i2)
91    { return !(i > i2); }
92 
operator >=(const constant_iterator & i,const constant_iterator & i2)93    friend bool operator>= (const constant_iterator& i, const constant_iterator& i2)
94    { return !(i < i2); }
95 
operator -(const constant_iterator & i,const constant_iterator & i2)96    friend Difference operator- (const constant_iterator& i, const constant_iterator& i2)
97    { return i2.distance_to(i); }
98 
99    //Arithmetic
operator +=(Difference off)100    constant_iterator& operator+=(Difference off)
101    {  this->advance(off); return *this;   }
102 
operator +(Difference off) const103    constant_iterator operator+(Difference off) const
104    {
105       constant_iterator other(*this);
106       other.advance(off);
107       return other;
108    }
109 
operator +(Difference off,const constant_iterator & right)110    friend constant_iterator operator+(Difference off, const constant_iterator& right)
111    {  return right + off; }
112 
operator -=(Difference off)113    constant_iterator& operator-=(Difference off)
114    {  this->advance(-off); return *this;   }
115 
operator -(Difference off) const116    constant_iterator operator-(Difference off) const
117    {  return *this + (-off);  }
118 
operator *() const119    const T& operator*() const
120    { return dereference(); }
121 
operator [](Difference) const122    const T& operator[] (Difference ) const
123    { return dereference(); }
124 
operator ->() const125    const T* operator->() const
126    { return &(dereference()); }
127 
128    private:
129    const T *   m_ptr;
130    Difference  m_num;
131 
increment()132    void increment()
133    { --m_num; }
134 
decrement()135    void decrement()
136    { ++m_num; }
137 
equal(const this_type & other) const138    bool equal(const this_type &other) const
139    {  return m_num == other.m_num;   }
140 
less(const this_type & other) const141    bool less(const this_type &other) const
142    {  return other.m_num < m_num;   }
143 
dereference() const144    const T & dereference() const
145    { return *m_ptr; }
146 
advance(Difference n)147    void advance(Difference n)
148    {  m_num -= n; }
149 
distance_to(const this_type & other) const150    Difference distance_to(const this_type &other)const
151    {  return m_num - other.m_num;   }
152 };
153 
154 template <class T, class Difference>
155 class value_init_construct_iterator
156   : public ::boost::container::iterator
157       <std::random_access_iterator_tag, T, Difference, const T*, const T &>
158 {
159    typedef  value_init_construct_iterator<T, Difference> this_type;
160 
161    public:
value_init_construct_iterator(Difference range_size)162    explicit value_init_construct_iterator(Difference range_size)
163       :  m_num(range_size){}
164 
165    //Constructors
value_init_construct_iterator()166    value_init_construct_iterator()
167       :  m_num(0){}
168 
operator ++()169    value_init_construct_iterator& operator++()
170    { increment();   return *this;   }
171 
operator ++(int)172    value_init_construct_iterator operator++(int)
173    {
174       value_init_construct_iterator result (*this);
175       increment();
176       return result;
177    }
178 
operator --()179    value_init_construct_iterator& operator--()
180    { decrement();   return *this;   }
181 
operator --(int)182    value_init_construct_iterator operator--(int)
183    {
184       value_init_construct_iterator result (*this);
185       decrement();
186       return result;
187    }
188 
operator ==(const value_init_construct_iterator & i,const value_init_construct_iterator & i2)189    friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
190    { return i.equal(i2); }
191 
operator !=(const value_init_construct_iterator & i,const value_init_construct_iterator & i2)192    friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
193    { return !(i == i2); }
194 
operator <(const value_init_construct_iterator & i,const value_init_construct_iterator & i2)195    friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
196    { return i.less(i2); }
197 
operator >(const value_init_construct_iterator & i,const value_init_construct_iterator & i2)198    friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
199    { return i2 < i; }
200 
operator <=(const value_init_construct_iterator & i,const value_init_construct_iterator & i2)201    friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
202    { return !(i > i2); }
203 
operator >=(const value_init_construct_iterator & i,const value_init_construct_iterator & i2)204    friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
205    { return !(i < i2); }
206 
operator -(const value_init_construct_iterator & i,const value_init_construct_iterator & i2)207    friend Difference operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
208    { return i2.distance_to(i); }
209 
210    //Arithmetic
operator +=(Difference off)211    value_init_construct_iterator& operator+=(Difference off)
212    {  this->advance(off); return *this;   }
213 
operator +(Difference off) const214    value_init_construct_iterator operator+(Difference off) const
215    {
216       value_init_construct_iterator other(*this);
217       other.advance(off);
218       return other;
219    }
220 
operator +(Difference off,const value_init_construct_iterator & right)221    friend value_init_construct_iterator operator+(Difference off, const value_init_construct_iterator& right)
222    {  return right + off; }
223 
operator -=(Difference off)224    value_init_construct_iterator& operator-=(Difference off)
225    {  this->advance(-off); return *this;   }
226 
operator -(Difference off) const227    value_init_construct_iterator operator-(Difference off) const
228    {  return *this + (-off);  }
229 
230    //This pseudo-iterator's dereference operations have no sense since value is not
231    //constructed until ::boost::container::construct_in_place is called.
232    //So comment them to catch bad uses
233    //const T& operator*() const;
234    //const T& operator[](difference_type) const;
235    //const T* operator->() const;
236 
237    private:
238    Difference  m_num;
239 
increment()240    void increment()
241    { --m_num; }
242 
decrement()243    void decrement()
244    { ++m_num; }
245 
equal(const this_type & other) const246    bool equal(const this_type &other) const
247    {  return m_num == other.m_num;   }
248 
less(const this_type & other) const249    bool less(const this_type &other) const
250    {  return other.m_num < m_num;   }
251 
dereference() const252    const T & dereference() const
253    {
254       static T dummy;
255       return dummy;
256    }
257 
advance(Difference n)258    void advance(Difference n)
259    {  m_num -= n; }
260 
distance_to(const this_type & other) const261    Difference distance_to(const this_type &other)const
262    {  return m_num - other.m_num;   }
263 };
264 
265 template <class T, class Difference>
266 class default_init_construct_iterator
267   : public ::boost::container::iterator
268       <std::random_access_iterator_tag, T, Difference, const T*, const T &>
269 {
270    typedef  default_init_construct_iterator<T, Difference> this_type;
271 
272    public:
default_init_construct_iterator(Difference range_size)273    explicit default_init_construct_iterator(Difference range_size)
274       :  m_num(range_size){}
275 
276    //Constructors
default_init_construct_iterator()277    default_init_construct_iterator()
278       :  m_num(0){}
279 
operator ++()280    default_init_construct_iterator& operator++()
281    { increment();   return *this;   }
282 
operator ++(int)283    default_init_construct_iterator operator++(int)
284    {
285       default_init_construct_iterator result (*this);
286       increment();
287       return result;
288    }
289 
operator --()290    default_init_construct_iterator& operator--()
291    { decrement();   return *this;   }
292 
operator --(int)293    default_init_construct_iterator operator--(int)
294    {
295       default_init_construct_iterator result (*this);
296       decrement();
297       return result;
298    }
299 
operator ==(const default_init_construct_iterator & i,const default_init_construct_iterator & i2)300    friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
301    { return i.equal(i2); }
302 
operator !=(const default_init_construct_iterator & i,const default_init_construct_iterator & i2)303    friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
304    { return !(i == i2); }
305 
operator <(const default_init_construct_iterator & i,const default_init_construct_iterator & i2)306    friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
307    { return i.less(i2); }
308 
operator >(const default_init_construct_iterator & i,const default_init_construct_iterator & i2)309    friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
310    { return i2 < i; }
311 
operator <=(const default_init_construct_iterator & i,const default_init_construct_iterator & i2)312    friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
313    { return !(i > i2); }
314 
operator >=(const default_init_construct_iterator & i,const default_init_construct_iterator & i2)315    friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
316    { return !(i < i2); }
317 
operator -(const default_init_construct_iterator & i,const default_init_construct_iterator & i2)318    friend Difference operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
319    { return i2.distance_to(i); }
320 
321    //Arithmetic
operator +=(Difference off)322    default_init_construct_iterator& operator+=(Difference off)
323    {  this->advance(off); return *this;   }
324 
operator +(Difference off) const325    default_init_construct_iterator operator+(Difference off) const
326    {
327       default_init_construct_iterator other(*this);
328       other.advance(off);
329       return other;
330    }
331 
operator +(Difference off,const default_init_construct_iterator & right)332    friend default_init_construct_iterator operator+(Difference off, const default_init_construct_iterator& right)
333    {  return right + off; }
334 
operator -=(Difference off)335    default_init_construct_iterator& operator-=(Difference off)
336    {  this->advance(-off); return *this;   }
337 
operator -(Difference off) const338    default_init_construct_iterator operator-(Difference off) const
339    {  return *this + (-off);  }
340 
341    //This pseudo-iterator's dereference operations have no sense since value is not
342    //constructed until ::boost::container::construct_in_place is called.
343    //So comment them to catch bad uses
344    //const T& operator*() const;
345    //const T& operator[](difference_type) const;
346    //const T* operator->() const;
347 
348    private:
349    Difference  m_num;
350 
increment()351    void increment()
352    { --m_num; }
353 
decrement()354    void decrement()
355    { ++m_num; }
356 
equal(const this_type & other) const357    bool equal(const this_type &other) const
358    {  return m_num == other.m_num;   }
359 
less(const this_type & other) const360    bool less(const this_type &other) const
361    {  return other.m_num < m_num;   }
362 
dereference() const363    const T & dereference() const
364    {
365       static T dummy;
366       return dummy;
367    }
368 
advance(Difference n)369    void advance(Difference n)
370    {  m_num -= n; }
371 
distance_to(const this_type & other) const372    Difference distance_to(const this_type &other)const
373    {  return m_num - other.m_num;   }
374 };
375 
376 
377 template <class T, class Difference = std::ptrdiff_t>
378 class repeat_iterator
379   : public ::boost::container::iterator
380       <std::random_access_iterator_tag, T, Difference>
381 {
382    typedef repeat_iterator<T, Difference> this_type;
383    public:
repeat_iterator(T & ref,Difference range_size)384    explicit repeat_iterator(T &ref, Difference range_size)
385       :  m_ptr(&ref), m_num(range_size){}
386 
387    //Constructors
repeat_iterator()388    repeat_iterator()
389       :  m_ptr(0), m_num(0){}
390 
operator ++()391    this_type& operator++()
392    { increment();   return *this;   }
393 
operator ++(int)394    this_type operator++(int)
395    {
396       this_type result (*this);
397       increment();
398       return result;
399    }
400 
operator --()401    this_type& operator--()
402    { increment();   return *this;   }
403 
operator --(int)404    this_type operator--(int)
405    {
406       this_type result (*this);
407       increment();
408       return result;
409    }
410 
operator ==(const this_type & i,const this_type & i2)411    friend bool operator== (const this_type& i, const this_type& i2)
412    { return i.equal(i2); }
413 
operator !=(const this_type & i,const this_type & i2)414    friend bool operator!= (const this_type& i, const this_type& i2)
415    { return !(i == i2); }
416 
operator <(const this_type & i,const this_type & i2)417    friend bool operator< (const this_type& i, const this_type& i2)
418    { return i.less(i2); }
419 
operator >(const this_type & i,const this_type & i2)420    friend bool operator> (const this_type& i, const this_type& i2)
421    { return i2 < i; }
422 
operator <=(const this_type & i,const this_type & i2)423    friend bool operator<= (const this_type& i, const this_type& i2)
424    { return !(i > i2); }
425 
operator >=(const this_type & i,const this_type & i2)426    friend bool operator>= (const this_type& i, const this_type& i2)
427    { return !(i < i2); }
428 
operator -(const this_type & i,const this_type & i2)429    friend Difference operator- (const this_type& i, const this_type& i2)
430    { return i2.distance_to(i); }
431 
432    //Arithmetic
operator +=(Difference off)433    this_type& operator+=(Difference off)
434    {  this->advance(off); return *this;   }
435 
operator +(Difference off) const436    this_type operator+(Difference off) const
437    {
438       this_type other(*this);
439       other.advance(off);
440       return other;
441    }
442 
operator +(Difference off,const this_type & right)443    friend this_type operator+(Difference off, const this_type& right)
444    {  return right + off; }
445 
operator -=(Difference off)446    this_type& operator-=(Difference off)
447    {  this->advance(-off); return *this;   }
448 
operator -(Difference off) const449    this_type operator-(Difference off) const
450    {  return *this + (-off);  }
451 
operator *() const452    T& operator*() const
453    { return dereference(); }
454 
operator [](Difference) const455    T& operator[] (Difference ) const
456    { return dereference(); }
457 
operator ->() const458    T *operator->() const
459    { return &(dereference()); }
460 
461    private:
462    T *         m_ptr;
463    Difference  m_num;
464 
increment()465    void increment()
466    { --m_num; }
467 
decrement()468    void decrement()
469    { ++m_num; }
470 
equal(const this_type & other) const471    bool equal(const this_type &other) const
472    {  return m_num == other.m_num;   }
473 
less(const this_type & other) const474    bool less(const this_type &other) const
475    {  return other.m_num < m_num;   }
476 
dereference() const477    T & dereference() const
478    { return *m_ptr; }
479 
advance(Difference n)480    void advance(Difference n)
481    {  m_num -= n; }
482 
distance_to(const this_type & other) const483    Difference distance_to(const this_type &other)const
484    {  return m_num - other.m_num;   }
485 };
486 
487 template <class T, class EmplaceFunctor, class Difference /*= std::ptrdiff_t*/>
488 class emplace_iterator
489   : public ::boost::container::iterator
490       <std::random_access_iterator_tag, T, Difference, const T*, const T &>
491 {
492    typedef emplace_iterator this_type;
493 
494    public:
495    typedef Difference difference_type;
emplace_iterator(EmplaceFunctor & e)496    explicit emplace_iterator(EmplaceFunctor&e)
497       :  m_num(1), m_pe(&e){}
498 
emplace_iterator()499    emplace_iterator()
500       :  m_num(0), m_pe(0){}
501 
operator ++()502    this_type& operator++()
503    { increment();   return *this;   }
504 
operator ++(int)505    this_type operator++(int)
506    {
507       this_type result (*this);
508       increment();
509       return result;
510    }
511 
operator --()512    this_type& operator--()
513    { decrement();   return *this;   }
514 
operator --(int)515    this_type operator--(int)
516    {
517       this_type result (*this);
518       decrement();
519       return result;
520    }
521 
operator ==(const this_type & i,const this_type & i2)522    friend bool operator== (const this_type& i, const this_type& i2)
523    { return i.equal(i2); }
524 
operator !=(const this_type & i,const this_type & i2)525    friend bool operator!= (const this_type& i, const this_type& i2)
526    { return !(i == i2); }
527 
operator <(const this_type & i,const this_type & i2)528    friend bool operator< (const this_type& i, const this_type& i2)
529    { return i.less(i2); }
530 
operator >(const this_type & i,const this_type & i2)531    friend bool operator> (const this_type& i, const this_type& i2)
532    { return i2 < i; }
533 
operator <=(const this_type & i,const this_type & i2)534    friend bool operator<= (const this_type& i, const this_type& i2)
535    { return !(i > i2); }
536 
operator >=(const this_type & i,const this_type & i2)537    friend bool operator>= (const this_type& i, const this_type& i2)
538    { return !(i < i2); }
539 
operator -(const this_type & i,const this_type & i2)540    friend difference_type operator- (const this_type& i, const this_type& i2)
541    { return i2.distance_to(i); }
542 
543    //Arithmetic
operator +=(difference_type off)544    this_type& operator+=(difference_type off)
545    {  this->advance(off); return *this;   }
546 
operator +(difference_type off) const547    this_type operator+(difference_type off) const
548    {
549       this_type other(*this);
550       other.advance(off);
551       return other;
552    }
553 
operator +(difference_type off,const this_type & right)554    friend this_type operator+(difference_type off, const this_type& right)
555    {  return right + off; }
556 
operator -=(difference_type off)557    this_type& operator-=(difference_type off)
558    {  this->advance(-off); return *this;   }
559 
operator -(difference_type off) const560    this_type operator-(difference_type off) const
561    {  return *this + (-off);  }
562 
563    //This pseudo-iterator's dereference operations have no sense since value is not
564    //constructed until ::boost::container::construct_in_place is called.
565    //So comment them to catch bad uses
566    //const T& operator*() const;
567    //const T& operator[](difference_type) const;
568    //const T* operator->() const;
569 
570    template<class Allocator>
construct_in_place(Allocator & a,T * ptr)571    void construct_in_place(Allocator &a, T* ptr)
572    {  (*m_pe)(a, ptr);  }
573 
574    private:
575    difference_type m_num;
576    EmplaceFunctor *            m_pe;
577 
increment()578    void increment()
579    { --m_num; }
580 
decrement()581    void decrement()
582    { ++m_num; }
583 
equal(const this_type & other) const584    bool equal(const this_type &other) const
585    {  return m_num == other.m_num;   }
586 
less(const this_type & other) const587    bool less(const this_type &other) const
588    {  return other.m_num < m_num;   }
589 
dereference() const590    const T & dereference() const
591    {
592       static T dummy;
593       return dummy;
594    }
595 
advance(difference_type n)596    void advance(difference_type n)
597    {  m_num -= n; }
598 
distance_to(const this_type & other) const599    difference_type distance_to(const this_type &other)const
600    {  return difference_type(m_num - other.m_num);   }
601 };
602 
603 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
604 
605 template<class ...Args>
606 struct emplace_functor
607 {
608    typedef typename container_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t;
609 
emplace_functorboost::container::emplace_functor610    emplace_functor(BOOST_FWD_REF(Args)... args)
611       : args_(args...)
612    {}
613 
614    template<class Allocator, class T>
operator ()boost::container::emplace_functor615    void operator()(Allocator &a, T *ptr)
616    {  emplace_functor::inplace_impl(a, ptr, index_tuple_t());  }
617 
618    template<class Allocator, class T, int ...IdxPack>
inplace_implboost::container::emplace_functor619    void inplace_impl(Allocator &a, T* ptr, const container_detail::index_tuple<IdxPack...>&)
620    {
621       allocator_traits<Allocator>::construct
622          (a, ptr, ::boost::forward<Args>(container_detail::get<IdxPack>(args_))...);
623    }
624 
625    container_detail::tuple<Args&...> args_;
626 };
627 
628 #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
629 
630 #define BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE(N) \
631 BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
632 struct emplace_functor##N\
633 {\
634    explicit emplace_functor##N( BOOST_MOVE_UREF##N )\
635       BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\
636    \
637    template<class Allocator, class T>\
638    void operator()(Allocator &a, T *ptr)\
639    {  allocator_traits<Allocator>::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);  }\
640    \
641    BOOST_MOVE_MREF##N\
642 };\
643 //
644 BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE)
645 #undef BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE
646 
647 #endif
648 
649 namespace container_detail {
650 
651 template<class T>
652 struct has_iterator_category
653 {
654    struct two { char _[2]; };
655 
656    template <typename X>
657    static char test(int, typename X::iterator_category*);
658 
659    template <typename X>
660    static two test(int, ...);
661 
662    static const bool value = (1 == sizeof(test<T>(0, 0)));
663 };
664 
665 
666 template<class T, bool = has_iterator_category<T>::value >
667 struct is_input_iterator
668 {
669    static const bool value = is_same<typename T::iterator_category, std::input_iterator_tag>::value;
670 };
671 
672 template<class T>
673 struct is_input_iterator<T, false>
674 {
675    static const bool value = false;
676 };
677 
678 template<class T>
679 struct is_not_input_iterator
680 {
681    static const bool value = !is_input_iterator<T>::value;
682 };
683 
684 template<class T, bool = has_iterator_category<T>::value >
685 struct is_forward_iterator
686 {
687    static const bool value = is_same<typename T::iterator_category, std::forward_iterator_tag>::value;
688 };
689 
690 template<class T>
691 struct is_forward_iterator<T, false>
692 {
693    static const bool value = false;
694 };
695 
696 template<class T, bool = has_iterator_category<T>::value >
697 struct is_bidirectional_iterator
698 {
699    static const bool value = is_same<typename T::iterator_category, std::bidirectional_iterator_tag>::value;
700 };
701 
702 template<class T>
703 struct is_bidirectional_iterator<T, false>
704 {
705    static const bool value = false;
706 };
707 
708 template<class IINodeType>
709 struct iiterator_node_value_type {
710   typedef typename IINodeType::value_type type;
711 };
712 
713 template<class IIterator>
714 struct iiterator_types
715 {
716    typedef typename IIterator::value_type                            it_value_type;
717    typedef typename iiterator_node_value_type<it_value_type>::type   value_type;
718    typedef typename boost::container::iterator_traits<IIterator>::pointer         it_pointer;
719    typedef typename boost::container::iterator_traits<IIterator>::difference_type difference_type;
720    typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
721       template rebind_pointer<value_type>::type                      pointer;
722    typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
723       template rebind_pointer<const value_type>::type                const_pointer;
724    typedef typename ::boost::intrusive::
725       pointer_traits<pointer>::reference                             reference;
726    typedef typename ::boost::intrusive::
727       pointer_traits<const_pointer>::reference                       const_reference;
728    typedef typename IIterator::iterator_category                     iterator_category;
729 };
730 
731 template<class IIterator, bool IsConst>
732 struct iterator_types
733 {
734    typedef typename ::boost::container::iterator
735       < typename iiterator_types<IIterator>::iterator_category
736       , typename iiterator_types<IIterator>::value_type
737       , typename iiterator_types<IIterator>::difference_type
738       , typename iiterator_types<IIterator>::const_pointer
739       , typename iiterator_types<IIterator>::const_reference> type;
740 };
741 
742 template<class IIterator>
743 struct iterator_types<IIterator, false>
744 {
745    typedef typename ::boost::container::iterator
746       < typename iiterator_types<IIterator>::iterator_category
747       , typename iiterator_types<IIterator>::value_type
748       , typename iiterator_types<IIterator>::difference_type
749       , typename iiterator_types<IIterator>::pointer
750       , typename iiterator_types<IIterator>::reference> type;
751 };
752 
753 template<class IIterator, bool IsConst>
754 class iterator_from_iiterator
755 {
756    typedef typename iterator_types<IIterator, IsConst>::type types_t;
757 
758    public:
759    typedef typename types_t::pointer             pointer;
760    typedef typename types_t::reference           reference;
761    typedef typename types_t::difference_type     difference_type;
762    typedef typename types_t::iterator_category   iterator_category;
763    typedef typename types_t::value_type          value_type;
764 
iterator_from_iiterator()765    iterator_from_iiterator()
766    {}
767 
iterator_from_iiterator(IIterator iit)768    explicit iterator_from_iiterator(IIterator iit) BOOST_NOEXCEPT_OR_NOTHROW
769       : m_iit(iit)
770    {}
771 
iterator_from_iiterator(iterator_from_iiterator<IIterator,false> const & other)772    iterator_from_iiterator(iterator_from_iiterator<IIterator, false> const& other) BOOST_NOEXCEPT_OR_NOTHROW
773       :  m_iit(other.get())
774    {}
775 
operator ++()776    iterator_from_iiterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
777    {  ++this->m_iit;   return *this;  }
778 
operator ++(int)779    iterator_from_iiterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
780    {
781       iterator_from_iiterator result (*this);
782       ++this->m_iit;
783       return result;
784    }
785 
operator --()786    iterator_from_iiterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
787    {
788       //If the iterator_from_iiterator is not a bidirectional iterator, operator-- should not exist
789       BOOST_STATIC_ASSERT((is_bidirectional_iterator<iterator_from_iiterator>::value));
790       --this->m_iit;   return *this;
791    }
792 
operator --(int)793    iterator_from_iiterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
794    {
795       iterator_from_iiterator result (*this);
796       --this->m_iit;
797       return result;
798    }
799 
operator ==(const iterator_from_iiterator & l,const iterator_from_iiterator & r)800    friend bool operator== (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW
801    {  return l.m_iit == r.m_iit;   }
802 
operator !=(const iterator_from_iiterator & l,const iterator_from_iiterator & r)803    friend bool operator!= (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW
804    {  return !(l == r); }
805 
operator *() const806    reference operator*()  const BOOST_NOEXCEPT_OR_NOTHROW
807    {  return this->m_iit->get_data();  }
808 
operator ->() const809    pointer   operator->() const BOOST_NOEXCEPT_OR_NOTHROW
810    {  return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*());  }
811 
get() const812    const IIterator &get() const BOOST_NOEXCEPT_OR_NOTHROW
813    {  return this->m_iit;   }
814 
815    private:
816    IIterator m_iit;
817 };
818 
819 }  //namespace container_detail {
820 
821 using ::boost::intrusive::reverse_iterator;
822 
823 }  //namespace container {
824 }  //namespace boost {
825 
826 #include <boost/container/detail/config_end.hpp>
827 
828 #endif   //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
829