You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
546 lines
14 KiB
546 lines
14 KiB
////////////////////////////////////////////////////////////////////////////// |
|
// |
|
// (C) Copyright Ion Gaztanaga 2005-2011. |
|
// (C) Copyright Gennaro Prota 2003 - 2004. |
|
// |
|
// Distributed under the Boost Software License, Version 1.0. |
|
// (See accompanying file LICENSE_1_0.txt or copy at |
|
// http://www.boost.org/LICENSE_1_0.txt) |
|
// |
|
// See http://www.boost.org/libs/container for documentation. |
|
// |
|
////////////////////////////////////////////////////////////////////////////// |
|
|
|
#ifndef BOOST_CONTAINERS_DETAIL_ITERATORS_HPP |
|
#define BOOST_CONTAINERS_DETAIL_ITERATORS_HPP |
|
|
|
#if (defined _MSC_VER) && (_MSC_VER >= 1200) |
|
# pragma once |
|
#endif |
|
|
|
#include "config_begin.hpp" |
|
#include <boost/container/detail/workaround.hpp> |
|
#include <boost/move/move.hpp> |
|
|
|
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING |
|
#include <boost/container/detail/variadic_templates_tools.hpp> |
|
#include <boost/container/detail/stored_ref.hpp> |
|
#else |
|
#include <boost/container/detail/preprocessor.hpp> |
|
#endif |
|
|
|
#include <iterator> |
|
|
|
namespace boost { |
|
namespace container { |
|
|
|
template <class T, class Difference = std::ptrdiff_t> |
|
class constant_iterator |
|
: public std::iterator |
|
<std::random_access_iterator_tag, T, Difference, const T*, const T &> |
|
{ |
|
typedef constant_iterator<T, Difference> this_type; |
|
|
|
public: |
|
explicit constant_iterator(const T &ref, Difference range_size) |
|
: m_ptr(&ref), m_num(range_size){} |
|
|
|
//Constructors |
|
constant_iterator() |
|
: m_ptr(0), m_num(0){} |
|
|
|
constant_iterator& operator++() |
|
{ increment(); return *this; } |
|
|
|
constant_iterator operator++(int) |
|
{ |
|
constant_iterator result (*this); |
|
increment(); |
|
return result; |
|
} |
|
|
|
constant_iterator& operator--() |
|
{ decrement(); return *this; } |
|
|
|
constant_iterator operator--(int) |
|
{ |
|
constant_iterator result (*this); |
|
decrement(); |
|
return result; |
|
} |
|
|
|
friend bool operator== (const constant_iterator& i, const constant_iterator& i2) |
|
{ return i.equal(i2); } |
|
|
|
friend bool operator!= (const constant_iterator& i, const constant_iterator& i2) |
|
{ return !(i == i2); } |
|
|
|
friend bool operator< (const constant_iterator& i, const constant_iterator& i2) |
|
{ return i.less(i2); } |
|
|
|
friend bool operator> (const constant_iterator& i, const constant_iterator& i2) |
|
{ return i2 < i; } |
|
|
|
friend bool operator<= (const constant_iterator& i, const constant_iterator& i2) |
|
{ return !(i > i2); } |
|
|
|
friend bool operator>= (const constant_iterator& i, const constant_iterator& i2) |
|
{ return !(i < i2); } |
|
|
|
friend Difference operator- (const constant_iterator& i, const constant_iterator& i2) |
|
{ return i2.distance_to(i); } |
|
|
|
//Arithmetic |
|
constant_iterator& operator+=(Difference off) |
|
{ this->advance(off); return *this; } |
|
|
|
constant_iterator operator+(Difference off) const |
|
{ |
|
constant_iterator other(*this); |
|
other.advance(off); |
|
return other; |
|
} |
|
|
|
friend constant_iterator operator+(Difference off, const constant_iterator& right) |
|
{ return right + off; } |
|
|
|
constant_iterator& operator-=(Difference off) |
|
{ this->advance(-off); return *this; } |
|
|
|
constant_iterator operator-(Difference off) const |
|
{ return *this + (-off); } |
|
|
|
const T& operator*() const |
|
{ return dereference(); } |
|
|
|
const T& operator[] (Difference n) const |
|
{ return dereference(); } |
|
|
|
const T* operator->() const |
|
{ return &(dereference()); } |
|
|
|
private: |
|
const T * m_ptr; |
|
Difference m_num; |
|
|
|
void increment() |
|
{ --m_num; } |
|
|
|
void decrement() |
|
{ ++m_num; } |
|
|
|
bool equal(const this_type &other) const |
|
{ return m_num == other.m_num; } |
|
|
|
bool less(const this_type &other) const |
|
{ return other.m_num < m_num; } |
|
|
|
const T & dereference() const |
|
{ return *m_ptr; } |
|
|
|
void advance(Difference n) |
|
{ m_num -= n; } |
|
|
|
Difference distance_to(const this_type &other)const |
|
{ return m_num - other.m_num; } |
|
}; |
|
|
|
template <class T, class Difference = std::ptrdiff_t> |
|
class default_construct_iterator |
|
: public std::iterator |
|
<std::random_access_iterator_tag, T, Difference, const T*, const T &> |
|
{ |
|
typedef default_construct_iterator<T, Difference> this_type; |
|
|
|
public: |
|
explicit default_construct_iterator(Difference range_size) |
|
: m_num(range_size){} |
|
|
|
//Constructors |
|
default_construct_iterator() |
|
: m_num(0){} |
|
|
|
default_construct_iterator& operator++() |
|
{ increment(); return *this; } |
|
|
|
default_construct_iterator operator++(int) |
|
{ |
|
default_construct_iterator result (*this); |
|
increment(); |
|
return result; |
|
} |
|
|
|
default_construct_iterator& operator--() |
|
{ decrement(); return *this; } |
|
|
|
default_construct_iterator operator--(int) |
|
{ |
|
default_construct_iterator result (*this); |
|
decrement(); |
|
return result; |
|
} |
|
|
|
friend bool operator== (const default_construct_iterator& i, const default_construct_iterator& i2) |
|
{ return i.equal(i2); } |
|
|
|
friend bool operator!= (const default_construct_iterator& i, const default_construct_iterator& i2) |
|
{ return !(i == i2); } |
|
|
|
friend bool operator< (const default_construct_iterator& i, const default_construct_iterator& i2) |
|
{ return i.less(i2); } |
|
|
|
friend bool operator> (const default_construct_iterator& i, const default_construct_iterator& i2) |
|
{ return i2 < i; } |
|
|
|
friend bool operator<= (const default_construct_iterator& i, const default_construct_iterator& i2) |
|
{ return !(i > i2); } |
|
|
|
friend bool operator>= (const default_construct_iterator& i, const default_construct_iterator& i2) |
|
{ return !(i < i2); } |
|
|
|
friend Difference operator- (const default_construct_iterator& i, const default_construct_iterator& i2) |
|
{ return i2.distance_to(i); } |
|
|
|
//Arithmetic |
|
default_construct_iterator& operator+=(Difference off) |
|
{ this->advance(off); return *this; } |
|
|
|
default_construct_iterator operator+(Difference off) const |
|
{ |
|
default_construct_iterator other(*this); |
|
other.advance(off); |
|
return other; |
|
} |
|
|
|
friend default_construct_iterator operator+(Difference off, const default_construct_iterator& right) |
|
{ return right + off; } |
|
|
|
default_construct_iterator& operator-=(Difference off) |
|
{ this->advance(-off); return *this; } |
|
|
|
default_construct_iterator operator-(Difference off) const |
|
{ return *this + (-off); } |
|
|
|
const T& operator*() const |
|
{ return dereference(); } |
|
|
|
const T* operator->() const |
|
{ return &(dereference()); } |
|
|
|
const T& operator[] (Difference n) const |
|
{ return dereference(); } |
|
|
|
private: |
|
Difference m_num; |
|
|
|
void increment() |
|
{ --m_num; } |
|
|
|
void decrement() |
|
{ ++m_num; } |
|
|
|
bool equal(const this_type &other) const |
|
{ return m_num == other.m_num; } |
|
|
|
bool less(const this_type &other) const |
|
{ return other.m_num < m_num; } |
|
|
|
const T & dereference() const |
|
{ |
|
static T dummy; |
|
return dummy; |
|
} |
|
|
|
void advance(Difference n) |
|
{ m_num -= n; } |
|
|
|
Difference distance_to(const this_type &other)const |
|
{ return m_num - other.m_num; } |
|
}; |
|
|
|
template <class T, class Difference = std::ptrdiff_t> |
|
class repeat_iterator |
|
: public std::iterator |
|
<std::random_access_iterator_tag, T, Difference> |
|
{ |
|
typedef repeat_iterator<T, Difference> this_type; |
|
public: |
|
explicit repeat_iterator(T &ref, Difference range_size) |
|
: m_ptr(&ref), m_num(range_size){} |
|
|
|
//Constructors |
|
repeat_iterator() |
|
: m_ptr(0), m_num(0){} |
|
|
|
this_type& operator++() |
|
{ increment(); return *this; } |
|
|
|
this_type operator++(int) |
|
{ |
|
this_type result (*this); |
|
increment(); |
|
return result; |
|
} |
|
|
|
this_type& operator--() |
|
{ increment(); return *this; } |
|
|
|
this_type operator--(int) |
|
{ |
|
this_type result (*this); |
|
increment(); |
|
return result; |
|
} |
|
|
|
friend bool operator== (const this_type& i, const this_type& i2) |
|
{ return i.equal(i2); } |
|
|
|
friend bool operator!= (const this_type& i, const this_type& i2) |
|
{ return !(i == i2); } |
|
|
|
friend bool operator< (const this_type& i, const this_type& i2) |
|
{ return i.less(i2); } |
|
|
|
friend bool operator> (const this_type& i, const this_type& i2) |
|
{ return i2 < i; } |
|
|
|
friend bool operator<= (const this_type& i, const this_type& i2) |
|
{ return !(i > i2); } |
|
|
|
friend bool operator>= (const this_type& i, const this_type& i2) |
|
{ return !(i < i2); } |
|
|
|
friend Difference operator- (const this_type& i, const this_type& i2) |
|
{ return i2.distance_to(i); } |
|
|
|
//Arithmetic |
|
this_type& operator+=(Difference off) |
|
{ this->advance(off); return *this; } |
|
|
|
this_type operator+(Difference off) const |
|
{ |
|
this_type other(*this); |
|
other.advance(off); |
|
return other; |
|
} |
|
|
|
friend this_type operator+(Difference off, const this_type& right) |
|
{ return right + off; } |
|
|
|
this_type& operator-=(Difference off) |
|
{ this->advance(-off); return *this; } |
|
|
|
this_type operator-(Difference off) const |
|
{ return *this + (-off); } |
|
|
|
T& operator*() const |
|
{ return dereference(); } |
|
|
|
T& operator[] (Difference n) const |
|
{ return dereference(); } |
|
|
|
T *operator->() const |
|
{ return &(dereference()); } |
|
|
|
private: |
|
T * m_ptr; |
|
Difference m_num; |
|
|
|
void increment() |
|
{ --m_num; } |
|
|
|
void decrement() |
|
{ ++m_num; } |
|
|
|
bool equal(const this_type &other) const |
|
{ return m_num == other.m_num; } |
|
|
|
bool less(const this_type &other) const |
|
{ return other.m_num < m_num; } |
|
|
|
T & dereference() const |
|
{ return *m_ptr; } |
|
|
|
void advance(Difference n) |
|
{ m_num -= n; } |
|
|
|
Difference distance_to(const this_type &other)const |
|
{ return m_num - other.m_num; } |
|
}; |
|
|
|
template <class T, class E, class Difference /*= std::ptrdiff_t*/> |
|
class emplace_iterator |
|
: public std::iterator |
|
<std::random_access_iterator_tag, T, Difference, const T*, const T &> |
|
{ |
|
typedef emplace_iterator this_type; |
|
|
|
public: |
|
typedef Difference difference_type; |
|
explicit emplace_iterator(E&e) |
|
: m_num(1), m_pe(&e){} |
|
|
|
emplace_iterator() |
|
: m_num(0), m_pe(0){} |
|
|
|
this_type& operator++() |
|
{ increment(); return *this; } |
|
|
|
this_type operator++(int) |
|
{ |
|
this_type result (*this); |
|
increment(); |
|
return result; |
|
} |
|
|
|
this_type& operator--() |
|
{ decrement(); return *this; } |
|
|
|
this_type operator--(int) |
|
{ |
|
this_type result (*this); |
|
decrement(); |
|
return result; |
|
} |
|
|
|
friend bool operator== (const this_type& i, const this_type& i2) |
|
{ return i.equal(i2); } |
|
|
|
friend bool operator!= (const this_type& i, const this_type& i2) |
|
{ return !(i == i2); } |
|
|
|
friend bool operator< (const this_type& i, const this_type& i2) |
|
{ return i.less(i2); } |
|
|
|
friend bool operator> (const this_type& i, const this_type& i2) |
|
{ return i2 < i; } |
|
|
|
friend bool operator<= (const this_type& i, const this_type& i2) |
|
{ return !(i > i2); } |
|
|
|
friend bool operator>= (const this_type& i, const this_type& i2) |
|
{ return !(i < i2); } |
|
|
|
friend difference_type operator- (const this_type& i, const this_type& i2) |
|
{ return i2.distance_to(i); } |
|
|
|
//Arithmetic |
|
this_type& operator+=(difference_type off) |
|
{ this->advance(off); return *this; } |
|
|
|
this_type operator+(difference_type off) const |
|
{ |
|
this_type other(*this); |
|
other.advance(off); |
|
return other; |
|
} |
|
|
|
friend this_type operator+(difference_type off, const this_type& right) |
|
{ return right + off; } |
|
|
|
this_type& operator-=(difference_type off) |
|
{ this->advance(-off); return *this; } |
|
|
|
this_type operator-(difference_type off) const |
|
{ return *this + (-off); } |
|
|
|
const T& operator*() const |
|
{ return dereference(); } |
|
|
|
const T& operator[](difference_type) const |
|
{ return dereference(); } |
|
|
|
const T* operator->() const |
|
{ return &(dereference()); } |
|
|
|
void construct_in_place(T* ptr) |
|
{ (*m_pe)(ptr); } |
|
|
|
private: |
|
difference_type m_num; |
|
E * m_pe; |
|
|
|
void increment() |
|
{ --m_num; } |
|
|
|
void decrement() |
|
{ ++m_num; } |
|
|
|
bool equal(const this_type &other) const |
|
{ return m_num == other.m_num; } |
|
|
|
bool less(const this_type &other) const |
|
{ return other.m_num < m_num; } |
|
|
|
const T & dereference() const |
|
{ |
|
static T dummy; |
|
return dummy; |
|
} |
|
|
|
void advance(difference_type n) |
|
{ m_num -= n; } |
|
|
|
difference_type distance_to(const this_type &other)const |
|
{ return difference_type(m_num - other.m_num); } |
|
}; |
|
|
|
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING |
|
|
|
template<class T, class ...Args> |
|
struct emplace_functor |
|
{ |
|
typedef typename containers_detail::build_number_seq<sizeof...(Args)>::type index_tuple_t; |
|
|
|
emplace_functor(Args&&... args) |
|
: args_(args...) |
|
{} |
|
|
|
void operator()(T *ptr) |
|
{ emplace_functor::inplace_impl(ptr, index_tuple_t()); } |
|
|
|
template<int ...IdxPack> |
|
void inplace_impl(T* ptr, const containers_detail::index_tuple<IdxPack...>&) |
|
{ ::new(ptr) T(containers_detail::stored_ref<Args>::forward(containers_detail::get<IdxPack>(args_))...); } |
|
|
|
containers_detail::tuple<Args&...> args_; |
|
}; |
|
|
|
#else |
|
|
|
template<class T> |
|
struct emplace_functor |
|
{ |
|
emplace_functor() |
|
{} |
|
void operator()(T *ptr) |
|
{ new(ptr) T(); } |
|
}; |
|
|
|
#define BOOST_PP_LOCAL_MACRO(n) \ |
|
template <class T, BOOST_PP_ENUM_PARAMS(n, class P) > \ |
|
struct BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \ |
|
{ \ |
|
BOOST_PP_CAT(BOOST_PP_CAT(emplace_functor, n), arg) \ |
|
( BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_PARAM_LIST, _) ) \ |
|
: BOOST_PP_ENUM(n, BOOST_CONTAINERS_AUX_PARAM_INIT, _) {} \ |
|
\ |
|
void operator()(T *ptr) \ |
|
{ \ |
|
new(ptr)T (BOOST_PP_ENUM(n, BOOST_CONTAINERS_PP_MEMBER_FORWARD, _)); \ |
|
} \ |
|
BOOST_PP_REPEAT(n, BOOST_CONTAINERS_AUX_PARAM_DEFINE, _) \ |
|
}; \ |
|
//! |
|
#define BOOST_PP_LOCAL_LIMITS (1, BOOST_CONTAINERS_MAX_CONSTRUCTOR_PARAMETERS) |
|
#include BOOST_PP_LOCAL_ITERATE() |
|
|
|
#endif |
|
|
|
} //namespace container { |
|
} //namespace boost { |
|
|
|
#include <boost/container/detail/config_end.hpp> |
|
|
|
#endif //#ifndef BOOST_CONTAINERS_DETAIL_ITERATORS_HPP |
|
|
|
|