blob: bfc4e1d042111cbca8e4c6783fe5adddb2079697 [file] [log] [blame]
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005-2009.
// (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 INCLUDE_BOOST_CONTAINER_DETAIL_WORKAROUND_HPP
#include INCLUDE_BOOST_CONTAINER_MOVE_HPP
#ifdef BOOST_CONTAINERS_PERFECT_FORWARDING
#include INCLUDE_BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
#include INCLUDE_BOOST_CONTAINER_DETAIL_STORED_REF_HPP
#else
#include 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 emplace_iterator
: public std::iterator
<std::random_access_iterator_tag, T, std::ptrdiff_t, const T*, const T &>
{
typedef emplace_iterator this_type;
public:
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 std::ptrdiff_t operator- (const this_type& i, const this_type& i2)
{ return i2.distance_to(i); }
//Arithmetic
this_type& operator+=(std::ptrdiff_t off)
{ this->advance(off); return *this; }
this_type operator+(std::ptrdiff_t off) const
{
this_type other(*this);
other.advance(off);
return other;
}
friend this_type operator+(std::ptrdiff_t off, const this_type& right)
{ return right + off; }
this_type& operator-=(std::ptrdiff_t off)
{ this->advance(-off); return *this; }
this_type operator-(std::ptrdiff_t off) const
{ return *this + (-off); }
const T& operator*() const
{ return dereference(); }
const T& operator[](std::ptrdiff_t) const
{ return dereference(); }
const T* operator->() const
{ return &(dereference()); }
void construct_in_place(T* ptr)
{ (*m_pe)(ptr); }
private:
std::ptrdiff_t 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(std::ptrdiff_t n)
{ m_num -= n; }
std::ptrdiff_t distance_to(const this_type &other)const
{ return 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 INCLUDE_BOOST_CONTAINER_DETAIL_CONFIG_END_HPP
#endif //#ifndef BOOST_CONTAINERS_DETAIL_ITERATORS_HPP