mirror of
https://github.com/boostorg/container.git
synced 2025-08-01 05:24:31 +02:00
Add experimental (macro protected) support for lighter iterators
This commit is contained in:
@@ -106,6 +106,10 @@ namespace dtl {
|
||||
// [map, map + map_size).
|
||||
// A pointer in the range [map, map + map_size) points to an allocated node
|
||||
// if and only if the pointer is in the range [start.node, finish.node].
|
||||
|
||||
#define BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL 0
|
||||
|
||||
#if BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL == 0
|
||||
template<class Pointer, bool IsConst>
|
||||
class deque_iterator
|
||||
{
|
||||
@@ -241,15 +245,15 @@ class deque_iterator
|
||||
if (!n)
|
||||
return *this;
|
||||
BOOST_ASSERT(!!m_cur);
|
||||
difference_type offset = n + (this->m_cur - this->m_first);
|
||||
const difference_type offset = n + (this->m_cur - this->m_first);
|
||||
const difference_type block_size = m_last - m_first;
|
||||
BOOST_ASSERT(block_size);
|
||||
if (offset >= 0 && offset < block_size)
|
||||
this->m_cur += difference_type(n);
|
||||
else {
|
||||
difference_type node_offset =
|
||||
offset > 0 ? (offset / block_size)
|
||||
: (-difference_type((-offset - 1) / block_size) - 1);
|
||||
const difference_type node_offset =
|
||||
offset > 0 ? (offset / block_size)
|
||||
: (-difference_type((-offset - 1) / block_size) - 1);
|
||||
this->priv_set_node(this->m_node + node_offset, size_type(block_size));
|
||||
this->m_cur = this->m_first +
|
||||
(offset - node_offset * block_size);
|
||||
@@ -313,6 +317,447 @@ class deque_iterator
|
||||
}
|
||||
};
|
||||
|
||||
#elif BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL == 1
|
||||
|
||||
template<class Pointer, bool IsConst, unsigned BlockBytes, unsigned BlockSize>
|
||||
class deque_iterator
|
||||
{
|
||||
public:
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
|
||||
typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
|
||||
typedef typename boost::intrusive::pointer_traits<Pointer>::size_type size_type;
|
||||
typedef typename if_c
|
||||
< IsConst
|
||||
, typename boost::intrusive::pointer_traits<Pointer>::template
|
||||
rebind_pointer<const value_type>::type
|
||||
, Pointer
|
||||
>::type pointer;
|
||||
typedef typename if_c
|
||||
< IsConst
|
||||
, const value_type&
|
||||
, value_type&
|
||||
>::type reference;
|
||||
|
||||
BOOST_CONSTEXPR inline static size_type get_block_size() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return deque_block_size<value_type, BlockBytes, BlockSize>::value; }
|
||||
|
||||
BOOST_CONSTEXPR inline static difference_type get_block_ssize() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return difference_type((get_block_size())); }
|
||||
|
||||
class nat;
|
||||
typedef typename dtl::if_c< IsConst
|
||||
, deque_iterator<Pointer, false, BlockBytes, BlockSize>
|
||||
, nat>::type nonconst_iterator;
|
||||
|
||||
typedef Pointer val_alloc_ptr;
|
||||
typedef typename boost::intrusive::pointer_traits<Pointer>::
|
||||
template rebind_pointer<Pointer>::type index_pointer;
|
||||
|
||||
Pointer m_cur;
|
||||
Pointer m_first;
|
||||
index_pointer m_node;
|
||||
|
||||
public:
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_cur() const { return m_cur; }
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_first() const { return m_first; }
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_last() const { return m_first + get_block_ssize(); }
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline index_pointer get_node() const { return m_node; }
|
||||
|
||||
inline deque_iterator(val_alloc_ptr x, index_pointer y, difference_type ) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_cur(x), m_first(*y), m_node(y)
|
||||
{}
|
||||
|
||||
inline deque_iterator(val_alloc_ptr x, index_pointer y, size_type ) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_cur(x), m_first(*y), m_node(y)
|
||||
{}
|
||||
|
||||
inline deque_iterator() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_cur(), m_first(), m_node() //Value initialization to achieve "null iterators" (N3644)
|
||||
{}
|
||||
|
||||
inline deque_iterator(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_cur(x.get_cur()), m_first(x.get_first()), m_node(x.get_node())
|
||||
{}
|
||||
|
||||
inline deque_iterator(const nonconst_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_cur(x.get_cur()), m_first(x.get_first()), m_node(x.get_node())
|
||||
{}
|
||||
|
||||
inline deque_iterator(Pointer cur, Pointer first, index_pointer node) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_cur(cur), m_first(first), m_node(node)
|
||||
{}
|
||||
|
||||
inline deque_iterator& operator=(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ m_cur = x.get_cur(); m_first = x.get_first(); m_node = x.get_node(); return *this; }
|
||||
|
||||
inline nonconst_iterator unconst() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
return nonconst_iterator(this->get_cur(), this->get_first(), this->get_node());
|
||||
}
|
||||
|
||||
inline reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return *this->m_cur; }
|
||||
|
||||
inline pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_cur; }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD difference_type operator-(const deque_iterator& x) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
if(!this->m_cur && !x.m_cur){
|
||||
return 0;
|
||||
}
|
||||
const difference_type block_size = get_block_ssize();
|
||||
BOOST_ASSERT(block_size);
|
||||
return block_size * (this->m_node - x.m_node - 1) +
|
||||
(this->m_cur - this->m_first) + ((x.m_first+block_size) - x.m_cur);
|
||||
}
|
||||
|
||||
deque_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT(!!m_cur);
|
||||
++this->m_cur;
|
||||
const difference_type block_size = get_block_ssize();
|
||||
if (this->m_cur == (this->m_first+block_size)) {
|
||||
|
||||
BOOST_ASSERT(block_size);
|
||||
++this->m_node;
|
||||
this->m_first = *this->m_node;
|
||||
this->m_cur = this->m_first;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline deque_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
deque_iterator tmp(*this);
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
deque_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT(!!m_cur);
|
||||
if (this->m_cur == this->m_first) {
|
||||
--this->m_node;
|
||||
this->m_first = *this->m_node;
|
||||
this->m_cur = this->m_first + get_block_ssize();
|
||||
}
|
||||
--this->m_cur;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline deque_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
deque_iterator tmp(*this);
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
deque_iterator& operator+=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
if (!n)
|
||||
return *this;
|
||||
BOOST_ASSERT(!!m_cur);
|
||||
const difference_type offset = n + (this->m_cur - this->m_first);
|
||||
const difference_type block_size = get_block_ssize();
|
||||
BOOST_ASSERT(block_size);
|
||||
if (offset >= 0 && offset < block_size)
|
||||
this->m_cur += difference_type(n);
|
||||
else {
|
||||
const difference_type node_offset =
|
||||
offset > 0 ? (offset / block_size)
|
||||
: (-difference_type((-offset - 1) / block_size) - 1);
|
||||
this->m_node += node_offset;
|
||||
this->m_first = *this->m_node;
|
||||
this->m_cur = this->m_first + (offset - node_offset * block_size);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
deque_iterator operator+(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ deque_iterator tmp(*this); return tmp += n; }
|
||||
|
||||
inline
|
||||
deque_iterator& operator-=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return *this += -n; }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
deque_iterator operator-(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ deque_iterator tmp(*this); return tmp -= n; }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
reference operator[](difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return *(*this + n); }
|
||||
|
||||
//Comparisons
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
friend bool operator==(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return l.m_cur == r.m_cur; }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
friend bool operator!=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return l.m_cur != r.m_cur; }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
friend bool operator<(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return (l.m_node == r.m_node) ? (l.m_cur < r.m_cur) : (l.m_node < r.m_node); }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
friend bool operator>(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return r < l; }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
friend bool operator<=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return !(r < l); }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
friend bool operator>=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return !(l < r); }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
friend deque_iterator operator+(difference_type n, deque_iterator x) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return x += n; }
|
||||
|
||||
inline void priv_set_node(index_pointer new_node, size_type ) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->priv_set_node(new_node, difference_type()); }
|
||||
|
||||
inline void priv_set_node(index_pointer new_node, difference_type) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
this->m_node = new_node;
|
||||
this->m_first = *new_node;
|
||||
}
|
||||
};
|
||||
|
||||
#elif BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL == 2
|
||||
|
||||
template<class Pointer, bool IsConst, unsigned BlockBytes, unsigned BlockSize>
|
||||
class deque_iterator
|
||||
{
|
||||
public:
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef typename boost::intrusive::pointer_traits<Pointer>::element_type value_type;
|
||||
typedef typename boost::intrusive::pointer_traits<Pointer>::difference_type difference_type;
|
||||
typedef typename boost::intrusive::pointer_traits<Pointer>::size_type size_type;
|
||||
typedef typename if_c
|
||||
< IsConst
|
||||
, typename boost::intrusive::pointer_traits<Pointer>::template
|
||||
rebind_pointer<const value_type>::type
|
||||
, Pointer
|
||||
>::type pointer;
|
||||
typedef typename if_c
|
||||
< IsConst
|
||||
, const value_type&
|
||||
, value_type&
|
||||
>::type reference;
|
||||
|
||||
BOOST_CONSTEXPR inline static size_type get_block_size() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_CONTAINER_STATIC_ASSERT((deque_block_size<value_type, BlockBytes, BlockSize>::value));
|
||||
return deque_block_size<value_type, BlockBytes, BlockSize>::value;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline static difference_type get_block_ssize() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return difference_type((get_block_size())); }
|
||||
|
||||
class nat;
|
||||
typedef typename dtl::if_c< IsConst
|
||||
, deque_iterator<Pointer, false, BlockBytes, BlockSize>
|
||||
, nat>::type nonconst_iterator;
|
||||
|
||||
typedef Pointer val_alloc_ptr;
|
||||
typedef typename boost::intrusive::pointer_traits<Pointer>::
|
||||
template rebind_pointer<Pointer>::type index_pointer;
|
||||
|
||||
Pointer m_cur;
|
||||
index_pointer m_node;
|
||||
|
||||
public:
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_cur() const { return m_cur; }
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_first() const { return *m_node; }
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline Pointer get_last() const { return *m_node + get_block_ssize(); }
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline index_pointer get_node() const { return m_node; }
|
||||
|
||||
inline deque_iterator(val_alloc_ptr x, index_pointer y, difference_type ) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_cur(x), m_node(y)
|
||||
{}
|
||||
|
||||
inline deque_iterator(val_alloc_ptr x, index_pointer y, size_type ) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_cur(x), m_node(y)
|
||||
{}
|
||||
|
||||
inline deque_iterator() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_cur(), m_node() //Value initialization to achieve "null iterators" (N3644)
|
||||
{}
|
||||
|
||||
inline deque_iterator(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_cur(x.get_cur()), m_node(x.get_node())
|
||||
{}
|
||||
|
||||
inline deque_iterator(const nonconst_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_cur(x.get_cur()), m_node(x.get_node())
|
||||
{}
|
||||
|
||||
inline deque_iterator(Pointer cur, index_pointer node) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
: m_cur(cur), m_node(node)
|
||||
{}
|
||||
|
||||
inline deque_iterator& operator=(const deque_iterator& x) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ m_cur = x.get_cur(); m_node = x.get_node(); return *this; }
|
||||
|
||||
inline nonconst_iterator unconst() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
return nonconst_iterator(this->get_cur(), this->get_node());
|
||||
}
|
||||
|
||||
inline reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return *this->m_cur; }
|
||||
|
||||
inline pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->m_cur; }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD difference_type operator-(const deque_iterator& x) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
if(!this->m_cur && !x.m_cur){
|
||||
return 0;
|
||||
}
|
||||
const difference_type block_size = get_block_ssize();
|
||||
BOOST_ASSERT(block_size);
|
||||
return block_size * (this->m_node - x.m_node - 1) +
|
||||
(this->m_cur - this->get_first()) + (x.get_last() - x.m_cur);
|
||||
}
|
||||
|
||||
deque_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT(!!m_cur);
|
||||
++this->m_cur;
|
||||
if (this->m_cur == (this->get_last())) {
|
||||
|
||||
++this->m_node;
|
||||
this->m_cur = *this->m_node;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline deque_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
deque_iterator tmp(*this);
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
deque_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT(!!m_cur);
|
||||
if (this->m_cur == this->get_first()) {
|
||||
--this->m_node;
|
||||
this->m_cur = this->get_last();
|
||||
}
|
||||
--this->m_cur;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline deque_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
deque_iterator tmp(*this);
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
deque_iterator& operator+=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
if (!n)
|
||||
return *this;
|
||||
BOOST_ASSERT(!!m_cur);
|
||||
const difference_type offset = n + (this->m_cur - this->get_first());
|
||||
const difference_type block_size = get_block_ssize();
|
||||
BOOST_ASSERT(block_size);
|
||||
if (offset >= 0 && offset < block_size)
|
||||
this->m_cur += difference_type(n);
|
||||
else {
|
||||
const difference_type node_offset =
|
||||
offset > 0 ? (offset / block_size)
|
||||
: (-difference_type((-offset - 1) / block_size) - 1);
|
||||
this->m_node += node_offset;
|
||||
this->m_cur = this->get_first() + (offset - node_offset * block_size);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
deque_iterator operator+(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ deque_iterator tmp(*this); return tmp += n; }
|
||||
|
||||
inline
|
||||
deque_iterator& operator-=(difference_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return *this += -n; }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
deque_iterator operator-(difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ deque_iterator tmp(*this); return tmp -= n; }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
reference operator[](difference_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT(!!m_cur);
|
||||
const difference_type offset = n + (this->m_cur - this->get_first());
|
||||
const difference_type block_size = get_block_ssize();
|
||||
if (offset >= 0 && offset < block_size)
|
||||
return this->m_cur[difference_type(n)];
|
||||
else {
|
||||
const difference_type node_offset = offset > 0
|
||||
? (offset / block_size)
|
||||
: (-difference_type((-offset - 1) / block_size) - 1);
|
||||
return (this->m_node[node_offset]) [offset - node_offset * block_size];
|
||||
}
|
||||
}
|
||||
|
||||
//Comparisons
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
friend bool operator==(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return l.m_cur == r.m_cur; }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
friend bool operator!=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return l.m_cur != r.m_cur; }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
friend bool operator<(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return (l.m_node == r.m_node) ? (l.m_cur < r.m_cur) : (l.m_node < r.m_node); }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
friend bool operator>(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return r < l; }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
friend bool operator<=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return !(r < l); }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
friend bool operator>=(const deque_iterator& l, const deque_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return !(l < r); }
|
||||
|
||||
BOOST_CONTAINER_ATTRIBUTE_NODISCARD inline
|
||||
friend deque_iterator operator+(difference_type n, deque_iterator x) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return x += n; }
|
||||
|
||||
inline void priv_set_node(index_pointer new_node, size_type ) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->priv_set_node(new_node, difference_type()); }
|
||||
|
||||
inline void priv_set_node(index_pointer new_node, difference_type) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
this->m_node = new_node;
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#error "Invalid BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL"
|
||||
|
||||
#endif
|
||||
} //namespace dtl {
|
||||
|
||||
template<class Options>
|
||||
@@ -360,15 +805,20 @@ class deque_base
|
||||
typedef typename get_deque_opt<Options>::type options_type;
|
||||
|
||||
protected:
|
||||
#if BOOST_CONTAINER_DEQUE_LIGHTER_ITERATOR_LEVEL == 0
|
||||
typedef dtl::deque_iterator<val_alloc_ptr, false> iterator;
|
||||
typedef dtl::deque_iterator<val_alloc_ptr, true > const_iterator;
|
||||
typedef dtl::deque_iterator<val_alloc_ptr, true> const_iterator;
|
||||
#else
|
||||
typedef dtl::deque_iterator<val_alloc_ptr, false, options_type::block_bytes, options_type::block_size> iterator;
|
||||
typedef dtl::deque_iterator<val_alloc_ptr, true, options_type::block_bytes, options_type::block_size> const_iterator;
|
||||
#endif
|
||||
|
||||
BOOST_CONSTEXPR inline static val_alloc_diff get_block_ssize() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return val_alloc_diff((get_block_size())); }
|
||||
|
||||
BOOST_CONSTEXPR inline static size_type get_block_size() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return deque_block_size<val_alloc_val, options_type::block_bytes, options_type::block_size>::value; }
|
||||
|
||||
BOOST_CONSTEXPR inline static val_alloc_diff get_block_ssize() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return val_alloc_diff((get_block_size)()); }
|
||||
|
||||
typedef deque_value_traits<val_alloc_val> traits_t;
|
||||
typedef ptr_alloc_t map_allocator_type;
|
||||
|
||||
@@ -446,8 +896,8 @@ class deque_base
|
||||
|
||||
this->members_.m_start.priv_set_node(nstart, get_block_size());
|
||||
this->members_.m_finish.priv_set_node(nfinish - 1, get_block_size());
|
||||
this->members_.m_start.m_cur = this->members_.m_start.m_first;
|
||||
this->members_.m_finish.m_cur = this->members_.m_finish.m_first + difference_type(num_elements % get_block_size());
|
||||
this->members_.m_start.m_cur = this->members_.m_start.get_first();
|
||||
this->members_.m_finish.m_cur = this->members_.m_finish.get_first() + difference_type(num_elements % get_block_size());
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -1741,7 +2191,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
|
||||
void pop_front() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
if (this->members_.m_start.m_cur != this->members_.m_start.m_last - 1) {
|
||||
if (this->members_.m_start.m_cur != this->members_.m_start.get_last() - 1) {
|
||||
allocator_traits_type::destroy
|
||||
( this->alloc()
|
||||
, boost::movelib::to_raw_pointer(this->members_.m_start.m_cur)
|
||||
@@ -1760,7 +2210,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
|
||||
void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
if (this->members_.m_finish.m_cur != this->members_.m_finish.m_first) {
|
||||
if (this->members_.m_finish.m_cur != this->members_.m_finish.get_first()) {
|
||||
--this->members_.m_finish.m_cur;
|
||||
allocator_traits_type::destroy
|
||||
( this->alloc()
|
||||
@@ -1865,9 +2315,9 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
|
||||
}
|
||||
|
||||
if (this->members_.m_start.m_node != this->members_.m_finish.m_node) {
|
||||
this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.m_last);
|
||||
this->priv_destroy_range(this->members_.m_finish.m_first, this->members_.m_finish.m_cur);
|
||||
this->priv_deallocate_node(this->members_.m_finish.m_first);
|
||||
this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_start.get_last());
|
||||
this->priv_destroy_range(this->members_.m_finish.get_first(), this->members_.m_finish.m_cur);
|
||||
this->priv_deallocate_node(this->members_.m_finish.get_first());
|
||||
}
|
||||
else
|
||||
this->priv_destroy_range(this->members_.m_start.m_cur, this->members_.m_finish.m_cur);
|
||||
@@ -2016,7 +2466,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
|
||||
inline bool priv_push_back_simple_available() const
|
||||
{
|
||||
return this->members_.m_map &&
|
||||
(this->members_.m_finish.m_cur != (this->members_.m_finish.m_last - 1));
|
||||
(this->members_.m_finish.m_cur != (this->members_.m_finish.get_last() - 1));
|
||||
}
|
||||
|
||||
inline T *priv_push_back_simple_pos() const
|
||||
@@ -2032,7 +2482,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
|
||||
inline bool priv_push_front_simple_available() const
|
||||
{
|
||||
return this->members_.m_map &&
|
||||
(this->members_.m_start.m_cur != this->members_.m_start.m_first);
|
||||
(this->members_.m_start.m_cur != this->members_.m_start.get_first());
|
||||
}
|
||||
|
||||
inline T *priv_push_front_simple_pos() const
|
||||
@@ -2060,84 +2510,117 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
|
||||
}
|
||||
|
||||
template<class InsertProxy>
|
||||
iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy proxy)
|
||||
iterator priv_insert_middle_aux_impl(const_iterator p, const size_type elemsbefore, const size_type length, const size_type n, InsertProxy proxy)
|
||||
{
|
||||
iterator pos(p.unconst());
|
||||
const size_type pos_n = size_type(p - this->cbegin());
|
||||
if(!this->members_.m_map){
|
||||
if (!this->members_.m_map) {
|
||||
this->priv_initialize_map(0);
|
||||
pos = this->begin();
|
||||
p = this->cbegin();
|
||||
}
|
||||
|
||||
const size_type elemsbefore = static_cast<size_type>(pos - this->members_.m_start);
|
||||
const size_type length = this->size();
|
||||
iterator pos(p.unconst());
|
||||
const size_type pos_n = size_type(p - this->cbegin());
|
||||
|
||||
if (elemsbefore < length / 2) {
|
||||
const iterator new_start = this->priv_reserve_elements_at_front(n);
|
||||
const iterator old_start = this->members_.m_start;
|
||||
if(!elemsbefore){
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n);
|
||||
this->members_.m_start = new_start;
|
||||
}
|
||||
else{
|
||||
pos = this->members_.m_start + difference_type(elemsbefore);
|
||||
if (elemsbefore >= n) {
|
||||
const iterator start_n = this->members_.m_start + difference_type(n);
|
||||
pos = this->members_.m_start + difference_type(elemsbefore);
|
||||
if (elemsbefore >= n) {
|
||||
const iterator start_n = this->members_.m_start + difference_type(n);
|
||||
BOOST_CONTAINER_TRY {
|
||||
::boost::container::uninitialized_move_alloc
|
||||
(this->alloc(), this->members_.m_start, start_n, new_start);
|
||||
this->members_.m_start = new_start;
|
||||
boost::container::move(start_n, pos, old_start);
|
||||
proxy.copy_n_and_update(this->alloc(), pos - difference_type(n), n);
|
||||
}
|
||||
else {
|
||||
const size_type mid_count = n - elemsbefore;
|
||||
const iterator mid_start = old_start - difference_type(mid_count);
|
||||
BOOST_CONTAINER_CATCH(...) {
|
||||
this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
|
||||
BOOST_CONTAINER_RETHROW
|
||||
}
|
||||
BOOST_CONTAINER_CATCH_END
|
||||
this->members_.m_start = new_start;
|
||||
boost::container::move(start_n, pos, old_start);
|
||||
proxy.copy_n_and_update(this->alloc(), pos - difference_type(n), n);
|
||||
}
|
||||
else {
|
||||
const size_type mid_count = n - elemsbefore;
|
||||
const iterator mid_start = old_start - difference_type(mid_count);
|
||||
BOOST_CONTAINER_TRY {
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), mid_start, mid_count);
|
||||
this->members_.m_start = mid_start;
|
||||
::boost::container::uninitialized_move_alloc
|
||||
(this->alloc(), old_start, pos, new_start);
|
||||
this->members_.m_start = new_start;
|
||||
proxy.copy_n_and_update(this->alloc(), old_start, elemsbefore);
|
||||
::boost::container::uninitialized_move_alloc(this->alloc(), old_start, pos, new_start);
|
||||
}
|
||||
BOOST_CONTAINER_CATCH(...) {
|
||||
this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
|
||||
BOOST_CONTAINER_RETHROW
|
||||
}
|
||||
BOOST_CONTAINER_CATCH_END
|
||||
this->members_.m_start = new_start;
|
||||
proxy.copy_n_and_update(this->alloc(), old_start, elemsbefore);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const iterator new_finish = this->priv_reserve_elements_at_back(n);
|
||||
const iterator old_finish = this->members_.m_finish;
|
||||
const size_type elemsafter = length - elemsbefore;
|
||||
if(!elemsafter){
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, n);
|
||||
this->members_.m_finish = new_finish;
|
||||
}
|
||||
else{
|
||||
pos = old_finish - difference_type(elemsafter);
|
||||
if (elemsafter >= n) {
|
||||
iterator finish_n = old_finish - difference_type(n);
|
||||
::boost::container::uninitialized_move_alloc
|
||||
(this->alloc(), finish_n, old_finish, old_finish);
|
||||
this->members_.m_finish = new_finish;
|
||||
boost::container::move_backward(pos, finish_n, old_finish);
|
||||
proxy.copy_n_and_update(this->alloc(), pos, n);
|
||||
|
||||
pos = old_finish - difference_type(elemsafter);
|
||||
if (elemsafter >= n) {
|
||||
iterator finish_n = old_finish - difference_type(n);
|
||||
BOOST_CONTAINER_TRY {
|
||||
::boost::container::uninitialized_move_alloc(this->alloc(), finish_n, old_finish, old_finish);
|
||||
}
|
||||
else {
|
||||
const size_type raw_gap = n - elemsafter;
|
||||
BOOST_CONTAINER_CATCH(...) {
|
||||
this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1);
|
||||
BOOST_CONTAINER_RETHROW
|
||||
}
|
||||
BOOST_CONTAINER_CATCH_END
|
||||
|
||||
this->members_.m_finish = new_finish;
|
||||
boost::container::move_backward(pos, finish_n, old_finish);
|
||||
proxy.copy_n_and_update(this->alloc(), pos, n);
|
||||
}
|
||||
else {
|
||||
const size_type raw_gap = n - elemsafter;
|
||||
BOOST_CONTAINER_TRY{
|
||||
::boost::container::uninitialized_move_alloc
|
||||
(this->alloc(), pos, old_finish, old_finish + difference_type(raw_gap));
|
||||
BOOST_CONTAINER_TRY{
|
||||
proxy.copy_n_and_update(this->alloc(), pos, elemsafter);
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, raw_gap);
|
||||
}
|
||||
BOOST_CONTAINER_CATCH(...){
|
||||
BOOST_CONTAINER_CATCH(...) {
|
||||
this->priv_destroy_range(old_finish, old_finish + difference_type(elemsafter));
|
||||
BOOST_CONTAINER_RETHROW
|
||||
}
|
||||
BOOST_CONTAINER_CATCH_END
|
||||
this->members_.m_finish = new_finish;
|
||||
}
|
||||
BOOST_CONTAINER_CATCH(...) {
|
||||
this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1);
|
||||
BOOST_CONTAINER_RETHROW
|
||||
}
|
||||
BOOST_CONTAINER_CATCH_END
|
||||
this->members_.m_finish = new_finish;
|
||||
}
|
||||
}
|
||||
return this->begin() + difference_type(pos_n);
|
||||
}
|
||||
|
||||
template<class InsertProxy>
|
||||
iterator priv_insert_aux_impl(const_iterator p, size_type n, InsertProxy proxy)
|
||||
{
|
||||
iterator pos(p.unconst());
|
||||
const size_type elemsbefore = static_cast<size_type>(pos - this->members_.m_start);
|
||||
const size_type length = this->size();
|
||||
|
||||
if (!elemsbefore) {
|
||||
return this->priv_insert_front_aux_impl(n, proxy);
|
||||
}
|
||||
else if (elemsbefore == length) {
|
||||
return this->priv_insert_back_aux_impl(n, proxy);
|
||||
}
|
||||
else {
|
||||
return this->priv_insert_middle_aux_impl(p, elemsbefore, length, n, proxy);
|
||||
}
|
||||
}
|
||||
|
||||
template <class InsertProxy>
|
||||
iterator priv_insert_back_aux_impl(size_type n, InsertProxy proxy)
|
||||
{
|
||||
@@ -2146,8 +2629,14 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
|
||||
}
|
||||
|
||||
iterator new_finish = this->priv_reserve_elements_at_back(n);
|
||||
iterator old_finish = this->members_.m_finish;
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), old_finish, n);
|
||||
BOOST_CONTAINER_TRY{
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), this->members_.m_finish, n);
|
||||
}
|
||||
BOOST_CONTAINER_CATCH(...) {
|
||||
this->priv_destroy_nodes(this->members_.m_finish.m_node + 1, new_finish.m_node + 1);
|
||||
BOOST_CONTAINER_RETHROW
|
||||
}
|
||||
BOOST_CONTAINER_CATCH_END
|
||||
this->members_.m_finish = new_finish;
|
||||
return iterator(this->members_.m_finish - difference_type(n));
|
||||
}
|
||||
@@ -2160,7 +2649,15 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
|
||||
}
|
||||
|
||||
iterator new_start = this->priv_reserve_elements_at_front(n);
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n);
|
||||
BOOST_CONTAINER_TRY{
|
||||
proxy.uninitialized_copy_n_and_update(this->alloc(), new_start, n);
|
||||
}
|
||||
BOOST_CONTAINER_CATCH(...) {
|
||||
this->priv_destroy_nodes(new_start.m_node, this->members_.m_start.m_node);
|
||||
BOOST_CONTAINER_RETHROW
|
||||
}
|
||||
BOOST_CONTAINER_CATCH_END
|
||||
|
||||
this->members_.m_start = new_start;
|
||||
return new_start;
|
||||
}
|
||||
@@ -2181,7 +2678,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
|
||||
(this->alloc(), *cur, *cur + get_block_ssize(), value);
|
||||
}
|
||||
boost::container::uninitialized_fill_alloc
|
||||
(this->alloc(), this->members_.m_finish.m_first, this->members_.m_finish.m_cur, value);
|
||||
(this->alloc(), this->members_.m_finish.get_first(), this->members_.m_finish.m_cur, value);
|
||||
}
|
||||
BOOST_CONTAINER_CATCH(...){
|
||||
this->priv_destroy_range(this->members_.m_start, iterator(*cur, cur, get_block_size()));
|
||||
@@ -2220,7 +2717,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
|
||||
::boost::container::uninitialized_copy_alloc(this->alloc(), first, mid, *cur_node);
|
||||
first = mid;
|
||||
}
|
||||
::boost::container::uninitialized_copy_alloc(this->alloc(), first, last, this->members_.m_finish.m_first);
|
||||
::boost::container::uninitialized_copy_alloc(this->alloc(), first, last, this->members_.m_finish.get_first());
|
||||
}
|
||||
BOOST_CONTAINER_CATCH(...){
|
||||
this->priv_destroy_range(this->members_.m_start, iterator(*cur_node, cur_node, get_block_size()));
|
||||
@@ -2229,21 +2726,21 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
|
||||
BOOST_CONTAINER_CATCH_END
|
||||
}
|
||||
|
||||
// Called only if this->members_.m_finish.m_cur == this->members_.m_finish.m_first.
|
||||
// Called only if this->members_.m_finish.m_cur == this->members_.m_finish.get_first().
|
||||
void priv_pop_back_aux() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
this->priv_deallocate_node(this->members_.m_finish.m_first);
|
||||
this->priv_deallocate_node(this->members_.m_finish.get_first());
|
||||
this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node - 1, get_block_size());
|
||||
this->members_.m_finish.m_cur = this->members_.m_finish.m_last - 1;
|
||||
this->members_.m_finish.m_cur = this->members_.m_finish.get_last() - 1;
|
||||
allocator_traits_type::destroy
|
||||
( this->alloc()
|
||||
, boost::movelib::to_raw_pointer(this->members_.m_finish.m_cur)
|
||||
);
|
||||
}
|
||||
|
||||
// Called only if this->members_.m_start.m_cur == this->members_.m_start.m_last - 1. Note that
|
||||
// Called only if this->members_.m_start.m_cur == this->members_.m_start.get_last() - 1. Note that
|
||||
// if the deque has at least one element (a precondition for this member
|
||||
// function), and if this->members_.m_start.m_cur == this->members_.m_start.m_last, then the deque
|
||||
// function), and if this->members_.m_start.m_cur == this->members_.m_start.get_last(), then the deque
|
||||
// must have at least two nodes.
|
||||
void priv_pop_front_aux() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
@@ -2251,14 +2748,14 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
|
||||
( this->alloc()
|
||||
, boost::movelib::to_raw_pointer(this->members_.m_start.m_cur)
|
||||
);
|
||||
this->priv_deallocate_node(this->members_.m_start.m_first);
|
||||
this->priv_deallocate_node(this->members_.m_start.get_first());
|
||||
this->members_.m_start.priv_set_node(this->members_.m_start.m_node + 1, get_block_size());
|
||||
this->members_.m_start.m_cur = this->members_.m_start.m_first;
|
||||
this->members_.m_start.m_cur = this->members_.m_start.get_first();
|
||||
}
|
||||
|
||||
iterator priv_reserve_elements_at_front(size_type n)
|
||||
{
|
||||
size_type vacancies = size_type(this->members_.m_start.m_cur - this->members_.m_start.m_first);
|
||||
size_type vacancies = size_type(this->members_.m_start.m_cur - this->members_.m_start.get_first());
|
||||
if (n > vacancies){
|
||||
size_type new_elems = n-vacancies;
|
||||
size_type new_nodes = (new_elems + get_block_size() - 1u) / get_block_size();
|
||||
@@ -2283,7 +2780,7 @@ class deque : protected deque_base<typename real_allocator<T, Allocator>::type,
|
||||
|
||||
iterator priv_reserve_elements_at_back(size_type n)
|
||||
{
|
||||
size_type vacancies = size_type(this->members_.m_finish.m_last - this->members_.m_finish.m_cur - 1);
|
||||
size_type vacancies = size_type(this->members_.m_finish.get_last() - this->members_.m_finish.m_cur - 1);
|
||||
if (n > vacancies){
|
||||
size_type new_elems = size_type(n - vacancies);
|
||||
size_type new_nodes = size_type(new_elems + get_block_size() - 1u)/get_block_size();
|
||||
@@ -2348,7 +2845,8 @@ template <typename InputIterator, typename Allocator>
|
||||
deque(InputIterator, InputIterator, Allocator const&) -> deque<typename iterator_traits<InputIterator>::value_type, Allocator>;
|
||||
#endif
|
||||
|
||||
}}
|
||||
} //namespace container
|
||||
} //namespace boost
|
||||
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
|
||||
|
Reference in New Issue
Block a user