summaryrefslogtreecommitdiff
path: root/boost/container/detail/tree.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/container/detail/tree.hpp')
-rw-r--r--boost/container/detail/tree.hpp37
1 files changed, 32 insertions, 5 deletions
diff --git a/boost/container/detail/tree.hpp b/boost/container/detail/tree.hpp
index c90202973a..c2d6b1d17d 100644
--- a/boost/container/detail/tree.hpp
+++ b/boost/container/detail/tree.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)
//
@@ -413,8 +413,11 @@ struct key_node_compare
{ return node.get_data(); }
template<class T>
- typename enable_if_c<!is_node<T>::value, const T &>::type
- key_forward(const T &key) const
+ #if defined(BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN)
+ const T &key_forward(const T &key, typename enable_if_c<!is_node<T>::value>::type* =0) const
+ #else
+ typename enable_if_c<!is_node<T>::value, const T &>::type key_forward(const T &key) const
+ #endif
{ return key; }
template<class KeyType, class KeyType2>
@@ -811,6 +814,7 @@ class tree
std::pair<iterator,bool> insert_unique_check
(const_iterator hint, const key_type& key, insert_commit_data &data)
{
+ BOOST_ASSERT((priv_is_linked)(hint));
std::pair<iiterator, bool> ret =
this->icont().insert_unique_check(hint.get(), key, KeyNodeCompare(value_comp()), data);
return std::pair<iterator, bool>(iterator(ret.first), ret.second);
@@ -861,6 +865,15 @@ class tree
private:
+ bool priv_is_linked(const_iterator const position) const
+ {
+ iiterator const cur(position.get());
+ return cur == this->icont().end() ||
+ cur == this->icont().root() ||
+ iiterator(cur).go_parent().go_left() == cur ||
+ iiterator(cur).go_parent().go_right() == cur;
+ }
+
template<class MovableConvertible>
void push_back_impl(BOOST_FWD_REF(MovableConvertible) v)
{
@@ -888,6 +901,7 @@ class tree
iterator emplace_unique_hint_impl(const_iterator hint, NodePtr p)
{
+ BOOST_ASSERT((priv_is_linked)(hint));
value_type &v = p->get_data();
insert_commit_data data;
std::pair<iterator,bool> ret =
@@ -924,6 +938,7 @@ class tree
template <class... Args>
iterator emplace_hint_equal(const_iterator hint, BOOST_FWD_REF(Args)... args)
{
+ BOOST_ASSERT((priv_is_linked)(hint));
NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
@@ -955,6 +970,7 @@ class tree
BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \
iterator emplace_hint_equal(const_iterator hint BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\
{\
+ BOOST_ASSERT((priv_is_linked)(hint));\
NodePtr tmp(AllocHolder::create_node(BOOST_MOVE_FWD##N));\
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());\
iterator ret(this->icont().insert_equal(hint.get(), *tmp));\
@@ -969,6 +985,7 @@ class tree
iterator insert_unique(const_iterator hint, const value_type& v)
{
+ BOOST_ASSERT((priv_is_linked)(hint));
insert_commit_data data;
std::pair<iterator,bool> ret =
this->insert_unique_check(hint, KeyOfValue()(v), data);
@@ -980,6 +997,7 @@ class tree
template<class MovableConvertible>
iterator insert_unique(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v)
{
+ BOOST_ASSERT((priv_is_linked)(hint));
insert_commit_data data;
std::pair<iterator,bool> ret =
this->insert_unique_check(hint, KeyOfValue()(v), data);
@@ -1016,6 +1034,7 @@ class tree
iterator insert_equal(const_iterator hint, const value_type& v)
{
+ BOOST_ASSERT((priv_is_linked)(hint));
NodePtr tmp(AllocHolder::create_node(v));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
@@ -1026,6 +1045,7 @@ class tree
template<class MovableConvertible>
iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) v)
{
+ BOOST_ASSERT((priv_is_linked)(hint));
NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(v)));
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
@@ -1041,13 +1061,20 @@ class tree
}
iterator erase(const_iterator position)
- { return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc()))); }
+ {
+ BOOST_ASSERT(position != this->cend() && (priv_is_linked)(position));
+ return iterator(this->icont().erase_and_dispose(position.get(), Destroyer(this->node_alloc())));
+ }
size_type erase(const key_type& k)
{ return AllocHolder::erase_key(k, KeyNodeCompare(value_comp()), alloc_version()); }
iterator erase(const_iterator first, const_iterator last)
- { 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()));
+ }
void clear()
{ AllocHolder::clear(alloc_version()); }