mirror of
https://github.com/boostorg/container.git
synced 2025-08-02 14:04:26 +02:00
Added debug assertions via BOOST_ASSERT to check preconditions in several members. All checks are O(1)
This commit is contained in:
@@ -1216,6 +1216,8 @@ use [*Boost.Container]? There are several reasons for that:
|
||||
[section:release_notes_boost_1_60_00 Boost 1.60 Release]
|
||||
|
||||
* Implemented [link container.extended_functionality.polymorphic_memory_resources Polymorphic Memory Resources].
|
||||
* Add more BOOST_ASSERT checks to test preconditions in some operations (like `pop_back`, `pop_front`, `back`, `front`, etc.)
|
||||
* Added C++11 `back`/`front` operations to [classref boost::container::basic_string basic_string].
|
||||
* Fixed bugs:
|
||||
* [@https://svn.boost.org/trac/boost/ticket/11627 Trac #11627: ['"small_vector<T,n>::swap() appears to be broken"]].
|
||||
* [@https://svn.boost.org/trac/boost/ticket/11628 Trac #11628: ['"small_vector<int,n> iterates over elements in destructor"]].
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2015. 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)
|
||||
//
|
||||
@@ -1140,7 +1140,10 @@ class deque : protected deque_base<Allocator>
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
reference front() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return *this->members_.m_start; }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return *this->members_.m_start;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: !empty()
|
||||
//!
|
||||
@@ -1151,7 +1154,10 @@ class deque : protected deque_base<Allocator>
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return *this->members_.m_start; }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return *this->members_.m_start;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: !empty()
|
||||
//!
|
||||
@@ -1162,7 +1168,10 @@ class deque : protected deque_base<Allocator>
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
reference back() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return *(end()-1); }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return *(end()-1);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: !empty()
|
||||
//!
|
||||
@@ -1173,7 +1182,10 @@ class deque : protected deque_base<Allocator>
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return *(cend()-1); }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return *(cend()-1);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: size() > n.
|
||||
//!
|
||||
@@ -1184,7 +1196,10 @@ class deque : protected deque_base<Allocator>
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->members_.m_start[difference_type(n)]; }
|
||||
{
|
||||
BOOST_ASSERT(this->size() > n);
|
||||
return this->members_.m_start[difference_type(n)];
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: size() > n.
|
||||
//!
|
||||
@@ -1195,7 +1210,10 @@ class deque : protected deque_base<Allocator>
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->members_.m_start[difference_type(n)]; }
|
||||
{
|
||||
BOOST_ASSERT(this->size() > n);
|
||||
return this->members_.m_start[difference_type(n)];
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: size() >= n.
|
||||
//!
|
||||
@@ -1243,7 +1261,10 @@ class deque : protected deque_base<Allocator>
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension
|
||||
size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->priv_index_of(p); }
|
||||
{
|
||||
//Range checked priv_index_of
|
||||
return this->priv_index_of(p);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: begin() <= p <= end().
|
||||
//!
|
||||
@@ -1256,7 +1277,10 @@ class deque : protected deque_base<Allocator>
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension
|
||||
size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->priv_index_of(p); }
|
||||
{
|
||||
//Range checked priv_index_of
|
||||
return this->priv_index_of(p);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: size() > n.
|
||||
//!
|
||||
@@ -1267,7 +1291,10 @@ class deque : protected deque_base<Allocator>
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
reference at(size_type n)
|
||||
{ this->priv_range_check(n); return (*this)[n]; }
|
||||
{
|
||||
this->priv_throw_if_out_of_range(n);
|
||||
return (*this)[n];
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: size() > n.
|
||||
//!
|
||||
@@ -1278,7 +1305,10 @@ class deque : protected deque_base<Allocator>
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reference at(size_type n) const
|
||||
{ this->priv_range_check(n); return (*this)[n]; }
|
||||
{
|
||||
this->priv_throw_if_out_of_range(n);
|
||||
return (*this)[n];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
//
|
||||
@@ -1344,6 +1374,7 @@ class deque : protected deque_base<Allocator>
|
||||
template <class... Args>
|
||||
iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(p));
|
||||
if(p == this->cbegin()){
|
||||
this->emplace_front(boost::forward<Args>(args)...);
|
||||
return this->begin();
|
||||
@@ -1394,6 +1425,7 @@ class deque : protected deque_base<Allocator>
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\
|
||||
iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(p));\
|
||||
if(p == this->cbegin()){\
|
||||
this->emplace_front(BOOST_MOVE_FWD##N);\
|
||||
return this->begin();\
|
||||
@@ -1494,6 +1526,7 @@ class deque : protected deque_base<Allocator>
|
||||
//! <b>Complexity</b>: Linear to n.
|
||||
iterator insert(const_iterator pos, size_type n, const value_type& x)
|
||||
{
|
||||
//Range check of p is done by insert()
|
||||
typedef constant_iterator<value_type, difference_type> c_it;
|
||||
return this->insert(pos, c_it(x, n), c_it());
|
||||
}
|
||||
@@ -1519,6 +1552,7 @@ class deque : protected deque_base<Allocator>
|
||||
#endif
|
||||
)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(pos));
|
||||
size_type n = 0;
|
||||
iterator it(pos.unconst());
|
||||
for(;first != last; ++first, ++n){
|
||||
@@ -1541,7 +1575,10 @@ class deque : protected deque_base<Allocator>
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
|
||||
iterator insert(const_iterator pos, std::initializer_list<value_type> il)
|
||||
{ return insert(pos, il.begin(), il.end()); }
|
||||
{
|
||||
//Range check os pos is done in insert()
|
||||
return insert(pos, il.begin(), il.end());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
@@ -1556,6 +1593,7 @@ class deque : protected deque_base<Allocator>
|
||||
#endif
|
||||
)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(p));
|
||||
container_detail::insert_range_proxy<Allocator, FwdIt, iterator> proxy(first);
|
||||
return priv_insert_aux_impl(p, boost::container::iterator_distance(first, last), proxy);
|
||||
}
|
||||
@@ -1568,6 +1606,7 @@ class deque : protected deque_base<Allocator>
|
||||
//! <b>Complexity</b>: Constant time.
|
||||
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) {
|
||||
allocator_traits_type::destroy
|
||||
( this->alloc()
|
||||
@@ -1586,6 +1625,7 @@ class deque : protected deque_base<Allocator>
|
||||
//! <b>Complexity</b>: Constant time.
|
||||
void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
if (this->members_.m_finish.m_cur != this->members_.m_finish.m_first) {
|
||||
--this->members_.m_finish.m_cur;
|
||||
allocator_traits_type::destroy
|
||||
@@ -1607,6 +1647,7 @@ class deque : protected deque_base<Allocator>
|
||||
//! Constant if pos is the first or the last element.
|
||||
iterator erase(const_iterator pos) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range(pos));
|
||||
iterator next = pos.unconst();
|
||||
++next;
|
||||
size_type index = pos - this->members_.m_start;
|
||||
@@ -1631,6 +1672,9 @@ class deque : protected deque_base<Allocator>
|
||||
//! if(pos is near the beginning).
|
||||
iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT(first <= last);
|
||||
BOOST_ASSERT(first == last || this->priv_in_range(first));
|
||||
BOOST_ASSERT(first == last || this->priv_in_range_or_end(last));
|
||||
if (first == this->members_.m_start && last == this->members_.m_finish) {
|
||||
this->clear();
|
||||
return this->members_.m_finish;
|
||||
@@ -1764,12 +1808,26 @@ class deque : protected deque_base<Allocator>
|
||||
}
|
||||
}
|
||||
|
||||
void priv_range_check(size_type n) const
|
||||
{ if (n >= this->size()) throw_out_of_range("deque::at out of range"); }
|
||||
void priv_throw_if_out_of_range(size_type n) const
|
||||
{
|
||||
if (n >= this->size())
|
||||
throw_out_of_range("deque::at out of range");
|
||||
}
|
||||
|
||||
bool priv_in_range(const_iterator pos) const
|
||||
{
|
||||
return (this->begin() <= pos) && (pos < this->end());
|
||||
}
|
||||
|
||||
bool priv_in_range_or_end(const_iterator pos) const
|
||||
{
|
||||
return (this->begin() <= pos) && (pos <= this->end());
|
||||
}
|
||||
|
||||
template <class U>
|
||||
iterator priv_insert(const_iterator p, BOOST_FWD_REF(U) x)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(p));
|
||||
if (p == cbegin()){
|
||||
this->push_front(::boost::forward<U>(x));
|
||||
return begin();
|
||||
|
@@ -1,6 +1,6 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2015. 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)
|
||||
//
|
||||
@@ -376,35 +376,39 @@ class flat_tree
|
||||
return i;
|
||||
}
|
||||
|
||||
iterator insert_unique(const_iterator pos, const value_type& val)
|
||||
iterator insert_unique(const_iterator hint, const value_type& val)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(hint));
|
||||
std::pair<iterator,bool> ret;
|
||||
insert_commit_data data;
|
||||
return this->priv_insert_unique_prepare(pos, val, data)
|
||||
return this->priv_insert_unique_prepare(hint, val, data)
|
||||
? this->priv_insert_commit(data, val)
|
||||
: iterator(vector_iterator_get_ptr(data.position));
|
||||
}
|
||||
|
||||
iterator insert_unique(const_iterator pos, BOOST_RV_REF(value_type) val)
|
||||
iterator insert_unique(const_iterator hint, BOOST_RV_REF(value_type) val)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(hint));
|
||||
std::pair<iterator,bool> ret;
|
||||
insert_commit_data data;
|
||||
return this->priv_insert_unique_prepare(pos, val, data)
|
||||
return this->priv_insert_unique_prepare(hint, val, data)
|
||||
? this->priv_insert_commit(data, boost::move(val))
|
||||
: iterator(vector_iterator_get_ptr(data.position));
|
||||
}
|
||||
|
||||
iterator insert_equal(const_iterator pos, const value_type& val)
|
||||
iterator insert_equal(const_iterator hint, const value_type& val)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(hint));
|
||||
insert_commit_data data;
|
||||
this->priv_insert_equal_prepare(pos, val, data);
|
||||
this->priv_insert_equal_prepare(hint, val, data);
|
||||
return this->priv_insert_commit(data, val);
|
||||
}
|
||||
|
||||
iterator insert_equal(const_iterator pos, BOOST_RV_REF(value_type) mval)
|
||||
iterator insert_equal(const_iterator hint, BOOST_RV_REF(value_type) mval)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(hint));
|
||||
insert_commit_data data;
|
||||
this->priv_insert_equal_prepare(pos, mval, data);
|
||||
this->priv_insert_equal_prepare(hint, mval, data);
|
||||
return this->priv_insert_commit(data, boost::move(mval));
|
||||
}
|
||||
|
||||
@@ -524,6 +528,7 @@ class flat_tree
|
||||
template <class... Args>
|
||||
iterator emplace_hint_unique(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
//hint checked in insert_unique
|
||||
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
|
||||
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
|
||||
stored_allocator_type &a = this->get_stored_allocator();
|
||||
@@ -546,6 +551,7 @@ class flat_tree
|
||||
template <class... Args>
|
||||
iterator emplace_hint_equal(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
//hint checked in insert_equal
|
||||
typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
|
||||
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
|
||||
stored_allocator_type &a = this->get_stored_allocator();
|
||||
@@ -732,6 +738,12 @@ class flat_tree
|
||||
{ x.swap(y); }
|
||||
|
||||
private:
|
||||
|
||||
bool priv_in_range_or_end(const_iterator pos) const
|
||||
{
|
||||
return (this->begin() <= pos) && (pos <= this->end());
|
||||
}
|
||||
|
||||
struct insert_commit_data
|
||||
{
|
||||
const_iterator position;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2015. 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)
|
||||
//
|
||||
@@ -811,6 +811,7 @@ class tree
|
||||
std::pair<iterator,bool> insert_unique_check
|
||||
(const_iterator hint, const key_type& key, insert_commit_data &data)
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(hint));
|
||||
std::pair<iiterator, bool> ret =
|
||||
this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(value_comp()), data);
|
||||
return std::pair<iterator, bool>(iterator(ret.first), ret.second);
|
||||
@@ -861,6 +862,15 @@ class tree
|
||||
|
||||
private:
|
||||
|
||||
bool priv_is_linked(const_iterator const position) const
|
||||
{
|
||||
iiterator const cur(position.get());
|
||||
return cur == this->icont().end() ||
|
||||
cur == this->icont().root() ||
|
||||
iiterator(cur).go_parent().go_left() == cur ||
|
||||
iiterator(cur).go_parent().go_right() == cur;
|
||||
}
|
||||
|
||||
template<class MovableConvertible>
|
||||
void push_back_impl(BOOST_FWD_REF(MovableConvertible) v)
|
||||
{
|
||||
@@ -888,6 +898,7 @@ class tree
|
||||
|
||||
iterator emplace_unique_hint_impl(const_iterator hint, NodePtr p)
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(hint));
|
||||
value_type &v = p->get_data();
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret =
|
||||
@@ -924,6 +935,7 @@ class tree
|
||||
template <class... Args>
|
||||
iterator emplace_hint_equal(const_iterator hint, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(hint));
|
||||
NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
|
||||
@@ -955,6 +967,7 @@ class tree
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
iterator emplace_hint_equal(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
BOOST_ASSERT((priv_is_linked)(hint));\
|
||||
NodePtr tmp(AllocHolder::create_node(BOOST_MOVE_FWD##N));\
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());\
|
||||
iterator ret(this->icont().insert_equal(hint.get(), *tmp));\
|
||||
@@ -969,6 +982,7 @@ class tree
|
||||
|
||||
iterator insert_unique(const_iterator hint, const value_type& v)
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(hint));
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret =
|
||||
this->insert_unique_check(hint, KeyOfValue()(v), data);
|
||||
@@ -980,6 +994,7 @@ class tree
|
||||
template<class MovableConvertible>
|
||||
iterator insert_unique(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v)
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(hint));
|
||||
insert_commit_data data;
|
||||
std::pair<iterator,bool> ret =
|
||||
this->insert_unique_check(hint, KeyOfValue()(v), data);
|
||||
@@ -1016,6 +1031,7 @@ class tree
|
||||
|
||||
iterator insert_equal(const_iterator hint, const value_type& v)
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(hint));
|
||||
NodePtr tmp(AllocHolder::create_node(v));
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
|
||||
@@ -1026,6 +1042,7 @@ class tree
|
||||
template<class MovableConvertible>
|
||||
iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v)
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(hint));
|
||||
NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(v)));
|
||||
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
|
||||
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
|
||||
@@ -1041,13 +1058,20 @@ class tree
|
||||
}
|
||||
|
||||
iterator erase(const_iterator position)
|
||||
{ return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc()))); }
|
||||
{
|
||||
BOOST_ASSERT(position != this->cend() && (priv_is_linked)(position));
|
||||
return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc())));
|
||||
}
|
||||
|
||||
size_type erase(const key_type& k)
|
||||
{ return AllocHolder::erase_key(k, KeyNodeCompare(value_comp()), alloc_version()); }
|
||||
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
{ return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
|
||||
{
|
||||
BOOST_ASSERT(first == last || (first != this->cend() && (priv_is_linked)(first)));
|
||||
BOOST_ASSERT(first == last || (priv_is_linked)(last));
|
||||
return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version()));
|
||||
}
|
||||
|
||||
void clear()
|
||||
{ AllocHolder::clear(alloc_version()); }
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2015. 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)
|
||||
//
|
||||
@@ -651,7 +651,10 @@ class list
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
reference front() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return *this->begin(); }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return *this->begin();
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: !empty()
|
||||
//!
|
||||
@@ -662,7 +665,10 @@ class list
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return *this->begin(); }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return *this->begin();
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: !empty()
|
||||
//!
|
||||
@@ -673,7 +679,10 @@ class list
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
reference back() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return *(--this->end()); }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return *(--this->end());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: !empty()
|
||||
//!
|
||||
@@ -684,7 +693,10 @@ class list
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return *(--this->end()); }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return *(--this->end());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
//
|
||||
@@ -724,10 +736,11 @@ class list
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant
|
||||
template <class... Args>
|
||||
iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
|
||||
iterator emplace(const_iterator position, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(position));
|
||||
NodePtr pnode(AllocHolder::create_node(boost::forward<Args>(args)...));
|
||||
return iterator(this->icont().insert(p.get(), *pnode));
|
||||
return iterator(this->icont().insert(position.get(), *pnode));
|
||||
}
|
||||
|
||||
#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
@@ -742,10 +755,11 @@ class list
|
||||
{ this->emplace(this->cbegin() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);}\
|
||||
\
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
iterator emplace(const_iterator position BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
BOOST_ASSERT(position == this->cend() || (--(++position) == position) );\
|
||||
NodePtr pnode (AllocHolder::create_node(BOOST_MOVE_FWD##N));\
|
||||
return iterator(this->icont().insert(p.get(), *pnode));\
|
||||
return iterator(this->icont().insert(position.get(), *pnode));\
|
||||
}\
|
||||
//
|
||||
BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_LIST_EMPLACE_CODE)
|
||||
@@ -828,10 +842,11 @@ class list
|
||||
//! <b>Throws</b>: If memory allocation throws or T's copy constructor throws.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to n.
|
||||
iterator insert(const_iterator p, size_type n, const T& x)
|
||||
iterator insert(const_iterator position, size_type n, const T& x)
|
||||
{
|
||||
//range check is done by insert
|
||||
typedef constant_iterator<value_type, difference_type> cvalue_iterator;
|
||||
return this->insert(p, cvalue_iterator(x, n), cvalue_iterator());
|
||||
return this->insert(position, cvalue_iterator(x, n), cvalue_iterator());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: p must be a valid iterator of *this.
|
||||
@@ -856,6 +871,7 @@ class list
|
||||
#endif
|
||||
)
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(p));
|
||||
const typename Icont::iterator ipos(p.get());
|
||||
iterator ret_it(ipos);
|
||||
if(first != last){
|
||||
@@ -870,7 +886,7 @@ class list
|
||||
|
||||
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
|
||||
template <class FwdIt>
|
||||
iterator insert(const_iterator p, FwdIt first, FwdIt last
|
||||
iterator insert(const_iterator position, FwdIt first, FwdIt last
|
||||
, typename container_detail::enable_if_c
|
||||
< !container_detail::is_convertible<FwdIt, size_type>::value
|
||||
&& !(container_detail::is_input_iterator<FwdIt>::value
|
||||
@@ -879,9 +895,10 @@ class list
|
||||
>::type * = 0
|
||||
)
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(position));
|
||||
//Optimized allocation and construction
|
||||
insertion_functor func(this->icont(), p.get());
|
||||
iterator before_p(p.get());
|
||||
insertion_functor func(this->icont(), position.get());
|
||||
iterator before_p(position.get());
|
||||
--before_p;
|
||||
this->allocate_many_and_construct(first, boost::container::iterator_distance(first, last), func);
|
||||
return ++before_p;
|
||||
@@ -900,7 +917,10 @@ class list
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
|
||||
iterator insert(const_iterator p, std::initializer_list<value_type> il)
|
||||
{ return insert(p, il.begin(), il.end()); }
|
||||
{
|
||||
//position range check is done by insert()
|
||||
return insert(p, il.begin(), il.end());
|
||||
}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Removes the first element from the list.
|
||||
@@ -909,7 +929,10 @@ class list
|
||||
//!
|
||||
//! <b>Complexity</b>: Amortized constant time.
|
||||
void pop_front() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ this->erase(this->cbegin()); }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
this->erase(this->cbegin());
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Removes the last element from the list.
|
||||
//!
|
||||
@@ -917,7 +940,11 @@ class list
|
||||
//!
|
||||
//! <b>Complexity</b>: Amortized constant time.
|
||||
void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ const_iterator tmp = this->cend(); this->erase(--tmp); }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
const_iterator tmp = this->cend();
|
||||
this->erase(--tmp);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: p must be a valid iterator of *this.
|
||||
//!
|
||||
@@ -927,7 +954,10 @@ class list
|
||||
//!
|
||||
//! <b>Complexity</b>: Amortized constant time.
|
||||
iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc()))); }
|
||||
{
|
||||
BOOST_ASSERT(p != this->cend() && (priv_is_linked)(p));
|
||||
return iterator(this->icont().erase_and_dispose(p.get(), Destroyer(this->node_alloc())));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: first and last must be valid iterator to elements in *this.
|
||||
//!
|
||||
@@ -937,7 +967,11 @@ class list
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the distance between first and last.
|
||||
iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version())); }
|
||||
{
|
||||
BOOST_ASSERT(first == last || (first != this->cend() && (priv_is_linked)(first)));
|
||||
BOOST_ASSERT(first == last || (priv_is_linked)(last));
|
||||
return iterator(AllocHolder::erase_range(first.get(), last.get(), alloc_version()));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Swaps the contents of *this and x.
|
||||
//!
|
||||
@@ -947,7 +981,12 @@ class list
|
||||
void swap(list& x)
|
||||
BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value
|
||||
|| allocator_traits_type::is_always_equal::value)
|
||||
{ AllocHolder::swap(x); }
|
||||
{
|
||||
BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value ||
|
||||
allocator_traits_type::is_always_equal::value ||
|
||||
this->get_stored_allocator() == x.get_stored_allocator());
|
||||
AllocHolder::swap(x);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Erases all the elements of the list.
|
||||
//!
|
||||
@@ -977,6 +1016,7 @@ class list
|
||||
//! this list. Iterators of this list and all the references are not invalidated.
|
||||
void splice(const_iterator p, list& x) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(p));
|
||||
BOOST_ASSERT(this != &x);
|
||||
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
|
||||
this->icont().splice(p.get(), x.icont());
|
||||
@@ -995,7 +1035,10 @@ class list
|
||||
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of
|
||||
//! this list. Iterators of this list and all the references are not invalidated.
|
||||
void splice(const_iterator p, BOOST_RV_REF(list) x) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ this->splice(p, static_cast<list&>(x)); }
|
||||
{
|
||||
//Checks done in splice
|
||||
this->splice(p, static_cast<list&>(x));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: p must point to an element contained
|
||||
//! by this list. i must point to an element contained in list x.
|
||||
@@ -1013,7 +1056,7 @@ class list
|
||||
//! list. Iterators of this list and all the references are not invalidated.
|
||||
void splice(const_iterator p, list &x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
//BOOST_ASSERT(this != &x);
|
||||
BOOST_ASSERT((priv_is_linked)(p));
|
||||
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
|
||||
this->icont().splice(p.get(), x.icont(), i.get());
|
||||
}
|
||||
@@ -1033,7 +1076,11 @@ class list
|
||||
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
|
||||
//! list. Iterators of this list and all the references are not invalidated.
|
||||
void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator i) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ this->splice(p, static_cast<list&>(x), i); }
|
||||
{
|
||||
BOOST_ASSERT(this != &x);
|
||||
//Additional checks done in splice()
|
||||
this->splice(p, static_cast<list&>(x), i);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: p must point to an element contained
|
||||
//! by this list. first and last must point to elements contained in list x.
|
||||
@@ -1050,6 +1097,9 @@ class list
|
||||
//! list. Iterators of this list and all the references are not invalidated.
|
||||
void splice(const_iterator p, list &x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(p));
|
||||
BOOST_ASSERT(first == last || (first != x.cend() && x.priv_is_linked(first)));
|
||||
BOOST_ASSERT(first == last || x.priv_is_linked(last));
|
||||
BOOST_ASSERT(this->node_alloc() == x.node_alloc());
|
||||
this->icont().splice(p.get(), x.icont(), first.get(), last.get());
|
||||
}
|
||||
@@ -1068,7 +1118,11 @@ class list
|
||||
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
|
||||
//! list. Iterators of this list and all the references are not invalidated.
|
||||
void splice(const_iterator p, BOOST_RV_REF(list) x, const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ this->splice(p, static_cast<list&>(x), first, last); }
|
||||
{
|
||||
BOOST_ASSERT(this != &x);
|
||||
//Additional checks done in splice()
|
||||
this->splice(p, static_cast<list&>(x), first, last);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: p must point to an element contained
|
||||
//! by this list. first and last must point to elements contained in list x.
|
||||
@@ -1318,6 +1372,13 @@ class list
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
|
||||
static bool priv_is_linked(const_iterator const position)
|
||||
{
|
||||
const_iterator cur(position);
|
||||
//This list is circular including end nodes
|
||||
return (--(++cur)) == position && (++(--cur)) == position;
|
||||
}
|
||||
|
||||
bool priv_try_shrink(size_type new_size)
|
||||
{
|
||||
const size_type len = this->size();
|
||||
@@ -1348,12 +1409,14 @@ class list
|
||||
|
||||
iterator priv_insert(const_iterator p, const T &x)
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(p));
|
||||
NodePtr tmp = AllocHolder::create_node(x);
|
||||
return iterator(this->icont().insert(p.get(), *tmp));
|
||||
}
|
||||
|
||||
iterator priv_insert(const_iterator p, BOOST_RV_REF(T) x)
|
||||
{
|
||||
BOOST_ASSERT((priv_is_linked)(p));
|
||||
NodePtr tmp = AllocHolder::create_node(boost::move(x));
|
||||
return iterator(this->icont().insert(p.get(), *tmp));
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2004-2015. 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)
|
||||
//
|
||||
@@ -684,7 +684,10 @@ class slist
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
reference front()
|
||||
{ return *this->begin(); }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return *this->begin();
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: !empty()
|
||||
//!
|
||||
@@ -695,7 +698,10 @@ class slist
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reference front() const
|
||||
{ return *this->begin(); }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return *this->begin();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
//
|
||||
@@ -897,7 +903,10 @@ class slist
|
||||
//!
|
||||
//! <b>Complexity</b>: Amortized constant time.
|
||||
void pop_front()
|
||||
{ this->icont().pop_front_and_dispose(Destroyer(this->node_alloc())); }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
this->icont().pop_front_and_dispose(Destroyer(this->node_alloc()));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Erases the element after the element pointed by prev_p
|
||||
//! of the list.
|
||||
@@ -939,7 +948,12 @@ class slist
|
||||
void swap(slist& x)
|
||||
BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value
|
||||
|| allocator_traits_type::is_always_equal::value)
|
||||
{ AllocHolder::swap(x); }
|
||||
{
|
||||
BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value ||
|
||||
allocator_traits_type::is_always_equal::value ||
|
||||
this->get_stored_allocator() == x.get_stored_allocator());
|
||||
AllocHolder::swap(x);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Erases all the elements of the list.
|
||||
//!
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2015. 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)
|
||||
//
|
||||
@@ -1196,7 +1196,10 @@ class stable_vector
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
reference front() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return static_cast<node_reference>(*this->index.front()).value; }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return static_cast<node_reference>(*this->index.front()).value;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: !empty()
|
||||
//!
|
||||
@@ -1207,7 +1210,10 @@ class stable_vector
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return static_cast<const_node_reference>(*this->index.front()).value; }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return static_cast<const_node_reference>(*this->index.front()).value;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: !empty()
|
||||
//!
|
||||
@@ -1218,7 +1224,10 @@ class stable_vector
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
reference back() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return static_cast<node_reference>(*this->index[this->size()-1u]).value; }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return static_cast<node_reference>(*this->index[this->size()-1u]).value;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: !empty()
|
||||
//!
|
||||
@@ -1229,7 +1238,10 @@ class stable_vector
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return static_cast<const_node_reference>(*this->index[this->size()-1u]).value; }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return static_cast<const_node_reference>(*this->index[this->size()-1u]).value;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: size() > n.
|
||||
//!
|
||||
@@ -1241,7 +1253,7 @@ class stable_vector
|
||||
//! <b>Complexity</b>: Constant.
|
||||
reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT(n < this->size());
|
||||
BOOST_ASSERT(this->size() > n);
|
||||
return static_cast<node_reference>(*this->index[n]).value;
|
||||
}
|
||||
|
||||
@@ -1255,7 +1267,7 @@ class stable_vector
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT(n < this->size());
|
||||
BOOST_ASSERT(this->size() > n);
|
||||
return static_cast<const_node_reference>(*this->index[n]).value;
|
||||
}
|
||||
|
||||
@@ -1386,6 +1398,7 @@ class stable_vector
|
||||
template<class ...Args>
|
||||
iterator emplace(const_iterator p, Args && ...args)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(p));
|
||||
size_type pos_n = p - cbegin();
|
||||
typedef emplace_functor<Args...> EmplaceFunctor;
|
||||
typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;
|
||||
@@ -1410,6 +1423,7 @@ class stable_vector
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(p));\
|
||||
typedef emplace_functor##N\
|
||||
BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N EmplaceFunctor;\
|
||||
typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;\
|
||||
@@ -1483,6 +1497,7 @@ class stable_vector
|
||||
//! <b>Complexity</b>: Linear to n.
|
||||
iterator insert(const_iterator p, size_type n, const T& t)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(p));
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
typedef constant_iterator<value_type, difference_type> cvalue_iterator;
|
||||
return this->insert(p, cvalue_iterator(t, n), cvalue_iterator());
|
||||
@@ -1499,6 +1514,7 @@ class stable_vector
|
||||
//! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
|
||||
iterator insert(const_iterator p, std::initializer_list<value_type> il)
|
||||
{
|
||||
//Position checks done by insert()
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
return insert(p, il.begin(), il.end());
|
||||
}
|
||||
@@ -1526,6 +1542,7 @@ class stable_vector
|
||||
#endif
|
||||
insert(const_iterator p, InputIterator first, InputIterator last)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(p));
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
const size_type pos_n = p - this->cbegin();
|
||||
for(; first != last; ++first){
|
||||
@@ -1543,6 +1560,7 @@ class stable_vector
|
||||
>::type
|
||||
insert(const_iterator p, FwdIt first, FwdIt last)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(p));
|
||||
const size_type num_new = static_cast<size_type>(boost::container::iterator_distance(first, last));
|
||||
const size_type idx = static_cast<size_type>(p - this->cbegin());
|
||||
if(num_new){
|
||||
@@ -1581,7 +1599,10 @@ class stable_vector
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant time.
|
||||
void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ this->erase(--this->cend()); }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
this->erase(--this->cend());
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Erases the element at p.
|
||||
//!
|
||||
@@ -1591,6 +1612,7 @@ class stable_vector
|
||||
//! last element. Constant if p is the last element.
|
||||
iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range(p));
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
const size_type d = p - this->cbegin();
|
||||
index_iterator it = this->index.begin() + d;
|
||||
@@ -1608,6 +1630,9 @@ class stable_vector
|
||||
//! plus linear to the elements between p and the last element.
|
||||
iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT(first <= last);
|
||||
BOOST_ASSERT(first == last || this->priv_in_range(first));
|
||||
BOOST_ASSERT(first == last || this->priv_in_range_or_end(last));
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
const const_iterator cbeg(this->cbegin());
|
||||
const size_type d1 = static_cast<size_type>(first - cbeg),
|
||||
@@ -1641,6 +1666,9 @@ class stable_vector
|
||||
BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value
|
||||
|| allocator_traits_type::is_always_equal::value)
|
||||
{
|
||||
BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value ||
|
||||
allocator_traits_type::is_always_equal::value ||
|
||||
this->get_stored_allocator() == x.get_stored_allocator());
|
||||
STABLE_VECTOR_CHECK_INVARIANT;
|
||||
container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag;
|
||||
container_detail::swap_alloc(this->priv_node_alloc(), x.priv_node_alloc(), flag);
|
||||
@@ -1702,6 +1730,16 @@ class stable_vector
|
||||
#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
|
||||
private:
|
||||
|
||||
bool priv_in_range(const_iterator pos) const
|
||||
{
|
||||
return (this->begin() <= pos) && (pos < this->end());
|
||||
}
|
||||
|
||||
bool priv_in_range_or_end(const_iterator pos) const
|
||||
{
|
||||
return (this->begin() <= pos) && (pos <= this->end());
|
||||
}
|
||||
|
||||
size_type priv_index_of(node_ptr p) const
|
||||
{
|
||||
//Check range
|
||||
@@ -1807,12 +1845,14 @@ class stable_vector
|
||||
|
||||
iterator priv_insert(const_iterator p, const value_type &t)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(p));
|
||||
typedef constant_iterator<value_type, difference_type> cvalue_iterator;
|
||||
return this->insert(p, cvalue_iterator(t, 1), cvalue_iterator());
|
||||
}
|
||||
|
||||
iterator priv_insert(const_iterator p, BOOST_RV_REF(T) x)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(p));
|
||||
typedef repeat_iterator<T, difference_type> repeat_it;
|
||||
typedef boost::move_iterator<repeat_it> repeat_move_it;
|
||||
//Just call more general insert(p, size, value) and return iterator
|
||||
|
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2014. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2015. 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)
|
||||
//
|
||||
@@ -1097,6 +1097,7 @@ class vector
|
||||
BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
|
||||
|| allocator_traits_type::is_always_equal::value)
|
||||
{
|
||||
BOOST_ASSERT(&x != this);
|
||||
this->priv_move_assign(boost::move(x));
|
||||
return *this;
|
||||
}
|
||||
@@ -1512,7 +1513,10 @@ class vector
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
reference front() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return *this->m_holder.start(); }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return *this->m_holder.start();
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: !empty()
|
||||
//!
|
||||
@@ -1523,7 +1527,10 @@ class vector
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return *this->m_holder.start(); }
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return *this->m_holder.start();
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: !empty()
|
||||
//!
|
||||
@@ -1535,7 +1542,7 @@ class vector
|
||||
//! <b>Complexity</b>: Constant.
|
||||
reference back() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT(this->m_holder.m_size > 0);
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return this->m_holder.start()[this->m_holder.m_size - 1];
|
||||
}
|
||||
|
||||
@@ -1549,7 +1556,7 @@ class vector
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT(this->m_holder.m_size > 0);
|
||||
BOOST_ASSERT(!this->empty());
|
||||
return this->m_holder.start()[this->m_holder.m_size - 1];
|
||||
}
|
||||
|
||||
@@ -1577,7 +1584,8 @@ class vector
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
return this->m_holder.start()[n];
|
||||
BOOST_ASSERT(this->m_holder.m_size > n);
|
||||
return this->m_holder.start()[n];
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: size() >= n.
|
||||
@@ -1626,7 +1634,10 @@ class vector
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension
|
||||
size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->priv_index_of(vector_iterator_get_ptr(p)); }
|
||||
{
|
||||
//Range check assert done in priv_index_of
|
||||
return this->priv_index_of(vector_iterator_get_ptr(p));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: begin() <= p <= end().
|
||||
//!
|
||||
@@ -1639,7 +1650,10 @@ class vector
|
||||
//!
|
||||
//! <b>Note</b>: Non-standard extension
|
||||
size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{ return this->priv_index_of(vector_iterator_get_ptr(p)); }
|
||||
{
|
||||
//Range check assert done in priv_index_of
|
||||
return this->priv_index_of(vector_iterator_get_ptr(p));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: size() > n.
|
||||
//!
|
||||
@@ -1650,7 +1664,10 @@ class vector
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
reference at(size_type n)
|
||||
{ this->priv_check_range(n); return this->m_holder.start()[n]; }
|
||||
{
|
||||
this->priv_throw_if_out_of_range(n);
|
||||
return this->m_holder.start()[n];
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: size() > n.
|
||||
//!
|
||||
@@ -1661,7 +1678,10 @@ class vector
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reference at(size_type n) const
|
||||
{ this->priv_check_range(n); return this->m_holder.start()[n]; }
|
||||
{
|
||||
this->priv_throw_if_out_of_range(n);
|
||||
return this->m_holder.start()[n];
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
//
|
||||
@@ -1749,6 +1769,7 @@ class vector
|
||||
template<class ...Args>
|
||||
iterator emplace(const_iterator position, BOOST_FWD_REF(Args) ...args)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(position));
|
||||
//Just call more general insert(pos, size, value) and return iterator
|
||||
typedef container_detail::insert_emplace_proxy<Allocator, T*, Args...> type;
|
||||
return this->priv_forward_range_insert( vector_iterator_get_ptr(position), 1
|
||||
@@ -1788,6 +1809,7 @@ class vector
|
||||
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
|
||||
iterator emplace(const_iterator pos BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
|
||||
{\
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(pos));\
|
||||
typedef container_detail::insert_emplace_proxy_arg##N<Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_TARG##N> type;\
|
||||
return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), 1, type(BOOST_MOVE_FWD##N));\
|
||||
}\
|
||||
@@ -1853,6 +1875,7 @@ class vector
|
||||
//! <b>Complexity</b>: Linear to n.
|
||||
iterator insert(const_iterator p, size_type n, const T& x)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(p));
|
||||
container_detail::insert_n_copies_proxy<Allocator, T*> proxy(x);
|
||||
return this->priv_forward_range_insert(vector_iterator_get_ptr(p), n, proxy);
|
||||
}
|
||||
@@ -1878,6 +1901,7 @@ class vector
|
||||
#endif
|
||||
)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(pos));
|
||||
const size_type n_pos = pos - this->cbegin();
|
||||
iterator it(vector_iterator_get_ptr(pos));
|
||||
for(;first != last; ++first){
|
||||
@@ -1897,6 +1921,7 @@ class vector
|
||||
>::type * = 0
|
||||
)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(pos));
|
||||
container_detail::insert_range_proxy<Allocator, FwdIt, T*> proxy(first);
|
||||
return this->priv_forward_range_insert(vector_iterator_get_ptr(pos), boost::container::iterator_distance(first, last), proxy);
|
||||
}
|
||||
@@ -1921,6 +1946,7 @@ class vector
|
||||
template <class InIt>
|
||||
iterator insert(const_iterator pos, size_type num, InIt first, InIt last)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(pos));
|
||||
BOOST_ASSERT(container_detail::is_input_iterator<InIt>::value ||
|
||||
num == static_cast<size_type>(boost::container::iterator_distance(first, last)));
|
||||
(void)last;
|
||||
@@ -1939,17 +1965,19 @@ class vector
|
||||
//! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
|
||||
iterator insert(const_iterator position, std::initializer_list<value_type> il)
|
||||
{
|
||||
//Assertion done in insert()
|
||||
return this->insert(position, il.begin(), il.end());
|
||||
}
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Removes the last element from the vector.
|
||||
//! <b>Effects</b>: Removes the last element from the container.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant time.
|
||||
void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
|
||||
{
|
||||
BOOST_ASSERT(!this->empty());
|
||||
//Destroy last element
|
||||
this->priv_destroy_last();
|
||||
}
|
||||
@@ -1962,6 +1990,7 @@ class vector
|
||||
//! last element. Constant if pos is the last element.
|
||||
iterator erase(const_iterator position)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range(position));
|
||||
const pointer p = vector_iterator_get_ptr(position);
|
||||
T *const pos_ptr = container_detail::to_raw_pointer(p);
|
||||
T *const beg_ptr = container_detail::to_raw_pointer(this->m_holder.start());
|
||||
@@ -1979,6 +2008,9 @@ class vector
|
||||
//! plus linear to the elements between pos and the last element.
|
||||
iterator erase(const_iterator first, const_iterator last)
|
||||
{
|
||||
BOOST_ASSERT(first <= last);
|
||||
BOOST_ASSERT(first == last || this->priv_in_range(first));
|
||||
BOOST_ASSERT(first == last || this->priv_in_range_or_end(last));
|
||||
if (first != last){
|
||||
T* const old_end_ptr = this->back_raw();
|
||||
T* const first_ptr = container_detail::to_raw_pointer(vector_iterator_get_ptr(first));
|
||||
@@ -2571,6 +2603,7 @@ class vector
|
||||
template<class U>
|
||||
iterator priv_insert(const const_iterator &p, BOOST_FWD_REF(U) x)
|
||||
{
|
||||
BOOST_ASSERT(this->priv_in_range_or_end(p));
|
||||
return this->priv_forward_range_insert
|
||||
( vector_iterator_get_ptr(p), 1, container_detail::get_insert_value_proxy<T*, Allocator>(::boost::forward<U>(x)));
|
||||
}
|
||||
@@ -3292,7 +3325,7 @@ class vector
|
||||
}
|
||||
}
|
||||
|
||||
void priv_check_range(size_type n) const
|
||||
void priv_throw_if_out_of_range(size_type n) const
|
||||
{
|
||||
//If n is out of range, throw an out_of_range exception
|
||||
if (n >= this->size()){
|
||||
@@ -3300,6 +3333,16 @@ class vector
|
||||
}
|
||||
}
|
||||
|
||||
bool priv_in_range(const_iterator pos) const
|
||||
{
|
||||
return (this->begin() <= pos) && (pos < this->end());
|
||||
}
|
||||
|
||||
bool priv_in_range_or_end(const_iterator pos) const
|
||||
{
|
||||
return (this->begin() <= pos) && (pos <= this->end());
|
||||
}
|
||||
|
||||
#ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
|
||||
public:
|
||||
unsigned int num_expand_fwd;
|
||||
|
Reference in New Issue
Block a user