diff options
Diffstat (limited to 'boost/container/stable_vector.hpp')
-rw-r--r-- | boost/container/stable_vector.hpp | 86 |
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 |