Added debug assertions via BOOST_ASSERT to check preconditions in several members. All checks are O(1)

This commit is contained in:
Ion Gaztañaga
2015-09-18 14:39:17 +02:00
parent 3f4a5dec6e
commit 85b2ed509b
8 changed files with 331 additions and 75 deletions

View File

@@ -1216,6 +1216,8 @@ use [*Boost.Container]? There are several reasons for that:
[section:release_notes_boost_1_60_00 Boost 1.60 Release] [section:release_notes_boost_1_60_00 Boost 1.60 Release]
* Implemented [link container.extended_functionality.polymorphic_memory_resources Polymorphic Memory Resources]. * 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: * 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/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"]]. * [@https://svn.boost.org/trac/boost/ticket/11628 Trac #11628: ['"small_vector<int,n> iterates over elements in destructor"]].

View File

@@ -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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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. //! <b>Complexity</b>: Constant.
reference front() BOOST_NOEXCEPT_OR_NOTHROW reference front() BOOST_NOEXCEPT_OR_NOTHROW
{ return *this->members_.m_start; } {
BOOST_ASSERT(!this->empty());
return *this->members_.m_start;
}
//! <b>Requires</b>: !empty() //! <b>Requires</b>: !empty()
//! //!
@@ -1151,7 +1154,10 @@ class deque : protected deque_base<Allocator>
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW 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() //! <b>Requires</b>: !empty()
//! //!
@@ -1162,7 +1168,10 @@ class deque : protected deque_base<Allocator>
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
reference back() BOOST_NOEXCEPT_OR_NOTHROW reference back() BOOST_NOEXCEPT_OR_NOTHROW
{ return *(end()-1); } {
BOOST_ASSERT(!this->empty());
return *(end()-1);
}
//! <b>Requires</b>: !empty() //! <b>Requires</b>: !empty()
//! //!
@@ -1173,7 +1182,10 @@ class deque : protected deque_base<Allocator>
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW
{ return *(cend()-1); } {
BOOST_ASSERT(!this->empty());
return *(cend()-1);
}
//! <b>Requires</b>: size() > n. //! <b>Requires</b>: size() > n.
//! //!
@@ -1184,7 +1196,10 @@ class deque : protected deque_base<Allocator>
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW 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. //! <b>Requires</b>: size() > n.
//! //!
@@ -1195,7 +1210,10 @@ class deque : protected deque_base<Allocator>
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW 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. //! <b>Requires</b>: size() >= n.
//! //!
@@ -1243,7 +1261,10 @@ class deque : protected deque_base<Allocator>
//! //!
//! <b>Note</b>: Non-standard extension //! <b>Note</b>: Non-standard extension
size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW 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(). //! <b>Requires</b>: begin() <= p <= end().
//! //!
@@ -1256,7 +1277,10 @@ class deque : protected deque_base<Allocator>
//! //!
//! <b>Note</b>: Non-standard extension //! <b>Note</b>: Non-standard extension
size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW 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. //! <b>Requires</b>: size() > n.
//! //!
@@ -1267,7 +1291,10 @@ class deque : protected deque_base<Allocator>
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
reference at(size_type n) 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. //! <b>Requires</b>: size() > n.
//! //!
@@ -1278,7 +1305,10 @@ class deque : protected deque_base<Allocator>
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference at(size_type n) const 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> template <class... Args>
iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args) iterator emplace(const_iterator p, BOOST_FWD_REF(Args)... args)
{ {
BOOST_ASSERT(this->priv_in_range_or_end(p));
if(p == this->cbegin()){ if(p == this->cbegin()){
this->emplace_front(boost::forward<Args>(args)...); this->emplace_front(boost::forward<Args>(args)...);
return this->begin(); 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\ 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 p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\ {\
BOOST_ASSERT(this->priv_in_range_or_end(p));\
if(p == this->cbegin()){\ if(p == this->cbegin()){\
this->emplace_front(BOOST_MOVE_FWD##N);\ this->emplace_front(BOOST_MOVE_FWD##N);\
return this->begin();\ return this->begin();\
@@ -1494,6 +1526,7 @@ class deque : protected deque_base<Allocator>
//! <b>Complexity</b>: Linear to n. //! <b>Complexity</b>: Linear to n.
iterator insert(const_iterator pos, size_type n, const value_type& x) 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; typedef constant_iterator<value_type, difference_type> c_it;
return this->insert(pos, c_it(x, n), c_it()); return this->insert(pos, c_it(x, n), c_it());
} }
@@ -1519,6 +1552,7 @@ class deque : protected deque_base<Allocator>
#endif #endif
) )
{ {
BOOST_ASSERT(this->priv_in_range_or_end(pos));
size_type n = 0; size_type n = 0;
iterator it(pos.unconst()); iterator it(pos.unconst());
for(;first != last; ++first, ++n){ 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()). //! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
iterator insert(const_iterator pos, std::initializer_list<value_type> il) 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 #endif
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
@@ -1556,6 +1593,7 @@ class deque : protected deque_base<Allocator>
#endif #endif
) )
{ {
BOOST_ASSERT(this->priv_in_range_or_end(p));
container_detail::insert_range_proxy<Allocator, FwdIt, iterator> proxy(first); container_detail::insert_range_proxy<Allocator, FwdIt, iterator> proxy(first);
return priv_insert_aux_impl(p, boost::container::iterator_distance(first, last), proxy); 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. //! <b>Complexity</b>: Constant time.
void pop_front() BOOST_NOEXCEPT_OR_NOTHROW 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.m_last - 1) {
allocator_traits_type::destroy allocator_traits_type::destroy
( this->alloc() ( this->alloc()
@@ -1586,6 +1625,7 @@ class deque : protected deque_base<Allocator>
//! <b>Complexity</b>: Constant time. //! <b>Complexity</b>: Constant time.
void pop_back() BOOST_NOEXCEPT_OR_NOTHROW 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.m_first) {
--this->members_.m_finish.m_cur; --this->members_.m_finish.m_cur;
allocator_traits_type::destroy allocator_traits_type::destroy
@@ -1607,6 +1647,7 @@ class deque : protected deque_base<Allocator>
//! Constant if pos is the first or the last element. //! Constant if pos is the first or the last element.
iterator erase(const_iterator pos) BOOST_NOEXCEPT_OR_NOTHROW iterator erase(const_iterator pos) BOOST_NOEXCEPT_OR_NOTHROW
{ {
BOOST_ASSERT(this->priv_in_range(pos));
iterator next = pos.unconst(); iterator next = pos.unconst();
++next; ++next;
size_type index = pos - this->members_.m_start; size_type index = pos - this->members_.m_start;
@@ -1631,6 +1672,9 @@ class deque : protected deque_base<Allocator>
//! if(pos is near the beginning). //! if(pos is near the beginning).
iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW 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) { if (first == this->members_.m_start && last == this->members_.m_finish) {
this->clear(); this->clear();
return this->members_.m_finish; return this->members_.m_finish;
@@ -1764,12 +1808,26 @@ class deque : protected deque_base<Allocator>
} }
} }
void priv_range_check(size_type n) const void priv_throw_if_out_of_range(size_type n) const
{ if (n >= this->size()) throw_out_of_range("deque::at out of range"); } {
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> template <class U>
iterator priv_insert(const_iterator p, BOOST_FWD_REF(U) x) iterator priv_insert(const_iterator p, BOOST_FWD_REF(U) x)
{ {
BOOST_ASSERT(this->priv_in_range_or_end(p));
if (p == cbegin()){ if (p == cbegin()){
this->push_front(::boost::forward<U>(x)); this->push_front(::boost::forward<U>(x));
return begin(); return begin();

View File

@@ -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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// //
@@ -376,35 +376,39 @@ class flat_tree
return i; 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; std::pair<iterator,bool> ret;
insert_commit_data data; 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) ? this->priv_insert_commit(data, val)
: iterator(vector_iterator_get_ptr(data.position)); : 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; std::pair<iterator,bool> ret;
insert_commit_data data; 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)) ? this->priv_insert_commit(data, boost::move(val))
: iterator(vector_iterator_get_ptr(data.position)); : 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; 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); 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; 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)); return this->priv_insert_commit(data, boost::move(mval));
} }
@@ -524,6 +528,7 @@ class flat_tree
template <class... Args> template <class... Args>
iterator emplace_hint_unique(const_iterator hint, BOOST_FWD_REF(Args)... 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; typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_type &a = this->get_stored_allocator();
@@ -546,6 +551,7 @@ class flat_tree
template <class... Args> template <class... Args>
iterator emplace_hint_equal(const_iterator hint, BOOST_FWD_REF(Args)... 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; typename aligned_storage<sizeof(value_type), alignment_of<value_type>::value>::type v;
value_type &val = *static_cast<value_type *>(static_cast<void *>(&v)); value_type &val = *static_cast<value_type *>(static_cast<void *>(&v));
stored_allocator_type &a = this->get_stored_allocator(); stored_allocator_type &a = this->get_stored_allocator();
@@ -732,6 +738,12 @@ class flat_tree
{ x.swap(y); } { x.swap(y); }
private: private:
bool priv_in_range_or_end(const_iterator pos) const
{
return (this->begin() <= pos) && (pos <= this->end());
}
struct insert_commit_data struct insert_commit_data
{ {
const_iterator position; const_iterator position;

View File

@@ -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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 std::pair<iterator,bool> insert_unique_check
(const_iterator hint, const key_type& key, insert_commit_data &data) (const_iterator hint, const key_type& key, insert_commit_data &data)
{ {
BOOST_ASSERT((priv_is_linked)(hint));
std::pair<iiterator, bool> ret = std::pair<iiterator, bool> ret =
this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(value_comp()), data); this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(value_comp()), data);
return std::pair<iterator, bool>(iterator(ret.first), ret.second); return std::pair<iterator, bool>(iterator(ret.first), ret.second);
@@ -861,6 +862,15 @@ class tree
private: 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> template<class MovableConvertible>
void push_back_impl(BOOST_FWD_REF(MovableConvertible) v) 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) iterator emplace_unique_hint_impl(const_iterator hint, NodePtr p)
{ {
BOOST_ASSERT((priv_is_linked)(hint));
value_type &v = p->get_data(); value_type &v = p->get_data();
insert_commit_data data; insert_commit_data data;
std::pair<iterator,bool> ret = std::pair<iterator,bool> ret =
@@ -924,6 +935,7 @@ class tree
template <class... Args> template <class... Args>
iterator emplace_hint_equal(const_iterator hint, BOOST_FWD_REF(Args)... 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)...)); NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(hint.get(), *tmp)); 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 \ 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)\ 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));\ NodePtr tmp(AllocHolder::create_node(BOOST_MOVE_FWD##N));\
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());\ scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());\
iterator ret(this->icont().insert_equal(hint.get(), *tmp));\ 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) iterator insert_unique(const_iterator hint, const value_type& v)
{ {
BOOST_ASSERT((priv_is_linked)(hint));
insert_commit_data data; insert_commit_data data;
std::pair<iterator,bool> ret = std::pair<iterator,bool> ret =
this->insert_unique_check(hint, KeyOfValue()(v), data); this->insert_unique_check(hint, KeyOfValue()(v), data);
@@ -980,6 +994,7 @@ class tree
template<class MovableConvertible> template<class MovableConvertible>
iterator insert_unique(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v) iterator insert_unique(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v)
{ {
BOOST_ASSERT((priv_is_linked)(hint));
insert_commit_data data; insert_commit_data data;
std::pair<iterator,bool> ret = std::pair<iterator,bool> ret =
this->insert_unique_check(hint, KeyOfValue()(v), data); this->insert_unique_check(hint, KeyOfValue()(v), data);
@@ -1016,6 +1031,7 @@ class tree
iterator insert_equal(const_iterator hint, const value_type& v) iterator insert_equal(const_iterator hint, const value_type& v)
{ {
BOOST_ASSERT((priv_is_linked)(hint));
NodePtr tmp(AllocHolder::create_node(v)); NodePtr tmp(AllocHolder::create_node(v));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(hint.get(), *tmp)); iterator ret(this->icont().insert_equal(hint.get(), *tmp));
@@ -1026,6 +1042,7 @@ class tree
template<class MovableConvertible> template<class MovableConvertible>
iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v) 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))); NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(v)));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(hint.get(), *tmp)); iterator ret(this->icont().insert_equal(hint.get(), *tmp));
@@ -1041,13 +1058,20 @@ class tree
} }
iterator erase(const_iterator position) 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) size_type erase(const key_type& k)
{ return AllocHolder::erase_key(k, KeyNodeCompare(value_comp()), alloc_version()); } { return AllocHolder::erase_key(k, KeyNodeCompare(value_comp()), alloc_version()); }
iterator erase(const_iterator first, const_iterator last) 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() void clear()
{ AllocHolder::clear(alloc_version()); } { AllocHolder::clear(alloc_version()); }

