summaryrefslogtreecommitdiff
path: root/boost/container/list.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/container/list.hpp')
-rw-r--r--boost/container/list.hpp111
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));
}