1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2005-2009.
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_CONTAINERS_DETAIL_ITERATORS_HPP
15 #define BOOST_CONTAINERS_DETAIL_ITERATORS_HPP
16 
17 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
18 #  pragma once
19 #endif
20 
21 #include "config_begin.hpp"
22 #include INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
23 #include INCLUDE_BOOST_CONTAINER_MOVE_HPP
24 
25 #ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
26 #include INCLUDE_BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
27 #include INCLUDE_BOOST_CONTAINER_DETAIL_STORED_REF_HPP
28 #else
29 #include INCLUDE_BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
30 #endif
31 
32 #include <iterator>
33 
34 namespace boost {
35 namespace container {
36 
37 template <class T, class Difference = std::ptrdiff_t>
38 class constant_iterator
39   : public std::iterator
40       <std::random_access_iterator_tag, T, Difference, const T*, const T &>
41 {
42    typedef  constant_iterator<T, Difference> this_type;
43 
44    public:
constant_iterator(const T & ref,Difference range_size)45    explicit constant_iterator(const T &ref, Difference range_size)
46       :  m_ptr(&ref), m_num(range_size){}
47 
48    //Constructors
constant_iterator()49    constant_iterator()
50       :  m_ptr(0), m_num(0){}
51 
operator ++()52    constant_iterator& operator++()
53    { increment();   return *this;   }
54 
operator ++(int)55    constant_iterator operator++(int)
56    {
57       constant_iterator result (*this);
58       increment();
59       return result;
60    }
61 
operator --()62    constant_iterator& operator--()
63    { decrement();   return *this;   }
64 
operator --(int)65    constant_iterator operator--(int)
66    {
67       constant_iterator result (*this);
68       decrement();
69       return result;
70    }
71 
operator ==(const constant_iterator & i,const constant_iterator & i2)72    friend bool operator== (const constant_iterator& i, const constant_iterator& i2)
73    { return i.equal(i2); }
74 
operator !=(const constant_iterator & i,const constant_iterator & i2)75    friend bool operator!= (const constant_iterator& i, const constant_iterator& i2)
76    { return !(i == i2); }
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.less(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 i2 < i; }
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 > 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 !(i < i2); }
89 
operator -(const constant_iterator & i,const constant_iterator & i2)90    friend Difference operator- (const constant_iterator& i, const constant_iterator& i2)
91    { return i2.distance_to(i); }
92 
93    //Arithmetic
operator +=(Difference off)94    constant_iterator& operator+=(Difference off)
95    {  this->advance(off); return *this;   }
96 
operator +(Difference off) const97    constant_iterator operator+(Difference off) const
98    {
99       constant_iterator other(*this);
100       other.advance(off);
101       return other;
102    }
103 
operator +(Difference off,const constant_iterator & right)104    friend constant_iterator operator+(Difference off, const constant_iterator& right)
105    {  return right + off; }
106 
operator -=(Difference off)107    constant_iterator& operator-=(Difference off)
108    {  this->advance(-off); return *this;   }
109 
operator -(Difference off) const110    constant_iterator operator-(Difference off) const
111    {  return *this + (-off);  }
112 
operator *() const113    const T& operator*() const
114    { return dereference(); }
115 
operator [](Difference n) const116    const T& operator[] (Difference n) const
117    { return dereference(); }
118 
operator ->() const119    const T* operator->() const
120    { return &(dereference()); }
121 
122    private:
123    const T *   m_ptr;
124    Difference  m_num;
125 
increment()126    void increment()
127    { --m_num; }
128 
decrement()129    void decrement()
130    { ++m_num; }
131 
equal(const this_type & other) const132    bool equal(const this_type &other) const
133    {  return m_num == other.m_num;   }
134 
less(const this_type & other) const135    bool less(const this_type &other) const
136    {  return other.m_num < m_num;   }
137 
dereference() const138    const T & dereference() const
139    { return *m_ptr; }
140 
advance(Difference n)141    void advance(Difference n)
142    {  m_num -= n; }
143 
distance_to(const this_type & other) const144    Difference distance_to(const this_type &other)const
145    {  return m_num - other.m_num;   }
146 };
147 
148 template <class T, class Difference = std::ptrdiff_t>
149 class default_construct_iterator
150   : public std::iterator
151       <std::random_access_iterator_tag, T, Difference, const T*, const T &>
152 {
153    typedef  default_construct_iterator<T, Difference> this_type;
154 
155    public:
default_construct_iterator(Difference range_size)156    explicit default_construct_iterator(Difference range_size)
157       :  m_num(range_size){}
158 
159    //Constructors
default_construct_iterator()160    default_construct_iterator()
161       :  m_num(0){}
162 
operator ++()163    default_construct_iterator& operator++()
164    { increment();   return *this;   }
165 
operator ++(int)166    default_construct_iterator operator++(int)
167    {
168       default_construct_iterator result (*this);
169       increment();
170       return result;
171    }
172 
operator --()173    default_construct_iterator& operator--()
174    { decrement();   return *this;   }
175 
operator --(int)176    default_construct_iterator operator--(int)
177    {
178       default_construct_iterator result (*this);
179       decrement();
180       return result;
181    }
182 
operator ==(const default_construct_iterator & i,const default_construct_iterator & i2)183    friend bool operator== (const default_construct_iterator& i, const default_construct_iterator& i2)
184    { return i.equal(i2); }
185 
operator !=(const default_construct_iterator & i,const default_construct_iterator & i2)186    friend bool operator!= (const default_construct_iterator& i, const default_construct_iterator& i2)
187    { return !(i == i2); }
188 
operator <(const default_construct_iterator & i,const default_construct_iterator & i2)189    friend bool operator< (const default_construct_iterator& i, const default_construct_iterator& i2)
190    { return i.less(i2); }
191 
operator >(const default_construct_iterator & i,const default_construct_iterator & i2)192    friend bool operator> (const default_construct_iterator& i, const default_construct_iterator& i2)
193    { return i2 < i; }
194 
operator <=(const default_construct_iterator & i,const default_construct_iterator & i2)195    friend bool operator<= (const default_construct_iterator& i, const default_construct_iterator& i2)
196    { return !(i > i2); }
197 
operator >=(const default_construct_iterator & i,const default_construct_iterator & i2)198    friend bool operator>= (const default_construct_iterator& i, const default_construct_iterator& i2)
199    { return !(i < i2); }
200 
operator -(const default_construct_iterator & i,const default_construct_iterator & i2)201    friend Difference operator- (const default_construct_iterator& i, const default_construct_iterator& i2)
202    { return i2.distance_to(i); }
203 
204    //Arithmetic
operator +=(Difference off)205    default_construct_iterator& operator+=(Difference off)
206    {  this->advance(off); return *this;   }
207 
operator +(Difference off) const208    default_construct_iterator operator+(Difference off) const
209    {
210       default_construct_iterator other(*this);
211       other.advance(off);
212       return other;
213    }
214 
operator +(Difference off,const default_construct_iterator & right)215    friend default_construct_iterator operator+(Difference off, const default_construct_iterator& right)
216    {  return right + off; }
217 
operator -=(Difference off)218    default_construct_iterator& operator-=(Difference off)
219    {  this->advance(-off); return *this;   }
220 
operator -(Difference off) const221    default_construct_iterator operator-(Difference off) const
222    {  return *this + (-off);  }
223 
operator *() const224    const T& operator*() const
225    { return dereference(); }
226 
operator ->() const227    const T* operator->() const
228    { return &(dereference()); }
229 
operator [](Difference n) const230    const T& operator[] (Difference n) const
231    { return dereference(); }
232 
233    private:
234    Difference  m_num;
235 
increment()236    void increment()
237    { --m_num; }
238 
decrement()239    void decrement()
240    { ++m_num; }
241 
equal(const this_type & other) const242    bool equal(const this_type &other) const
243    {  return m_num == other.m_num;   }
244 
less(const this_type & other) const245    bool less(const this_type &other) const
246    {  return other.m_num < m_num;   }
247 
dereference() const248    const T & dereference() const
249    {
250       static T dummy;
251       return dummy;
252    }
253 
advance(Difference n)254    void advance(Difference n)
255    {  m_num -= n; }
256 
distance_to(const this_type & other) const257    Difference distance_to(const this_type &other)const
258    {  return m_num - other.m_num;   }
259 };
260 
261 template <class T, class Difference = std::ptrdiff_t>
262 class repeat_iterator
263   : public std::iterator
264       <std::random_access_iterator_tag, T, Difference>
265 {
266    typedef repeat_iterator<T, Difference> this_type;
267    public:
repeat_iterator(T & ref,Difference range_size)268    explicit repeat_iterator(T &ref, Difference range_size)
269       :  m_ptr(&ref), m_num(range_size){}
270 
271    //Constructors
repeat_iterator()272    repeat_iterator()
273       :  m_ptr(0), m_num(0){}
274 
operator ++()275    this_type& operator++()
276    { increment();   return *this;   }
277 
operator ++(int)278    this_type operator++(int)
279    {
280       this_type result (*this);
281       increment();
282       return result;
283    }
284 
operator --()285    this_type& operator--()
286    { increment();   return *this;   }
287 
operator --(int)288    this_type operator--(int)
289    {
290       this_type result (*this);
291       increment();
292       return result;
293    }
294 
operator ==(const this_type & i,const this_type & i2)295    friend bool operator== (const this_type& i, const this_type& i2)
296    { return i.equal(i2); }
297 
operator !=(const this_type & i,const this_type & i2)298    friend bool operator!= (const this_type& i, const this_type& i2)
299    { return !(i == i2); }
300 
operator <(const this_type & i,const this_type & i2)301    friend bool operator< (const this_type& i, const this_type& i2)
302    { return i.less(i2); }
303 
operator >(const this_type & i,const this_type & i2)304    friend bool operator> (const this_type& i, const this_type& i2)
305    { return i2 < i; }
306 
operator <=(const this_type & i,const this_type & i2)307    friend bool operator<= (const this_type& i, const this_type& i2)
308    { return !(i > i2); }
309 
operator >=(const this_type & i,const this_type & i2)310    friend bool operator>= (const this_type& i, const this_type& i2)
311    { return !(i < i2); }
312 
operator -(const this_type & i,const this_type & i2)313    friend Difference operator- (const this_type& i, const this_type& i2)
314    { return i2.distance_to(i); }
315 
316    //Arithmetic
operator +=(Difference off)317    this_type& operator+=(Difference off)
318    {  this->advance(off); return *this;   }
319 
operator +(Difference off) const320    this_type operator+(Difference off) const
321    {
322       this_type other(*this);
323       other.advance(off);
324       return other;
325    }
326 
operator +(Difference off,const this_type & right)327    friend this_type operator+(Difference off, const this_type& right)
328    {  return right + off; }
329 
operator -=(Difference off)330    this_type& operator-=(Difference off)
331    {  this->advance(-off); return *this;   }
332 
operator -(Difference off) const333    this_type operator-(Difference off) const
334    {  return *this + (-off);  }
335 
operator *() const336    T& operator*() const
337    { return dereference(); }
338 
operator [](Difference n) const339    T& operator[] (Difference n) const
340    { return dereference(); }
341 
operator ->() const342    T *operator->() const
343    { return &(dereference()); }
344 
345    private:
346    T *         m_ptr;
347    Difference  m_num;
348 
increment()349    void increment()
350    { --m_num; }
351 
decrement()352    void decrement()
353    { ++m_num; }
354 
equal(const this_type & other) const355    bool equal(const this_type &other) const
356    {  return m_num == other.m_num;   }
357 
less(const this_type & other) const358    bool less(const this_type &other) const
359    {  return other.m_num < m_num;   }
360 
dereference() const361    T & dereference() const
362    { return *m_ptr; }
363 
advance(Difference n)364    void advance(Difference n)
365    {  m_num -= n; }
366 
distance_to(const this_type & other) const367    Difference distance_to(const this_type &other)const
368    {  return m_num - other.m_num;   }
369 };
370 
371 template <class T, class E>
372 class emplace_iterator
373   : public std::iterator
374       <std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &>
375 {
376    typedef emplace_iterator this_type;
377 
378    public:
emplace_iterator(E & e)379    explicit emplace_iterator(E&e)
380       :  m_num(1), m_pe(&e){}
381 
emplace_iterator()382    emplace_iterator()
383       :  m_num(0), m_pe(0){}
384 
operator ++()385    this_type& operator++()
386    { increment();   return *this;   }
387 
operator ++(int)388    this_type operator++(int)
389    {
390       this_type result (*this);
391       increment();
392       return result;
393    }
394 
operator --()395    this_type& operator--()
396    { decrement();   return *this;   }
397 
operator --(int)398    this_type operator--(int)
399    {
400       this_type result (*this);
401       decrement();
402       return result;
403    }
404 
operator ==(const this_type & i,const this_type & i2)405    friend bool operator== (const this_type& i, const this_type& i2)
406    { return i.equal(i2); }
407 
operator !=(const this_type & i,const this_type & i2)408    friend bool operator!= (const this_type& i, const this_type& i2)
409    { return !(i == i2); }
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.less(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 i2 < i; }
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 > 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 !(i < i2); }
422 
operator -(const this_type & i,const this_type & i2)423    friend std::ptrdiff_t operator- (const this_type& i, const this_type& i2)
424    { return i2.distance_to(i); }
425 
426    //Arithmetic
operator +=(std::ptrdiff_t off)427    this_type& operator+=(std::ptrdiff_t off)
428    {  this->advance(off); return *this;   }
429 
operator +(std::ptrdiff_t off) const430    this_type operator+(std::ptrdiff_t off) const
431    {
432       this_type other(*this);
433       other.advance(off);
434       return other;
435    }
436 
operator +(std::ptrdiff_t off,const this_type & right)437    friend this_type operator+(std::ptrdiff_t off, const this_type& right)
438    {  return right + off; }
439 
operator -=(std::ptrdiff_t off)440    this_type& operator-=(std::ptrdiff_t off)
441    {  this->advance(-off); return *this;   }
442 
operator -(std::ptrdiff_t off) const443    this_type operator-(std::ptrdiff_t off) const
444    {  return *this + (-off);  }
445 
operator *() const446    const T& operator*() const
447    { return dereference(); }
448 
operator [](std::ptrdiff_t) const449    const T& operator[](std::ptrdiff_t) const
450    { return dereference(); }
451 
operator ->() const452    const T* operator->() const
453    { return &(dereference()); }
454 
construct_in_place(T * ptr)455    void construct_in_place(T* ptr)
456    {  (*m_pe)(ptr);  }
457 
458    private:
459    std::ptrdiff_t m_num;
460    E *            m_pe;
461 
increment()462    void increment()
463    { --m_num; }
464 
decrement()465    void decrement()
466    { ++m_num; }
467 
equal(const this_type & other) const468    bool equal(const this_type &other) const
469    {  return m_num == other.m_num;   }
470 
less(const this_type & other) const471    bool less(const this_type &other) const
472    {  return other.m_num < m_num;   }
473 
dereference() const474    const T & dereference() const
475    {
476       static T dummy;
477       return dummy;
478    }
479 
advance(std::ptrdiff_t n)480    void advance(std::ptrdiff_t n)
481    {  m_num -= n; }
482 
distance_to(const this_type & other) const483    std::ptrdiff_t distance_to(const this_type &other)const
484    {  return m_num - other.m_num;   }
485 };
486 
487 #ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
488 
489 template<class T, class ...Args>
490 struct emplace_functor
491 {
492    typedef typename containers_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t;
493 
emplace_functorboost::container::emplace_functor494    emplace_functor(Args&&... args)
495       : args_(args...)
496    {}
497 
operator ()boost::container::emplace_functor498    void operator()(T *ptr)
499    {  emplace_functor::inplace_impl(ptr, index_tuple_t());  }
500 
501    template<int ...IdxPack>
inplace_implboost::container::emplace_functor502    void inplace_impl(T* ptr, const containers_detail::index_tuple<IdxPack...>&)
503    {  ::new(ptr) T(containers_detail::stored_ref<Args>::forward(containers_detail::get<IdxPack>(args_))...); }
504 
505    containers_detail::tuple<Args&...> args_;
506 };
507 
508 #else
509 
510 template<class T>
511 struct emplace_functor
512 {
emplace_functorboost::container::emplace_functor513    emplace_functor()
514    {}
operator ()boost::container::emplace_functor515    void operator()(T *ptr)
516    {  new(ptr) T();  }
517 };
518 
519 #define BOOST_PP_LOCAL_MACRO(n)                                                        \
520    template <class T, BOOST_PP_ENUM_PARAMS(n, class P) >                               \
521    struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg)                          \
522    {                                                                                   \
523       BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg)                              \
524          ( BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _) )                       \
525       :  BOOST_PP_ENUM(n, BOOST_CONTAINERS_AUX_PARAM_INIT, _) {}                       \
526                                                                                        \
527       void operator()(T *ptr)                                                          \
528       {                                                                                \
529          new(ptr)T (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _));          \
530       }                                                                                \
531       BOOST_PP_REPEAT(n, BOOST_CONTAINERS_AUX_PARAM_DEFINE, _)                         \
532    };                                                                                  \
533    //!
534 #define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS)
535 #include BOOST_PP_LOCAL_ITERATE()
536 
537 #endif
538 
539 }  //namespace container {
540 }  //namespace boost {
541 
542 #include INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
543 
544 #endif   //#ifndef BOOST_CONTAINERS_DETAIL_ITERATORS_HPP
545 
546