summaryrefslogtreecommitdiff
path: root/boost/container/stable_vector.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/container/stable_vector.hpp')
-rw-r--r--boost/container/stable_vector.hpp86
1 files changed, 63 insertions, 23 deletions
diff --git a/boost/container/stable_vector.hpp b/boost/container/stable_vector.hpp
index 6aca69bde6..a332dbc66c 100644
--- a/boost/container/stable_vector.hpp
+++ b/boost/container/stable_vector.hpp
@@ -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());
}
@@ -1515,17 +1531,19 @@ class stable_vector
//!
//! <b>Complexity</b>: Linear to distance [first, last).
template <class InputIterator>
- #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
- typename container_detail::disable_if_or
- < iterator
- , container_detail::is_convertible<InputIterator, size_type>
- , container_detail::is_not_input_iterator<InputIterator>
- >::type
- #else
- iterator
- #endif
- insert(const_iterator p, InputIterator first, InputIterator last)
- {
+ iterator insert(const_iterator p, InputIterator first, InputIterator last
+ #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+ //Put this as argument instead of the return type as old GCC's like 3.4
+ //detect this and the next disable_if_or as overloads
+ , typename container_detail::disable_if_or
+ < void
+ , container_detail::is_convertible<InputIterator, size_type>
+ , container_detail::is_not_input_iterator<InputIterator>
+ >::type* = 0
+ #endif
+ )
+ {
+ 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 +1561,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){
@@ -1556,12 +1575,12 @@ class stable_vector
//Prepare rollback
insert_rollback rollback(*this, it_past_newly_constructed, it_past_new);
while(first != last){
- const node_ptr p = this->priv_get_from_pool();
- BOOST_ASSERT(!!p);
+ const node_ptr n = this->priv_get_from_pool();
+ BOOST_ASSERT(!!n);
//Put it in the index so rollback can return it in pool if construct_in_place throws
- *it_past_newly_constructed = p;
+ *it_past_newly_constructed = n;
//Constructs and fixes up pointers This can throw
- this->priv_build_node_from_it(p, it_past_newly_constructed, first);
+ this->priv_build_node_from_it(n, it_past_newly_constructed, first);
++first;
++it_past_newly_constructed;
}
@@ -1581,7 +1600,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 +1613,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 +1631,8 @@ 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 ||
+ (first < last && this->priv_in_range(first) && 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