forked from boostorg/container
Added debug assertions via BOOST_ASSERT to check preconditions in several members. All checks are O(1)
This commit is contained in:
1 parent
3f4a5dec6e
commit
85b2ed509b
8 files changed
+331
-75
No files matched your search
@@ -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));
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user