diff options
Diffstat (limited to 'boost/container/list.hpp')
-rw-r--r-- | boost/container/list.hpp | 111 |
1 files changed, 87 insertions, 24 deletions
diff --git a/boost/container/list.hpp b/boost/container/list.hpp index 5135eaecee..8236ff7939 100644 --- a/boost/container/list.hpp +++ b/boost/container/list.hpp @@ -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)); } |