View File

@@ -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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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. //! <b>Complexity</b>: Constant.
reference front() BOOST_NOEXCEPT_OR_NOTHROW reference front() BOOST_NOEXCEPT_OR_NOTHROW
{ return *this->begin(); } {
BOOST_ASSERT(!this->empty());
return *this->begin();
}
//! <b>Requires</b>: !empty() //! <b>Requires</b>: !empty()
//! //!
@@ -662,7 +665,10 @@ class list
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW
{ return *this->begin(); } {
BOOST_ASSERT(!this->empty());
return *this->begin();
}
//! <b>Requires</b>: !empty() //! <b>Requires</b>: !empty()
//! //!
@@ -673,7 +679,10 @@ class list
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
reference back() BOOST_NOEXCEPT_OR_NOTHROW reference back() BOOST_NOEXCEPT_OR_NOTHROW
{ return *(--this->end()); } {
BOOST_ASSERT(!this->empty());
return *(--this->end());
}
//! <b>Requires</b>: !empty() //! <b>Requires</b>: !empty()
//! //!
@@ -684,7 +693,10 @@ class list
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW 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 //! <b>Complexity</b>: Constant
template <class... Args> 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)...)); 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) #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);}\ { 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 \ 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));\ 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) 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>Throws</b>: If memory allocation throws or T's copy constructor throws.
//! //!
//! <b>Complexity</b>: Linear to n. //! <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; 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. //! <b>Requires</b>: p must be a valid iterator of *this.
@@ -856,6 +871,7 @@ class list
#endif #endif
) )
{ {
BOOST_ASSERT((priv_is_linked)(p));
const typename Icont::iterator ipos(p.get()); const typename Icont::iterator ipos(p.get());
iterator ret_it(ipos); iterator ret_it(ipos);
if(first != last){ if(first != last){
@@ -870,7 +886,7 @@ class list
#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
template <class FwdIt> 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 , typename container_detail::enable_if_c
< !container_detail::is_convertible<FwdIt, size_type>::value < !container_detail::is_convertible<FwdIt, size_type>::value
&& !(container_detail::is_input_iterator<FwdIt>::value && !(container_detail::is_input_iterator<FwdIt>::value
@@ -879,9 +895,10 @@ class list
>::type * = 0 >::type * = 0
) )
{ {
BOOST_ASSERT((priv_is_linked)(position));
//Optimized allocation and construction //Optimized allocation and construction
insertion_functor func(this->icont(), p.get()); insertion_functor func(this->icont(), position.get());
iterator before_p(p.get()); iterator before_p(position.get());
--before_p; --before_p;
this->allocate_many_and_construct(first, boost::container::iterator_distance(first, last), func); this->allocate_many_and_construct(first, boost::container::iterator_distance(first, last), func);
return ++before_p; return ++before_p;
@@ -900,7 +917,10 @@ class list
//! //!
//! <b>Complexity</b>: Linear to distance [il.begin(), il.end()). //! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
iterator insert(const_iterator p, std::initializer_list<value_type> il) 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 #endif
//! <b>Effects</b>: Removes the first element from the list. //! <b>Effects</b>: Removes the first element from the list.
@@ -909,7 +929,10 @@ class list
//! //!
//! <b>Complexity</b>: Amortized constant time. //! <b>Complexity</b>: Amortized constant time.
void pop_front() BOOST_NOEXCEPT_OR_NOTHROW 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. //! <b>Effects</b>: Removes the last element from the list.
//! //!
@@ -917,7 +940,11 @@ class list
//! //!
//! <b>Complexity</b>: Amortized constant time. //! <b>Complexity</b>: Amortized constant time.
void pop_back() BOOST_NOEXCEPT_OR_NOTHROW 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. //! <b>Requires</b>: p must be a valid iterator of *this.
//! //!
@@ -927,7 +954,10 @@ class list
//! //!
//! <b>Complexity</b>: Amortized constant time. //! <b>Complexity</b>: Amortized constant time.
iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW 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. //! <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. //! <b>Complexity</b>: Linear to the distance between first and last.
iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW 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. //! <b>Effects</b>: Swaps the contents of *this and x.
//! //!
@@ -947,7 +981,12 @@ class list
void swap(list& x) void swap(list& x)
BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_swap::value
|| allocator_traits_type::is_always_equal::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. //! <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. //! this list. Iterators of this list and all the references are not invalidated.
void splice(const_iterator p, list& x) BOOST_NOEXCEPT_OR_NOTHROW void splice(const_iterator p, list& x) BOOST_NOEXCEPT_OR_NOTHROW
{ {
BOOST_ASSERT((priv_is_linked)(p));
BOOST_ASSERT(this != &x); BOOST_ASSERT(this != &x);
BOOST_ASSERT(this->node_alloc() == x.node_alloc()); BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice(p.get(), x.icont()); 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 //! <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. //! 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 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 //! <b>Requires</b>: p must point to an element contained
//! by this list. i must point to an element contained in list x. //! 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. //! 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 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()); BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice(p.get(), x.icont(), i.get()); 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 //! <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. //! 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 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 //! <b>Requires</b>: p must point to an element contained
//! by this list. first and last must point to elements contained in list x. //! 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. //! 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 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()); BOOST_ASSERT(this->node_alloc() == x.node_alloc());
this->icont().splice(p.get(), x.icont(), first.get(), last.get()); 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 //! <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. //! 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 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 //! <b>Requires</b>: p must point to an element contained
//! by this list. first and last must point to elements contained in list x. //! 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 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private: 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) bool priv_try_shrink(size_type new_size)
{ {
const size_type len = this->size(); const size_type len = this->size();
@@ -1348,12 +1409,14 @@ class list
iterator priv_insert(const_iterator p, const T &x) iterator priv_insert(const_iterator p, const T &x)
{ {
BOOST_ASSERT((priv_is_linked)(p));
NodePtr tmp = AllocHolder::create_node(x); NodePtr tmp = AllocHolder::create_node(x);
return iterator(this->icont().insert(p.get(), *tmp)); return iterator(this->icont().insert(p.get(), *tmp));
} }
iterator priv_insert(const_iterator p, BOOST_RV_REF(T) x) 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)); NodePtr tmp = AllocHolder::create_node(boost::move(x));
return iterator(this->icont().insert(p.get(), *tmp)); return iterator(this->icont().insert(p.get(), *tmp));
} }

View File

@@ -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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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. //! <b>Complexity</b>: Constant.
reference front() reference front()
{ return *this->begin(); } {
BOOST_ASSERT(!this->empty());
return *this->begin();
}
//! <b>Requires</b>: !empty() //! <b>Requires</b>: !empty()
//! //!
@@ -695,7 +698,10 @@ class slist
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference front() const 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. //! <b>Complexity</b>: Amortized constant time.
void pop_front() 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 //! <b>Effects</b>: Erases the element after the element pointed by prev_p
//! of the list. //! of the list.
@@ -939,7 +948,12 @@ class slist
void swap(slist& x) void swap(slist& x)
BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value
|| allocator_traits_type::is_always_equal::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. //! <b>Effects</b>: Erases all the elements of the list.
//! //!

View File

@@ -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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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. //! <b>Complexity</b>: Constant.
reference front() BOOST_NOEXCEPT_OR_NOTHROW 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() //! <b>Requires</b>: !empty()
//! //!
@@ -1207,7 +1210,10 @@ class stable_vector
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW 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() //! <b>Requires</b>: !empty()
//! //!
@@ -1218,7 +1224,10 @@ class stable_vector
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
reference back() BOOST_NOEXCEPT_OR_NOTHROW 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() //! <b>Requires</b>: !empty()
//! //!
@@ -1229,7 +1238,10 @@ class stable_vector
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW 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. //! <b>Requires</b>: size() > n.
//! //!
@@ -1241,7 +1253,7 @@ class stable_vector
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW 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; return static_cast<node_reference>(*this->index[n]).value;
} }
@@ -1255,7 +1267,7 @@ class stable_vector
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW 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; return static_cast<const_node_reference>(*this->index[n]).value;
} }
@@ -1386,6 +1398,7 @@ class stable_vector
template<class ...Args> template<class ...Args>
iterator emplace(const_iterator p, Args && ...args) iterator emplace(const_iterator p, Args && ...args)
{ {
BOOST_ASSERT(this->priv_in_range_or_end(p));
size_type pos_n = p - cbegin(); size_type pos_n = p - cbegin();
typedef emplace_functor<Args...> EmplaceFunctor; typedef emplace_functor<Args...> EmplaceFunctor;
typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator; 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 \ 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 p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\ {\
BOOST_ASSERT(this->priv_in_range_or_end(p));\
typedef emplace_functor##N\ typedef emplace_functor##N\
BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N EmplaceFunctor;\ BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N EmplaceFunctor;\
typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;\ typedef emplace_iterator<value_type, EmplaceFunctor, difference_type> EmplaceIterator;\
@@ -1483,6 +1497,7 @@ class stable_vector
//! <b>Complexity</b>: Linear to n. //! <b>Complexity</b>: Linear to n.
iterator insert(const_iterator p, size_type n, const T& t) iterator insert(const_iterator p, size_type n, const T& t)
{ {
BOOST_ASSERT(this->priv_in_range_or_end(p));
STABLE_VECTOR_CHECK_INVARIANT; STABLE_VECTOR_CHECK_INVARIANT;
typedef constant_iterator<value_type, difference_type> cvalue_iterator; typedef constant_iterator<value_type, difference_type> cvalue_iterator;
return this->insert(p, cvalue_iterator(t, n), 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()). //! <b>Complexity</b>: Linear to distance [il.begin(), il.end()).
iterator insert(const_iterator p, std::initializer_list<value_type> il) iterator insert(const_iterator p, std::initializer_list<value_type> il)
{ {
//Position checks done by insert()
STABLE_VECTOR_CHECK_INVARIANT; STABLE_VECTOR_CHECK_INVARIANT;
return insert(p, il.begin(), il.end()); return insert(p, il.begin(), il.end());
} }
@@ -1526,6 +1542,7 @@ class stable_vector
#endif #endif
insert(const_iterator p, InputIterator first, InputIterator last) insert(const_iterator p, InputIterator first, InputIterator last)
{ {
BOOST_ASSERT(this->priv_in_range_or_end(p));
STABLE_VECTOR_CHECK_INVARIANT; STABLE_VECTOR_CHECK_INVARIANT;
const size_type pos_n = p - this->cbegin(); const size_type pos_n = p - this->cbegin();
for(; first != last; ++first){ for(; first != last; ++first){
@@ -1543,6 +1560,7 @@ class stable_vector
>::type >::type
insert(const_iterator p, FwdIt first, FwdIt last) 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 num_new = static_cast<size_type>(boost::container::iterator_distance(first, last));
const size_type idx = static_cast<size_type>(p - this->cbegin()); const size_type idx = static_cast<size_type>(p - this->cbegin());
if(num_new){ if(num_new){
@@ -1581,7 +1599,10 @@ class stable_vector
//! //!
//! <b>Complexity</b>: Constant time. //! <b>Complexity</b>: Constant time.
void pop_back() BOOST_NOEXCEPT_OR_NOTHROW 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. //! <b>Effects</b>: Erases the element at p.
//! //!
@@ -1591,6 +1612,7 @@ class stable_vector
//! last element. Constant if p is the last element. //! last element. Constant if p is the last element.
iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW
{ {
BOOST_ASSERT(this->priv_in_range(p));
STABLE_VECTOR_CHECK_INVARIANT; STABLE_VECTOR_CHECK_INVARIANT;
const size_type d = p - this->cbegin(); const size_type d = p - this->cbegin();
index_iterator it = this->index.begin() + d; 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. //! plus linear to the elements between p and the last element.
iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW 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; STABLE_VECTOR_CHECK_INVARIANT;
const const_iterator cbeg(this->cbegin()); const const_iterator cbeg(this->cbegin());
const size_type d1 = static_cast<size_type>(first - cbeg), 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 BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value
|| allocator_traits_type::is_always_equal::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; STABLE_VECTOR_CHECK_INVARIANT;
container_detail::bool_<allocator_traits_type::propagate_on_container_swap::value> flag; 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); 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 #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED
private: 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 size_type priv_index_of(node_ptr p) const
{ {
//Check range //Check range
@@ -1807,12 +1845,14 @@ class stable_vector
iterator priv_insert(const_iterator p, const value_type &t) 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; typedef constant_iterator<value_type, difference_type> cvalue_iterator;
return this->insert(p, cvalue_iterator(t, 1), cvalue_iterator()); return this->insert(p, cvalue_iterator(t, 1), cvalue_iterator());
} }
iterator priv_insert(const_iterator p, BOOST_RV_REF(T) x) 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 repeat_iterator<T, difference_type> repeat_it;
typedef boost::move_iterator<repeat_it> repeat_move_it; typedef boost::move_iterator<repeat_it> repeat_move_it;
//Just call more general insert(p, size, value) and return iterator //Just call more general insert(p, size, value) and return iterator

View File

@@ -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 // Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // 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 BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value
|| allocator_traits_type::is_always_equal::value) || allocator_traits_type::is_always_equal::value)
{ {
BOOST_ASSERT(&x != this);
this->priv_move_assign(boost::move(x)); this->priv_move_assign(boost::move(x));
return *this; return *this;
} }
@@ -1512,7 +1513,10 @@ class vector
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
reference front() BOOST_NOEXCEPT_OR_NOTHROW reference front() BOOST_NOEXCEPT_OR_NOTHROW
{ return *this->m_holder.start(); } {
BOOST_ASSERT(!this->empty());
return *this->m_holder.start();
}
//! <b>Requires</b>: !empty() //! <b>Requires</b>: !empty()
//! //!
@@ -1523,7 +1527,10 @@ class vector
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW 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() //! <b>Requires</b>: !empty()
//! //!
@@ -1535,7 +1542,7 @@ class vector
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
reference back() BOOST_NOEXCEPT_OR_NOTHROW 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]; return this->m_holder.start()[this->m_holder.m_size - 1];
} }
@@ -1549,7 +1556,7 @@ class vector
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW 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]; return this->m_holder.start()[this->m_holder.m_size - 1];
} }
@@ -1577,6 +1584,7 @@ class vector
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW
{ {
BOOST_ASSERT(this->m_holder.m_size > n);
return this->m_holder.start()[n]; return this->m_holder.start()[n];
} }
@@ -1626,7 +1634,10 @@ class vector
//! //!
//! <b>Note</b>: Non-standard extension //! <b>Note</b>: Non-standard extension
size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW 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(). //! <b>Requires</b>: begin() <= p <= end().
//! //!
@@ -1639,7 +1650,10 @@ class vector
//! //!
//! <b>Note</b>: Non-standard extension //! <b>Note</b>: Non-standard extension
size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW 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. //! <b>Requires</b>: size() > n.
//! //!
@@ -1650,7 +1664,10 @@ class vector
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
reference at(size_type n) 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. //! <b>Requires</b>: size() > n.
//! //!
@@ -1661,7 +1678,10 @@ class vector
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
const_reference at(size_type n) const 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> template<class ...Args>
iterator emplace(const_iterator position, BOOST_FWD_REF(Args) ...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 //Just call more general insert(pos, size, value) and return iterator
typedef container_detail::insert_emplace_proxy<Allocator, T*, Args...> type; typedef container_detail::insert_emplace_proxy<Allocator, T*, Args...> type;
return this->priv_forward_range_insert( vector_iterator_get_ptr(position), 1 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 \ 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)\ 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;\ 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));\ 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. //! <b>Complexity</b>: Linear to n.
iterator insert(const_iterator p, size_type n, const T& x) 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); container_detail::insert_n_copies_proxy<Allocator, T*> proxy(x);
return this->priv_forward_range_insert(vector_iterator_get_ptr(p), n, proxy); return this->priv_forward_range_insert(vector_iterator_get_ptr(p), n, proxy);
} }
@@ -1878,6 +1901,7 @@ class vector
#endif #endif
) )
{ {
BOOST_ASSERT(this->priv_in_range_or_end(pos));
const size_type n_pos = pos - this->cbegin(); const size_type n_pos = pos - this->cbegin();
iterator it(vector_iterator_get_ptr(pos)); iterator it(vector_iterator_get_ptr(pos));
for(;first != last; ++first){ for(;first != last; ++first){
@@ -1897,6 +1921,7 @@ class vector
>::type * = 0 >::type * = 0
) )
{ {
BOOST_ASSERT(this->priv_in_range_or_end(pos));
container_detail::insert_range_proxy<Allocator, FwdIt, T*> proxy(first); 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); 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> template <class InIt>
iterator insert(const_iterator pos, size_type num, InIt first, InIt last) 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 || BOOST_ASSERT(container_detail::is_input_iterator<InIt>::value ||
num == static_cast<size_type>(boost::container::iterator_distance(first, last))); num == static_cast<size_type>(boost::container::iterator_distance(first, last)));
(void)last; (void)last;
@@ -1939,17 +1965,19 @@ class vector
//! <b>Complexity</b>: Linear to the range [il.begin(), il.end()). //! <b>Complexity</b>: Linear to the range [il.begin(), il.end()).
iterator insert(const_iterator position, std::initializer_list<value_type> il) iterator insert(const_iterator position, std::initializer_list<value_type> il)
{ {
//Assertion done in insert()
return this->insert(position, il.begin(), il.end()); return this->insert(position, il.begin(), il.end());
} }
#endif #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>Throws</b>: Nothing.
//! //!
//! <b>Complexity</b>: Constant time. //! <b>Complexity</b>: Constant time.
void pop_back() BOOST_NOEXCEPT_OR_NOTHROW void pop_back() BOOST_NOEXCEPT_OR_NOTHROW
{ {
BOOST_ASSERT(!this->empty());
//Destroy last element //Destroy last element
this->priv_destroy_last(); this->priv_destroy_last();
} }
@@ -1962,6 +1990,7 @@ class vector
//! last element. Constant if pos is the last element. //! last element. Constant if pos is the last element.
iterator erase(const_iterator position) iterator erase(const_iterator position)
{ {
BOOST_ASSERT(this->priv_in_range(position));
const pointer p = vector_iterator_get_ptr(position); const pointer p = vector_iterator_get_ptr(position);
T *const pos_ptr = container_detail::to_raw_pointer(p); T *const pos_ptr = container_detail::to_raw_pointer(p);
T *const beg_ptr = container_detail::to_raw_pointer(this->m_holder.start()); 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. //! plus linear to the elements between pos and the last element.
iterator erase(const_iterator first, const_iterator last) 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){ if (first != last){
T* const old_end_ptr = this->back_raw(); T* const old_end_ptr = this->back_raw();
T* const first_ptr = container_detail::to_raw_pointer(vector_iterator_get_ptr(first)); T* const first_ptr = container_detail::to_raw_pointer(vector_iterator_get_ptr(first));
@@ -2571,6 +2603,7 @@ class vector
template<class U> template<class U>
iterator priv_insert(const const_iterator &p, BOOST_FWD_REF(U) x) 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 return this->priv_forward_range_insert
( vector_iterator_get_ptr(p), 1, container_detail::get_insert_value_proxy<T*, Allocator>(::boost::forward<U>(x))); ( 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 is out of range, throw an out_of_range exception
if (n >= this->size()){ 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 #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS
public: public:
unsigned int num_expand_fwd; unsigned int num_expand_fwd;