diff --git a/include/boost/intrusive/any_hook.hpp b/include/boost/intrusive/any_hook.hpp
index 29a5b08..b1b0194 100644
--- a/include/boost/intrusive/any_hook.hpp
+++ b/include/boost/intrusive/any_hook.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/intrusive/avl_set.hpp b/include/boost/intrusive/avl_set.hpp
index 3998f05..a944077 100644
--- a/include/boost/intrusive/avl_set.hpp
+++ b/include/boost/intrusive/avl_set.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -489,6 +489,60 @@ class avl_set_impl
void insert(Iterator b, Iterator e)
{ tree_.insert_unique(b, e); }
+ //! Requires: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate. "value" must not be equal to any
+ //! inserted key according to the predicate.
+ //!
+ //! Effects: Inserts x into the tree before "pos".
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" or "value" is not unique tree ordering and uniqueness
+ //! invariants will be broken respectively.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ { return tree_.insert_before(pos, value); }
+
+ //! Requires: value must be an lvalue, and it must be greater than
+ //! any inserted key according to the predicate.
+ //!
+ //! Effects: Inserts x into the tree in the last position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! less than or equal to the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ { tree_.push_back(value); }
+
+ //! Requires: value must be an lvalue, and it must be less
+ //! than any inserted key according to the predicate.
+ //!
+ //! Effects: Inserts x into the tree in the first position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! greater than or equal to the the mimum inserted key tree ordering or uniqueness
+ //! invariants will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ { tree_.push_front(value); }
+
//! Effects: Erases the element pointed to by pos.
//!
//! Complexity: Average complexity is constant time.
@@ -1532,9 +1586,63 @@ class avl_multiset_impl
void insert(Iterator b, Iterator e)
{ tree_.insert_equal(b, e); }
+ //! Requires: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate. "value" must not be equal to any
+ //! inserted key according to the predicate.
+ //!
+ //! Effects: Inserts x into the tree before "pos".
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" or "value" is not unique tree ordering and uniqueness
+ //! invariants will be broken respectively.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ { return tree_.insert_before(pos, value); }
+
+ //! Requires: value must be an lvalue, and it must be greater than
+ //! any inserted key according to the predicate.
+ //!
+ //! Effects: Inserts x into the tree in the last position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! less than or equal to the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ { tree_.push_back(value); }
+
+ //! Requires: value must be an lvalue, and it must be less
+ //! than any inserted key according to the predicate.
+ //!
+ //! Effects: Inserts x into the tree in the first position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! greater than or equal to the the mimum inserted key tree ordering or uniqueness
+ //! invariants will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ { tree_.push_front(value); }
+
//! Effects: Erases the element pointed to by pos.
//!
- //! Complexity: Average complexity is constant time.
+ //! Complexity: Average complexity is constant time.
//!
//! Returns: An iterator to the element after the erased element.
//!
diff --git a/include/boost/intrusive/avl_set_hook.hpp b/include/boost/intrusive/avl_set_hook.hpp
index 00d2fc8..23b1f0b 100644
--- a/include/boost/intrusive/avl_set_hook.hpp
+++ b/include/boost/intrusive/avl_set_hook.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -96,6 +96,7 @@ class avl_set_base_hook
::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
//! Effects: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
@@ -221,6 +222,7 @@ class avl_set_member_hook
::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
//! Effects: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
diff --git a/include/boost/intrusive/avltree.hpp b/include/boost/intrusive/avltree.hpp
index c247e32..e65f182 100644
--- a/include/boost/intrusive/avltree.hpp
+++ b/include/boost/intrusive/avltree.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -704,6 +704,76 @@ class avltree_impl
return iterator(to_insert, this);
}
+ //! Requires: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate
+ //!
+ //! Effects: Inserts x into the tree before "pos".
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" tree ordering invariant will be broken.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ return iterator(node_algorithms::insert_before
+ (node_ptr(&priv_header()), pos.pointed_node(), to_insert), this);
+ }
+
+ //! Requires: value must be an lvalue, and it must be no less
+ //! than the greatest inserted key
+ //!
+ //! Effects: Inserts x into the tree in the last position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! less than the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ node_algorithms::push_back(node_ptr(&priv_header()), to_insert);
+ }
+
+ //! Requires: value must be an lvalue, and it must be no greater
+ //! than the minimum inserted key
+ //!
+ //! Effects: Inserts x into the tree in the first position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! greater than the minimum inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ node_algorithms::push_front(node_ptr(&priv_header()), to_insert);
+ }
+
//! Effects: Erases the element pointed to by pos.
//!
//! Complexity: Average complexity for erase element is constant time.
diff --git a/include/boost/intrusive/avltree_algorithms.hpp b/include/boost/intrusive/avltree_algorithms.hpp
index 6385ff9..a632581 100644
--- a/include/boost/intrusive/avltree_algorithms.hpp
+++ b/include/boost/intrusive/avltree_algorithms.hpp
@@ -530,6 +530,66 @@ class avltree_algorithms
return new_node;
}
+ //! Requires: "header" must be the header node of a tree.
+ //! "pos" must be a valid iterator or header (end) node.
+ //! "pos" must be an iterator pointing to the successor to "new_node"
+ //! once inserted according to the order of already inserted nodes. This function does not
+ //! check "pos" and this precondition must be guaranteed by the caller.
+ //!
+ //! Effects: Inserts new_node into the tree before "pos".
+ //!
+ //! Complexity: Constant-time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: If "pos" is not the successor of the newly inserted "new_node"
+ //! tree invariants might be broken.
+ static node_ptr insert_before
+ (node_ptr header, node_ptr pos, node_ptr new_node)
+ {
+ tree_algorithms::insert_before(header, pos, new_node);
+ rebalance_after_insertion(header, new_node);
+ return new_node;
+ }
+
+ //! Requires: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering no less than the
+ //! greatest inserted key.
+ //!
+ //! Effects: Inserts new_node into the tree before "pos".
+ //!
+ //! Complexity: Constant-time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: If "new_node" is less than the greatest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ static void push_back(node_ptr header, node_ptr new_node)
+ {
+ tree_algorithms::push_back(header, new_node);
+ rebalance_after_insertion(header, new_node);
+ }
+
+ //! Requires: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering, no greater than the
+ //! lowest inserted key.
+ //!
+ //! Effects: Inserts new_node into the tree before "pos".
+ //!
+ //! Complexity: Constant-time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: If "new_node" is greater than the lowest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ static void push_front(node_ptr header, node_ptr new_node)
+ {
+ tree_algorithms::push_front(header, new_node);
+ rebalance_after_insertion(header, new_node);
+ }
+
//! Requires: "header" must be the header node of a tree.
//! KeyNodePtrCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the
diff --git a/include/boost/intrusive/bs_set_hook.hpp b/include/boost/intrusive/bs_set_hook.hpp
index 3ab0310..bf8e2de 100644
--- a/include/boost/intrusive/bs_set_hook.hpp
+++ b/include/boost/intrusive/bs_set_hook.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -96,6 +96,7 @@ class bs_set_base_hook
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
//! Effects: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
@@ -220,6 +221,7 @@ class bs_set_member_hook
::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
//! Effects: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
diff --git a/include/boost/intrusive/circular_list_algorithms.hpp b/include/boost/intrusive/circular_list_algorithms.hpp
index aeb0358..16b1971 100644
--- a/include/boost/intrusive/circular_list_algorithms.hpp
+++ b/include/boost/intrusive/circular_list_algorithms.hpp
@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -110,7 +110,7 @@ class circular_list_algorithms
//! Effects: Returns the number of nodes in a circular list. If the circular list
//! is empty, returns 1.
//!
- //! Complexity: Constant
+ //! Complexity: Linear
//!
//! Throws: Nothing.
static std::size_t count(const_node_ptr this_node)
diff --git a/include/boost/intrusive/circular_slist_algorithms.hpp b/include/boost/intrusive/circular_slist_algorithms.hpp
index cb9cb3b..ae06396 100644
--- a/include/boost/intrusive/circular_slist_algorithms.hpp
+++ b/include/boost/intrusive/circular_slist_algorithms.hpp
@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -199,7 +199,7 @@ class circular_slist_algorithms
//! Effects: Returns the number of nodes in a circular list. If the circular list
//! is empty, returns 1.
//!
- //! Complexity: Constant
+ //! Complexity: Linear
//!
//! Throws: Nothing.
static std::size_t count(const_node_ptr this_node)
diff --git a/include/boost/intrusive/derivation_value_traits.hpp b/include/boost/intrusive/derivation_value_traits.hpp
index 58467d5..88edeab 100644
--- a/include/boost/intrusive/derivation_value_traits.hpp
+++ b/include/boost/intrusive/derivation_value_traits.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/intrusive/detail/any_node_and_algorithms.hpp b/include/boost/intrusive/detail/any_node_and_algorithms.hpp
index 6a3d955..e2fbbfa 100644
--- a/include/boost/intrusive/detail/any_node_and_algorithms.hpp
+++ b/include/boost/intrusive/detail/any_node_and_algorithms.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/intrusive/detail/assert.hpp b/include/boost/intrusive/detail/assert.hpp
index 0fe98f8..cfe392b 100644
--- a/include/boost/intrusive/detail/assert.hpp
+++ b/include/boost/intrusive/detail/assert.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/intrusive/detail/clear_on_destructor_base.hpp b/include/boost/intrusive/detail/clear_on_destructor_base.hpp
index 838dd67..6765dfa 100644
--- a/include/boost/intrusive/detail/clear_on_destructor_base.hpp
+++ b/include/boost/intrusive/detail/clear_on_destructor_base.hpp
@@ -1,6 +1,6 @@
//////} // ///////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2008-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2008-2009. 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)
//
diff --git a/include/boost/intrusive/detail/common_slist_algorithms.hpp b/include/boost/intrusive/detail/common_slist_algorithms.hpp
index d837ad0..c6bdb20 100644
--- a/include/boost/intrusive/detail/common_slist_algorithms.hpp
+++ b/include/boost/intrusive/detail/common_slist_algorithms.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -74,15 +74,22 @@ class common_slist_algorithms
NodeTraits::set_next(prev_node, this_node);
}
- static void transfer_after(node_ptr p, node_ptr b, node_ptr e)
+ static void incorporate_after(node_ptr bp, node_ptr b, node_ptr be)
{
- if (p != b && p != e && b != e) {
- node_ptr next_b = NodeTraits::get_next(b);
- node_ptr next_e = NodeTraits::get_next(e);
- node_ptr next_p = NodeTraits::get_next(p);
- NodeTraits::set_next(b, next_e);
- NodeTraits::set_next(e, next_p);
- NodeTraits::set_next(p, next_b);
+ node_ptr p(NodeTraits::get_next(bp));
+ NodeTraits::set_next(bp, b);
+ NodeTraits::set_next(be, p);
+ }
+
+ static void transfer_after(node_ptr bp, node_ptr bb, node_ptr be)
+ {
+ if (bp != bb && bp != be && bb != be) {
+ node_ptr next_b = NodeTraits::get_next(bb);
+ node_ptr next_e = NodeTraits::get_next(be);
+ node_ptr next_p = NodeTraits::get_next(bp);
+ NodeTraits::set_next(bb, next_e);
+ NodeTraits::set_next(be, next_p);
+ NodeTraits::set_next(bp, next_b);
}
}
};
diff --git a/include/boost/intrusive/detail/config_begin.hpp b/include/boost/intrusive/detail/config_begin.hpp
index 1c390be..bb126fc 100644
--- a/include/boost/intrusive/detail/config_begin.hpp
+++ b/include/boost/intrusive/detail/config_begin.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/intrusive/detail/config_end.hpp b/include/boost/intrusive/detail/config_end.hpp
index f04b2e9..4277cb5 100644
--- a/include/boost/intrusive/detail/config_end.hpp
+++ b/include/boost/intrusive/detail/config_end.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/intrusive/detail/ebo_functor_holder.hpp b/include/boost/intrusive/detail/ebo_functor_holder.hpp
index 35628f2..d4c2d15 100644
--- a/include/boost/intrusive/detail/ebo_functor_holder.hpp
+++ b/include/boost/intrusive/detail/ebo_functor_holder.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Joaquin M Lopez Munoz 2006-2008
+// (C) Copyright Joaquin M Lopez Munoz 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -13,6 +13,7 @@
#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
#define BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
+#include
#include
namespace boost {
@@ -89,4 +90,6 @@ class ebo_functor_holder
} //namespace intrusive {
} //namespace boost {
+#include
+
#endif //#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
diff --git a/include/boost/intrusive/detail/function_detector.hpp b/include/boost/intrusive/detail/function_detector.hpp
new file mode 100644
index 0000000..a20db6d
--- /dev/null
+++ b/include/boost/intrusive/detail/function_detector.hpp
@@ -0,0 +1,87 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009-2009.
+//
+// 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)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+// This code was modified from the code posted by Alexandre Courpron in his
+// article "Interface Detection" in The Code Project:
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2007 Alexandre Courpron
+//
+// Permission to use, copy, modify, redistribute and sell this software,
+// provided that this copyright notice appears on all copies of the software.
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP
+#define BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP
+
+#include
+
+namespace boost {
+namespace intrusive {
+namespace function_detector {
+
+ typedef char NotFoundType;
+ struct StaticFunctionType { NotFoundType x [2]; };
+ struct NonStaticFunctionType { NotFoundType x [3]; };
+
+ enum
+ { NotFound = 0,
+ StaticFunction = sizeof( StaticFunctionType ) - sizeof( NotFoundType ),
+ NonStaticFunction = sizeof( NonStaticFunctionType ) - sizeof( NotFoundType )
+ };
+
+} //namespace boost {
+} //namespace intrusive {
+} //namespace function_detector {
+
+#define BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(Identifier, InstantiationKey) \
+ namespace boost { \
+ namespace intrusive { \
+ namespace function_detector { \
+ template < class T, \
+ class NonStaticType, \
+ class NonStaticConstType, \
+ class StaticType > \
+ class DetectMember_##InstantiationKey_##Identifier { \
+ template < NonStaticType > \
+ struct TestNonStaticNonConst ; \
+ \
+ template < NonStaticConstType > \
+ struct TestNonStaticConst ; \
+ \
+ template < StaticType > \
+ struct TestStatic ; \
+ \
+ template \
+ static NonStaticFunctionType Test( TestNonStaticNonConst<&U::Identifier>*, int ); \
+ \
+ template \
+ static NonStaticFunctionType Test( TestNonStaticConst<&U::Identifier>*, int ); \
+ \
+ template \
+ static StaticFunctionType Test( TestStatic<&U::Identifier>*, int ); \
+ \
+ template \
+ static NotFoundType Test( ... ); \
+ public : \
+ static const int check = NotFound + (sizeof(Test(0, 0)) - sizeof(NotFoundType));\
+ };\
+}}} //namespace boost::intrusive::function_detector {
+
+#define BOOST_INTRUSIVE_DETECT_FUNCTION(Class, InstantiationKey, ReturnType, Identifier, Params) \
+ ::boost::intrusive::function_detector::DetectMember_##InstantiationKey_##Identifier< Class,\
+ ReturnType (Class::*)Params,\
+ ReturnType (Class::*)Params const,\
+ ReturnType (*)Params \
+ >::check
+
+#include
+
+#endif //@ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP
diff --git a/include/boost/intrusive/detail/generic_hook.hpp b/include/boost/intrusive/detail/generic_hook.hpp
index 1b4736b..ae1282e 100644
--- a/include/boost/intrusive/detail/generic_hook.hpp
+++ b/include/boost/intrusive/detail/generic_hook.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/intrusive/detail/hashtable_node.hpp b/include/boost/intrusive/detail/hashtable_node.hpp
index fbb150d..1676b1c 100644
--- a/include/boost/intrusive/detail/hashtable_node.hpp
+++ b/include/boost/intrusive/detail/hashtable_node.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -100,8 +100,12 @@ template
class hashtable_iterator
: public std::iterator
< std::forward_iterator_tag
+ , typename Container::value_type
+ , typename std::iterator_traits::difference_type
, typename detail::add_const_if_c
- ::type
+ ::type *
+ , typename detail::add_const_if_c
+ ::type &
>
{
typedef typename Container::real_value_traits real_value_traits;
@@ -116,8 +120,11 @@ class hashtable_iterator
{ return typename Container::node_ptr(&static_cast(*p)); }
public:
+ typedef typename Container::value_type value_type;
+ typedef typename detail::add_const_if_c
+ ::type *pointer;
typedef typename detail::add_const_if_c
- ::type value_type;
+ ::type &reference;
hashtable_iterator ()
{}
@@ -133,6 +140,9 @@ class hashtable_iterator
const siterator &slist_it() const
{ return slist_it_; }
+ hashtable_iterator unconst() const
+ { return hashtable_iterator(this->slist_it(), this->get_container()); }
+
public:
hashtable_iterator& operator++()
{ this->increment(); return *this; }
@@ -150,10 +160,10 @@ class hashtable_iterator
friend bool operator!= (const hashtable_iterator& i, const hashtable_iterator& i2)
{ return !(i == i2); }
- value_type& operator*() const
+ reference operator*() const
{ return *this->operator ->(); }
- value_type* operator->() const
+ pointer operator->() const
{ return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(downcast_bucket(slist_it_.pointed_node()))); }
const Container *get_container() const
diff --git a/include/boost/intrusive/detail/is_stateful_value_traits.hpp b/include/boost/intrusive/detail/is_stateful_value_traits.hpp
new file mode 100644
index 0000000..a11f988
--- /dev/null
+++ b/include/boost/intrusive/detail/is_stateful_value_traits.hpp
@@ -0,0 +1,56 @@
+/////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009-2009.
+//
+// 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)
+//
+// See http://www.boost.org/libs/intrusive for documentation.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP
+#define BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP
+
+#include
+#include
+
+BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(to_node_ptr, boost_intrusive)
+BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(to_value_ptr, boost_intrusive)
+
+namespace boost {
+namespace intrusive {
+namespace detail {
+
+template
+struct is_stateful_value_traits
+{
+ typedef typename ValueTraits::node_ptr node_ptr;
+ typedef typename ValueTraits::pointer pointer;
+ typedef typename ValueTraits::value_type value_type;
+ typedef typename ValueTraits::const_node_ptr const_node_ptr;
+ typedef typename ValueTraits::const_pointer const_pointer;
+
+ typedef ValueTraits value_traits;
+
+ static const bool value =
+ (boost::intrusive::function_detector::NonStaticFunction ==
+ (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, node_ptr, to_node_ptr, (value_type&) )))
+ ||
+ (boost::intrusive::function_detector::NonStaticFunction ==
+ (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, pointer, to_value_ptr, (node_ptr) )))
+ ||
+ (boost::intrusive::function_detector::NonStaticFunction ==
+ (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, const_node_ptr, to_node_ptr, (const value_type&) )))
+ ||
+ (boost::intrusive::function_detector::NonStaticFunction ==
+ (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, const_pointer, to_value_ptr, (const_node_ptr) )))
+ ;
+};
+
+}}}
+
+#include
+
+#endif //@ifndef BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP
diff --git a/include/boost/intrusive/detail/list_node.hpp b/include/boost/intrusive/detail/list_node.hpp
index effd36a..935c522 100644
--- a/include/boost/intrusive/detail/list_node.hpp
+++ b/include/boost/intrusive/detail/list_node.hpp
@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -63,8 +63,12 @@ template
class list_iterator
: public std::iterator
< std::bidirectional_iterator_tag
+ , typename Container::value_type
+ , typename std::iterator_traits::difference_type
, typename detail::add_const_if_c
- ::type
+ ::type *
+ , typename detail::add_const_if_c
+ ::type &
>
{
protected:
@@ -78,11 +82,11 @@ class list_iterator
detail::store_cont_ptr_on_it::value;
public:
+ typedef typename Container::value_type value_type;
+ typedef typename detail::add_const_if_c
+ ::type *pointer;
typedef typename detail::add_const_if_c
-
- ::type value_type;
- typedef value_type & reference;
- typedef value_type * pointer;
+ ::type &reference;
list_iterator()
: members_ (node_ptr(0), 0)
@@ -135,7 +139,7 @@ class list_iterator
bool operator!= (const list_iterator& i) const
{ return !operator== (i); }
- value_type& operator*() const
+ reference operator*() const
{ return *operator->(); }
pointer operator->() const
diff --git a/include/boost/intrusive/detail/mpl.hpp b/include/boost/intrusive/detail/mpl.hpp
index 20f50da..5f57e37 100644
--- a/include/boost/intrusive/detail/mpl.hpp
+++ b/include/boost/intrusive/detail/mpl.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -13,6 +13,7 @@
#ifndef BOOST_INTRUSIVE_DETAIL_MPL_HPP
#define BOOST_INTRUSIVE_DETAIL_MPL_HPP
+#include
#include
namespace boost {
@@ -364,4 +365,6 @@ struct ls_zeros<1>
} //namespace intrusive
} //namespace boost
+#include
+
#endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP
diff --git a/include/boost/intrusive/detail/parent_from_member.hpp b/include/boost/intrusive/detail/parent_from_member.hpp
index c750ad8..0b30867 100644
--- a/include/boost/intrusive/detail/parent_from_member.hpp
+++ b/include/boost/intrusive/detail/parent_from_member.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/intrusive/detail/rbtree_node.hpp b/include/boost/intrusive/detail/rbtree_node.hpp
index 6d6dd84..87ba59d 100644
--- a/include/boost/intrusive/detail/rbtree_node.hpp
+++ b/include/boost/intrusive/detail/rbtree_node.hpp
@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008.
+// (C) Copyright Ion Gaztanaga 2006-2009.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/intrusive/detail/slist_node.hpp b/include/boost/intrusive/detail/slist_node.hpp
index 4101092..a7df9e1 100644
--- a/include/boost/intrusive/detail/slist_node.hpp
+++ b/include/boost/intrusive/detail/slist_node.hpp
@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -55,8 +55,12 @@ template
class slist_iterator
: public std::iterator
< std::forward_iterator_tag
+ , typename Container::value_type
+ , typename std::iterator_traits::difference_type
, typename detail::add_const_if_c
- ::type
+ ::type *
+ , typename detail::add_const_if_c
+ ::type &
>
{
protected:
@@ -70,11 +74,11 @@ class slist_iterator
detail::store_cont_ptr_on_it::value;
public:
+ typedef typename Container::value_type value_type;
+ typedef typename detail::add_const_if_c
+ ::type *pointer;
typedef typename detail::add_const_if_c
-
- ::type value_type;
- typedef value_type & reference;
- typedef value_type * pointer;
+ ::type &reference;
slist_iterator()
: members_ (node_ptr(0), 0)
@@ -114,7 +118,7 @@ class slist_iterator
bool operator!= (const slist_iterator& i) const
{ return !operator== (i); }
- value_type& operator*() const
+ reference operator*() const
{ return *operator->(); }
pointer operator->() const
diff --git a/include/boost/intrusive/detail/transform_iterator.hpp b/include/boost/intrusive/detail/transform_iterator.hpp
index a4afd77..a9de49e 100644
--- a/include/boost/intrusive/detail/transform_iterator.hpp
+++ b/include/boost/intrusive/detail/transform_iterator.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/intrusive/detail/tree_algorithms.hpp b/include/boost/intrusive/detail/tree_algorithms.hpp
index 57d5206..32bbfb5 100644
--- a/include/boost/intrusive/detail/tree_algorithms.hpp
+++ b/include/boost/intrusive/detail/tree_algorithms.hpp
@@ -160,7 +160,7 @@ class tree_algorithms
//!
//! Throws: Nothing.
static bool unique(const_node_ptr node)
- { return NodeTraits::get_parent(node) == 0; }
+ { return !NodeTraits::get_parent(node); }
static node_ptr get_header(const_node_ptr node)
{
@@ -460,7 +460,8 @@ class tree_algorithms
static node_ptr prev_node(node_ptr p)
{
if(is_header(p)){
- return maximum(NodeTraits::get_parent(p));
+ return NodeTraits::get_right(p);
+ //return maximum(NodeTraits::get_parent(p));
}
else if(NodeTraits::get_left(p)){
return maximum(NodeTraits::get_left(p));
@@ -721,21 +722,19 @@ class tree_algorithms
static bool is_header(const_node_ptr p)
{
- bool is_header = false;
- if(NodeTraits::get_parent(p) == p){
- is_header = true;
+ node_ptr p_left (NodeTraits::get_left(p));
+ node_ptr p_right(NodeTraits::get_right(p));
+ if(!NodeTraits::get_parent(p) || //Header condition when empty tree
+ (p_left && p_right && //Header always has leftmost and rightmost
+ (p_left == p_right || //Header condition when only node
+ (NodeTraits::get_parent(p_left) != p ||
+ NodeTraits::get_parent(p_right) != p ))
+ //When tree size > 1 headers can't be leftmost's
+ //and rightmost's parent
+ )){
+ return true;
}
- else if(NodeTraits::get_parent(NodeTraits::get_parent(p)) == p){
- if(NodeTraits::get_left(p) != 0){
- if(NodeTraits::get_parent(NodeTraits::get_left(p)) != p){
- is_header = true;
- }
- if(NodeTraits::get_parent(p) == NodeTraits::get_left(p)){
- is_header = true;
- }
- }
- }
- return is_header;
+ return false;
}
//! Requires: "header" must be the header node of a tree.
@@ -894,10 +893,32 @@ class tree_algorithms
//! erased between the "insert_check" and "insert_commit" calls.
static void insert_unique_commit
(node_ptr header, node_ptr new_value, const insert_commit_data &commit_data)
+ { return insert_commit(header, new_value, commit_data); }
+
+ static void insert_commit
+ (node_ptr header, node_ptr new_node, const insert_commit_data &commit_data)
{
//Check if commit_data has not been initialized by a insert_unique_check call.
BOOST_INTRUSIVE_INVARIANT_ASSERT(commit_data.node != 0);
- link(header, new_value, commit_data.node, commit_data.link_left);
+ node_ptr parent_node(commit_data.node);
+ if(parent_node == header){
+ NodeTraits::set_parent(header, new_node);
+ NodeTraits::set_right(header, new_node);
+ NodeTraits::set_left(header, new_node);
+ }
+ else if(commit_data.link_left){
+ NodeTraits::set_left(parent_node, new_node);
+ if(parent_node == NodeTraits::get_left(header))
+ NodeTraits::set_left(header, new_node);
+ }
+ else{
+ NodeTraits::set_right(parent_node, new_node);
+ if(parent_node == NodeTraits::get_right(header))
+ NodeTraits::set_right(header, new_node);
+ }
+ NodeTraits::set_parent(new_node, parent_node);
+ NodeTraits::set_right(new_node, node_ptr(0));
+ NodeTraits::set_left(new_node, node_ptr(0));
}
//! Requires: "header" must be the header node of a tree.
@@ -979,9 +1000,9 @@ class tree_algorithms
{
//hint must be bigger than the key
if(hint == header || comp(key, hint)){
- node_ptr prev = hint;
- //The previous value should be less than the key
- if(prev == NodeTraits::get_left(header) || comp((prev = prev_node(hint)), key)){
+ node_ptr prev(hint);
+ //Previous value should be less than the key
+ if(hint == begin_node(header)|| comp((prev = prev_node(hint)), key)){
commit_data.link_left = unique(header) || !NodeTraits::get_left(hint);
commit_data.node = commit_data.link_left ? hint : prev;
if(pdepth){
@@ -989,14 +1010,9 @@ class tree_algorithms
}
return std::pair(node_ptr(), true);
}
- else{
- return insert_unique_check(header, key, comp, commit_data, pdepth);
- }
- }
- //The hint was wrong, use hintless insert
- else{
- return insert_unique_check(header, key, comp, commit_data, pdepth);
}
+ //Hint was wrong, use hintless insertion
+ return insert_unique_check(header, key, comp, commit_data, pdepth);
}
template
@@ -1040,7 +1056,7 @@ class tree_algorithms
{
insert_commit_data commit_data;
insert_equal_check(h, hint, new_node, comp, commit_data, pdepth);
- link(h, new_node, commit_data.node, commit_data.link_left);
+ insert_commit(h, new_node, commit_data);
return new_node;
}
@@ -1050,7 +1066,7 @@ class tree_algorithms
{
insert_commit_data commit_data;
insert_equal_upper_bound_check(h, new_node, comp, commit_data, pdepth);
- link(h, new_node, commit_data.node, commit_data.link_left);
+ insert_commit(h, new_node, commit_data);
return new_node;
}
@@ -1060,10 +1076,72 @@ class tree_algorithms
{
insert_commit_data commit_data;
insert_equal_lower_bound_check(h, new_node, comp, commit_data, pdepth);
- link(h, new_node, commit_data.node, commit_data.link_left);
+ insert_commit(h, new_node, commit_data);
return new_node;
}
+ static node_ptr insert_before
+ (node_ptr header, node_ptr pos, node_ptr new_node, std::size_t *pdepth = 0)
+ {
+ insert_commit_data commit_data;
+ insert_before_check(header, pos, commit_data, pdepth);
+ insert_commit(header, new_node, commit_data);
+ return new_node;
+ }
+
+ static void insert_before_check
+ ( node_ptr header, node_ptr pos
+ , insert_commit_data &commit_data, std::size_t *pdepth = 0)
+ {
+ node_ptr prev(pos);
+ if(pos != NodeTraits::get_left(header))
+ prev = prev_node(pos);
+ bool link_left = unique(header) || !NodeTraits::get_left(pos);
+ commit_data.link_left = link_left;
+ commit_data.node = link_left ? pos : prev;
+ if(pdepth){
+ *pdepth = commit_data.node == header ? 0 : depth(commit_data.node) + 1;
+ }
+ }
+
+ static void push_back
+ (node_ptr header, node_ptr new_node, std::size_t *pdepth = 0)
+ {
+ insert_commit_data commit_data;
+ push_back_check(header, commit_data, pdepth);
+ insert_commit(header, new_node, commit_data);
+ }
+
+ static void push_back_check
+ (node_ptr header, insert_commit_data &commit_data, std::size_t *pdepth = 0)
+ {
+ node_ptr prev(NodeTraits::get_right(header));
+ if(pdepth){
+ *pdepth = prev == header ? 0 : depth(prev) + 1;
+ }
+ commit_data.link_left = false;
+ commit_data.node = prev;
+ }
+
+ static void push_front
+ (node_ptr header, node_ptr new_node, std::size_t *pdepth = 0)
+ {
+ insert_commit_data commit_data;
+ push_front_check(header, commit_data, pdepth);
+ insert_commit(header, new_node, commit_data);
+ }
+
+ static void push_front_check
+ (node_ptr header, insert_commit_data &commit_data, std::size_t *pdepth = 0)
+ {
+ node_ptr pos(NodeTraits::get_left(header));
+ if(pdepth){
+ *pdepth = pos == header ? 0 : depth(pos) + 1;
+ }
+ commit_data.link_left = true;
+ commit_data.node = pos;
+ }
+
//! Requires: p can't be a header node.
//!
//! Effects: Calculates the depth of a node: the depth of a
@@ -1303,32 +1381,10 @@ class tree_algorithms
replace_own_impl(p, x, header, p_old_parent, p_was_left);
}
- static void link(node_ptr header, node_ptr z, node_ptr par, bool left)
- {
- if(par == header){
- NodeTraits::set_parent(header, z);
- NodeTraits::set_right(header, z);
- NodeTraits::set_left(header, z);
- }
- else if(left){
- NodeTraits::set_left(par, z);
- if(par == NodeTraits::get_left(header))
- NodeTraits::set_left(header, z);
- }
- else{
- NodeTraits::set_right(par, z);
- if(par == NodeTraits::get_right(header))
- NodeTraits::set_right(header, z);
- }
- NodeTraits::set_parent(z, par);
- NodeTraits::set_right(z, node_ptr(0));
- NodeTraits::set_left(z, node_ptr(0));
- }
-
static void erase(node_ptr header, node_ptr z)
{
data_for_rebalance ignored;
- erase(header, z, nop_erase_fixup(), ignored);
+ erase_impl(header, z, ignored);
}
struct data_for_rebalance
@@ -1609,12 +1665,12 @@ class tree_algorithms
NodeTraits::set_parent(x, x_parent);
tree_algorithms::replace_own (z, x, header);
if(NodeTraits::get_left(header) == z){
- NodeTraits::set_left(header, NodeTraits::get_right(z) == 0 ? // z->get_left() must be null also
+ NodeTraits::set_left(header, !NodeTraits::get_right(z) ? // z->get_left() must be null also
NodeTraits::get_parent(z) : // makes leftmost == header if z == root
tree_algorithms::minimum (x));
}
if(NodeTraits::get_right(header) == z){
- NodeTraits::set_right(header, NodeTraits::get_left(z) == 0 ? // z->get_right() must be null also
+ NodeTraits::set_right(header, !NodeTraits::get_left(z) ? // z->get_right() must be null also
NodeTraits::get_parent(z) : // makes rightmost == header if z == root
tree_algorithms::maximum(x));
}
diff --git a/include/boost/intrusive/detail/tree_node.hpp b/include/boost/intrusive/detail/tree_node.hpp
index 146f758..3508e85 100644
--- a/include/boost/intrusive/detail/tree_node.hpp
+++ b/include/boost/intrusive/detail/tree_node.hpp
@@ -72,8 +72,12 @@ template
class tree_iterator
: public std::iterator
< std::bidirectional_iterator_tag
+ , typename Container::value_type
+ , typename std::iterator_traits::difference_type
, typename detail::add_const_if_c
- ::type
+ ::type *
+ , typename detail::add_const_if_c
+ ::type &
>
{
protected:
@@ -88,12 +92,11 @@ class tree_iterator
detail::store_cont_ptr_on_it::value;
public:
- public:
+ typedef typename Container::value_type value_type;
+ typedef typename detail::add_const_if_c
+ ::type *pointer;
typedef typename detail::add_const_if_c
-
- ::type value_type;
- typedef value_type & reference;
- typedef value_type * pointer;
+ ::type &reference;
tree_iterator()
: members_ (0, 0)
@@ -146,27 +149,17 @@ class tree_iterator
bool operator!= (const tree_iterator& i) const
{ return !operator== (i); }
- value_type& operator*() const
+ reference operator*() const
{ return *operator->(); }
pointer operator->() const
{ return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); }
const Container *get_container() const
- {
- if(store_container_ptr)
- return static_cast(members_.get_ptr());
- else
- return 0;
- }
+ { return static_cast(members_.get_ptr()); }
const real_value_traits *get_real_value_traits() const
- {
- if(store_container_ptr)
- return &this->get_container()->get_real_value_traits();
- else
- return 0;
- }
+ { return &this->get_container()->get_real_value_traits(); }
tree_iterator end_iterator_from_it() const
{
diff --git a/include/boost/intrusive/detail/utilities.hpp b/include/boost/intrusive/detail/utilities.hpp
index ab974ff..7846716 100644
--- a/include/boost/intrusive/detail/utilities.hpp
+++ b/include/boost/intrusive/detail/utilities.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -45,8 +46,7 @@ struct internal_base_hook_bool
template
struct two_or_three {one _[2 + Add];};
template static one test(...);
- template static two_or_three
- test (int);
+ template static two_or_three test (int);
static const std::size_t value = sizeof(test(0));
};
@@ -62,8 +62,7 @@ struct internal_any_hook_bool
template
struct two_or_three {one _[2 + Add];};
template static one test(...);
- template static two_or_three
- test (int);
+ template static two_or_three test (int);
static const std::size_t value = sizeof(test(0));
};
@@ -80,8 +79,7 @@ struct external_value_traits_bool
template
struct two_or_three {one _[2 + Add];};
template static one test(...);
- template static two_or_three
- test (int);
+ template static two_or_three test (int);
static const std::size_t value = sizeof(test(0));
};
@@ -91,8 +89,7 @@ struct external_bucket_traits_bool
template
struct two_or_three {one _[2 + Add];};
template static one test(...);
- template static two_or_three
- test (int);
+ template static two_or_three test (int);
static const std::size_t value = sizeof(test(0));
};
@@ -337,16 +334,6 @@ struct select_constptr
>::type type;
};
-template
-struct store_cont_ptr_on_it
-{
- typedef typename Container::value_traits value_traits;
- static const bool value =
- !detail::is_empty_class::value
- || detail::external_value_traits_is_true::value
- ;
-};
-
template
struct add_const_if_c
{
@@ -357,58 +344,6 @@ struct add_const_if_c
>::type type;
};
-template
-struct node_to_value
- : public detail::select_constptr
- < typename boost::pointer_to_other
- ::type
- , detail::store_cont_ptr_on_it::value
- >::type
-{
- static const bool store_container_ptr =
- detail::store_cont_ptr_on_it::value;
-
- typedef typename Container::real_value_traits real_value_traits;
- typedef typename real_value_traits::value_type value_type;
- typedef typename detail::select_constptr
- < typename boost::pointer_to_other
- ::type
- , store_container_ptr >::type Base;
- typedef typename real_value_traits::node_traits::node node;
- typedef typename detail::add_const_if_c
- ::type vtype;
- typedef typename detail::add_const_if_c
- ::type ntype;
- typedef typename boost::pointer_to_other
- ::type npointer;
-
- node_to_value(const Container *cont)
- : Base(cont)
- {}
-
- typedef vtype & result_type;
- typedef ntype & first_argument_type;
-
- const Container *get_container() const
- {
- if(store_container_ptr)
- return static_cast(Base::get_ptr());
- else
- return 0;
- }
-
- const real_value_traits *get_real_value_traits() const
- {
- if(store_container_ptr)
- return &this->get_container()->get_real_value_traits();
- else
- return 0;
- }
-
- result_type operator()(first_argument_type arg) const
- { return *(this->get_real_value_traits()->to_value_ptr(npointer(&arg))); }
-};
-
template
struct link_dispatch
{};
@@ -625,6 +560,79 @@ class exception_array_disposer
}
};
+template
+struct store_cont_ptr_on_it_impl
+{
+ static const bool value = is_stateful_value_traits::value;
+};
+
+template
+struct store_cont_ptr_on_it_impl
+{
+ static const bool value = false;
+};
+
+template
+struct store_cont_ptr_on_it
+{
+ typedef typename Container::value_traits value_traits;
+ static const bool value = store_cont_ptr_on_it_impl
+ ::value>::value;
+};
+
+template
+struct node_to_value
+ : public detail::select_constptr
+ < typename boost::pointer_to_other
+ ::type
+ , detail::store_cont_ptr_on_it::value
+ >::type
+{
+ static const bool store_container_ptr =
+ detail::store_cont_ptr_on_it::value;
+
+ typedef typename Container::real_value_traits real_value_traits;
+ typedef typename real_value_traits::value_type value_type;
+ typedef typename detail::select_constptr
+ < typename boost::pointer_to_other
+ ::type
+ , store_container_ptr >::type Base;
+ typedef typename real_value_traits::node_traits::node node;
+ typedef typename detail::add_const_if_c
+ ::type vtype;
+ typedef typename detail::add_const_if_c
+ ::type ntype;
+ typedef typename boost::pointer_to_other
+ ::type npointer;
+
+ node_to_value(const Container *cont)
+ : Base(cont)
+ {}
+
+ typedef vtype & result_type;
+ typedef ntype & first_argument_type;
+
+ const Container *get_container() const
+ {
+ if(store_container_ptr)
+ return static_cast(Base::get_ptr());
+ else
+ return 0;
+ }
+
+ const real_value_traits *get_real_value_traits() const
+ {
+ if(store_container_ptr)
+ return &this->get_container()->get_real_value_traits();
+ else
+ return 0;
+ }
+
+ result_type operator()(first_argument_type arg) const
+ { return *(this->get_real_value_traits()->to_value_ptr(npointer(&arg))); }
+};
+
+
} //namespace detail
} //namespace intrusive
} //namespace boost
diff --git a/include/boost/intrusive/detail/workaround.hpp b/include/boost/intrusive/detail/workaround.hpp
index a4c0974..dd70862 100644
--- a/include/boost/intrusive/detail/workaround.hpp
+++ b/include/boost/intrusive/detail/workaround.hpp
@@ -1,6 +1,6 @@
//////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost
+// (C) Copyright Ion Gaztanaga 2005-2009. 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)
//
diff --git a/include/boost/intrusive/hashtable.hpp b/include/boost/intrusive/hashtable.hpp
index 8f016f7..51cc6c1 100644
--- a/include/boost/intrusive/hashtable.hpp
+++ b/include/boost/intrusive/hashtable.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -186,8 +186,7 @@ struct store_hash_bool
template
struct two_or_three {one _[2 + Add];};
template static one test(...);
- template static two_or_three
- test (int);
+ template static two_or_three test (int);
static const std::size_t value = sizeof(test(0));
};
@@ -203,8 +202,7 @@ struct optimize_multikey_bool
template
struct two_or_three {one _[2 + Add];};
template static one test(...);
- template static two_or_three
- test (int);
+ template static two_or_three test (int);
static const std::size_t value = sizeof(test(0));
};
@@ -603,7 +601,7 @@ class hashtable_impl
typedef typename real_value_traits::pointer pointer;
typedef typename real_value_traits::const_pointer const_pointer;
- typedef typename std::iterator_traits::value_type value_type;
+ typedef typename real_value_traits::value_type value_type;
typedef typename std::iterator_traits::reference reference;
typedef typename std::iterator_traits::reference const_reference;
typedef typename std::iterator_traits::difference_type difference_type;
@@ -626,7 +624,7 @@ class hashtable_impl
::type const_node_ptr;
typedef typename slist_impl::node_algorithms node_algorithms;
- static const bool stateful_value_traits = detail::store_cont_ptr_on_it::value;
+ static const bool stateful_value_traits = detail::is_stateful_value_traits::value;
static const bool store_hash = detail::store_hash_is_true::value;
static const bool unique_keys = 0 != (Config::bool_flags & detail::hash_bool_flags::unique_keys_pos);
@@ -1231,8 +1229,8 @@ class hashtable_impl
//!
//! Note: Invalidates the iterators (but not the references)
//! to the erased element. No destructors are called.
- void erase(const_iterator i)
- { this->erase_and_dispose(i, detail::null_disposer()); }
+ iterator erase(const_iterator i)
+ { return this->erase_and_dispose(i, detail::null_disposer()); }
//! Effects: Erases the range pointed to by b end e.
//!
@@ -1243,8 +1241,8 @@ class hashtable_impl
//!
//! Note: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
- void erase(const_iterator b, const_iterator e)
- { this->erase_and_dispose(b, e, detail::null_disposer()); }
+ iterator erase(const_iterator b, const_iterator e)
+ { return this->erase_and_dispose(b, e, detail::null_disposer()); }
//! Effects: Erases all the elements with the given value.
//!
@@ -1297,19 +1295,20 @@ class hashtable_impl
//! Note: Invalidates the iterators
//! to the erased elements.
template
- void erase_and_dispose(const_iterator i, Disposer disposer)
+ iterator erase_and_dispose(const_iterator i, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c::value >::type * = 0
+ /// @endcond
+ )
{
+ iterator ret(i.unconst());
+ ++ret;
priv_erase(i, disposer, optimize_multikey_t());
this->priv_size_traits().decrement();
priv_erasure_update_cache();
+ return ret;
}
- #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
- template
- iterator erase_and_dispose(iterator i, Disposer disposer)
- { return this->erase_and_dispose(const_iterator(i), disposer); }
- #endif
-
//! Requires: Disposer::operator()(pointer) shouldn't throw.
//!
//! Effects: Erases the range pointed to by b end e.
@@ -1323,31 +1322,32 @@ class hashtable_impl
//! Note: Invalidates the iterators
//! to the erased elements.
template
- void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
+ iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
{
- if(b == e) return;
+ if(b != e){
+ //Get the bucket number and local iterator for both iterators
+ siterator first_local_it(b.slist_it());
+ size_type first_bucket_num = this->priv_get_bucket_num(first_local_it);
- //Get the bucket number and local iterator for both iterators
- siterator first_local_it(b.slist_it());
- size_type first_bucket_num = this->priv_get_bucket_num(first_local_it);
+ siterator before_first_local_it
+ = priv_get_previous(priv_buckets()[first_bucket_num], first_local_it);
+ size_type last_bucket_num;
+ siterator last_local_it;
- siterator before_first_local_it
- = priv_get_previous(priv_buckets()[first_bucket_num], first_local_it);
- size_type last_bucket_num;
- siterator last_local_it;
-
- //For the end iterator, we will assign the end iterator
- //of the last bucket
- if(e == this->end()){
- last_bucket_num = this->bucket_count() - 1;
- last_local_it = priv_buckets()[last_bucket_num].end();
+ //For the end iterator, we will assign the end iterator
+ //of the last bucket
+ if(e == this->end()){
+ last_bucket_num = this->bucket_count() - 1;
+ last_local_it = priv_buckets()[last_bucket_num].end();
+ }
+ else{
+ last_local_it = e.slist_it();
+ last_bucket_num = this->priv_get_bucket_num(last_local_it);
+ }
+ priv_erase_range(before_first_local_it, first_bucket_num, last_local_it, last_bucket_num, disposer);
+ priv_erasure_update_cache(first_bucket_num, last_bucket_num);
}
- else{
- last_local_it = e.slist_it();
- last_bucket_num = this->priv_get_bucket_num(last_local_it);
- }
- priv_erase_range(before_first_local_it, first_bucket_num, last_local_it, last_bucket_num, disposer);
- priv_erasure_update_cache(first_bucket_num, last_bucket_num);
+ return e.unconst();
}
//! Requires: Disposer::operator()(pointer) shouldn't throw.
diff --git a/include/boost/intrusive/intrusive_fwd.hpp b/include/boost/intrusive/intrusive_fwd.hpp
index 5b1e451..7c9b2a1 100644
--- a/include/boost/intrusive/intrusive_fwd.hpp
+++ b/include/boost/intrusive/intrusive_fwd.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/intrusive/linear_slist_algorithms.hpp b/include/boost/intrusive/linear_slist_algorithms.hpp
index 9d045a5..193b449 100644
--- a/include/boost/intrusive/linear_slist_algorithms.hpp
+++ b/include/boost/intrusive/linear_slist_algorithms.hpp
@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -156,7 +156,7 @@ class linear_slist_algorithms
//! Effects: Returns the number of nodes in a linear list. If the linear list
//! is empty, returns 1.
//!
- //! Complexity: Constant
+ //! Complexity: Linear
//!
//! Throws: Nothing.
static std::size_t count(const_node_ptr this_node)
diff --git a/include/boost/intrusive/link_mode.hpp b/include/boost/intrusive/link_mode.hpp
index 16b9649..17012c9 100644
--- a/include/boost/intrusive/link_mode.hpp
+++ b/include/boost/intrusive/link_mode.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/intrusive/list.hpp b/include/boost/intrusive/list.hpp
index d38d960..2cf3fed 100644
--- a/include/boost/intrusive/list.hpp
+++ b/include/boost/intrusive/list.hpp
@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -106,7 +106,8 @@ class list_impl
typedef circular_list_algorithms node_algorithms;
static const bool constant_time_size = Config::constant_time_size;
- static const bool stateful_value_traits = detail::store_cont_ptr_on_it::value;
+ static const bool stateful_value_traits = detail::is_stateful_value_traits::value;
+ BOOST_STATIC_ASSERT(( stateful_value_traits == false ));
/// @cond
diff --git a/include/boost/intrusive/list_hook.hpp b/include/boost/intrusive/list_hook.hpp
index 2deceb0..ed93434 100644
--- a/include/boost/intrusive/list_hook.hpp
+++ b/include/boost/intrusive/list_hook.hpp
@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -93,6 +93,7 @@ class list_base_hook
::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
//! Effects: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
@@ -214,6 +215,7 @@ class list_member_hook
::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
//! Effects: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
diff --git a/include/boost/intrusive/member_value_traits.hpp b/include/boost/intrusive/member_value_traits.hpp
index 372334c..ce7e56b 100644
--- a/include/boost/intrusive/member_value_traits.hpp
+++ b/include/boost/intrusive/member_value_traits.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/intrusive/options.hpp b/include/boost/intrusive/options.hpp
index 8ab0890..d692b1e 100644
--- a/include/boost/intrusive/options.hpp
+++ b/include/boost/intrusive/options.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/intrusive/pointer_plus_bits.hpp b/include/boost/intrusive/pointer_plus_bits.hpp
index b2b51e8..10b2fe0 100644
--- a/include/boost/intrusive/pointer_plus_bits.hpp
+++ b/include/boost/intrusive/pointer_plus_bits.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -50,7 +50,7 @@ template
struct pointer_plus_bits;
//!This is the specialization to embed extra bits of information
-//!in a raw pointer. The extra bits are stored in the lower bit of the pointer.
+//!in a raw pointer. The extra bits are stored in the lower bits of the pointer.
template
struct pointer_plus_bits
{
diff --git a/include/boost/intrusive/priority_compare.hpp b/include/boost/intrusive/priority_compare.hpp
index 9689851..abde27a 100644
--- a/include/boost/intrusive/priority_compare.hpp
+++ b/include/boost/intrusive/priority_compare.hpp
@@ -23,7 +23,7 @@ namespace intrusive {
template
struct priority_compare
- : public std::binary_function
+ : public std::binary_function
{
bool operator()(const T &val, const T &val2) const
{
diff --git a/include/boost/intrusive/rbtree.hpp b/include/boost/intrusive/rbtree.hpp
index 572b545..8d9cacf 100644
--- a/include/boost/intrusive/rbtree.hpp
+++ b/include/boost/intrusive/rbtree.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -29,6 +29,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -116,8 +117,7 @@ class rbtree_impl
typedef rbtree_algorithms node_algorithms;
static const bool constant_time_size = Config::constant_time_size;
- static const bool stateful_value_traits = detail::store_cont_ptr_on_it::value;
-
+ static const bool stateful_value_traits = detail::is_stateful_value_traits::value;
/// @cond
private:
typedef detail::size_holder size_traits;
@@ -704,6 +704,76 @@ class rbtree_impl
return iterator(to_insert, this);
}
+ //! Requires: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate
+ //!
+ //! Effects: Inserts x into the tree before "pos".
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" tree ordering invariant will be broken.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ return iterator(node_algorithms::insert_before
+ (node_ptr(&priv_header()), pos.pointed_node(), to_insert), this);
+ }
+
+ //! Requires: value must be an lvalue, and it must be no less
+ //! than the greatest inserted key
+ //!
+ //! Effects: Inserts x into the tree in the last position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! less than the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ node_algorithms::push_back(node_ptr(&priv_header()), to_insert);
+ }
+
+ //! Requires: value must be an lvalue, and it must be no greater
+ //! than the minimum inserted key
+ //!
+ //! Effects: Inserts x into the tree in the first position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! greater than the minimum inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ node_algorithms::push_front(node_ptr(&priv_header()), to_insert);
+ }
+
//! Effects: Erases the element pointed to by pos.
//!
//! Complexity: Average complexity for erase element is constant time.
diff --git a/include/boost/intrusive/rbtree_algorithms.hpp b/include/boost/intrusive/rbtree_algorithms.hpp
index 37140a3..ca6f7eb 100644
--- a/include/boost/intrusive/rbtree_algorithms.hpp
+++ b/include/boost/intrusive/rbtree_algorithms.hpp
@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008.
+// (C) Copyright Ion Gaztanaga 2006-2009.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -585,6 +585,66 @@ class rbtree_algorithms
return new_node;
}
+ //! Requires: "header" must be the header node of a tree.
+ //! "pos" must be a valid iterator or header (end) node.
+ //! "pos" must be an iterator pointing to the successor to "new_node"
+ //! once inserted according to the order of already inserted nodes. This function does not
+ //! check "pos" and this precondition must be guaranteed by the caller.
+ //!
+ //! Effects: Inserts new_node into the tree before "pos".
+ //!
+ //! Complexity: Constant-time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: If "pos" is not the successor of the newly inserted "new_node"
+ //! tree invariants might be broken.
+ static node_ptr insert_before
+ (node_ptr header, node_ptr pos, node_ptr new_node)
+ {
+ tree_algorithms::insert_before(header, pos, new_node);
+ rebalance_after_insertion(header, new_node);
+ return new_node;
+ }
+
+ //! Requires: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering no less than the
+ //! greatest inserted key.
+ //!
+ //! Effects: Inserts new_node into the tree before "pos".
+ //!
+ //! Complexity: Constant-time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: If "new_node" is less than the greatest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ static void push_back(node_ptr header, node_ptr new_node)
+ {
+ tree_algorithms::push_back(header, new_node);
+ rebalance_after_insertion(header, new_node);
+ }
+
+ //! Requires: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering, no greater than the
+ //! lowest inserted key.
+ //!
+ //! Effects: Inserts new_node into the tree before "pos".
+ //!
+ //! Complexity: Constant-time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: If "new_node" is greater than the lowest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ static void push_front(node_ptr header, node_ptr new_node)
+ {
+ tree_algorithms::push_front(header, new_node);
+ rebalance_after_insertion(header, new_node);
+ }
+
//! Requires: "header" must be the header node of a tree.
//! KeyNodePtrCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the
diff --git a/include/boost/intrusive/set.hpp b/include/boost/intrusive/set.hpp
index 40d7c6b..54c5a65 100644
--- a/include/boost/intrusive/set.hpp
+++ b/include/boost/intrusive/set.hpp
@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -490,6 +490,60 @@ class set_impl
void insert(Iterator b, Iterator e)
{ tree_.insert_unique(b, e); }
+ //! Requires: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate. "value" must not be equal to any
+ //! inserted key according to the predicate.
+ //!
+ //! Effects: Inserts x into the tree before "pos".
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" or "value" is not unique tree ordering and uniqueness
+ //! invariants will be broken respectively.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ { return tree_.insert_before(pos, value); }
+
+ //! Requires: value must be an lvalue, and it must be greater than
+ //! any inserted key according to the predicate.
+ //!
+ //! Effects: Inserts x into the tree in the last position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! less than or equal to the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ { tree_.push_back(value); }
+
+ //! Requires: value must be an lvalue, and it must be less
+ //! than any inserted key according to the predicate.
+ //!
+ //! Effects: Inserts x into the tree in the first position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! greater than or equal to the the mimum inserted key tree ordering or uniqueness
+ //! invariants will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ { tree_.push_front(value); }
+
//! Effects: Erases the element pointed to by pos.
//!
//! Complexity: Average complexity is constant time.
@@ -1533,6 +1587,57 @@ class multiset_impl
void insert(Iterator b, Iterator e)
{ tree_.insert_equal(b, e); }
+ //! Requires: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate
+ //!
+ //! Effects: Inserts x into the tree before "pos".
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" tree ordering invariant will be broken.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ { return tree_.insert_before(pos, value); }
+
+ //! Requires: value must be an lvalue, and it must be no less
+ //! than the greatest inserted key
+ //!
+ //! Effects: Inserts x into the tree in the last position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! less than the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ { tree_.push_back(value); }
+
+ //! Requires: value must be an lvalue, and it must be no greater
+ //! than the minimum inserted key
+ //!
+ //! Effects: Inserts x into the tree in the first position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! greater than the minimum inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ { tree_.push_front(value); }
+
//! Effects: Erases the element pointed to by pos.
//!
//! Complexity: Average complexity is constant time.
diff --git a/include/boost/intrusive/set_hook.hpp b/include/boost/intrusive/set_hook.hpp
index 1420480..35746a2 100644
--- a/include/boost/intrusive/set_hook.hpp
+++ b/include/boost/intrusive/set_hook.hpp
@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -98,6 +98,7 @@ class set_base_hook
>::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
//! Effects: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
@@ -224,6 +225,7 @@ class set_member_hook
>::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
//! Effects: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
diff --git a/include/boost/intrusive/sg_set.hpp b/include/boost/intrusive/sg_set.hpp
index 4c519c1..3a7c77a 100644
--- a/include/boost/intrusive/sg_set.hpp
+++ b/include/boost/intrusive/sg_set.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -381,7 +381,7 @@ class sg_set_impl
//! Requires: key_value_comp must be a comparison function that induces
//! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an ascapegoatitrary key with the contained values.
+ //! key_value_comp compares an arbitrary key with the contained values.
//!
//! Effects: Checks if a value can be inserted in the sg_set, using
//! a user provided key instead of the value itself.
@@ -416,7 +416,7 @@ class sg_set_impl
//! Requires: key_value_comp must be a comparison function that induces
//! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an ascapegoatitrary key with the contained values.
+ //! key_value_comp compares an arbitrary key with the contained values.
//!
//! Effects: Checks if a value can be inserted in the sg_set, using
//! a user provided key instead of the value itself, using "hint"
@@ -489,6 +489,60 @@ class sg_set_impl
void insert(Iterator b, Iterator e)
{ tree_.insert_unique(b, e); }
+ //! Requires: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate. "value" must not be equal to any
+ //! inserted key according to the predicate.
+ //!
+ //! Effects: Inserts x into the tree before "pos".
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" or "value" is not unique tree ordering and uniqueness
+ //! invariants will be broken respectively.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ { return tree_.insert_before(pos, value); }
+
+ //! Requires: value must be an lvalue, and it must be greater than
+ //! any inserted key according to the predicate.
+ //!
+ //! Effects: Inserts x into the tree in the last position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! less than or equal to the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ { tree_.push_back(value); }
+
+ //! Requires: value must be an lvalue, and it must be less
+ //! than any inserted key according to the predicate.
+ //!
+ //! Effects: Inserts x into the tree in the first position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! greater than or equal to the the mimum inserted key tree ordering or uniqueness
+ //! invariants will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ { tree_.push_front(value); }
+
//! Effects: Erases the element pointed to by pos.
//!
//! Complexity: Average complexity is constant time.
@@ -1572,6 +1626,57 @@ class sg_multiset_impl
void insert(Iterator b, Iterator e)
{ tree_.insert_equal(b, e); }
+ //! Requires: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate
+ //!
+ //! Effects: Inserts x into the tree before "pos".
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" tree ordering invariant will be broken.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ { return tree_.insert_before(pos, value); }
+
+ //! Requires: value must be an lvalue, and it must be no less
+ //! than the greatest inserted key
+ //!
+ //! Effects: Inserts x into the tree in the last position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! less than the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ { tree_.push_back(value); }
+
+ //! Requires: value must be an lvalue, and it must be no greater
+ //! than the minimum inserted key
+ //!
+ //! Effects: Inserts x into the tree in the first position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! greater than the minimum inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ { tree_.push_front(value); }
+
//! Effects: Erases the element pointed to by pos.
//!
//! Complexity: Average complexity is constant time.
diff --git a/include/boost/intrusive/sgtree.hpp b/include/boost/intrusive/sgtree.hpp
index 0d19919..5507893 100644
--- a/include/boost/intrusive/sgtree.hpp
+++ b/include/boost/intrusive/sgtree.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -244,7 +244,7 @@ class sgtree_impl
static const bool floating_point = Config::floating_point;
static const bool constant_time_size = true;
- static const bool stateful_value_traits = detail::store_cont_ptr_on_it::value;
+ static const bool stateful_value_traits = detail::is_stateful_value_traits::value;
/// @cond
private:
@@ -871,6 +871,88 @@ class sgtree_impl
return iterator(to_insert, this);
}
+ //! Requires: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate
+ //!
+ //! Effects: Inserts x into the tree before "pos".
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" tree ordering invariant will be broken.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
+ node_ptr p = node_algorithms::insert_before
+ ( node_ptr(&priv_header()), pos.pointed_node(), to_insert
+ , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
+ data_.max_tree_size_ = (size_type)max_tree_size;
+ return iterator(p, this);
+ }
+
+ //! Requires: value must be an lvalue, and it must be no less
+ //! than the greatest inserted key
+ //!
+ //! Effects: Inserts x into the tree in the last position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! less than the greatest inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
+ node_algorithms::push_back
+ ( node_ptr(&priv_header()), to_insert
+ , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
+ data_.max_tree_size_ = (size_type)max_tree_size;
+ }
+
+ //! Requires: value must be an lvalue, and it must be no greater
+ //! than the minimum inserted key
+ //!
+ //! Effects: Inserts x into the tree in the first position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! greater than the minimum inserted key tree ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
+ node_algorithms::push_front
+ ( node_ptr(&priv_header()), to_insert
+ , (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
+ data_.max_tree_size_ = (size_type)max_tree_size;
+ }
+
//! Effects: Erases the element pointed to by pos.
//!
//! Complexity: Average complexity for erase element is constant time.
@@ -1071,7 +1153,6 @@ class sgtree_impl
{
node_algorithms::clear_and_dispose(node_ptr(&priv_header())
, detail::node_disposer(disposer, this));
- node_algorithms::init_header(&priv_header());
this->priv_size_traits().set_size(0);
}
diff --git a/include/boost/intrusive/sgtree_algorithms.hpp b/include/boost/intrusive/sgtree_algorithms.hpp
index c9af84f..bb6ef06 100644
--- a/include/boost/intrusive/sgtree_algorithms.hpp
+++ b/include/boost/intrusive/sgtree_algorithms.hpp
@@ -539,6 +539,76 @@ class sgtree_algorithms
return ret;
}
+
+ //! Requires: "header" must be the header node of a tree.
+ //! "pos" must be a valid iterator or header (end) node.
+ //! "pos" must be an iterator pointing to the successor to "new_node"
+ //! once inserted according to the order of already inserted nodes. This function does not
+ //! check "pos" and this precondition must be guaranteed by the caller.
+ //!
+ //! Effects: Inserts new_node into the tree before "pos".
+ //!
+ //! Complexity: Constant-time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: If "pos" is not the successor of the newly inserted "new_node"
+ //! tree invariants might be broken.
+ template
+ static node_ptr insert_before
+ (node_ptr header, node_ptr pos, node_ptr new_node
+ ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
+ {
+ std::size_t depth;
+ tree_algorithms::insert_before(header, pos, new_node, &depth);
+ rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
+ return new_node;
+ }
+
+ //! Requires: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering no less than the
+ //! greatest inserted key.
+ //!
+ //! Effects: Inserts new_node into the tree before "pos".
+ //!
+ //! Complexity: Constant-time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: If "new_node" is less than the greatest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ template
+ static void push_back(node_ptr header, node_ptr new_node
+ ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
+ {
+ std::size_t depth;
+ tree_algorithms::push_back(header, new_node, &depth);
+ rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
+ }
+
+ //! Requires: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering, no greater than the
+ //! lowest inserted key.
+ //!
+ //! Effects: Inserts new_node into the tree before "pos".
+ //!
+ //! Complexity: Constant-time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: If "new_node" is greater than the lowest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ template
+ static void push_front(node_ptr header, node_ptr new_node
+ ,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
+ {
+ std::size_t depth;
+ tree_algorithms::push_front(header, new_node, &depth);
+ rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
+ }
+
//! Requires: "header" must be the header node of a tree.
//! KeyNodePtrCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the
diff --git a/include/boost/intrusive/slist.hpp b/include/boost/intrusive/slist.hpp
index e430fb1..8314a75 100644
--- a/include/boost/intrusive/slist.hpp
+++ b/include/boost/intrusive/slist.hpp
@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -140,7 +140,7 @@ class slist_impl
>::type node_algorithms;
static const bool constant_time_size = Config::constant_time_size;
- static const bool stateful_value_traits = detail::store_cont_ptr_on_it::value;
+ static const bool stateful_value_traits = detail::is_stateful_value_traits::value;
static const bool linear = Config::linear;
static const bool cache_last = Config::cache_last;
@@ -539,6 +539,36 @@ class slist_impl
const_iterator cbefore_begin() const
{ return this->before_begin(); }
+ //! Effects: Returns an iterator to the last element contained in the list.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Complexity: Constant.
+ //!
+ //! Note: This function is present only if cached_last<> option is true.
+ iterator last()
+ { return iterator (this->get_last_node(), this); }
+
+ //! Effects: Returns a const_iterator to the first element contained in the list.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Complexity: Constant.
+ //!
+ //! Note: This function is present only if cached_last<> option is true.
+ const_iterator last() const
+ { return const_iterator (this->get_last_node(), this); }
+
+ //! Effects: Returns a const_iterator to the first element contained in the list.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Complexity: Constant.
+ //!
+ //! Note: This function is present only if cached_last<> option is true.
+ const_iterator clast() const
+ { return const_iterator(this->get_last_node(), this); }
+
//! Precondition: end_iterator must be a valid end iterator
//! of slist.
//!
@@ -1058,20 +1088,31 @@ class slist_impl
//! Effects: Transfers all the elements of list x to this list, after the
//! the element pointed by prev. No destructors or copy constructors are called.
//!
- //! Returns: The last element inserted of x or prev if x is empty.
- //! This iterator can be used as new "prev" iterator for a new splice_after call.
- //! that will splice new values after the previously spliced values.
+ //! Returns: Nothing.
//!
//! Throws: Nothing.
//!
- //! Complexity: Linear to the elements contained in x.
- //! Constant-time if cache_last<> option is true.
+ //! Complexity: In general, linear to the elements contained in x.
+ //! Constant-time if cache_last<> option is true and also constant-time if
+ //! linear<> option is true "this" is empty and "last" is not used.
//!
//! Note: 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.
- iterator splice_after(const_iterator prev, slist_impl &x)
+ //!
+ //! Additional note: If the optional parameter "last" is provided, it will be
+ //! assigned to the last spliced element or prev if x is empty.
+ //! This iterator can be used as new "prev" iterator for a new splice_after call.
+ //! that will splice new values after the previously spliced values.
+ void splice_after(const_iterator prev, slist_impl &x, const_iterator *last = 0)
{
- if (!x.empty()){
+ if(x.empty()){
+ if(last) *last = prev;
+ }
+ else if(linear && this->empty()){
+ this->swap(x);
+ if(last) *last = this->previous(this->cend());
+ }
+ else{
const_iterator last_x(x.previous(x.end())); //<- constant time if cache_last is active
node_ptr prev_n(prev.pointed_node());
node_ptr last_x_n(last_x.pointed_node());
@@ -1084,10 +1125,7 @@ class slist_impl
node_algorithms::transfer_after( prev_n, x.before_begin().pointed_node(), last_x_n);
this->priv_size_traits().set_size(this->priv_size_traits().get_size() + x.priv_size_traits().get_size());
x.priv_size_traits().set_size(size_type(0));
- return last_x.unconst();
- }
- else{
- return prev.unconst();
+ if(last) *last = last_x;
}
}
@@ -1166,10 +1204,7 @@ class slist_impl
//! Effects: Transfers all the elements of list x to this list, before the
//! the element pointed by it. No destructors or copy constructors are called.
//!
- //! Returns: The last element inserted of x or the previous element
- //! of it if x is empty.
- //! This iterator can be used as new "prev" iterator for a new splice call.
- //! that will splice new values after the previously spliced values.
+ //! Returns: Nothing.
//!
//! Throws: Nothing.
//!
@@ -1180,8 +1215,13 @@ class slist_impl
//!
//! Note: 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.
- iterator splice(const_iterator it, slist_impl &x)
- { return this->splice_after(this->previous(it), x); }
+ //!
+ //! Additional note: If the optional parameter "last" is provided, it will be
+ //! assigned to the last spliced element or prev if x is empty.
+ //! This iterator can be used as new "prev" iterator for a new splice_after call.
+ //! that will splice new values after the previously spliced values.
+ void splice(const_iterator it, slist_impl &x, iterator *last = 0)
+ { this->splice_after(this->previous(it), x, last); }
//! Requires: it p must be a valid iterator of *this.
//! elem must point to an element contained in list
@@ -1254,7 +1294,7 @@ class slist_impl
void sort(Predicate p)
{
if (node_traits::get_next(node_traits::get_next(this->get_root_node()))
- != this->get_root_node()) {
+ != this->get_root_node()) {
slist_impl carry;
slist_impl counter[64];
int fill = 0;
@@ -1265,33 +1305,28 @@ class slist_impl
int i = 0;
while(i < fill && !counter[i].empty()) {
carry.swap(counter[i]);
- last_inserted = carry.merge(counter[i++], p);
+ carry.merge(counter[i++], p, &last_inserted);
}
BOOST_INTRUSIVE_INVARIANT_ASSERT(counter[i].empty());
+ const_iterator last_element(carry.previous(last_inserted, carry.end()));
- node_ptr p = node_algorithms::get_previous_node
- (last_inserted.pointed_node(), carry.cend().pointed_node());
- const_iterator last_element(p, this);
if(constant_time_size){
counter[i].splice_after( counter[i].cbefore_begin(), carry
- , carry.cbefore_begin(), last_element
- , carry.size());
+ , carry.cbefore_begin(), last_element
+ , carry.size());
}
else{
counter[i].splice_after( counter[i].cbefore_begin(), carry
- , carry.cbefore_begin(), last_element);
+ , carry.cbefore_begin(), last_element);
}
if(i == fill)
++fill;
}
for (int i = 1; i < fill; ++i)
- last_inserted = counter[i].merge(counter[i-1], p);
- BOOST_INTRUSIVE_INVARIANT_ASSERT(this->empty());
-
- node_ptr p = node_algorithms::get_previous_node
- (last_inserted.pointed_node(), counter[--fill].end().pointed_node());
- const_iterator last_element(p, this);
+ counter[i].merge(counter[i-1], p, &last_inserted);
+ --fill;
+ const_iterator last_element(counter[fill].previous(last_inserted, counter[fill].end()));
if(constant_time_size){
this->splice_after( cbefore_begin(), counter[fill], counter[fill].cbefore_begin()
, last_element, counter[fill].size());
@@ -1330,7 +1365,7 @@ class slist_impl
//! in order into *this. The merge is stable; that is, if an element from *this is
//! equivalent to one from x, then the element from *this will precede the one from x.
//!
- //! Returns: An iterator to the last transferred value, end() is x is empty.
+ //! Returns: Nothing.
//!
//! Throws: If the predicate throws. Basic guarantee.
//!
@@ -1338,11 +1373,15 @@ class slist_impl
//! size() + x.size() - 1 comparisons.
//!
//! Note: Iterators and references are not invalidated.
+ //!
+ //! Additional note: If optional "last" argument is passed, it is assigned
+ //! to an iterator to the last transferred value or end() is x is empty.
template
- iterator merge(slist_impl& x, Predicate p)
+ void merge(slist_impl& x, Predicate p, const_iterator *last = 0)
{
const_iterator e(this->cend()), ex(x.cend()), bb(this->cbefore_begin()),
- bb_next, last_inserted(e);
+ bb_next;
+ if(last) *last = e.unconst();
while(!x.empty()){
const_iterator ibx_next(x.cbefore_begin()), ibx(ibx_next++);
while (++(bb_next = bb) != e && !p(*ibx_next, *bb_next)){
@@ -1350,7 +1389,7 @@ class slist_impl
}
if(bb_next == e){
//Now transfer the rest to the end of the container
- last_inserted = this->splice_after(bb, x);
+ this->splice_after(bb, x, last);
break;
}
else{
@@ -1359,10 +1398,9 @@ class slist_impl
ibx = ibx_next; ++n;
} while(++(ibx_next = ibx) != ex && p(*ibx_next, *bb_next));
this->splice_after(bb, x, x.before_begin(), ibx, n);
- last_inserted = ibx;
+ if(last) *last = ibx;
}
}
- return last_inserted.unconst();
}
//! Effects: This function removes all of x's elements and inserts them
@@ -1618,14 +1656,7 @@ class slist_impl
//! Complexity: Linear to the number of elements before i.
//! Constant if cache_last<> is true and i == end().
iterator previous(iterator i)
- {
- if(cache_last && (i.pointed_node() == this->get_end_node())){
- return iterator(this->get_last_node(), this);
- }
- return iterator
- (node_algorithms::get_previous_node
- (this->before_begin().pointed_node(), i.pointed_node()), this);
- }
+ { return this->previous(this->cbefore_begin(), i); }
//! Returns: The const_iterator to the element before i in the list.
//! Returns the end-const_iterator, if either i is the begin-const_iterator or
@@ -1636,13 +1667,86 @@ class slist_impl
//! Complexity: Linear to the number of elements before i.
//! Constant if cache_last<> is true and i == end().
const_iterator previous(const_iterator i) const
+ { return this->previous(this->cbefore_begin(), i); }
+
+ //! Returns: The iterator to the element before i in the list,
+ //! starting the search on element after prev_from.
+ //! Returns the end-iterator, if either i is the begin-iterator or the
+ //! list is empty.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Complexity: Linear to the number of elements before i.
+ //! Constant if cache_last<> is true and i == end().
+ iterator previous(const_iterator prev_from, iterator i)
+ { return this->previous(prev_from, const_iterator(i)).unconst(); }
+
+ //! Returns: The const_iterator to the element before i in the list,
+ //! starting the search on element after prev_from.
+ //! Returns the end-const_iterator, if either i is the begin-const_iterator or
+ //! the list is empty.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Complexity: Linear to the number of elements before i.
+ //! Constant if cache_last<> is true and i == end().
+ const_iterator previous(const_iterator prev_from, const_iterator i) const
{
if(cache_last && (i.pointed_node() == this->get_end_node())){
return const_iterator(uncast(this->get_last_node()), this);
}
return const_iterator
(node_algorithms::get_previous_node
- (this->before_begin().pointed_node(), i.pointed_node()), this);
+ (prev_from.pointed_node(), i.pointed_node()), this);
+ }
+
+ //! Requires: prev_pos must be a dereferenceable iterator in *this or be
+ //! before_begin(), and before_first and before_last belong to x and
+ //! ++before_first != x.end() && before_last != x.end().
+ //!
+ //! Effects: Transfers the range (before_first, before_last] to this
+ //! list, after the element pointed by prev_pos.
+ //! No destructors or copy constructors are called.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Complexity: Linear to the number of elements transferred
+ //! if constant_time_size is true. Constant-time otherwise.
+ //!
+ //! Note: 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 incorporate_after(const_iterator prev_from, node_ptr first, node_ptr before_last)
+ {
+ if(constant_time_size)
+ this->incorporate_after(prev_from, first, before_last, std::distance(first, before_last)+1);
+ else
+ this->priv_incorporate_after
+ (prev_from.pointed_node(), first, before_last);
+ }
+
+ //! Requires: prev_pos must be a dereferenceable iterator in *this or be
+ //! before_begin(), and before_first and before_last belong to x and
+ //! ++before_first != x.end() && before_last != x.end() and
+ //! n == std::distance(first, before_last) + 1.
+ //!
+ //! Effects: Transfers the range (before_first, before_last] from list x to this
+ //! list, after the element pointed by p. No destructors or copy constructors are called.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Note: 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 incorporate_after(const_iterator prev_pos, node_ptr first, node_ptr before_last, difference_type n)
+ {
+ if(n){
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(iterator(first, this), iterator(before_last, this))+1 == n);
+ this->priv_incorporate_after(prev_pos.pointed_node(), first, before_last);
+ if(constant_time_size){
+ this->priv_size_traits().set_size(this->priv_size_traits().get_size() + n);
+ }
+ }
}
private:
@@ -1662,6 +1766,16 @@ class slist_impl
}
}
+ void priv_incorporate_after(node_ptr prev_pos_n, node_ptr first_n, node_ptr before_last_n)
+ {
+ if(cache_last){
+ if(node_traits::get_next(prev_pos_n) == this->get_end_node()){
+ this->set_last_node(before_last_n);
+ }
+ }
+ node_algorithms::incorporate_after(prev_pos_n, first_n, before_last_n);
+ }
+
void priv_reverse(detail::bool_)
{ node_algorithms::reverse(this->get_root_node()); }
diff --git a/include/boost/intrusive/slist_hook.hpp b/include/boost/intrusive/slist_hook.hpp
index 7779b98..1debe66 100644
--- a/include/boost/intrusive/slist_hook.hpp
+++ b/include/boost/intrusive/slist_hook.hpp
@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -96,6 +96,7 @@ class slist_base_hook
>::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
//! Effects: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
@@ -218,6 +219,7 @@ class slist_member_hook
>::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
//! Effects: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
diff --git a/include/boost/intrusive/splay_set.hpp b/include/boost/intrusive/splay_set.hpp
index 79bdbc1..9727d14 100644
--- a/include/boost/intrusive/splay_set.hpp
+++ b/include/boost/intrusive/splay_set.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -624,7 +624,7 @@ class splay_set_impl
/// @cond
, typename detail::enable_if_c::value >::type * = 0
/// @endcond
-)
+ )
{ return tree_.erase_and_dispose(key, comp, disposer); }
//! Effects: Erases all the elements of the container.
diff --git a/include/boost/intrusive/splay_set_hook.hpp b/include/boost/intrusive/splay_set_hook.hpp
index 472fde3..d42f4c8 100644
--- a/include/boost/intrusive/splay_set_hook.hpp
+++ b/include/boost/intrusive/splay_set_hook.hpp
@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -93,6 +93,7 @@ class splay_set_base_hook
>::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
//! Effects: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
@@ -216,6 +217,7 @@ class splay_set_member_hook
>::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
//! Effects: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
diff --git a/include/boost/intrusive/splaytree.hpp b/include/boost/intrusive/splaytree.hpp
index 971f846..4020c85 100644
--- a/include/boost/intrusive/splaytree.hpp
+++ b/include/boost/intrusive/splaytree.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -115,7 +115,7 @@ class splaytree_impl
typedef splaytree_algorithms node_algorithms;
static const bool constant_time_size = Config::constant_time_size;
- static const bool stateful_value_traits = detail::store_cont_ptr_on_it::value;
+ static const bool stateful_value_traits = detail::is_stateful_value_traits::value;
/// @cond
private:
@@ -895,7 +895,6 @@ class splaytree_impl
{
node_algorithms::clear_and_dispose(node_ptr(&priv_header())
, detail::node_disposer(disposer, this));
- node_algorithms::init_header(&priv_header());
this->priv_size_traits().set_size(0);
}
diff --git a/include/boost/intrusive/splaytree_algorithms.hpp b/include/boost/intrusive/splaytree_algorithms.hpp
index e727ab6..eb25e9f 100644
--- a/include/boost/intrusive/splaytree_algorithms.hpp
+++ b/include/boost/intrusive/splaytree_algorithms.hpp
@@ -543,6 +543,79 @@ class splaytree_algorithms
return tree_algorithms::insert_equal(header, hint, new_node, comp);
}
+
+ //! Requires: "header" must be the header node of a tree.
+ //! "pos" must be a valid iterator or header (end) node.
+ //! "pos" must be an iterator pointing to the successor to "new_node"
+ //! once inserted according to the order of already inserted nodes. This function does not
+ //! check "pos" and this precondition must be guaranteed by the caller.
+ //!
+ //! Effects: Inserts new_node into the tree before "pos".
+ //!
+ //! Complexity: Constant-time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: If "pos" is not the successor of the newly inserted "new_node"
+ //! tree invariants might be broken.
+ static node_ptr insert_before
+ (node_ptr header, node_ptr pos, node_ptr new_node)
+ {
+ tree_algorithms::insert_before(header, pos, new_node);
+ splay_up(new_node, header);
+ return new_node;
+ }
+
+ //! Requires: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering no less than the
+ //! greatest inserted key.
+ //!
+ //! Effects: Inserts new_node into the tree before "pos".
+ //!
+ //! Complexity: Constant-time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: If "new_node" is less than the greatest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ static void push_back(node_ptr header, node_ptr new_node)
+ {
+ tree_algorithms::push_back(header, new_node);
+ splay_up(new_node, header);
+ }
+
+ //! Requires: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering, no greater than the
+ //! lowest inserted key.
+ //!
+ //! Effects: Inserts new_node into the tree before "pos".
+ //!
+ //! Complexity: Constant-time.
+ //!
+ //! Throws: Nothing.
+ //!
+ //! Note: If "new_node" is greater than the lowest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ static void push_front(node_ptr header, node_ptr new_node)
+ {
+ tree_algorithms::push_front(header, new_node);
+ splay_up(new_node, header);
+ }
+
+ //! Requires: "header" must be the header node of a tree.
+ //! NodePtrCompare is a function object that induces a strict weak
+ //! ordering compatible with the strict weak ordering used to create the
+ //! the tree. NodePtrCompare compares two node_ptrs.
+ //!
+ //! Effects: Inserts new_node into the tree before the upper bound
+ //! according to "comp".
+ //!
+ //! Complexity: Average complexity for insert element is at
+ //! most logarithmic.
+ //!
+ //! Throws: If "comp" throws.
template
static node_ptr insert_equal_upper_bound
(node_ptr header, node_ptr new_node, NodePtrCompare comp)
@@ -551,6 +624,18 @@ class splaytree_algorithms
return tree_algorithms::insert_equal_upper_bound(header, new_node, comp);
}
+ //! Requires: "header" must be the header node of a tree.
+ //! NodePtrCompare is a function object that induces a strict weak
+ //! ordering compatible with the strict weak ordering used to create the
+ //! the tree. NodePtrCompare compares two node_ptrs.
+ //!
+ //! Effects: Inserts new_node into the tree before the lower bound
+ //! according to "comp".
+ //!
+ //! Complexity: Average complexity for insert element is at
+ //! most logarithmic.
+ //!
+ //! Throws: If "comp" throws.
template
static node_ptr insert_equal_lower_bound
(node_ptr header, node_ptr new_node, NodePtrCompare comp)
@@ -605,9 +690,8 @@ class splaytree_algorithms
// if( data_->parent == t )
// data_->parent = find_leftmost();
//posibility 1
- if(splay && NodeTraits::get_left(z) != 0 ){
- node_ptr l = prev_node(z);
- splay_up(l, header);
+ if(splay && NodeTraits::get_left(z)){
+ splay_up(prev_node(z), header);
}
/*
//possibility 2
@@ -644,8 +728,8 @@ class splaytree_algorithms
if( n == t ) return;
for( ;; ){
- node_ptr p = NodeTraits::get_parent(n);
- node_ptr g = NodeTraits::get_parent(p);
+ node_ptr p(NodeTraits::get_parent(n));
+ node_ptr g(NodeTraits::get_parent(p));
if( p == t ) break;
@@ -688,9 +772,8 @@ class splaytree_algorithms
if(!NodeTraits::get_left(t) && !NodeTraits::get_right(t))
return t;
//Backup leftmost/rightmost
- node_ptr leftmost = NodeTraits::get_left(header);
- node_ptr rightmost = NodeTraits::get_right(header);
-
+ node_ptr leftmost (NodeTraits::get_left(header));
+ node_ptr rightmost(NodeTraits::get_right(header));
{
detail::splaydown_rollback rollback(&t, header, leftmost, rightmost);
node_ptr null = header;
diff --git a/include/boost/intrusive/treap.hpp b/include/boost/intrusive/treap.hpp
index 7298db3..b7c9ed2 100644
--- a/include/boost/intrusive/treap.hpp
+++ b/include/boost/intrusive/treap.hpp
@@ -119,7 +119,7 @@ class treap_impl
typedef treap_algorithms node_algorithms;
static const bool constant_time_size = Config::constant_time_size;
- static const bool stateful_value_traits = detail::store_cont_ptr_on_it::value;
+ static const bool stateful_value_traits = detail::is_stateful_value_traits::value;
/// @cond
private:
@@ -217,7 +217,7 @@ class treap_impl
typedef typename node_algorithms::insert_commit_data insert_commit_data;
- //! Effects: Constructs an empty tree.
+ //! Effects: Constructs an empty treap.
//!
//! Complexity: Constant.
//!
@@ -236,7 +236,7 @@ class treap_impl
//! Requires: Dereferencing iterator must yield an lvalue of type value_type.
//! cmp must be a comparison function that induces a strict weak ordering.
//!
- //! Effects: Constructs an empty tree and inserts elements from
+ //! Effects: Constructs an empty treap and inserts elements from
//! [b, e).
//!
//! Complexity: Linear in N if [b, e) is already sorted using
@@ -272,7 +272,7 @@ class treap_impl
~treap_impl()
{}
- //! Effects: Returns an iterator pointing to the beginning of the tree.
+ //! Effects: Returns an iterator pointing to the beginning of the treap.
//!
//! Complexity: Constant.
//!
@@ -280,7 +280,7 @@ class treap_impl
iterator begin()
{ return iterator (node_traits::get_left(node_ptr(&priv_header())), this); }
- //! Effects: Returns a const_iterator pointing to the beginning of the tree.
+ //! Effects: Returns a const_iterator pointing to the beginning of the treap.
//!
//! Complexity: Constant.
//!
@@ -288,7 +288,7 @@ class treap_impl
const_iterator begin() const
{ return this->cbegin(); }
- //! Effects: Returns a const_iterator pointing to the beginning of the tree.
+ //! Effects: Returns a const_iterator pointing to the beginning of the treap.
//!
//! Complexity: Constant.
//!
@@ -296,7 +296,7 @@ class treap_impl
const_iterator cbegin() const
{ return const_iterator (node_traits::get_left(const_node_ptr(&priv_header())), this); }
- //! Effects: Returns an iterator pointing to the end of the tree.
+ //! Effects: Returns an iterator pointing to the end of the treap.
//!
//! Complexity: Constant.
//!
@@ -304,7 +304,7 @@ class treap_impl
iterator end()
{ return iterator (node_ptr(&priv_header()), this); }
- //! Effects: Returns a const_iterator pointing to the end of the tree.
+ //! Effects: Returns a const_iterator pointing to the end of the treap.
//!
//! Complexity: Constant.
//!
@@ -312,7 +312,7 @@ class treap_impl
const_iterator end() const
{ return this->cend(); }
- //! Effects: Returns a const_iterator pointing to the end of the tree.
+ //! Effects: Returns a const_iterator pointing to the end of the treap.
//!
//! Complexity: Constant.
//!
@@ -321,7 +321,7 @@ class treap_impl
{ return const_iterator (uncast(const_node_ptr(&priv_header())), this); }
- //! Effects: Returns an iterator pointing to the highest priority object of the tree.
+ //! Effects: Returns an iterator pointing to the highest priority object of the treap.
//!
//! Complexity: Constant.
//!
@@ -329,7 +329,7 @@ class treap_impl
iterator top()
{ return this->empty() ? this->end() : iterator (node_traits::get_parent(node_ptr(&priv_header())), this); }
- //! Effects: Returns a const_iterator pointing to the highest priority object of the tree..
+ //! Effects: Returns a const_iterator pointing to the highest priority object of the treap..
//!
//! Complexity: Constant.
//!
@@ -337,7 +337,7 @@ class treap_impl
const_iterator top() const
{ return this->ctop(); }
- //! Effects: Returns a const_iterator pointing to the highest priority object of the tree..
+ //! Effects: Returns a const_iterator pointing to the highest priority object of the treap..
//!
//! Complexity: Constant.
//!
@@ -346,7 +346,7 @@ class treap_impl
{ return this->empty() ? this->cend() : const_iterator (node_traits::get_parent(const_node_ptr(&priv_header())), this); }
//! Effects: Returns a reverse_iterator pointing to the beginning of the
- //! reversed tree.
+ //! reversed treap.
//!
//! Complexity: Constant.
//!
@@ -355,7 +355,7 @@ class treap_impl
{ return reverse_iterator(this->end()); }
//! Effects: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed tree.
+ //! of the reversed treap.
//!
//! Complexity: Constant.
//!
@@ -364,7 +364,7 @@ class treap_impl
{ return const_reverse_iterator(this->end()); }
//! Effects: Returns a const_reverse_iterator pointing to the beginning
- //! of the reversed tree.
+ //! of the reversed treap.
//!
//! Complexity: Constant.
//!
@@ -373,7 +373,7 @@ class treap_impl
{ return const_reverse_iterator(this->end()); }
//! Effects: Returns a reverse_iterator pointing to the end
- //! of the reversed tree.
+ //! of the reversed treap.
//!
//! Complexity: Constant.
//!
@@ -382,7 +382,7 @@ class treap_impl
{ return reverse_iterator(this->begin()); }
//! Effects: Returns a const_reverse_iterator pointing to the end
- //! of the reversed tree.
+ //! of the reversed treap.
//!
//! Complexity: Constant.
//!
@@ -391,7 +391,7 @@ class treap_impl
{ return const_reverse_iterator(this->begin()); }
//! Effects: Returns a const_reverse_iterator pointing to the end
- //! of the reversed tree.
+ //! of the reversed treap.
//!
//! Complexity: Constant.
//!
@@ -400,7 +400,7 @@ class treap_impl
{ return const_reverse_iterator(this->begin()); }
//! Effects: Returns a reverse_iterator pointing to the highest priority object of the
- //! reversed tree.
+ //! reversed treap.
//!
//! Complexity: Constant.
//!
@@ -409,7 +409,7 @@ class treap_impl
{ return reverse_iterator(this->top()); }
//! Effects: Returns a const_reverse_iterator pointing to the highest priority objec
- //! of the reversed tree.
+ //! of the reversed treap.
//!
//! Complexity: Constant.
//!
@@ -418,7 +418,7 @@ class treap_impl
{ return const_reverse_iterator(this->top()); }
//! Effects: Returns a const_reverse_iterator pointing to the highest priority object
- //! of the reversed tree.
+ //! of the reversed treap.
//!
//! Complexity: Constant.
//!
@@ -451,7 +451,7 @@ class treap_impl
//! Precondition: it must be a valid iterator
//! of treap.
//!
- //! Effects: Returns a const reference to the tree associated to the iterator
+ //! Effects: Returns a const reference to the treap associated to the iterator
//!
//! Throws: Nothing.
//!
@@ -462,7 +462,7 @@ class treap_impl
//! Precondition: it must be a valid end const_iterator
//! of treap.
//!
- //! Effects: Returns a const reference to the tree associated to the end iterator
+ //! Effects: Returns a const reference to the treap associated to the end iterator
//!
//! Throws: Nothing.
//!
@@ -470,7 +470,7 @@ class treap_impl
static const treap_impl &container_from_iterator(const_iterator it)
{ return priv_container_from_iterator(it); }
- //! Effects: Returns the value_compare object used by the tree.
+ //! Effects: Returns the value_compare object used by the treap.
//!
//! Complexity: Constant.
//!
@@ -478,7 +478,7 @@ class treap_impl
value_compare value_comp() const
{ return this->priv_comp(); }
- //! Effects: Returns the priority_compare object used by the tree.
+ //! Effects: Returns the priority_compare object used by the treap.
//!
//! Complexity: Constant.
//!
@@ -494,7 +494,7 @@ class treap_impl
bool empty() const
{ return node_algorithms::unique(const_node_ptr(&priv_header())); }
- //! Effects: Returns the number of elements stored in the tree.
+ //! Effects: Returns the number of elements stored in the treap.
//!
//! Complexity: Linear to elements contained in *this
//! if constant-time size option is disabled. Constant time otherwise.
@@ -531,12 +531,12 @@ class treap_impl
//! Requires: value must be an lvalue
//!
- //! Effects: Inserts value into the tree before the upper bound.
+ //! Effects: Inserts value into the treap before the upper bound.
//!
//! Complexity: Average complexity for insert element is at
//! most logarithmic.
//!
- //! Throws: If the internal value_compare or priority_compare funcstions throw. Strong guarantee.
+ //! Throws: If the internal value_compare or priority_compare functions throw. Strong guarantee.
//!
//! Note: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
@@ -557,14 +557,14 @@ class treap_impl
//! Requires: value must be an lvalue, and "hint" must be
//! a valid iterator.
//!
- //! Effects: Inserts x into the tree, using "hint" as a hint to
+ //! Effects: Inserts x into the treap, using "hint" as a hint to
//! where it will be inserted. If "hint" is the upper_bound
//! the insertion takes constant time (two comparisons in the worst case)
//!
//! Complexity: Logarithmic in general, but it is amortized
//! constant time if t is inserted immediately before hint.
//!
- //! Throws: If the internal value_compare or priority_compare funcstions throw. Strong guarantee.
+ //! Throws: If the internal value_compare or priority_compare functions throw. Strong guarantee.
//!
//! Note: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
@@ -585,14 +585,14 @@ class treap_impl
//! Requires: Dereferencing iterator must yield an lvalue
//! of type value_type.
//!
- //! Effects: Inserts a each element of a range into the tree
+ //! Effects: Inserts a each element of a range into the treap
//! before the upper bound of the key of each element.
//!
//! Complexity: Insert range is in general O(N * log(N)), where N is the
//! size of the range. However, it is linear in N if the range is already sorted
//! by value_comp().
//!
- //! Throws: If the internal value_compare or priority_compare funcstions throw.
+ //! Throws: If the internal value_compare or priority_compare functions throw.
//! Strong guarantee.
//!
//! Note: Does not affect the validity of iterators and references.
@@ -607,13 +607,13 @@ class treap_impl
//! Requires: value must be an lvalue
//!
- //! Effects: Inserts value into the tree if the value
+ //! Effects: Inserts value into the treap if the value
//! is not already present.
//!
//! Complexity: Average complexity for insert element is at
//! most logarithmic.
//!
- //! Throws: If the internal value_compare or priority_compare funcstions throw.
+ //! Throws: If the internal value_compare or priority_compare functions throw.
//! Strong guarantee.
//!
//! Note: Does not affect the validity of iterators and references.
@@ -630,14 +630,14 @@ class treap_impl
//! Requires: value must be an lvalue, and "hint" must be
//! a valid iterator
//!
- //! Effects: Tries to insert x into the tree, using "hint" as a hint
+ //! Effects: Tries to insert x into the treap, using "hint" as a hint
//! to where it will be inserted.
//!
//! Complexity: Logarithmic in general, but it is amortized
//! constant time (two comparisons in the worst case)
//! if t is inserted immediately before hint.
//!
- //! Throws: If the internal value_compare or priority_compare funcstions throw.
+ //! Throws: If the internal value_compare or priority_compare functions throw.
//! Strong guarantee.
//!
//! Note: Does not affect the validity of iterators and references.
@@ -654,13 +654,13 @@ class treap_impl
//! Requires: Dereferencing iterator must yield an lvalue
//! of type value_type.
//!
- //! Effects: Tries to insert each element of a range into the tree.
+ //! Effects: Tries to insert each element of a range into the treap.
//!
//! Complexity: Insert range is in general O(N * log(N)), where N is the
//! size of the range. However, it is linear in N if the range is already sorted
//! by value_comp().
//!
- //! Throws: If the internal value_compare or priority_compare funcstions throw.
+ //! Throws: If the internal value_compare or priority_compare functions throw.
//! Strong guarantee.
//!
//! Note: Does not affect the validity of iterators and references.
@@ -680,8 +680,10 @@ class treap_impl
}
//! Requires: key_value_comp must be a comparison function that induces
- //! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an arbitrary key with the contained values.
+ //! the same strict weak ordering as value_compare.
+ //! key_value_pcomp must be a comparison function that induces
+ //! the same strict weak ordering as priority_compare. The difference is that
+ //! key_value_pcomp and key_value_comp compare an arbitrary key with the contained values.
//!
//! Effects: Checks if a value can be inserted in the container, using
//! a user provided key instead of the value itself.
@@ -694,7 +696,8 @@ class treap_impl
//!
//! Complexity: Average complexity is at most logarithmic.
//!
- //! Throws: If the key_value_comp ordering function throws. Strong guarantee.
+ //! Throws: If the key_value_comp or key_value_pcomp
+ //! ordering functions throw. Strong guarantee.
//!
//! Notes: This function is used to improve performance when constructing
//! a value_type is expensive: if there is an equivalent value
@@ -725,8 +728,10 @@ class treap_impl
}
//! Requires: key_value_comp must be a comparison function that induces
- //! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an arbitrary key with the contained values.
+ //! the same strict weak ordering as value_compare.
+ //! key_value_pcomp must be a comparison function that induces
+ //! the same strict weak ordering as priority_compare. The difference is that
+ //! key_value_pcomp and key_value_comp compare an arbitrary key with the contained values.
//!
//! Effects: Checks if a value can be inserted in the container, using
//! a user provided key instead of the value itself, using "hint"
@@ -741,7 +746,8 @@ class treap_impl
//! Complexity: Logarithmic in general, but it's amortized
//! constant time if t is inserted immediately before hint.
//!
- //! Throws: If the key_value_comp ordering function throws. Strong guarantee.
+ //! Throws: If the key_value_comp or key_value_pcomp
+ //! ordering functions throw. Strong guarantee.
//!
//! Notes: This function is used to improve performance when constructing
//! a value_type is expensive: if there is an equivalent value
@@ -800,6 +806,82 @@ class treap_impl
return iterator(to_insert, this);
}
+ //! Requires: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate
+ //!
+ //! Effects: Inserts x into the treap before "pos".
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! Note: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" treap ordering invariant will be broken.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ detail::key_nodeptr_comp
+ pcomp(priv_pcomp(), this);
+ return iterator(node_algorithms::insert_before
+ (node_ptr(&priv_header()), pos.pointed_node(), to_insert, pcomp), this);
+ }
+
+ //! Requires: value must be an lvalue, and it must be no less
+ //! than the greatest inserted key
+ //!
+ //! Effects: Inserts x into the treap in the last position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! less than the greatest inserted key treap ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ detail::key_nodeptr_comp
+ pcomp(priv_pcomp(), this);
+ node_algorithms::push_back(node_ptr(&priv_header()), to_insert, pcomp);
+ }
+
+ //! Requires: value must be an lvalue, and it must be no greater
+ //! than the minimum inserted key
+ //!
+ //! Effects: Inserts x into the treap in the first position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! greater than the minimum inserted key treap ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ {
+ node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
+ if(safemode_or_autounlink)
+ BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
+ this->priv_size_traits().increment();
+ detail::key_nodeptr_comp
+ pcomp(priv_pcomp(), this);
+ node_algorithms::push_front(node_ptr(&priv_header()), to_insert, pcomp);
+ }
+
//! Effects: Erases the element pointed to by pos.
//!
//! Complexity: Average complexity for erase element is constant time.
@@ -817,7 +899,7 @@ class treap_impl
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
detail::key_nodeptr_comp
key_node_pcomp(priv_pcomp(), this);
- node_algorithms::erase(&priv_header(), to_erase,key_node_pcomp);
+ node_algorithms::erase(&priv_header(), to_erase, key_node_pcomp);
this->priv_size_traits().decrement();
if(safemode_or_autounlink)
node_algorithms::init(to_erase);
@@ -856,7 +938,8 @@ class treap_impl
//!
//! Complexity: O(log(size() + N).
//!
- //! Throws: if the internal priority_compare function throws. Strong guarantee.
+ //! Throws: if the internal priority_compare function throws.
+ //! Equivalent guarantee to while(beg != end) erase(beg++);
//!
//! Note: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -1260,16 +1343,16 @@ class treap_impl
}
}
- //! Effects: Unlinks the leftmost node from the tree.
+ //! Effects: Unlinks the leftmost node from the treap.
//!
//! Complexity: Average complexity is constant time.
//!
//! Throws: Nothing.
//!
- //! Notes: This function breaks the tree and the tree can
+ //! Notes: This function breaks the treap and the treap can
//! only be used for more unlink_leftmost_without_rebalance calls.
//! This function is normally used to achieve a step by step
- //! controlled destruction of the tree.
+ //! controlled destruction of the treap.
pointer unlink_leftmost_without_rebalance()
{
node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance
@@ -1283,10 +1366,10 @@ class treap_impl
}
//! Requires: replace_this must be a valid iterator of *this
- //! and with_this must not be inserted in any tree.
+ //! and with_this must not be inserted in any treap.
//!
//! Effects: Replaces replace_this in its position in the
- //! tree with with_this. The tree does not need to be rebalanced.
+ //! treap with with_this. The treap does not need to be rebalanced.
//!
//! Complexity: Constant.
//!
@@ -1363,7 +1446,7 @@ class treap_impl
const_iterator iterator_to(const_reference value) const
{ return const_iterator (value_traits::to_node_ptr(const_cast (value)), this); }
- //! Requires: value shall not be in a tree.
+ //! Requires: value shall not be in a treap.
//!
//! Effects: init_node puts the hook of a value in a well-known default
//! state.
diff --git a/include/boost/intrusive/treap_algorithms.hpp b/include/boost/intrusive/treap_algorithms.hpp
index bdceac2..6c05efa 100644
--- a/include/boost/intrusive/treap_algorithms.hpp
+++ b/include/boost/intrusive/treap_algorithms.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2006-2008.
+// (C) Copyright Ion Gaztanaga 2006-2009.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -10,8 +10,8 @@
//
/////////////////////////////////////////////////////////////////////////////
-#ifndef BOOST_INTRUSIVE_TRIE_ALGORITHMS_HPP
-#define BOOST_INTRUSIVE_TRIE_ALGORITHMS_HPP
+#ifndef BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP
+#define BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP
#include
@@ -270,15 +270,15 @@ class treap_algorithms
//!
//! Complexity: Average complexity is constant time.
//!
- //! Throws: Nothing.
- template
- static void unlink(node_ptr node, NodePriorityCompare prio)
+ //! Throws: If "pcomp" throws, strong guarantee
+ template
+ static void unlink(node_ptr node, NodePtrPriorityCompare pcomp)
{
node_ptr x = NodeTraits::get_parent(node);
if(x){
while(!is_header(x))
x = NodeTraits::get_parent(x);
- erase(x, node, prio);
+ erase(x, node, pcomp);
}
}
@@ -383,9 +383,9 @@ class treap_algorithms
//!
//! Complexity: Amortized constant time.
//!
- //! Throws: Nothing.
- template
- static node_ptr erase(node_ptr header, node_ptr z, NodePriorityCompare pcomp)
+ //! Throws: If "pcomp" throws, strong guarantee.
+ template
+ static node_ptr erase(node_ptr header, node_ptr z, NodePtrPriorityCompare pcomp)
{
rebalance_for_erasure(header, z, pcomp);
tree_algorithms::erase(header, z);
@@ -503,23 +503,24 @@ class treap_algorithms
//! NodePtrCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the
//! the tree. NodePtrCompare compares two node_ptrs.
+ //! NodePtrPriorityCompare is a priority function object that induces a strict weak
+ //! ordering compatible with the one used to create the
+ //! the tree. NodePtrPriorityCompare compares two node_ptrs.
//!
//! Effects: Inserts new_node into the tree before the upper bound
- //! according to "comp".
+ //! according to "comp" and rotates the tree according to "pcomp".
//!
//! Complexity: Average complexity for insert element is at
//! most logarithmic.
//!
- //! Throws: If "comp" throws.
- template
+ //! Throws: If "comp" throw or "pcomp" throw.
+ template
static node_ptr insert_equal_upper_bound
- (node_ptr h, node_ptr new_node, NodePtrCompare comp, PriorityNodeCompare pcomp)
+ (node_ptr h, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
tree_algorithms::insert_equal_upper_bound_check(h, new_node, comp, commit_data);
- rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
- tree_algorithms::insert_unique_commit(h, new_node, commit_data);
- rebalance_after_insertion_commit(h, new_node, commit_data.rotations);
+ rebalance_check_and_commit(h, new_node, pcomp, commit_data);
return new_node;
}
@@ -527,23 +528,24 @@ class treap_algorithms
//! NodePtrCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the
//! the tree. NodePtrCompare compares two node_ptrs.
+ //! NodePtrPriorityCompare is a priority function object that induces a strict weak
+ //! ordering compatible with the one used to create the
+ //! the tree. NodePtrPriorityCompare compares two node_ptrs.
//!
- //! Effects: Inserts new_node into the tree before the lower bound
- //! according to "comp".
+ //! Effects: Inserts new_node into the tree before the upper bound
+ //! according to "comp" and rotates the tree according to "pcomp".
//!
//! Complexity: Average complexity for insert element is at
//! most logarithmic.
//!
//! Throws: If "comp" throws.
- template
+ template
static node_ptr insert_equal_lower_bound
- (node_ptr h, node_ptr new_node, NodePtrCompare comp, NodePriorityCompare pcomp)
+ (node_ptr h, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
tree_algorithms::insert_equal_lower_bound_check(h, new_node, comp, commit_data);
- rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
- tree_algorithms::insert_unique_commit(h, new_node, commit_data);
- rebalance_after_insertion_commit(h, new_node, commit_data.rotations);
+ rebalance_check_and_commit(h, new_node, pcomp, commit_data);
return new_node;
}
@@ -552,27 +554,107 @@ class treap_algorithms
//! ordering compatible with the strict weak ordering used to create the
//! the tree. NodePtrCompare compares two node_ptrs. "hint" is node from
//! the "header"'s tree.
+ //! NodePtrPriorityCompare is a priority function object that induces a strict weak
+ //! ordering compatible with the one used to create the
+ //! the tree. NodePtrPriorityCompare compares two node_ptrs.
//!
//! Effects: Inserts new_node into the tree, using "hint" as a hint to
//! where it will be inserted. If "hint" is the upper_bound
//! the insertion takes constant time (two comparisons in the worst case).
+ //! Rotates the tree according to "pcomp".
//!
//! Complexity: Logarithmic in general, but it is amortized
//! constant time if new_node is inserted immediately before "hint".
//!
- //! Throws: If "comp" throws.
- template
+ //! Throws: If "comp" throw or "pcomp" throw.
+ template
static node_ptr insert_equal
- (node_ptr h, node_ptr hint, node_ptr new_node, NodePtrCompare comp, NodePriorityCompare pcomp)
+ (node_ptr h, node_ptr hint, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
tree_algorithms::insert_equal_check(h, hint, new_node, comp, commit_data);
- rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
- tree_algorithms::insert_unique_commit(h, new_node, commit_data);
- rebalance_after_insertion_commit(h, new_node, commit_data.rotations);
+ rebalance_check_and_commit(h, new_node, pcomp, commit_data);
return new_node;
}
+ //! Requires: "header" must be the header node of a tree.
+ //! "pos" must be a valid node of the tree (including header end) node.
+ //! "pos" must be a node pointing to the successor to "new_node"
+ //! once inserted according to the order of already inserted nodes. This function does not
+ //! check "pos" and this precondition must be guaranteed by the caller.
+ //! NodePtrPriorityCompare is a priority function object that induces a strict weak
+ //! ordering compatible with the one used to create the
+ //! the tree. NodePtrPriorityCompare compares two node_ptrs.
+ //!
+ //! Effects: Inserts new_node into the tree before "pos"
+ //! and rotates the tree according to "pcomp".
+ //!
+ //! Complexity: Constant-time.
+ //!
+ //! Throws: If "pcomp" throws, strong guarantee.
+ //!
+ //! Note: If "pos" is not the successor of the newly inserted "new_node"
+ //! tree invariants might be broken.
+ template
+ static node_ptr insert_before
+ (node_ptr header, node_ptr pos, node_ptr new_node, NodePtrPriorityCompare pcomp)
+ {
+ insert_commit_data commit_data;
+ tree_algorithms::insert_before_check(header, pos, commit_data);
+ rebalance_check_and_commit(header, new_node, pcomp, commit_data);
+ return new_node;
+ }
+
+ //! Requires: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering no less than the
+ //! greatest inserted key.
+ //! NodePtrPriorityCompare is a priority function object that induces a strict weak
+ //! ordering compatible with the one used to create the
+ //! the tree. NodePtrPriorityCompare compares two node_ptrs.
+ //!
+ //! Effects: Inserts x into the tree in the last position
+ //! and rotates the tree according to "pcomp".
+ //!
+ //! Complexity: Constant-time.
+ //!
+ //! Throws: If "pcomp" throws, strong guarantee.
+ //!
+ //! Note: If "new_node" is less than the greatest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ template
+ static void push_back(node_ptr header, node_ptr new_node, NodePtrPriorityCompare pcomp)
+ {
+ insert_commit_data commit_data;
+ tree_algorithms::push_back_check(header, commit_data);
+ rebalance_check_and_commit(header, new_node, pcomp, commit_data);
+ }
+
+ //! Requires: "header" must be the header node of a tree.
+ //! "new_node" must be, according to the used ordering, no greater than the
+ //! lowest inserted key.
+ //! NodePtrPriorityCompare is a priority function object that induces a strict weak
+ //! ordering compatible with the one used to create the
+ //! the tree. NodePtrPriorityCompare compares two node_ptrs.
+ //!
+ //! Effects: Inserts x into the tree in the first position
+ //! and rotates the tree according to "pcomp".
+ //!
+ //! Complexity: Constant-time.
+ //!
+ //! Throws: If "pcomp" throws, strong guarantee.
+ //!
+ //! Note: If "new_node" is greater than the lowest inserted key
+ //! tree invariants are broken. This function is slightly faster than
+ //! using "insert_before".
+ template
+ static void push_front(node_ptr header, node_ptr new_node, NodePtrPriorityCompare pcomp)
+ {
+ insert_commit_data commit_data;
+ tree_algorithms::push_front_check(header, commit_data);
+ rebalance_check_and_commit(header, new_node, pcomp, commit_data);
+ }
+
//! Requires: "header" must be the header node of a tree.
//! KeyNodePtrCompare is a function object that induces a strict weak
//! ordering compatible with the strict weak ordering used to create the
@@ -720,8 +802,8 @@ class treap_algorithms
return tree_algorithms::is_header(p);
}
- template
- static void rebalance_for_erasure(node_ptr header, node_ptr z, NodePriorityCompare pcomp)
+ template
+ static void rebalance_for_erasure(node_ptr header, node_ptr z, NodePtrPriorityCompare pcomp)
{
std::size_t n = 0;
rerotate_on_destroy rb(header, z, n);
@@ -742,6 +824,17 @@ class treap_algorithms
rb.release();
}
+ template
+ static void rebalance_check_and_commit
+ (node_ptr h, node_ptr new_node, NodePtrPriorityCompare pcomp, insert_commit_data &commit_data)
+ {
+ rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
+ //No-throw
+ tree_algorithms::insert_unique_commit(h, new_node, commit_data);
+ rebalance_after_insertion_commit(h, new_node, commit_data.rotations);
+ }
+
+
template
static void rebalance_after_insertion_check
( const_node_ptr header, const_node_ptr upnode, const Key &k
@@ -759,7 +852,7 @@ class treap_algorithms
static void rebalance_after_insertion_commit(node_ptr header, node_ptr p, std::size_t n)
{
- // Now to n rotations
+ // Now execute n rotations
for( node_ptr p_parent = NodeTraits::get_parent(p)
; n--
; p_parent = NodeTraits::get_parent(p)){
@@ -773,8 +866,8 @@ class treap_algorithms
}
}
- template
- static bool check_invariant(const_node_ptr header, NodePriorityCompare pcomp)
+ template
+ static bool check_invariant(const_node_ptr header, NodePtrPriorityCompare pcomp)
{
node_ptr beg = begin_node(header);
node_ptr end = end_node(header);
@@ -798,4 +891,4 @@ class treap_algorithms
#include
-#endif //BOOST_INTRUSIVE_TRIE_ALGORITHMS_HPP
+#endif //BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP
diff --git a/include/boost/intrusive/treap_set.hpp b/include/boost/intrusive/treap_set.hpp
index 9322a6b..12611ee 100644
--- a/include/boost/intrusive/treap_set.hpp
+++ b/include/boost/intrusive/treap_set.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2007-2008
+// (C) Copyright Ion Gaztanaga 2007-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -351,6 +351,14 @@ class treap_set_impl
value_compare value_comp() const
{ return tree_.value_comp(); }
+ //! Effects: Returns the priority_compare object used by the treap_set.
+ //!
+ //! Complexity: Constant.
+ //!
+ //! Throws: If priority_compare copy-constructor throws.
+ priority_compare priority_comp() const
+ { return tree_.priority_comp(); }
+
//! Effects: Returns true if the container is empty.
//!
//! Complexity: Constant.
@@ -408,7 +416,8 @@ class treap_set_impl
//! Complexity: Average complexity for insert element is at
//! most logarithmic.
//!
- //! Throws: If the internal value_compare ordering function throws. Strong guarantee.
+ //! Throws: If the internal value_compare or priority_compare ordering function throw.
+ //! Strong guarantee.
//!
//! Note: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
@@ -426,7 +435,8 @@ class treap_set_impl
//! Complexity: Logarithmic in general, but it's amortized
//! constant time if t is inserted immediately before hint.
//!
- //! Throws: If the internal value_compare ordering function throws. Strong guarantee.
+ //! Throws: If the internal value_compare or priority_compare ordering
+ //! functions throw. Strong guarantee.
//!
//! Note: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
@@ -434,8 +444,10 @@ class treap_set_impl
{ return tree_.insert_unique(hint, value); }
//! Requires: key_value_comp must be a comparison function that induces
- //! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an ascapegoatitrary key with the contained values.
+ //! the same strict weak ordering as value_compare.
+ //! key_value_pcomp must be a comparison function that induces
+ //! the same strict weak ordering as priority_compare. The difference is that
+ //! key_value_pcomp and key_value_comp compare an arbitrary key with the contained values.
//!
//! Effects: Checks if a value can be inserted in the treap_set, using
//! a user provided key instead of the value itself.
@@ -448,7 +460,8 @@ class treap_set_impl
//!
//! Complexity: Average complexity is at most logarithmic.
//!
- //! Throws: If the key_value_comp ordering function throws. Strong guarantee.
+ //! Throws: If key_value_comp or key_value_pcomp ordering function throw.
+ //! Strong guarantee.
//!
//! Notes: This function is used to improve performance when constructing
//! a value_type is expensive: if there is an equivalent value
@@ -463,14 +476,17 @@ class treap_set_impl
//!
//! "commit_data" remains valid for a subsequent "insert_commit" only if no more
//! objects are inserted or erased from the treap_set.
- template
+ template
std::pair insert_check
- (const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_.insert_unique_check(key, key_value_comp, commit_data); }
+ ( const KeyType &key, KeyValueCompare key_value_comp, KeyValuePriorityCompare key_value_pcomp
+ , insert_commit_data &commit_data)
+ { return tree_.insert_unique_check(key, key_value_comp, key_value_pcomp, commit_data); }
//! Requires: key_value_comp must be a comparison function that induces
- //! the same strict weak ordering as value_compare. The difference is that
- //! key_value_comp compares an ascapegoatitrary key with the contained values.
+ //! the same strict weak ordering as value_compare.
+ //! key_value_pcomp must be a comparison function that induces
+ //! the same strict weak ordering as priority_compare. The difference is that
+ //! key_value_pcomp and key_value_comp compare an arbitrary key with the contained values.
//!
//! Effects: Checks if a value can be inserted in the treap_set, using
//! a user provided key instead of the value itself, using "hint"
@@ -485,7 +501,8 @@ class treap_set_impl
//! Complexity: Logarithmic in general, but it's amortized
//! constant time if t is inserted immediately before hint.
//!
- //! Throws: If the key_value_comp ordering function throws. Strong guarantee.
+ //! Throws: If key_value_comp or key_value_pcomp ordering function throw.
+ //! Strong guarantee.
//!
//! Notes: This function is used to improve performance when constructing
//! a value_type is expensive: if there is an equivalent value
@@ -500,11 +517,12 @@ class treap_set_impl
//!
//! "commit_data" remains valid for a subsequent "insert_commit" only if no more
//! objects are inserted or erased from the treap_set.
- template
+ template
std::pair insert_check
- (const_iterator hint, const KeyType &key
- ,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
- { return tree_.insert_unique_check(hint, key, key_value_comp, commit_data); }
+ ( const_iterator hint, const KeyType &key
+ , KeyValueCompare key_value_comp, KeyValuePriorityCompare key_value_pcomp
+ , insert_commit_data &commit_data)
+ { return tree_.insert_unique_check(hint, key, key_value_comp, key_value_pcomp, commit_data); }
//! Requires: value must be an lvalue of type value_type. commit_data
//! must have been obtained from a previous call to "insert_check".
@@ -535,7 +553,8 @@ class treap_set_impl
//! size of the range. However, it is linear in N if the range is already sorted
//! by value_comp().
//!
- //! Throws: If the internal value_compare ordering function throws. Basic guarantee.
+ //! Throws: If the internal value_compare or priority_compare ordering function
+ //! throw. Basic guarantee.
//!
//! Note: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
@@ -543,13 +562,65 @@ class treap_set_impl
void insert(Iterator b, Iterator e)
{ tree_.insert_unique(b, e); }
+ //! Requires: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate. "value" must not be equal to any
+ //! inserted key according to the predicate.
+ //!
+ //! Effects: Inserts x into the treap before "pos".
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! Note: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" treap ordering invariant will be broken.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ { return tree_.insert_before(pos, value); }
+
+ //! Requires: value must be an lvalue, and it must be greater than
+ //! any inserted key according to the predicate.
+ //!
+ //! Effects: Inserts x into the treap in the last position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! less than the greatest inserted key treap ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ { tree_.push_back(value); }
+
+ //! Requires: value must be an lvalue, and it must be less
+ //! than any inserted key according to the predicate.
+ //!
+ //! Effects: Inserts x into the treap in the first position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! greater than the minimum inserted key treap ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ { tree_.push_front(value); }
+
//! Effects: Erases the element pointed to by pos.
//!
//! Complexity: Average complexity is constant time.
//!
//! Returns: An iterator to the element after the erased element.
//!
- //! Throws: Nothing.
+ //! Throws: If the internal priority_compare function throws. Strong guarantee.
//!
//! Note: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -563,7 +634,7 @@ class treap_set_impl
//!
//! Returns: An iterator to the element after the erased elements.
//!
- //! Throws: Nothing.
+ //! Throws: If the internal priority_compare function throws. Basic guarantee.
//!
//! Note: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -576,7 +647,8 @@ class treap_set_impl
//!
//! Complexity: O(log(size()) + this->count(value)).
//!
- //! Throws: If the internal value_compare ordering function throws. Basic guarantee.
+ //! Throws: If internal value_compare or priority_compare
+ //! ordering functions throw. Basic guarantee.
//!
//! Note: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -590,7 +662,8 @@ class treap_set_impl
//!
//! Complexity: O(log(size() + this->count(key, comp)).
//!
- //! Throws: If the comp ordering function throws. Basic guarantee.
+ //! Throws: If comp or internal priority_compare
+ //! ordering functions throw. Basic guarantee.
//!
//! Note: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -611,7 +684,7 @@ class treap_set_impl
//!
//! Returns: An iterator to the element after the erased element.
//!
- //! Throws: Nothing.
+ //! Throws: If the internal priority_compare function throws. Strong guarantee.
//!
//! Note: Invalidates the iterators
//! to the erased elements.
@@ -635,7 +708,7 @@ class treap_set_impl
//!
//! Returns: An iterator to the element after the erased elements.
//!
- //! Throws: Nothing.
+ //! Throws: If the internal priority_compare function throws. Basic guarantee.
//!
//! Note: Invalidates the iterators
//! to the erased elements.
@@ -652,7 +725,7 @@ class treap_set_impl
//!
//! Complexity: O(log(size() + this->count(value)). Basic guarantee.
//!
- //! Throws: Nothing.
+ //! Throws: If the internal priority_compare function throws. Strong guarantee.
//!
//! Note: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -670,7 +743,8 @@ class treap_set_impl
//!
//! Complexity: O(log(size() + this->count(key, comp)).
//!
- //! Throws: If comp ordering function throws. Basic guarantee.
+ //! Throws: If comp or internal priority_compare ordering functions throw.
+ //! Basic guarantee.
//!
//! Note: Invalidates the iterators
//! to the erased elements.
@@ -1584,6 +1658,14 @@ class treap_multiset_impl
value_compare value_comp() const
{ return tree_.value_comp(); }
+ //! Effects: Returns the priority_compare object used by the treap_multiset.
+ //!
+ //! Complexity: Constant.
+ //!
+ //! Throws: If priority_compare copy-constructor throws.
+ priority_compare priority_comp() const
+ { return tree_.priority_comp(); }
+
//! Effects: Returns true if the container is empty.
//!
//! Complexity: Constant.
@@ -1638,7 +1720,8 @@ class treap_multiset_impl
//! Complexity: Average complexity for insert element is at
//! most logarithmic.
//!
- //! Throws: If the internal value_compare ordering function throws. Strong guarantee.
+ //! Throws: If the internal value_compare or priority_compare ordering
+ //! function throws. Strong guarantee.
//!
//! Note: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
@@ -1656,7 +1739,8 @@ class treap_multiset_impl
//! Complexity: Logarithmic in general, but it is amortized
//! constant time if t is inserted immediately before hint.
//!
- //! Throws: If the internal value_compare ordering function throws. Strong guarantee.
+ //! Throws: If internal value_compare or priority_compare ordering functions throw.
+ //! Strong guarantee.
//!
//! Note: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
@@ -1675,7 +1759,8 @@ class treap_multiset_impl
//! size of the range. However, it is linear in N if the range is already sorted
//! by value_comp().
//!
- //! Throws: If the internal value_compare ordering function throws. Basic guarantee.
+ //! Throws: If internal value_compare or priority_compare ordering functions throw.
+ //! Basic guarantee.
//!
//! Note: Does not affect the validity of iterators and references.
//! No copy-constructors are called.
@@ -1683,13 +1768,64 @@ class treap_multiset_impl
void insert(Iterator b, Iterator e)
{ tree_.insert_equal(b, e); }
+ //! Requires: value must be an lvalue, "pos" must be
+ //! a valid iterator (or end) and must be the succesor of value
+ //! once inserted according to the predicate
+ //!
+ //! Effects: Inserts x into the treap before "pos".
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! Note: This function does not check preconditions so if "pos" is not
+ //! the successor of "value" treap ordering invariant will be broken.
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ iterator insert_before(const_iterator pos, reference value)
+ { return tree_.insert_before(pos, value); }
+
+ //! Requires: value must be an lvalue, and it must be no less
+ //! than the greatest inserted key.
+ //!
+ //! Effects: Inserts x into the treap in the last position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! less than the greatest inserted key treap ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_back(reference value)
+ { tree_.push_back(value); }
+
+ //! Requires: value must be an lvalue, and it must be no greater
+ //! than the minimum inserted key
+ //!
+ //! Effects: Inserts x into the treap in the first position.
+ //!
+ //! Complexity: Constant time.
+ //!
+ //! Throws: If the internal priority_compare function throws. Strong guarantee.
+ //!
+ //! Note: This function does not check preconditions so if value is
+ //! greater than the minimum inserted key treap ordering invariant will be broken.
+ //! This function is slightly more efficient than using "insert_before".
+ //! This is a low-level function to be used only for performance reasons
+ //! by advanced users.
+ void push_front(reference value)
+ { tree_.push_front(value); }
+
//! Effects: Erases the element pointed to by pos.
//!
//! Complexity: Average complexity is constant time.
//!
//! Returns: An iterator to the element after the erased element.
//!
- //! Throws: Nothing.
+ //! Throws: If the internal priority_compare function throws. Strong guarantee.
//!
//! Note: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -1703,7 +1839,7 @@ class treap_multiset_impl
//! Complexity: Average complexity for erase range is at most
//! O(log(size() + N)), where N is the number of elements in the range.
//!
- //! Throws: Nothing.
+ //! Throws: If the internal priority_compare function throws. Basic guarantee.
//!
//! Note: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -1716,7 +1852,8 @@ class treap_multiset_impl
//!
//! Complexity: O(log(size() + this->count(value)).
//!
- //! Throws: If the internal value_compare ordering function throws. Basic guarantee.
+ //! Throws: If the internal value_compare or priority_compare ordering
+ //! functiona throw. Basic guarantee.
//!
//! Note: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -1730,7 +1867,7 @@ class treap_multiset_impl
//!
//! Complexity: O(log(size() + this->count(key, comp)).
//!
- //! Throws: If comp ordering function throws. Basic guarantee.
+ //! Throws: If comp or internal priority_compare ordering functions throw. Basic guarantee.
//!
//! Note: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
@@ -1751,7 +1888,7 @@ class treap_multiset_impl
//!
//! Complexity: Average complexity for erase element is constant time.
//!
- //! Throws: Nothing.
+ //! Throws: If the internal priority_compare function throws. Strong guarantee.
//!
//! Note: Invalidates the iterators
//! to the erased elements.
@@ -1775,7 +1912,7 @@ class treap_multiset_impl
//! Complexity: Average complexity for erase range is at most
//! O(log(size() + N)), where N is the number of elements in the range.
//!
- //! Throws: Nothing.
+ //! Throws: If the internal priority_compare function throws. Basic guarantee.
//!
//! Note: Invalidates the iterators
//! to the erased elements.
@@ -1810,7 +1947,7 @@ class treap_multiset_impl
//!
//! Complexity: O(log(size() + this->count(key, comp)).
//!
- //! Throws: If comp ordering function throws. Basic guarantee.
+ //! Throws: If comp or internal priority_compare ordering functions throw. Basic guarantee.
//!
//! Note: Invalidates the iterators
//! to the erased elements.
diff --git a/include/boost/intrusive/trivial_value_traits.hpp b/include/boost/intrusive/trivial_value_traits.hpp
index dcf996d..4527d7c 100644
--- a/include/boost/intrusive/trivial_value_traits.hpp
+++ b/include/boost/intrusive/trivial_value_traits.hpp
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////
//
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
diff --git a/include/boost/intrusive/unordered_set.hpp b/include/boost/intrusive/unordered_set.hpp
index cdca860..47d1aab 100644
--- a/include/boost/intrusive/unordered_set.hpp
+++ b/include/boost/intrusive/unordered_set.hpp
@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -395,8 +395,8 @@ class unordered_set_impl
//!
//! Note: Invalidates the iterators (but not the references)
//! to the erased element. No destructors are called.
- void erase(const_iterator i)
- { table_.erase(i); }
+ iterator erase(const_iterator i)
+ { return table_.erase(i); }
//! Effects: Erases the range pointed to by b end e.
//!
@@ -407,8 +407,8 @@ class unordered_set_impl
//!
//! Note: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
- void erase(const_iterator b, const_iterator e)
- { table_.erase(b, e); }
+ iterator erase(const_iterator b, const_iterator e)
+ { return table_.erase(b, e); }
//! Effects: Erases all the elements with the given value.
//!
@@ -460,15 +460,13 @@ class unordered_set_impl
//! Note: Invalidates the iterators
//! to the erased elements.
template
- iterator erase_and_dispose(const_iterator i, Disposer disposer)
+ iterator erase_and_dispose(const_iterator i, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c::value >::type * = 0
+ /// @endcond
+ )
{ return table_.erase_and_dispose(i, disposer); }
- #if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
- template
- iterator erase_and_dispose(iterator i, Disposer disposer)
- { return this->erase_and_dispose(const_iterator(i), disposer); }
- #endif
-
//! Requires: Disposer::operator()(pointer) shouldn't throw.
//!
//! Effects: Erases the range pointed to by b end e.
@@ -1370,9 +1368,8 @@ class unordered_multiset_impl
//!
//! Effects: Equivalent to this->insert(t) for each element in [b, e).
//!
- //! Complexity: Insert range is in general O(N * log(N)), where N is the
- //! size of the range. However, it is linear in N if the range is already sorted
- //! by value_comp().
+ //! Complexity: Average case is O(N), where N is the
+ //! size of the range.
//!
//! Throws: If the internal hasher or the equality functor throws. Basic guarantee.
//!
@@ -1390,8 +1387,8 @@ class unordered_multiset_impl
//!
//! Note: Invalidates the iterators (but not the references)
//! to the erased element. No destructors are called.
- void erase(const_iterator i)
- { table_.erase(i); }
+ iterator erase(const_iterator i)
+ { return table_.erase(i); }
//! Effects: Erases the range pointed to by b end e.
//!
@@ -1402,8 +1399,8 @@ class unordered_multiset_impl
//!
//! Note: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
- void erase(const_iterator b, const_iterator e)
- { table_.erase(b, e); }
+ iterator erase(const_iterator b, const_iterator e)
+ { return table_.erase(b, e); }
//! Effects: Erases all the elements with the given value.
//!
@@ -1456,12 +1453,16 @@ class unordered_multiset_impl
//! Note: Invalidates the iterators
//! to the erased elements.
template
- void erase_and_dispose(const_iterator i, Disposer disposer)
- { table_.erase_and_dispose(i, disposer); }
+ iterator erase_and_dispose(const_iterator i, Disposer disposer
+ /// @cond
+ , typename detail::enable_if_c::value >::type * = 0
+ /// @endcond
+ )
+ { return table_.erase_and_dispose(i, disposer); }
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
template
- iterator erase_and_dispose(iterator i, Disposer disposer)
+ iterator erase_and_dispose(const_iterator i, Disposer disposer)
{ return this->erase_and_dispose(const_iterator(i), disposer); }
#endif
@@ -1478,8 +1479,8 @@ class unordered_multiset_impl
//! Note: Invalidates the iterators
//! to the erased elements.
template
- void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
- { table_.erase_and_dispose(b, e, disposer); }
+ iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
+ { return table_.erase_and_dispose(b, e, disposer); }
//! Requires: Disposer::operator()(pointer) shouldn't throw.
//!
diff --git a/include/boost/intrusive/unordered_set_hook.hpp b/include/boost/intrusive/unordered_set_hook.hpp
index adb3a8d..286b318 100644
--- a/include/boost/intrusive/unordered_set_hook.hpp
+++ b/include/boost/intrusive/unordered_set_hook.hpp
@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Olaf Krzikalla 2004-2006.
-// (C) Copyright Ion Gaztanaga 2006-2008
+// (C) Copyright Ion Gaztanaga 2006-2009
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -222,6 +222,7 @@ class unordered_set_base_hook
>::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
//! Effects: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!
@@ -351,6 +352,7 @@ class unordered_set_member_hook
>::type
{
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
+ public:
//! Effects: If link_mode is \c auto_unlink or \c safe_link
//! initializes the node to an unlinked state.
//!