forked from boostorg/intrusive
* Big refactoring in order to reduce template and debug symbol bloat.
* Fixes #8698 * Implemented SCARY iterators [SVN r85165]
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -37,7 +37,7 @@ struct get_any_node_algo
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = none, class O2 = none, class O3 = none>
|
||||
template<class O1 = void, class O2 = void, class O3 = void>
|
||||
#endif
|
||||
struct make_any_base_hook
|
||||
{
|
||||
@@ -51,11 +51,11 @@ struct make_any_base_hook
|
||||
#endif
|
||||
>::type packed_options;
|
||||
|
||||
typedef detail::generic_hook
|
||||
typedef generic_hook
|
||||
< get_any_node_algo<typename packed_options::void_pointer>
|
||||
, typename packed_options::tag
|
||||
, packed_options::link_mode
|
||||
, detail::AnyBaseHook
|
||||
, AnyBaseHookId
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
@@ -142,7 +142,7 @@ class any_base_hook
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = none, class O2 = none, class O3 = none>
|
||||
template<class O1 = void, class O2 = void, class O3 = void>
|
||||
#endif
|
||||
struct make_any_member_hook
|
||||
{
|
||||
@@ -156,11 +156,11 @@ struct make_any_member_hook
|
||||
#endif
|
||||
>::type packed_options;
|
||||
|
||||
typedef detail::generic_hook
|
||||
typedef generic_hook
|
||||
< get_any_node_algo<typename packed_options::void_pointer>
|
||||
, member_tag
|
||||
, packed_options::link_mode
|
||||
, detail::NoBaseHook
|
||||
, NoBaseHookId
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
@@ -244,7 +244,7 @@ namespace detail{
|
||||
template<class ValueTraits>
|
||||
struct any_to_get_base_pointer_type
|
||||
{
|
||||
typedef typename pointer_traits<typename ValueTraits::boost_intrusive_tags::node_traits::node_ptr>::template
|
||||
typedef typename pointer_traits<typename ValueTraits::hooktags::node_traits::node_ptr>::template
|
||||
rebind_pointer<void>::type type;
|
||||
};
|
||||
|
||||
@@ -260,17 +260,18 @@ struct any_to_get_member_pointer_type
|
||||
template<class BaseHook, template <class> class NodeTraits>
|
||||
struct any_to_some_hook
|
||||
{
|
||||
typedef typename BaseHook::template pack<none>::value_traits old_value_traits;
|
||||
typedef typename BaseHook::template pack<empty>::proto_value_traits old_proto_value_traits;
|
||||
|
||||
template<class Base>
|
||||
struct pack : public Base
|
||||
{
|
||||
struct value_traits : public old_value_traits
|
||||
struct proto_value_traits : public old_proto_value_traits
|
||||
{
|
||||
static const bool is_any_hook = true;
|
||||
typedef typename detail::eval_if_c
|
||||
< detail::internal_base_hook_bool_is_true<old_value_traits>::value
|
||||
, any_to_get_base_pointer_type<old_value_traits>
|
||||
, any_to_get_member_pointer_type<old_value_traits>
|
||||
< detail::internal_base_hook_bool_is_true<old_proto_value_traits>::value
|
||||
, any_to_get_base_pointer_type<old_proto_value_traits>
|
||||
, any_to_get_member_pointer_type<old_proto_value_traits>
|
||||
>::type void_pointer;
|
||||
typedef NodeTraits<void_pointer> node_traits;
|
||||
};
|
||||
|
||||
+422
-2026
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -37,7 +37,7 @@ struct get_avl_set_node_algo
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = none, class O2 = none, class O3 = none, class O4 = none>
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
|
||||
#endif
|
||||
struct make_avl_set_base_hook
|
||||
{
|
||||
@@ -50,12 +50,12 @@ struct make_avl_set_base_hook
|
||||
#endif
|
||||
::type packed_options;
|
||||
|
||||
typedef detail::generic_hook
|
||||
typedef generic_hook
|
||||
< get_avl_set_node_algo<typename packed_options::void_pointer
|
||||
,packed_options::optimize_size>
|
||||
, typename packed_options::tag
|
||||
, packed_options::link_mode
|
||||
, detail::AvlSetBaseHook
|
||||
, AvlTreeBaseHookId
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
@@ -168,7 +168,7 @@ class avl_set_base_hook
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = none, class O2 = none, class O3 = none, class O4 = none>
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
|
||||
#endif
|
||||
struct make_avl_set_member_hook
|
||||
{
|
||||
@@ -181,12 +181,12 @@ struct make_avl_set_member_hook
|
||||
#endif
|
||||
::type packed_options;
|
||||
|
||||
typedef detail::generic_hook
|
||||
typedef generic_hook
|
||||
< get_avl_set_node_algo<typename packed_options::void_pointer
|
||||
,packed_options::optimize_size>
|
||||
, member_tag
|
||||
, packed_options::link_mode
|
||||
, detail::NoBaseHook
|
||||
, NoBaseHookId
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
|
||||
+264
-1511
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Daniel K. O. 2005.
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -21,20 +21,52 @@
|
||||
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
#include <boost/intrusive/detail/tree_algorithms.hpp>
|
||||
#include <boost/intrusive/bstree_algorithms.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace intrusive {
|
||||
|
||||
/// @cond
|
||||
|
||||
template<class NodeTraits, class F>
|
||||
struct avltree_node_cloner
|
||||
: private detail::ebo_functor_holder<F>
|
||||
{
|
||||
typedef typename NodeTraits::node_ptr node_ptr;
|
||||
typedef detail::ebo_functor_holder<F> base_t;
|
||||
|
||||
avltree_node_cloner(F f)
|
||||
: base_t(f)
|
||||
{}
|
||||
|
||||
node_ptr operator()(const node_ptr & p)
|
||||
{
|
||||
node_ptr n = base_t::get()(p);
|
||||
NodeTraits::set_balance(n, NodeTraits::get_balance(p));
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
template<class NodeTraits>
|
||||
struct avltree_erase_fixup
|
||||
{
|
||||
typedef typename NodeTraits::node_ptr node_ptr;
|
||||
|
||||
void operator()(const node_ptr & to_erase, const node_ptr & successor)
|
||||
{ NodeTraits::set_balance(successor, NodeTraits::get_balance(to_erase)); }
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
|
||||
//! avltree_algorithms is configured with a NodeTraits class, which encapsulates the
|
||||
//! information about the node to be manipulated. NodeTraits must support the
|
||||
//! following interface:
|
||||
//!
|
||||
//! <b>Typedefs</b>:
|
||||
//!
|
||||
//! <tt>node</tt>: The type of the node that forms the circular list
|
||||
//! <tt>node</tt>: The type of the node that forms the binary search tree
|
||||
//!
|
||||
//! <tt>node_ptr</tt>: A pointer to a node
|
||||
//!
|
||||
@@ -67,6 +99,9 @@ namespace intrusive {
|
||||
//! <tt>static balance positive();</tt>
|
||||
template<class NodeTraits>
|
||||
class avltree_algorithms
|
||||
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
: public bstree_algorithms<NodeTraits>
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
typedef typename NodeTraits::node node;
|
||||
@@ -77,161 +112,69 @@ class avltree_algorithms
|
||||
|
||||
/// @cond
|
||||
private:
|
||||
typedef detail::tree_algorithms<NodeTraits> tree_algorithms;
|
||||
typedef bstree_algorithms<NodeTraits> bstree_algorithms;
|
||||
|
||||
template<class F>
|
||||
struct avltree_node_cloner
|
||||
: private detail::ebo_functor_holder<F>
|
||||
{
|
||||
typedef detail::ebo_functor_holder<F> base_t;
|
||||
|
||||
avltree_node_cloner(F f)
|
||||
: base_t(f)
|
||||
{}
|
||||
|
||||
node_ptr operator()(const node_ptr &p)
|
||||
{
|
||||
node_ptr n = base_t::get()(p);
|
||||
NodeTraits::set_balance(n, NodeTraits::get_balance(p));
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
struct avltree_erase_fixup
|
||||
{
|
||||
void operator()(const node_ptr &to_erase, const node_ptr &successor)
|
||||
{ NodeTraits::set_balance(successor, NodeTraits::get_balance(to_erase)); }
|
||||
};
|
||||
|
||||
static node_ptr uncast(const const_node_ptr & ptr)
|
||||
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
static node_ptr begin_node(const const_node_ptr & header)
|
||||
{ return tree_algorithms::begin_node(header); }
|
||||
|
||||
static node_ptr end_node(const const_node_ptr & header)
|
||||
{ return tree_algorithms::end_node(header); }
|
||||
|
||||
//! This type is the information that will be
|
||||
//! filled by insert_unique_check
|
||||
typedef typename tree_algorithms::insert_commit_data insert_commit_data;
|
||||
typedef typename bstree_algorithms::insert_commit_data insert_commit_data;
|
||||
|
||||
//! <b>Requires</b>: header1 and header2 must be the header nodes
|
||||
//! of two trees.
|
||||
//!
|
||||
//! <b>Effects</b>: Swaps two trees. After the function header1 will contain
|
||||
//! links to the second tree and header2 will have links to the first tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static void swap_tree(const node_ptr & header1, const node_ptr & header2)
|
||||
{ return tree_algorithms::swap_tree(header1, header2); }
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Requires</b>: node1 and node2 can't be header nodes
|
||||
//! of two trees.
|
||||
//!
|
||||
//! <b>Effects</b>: Swaps two nodes. After the function node1 will be inserted
|
||||
//! in the position node2 before the function. node2 will be inserted in the
|
||||
//! position node1 had before the function.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: This function will break container ordering invariants if
|
||||
//! node1 and node2 are not equivalent according to the ordering rules.
|
||||
//!
|
||||
//!Experimental function
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const const_node_ptr&)
|
||||
static node_ptr get_header(const const_node_ptr & n);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::begin_node
|
||||
static node_ptr begin_node(const const_node_ptr & header);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::end_node
|
||||
static node_ptr end_node(const const_node_ptr & header);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree
|
||||
static void swap_tree(const node_ptr & header1, const node_ptr & header2);
|
||||
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&)
|
||||
static void swap_nodes(const node_ptr & node1, const node_ptr & node2)
|
||||
{
|
||||
if(node1 == node2)
|
||||
return;
|
||||
|
||||
node_ptr header1(tree_algorithms::get_header(node1)), header2(tree_algorithms::get_header(node2));
|
||||
node_ptr header1(bstree_algorithms::get_header(node1)), header2(bstree_algorithms::get_header(node2));
|
||||
swap_nodes(node1, header1, node2, header2);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: node1 and node2 can't be header nodes
|
||||
//! of two trees with header header1 and header2.
|
||||
//!
|
||||
//! <b>Effects</b>: Swaps two nodes. After the function node1 will be inserted
|
||||
//! in the position node2 before the function. node2 will be inserted in the
|
||||
//! position node1 had before the function.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: This function will break container ordering invariants if
|
||||
//! node1 and node2 are not equivalent according to the ordering rules.
|
||||
//!
|
||||
//!Experimental function
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&,const node_ptr&,const node_ptr&)
|
||||
static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2)
|
||||
{
|
||||
if(node1 == node2) return;
|
||||
|
||||
tree_algorithms::swap_nodes(node1, header1, node2, header2);
|
||||
bstree_algorithms::swap_nodes(node1, header1, node2, header2);
|
||||
//Swap balance
|
||||
balance c = NodeTraits::get_balance(node1);
|
||||
NodeTraits::set_balance(node1, NodeTraits::get_balance(node2));
|
||||
NodeTraits::set_balance(node2, c);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: node_to_be_replaced must be inserted in a tree
|
||||
//! and new_node must not be inserted in a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Replaces node_to_be_replaced in its position in the
|
||||
//! tree with new_node. The tree does not need to be rebalanced
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: This function will break container ordering invariants if
|
||||
//! new_node is not equivalent to node_to_be_replaced according to the
|
||||
//! ordering rules. This function is faster than erasing and inserting
|
||||
//! the node, since no rebalancing and comparison is needed.
|
||||
//!
|
||||
//!Experimental function
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&)
|
||||
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node)
|
||||
{
|
||||
if(node_to_be_replaced == new_node)
|
||||
return;
|
||||
replace_node(node_to_be_replaced, tree_algorithms::get_header(node_to_be_replaced), new_node);
|
||||
replace_node(node_to_be_replaced, bstree_algorithms::get_header(node_to_be_replaced), new_node);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: node_to_be_replaced must be inserted in a tree
|
||||
//! with header "header" and new_node must not be inserted in a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Replaces node_to_be_replaced in its position in the
|
||||
//! tree with new_node. The tree does not need to be rebalanced
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: This function will break container ordering invariants if
|
||||
//! new_node is not equivalent to node_to_be_replaced according to the
|
||||
//! ordering rules. This function is faster than erasing and inserting
|
||||
//! the node, since no rebalancing or comparison is needed.
|
||||
//!
|
||||
//!Experimental function
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&,const node_ptr&)
|
||||
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node)
|
||||
{
|
||||
tree_algorithms::replace_node(node_to_be_replaced, header, new_node);
|
||||
bstree_algorithms::replace_node(node_to_be_replaced, header, new_node);
|
||||
NodeTraits::set_balance(new_node, NodeTraits::get_balance(node_to_be_replaced));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: node is a tree node but not the header.
|
||||
//!
|
||||
//! <b>Effects</b>: Unlinks the node and rebalances the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity is constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::unlink(const node_ptr&)
|
||||
static void unlink(const node_ptr & node)
|
||||
{
|
||||
node_ptr x = NodeTraits::get_parent(node);
|
||||
@@ -242,84 +185,25 @@ class avltree_algorithms
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: header is the header of a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Unlinks the leftmost node from the tree, and
|
||||
//! updates the header link to the new leftmost node.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity is constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Notes</b>: This function breaks the tree and the tree 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.
|
||||
static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header)
|
||||
{ return tree_algorithms::unlink_leftmost_without_rebalance(header); }
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance
|
||||
static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header);
|
||||
|
||||
//! <b>Requires</b>: node is a node of the tree or an node initialized
|
||||
//! by init(...).
|
||||
//!
|
||||
//! <b>Effects</b>: Returns true if the node is initialized by init().
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static bool unique(const const_node_ptr & node)
|
||||
{ return tree_algorithms::unique(node); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::unique(const const_node_ptr&)
|
||||
static bool unique(const const_node_ptr & node);
|
||||
|
||||
//! <b>Requires</b>: node is a node of the tree but it's not the header.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns the number of nodes of the subtree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static std::size_t count(const const_node_ptr & node)
|
||||
{ return tree_algorithms::count(node); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::size(const const_node_ptr&)
|
||||
static std::size_t size(const const_node_ptr & header);
|
||||
|
||||
//! <b>Requires</b>: header is the header node of the tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns the number of nodes above the header.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static std::size_t size(const const_node_ptr & header)
|
||||
{ return tree_algorithms::size(header); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const node_ptr&)
|
||||
static node_ptr next_node(const node_ptr & node);
|
||||
|
||||
//! <b>Requires</b>: p is a node from the tree except the header.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns the next node of the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static node_ptr next_node(const node_ptr & p)
|
||||
{ return tree_algorithms::next_node(p); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const node_ptr&)
|
||||
static node_ptr prev_node(const node_ptr & node);
|
||||
|
||||
//! <b>Requires</b>: p is a node from the tree except the leftmost node.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns the previous node of the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static node_ptr prev_node(const node_ptr & p)
|
||||
{ return tree_algorithms::prev_node(p); }
|
||||
|
||||
//! <b>Requires</b>: node must not be part of any tree.
|
||||
//!
|
||||
//! <b>Effects</b>: After the function unique(node) == true.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
|
||||
static void init(const node_ptr & node)
|
||||
{ tree_algorithms::init(node); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::init(const node_ptr&)
|
||||
static void init(const node_ptr & node);
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Requires</b>: node must not be part of any tree.
|
||||
//!
|
||||
@@ -333,419 +217,148 @@ class avltree_algorithms
|
||||
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
|
||||
static void init_header(const node_ptr & header)
|
||||
{
|
||||
tree_algorithms::init_header(header);
|
||||
bstree_algorithms::init_header(header);
|
||||
NodeTraits::set_balance(header, NodeTraits::zero());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: header must be the header of a tree, z a node
|
||||
//! of that tree and z != header.
|
||||
//!
|
||||
//! <b>Effects</b>: Erases node "z" from the tree with header "header".
|
||||
//!
|
||||
//! <b>Complexity</b>: Amortized constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::erase(const node_ptr&,const node_ptr&)
|
||||
static node_ptr erase(const node_ptr & header, const node_ptr & z)
|
||||
{
|
||||
typename tree_algorithms::data_for_rebalance info;
|
||||
tree_algorithms::erase(header, z, avltree_erase_fixup(), info);
|
||||
node_ptr x = info.x;
|
||||
node_ptr x_parent = info.x_parent;
|
||||
|
||||
typename bstree_algorithms::data_for_rebalance info;
|
||||
bstree_algorithms::erase(header, z, avltree_erase_fixup<NodeTraits>(), info);
|
||||
//Rebalance avltree
|
||||
rebalance_after_erasure(header, x, x_parent);
|
||||
rebalance_after_erasure(header, info.x, info.x_parent);
|
||||
return z;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "cloner" must be a function
|
||||
//! object taking a node_ptr and returning a new cloned node of it. "disposer" must
|
||||
//! take a node_ptr and shouldn't throw.
|
||||
//!
|
||||
//! <b>Effects</b>: First empties target tree calling
|
||||
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
|
||||
//! except the header.
|
||||
//!
|
||||
//! Then, duplicates the entire tree pointed by "source_header" cloning each
|
||||
//! source node with <tt>node_ptr Cloner::operator()(const node_ptr &)</tt> to obtain
|
||||
//! the nodes of the target tree. If "cloner" throws, the cloned target nodes
|
||||
//! are disposed using <tt>void disposer(const node_ptr &)</tt>.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
|
||||
//! number of elements of tree target tree when calling this function.
|
||||
//!
|
||||
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::clone(const const_node_ptr&,const node_ptr&,Cloner,Disposer)
|
||||
template <class Cloner, class Disposer>
|
||||
static void clone
|
||||
(const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer)
|
||||
{
|
||||
avltree_node_cloner<Cloner> new_cloner(cloner);
|
||||
tree_algorithms::clone(source_header, target_header, new_cloner, disposer);
|
||||
avltree_node_cloner<NodeTraits, Cloner> new_cloner(cloner);
|
||||
bstree_algorithms::clone(source_header, target_header, new_cloner, disposer);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "disposer" must be an object function
|
||||
//! taking a node_ptr parameter and shouldn't throw.
|
||||
//!
|
||||
//! <b>Effects</b>: Empties the target tree calling
|
||||
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
|
||||
//! except the header.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
|
||||
//! number of elements of tree target tree when calling this function.
|
||||
//!
|
||||
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const node_ptr&,Disposer)
|
||||
template<class Disposer>
|
||||
static void clear_and_dispose(const node_ptr & header, Disposer disposer)
|
||||
{ tree_algorithms::clear_and_dispose(header, disposer); }
|
||||
static void clear_and_dispose(const node_ptr & header, Disposer disposer);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an node_ptr to the first element that is
|
||||
//! not less than "key" according to "comp" or "header" if that element does
|
||||
//! not exist.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr lower_bound
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return tree_algorithms::lower_bound(header, key, comp); }
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an node_ptr to the first element that is greater
|
||||
//! than "key" according to "comp" or "header" if that element does not exist.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr upper_bound
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return tree_algorithms::upper_bound(header, key, comp); }
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an node_ptr to the element that is equivalent to
|
||||
//! "key" according to "comp" or "header" if that element does not exist.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr find
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return tree_algorithms::find(header, key, comp); }
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an a pair of node_ptr delimiting a range containing
|
||||
//! all elements that are equivalent to "key" according to "comp" or an
|
||||
//! empty range that indicates the position where those elements would be
|
||||
//! if they there are no equivalent elements.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, node_ptr> equal_range
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return tree_algorithms::equal_range(header, key, comp); }
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If
|
||||
//! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an a pair with the following criteria:
|
||||
//!
|
||||
//! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise
|
||||
//!
|
||||
//! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//!
|
||||
//! <b>Note</b>: This function can be more efficient than calling upper_bound
|
||||
//! and lower_bound for lower_key and upper_key.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, node_ptr> bounded_range
|
||||
(const const_node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
|
||||
, bool left_closed, bool right_closed)
|
||||
{ return tree_algorithms::bounded_range(header, lower_key, upper_key, comp, left_closed, right_closed); }
|
||||
, bool left_closed, bool right_closed);
|
||||
|
||||
//! <b>Requires</b>: "h" 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.
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node into the tree before the upper bound
|
||||
//! according to "comp".
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity for insert element is at
|
||||
//! most logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(const node_ptr&,const node_ptr&,NodePtrCompare)
|
||||
template<class NodePtrCompare>
|
||||
static node_ptr insert_equal_upper_bound
|
||||
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp)
|
||||
{
|
||||
tree_algorithms::insert_equal_upper_bound(h, new_node, comp);
|
||||
bstree_algorithms::insert_equal_upper_bound(h, new_node, comp);
|
||||
rebalance_after_insertion(h, new_node);
|
||||
return new_node;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "h" 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.
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node into the tree before the lower bound
|
||||
//! according to "comp".
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity for insert element is at
|
||||
//! most logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(const node_ptr&,const node_ptr&,NodePtrCompare)
|
||||
template<class NodePtrCompare>
|
||||
static node_ptr insert_equal_lower_bound
|
||||
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp)
|
||||
{
|
||||
tree_algorithms::insert_equal_lower_bound(h, new_node, comp);
|
||||
bstree_algorithms::insert_equal_lower_bound(h, new_node, comp);
|
||||
rebalance_after_insertion(h, new_node);
|
||||
return new_node;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "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. "hint" is node from
|
||||
//! the "header"'s tree.
|
||||
//!
|
||||
//! <b>Effects</b>: 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).
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic in general, but it is amortized
|
||||
//! constant time if new_node is inserted immediately before "hint".
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(const node_ptr&,const node_ptr&,const node_ptr&,NodePtrCompare)
|
||||
template<class NodePtrCompare>
|
||||
static node_ptr insert_equal
|
||||
(const node_ptr & header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp)
|
||||
{
|
||||
tree_algorithms::insert_equal(header, hint, new_node, comp);
|
||||
bstree_algorithms::insert_equal(header, hint, new_node, comp);
|
||||
rebalance_after_insertion(header, new_node);
|
||||
return new_node;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "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.
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant-time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
|
||||
//! tree invariants might be broken.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(const node_ptr&,const node_ptr&,const node_ptr&)
|
||||
static node_ptr insert_before
|
||||
(const node_ptr & header, const node_ptr & pos, const node_ptr & new_node)
|
||||
{
|
||||
tree_algorithms::insert_before(header, pos, new_node);
|
||||
bstree_algorithms::insert_before(header, pos, new_node);
|
||||
rebalance_after_insertion(header, new_node);
|
||||
return new_node;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "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.
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant-time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: If "new_node" is less than the greatest inserted key
|
||||
//! tree invariants are broken. This function is slightly faster than
|
||||
//! using "insert_before".
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::push_back(const node_ptr&,const node_ptr&)
|
||||
static void push_back(const node_ptr & header, const node_ptr & new_node)
|
||||
{
|
||||
tree_algorithms::push_back(header, new_node);
|
||||
bstree_algorithms::push_back(header, new_node);
|
||||
rebalance_after_insertion(header, new_node);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "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.
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant-time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: If "new_node" is greater than the lowest inserted key
|
||||
//! tree invariants are broken. This function is slightly faster than
|
||||
//! using "insert_before".
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::push_front(const node_ptr&,const node_ptr&)
|
||||
static void push_front(const node_ptr & header, const node_ptr & new_node)
|
||||
{
|
||||
tree_algorithms::push_front(header, new_node);
|
||||
bstree_algorithms::push_front(header, new_node);
|
||||
rebalance_after_insertion(header, new_node);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. NodePtrCompare compares KeyType with a node_ptr.
|
||||
//!
|
||||
//! <b>Effects</b>: Checks if there is an equivalent node to "key" in the
|
||||
//! tree according to "comp" and obtains the needed information to realize
|
||||
//! a constant-time node insertion if there is no equivalent node.
|
||||
//!
|
||||
//! <b>Returns</b>: If there is an equivalent value
|
||||
//! returns a pair containing a node_ptr to the already present node
|
||||
//! and false. If there is not equivalent key can be inserted returns true
|
||||
//! in the returned pair's boolean and fills "commit_data" that is meant to
|
||||
//! be used with the "insert_commit" function to achieve a constant-time
|
||||
//! insertion function.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity is at most logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//!
|
||||
//! <b>Notes</b>: This function is used to improve performance when constructing
|
||||
//! a node is expensive and the user does not want to have two equivalent nodes
|
||||
//! in the tree: if there is an equivalent value
|
||||
//! the constructed object must be discarded. Many times, the part of the
|
||||
//! node that is used to impose the order is much cheaper to construct
|
||||
//! than the node and this function offers the possibility to use that part
|
||||
//! to check if the insertion will be successful.
|
||||
//!
|
||||
//! If the check is successful, the user can construct the node and use
|
||||
//! "insert_commit" to insert the node in constant-time. This gives a total
|
||||
//! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
|
||||
//!
|
||||
//! "commit_data" remains valid for a subsequent "insert_unique_commit" only
|
||||
//! if no more objects are inserted or erased from the set.
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, bool> insert_unique_check
|
||||
(const const_node_ptr & header, const KeyType &key
|
||||
,KeyNodePtrCompare comp, insert_commit_data &commit_data)
|
||||
{ return tree_algorithms::insert_unique_check(header, key, comp, commit_data); }
|
||||
,KeyNodePtrCompare comp, insert_commit_data &commit_data);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. NodePtrCompare compares KeyType with a node_ptr.
|
||||
//! "hint" is node from the "header"'s tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Checks if there is an equivalent node to "key" in the
|
||||
//! tree according to "comp" using "hint" as a hint to where it should be
|
||||
//! inserted and obtains the needed information to realize
|
||||
//! a constant-time node insertion if there is no equivalent node.
|
||||
//! If "hint" is the upper_bound the function has constant time
|
||||
//! complexity (two comparisons in the worst case).
|
||||
//!
|
||||
//! <b>Returns</b>: If there is an equivalent value
|
||||
//! returns a pair containing a node_ptr to the already present node
|
||||
//! and false. If there is not equivalent key can be inserted returns true
|
||||
//! in the returned pair's boolean and fills "commit_data" that is meant to
|
||||
//! be used with the "insert_commit" function to achieve a constant-time
|
||||
//! insertion function.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity is at most logarithmic, but it is
|
||||
//! amortized constant time if new_node should be inserted immediately before "hint".
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//!
|
||||
//! <b>Notes</b>: This function is used to improve performance when constructing
|
||||
//! a node is expensive and the user does not want to have two equivalent nodes
|
||||
//! in the tree: if there is an equivalent value
|
||||
//! the constructed object must be discarded. Many times, the part of the
|
||||
//! node that is used to impose the order is much cheaper to construct
|
||||
//! than the node and this function offers the possibility to use that part
|
||||
//! to check if the insertion will be successful.
|
||||
//!
|
||||
//! If the check is successful, the user can construct the node and use
|
||||
//! "insert_commit" to insert the node in constant-time. This gives a total
|
||||
//! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
|
||||
//!
|
||||
//! "commit_data" remains valid for a subsequent "insert_unique_commit" only
|
||||
//! if no more objects are inserted or erased from the set.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, bool> insert_unique_check
|
||||
(const const_node_ptr & header, const node_ptr &hint, const KeyType &key
|
||||
,KeyNodePtrCompare comp, insert_commit_data &commit_data)
|
||||
{ return tree_algorithms::insert_unique_check(header, hint, key, comp, commit_data); }
|
||||
,KeyNodePtrCompare comp, insert_commit_data &commit_data);
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Requires</b>: "header" must be the header node of a tree.
|
||||
//! "commit_data" must have been obtained from a previous call to
|
||||
//! "insert_unique_check". No objects should have been inserted or erased
|
||||
//! from the set between the "insert_unique_check" that filled "commit_data"
|
||||
//! and the call to "insert_commit".
|
||||
//!
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node in the set using the information obtained
|
||||
//! from the "commit_data" that a previous "insert_check" filled.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Notes</b>: This function has only sense if a "insert_unique_check" has been
|
||||
//! previously executed to fill "commit_data". No value should be inserted or
|
||||
//! erased between the "insert_check" and "insert_commit" calls.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(const node_ptr&,const node_ptr&,const insert_commit_data &)
|
||||
static void insert_unique_commit
|
||||
(const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data)
|
||||
{
|
||||
tree_algorithms::insert_unique_commit(header, new_value, commit_data);
|
||||
bstree_algorithms::insert_unique_commit(header, new_value, commit_data);
|
||||
rebalance_after_insertion(header, new_value);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "n" must be a node inserted in a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns a pointer to the header node of the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static node_ptr get_header(const node_ptr & n)
|
||||
{ return tree_algorithms::get_header(n); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::is_header
|
||||
static bool is_header(const const_node_ptr & p)
|
||||
{ return NodeTraits::get_balance(p) == NodeTraits::zero() && bstree_algorithms::is_header(p); }
|
||||
|
||||
|
||||
/// @cond
|
||||
private:
|
||||
|
||||
//! <b>Requires</b>: p is a node of a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns true if p is the header of the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static bool is_header(const const_node_ptr & p)
|
||||
{ return NodeTraits::get_balance(p) == NodeTraits::zero() && tree_algorithms::is_header(p); }
|
||||
|
||||
static void rebalance_after_erasure(const node_ptr & header, const node_ptr & xnode, const node_ptr & xnode_parent)
|
||||
{
|
||||
node_ptr x(xnode), x_parent(xnode_parent);
|
||||
@@ -903,8 +516,8 @@ class avltree_algorithms
|
||||
// / \ //
|
||||
// e f //
|
||||
node_ptr b = NodeTraits::get_left(a), c = NodeTraits::get_right(b);
|
||||
tree_algorithms::rotate_left(b, hdr);
|
||||
tree_algorithms::rotate_right(a, hdr);
|
||||
bstree_algorithms::rotate_left(b, hdr);
|
||||
bstree_algorithms::rotate_right(a, hdr);
|
||||
left_right_balancing(a, b, c);
|
||||
}
|
||||
|
||||
@@ -920,15 +533,15 @@ class avltree_algorithms
|
||||
// / \ //
|
||||
// e f //
|
||||
node_ptr b = NodeTraits::get_right(a), c = NodeTraits::get_left(b);
|
||||
tree_algorithms::rotate_right(b, hdr);
|
||||
tree_algorithms::rotate_left(a, hdr);
|
||||
bstree_algorithms::rotate_right(b, hdr);
|
||||
bstree_algorithms::rotate_left(a, hdr);
|
||||
left_right_balancing(b, a, c);
|
||||
}
|
||||
|
||||
static void rotate_left(const node_ptr x, const node_ptr & hdr)
|
||||
{
|
||||
const node_ptr y = NodeTraits::get_right(x);
|
||||
tree_algorithms::rotate_left(x, hdr);
|
||||
bstree_algorithms::rotate_left(x, hdr);
|
||||
|
||||
// reset the balancing factor
|
||||
if (NodeTraits::get_balance(y) == NodeTraits::positive()) {
|
||||
@@ -944,7 +557,7 @@ class avltree_algorithms
|
||||
static void rotate_right(const node_ptr x, const node_ptr & hdr)
|
||||
{
|
||||
const node_ptr y = NodeTraits::get_left(x);
|
||||
tree_algorithms::rotate_right(x, hdr);
|
||||
bstree_algorithms::rotate_right(x, hdr);
|
||||
|
||||
// reset the balancing factor
|
||||
if (NodeTraits::get_balance(y) == NodeTraits::negative()) {
|
||||
@@ -960,6 +573,16 @@ class avltree_algorithms
|
||||
/// @endcond
|
||||
};
|
||||
|
||||
/// @cond
|
||||
|
||||
template<class NodeTraits>
|
||||
struct get_algo<AvlTreeAlgorithms, NodeTraits>
|
||||
{
|
||||
typedef avltree_algorithms<NodeTraits> type;
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
|
||||
} //namespace intrusive
|
||||
} //namespace boost
|
||||
|
||||
|
||||
@@ -0,0 +1,922 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2013-2013
|
||||
//
|
||||
// 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_BS_SET_HPP
|
||||
#define BOOST_INTRUSIVE_BS_SET_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/detail/mpl.hpp>
|
||||
#include <boost/intrusive/bstree.hpp>
|
||||
#include <iterator>
|
||||
#include <boost/move/move.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace intrusive {
|
||||
|
||||
//! The class template bs_set is an intrusive container, that mimics most of
|
||||
//! the interface of std::set as described in the C++ standard.
|
||||
//!
|
||||
//! The template parameter \c T is the type to be managed by the container.
|
||||
//! The user can specify additional options and if no options are provided
|
||||
//! default options are used.
|
||||
//!
|
||||
//! The container supports the following options:
|
||||
//! \c base_hook<>/member_hook<>/value_traits<>,
|
||||
//! \c constant_time_size<>, \c size_type<> and
|
||||
//! \c compare<>.
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize>
|
||||
#endif
|
||||
class bs_set_impl
|
||||
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
: public bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, BsTreeAlgorithms>
|
||||
#endif
|
||||
{
|
||||
/// @cond
|
||||
typedef bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, BsTreeAlgorithms> tree_type;
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_set_impl)
|
||||
|
||||
typedef tree_type implementation_defined;
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
typedef typename implementation_defined::value_type value_type;
|
||||
typedef typename implementation_defined::value_traits value_traits;
|
||||
typedef typename implementation_defined::pointer pointer;
|
||||
typedef typename implementation_defined::const_pointer const_pointer;
|
||||
typedef typename implementation_defined::reference reference;
|
||||
typedef typename implementation_defined::const_reference const_reference;
|
||||
typedef typename implementation_defined::difference_type difference_type;
|
||||
typedef typename implementation_defined::size_type size_type;
|
||||
typedef typename implementation_defined::value_compare value_compare;
|
||||
typedef typename implementation_defined::key_compare key_compare;
|
||||
typedef typename implementation_defined::iterator iterator;
|
||||
typedef typename implementation_defined::const_iterator const_iterator;
|
||||
typedef typename implementation_defined::reverse_iterator reverse_iterator;
|
||||
typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator;
|
||||
typedef typename implementation_defined::insert_commit_data insert_commit_data;
|
||||
typedef typename implementation_defined::node_traits node_traits;
|
||||
typedef typename implementation_defined::node node;
|
||||
typedef typename implementation_defined::node_ptr node_ptr;
|
||||
typedef typename implementation_defined::const_node_ptr const_node_ptr;
|
||||
typedef typename implementation_defined::node_algorithms node_algorithms;
|
||||
|
||||
static const bool constant_time_size = tree_type::constant_time_size;
|
||||
|
||||
public:
|
||||
//! @copydoc ::boost::intrusive::bstree::bstree(const value_compare &,const value_traits &)
|
||||
explicit bs_set_impl( const value_compare &cmp = value_compare()
|
||||
, const value_traits &v_traits = value_traits())
|
||||
: tree_type(cmp, v_traits)
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
|
||||
template<class Iterator>
|
||||
bs_set_impl( Iterator b, Iterator e
|
||||
, const value_compare &cmp = value_compare()
|
||||
, const value_traits &v_traits = value_traits())
|
||||
: tree_type(true, b, e, cmp, v_traits)
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::bstree(bstree &&)
|
||||
bs_set_impl(BOOST_RV_REF(bs_set_impl) x)
|
||||
: tree_type(::boost::move(static_cast<tree_type&>(x)))
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::operator=(bstree &&)
|
||||
bs_set_impl& operator=(BOOST_RV_REF(bs_set_impl) x)
|
||||
{ return static_cast<bs_set_impl&>(tree_type::operator=(::boost::move(static_cast<tree_type&>(x)))); }
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree::~bstree()
|
||||
~bs_set_impl();
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::begin()
|
||||
iterator begin();
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::begin()const
|
||||
const_iterator begin() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::cbegin()const
|
||||
const_iterator cbegin() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::end()
|
||||
iterator end();
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::end()const
|
||||
const_iterator end() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::cend()const
|
||||
const_iterator cend() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::rbegin()
|
||||
reverse_iterator rbegin();
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::rbegin()const
|
||||
const_reverse_iterator rbegin() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::crbegin()const
|
||||
const_reverse_iterator crbegin() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::rend()
|
||||
reverse_iterator rend();
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::rend()const
|
||||
const_reverse_iterator rend() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::crend()const
|
||||
const_reverse_iterator crend() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator)
|
||||
static bs_set_impl &container_from_end_iterator(iterator end_iterator);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator)
|
||||
static const bs_set_impl &container_from_end_iterator(const_iterator end_iterator);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator)
|
||||
static bs_set_impl &container_from_iterator(iterator it);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator)
|
||||
static const bs_set_impl &container_from_iterator(const_iterator it);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::key_comp()const
|
||||
key_compare key_comp() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::value_comp()const
|
||||
value_compare value_comp() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::empty()const
|
||||
bool empty() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::size()const
|
||||
size_type size() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::swap
|
||||
void swap(bs_set_impl& other);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::clone_from
|
||||
template <class Cloner, class Disposer>
|
||||
void clone_from(const bs_set_impl &src, Cloner cloner, Disposer disposer);
|
||||
|
||||
#endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_unique(reference)
|
||||
std::pair<iterator, bool> insert(reference value)
|
||||
{ return tree_type::insert_unique(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_unique(const_iterator,reference)
|
||||
iterator insert(const_iterator hint, reference value)
|
||||
{ return tree_type::insert_unique(hint, value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const KeyType&,KeyValueCompare,insert_commit_data&)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator, bool> insert_check
|
||||
(const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
|
||||
{ return tree_type::insert_unique_check(key, key_value_comp, commit_data); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator, bool> insert_check
|
||||
(const_iterator hint, const KeyType &key
|
||||
,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
|
||||
{ return tree_type::insert_unique_check(hint, key, key_value_comp, commit_data); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator)
|
||||
template<class Iterator>
|
||||
void insert(Iterator b, Iterator e)
|
||||
{ tree_type::insert_unique(b, e); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_unique_commit
|
||||
iterator insert_commit(reference value, const insert_commit_data &commit_data)
|
||||
{ return tree_type::insert_unique_commit(value, commit_data); }
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_before
|
||||
iterator insert_before(const_iterator pos, reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::push_back
|
||||
void push_back(reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::push_front
|
||||
void push_front(reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator)
|
||||
iterator erase(const_iterator i);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator)
|
||||
iterator erase(const_iterator b, const_iterator e);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::erase(const_reference)
|
||||
size_type erase(const_reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type erase(const KeyType& key, KeyValueCompare comp);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
|
||||
template<class Disposer>
|
||||
iterator erase_and_dispose(const_iterator i, Disposer disposer);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,const_iterator,Disposer)
|
||||
template<class Disposer>
|
||||
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_reference, Disposer)
|
||||
template<class Disposer>
|
||||
size_type erase_and_dispose(const_reference value, Disposer disposer);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
|
||||
template<class KeyType, class KeyValueCompare, class Disposer>
|
||||
size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::clear
|
||||
void clear();
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::clear_and_dispose
|
||||
template<class Disposer>
|
||||
void clear_and_dispose(Disposer disposer);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::count(const_reference)const
|
||||
size_type count(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
|
||||
iterator lower_bound(const_reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
iterator lower_bound(const KeyType& key, KeyValueCompare comp);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
|
||||
const_iterator lower_bound(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
|
||||
iterator upper_bound(const_reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
iterator upper_bound(const KeyType& key, KeyValueCompare comp);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
|
||||
const_iterator upper_bound(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::find(const_reference)
|
||||
iterator find(const_reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
iterator find(const KeyType& key, KeyValueCompare comp);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::find(const_reference)const
|
||||
const_iterator find(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> equal_range(const_reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
|
||||
std::pair<iterator,iterator> bounded_range
|
||||
(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator,iterator> bounded_range
|
||||
(const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const
|
||||
std::pair<const_iterator, const_iterator>
|
||||
bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator> bounded_range
|
||||
(const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
|
||||
static iterator s_iterator_to(reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference)
|
||||
static const_iterator s_iterator_to(const_reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::iterator_to(reference)
|
||||
iterator iterator_to(reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const
|
||||
const_iterator iterator_to(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::init_node(reference)
|
||||
static void init_node(reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance
|
||||
pointer unlink_leftmost_without_rebalance();
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::replace_node
|
||||
void replace_node(iterator replace_this, reference with_this);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::remove_node
|
||||
void remove_node(reference value);
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
|
||||
template<class T, class ...Options>
|
||||
bool operator!= (const bs_set_impl<T, Options...> &x, const bs_set_impl<T, Options...> &y);
|
||||
|
||||
template<class T, class ...Options>
|
||||
bool operator>(const bs_set_impl<T, Options...> &x, const bs_set_impl<T, Options...> &y);
|
||||
|
||||
template<class T, class ...Options>
|
||||
bool operator<=(const bs_set_impl<T, Options...> &x, const bs_set_impl<T, Options...> &y);
|
||||
|
||||
template<class T, class ...Options>
|
||||
bool operator>=(const bs_set_impl<T, Options...> &x, const bs_set_impl<T, Options...> &y);
|
||||
|
||||
template<class T, class ...Options>
|
||||
void swap(bs_set_impl<T, Options...> &x, bs_set_impl<T, Options...> &y);
|
||||
|
||||
#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
|
||||
//! Helper metafunction to define a \c bs_set that yields to the same type when the
|
||||
//! same options (either explicitly or implicitly) are used.
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class T, class O1 = void, class O2 = void
|
||||
, class O3 = void, class O4 = void>
|
||||
#endif
|
||||
struct make_bs_set
|
||||
{
|
||||
/// @cond
|
||||
typedef typename pack_options
|
||||
< bstree_defaults,
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
Options...
|
||||
#endif
|
||||
>::type packed_options;
|
||||
|
||||
typedef typename detail::get_value_traits
|
||||
<T, typename packed_options::proto_value_traits>::type value_traits;
|
||||
|
||||
typedef bs_set_impl
|
||||
< value_traits
|
||||
, typename packed_options::compare
|
||||
, typename packed_options::size_type
|
||||
, packed_options::constant_time_size
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
};
|
||||
|
||||
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class T, class O1, class O2, class O3, class O4>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
#endif
|
||||
class bs_set
|
||||
: public make_bs_set<T,
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
Options...
|
||||
#endif
|
||||
>::type
|
||||
{
|
||||
typedef typename make_bs_set
|
||||
<T,
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
Options...
|
||||
#endif
|
||||
>::type Base;
|
||||
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_set)
|
||||
public:
|
||||
typedef typename Base::value_compare value_compare;
|
||||
typedef typename Base::value_traits value_traits;
|
||||
typedef typename Base::iterator iterator;
|
||||
typedef typename Base::const_iterator const_iterator;
|
||||
|
||||
//Assert if passed value traits are compatible with the type
|
||||
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
|
||||
|
||||
bs_set( const value_compare &cmp = value_compare()
|
||||
, const value_traits &v_traits = value_traits())
|
||||
: Base(cmp, v_traits)
|
||||
{}
|
||||
|
||||
template<class Iterator>
|
||||
bs_set( Iterator b, Iterator e
|
||||
, const value_compare &cmp = value_compare()
|
||||
, const value_traits &v_traits = value_traits())
|
||||
: Base(b, e, cmp, v_traits)
|
||||
{}
|
||||
|
||||
bs_set(BOOST_RV_REF(bs_set) x)
|
||||
: Base(::boost::move(static_cast<Base&>(x)))
|
||||
{}
|
||||
|
||||
bs_set& operator=(BOOST_RV_REF(bs_set) x)
|
||||
{ return static_cast<bs_set &>(this->Base::operator=(::boost::move(static_cast<Base&>(x)))); }
|
||||
|
||||
static bs_set &container_from_end_iterator(iterator end_iterator)
|
||||
{ return static_cast<bs_set &>(Base::container_from_end_iterator(end_iterator)); }
|
||||
|
||||
static const bs_set &container_from_end_iterator(const_iterator end_iterator)
|
||||
{ return static_cast<const bs_set &>(Base::container_from_end_iterator(end_iterator)); }
|
||||
|
||||
static bs_set &container_from_iterator(iterator it)
|
||||
{ return static_cast<bs_set &>(Base::container_from_iterator(it)); }
|
||||
|
||||
static const bs_set &container_from_iterator(const_iterator it)
|
||||
{ return static_cast<const bs_set &>(Base::container_from_iterator(it)); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//! The class template bs_multiset is an intrusive container, that mimics most of
|
||||
//! the interface of std::multiset as described in the C++ standard.
|
||||
//!
|
||||
//! The template parameter \c T is the type to be managed by the container.
|
||||
//! The user can specify additional options and if no options are provided
|
||||
//! default options are used.
|
||||
//!
|
||||
//! The container supports the following options:
|
||||
//! \c base_hook<>/member_hook<>/value_traits<>,
|
||||
//! \c constant_time_size<>, \c size_type<> and
|
||||
//! \c compare<>.
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class ValueTraits, class Compare, class SizeType, bool ConstantTimeSize>
|
||||
#endif
|
||||
class bs_multiset_impl
|
||||
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
: public bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms>
|
||||
#endif
|
||||
{
|
||||
/// @cond
|
||||
typedef bstree_impl<ValueTraits, Compare, SizeType, ConstantTimeSize, RbTreeAlgorithms> tree_type;
|
||||
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_multiset_impl)
|
||||
typedef tree_type implementation_defined;
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
typedef typename implementation_defined::value_type value_type;
|
||||
typedef typename implementation_defined::value_traits value_traits;
|
||||
typedef typename implementation_defined::pointer pointer;
|
||||
typedef typename implementation_defined::const_pointer const_pointer;
|
||||
typedef typename implementation_defined::reference reference;
|
||||
typedef typename implementation_defined::const_reference const_reference;
|
||||
typedef typename implementation_defined::difference_type difference_type;
|
||||
typedef typename implementation_defined::size_type size_type;
|
||||
typedef typename implementation_defined::value_compare value_compare;
|
||||
typedef typename implementation_defined::key_compare key_compare;
|
||||
typedef typename implementation_defined::iterator iterator;
|
||||
typedef typename implementation_defined::const_iterator const_iterator;
|
||||
typedef typename implementation_defined::reverse_iterator reverse_iterator;
|
||||
typedef typename implementation_defined::const_reverse_iterator const_reverse_iterator;
|
||||
typedef typename implementation_defined::insert_commit_data insert_commit_data;
|
||||
typedef typename implementation_defined::node_traits node_traits;
|
||||
typedef typename implementation_defined::node node;
|
||||
typedef typename implementation_defined::node_ptr node_ptr;
|
||||
typedef typename implementation_defined::const_node_ptr const_node_ptr;
|
||||
typedef typename implementation_defined::node_algorithms node_algorithms;
|
||||
|
||||
static const bool constant_time_size = tree_type::constant_time_size;
|
||||
|
||||
public:
|
||||
//! @copydoc ::boost::intrusive::bstree::bstree(const value_compare &,const value_traits &)
|
||||
explicit bs_multiset_impl( const value_compare &cmp = value_compare()
|
||||
, const value_traits &v_traits = value_traits())
|
||||
: tree_type(cmp, v_traits)
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::bstree(bool,Iterator,Iterator,const value_compare &,const value_traits &)
|
||||
template<class Iterator>
|
||||
bs_multiset_impl( Iterator b, Iterator e
|
||||
, const value_compare &cmp = value_compare()
|
||||
, const value_traits &v_traits = value_traits())
|
||||
: tree_type(false, b, e, cmp, v_traits)
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::bstree(bstree &&)
|
||||
bs_multiset_impl(BOOST_RV_REF(bs_multiset_impl) x)
|
||||
: tree_type(::boost::move(static_cast<tree_type&>(x)))
|
||||
{}
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::operator=(bstree &&)
|
||||
bs_multiset_impl& operator=(BOOST_RV_REF(bs_multiset_impl) x)
|
||||
{ return static_cast<bs_multiset_impl&>(tree_type::operator=(::boost::move(static_cast<tree_type&>(x)))); }
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree::~bstree()
|
||||
~bs_multiset_impl();
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::begin()
|
||||
iterator begin();
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::begin()const
|
||||
const_iterator begin() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::cbegin()const
|
||||
const_iterator cbegin() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::end()
|
||||
iterator end();
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::end()const
|
||||
const_iterator end() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::cend()const
|
||||
const_iterator cend() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::rbegin()
|
||||
reverse_iterator rbegin();
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::rbegin()const
|
||||
const_reverse_iterator rbegin() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::crbegin()const
|
||||
const_reverse_iterator crbegin() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::rend()
|
||||
reverse_iterator rend();
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::rend()const
|
||||
const_reverse_iterator rend() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::crend()const
|
||||
const_reverse_iterator crend() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(iterator)
|
||||
static bs_multiset_impl &container_from_end_iterator(iterator end_iterator);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::container_from_end_iterator(const_iterator)
|
||||
static const bs_multiset_impl &container_from_end_iterator(const_iterator end_iterator);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::container_from_iterator(iterator)
|
||||
static bs_multiset_impl &container_from_iterator(iterator it);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::container_from_iterator(const_iterator)
|
||||
static const bs_multiset_impl &container_from_iterator(const_iterator it);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::key_comp()const
|
||||
key_compare key_comp() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::value_comp()const
|
||||
value_compare value_comp() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::empty()const
|
||||
bool empty() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::size()const
|
||||
size_type size() const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::swap
|
||||
void swap(bs_multiset_impl& other);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::clone_from
|
||||
template <class Cloner, class Disposer>
|
||||
void clone_from(const bs_multiset_impl &src, Cloner cloner, Disposer disposer);
|
||||
|
||||
#endif //#ifdef BOOST_iNTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
|
||||
iterator insert(reference value)
|
||||
{ return tree_type::insert_equal(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_equal(const_iterator,reference)
|
||||
iterator insert(const_iterator hint, reference value)
|
||||
{ return tree_type::insert_equal(hint, value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_equal(Iterator,Iterator)
|
||||
template<class Iterator>
|
||||
void insert(Iterator b, Iterator e)
|
||||
{ tree_type::insert_equal(b, e); }
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_before
|
||||
iterator insert_before(const_iterator pos, reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::push_back
|
||||
void push_back(reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::push_front
|
||||
void push_front(reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator)
|
||||
iterator erase(const_iterator i);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::erase(const_iterator,const_iterator)
|
||||
iterator erase(const_iterator b, const_iterator e);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::erase(const_reference)
|
||||
size_type erase(const_reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::erase(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type erase(const KeyType& key, KeyValueCompare comp);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,Disposer)
|
||||
template<class Disposer>
|
||||
iterator erase_and_dispose(const_iterator i, Disposer disposer);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_iterator,const_iterator,Disposer)
|
||||
template<class Disposer>
|
||||
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const_reference, Disposer)
|
||||
template<class Disposer>
|
||||
size_type erase_and_dispose(const_reference value, Disposer disposer);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::erase_and_dispose(const KeyType&,KeyValueCompare,Disposer)
|
||||
template<class KeyType, class KeyValueCompare, class Disposer>
|
||||
size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::clear
|
||||
void clear();
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::clear_and_dispose
|
||||
template<class Disposer>
|
||||
void clear_and_dispose(Disposer disposer);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::count(const_reference)const
|
||||
size_type count(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
|
||||
iterator lower_bound(const_reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
iterator lower_bound(const KeyType& key, KeyValueCompare comp);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
|
||||
const_iterator lower_bound(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
|
||||
iterator upper_bound(const_reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
iterator upper_bound(const KeyType& key, KeyValueCompare comp);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
|
||||
const_iterator upper_bound(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::find(const_reference)
|
||||
iterator find(const_reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
iterator find(const KeyType& key, KeyValueCompare comp);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::find(const_reference)const
|
||||
const_iterator find(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> equal_range(const_reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
|
||||
std::pair<iterator,iterator> bounded_range
|
||||
(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator,iterator> bounded_range
|
||||
(const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)const
|
||||
std::pair<const_iterator, const_iterator>
|
||||
bounded_range(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::bounded_range(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator> bounded_range
|
||||
(const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(reference)
|
||||
static iterator s_iterator_to(reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::s_iterator_to(const_reference)
|
||||
static const_iterator s_iterator_to(const_reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::iterator_to(reference)
|
||||
iterator iterator_to(reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::iterator_to(const_reference)const
|
||||
const_iterator iterator_to(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::init_node(reference)
|
||||
static void init_node(reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::unlink_leftmost_without_rebalance
|
||||
pointer unlink_leftmost_without_rebalance();
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::replace_node
|
||||
void replace_node(iterator replace_this, reference with_this);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::remove_node
|
||||
void remove_node(reference value);
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
};
|
||||
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
|
||||
template<class T, class ...Options>
|
||||
bool operator!= (const bs_multiset_impl<T, Options...> &x, const bs_multiset_impl<T, Options...> &y);
|
||||
|
||||
template<class T, class ...Options>
|
||||
bool operator>(const bs_multiset_impl<T, Options...> &x, const bs_multiset_impl<T, Options...> &y);
|
||||
|
||||
template<class T, class ...Options>
|
||||
bool operator<=(const bs_multiset_impl<T, Options...> &x, const bs_multiset_impl<T, Options...> &y);
|
||||
|
||||
template<class T, class ...Options>
|
||||
bool operator>=(const bs_multiset_impl<T, Options...> &x, const bs_multiset_impl<T, Options...> &y);
|
||||
|
||||
template<class T, class ...Options>
|
||||
void swap(bs_multiset_impl<T, Options...> &x, bs_multiset_impl<T, Options...> &y);
|
||||
|
||||
#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
|
||||
//! Helper metafunction to define a \c bs_multiset that yields to the same type when the
|
||||
//! same options (either explicitly or implicitly) are used.
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class T, class O1 = void, class O2 = void
|
||||
, class O3 = void, class O4 = void>
|
||||
#endif
|
||||
struct make_bs_multiset
|
||||
{
|
||||
/// @cond
|
||||
typedef typename pack_options
|
||||
< bstree_defaults,
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
Options...
|
||||
#endif
|
||||
>::type packed_options;
|
||||
|
||||
typedef typename detail::get_value_traits
|
||||
<T, typename packed_options::proto_value_traits>::type value_traits;
|
||||
|
||||
typedef bs_multiset_impl
|
||||
< value_traits
|
||||
, typename packed_options::compare
|
||||
, typename packed_options::size_type
|
||||
, packed_options::constant_time_size
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
};
|
||||
|
||||
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class T, class O1, class O2, class O3, class O4>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
#endif
|
||||
class bs_multiset
|
||||
: public make_bs_multiset<T,
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
Options...
|
||||
#endif
|
||||
>::type
|
||||
{
|
||||
typedef typename make_bs_multiset<T,
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4
|
||||
#else
|
||||
Options...
|
||||
#endif
|
||||
>::type Base;
|
||||
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(bs_multiset)
|
||||
|
||||
public:
|
||||
typedef typename Base::value_compare value_compare;
|
||||
typedef typename Base::value_traits value_traits;
|
||||
typedef typename Base::iterator iterator;
|
||||
typedef typename Base::const_iterator const_iterator;
|
||||
|
||||
//Assert if passed value traits are compatible with the type
|
||||
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
|
||||
|
||||
bs_multiset( const value_compare &cmp = value_compare()
|
||||
, const value_traits &v_traits = value_traits())
|
||||
: Base(cmp, v_traits)
|
||||
{}
|
||||
|
||||
template<class Iterator>
|
||||
bs_multiset( Iterator b, Iterator e
|
||||
, const value_compare &cmp = value_compare()
|
||||
, const value_traits &v_traits = value_traits())
|
||||
: Base(b, e, cmp, v_traits)
|
||||
{}
|
||||
|
||||
bs_multiset(BOOST_RV_REF(bs_multiset) x)
|
||||
: Base(::boost::move(static_cast<Base&>(x)))
|
||||
{}
|
||||
|
||||
bs_multiset& operator=(BOOST_RV_REF(bs_multiset) x)
|
||||
{ return static_cast<bs_multiset &>(this->Base::operator=(::boost::move(static_cast<Base&>(x)))); }
|
||||
|
||||
static bs_multiset &container_from_end_iterator(iterator end_iterator)
|
||||
{ return static_cast<bs_multiset &>(Base::container_from_end_iterator(end_iterator)); }
|
||||
|
||||
static const bs_multiset &container_from_end_iterator(const_iterator end_iterator)
|
||||
{ return static_cast<const bs_multiset &>(Base::container_from_end_iterator(end_iterator)); }
|
||||
|
||||
static bs_multiset &container_from_iterator(iterator it)
|
||||
{ return static_cast<bs_multiset &>(Base::container_from_iterator(it)); }
|
||||
|
||||
static const bs_multiset &container_from_iterator(const_iterator it)
|
||||
{ return static_cast<const bs_multiset &>(Base::container_from_iterator(it)); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} //namespace intrusive
|
||||
} //namespace boost
|
||||
|
||||
#include <boost/intrusive/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTRUSIVE_BS_SET_HPP
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -17,7 +17,7 @@
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
#include <boost/intrusive/detail/tree_node.hpp>
|
||||
#include <boost/intrusive/detail/tree_algorithms.hpp>
|
||||
#include <boost/intrusive/bstree_algorithms.hpp>
|
||||
#include <boost/intrusive/options.hpp>
|
||||
#include <boost/intrusive/detail/generic_hook.hpp>
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace intrusive {
|
||||
template<class VoidPointer>
|
||||
struct get_bs_set_node_algo
|
||||
{
|
||||
typedef detail::tree_algorithms<tree_node_traits<VoidPointer> > type;
|
||||
typedef bstree_algorithms<tree_node_traits<VoidPointer> > type;
|
||||
};
|
||||
/// @endcond
|
||||
|
||||
@@ -37,7 +37,7 @@ struct get_bs_set_node_algo
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = none, class O2 = none, class O3 = none>
|
||||
template<class O1 = void, class O2 = void, class O3 = void>
|
||||
#endif
|
||||
struct make_bs_set_base_hook
|
||||
{
|
||||
@@ -50,14 +50,11 @@ struct make_bs_set_base_hook
|
||||
#endif
|
||||
::type packed_options;
|
||||
|
||||
//Scapegoat trees can't be auto unlink trees
|
||||
BOOST_STATIC_ASSERT(((int)packed_options::link_mode != (int)auto_unlink));
|
||||
|
||||
typedef detail::generic_hook
|
||||
typedef generic_hook
|
||||
< get_bs_set_node_algo<typename packed_options::void_pointer>
|
||||
, typename packed_options::tag
|
||||
, packed_options::link_mode
|
||||
, detail::BsSetBaseHook
|
||||
, BsTreeBaseHookId
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
@@ -168,7 +165,7 @@ class bs_set_base_hook
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = none, class O2 = none, class O3 = none>
|
||||
template<class O1 = void, class O2 = void, class O3 = void>
|
||||
#endif
|
||||
struct make_bs_set_member_hook
|
||||
{
|
||||
@@ -182,14 +179,11 @@ struct make_bs_set_member_hook
|
||||
|
||||
::type packed_options;
|
||||
|
||||
//Scapegoat trees can't be auto unlink trees
|
||||
BOOST_STATIC_ASSERT(((int)packed_options::link_mode != (int)auto_unlink));
|
||||
|
||||
typedef detail::generic_hook
|
||||
typedef generic_hook
|
||||
< get_bs_set_node_algo<typename packed_options::void_pointer>
|
||||
, member_tag
|
||||
, packed_options::link_mode
|
||||
, detail::NoBaseHook
|
||||
, NoBaseHookId
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+743
-497
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Olaf Krzikalla 2004-2006.
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
@@ -405,6 +406,16 @@ class circular_list_algorithms
|
||||
}
|
||||
};
|
||||
|
||||
/// @cond
|
||||
|
||||
template<class NodeTraits>
|
||||
struct get_algo<CircularListAlgorithms, NodeTraits>
|
||||
{
|
||||
typedef circular_list_algorithms<NodeTraits> type;
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
|
||||
} //namespace intrusive
|
||||
} //namespace boost
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Olaf Krzikalla 2004-2006.
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/detail/common_slist_algorithms.hpp>
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace boost {
|
||||
@@ -396,6 +397,16 @@ class circular_slist_algorithms
|
||||
}
|
||||
};
|
||||
|
||||
/// @cond
|
||||
|
||||
template<class NodeTraits>
|
||||
struct get_algo<CircularSListAlgorithms, NodeTraits>
|
||||
{
|
||||
typedef circular_slist_algorithms<NodeTraits> type;
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
|
||||
} //namespace intrusive
|
||||
} //namespace boost
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////} // ///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2013. 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)
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Joaquin M Lopez Munoz 2006-2012
|
||||
// (C) Copyright Joaquin M Lopez Munoz 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2009-2012.
|
||||
// (C) Copyright Ion Gaztanaga 2009-2013.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -24,85 +24,71 @@
|
||||
|
||||
namespace boost {
|
||||
namespace intrusive {
|
||||
namespace detail {
|
||||
|
||||
/// @cond
|
||||
|
||||
enum
|
||||
{ NoBaseHook
|
||||
, ListBaseHook
|
||||
, SlistBaseHook
|
||||
, SetBaseHook
|
||||
, UsetBaseHook
|
||||
, SplaySetBaseHook
|
||||
, AvlSetBaseHook
|
||||
, BsSetBaseHook
|
||||
, AnyBaseHook
|
||||
enum base_hook_type
|
||||
{ NoBaseHookId
|
||||
, ListBaseHookId
|
||||
, SlistBaseHookId
|
||||
, RbTreeBaseHookId
|
||||
, HashBaseHookId
|
||||
, SplayTreeBaseHookId
|
||||
, AvlTreeBaseHookId
|
||||
, BsTreeBaseHookId
|
||||
, AnyBaseHookId
|
||||
};
|
||||
|
||||
struct no_default_definer{};
|
||||
|
||||
template <class Hook, unsigned int>
|
||||
struct default_definer;
|
||||
template <class HookTags, unsigned int>
|
||||
struct hook_tags_definer{};
|
||||
|
||||
template <class Hook>
|
||||
struct default_definer<Hook, ListBaseHook>
|
||||
{ typedef Hook default_list_hook; };
|
||||
template <class HookTags>
|
||||
struct hook_tags_definer<HookTags, ListBaseHookId>
|
||||
{ typedef HookTags default_list_hook; };
|
||||
|
||||
template <class Hook>
|
||||
struct default_definer<Hook, SlistBaseHook>
|
||||
{ typedef Hook default_slist_hook; };
|
||||
template <class HookTags>
|
||||
struct hook_tags_definer<HookTags, SlistBaseHookId>
|
||||
{ typedef HookTags default_slist_hook; };
|
||||
|
||||
template <class Hook>
|
||||
struct default_definer<Hook, SetBaseHook>
|
||||
{ typedef Hook default_set_hook; };
|
||||
template <class HookTags>
|
||||
struct hook_tags_definer<HookTags, RbTreeBaseHookId>
|
||||
{ typedef HookTags default_rbtree_hook; };
|
||||
|
||||
template <class Hook>
|
||||
struct default_definer<Hook, UsetBaseHook>
|
||||
{ typedef Hook default_uset_hook; };
|
||||
template <class HookTags>
|
||||
struct hook_tags_definer<HookTags, HashBaseHookId>
|
||||
{ typedef HookTags default_hashtable_hook; };
|
||||
|
||||
template <class Hook>
|
||||
struct default_definer<Hook, SplaySetBaseHook>
|
||||
{ typedef Hook default_splay_set_hook; };
|
||||
template <class HookTags>
|
||||
struct hook_tags_definer<HookTags, SplayTreeBaseHookId>
|
||||
{ typedef HookTags default_splaytree_hook; };
|
||||
|
||||
template <class Hook>
|
||||
struct default_definer<Hook, AvlSetBaseHook>
|
||||
{ typedef Hook default_avl_set_hook; };
|
||||
template <class HookTags>
|
||||
struct hook_tags_definer<HookTags, AvlTreeBaseHookId>
|
||||
{ typedef HookTags default_avltree_hook; };
|
||||
|
||||
template <class Hook>
|
||||
struct default_definer<Hook, BsSetBaseHook>
|
||||
{ typedef Hook default_bs_set_hook; };
|
||||
template <class HookTags>
|
||||
struct hook_tags_definer<HookTags, BsTreeBaseHookId>
|
||||
{ typedef HookTags default_bstree_hook; };
|
||||
|
||||
template <class Hook>
|
||||
struct default_definer<Hook, AnyBaseHook>
|
||||
{ typedef Hook default_any_hook; };
|
||||
|
||||
template <class Hook, unsigned int BaseHookType>
|
||||
struct make_default_definer
|
||||
{
|
||||
typedef typename detail::if_c
|
||||
< BaseHookType != 0
|
||||
, default_definer<Hook, BaseHookType>
|
||||
, no_default_definer>::type type;
|
||||
};
|
||||
template <class HookTags>
|
||||
struct hook_tags_definer<HookTags, AnyBaseHookId>
|
||||
{ typedef HookTags default_any_hook; };
|
||||
|
||||
template
|
||||
< class GetNodeAlgorithms
|
||||
< class NodeTraits
|
||||
, class Tag
|
||||
, link_mode_type LinkMode
|
||||
, int HookType
|
||||
, base_hook_type BaseHookType
|
||||
>
|
||||
struct make_node_holder
|
||||
struct hooktags
|
||||
{
|
||||
typedef typename detail::if_c
|
||||
<!detail::is_same<Tag, member_tag>::value
|
||||
, detail::node_holder
|
||||
< typename GetNodeAlgorithms::type::node
|
||||
, Tag
|
||||
, LinkMode
|
||||
, HookType>
|
||||
, typename GetNodeAlgorithms::type::node
|
||||
>::type type;
|
||||
static const link_mode_type link_mode = LinkMode;
|
||||
typedef Tag tag;
|
||||
typedef NodeTraits node_traits;
|
||||
static const bool is_base_hook = !detail::is_same<Tag, member_tag>::value;
|
||||
static const bool safemode_or_autounlink = is_safe_autounlink<link_mode>::value;
|
||||
static const unsigned int type = BaseHookType;
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
@@ -111,22 +97,28 @@ template
|
||||
< class GetNodeAlgorithms
|
||||
, class Tag
|
||||
, link_mode_type LinkMode
|
||||
, int HookType
|
||||
, base_hook_type BaseHookType
|
||||
>
|
||||
class generic_hook
|
||||
/// @cond
|
||||
|
||||
//If the hook is a base hook, derive generic hook from detail::node_holder
|
||||
//If the hook is a base hook, derive generic hook from node_holder
|
||||
//so that a unique base class is created to convert from the node
|
||||
//to the type. This mechanism will be used by base_hook_traits.
|
||||
//to the type. This mechanism will be used by bhtraits.
|
||||
//
|
||||
//If the hook is a member hook, generic hook will directly derive
|
||||
//from the hook.
|
||||
: public make_default_definer
|
||||
< generic_hook<GetNodeAlgorithms, Tag, LinkMode, HookType>
|
||||
, detail::is_same<Tag, default_tag>::value*HookType
|
||||
: public detail::if_c
|
||||
< detail::is_same<Tag, member_tag>::value
|
||||
, typename GetNodeAlgorithms::type::node
|
||||
, node_holder<typename GetNodeAlgorithms::type::node, Tag, BaseHookType>
|
||||
>::type
|
||||
, public make_node_holder<GetNodeAlgorithms, Tag, LinkMode, HookType>::type
|
||||
//If this is the a default-tagged base hook derive from a class that
|
||||
//will define an special internal typedef. Containers will be able to detect this
|
||||
//special typedef and obtain generic_hook's internal types in order to deduce
|
||||
//value_traits for this hook.
|
||||
, public hook_tags_definer
|
||||
< generic_hook<GetNodeAlgorithms, Tag, LinkMode, BaseHookType>
|
||||
, detail::is_same<Tag, default_tag>::value*BaseHookType>
|
||||
/// @endcond
|
||||
{
|
||||
/// @cond
|
||||
@@ -136,16 +128,10 @@ class generic_hook
|
||||
typedef typename node_algorithms::const_node_ptr const_node_ptr;
|
||||
|
||||
public:
|
||||
struct boost_intrusive_tags
|
||||
{
|
||||
static const int hook_type = HookType;
|
||||
static const link_mode_type link_mode = LinkMode;
|
||||
typedef Tag tag;
|
||||
typedef typename GetNodeAlgorithms::type::node_traits node_traits;
|
||||
static const bool is_base_hook = !detail::is_same<Tag, member_tag>::value;
|
||||
static const bool safemode_or_autounlink =
|
||||
(int)link_mode == (int)auto_unlink || (int)link_mode == (int)safe_link;
|
||||
};
|
||||
|
||||
typedef hooktags
|
||||
< typename GetNodeAlgorithms::type::node_traits
|
||||
, Tag, LinkMode, BaseHookType> hooktags;
|
||||
|
||||
node_ptr this_ptr()
|
||||
{ return pointer_traits<node_ptr>::pointer_to(static_cast<node&>(*this)); }
|
||||
@@ -158,14 +144,14 @@ class generic_hook
|
||||
|
||||
generic_hook()
|
||||
{
|
||||
if(boost_intrusive_tags::safemode_or_autounlink){
|
||||
if(hooktags::safemode_or_autounlink){
|
||||
node_algorithms::init(this->this_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
generic_hook(const generic_hook& )
|
||||
{
|
||||
if(boost_intrusive_tags::safemode_or_autounlink){
|
||||
if(hooktags::safemode_or_autounlink){
|
||||
node_algorithms::init(this->this_ptr());
|
||||
}
|
||||
}
|
||||
@@ -176,7 +162,7 @@ class generic_hook
|
||||
~generic_hook()
|
||||
{
|
||||
destructor_impl
|
||||
(*this, detail::link_dispatch<boost_intrusive_tags::link_mode>());
|
||||
(*this, detail::link_dispatch<hooktags::link_mode>());
|
||||
}
|
||||
|
||||
void swap_nodes(generic_hook &other)
|
||||
@@ -188,19 +174,18 @@ class generic_hook
|
||||
bool is_linked() const
|
||||
{
|
||||
//is_linked() can be only used in safe-mode or auto-unlink
|
||||
BOOST_STATIC_ASSERT(( boost_intrusive_tags::safemode_or_autounlink ));
|
||||
BOOST_STATIC_ASSERT(( hooktags::safemode_or_autounlink ));
|
||||
return !node_algorithms::unique(this->this_ptr());
|
||||
}
|
||||
|
||||
void unlink()
|
||||
{
|
||||
BOOST_STATIC_ASSERT(( (int)boost_intrusive_tags::link_mode == (int)auto_unlink ));
|
||||
BOOST_STATIC_ASSERT(( (int)hooktags::link_mode == (int)auto_unlink ));
|
||||
node_algorithms::unlink(this->this_ptr());
|
||||
node_algorithms::init(this->this_ptr());
|
||||
}
|
||||
};
|
||||
|
||||
} //namespace detail
|
||||
} //namespace intrusive
|
||||
} //namespace boost
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2011-2013. 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)
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -20,11 +20,13 @@
|
||||
#include <boost/intrusive/circular_list_algorithms.hpp>
|
||||
#include <boost/intrusive/detail/mpl.hpp>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
//#include <boost/intrusive/detail/slist_node.hpp> //remove-me
|
||||
#include <boost/intrusive/slist.hpp> //remove-me
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/intrusive/trivial_value_traits.hpp>
|
||||
#include <cstddef>
|
||||
#include <boost/type_traits/make_unsigned.hpp>
|
||||
#include <boost/pointer_cast.hpp>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
@@ -89,6 +91,7 @@ struct bucket_traits_impl
|
||||
typedef typename pointer_traits
|
||||
<typename Slist::pointer>::template rebind_pointer
|
||||
< bucket_impl<Slist> >::type bucket_ptr;
|
||||
typedef Slist slist;
|
||||
typedef typename Slist::size_type size_type;
|
||||
/// @endcond
|
||||
|
||||
@@ -100,7 +103,6 @@ struct bucket_traits_impl
|
||||
: buckets_(x.buckets_), buckets_len_(x.buckets_len_)
|
||||
{}
|
||||
|
||||
|
||||
bucket_traits_impl(BOOST_RV_REF(bucket_traits_impl) x)
|
||||
: buckets_(x.buckets_), buckets_len_(x.buckets_len_)
|
||||
{ x.buckets_ = bucket_ptr(); x.buckets_len_ = 0; }
|
||||
@@ -127,57 +129,104 @@ struct bucket_traits_impl
|
||||
size_type buckets_len_;
|
||||
};
|
||||
|
||||
template<class Container, bool IsConst>
|
||||
template <class NodeTraits>
|
||||
struct hash_reduced_slist_node_traits
|
||||
{
|
||||
template <class U> static detail::one test(...);
|
||||
template <class U> static detail::two test(typename U::reduced_slist_node_traits* = 0);
|
||||
static const bool value = sizeof(test<NodeTraits>(0)) == sizeof(detail::two);
|
||||
};
|
||||
|
||||
template <class NodeTraits>
|
||||
struct apply_reduced_slist_node_traits
|
||||
{
|
||||
typedef typename NodeTraits::reduced_slist_node_traits type;
|
||||
};
|
||||
|
||||
template <class NodeTraits>
|
||||
struct reduced_slist_node_traits
|
||||
{
|
||||
typedef typename detail::eval_if_c
|
||||
< hash_reduced_slist_node_traits<NodeTraits>::value
|
||||
, apply_reduced_slist_node_traits<NodeTraits>
|
||||
, detail::identity<NodeTraits>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<class NodeTraits>
|
||||
struct get_slist_impl
|
||||
{
|
||||
typedef trivial_value_traits<NodeTraits, normal_link> trivial_traits;
|
||||
|
||||
//Reducing symbol length
|
||||
struct type : make_slist
|
||||
< typename NodeTraits::node
|
||||
, boost::intrusive::value_traits<trivial_traits>
|
||||
, boost::intrusive::constant_time_size<false>
|
||||
, boost::intrusive::size_type<typename boost::make_unsigned
|
||||
<typename pointer_traits<typename NodeTraits::node_ptr>::difference_type>::type >
|
||||
>::type
|
||||
{};
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
|
||||
template<class BucketValueTraits, bool IsConst>
|
||||
class hashtable_iterator
|
||||
: public std::iterator
|
||||
< std::forward_iterator_tag
|
||||
, typename Container::value_type
|
||||
, typename pointer_traits<typename Container::value_type*>::difference_type
|
||||
, typename BucketValueTraits::real_value_traits::value_type
|
||||
, typename pointer_traits<typename BucketValueTraits::real_value_traits::value_type*>::difference_type
|
||||
, typename detail::add_const_if_c
|
||||
<typename Container::value_type, IsConst>::type *
|
||||
<typename BucketValueTraits::real_value_traits::value_type, IsConst>::type *
|
||||
, typename detail::add_const_if_c
|
||||
<typename Container::value_type, IsConst>::type &
|
||||
<typename BucketValueTraits::real_value_traits::value_type, IsConst>::type &
|
||||
>
|
||||
{
|
||||
typedef typename Container::real_value_traits real_value_traits;
|
||||
typedef typename Container::siterator siterator;
|
||||
typedef typename Container::const_siterator const_siterator;
|
||||
typedef typename Container::bucket_type bucket_type;
|
||||
typedef typename BucketValueTraits::real_value_traits real_value_traits;
|
||||
typedef typename BucketValueTraits::real_bucket_traits real_bucket_traits;
|
||||
typedef typename real_value_traits::node_traits node_traits;
|
||||
typedef typename detail::get_slist_impl
|
||||
<typename detail::reduced_slist_node_traits
|
||||
<typename real_value_traits::node_traits>::type
|
||||
>::type slist_impl;
|
||||
typedef typename slist_impl::iterator siterator;
|
||||
typedef typename slist_impl::const_iterator const_siterator;
|
||||
typedef detail::bucket_impl<slist_impl> bucket_type;
|
||||
|
||||
typedef typename pointer_traits
|
||||
<typename Container::pointer>::template rebind_pointer
|
||||
< const Container >::type const_cont_ptr;
|
||||
typedef typename Container::size_type size_type;
|
||||
<typename real_value_traits::pointer>::template rebind_pointer
|
||||
< const BucketValueTraits >::type const_bucketvaltraits_ptr;
|
||||
typedef typename slist_impl::size_type size_type;
|
||||
|
||||
static typename Container::node_ptr downcast_bucket(typename bucket_type::node_ptr p)
|
||||
|
||||
static typename node_traits::node_ptr downcast_bucket(typename bucket_type::node_ptr p)
|
||||
{
|
||||
return pointer_traits<typename Container::node_ptr>::
|
||||
pointer_to(static_cast<typename Container::node&>(*p));
|
||||
return pointer_traits<typename node_traits::node_ptr>::
|
||||
pointer_to(static_cast<typename node_traits::node&>(*p));
|
||||
}
|
||||
|
||||
public:
|
||||
typedef typename Container::value_type value_type;
|
||||
typedef typename detail::add_const_if_c
|
||||
<typename Container::value_type, IsConst>::type *pointer;
|
||||
typedef typename detail::add_const_if_c
|
||||
<typename Container::value_type, IsConst>::type &reference;
|
||||
typedef typename real_value_traits::value_type value_type;
|
||||
typedef typename detail::add_const_if_c<value_type, IsConst>::type *pointer;
|
||||
typedef typename detail::add_const_if_c<value_type, IsConst>::type &reference;
|
||||
|
||||
hashtable_iterator ()
|
||||
{}
|
||||
|
||||
explicit hashtable_iterator(siterator ptr, const Container *cont)
|
||||
: slist_it_ (ptr), cont_ (cont ? pointer_traits<const_cont_ptr>::pointer_to(*cont) : const_cont_ptr() )
|
||||
explicit hashtable_iterator(siterator ptr, const BucketValueTraits *cont)
|
||||
: slist_it_ (ptr), traitsptr_ (cont ? pointer_traits<const_bucketvaltraits_ptr>::pointer_to(*cont) : const_bucketvaltraits_ptr() )
|
||||
{}
|
||||
|
||||
hashtable_iterator(const hashtable_iterator<Container, false> &other)
|
||||
: slist_it_(other.slist_it()), cont_(other.get_container())
|
||||
hashtable_iterator(const hashtable_iterator<BucketValueTraits, false> &other)
|
||||
: slist_it_(other.slist_it()), traitsptr_(other.get_bucket_value_traits())
|
||||
{}
|
||||
|
||||
const siterator &slist_it() const
|
||||
{ return slist_it_; }
|
||||
|
||||
hashtable_iterator<Container, false> unconst() const
|
||||
{ return hashtable_iterator<Container, false>(this->slist_it(), this->get_container()); }
|
||||
hashtable_iterator<BucketValueTraits, false> unconst() const
|
||||
{ return hashtable_iterator<BucketValueTraits, false>(this->slist_it(), this->get_bucket_value_traits()); }
|
||||
|
||||
public:
|
||||
hashtable_iterator& operator++()
|
||||
@@ -201,48 +250,57 @@ class hashtable_iterator
|
||||
|
||||
pointer operator->() const
|
||||
{
|
||||
return boost::intrusive::detail::to_raw_pointer(this->get_real_value_traits()->to_value_ptr
|
||||
return boost::intrusive::detail::to_raw_pointer(this->priv_real_value_traits().to_value_ptr
|
||||
(downcast_bucket(slist_it_.pointed_node())));
|
||||
}
|
||||
|
||||
const const_cont_ptr &get_container() const
|
||||
{ return cont_; }
|
||||
const const_bucketvaltraits_ptr &get_bucket_value_traits() const
|
||||
{ return traitsptr_; }
|
||||
|
||||
const real_value_traits *get_real_value_traits() const
|
||||
{ return &this->get_container()->get_real_value_traits(); }
|
||||
const real_value_traits &priv_real_value_traits() const
|
||||
{ return traitsptr_->priv_real_value_traits(); }
|
||||
|
||||
const real_bucket_traits &priv_real_bucket_traits() const
|
||||
{ return traitsptr_->priv_real_bucket_traits(); }
|
||||
|
||||
private:
|
||||
void increment()
|
||||
{
|
||||
const Container *cont = boost::intrusive::detail::to_raw_pointer(cont_);
|
||||
bucket_type* buckets = boost::intrusive::detail::to_raw_pointer(cont->bucket_pointer());
|
||||
size_type buckets_len = cont->bucket_count();
|
||||
const real_bucket_traits &rbuck_traits = this->priv_real_bucket_traits();
|
||||
bucket_type* const buckets = boost::intrusive::detail::to_raw_pointer(rbuck_traits.bucket_begin());
|
||||
const size_type buckets_len = rbuck_traits.bucket_count();
|
||||
|
||||
++slist_it_;
|
||||
if(buckets[0].cend().pointed_node() <= slist_it_.pointed_node() &&
|
||||
slist_it_.pointed_node()<= buckets[buckets_len].cend().pointed_node() ){
|
||||
//Now get the bucket_impl from the iterator
|
||||
const typename slist_impl::node_ptr n = slist_it_.pointed_node();
|
||||
const siterator first_bucket_bbegin = buckets->end();
|
||||
if(first_bucket_bbegin.pointed_node() <= n && n <= buckets[buckets_len-1].cend().pointed_node()){
|
||||
//If one-past the node is inside the bucket then look for the next non-empty bucket
|
||||
//1. get the bucket_impl from the iterator
|
||||
const bucket_type &b = static_cast<const bucket_type&>
|
||||
(bucket_type::slist_type::container_from_end_iterator(slist_it_));
|
||||
|
||||
//Now just calculate the index b has in the bucket array
|
||||
size_type n_bucket = static_cast<size_type>(&b - &buckets[0]);
|
||||
//2. Now just calculate the index b has in the bucket array
|
||||
size_type n_bucket = static_cast<size_type>(&b - buckets);
|
||||
|
||||
//3. Iterate until a non-empty bucket is found
|
||||
do{
|
||||
if (++n_bucket == buckets_len){
|
||||
slist_it_ = (&buckets[0] + buckets_len)->end();
|
||||
break;
|
||||
if (++n_bucket >= buckets_len){ //bucket overflow, return end() iterator
|
||||
slist_it_ = buckets->before_begin();
|
||||
return;
|
||||
}
|
||||
slist_it_ = buckets[n_bucket].begin();
|
||||
}
|
||||
while (slist_it_ == buckets[n_bucket].end());
|
||||
while (buckets[n_bucket].empty());
|
||||
slist_it_ = buckets[n_bucket].begin();
|
||||
}
|
||||
else{
|
||||
//++slist_it_ yield to a valid object
|
||||
}
|
||||
}
|
||||
|
||||
siterator slist_it_;
|
||||
const_cont_ptr cont_;
|
||||
siterator slist_it_;
|
||||
const_bucketvaltraits_ptr traitsptr_;
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
} //namespace intrusive {
|
||||
} //namespace boost {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2009-2012.
|
||||
// (C) Copyright Ion Gaztanaga 2009-2013.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Olaf Krzikalla 2004-2006.
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -65,41 +65,41 @@ struct list_node_traits
|
||||
|
||||
// list_iterator provides some basic functions for a
|
||||
// node oriented bidirectional iterator:
|
||||
template<class Container, bool IsConst>
|
||||
template<class RealValueTraits, bool IsConst>
|
||||
class list_iterator
|
||||
: public std::iterator
|
||||
< std::bidirectional_iterator_tag
|
||||
, typename Container::value_type
|
||||
, typename Container::difference_type
|
||||
, typename detail::if_c<IsConst,typename Container::const_pointer,typename Container::pointer>::type
|
||||
, typename detail::if_c<IsConst,typename Container::const_reference,typename Container::reference>::type
|
||||
>
|
||||
: public iiterator<RealValueTraits, IsConst, std::bidirectional_iterator_tag>::iterator_base
|
||||
{
|
||||
protected:
|
||||
typedef typename Container::real_value_traits real_value_traits;
|
||||
typedef typename real_value_traits::node_traits node_traits;
|
||||
typedef typename node_traits::node node;
|
||||
typedef typename node_traits::node_ptr node_ptr;
|
||||
typedef typename pointer_traits<node_ptr>::
|
||||
template rebind_pointer<void>::type void_pointer;
|
||||
static const bool store_container_ptr =
|
||||
detail::store_cont_ptr_on_it<Container>::value;
|
||||
typedef iiterator
|
||||
<RealValueTraits, IsConst, std::bidirectional_iterator_tag> types_t;
|
||||
|
||||
static const bool stateful_value_traits = types_t::stateful_value_traits;
|
||||
|
||||
typedef RealValueTraits real_value_traits;
|
||||
typedef typename types_t::node_traits node_traits;
|
||||
|
||||
typedef typename types_t::node node;
|
||||
typedef typename types_t::node_ptr node_ptr;
|
||||
typedef typename types_t::void_pointer void_pointer;
|
||||
|
||||
public:
|
||||
typedef typename Container::value_type value_type;
|
||||
typedef typename detail::if_c<IsConst,typename Container::const_pointer,typename Container::pointer>::type pointer;
|
||||
typedef typename detail::if_c<IsConst,typename Container::const_reference,typename Container::reference>::type reference;
|
||||
typedef typename types_t::value_type value_type;
|
||||
typedef typename types_t::pointer pointer;
|
||||
typedef typename types_t::reference reference;
|
||||
|
||||
typedef typename pointer_traits
|
||||
<void_pointer>::template rebind_pointer
|
||||
<const real_value_traits>::type const_real_value_traits_ptr;
|
||||
|
||||
list_iterator()
|
||||
: members_ (node_ptr(), 0)
|
||||
{}
|
||||
|
||||
explicit list_iterator(const node_ptr & node, const Container *cont_ptr)
|
||||
: members_ (node, cont_ptr)
|
||||
explicit list_iterator(const node_ptr & nodeptr, const const_real_value_traits_ptr &traits_ptr)
|
||||
: members_(nodeptr, traits_ptr)
|
||||
{}
|
||||
|
||||
list_iterator(list_iterator<Container, false> const& other)
|
||||
: members_(other.pointed_node(), other.get_container())
|
||||
list_iterator(list_iterator<RealValueTraits, false> const& other)
|
||||
: members_(other.pointed_node(), other.get_real_value_traits())
|
||||
{}
|
||||
|
||||
const node_ptr &pointed_node() const
|
||||
@@ -108,12 +108,14 @@ class list_iterator
|
||||
list_iterator &operator=(const node_ptr &node)
|
||||
{ members_.nodeptr_ = node; return static_cast<list_iterator&>(*this); }
|
||||
|
||||
const_real_value_traits_ptr get_real_value_traits() const
|
||||
{ return pointer_traits<const_real_value_traits_ptr>::static_cast_from(members_.get_ptr()); }
|
||||
|
||||
public:
|
||||
list_iterator& operator++()
|
||||
{
|
||||
node_ptr p = node_traits::get_next(members_.nodeptr_);
|
||||
members_.nodeptr_ = p;
|
||||
//members_.nodeptr_ = node_traits::get_next(members_.nodeptr_);
|
||||
return static_cast<list_iterator&> (*this);
|
||||
}
|
||||
|
||||
@@ -149,43 +151,11 @@ class list_iterator
|
||||
pointer operator->() const
|
||||
{ return this->get_real_value_traits()->to_value_ptr(members_.nodeptr_); }
|
||||
|
||||
const Container *get_container() const
|
||||
{
|
||||
if(store_container_ptr){
|
||||
const Container* c = static_cast<const Container*>(members_.get_ptr());
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(c != 0);
|
||||
return c;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
list_iterator<Container, false> unconst() const
|
||||
{ return list_iterator<Container, false>(this->pointed_node(), this->get_container()); }
|
||||
list_iterator<RealValueTraits, false> unconst() const
|
||||
{ return list_iterator<RealValueTraits, false>(this->pointed_node(), this->get_real_value_traits()); }
|
||||
|
||||
private:
|
||||
struct members
|
||||
: public detail::select_constptr
|
||||
<void_pointer, store_container_ptr>::type
|
||||
{
|
||||
typedef typename detail::select_constptr
|
||||
<void_pointer, store_container_ptr>::type Base;
|
||||
|
||||
members(const node_ptr &n_ptr, const void *cont)
|
||||
: Base(cont), nodeptr_(n_ptr)
|
||||
{}
|
||||
|
||||
node_ptr nodeptr_;
|
||||
} members_;
|
||||
iiterator_members<node_ptr, stateful_value_traits> members_;
|
||||
};
|
||||
|
||||
} //namespace intrusive
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2011-2013. 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)
|
||||
//
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -30,18 +30,38 @@ inline std::ptrdiff_t offset_from_pointer_to_member(const Member Parent::* ptr_t
|
||||
{
|
||||
//The implementation of a pointer to member is compiler dependent.
|
||||
#if defined(BOOST_INTRUSIVE_MSVC_ABI_PTR_TO_MEMBER)
|
||||
//msvc compliant compilers use their the first 32 bits as offset (even in 64 bit mode)
|
||||
|
||||
//MSVC compliant compilers use their the first 32 bits as offset (even in 64 bit mode)
|
||||
union caster_union
|
||||
{
|
||||
const Member Parent::* ptr_to_member;
|
||||
boost::int32_t offset;
|
||||
} caster;
|
||||
caster.ptr_to_member = ptr_to_member;
|
||||
|
||||
//MSVC ABI can use up to 3 int32 to represent pointer to member data
|
||||
//with virtual base classes, in those cases there is no simple to
|
||||
//obtain the address of parent. So static assert to avoid runtime errors
|
||||
//obtain the address of the parent. So static assert to avoid runtime errors
|
||||
BOOST_STATIC_ASSERT( sizeof(caster) == sizeof(boost::int32_t) );
|
||||
|
||||
caster.ptr_to_member = ptr_to_member;
|
||||
return std::ptrdiff_t(caster.offset);
|
||||
//Additional info on MSVC behaviour for the future. For 2/3 int ptr-to-member
|
||||
//types dereference seems to be:
|
||||
//
|
||||
// vboffset = [compile_time_offset if 2-int ptr2memb] /
|
||||
// [ptr2memb.i32[2] if 3-int ptr2memb].
|
||||
// vbtable = *(this + vboffset);
|
||||
// adj = vbtable[ptr2memb.i32[1]];
|
||||
// var = adj + (this + vboffset) + ptr2memb.i32[0];
|
||||
//
|
||||
//To reverse the operation we need to
|
||||
// - obtain vboffset (in 2-int ptr2memb implementation only)
|
||||
// - Go to Parent's vbtable and obtain adjustment at index ptr2memb.i32[1]
|
||||
// - parent = member - adj - vboffset - ptr2memb.i32[0]
|
||||
//
|
||||
//Even accessing to RTTI we might not be able to obtain this information
|
||||
//so anyone who thinks it's possible, please send a patch.
|
||||
|
||||
//This works with gcc, msvc, ac++, ibmcpp
|
||||
#elif defined(__GNUC__) || defined(__HP_aCC) || defined(BOOST_INTEL) || \
|
||||
defined(__IBMCPP__) || defined(__DECCXX)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2008-2013. 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)
|
||||
//
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Olaf Krzikalla 2004-2006.
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012.
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -20,6 +20,8 @@
|
||||
#include <boost/intrusive/rbtree_algorithms.hpp>
|
||||
#include <boost/intrusive/pointer_plus_bits.hpp>
|
||||
#include <boost/intrusive/detail/mpl.hpp>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
#include <boost/intrusive/detail/tree_node.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace intrusive {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Olaf Krzikalla 2004-2006.
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -15,7 +15,7 @@
|
||||
#define BOOST_INTRUSIVE_SLIST_NODE_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <iterator>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
|
||||
@@ -54,41 +54,41 @@ struct slist_node_traits
|
||||
|
||||
// slist_iterator provides some basic functions for a
|
||||
// node oriented bidirectional iterator:
|
||||
template<class Container, bool IsConst>
|
||||
template<class RealValueTraits, bool IsConst>
|
||||
class slist_iterator
|
||||
: public std::iterator
|
||||
< std::forward_iterator_tag
|
||||
, typename Container::value_type
|
||||
, typename Container::difference_type
|
||||
, typename detail::if_c<IsConst,typename Container::const_pointer,typename Container::pointer>::type
|
||||
, typename detail::if_c<IsConst,typename Container::const_reference,typename Container::reference>::type
|
||||
>
|
||||
: public iiterator<RealValueTraits, IsConst, std::forward_iterator_tag>::iterator_base
|
||||
{
|
||||
protected:
|
||||
typedef typename Container::real_value_traits real_value_traits;
|
||||
typedef typename real_value_traits::node_traits node_traits;
|
||||
typedef typename node_traits::node node;
|
||||
typedef typename node_traits::node_ptr node_ptr;
|
||||
typedef typename pointer_traits
|
||||
<node_ptr>::template rebind_pointer <void>::type void_pointer;
|
||||
static const bool store_container_ptr =
|
||||
detail::store_cont_ptr_on_it<Container>::value;
|
||||
typedef iiterator
|
||||
<RealValueTraits, IsConst, std::forward_iterator_tag> types_t;
|
||||
|
||||
static const bool stateful_value_traits = types_t::stateful_value_traits;
|
||||
|
||||
typedef RealValueTraits real_value_traits;
|
||||
typedef typename types_t::node_traits node_traits;
|
||||
|
||||
typedef typename types_t::node node;
|
||||
typedef typename types_t::node_ptr node_ptr;
|
||||
typedef typename types_t::void_pointer void_pointer;
|
||||
|
||||
public:
|
||||
typedef typename Container::value_type value_type;
|
||||
typedef typename detail::if_c<IsConst,typename Container::const_pointer,typename Container::pointer>::type pointer;
|
||||
typedef typename detail::if_c<IsConst,typename Container::const_reference,typename Container::reference>::type reference;
|
||||
typedef typename types_t::value_type value_type;
|
||||
typedef typename types_t::pointer pointer;
|
||||
typedef typename types_t::reference reference;
|
||||
|
||||
typedef typename pointer_traits
|
||||
<void_pointer>::template rebind_pointer
|
||||
<const real_value_traits>::type const_real_value_traits_ptr;
|
||||
|
||||
slist_iterator()
|
||||
: members_ (node_ptr(), 0)
|
||||
{}
|
||||
|
||||
explicit slist_iterator(const node_ptr & node, const Container *cont_ptr)
|
||||
: members_ (node, cont_ptr)
|
||||
explicit slist_iterator(const node_ptr & nodeptr, const const_real_value_traits_ptr &traits_ptr)
|
||||
: members_(nodeptr, traits_ptr)
|
||||
{}
|
||||
|
||||
slist_iterator(slist_iterator<Container, false> const& other)
|
||||
: members_(other.pointed_node(), other.get_container())
|
||||
slist_iterator(slist_iterator<RealValueTraits, false> const& other)
|
||||
: members_(other.pointed_node(), other.get_real_value_traits())
|
||||
{}
|
||||
|
||||
const node_ptr &pointed_node() const
|
||||
@@ -97,6 +97,9 @@ class slist_iterator
|
||||
slist_iterator &operator=(const node_ptr &node)
|
||||
{ members_.nodeptr_ = node; return static_cast<slist_iterator&>(*this); }
|
||||
|
||||
const_real_value_traits_ptr get_real_value_traits() const
|
||||
{ return pointer_traits<const_real_value_traits_ptr>::static_cast_from(members_.get_ptr()); }
|
||||
|
||||
public:
|
||||
slist_iterator& operator++()
|
||||
{
|
||||
@@ -123,39 +126,12 @@ class slist_iterator
|
||||
pointer operator->() const
|
||||
{ return this->get_real_value_traits()->to_value_ptr(members_.nodeptr_); }
|
||||
|
||||
const Container *get_container() const
|
||||
{
|
||||
if(store_container_ptr)
|
||||
return static_cast<const Container*>(members_.get_ptr());
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
slist_iterator<Container, false> unconst() const
|
||||
{ return slist_iterator<Container, false>(this->pointed_node(), this->get_container()); }
|
||||
|
||||
const real_value_traits *get_real_value_traits() const
|
||||
{
|
||||
if(store_container_ptr)
|
||||
return &this->get_container()->get_real_value_traits();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
slist_iterator<RealValueTraits, false> unconst() const
|
||||
{ return slist_iterator<RealValueTraits, false>(this->pointed_node(), this->get_real_value_traits()); }
|
||||
|
||||
private:
|
||||
struct members
|
||||
: public detail::select_constptr
|
||||
<void_pointer, store_container_ptr>::type
|
||||
{
|
||||
typedef typename detail::select_constptr
|
||||
<void_pointer, store_container_ptr>::type Base;
|
||||
|
||||
members(const node_ptr &n_ptr, const void *cont)
|
||||
: Base(cont), nodeptr_(n_ptr)
|
||||
{}
|
||||
|
||||
node_ptr nodeptr_;
|
||||
} members_;
|
||||
iiterator_members<node_ptr, stateful_value_traits> members_;
|
||||
};
|
||||
|
||||
} //namespace intrusive
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -15,8 +15,11 @@
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <iterator>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
#include <boost/intrusive/options.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/intrusive/detail/mpl.hpp>
|
||||
#include <boost/intrusive/bstree_algorithms.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace intrusive {
|
||||
@@ -77,43 +80,42 @@ struct tree_node_traits
|
||||
|
||||
// tree_iterator provides some basic functions for a
|
||||
// node oriented bidirectional iterator:
|
||||
template<class Container, bool IsConst>
|
||||
template<class RealValueTraits, bool IsConst>
|
||||
class tree_iterator
|
||||
: public std::iterator
|
||||
< std::bidirectional_iterator_tag
|
||||
, typename Container::value_type
|
||||
, typename Container::difference_type
|
||||
, typename detail::if_c<IsConst,typename Container::const_pointer,typename Container::pointer>::type
|
||||
, typename detail::if_c<IsConst,typename Container::const_reference,typename Container::reference>::type
|
||||
>
|
||||
: public iiterator<RealValueTraits, IsConst, std::bidirectional_iterator_tag>::iterator_base
|
||||
{
|
||||
protected:
|
||||
typedef typename Container::real_value_traits real_value_traits;
|
||||
typedef typename Container::node_algorithms node_algorithms;
|
||||
typedef typename real_value_traits::node_traits node_traits;
|
||||
typedef typename node_traits::node node;
|
||||
typedef typename node_traits::node_ptr node_ptr;
|
||||
typedef typename pointer_traits<node_ptr>::template
|
||||
rebind_pointer<void>::type void_pointer;
|
||||
static const bool store_container_ptr =
|
||||
detail::store_cont_ptr_on_it<Container>::value;
|
||||
typedef iiterator< RealValueTraits, IsConst
|
||||
, std::bidirectional_iterator_tag> types_t;
|
||||
|
||||
typedef RealValueTraits real_value_traits;
|
||||
typedef typename types_t::node_traits node_traits;
|
||||
|
||||
typedef typename types_t::node node;
|
||||
typedef typename types_t::node_ptr node_ptr;
|
||||
typedef typename types_t::void_pointer void_pointer;
|
||||
static const bool stateful_value_traits = types_t::stateful_value_traits;
|
||||
|
||||
typedef typename pointer_traits
|
||||
<void_pointer>::template rebind_pointer
|
||||
<const real_value_traits>::type const_real_value_traits_ptr;
|
||||
|
||||
public:
|
||||
typedef typename Container::value_type value_type;
|
||||
typedef typename detail::if_c<IsConst,typename Container::const_pointer,typename Container::pointer>::type pointer;
|
||||
typedef typename detail::if_c<IsConst,typename Container::const_reference,typename Container::reference>::type reference;
|
||||
typedef typename types_t::value_type value_type;
|
||||
typedef typename types_t::pointer pointer;
|
||||
typedef typename types_t::reference reference;
|
||||
|
||||
typedef bstree_algorithms<node_traits> node_algorithms;
|
||||
|
||||
tree_iterator()
|
||||
: members_ (node_ptr(), (const void *)0)
|
||||
{}
|
||||
|
||||
explicit tree_iterator(const node_ptr & nodeptr, const Container *cont_ptr)
|
||||
: members_ (nodeptr, cont_ptr)
|
||||
explicit tree_iterator(const node_ptr & nodeptr, const const_real_value_traits_ptr &traits_ptr)
|
||||
: members_(nodeptr, traits_ptr)
|
||||
{}
|
||||
|
||||
tree_iterator(tree_iterator<Container, false> const& other)
|
||||
: members_(other.pointed_node(), other.get_container())
|
||||
tree_iterator(tree_iterator<real_value_traits, false> const& other)
|
||||
: members_(other.pointed_node(), other.get_real_value_traits())
|
||||
{}
|
||||
|
||||
const node_ptr &pointed_node() const
|
||||
@@ -161,34 +163,21 @@ class tree_iterator
|
||||
pointer operator->() const
|
||||
{ return this->get_real_value_traits()->to_value_ptr(members_.nodeptr_); }
|
||||
|
||||
const Container *get_container() const
|
||||
{ return static_cast<const Container*>(members_.get_ptr()); }
|
||||
|
||||
const real_value_traits *get_real_value_traits() const
|
||||
{ return &this->get_container()->get_real_value_traits(); }
|
||||
const_real_value_traits_ptr get_real_value_traits() const
|
||||
{
|
||||
return pointer_traits<const_real_value_traits_ptr>::static_cast_from(members_.get_ptr());
|
||||
}
|
||||
|
||||
tree_iterator end_iterator_from_it() const
|
||||
{
|
||||
return tree_iterator(node_algorithms::get_header(this->pointed_node()), this->get_container());
|
||||
return tree_iterator(node_algorithms::get_header(this->pointed_node()), this->get_real_value_traits());
|
||||
}
|
||||
|
||||
tree_iterator<Container, false> unconst() const
|
||||
{ return tree_iterator<Container, false>(this->pointed_node(), this->get_container()); }
|
||||
tree_iterator<real_value_traits, false> unconst() const
|
||||
{ return tree_iterator<real_value_traits, false>(this->pointed_node(), this->get_real_value_traits()); }
|
||||
|
||||
private:
|
||||
struct members
|
||||
: public detail::select_constptr
|
||||
<void_pointer, store_container_ptr>::type
|
||||
{
|
||||
typedef typename detail::select_constptr
|
||||
<void_pointer, store_container_ptr>::type Base;
|
||||
|
||||
members(const node_ptr &n_ptr, const void *cont)
|
||||
: Base(cont), nodeptr_(n_ptr)
|
||||
{}
|
||||
|
||||
node_ptr nodeptr_;
|
||||
} members_;
|
||||
iiterator_members<node_ptr, stateful_value_traits> members_;
|
||||
};
|
||||
|
||||
} //namespace intrusive
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -29,9 +29,36 @@
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
#include <functional>
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace intrusive {
|
||||
|
||||
enum algo_types
|
||||
{
|
||||
CircularListAlgorithms,
|
||||
CircularSListAlgorithms,
|
||||
LinearSListAlgorithms,
|
||||
BsTreeAlgorithms,
|
||||
RbTreeAlgorithms,
|
||||
AvlTreeAlgorithms,
|
||||
SgTreeAlgorithms,
|
||||
SplayTreeAlgorithms,
|
||||
TreapAlgorithms
|
||||
};
|
||||
|
||||
template<algo_types AlgoType, class NodeTraits>
|
||||
struct get_algo;
|
||||
|
||||
template <link_mode_type link_mode>
|
||||
struct is_safe_autounlink
|
||||
{
|
||||
static const bool value =
|
||||
(int)link_mode == (int)auto_unlink ||
|
||||
(int)link_mode == (int)safe_link;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T>
|
||||
@@ -60,17 +87,12 @@ struct TRAITS_PREFIX##_bool_is_true\
|
||||
};\
|
||||
//
|
||||
|
||||
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_base_hook, boost_intrusive_tags::is_base_hook)
|
||||
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_base_hook, hooktags::is_base_hook)
|
||||
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_any_hook, is_any_hook)
|
||||
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(external_value_traits, external_value_traits)
|
||||
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(external_bucket_traits, external_bucket_traits)
|
||||
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(resizable, resizable)
|
||||
|
||||
template<class Node, class Tag, link_mode_type LinkMode, int>
|
||||
struct node_holder
|
||||
: public Node
|
||||
{};
|
||||
|
||||
template <class T>
|
||||
inline T* to_raw_pointer(T* p)
|
||||
{ return p; }
|
||||
@@ -114,7 +136,7 @@ class init_disposer
|
||||
{ NodeAlgorithms::init(p); }
|
||||
};
|
||||
|
||||
template<bool ConstantSize, class SizeType>
|
||||
template<bool ConstantSize, class SizeType, class Tag = void>
|
||||
struct size_holder
|
||||
{
|
||||
static const bool constant_time_size = ConstantSize;
|
||||
@@ -166,17 +188,17 @@ struct size_holder<false, SizeType>
|
||||
{}
|
||||
};
|
||||
|
||||
template<class KeyValueCompare, class Container>
|
||||
template<class KeyValueCompare, class RealValueTraits>
|
||||
struct key_nodeptr_comp
|
||||
: private detail::ebo_functor_holder<KeyValueCompare>
|
||||
{
|
||||
typedef typename Container::real_value_traits real_value_traits;
|
||||
typedef typename Container::value_type value_type;
|
||||
typedef RealValueTraits real_value_traits;
|
||||
typedef typename real_value_traits::value_type value_type;
|
||||
typedef typename real_value_traits::node_ptr node_ptr;
|
||||
typedef typename real_value_traits::const_node_ptr const_node_ptr;
|
||||
typedef detail::ebo_functor_holder<KeyValueCompare> base_t;
|
||||
key_nodeptr_comp(KeyValueCompare kcomp, const Container *cont)
|
||||
: base_t(kcomp), cont_(cont)
|
||||
key_nodeptr_comp(KeyValueCompare kcomp, const RealValueTraits *traits)
|
||||
: base_t(kcomp), traits_(traits)
|
||||
{}
|
||||
|
||||
template<class T>
|
||||
@@ -188,7 +210,7 @@ struct key_nodeptr_comp
|
||||
template<class T>
|
||||
const value_type & key_forward
|
||||
(const T &node, typename enable_if_c<is_node_ptr<T>::value>::type * = 0) const
|
||||
{ return *cont_->get_real_value_traits().to_value_ptr(node); }
|
||||
{ return *traits_->to_value_ptr(node); }
|
||||
|
||||
template<class T>
|
||||
const T & key_forward(const T &key, typename enable_if_c<!is_node_ptr<T>::value>::type* = 0) const
|
||||
@@ -199,27 +221,28 @@ struct key_nodeptr_comp
|
||||
bool operator()(const KeyType &key1, const KeyType2 &key2) const
|
||||
{ return base_t::get()(this->key_forward(key1), this->key_forward(key2)); }
|
||||
|
||||
const Container *cont_;
|
||||
const RealValueTraits *traits_;
|
||||
};
|
||||
|
||||
template<class F, class Container>
|
||||
template<class F, class RealValueTraits, algo_types AlgoType>
|
||||
struct node_cloner
|
||||
: private detail::ebo_functor_holder<F>
|
||||
{
|
||||
typedef typename Container::real_value_traits real_value_traits;
|
||||
typedef typename Container::node_algorithms node_algorithms;
|
||||
typedef typename real_value_traits::value_type value_type;
|
||||
typedef typename real_value_traits::pointer pointer;
|
||||
typedef typename real_value_traits::node_traits::node node;
|
||||
typedef typename real_value_traits::node_ptr node_ptr;
|
||||
typedef RealValueTraits real_value_traits;
|
||||
typedef typename real_value_traits::node_traits node_traits;
|
||||
typedef typename node_traits::node_ptr node_ptr;
|
||||
typedef detail::ebo_functor_holder<F> base_t;
|
||||
typedef typename get_algo< AlgoType
|
||||
, node_traits>::type node_algorithms;
|
||||
static const bool safemode_or_autounlink =
|
||||
is_safe_autounlink<real_value_traits::link_mode>::value;
|
||||
typedef typename real_value_traits::value_type value_type;
|
||||
typedef typename real_value_traits::pointer pointer;
|
||||
typedef typename node_traits::node node;
|
||||
typedef typename real_value_traits::const_node_ptr const_node_ptr;
|
||||
typedef detail::ebo_functor_holder<F> base_t;
|
||||
enum { safemode_or_autounlink =
|
||||
(int)real_value_traits::link_mode == (int)auto_unlink ||
|
||||
(int)real_value_traits::link_mode == (int)safe_link };
|
||||
|
||||
node_cloner(F f, const Container *cont)
|
||||
: base_t(f), cont_(cont)
|
||||
node_cloner(F f, const RealValueTraits *traits)
|
||||
: base_t(f), traits_(traits)
|
||||
{}
|
||||
|
||||
node_ptr operator()(const node_ptr & p)
|
||||
@@ -228,50 +251,58 @@ struct node_cloner
|
||||
node_ptr operator()(const node &to_clone)
|
||||
{
|
||||
const value_type &v =
|
||||
*cont_->get_real_value_traits().to_value_ptr
|
||||
*traits_->to_value_ptr
|
||||
(pointer_traits<const_node_ptr>::pointer_to(to_clone));
|
||||
node_ptr n = cont_->get_real_value_traits().to_node_ptr(*base_t::get()(v));
|
||||
node_ptr n = traits_->to_node_ptr(*base_t::get()(v));
|
||||
//Cloned node must be in default mode if the linking mode requires it
|
||||
if(safemode_or_autounlink)
|
||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
|
||||
return n;
|
||||
}
|
||||
|
||||
const Container *cont_;
|
||||
const RealValueTraits *traits_;
|
||||
};
|
||||
|
||||
template<class F, class Container>
|
||||
template<class F, class RealValueTraits, algo_types AlgoType>
|
||||
struct node_disposer
|
||||
: private detail::ebo_functor_holder<F>
|
||||
{
|
||||
typedef typename Container::real_value_traits real_value_traits;
|
||||
typedef typename real_value_traits::node_ptr node_ptr;
|
||||
typedef RealValueTraits real_value_traits;
|
||||
typedef typename real_value_traits::node_traits node_traits;
|
||||
typedef typename node_traits::node_ptr node_ptr;
|
||||
typedef detail::ebo_functor_holder<F> base_t;
|
||||
typedef typename Container::node_algorithms node_algorithms;
|
||||
enum { safemode_or_autounlink =
|
||||
(int)real_value_traits::link_mode == (int)auto_unlink ||
|
||||
(int)real_value_traits::link_mode == (int)safe_link };
|
||||
typedef typename get_algo< AlgoType
|
||||
, node_traits>::type node_algorithms;
|
||||
static const bool safemode_or_autounlink =
|
||||
is_safe_autounlink<real_value_traits::link_mode>::value;
|
||||
|
||||
node_disposer(F f, const Container *cont)
|
||||
: base_t(f), cont_(cont)
|
||||
node_disposer(F f, const RealValueTraits *cont)
|
||||
: base_t(f), traits_(cont)
|
||||
{}
|
||||
|
||||
void operator()(const node_ptr & p)
|
||||
{
|
||||
if(safemode_or_autounlink)
|
||||
node_algorithms::init(p);
|
||||
base_t::get()(cont_->get_real_value_traits().to_value_ptr(p));
|
||||
base_t::get()(traits_->to_value_ptr(p));
|
||||
}
|
||||
const Container *cont_;
|
||||
const RealValueTraits *traits_;
|
||||
};
|
||||
|
||||
template<class VoidPointer>
|
||||
struct dummy_constptr
|
||||
{
|
||||
dummy_constptr(const void *)
|
||||
typedef typename boost::intrusive::pointer_traits<VoidPointer>::
|
||||
template rebind_pointer<const void>::type ConstVoidPtr;
|
||||
|
||||
explicit dummy_constptr(ConstVoidPtr)
|
||||
{}
|
||||
|
||||
const void *get_ptr() const
|
||||
{ return 0; }
|
||||
dummy_constptr()
|
||||
{}
|
||||
|
||||
ConstVoidPtr get_ptr() const
|
||||
{ return ConstVoidPtr(); }
|
||||
};
|
||||
|
||||
template<class VoidPointer>
|
||||
@@ -280,7 +311,10 @@ struct constptr
|
||||
typedef typename boost::intrusive::pointer_traits<VoidPointer>::
|
||||
template rebind_pointer<const void>::type ConstVoidPtr;
|
||||
|
||||
constptr(const void *ptr)
|
||||
constptr()
|
||||
{}
|
||||
|
||||
explicit constptr(const ConstVoidPtr &ptr)
|
||||
: const_void_ptr_(ptr)
|
||||
{}
|
||||
|
||||
@@ -296,7 +330,7 @@ struct select_constptr
|
||||
typedef typename detail::if_c
|
||||
< store_ptr
|
||||
, constptr<VoidPointer>
|
||||
, dummy_constptr
|
||||
, dummy_constptr<VoidPointer>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
@@ -330,148 +364,6 @@ template<class Hook>
|
||||
void destructor_impl(Hook &, detail::link_dispatch<normal_link>)
|
||||
{}
|
||||
|
||||
template<class T, class NodeTraits, link_mode_type LinkMode, class Tag, int HookType>
|
||||
struct base_hook_traits
|
||||
{
|
||||
public:
|
||||
typedef detail::node_holder
|
||||
<typename NodeTraits::node, Tag, LinkMode, HookType> node_holder;
|
||||
typedef typename NodeTraits::node node;
|
||||
typedef NodeTraits node_traits;
|
||||
typedef T value_type;
|
||||
typedef typename node_traits::node_ptr node_ptr;
|
||||
typedef typename node_traits::const_node_ptr const_node_ptr;
|
||||
typedef typename pointer_traits<node_ptr>::
|
||||
template rebind_pointer<T>::type pointer;
|
||||
typedef typename pointer_traits<node_ptr>::
|
||||
template rebind_pointer<const T>::type const_pointer;
|
||||
//typedef typename pointer_traits<pointer>::reference reference;
|
||||
//typedef typename pointer_traits<const_pointer>::reference const_reference;
|
||||
typedef T & reference;
|
||||
typedef const T & const_reference;
|
||||
typedef node_holder & node_holder_reference;
|
||||
typedef const node_holder & const_node_holder_reference;
|
||||
typedef node& node_reference;
|
||||
typedef const node & const_node_reference;
|
||||
|
||||
static const link_mode_type link_mode = LinkMode;
|
||||
|
||||
static pointer to_value_ptr(const node_ptr & n)
|
||||
{
|
||||
return pointer_traits<pointer>::pointer_to
|
||||
(static_cast<reference>(static_cast<node_holder_reference>(*n)));
|
||||
}
|
||||
|
||||
static const_pointer to_value_ptr(const const_node_ptr & n)
|
||||
{
|
||||
return pointer_traits<const_pointer>::pointer_to
|
||||
(static_cast<const_reference>(static_cast<const_node_holder_reference>(*n)));
|
||||
}
|
||||
|
||||
static node_ptr to_node_ptr(reference value)
|
||||
{
|
||||
return pointer_traits<node_ptr>::pointer_to
|
||||
(static_cast<node_reference>(static_cast<node_holder_reference>(value)));
|
||||
}
|
||||
|
||||
static const_node_ptr to_node_ptr(const_reference value)
|
||||
{
|
||||
return pointer_traits<const_node_ptr>::pointer_to
|
||||
(static_cast<const_node_reference>(static_cast<const_node_holder_reference>(value)));
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, class Hook, Hook T::* P>
|
||||
struct member_hook_traits
|
||||
{
|
||||
public:
|
||||
typedef Hook hook_type;
|
||||
typedef typename hook_type::boost_intrusive_tags::node_traits node_traits;
|
||||
typedef typename node_traits::node node;
|
||||
typedef T value_type;
|
||||
typedef typename node_traits::node_ptr node_ptr;
|
||||
typedef typename node_traits::const_node_ptr const_node_ptr;
|
||||
typedef typename pointer_traits<node_ptr>::
|
||||
template rebind_pointer<T>::type pointer;
|
||||
typedef typename pointer_traits<node_ptr>::
|
||||
template rebind_pointer<const T>::type const_pointer;
|
||||
typedef T & reference;
|
||||
typedef const T & const_reference;
|
||||
typedef node& node_reference;
|
||||
typedef const node & const_node_reference;
|
||||
typedef hook_type& hook_reference;
|
||||
typedef const hook_type & const_hook_reference;
|
||||
|
||||
static const link_mode_type link_mode = Hook::boost_intrusive_tags::link_mode;
|
||||
|
||||
static node_ptr to_node_ptr(reference value)
|
||||
{
|
||||
return pointer_traits<node_ptr>::pointer_to
|
||||
(static_cast<node_reference>(static_cast<hook_reference>(value.*P)));
|
||||
}
|
||||
|
||||
static const_node_ptr to_node_ptr(const_reference value)
|
||||
{
|
||||
return pointer_traits<const_node_ptr>::pointer_to
|
||||
(static_cast<const_node_reference>(static_cast<const_hook_reference>(value.*P)));
|
||||
}
|
||||
|
||||
static pointer to_value_ptr(const node_ptr & n)
|
||||
{
|
||||
return pointer_traits<pointer>::pointer_to
|
||||
(*detail::parent_from_member<T, Hook>
|
||||
(static_cast<Hook*>(boost::intrusive::detail::to_raw_pointer(n)), P));
|
||||
}
|
||||
|
||||
static const_pointer to_value_ptr(const const_node_ptr & n)
|
||||
{
|
||||
return pointer_traits<const_pointer>::pointer_to
|
||||
(*detail::parent_from_member<T, Hook>
|
||||
(static_cast<const Hook*>(boost::intrusive::detail::to_raw_pointer(n)), P));
|
||||
}
|
||||
};
|
||||
|
||||
template<class Functor>
|
||||
struct function_hook_traits
|
||||
{
|
||||
public:
|
||||
typedef typename Functor::hook_type hook_type;
|
||||
typedef typename Functor::hook_ptr hook_ptr;
|
||||
typedef typename Functor::const_hook_ptr const_hook_ptr;
|
||||
typedef typename hook_type::boost_intrusive_tags::node_traits node_traits;
|
||||
typedef typename node_traits::node node;
|
||||
typedef typename Functor::value_type value_type;
|
||||
typedef typename node_traits::node_ptr node_ptr;
|
||||
typedef typename node_traits::const_node_ptr const_node_ptr;
|
||||
typedef typename pointer_traits<node_ptr>::
|
||||
template rebind_pointer<value_type>::type pointer;
|
||||
typedef typename pointer_traits<node_ptr>::
|
||||
template rebind_pointer<const value_type>::type const_pointer;
|
||||
typedef value_type & reference;
|
||||
typedef const value_type & const_reference;
|
||||
static const link_mode_type link_mode = hook_type::boost_intrusive_tags::link_mode;
|
||||
|
||||
static node_ptr to_node_ptr(reference value)
|
||||
{ return static_cast<node*>(boost::intrusive::detail::to_raw_pointer(Functor::to_hook_ptr(value))); }
|
||||
|
||||
static const_node_ptr to_node_ptr(const_reference value)
|
||||
{ return static_cast<const node*>(boost::intrusive::detail::to_raw_pointer(Functor::to_hook_ptr(value))); }
|
||||
|
||||
static pointer to_value_ptr(const node_ptr & n)
|
||||
{ return Functor::to_value_ptr(to_hook_ptr(n)); }
|
||||
|
||||
static const_pointer to_value_ptr(const const_node_ptr & n)
|
||||
{ return Functor::to_value_ptr(to_hook_ptr(n)); }
|
||||
|
||||
private:
|
||||
static hook_ptr to_hook_ptr(const node_ptr & n)
|
||||
{ return hook_ptr(&*static_cast<hook_type*>(&*n)); }
|
||||
|
||||
static const_hook_ptr to_hook_ptr(const const_node_ptr & n)
|
||||
{ return const_hook_ptr(&*static_cast<const hook_type*>(&*n)); }
|
||||
};
|
||||
|
||||
|
||||
//This function uses binary search to discover the
|
||||
//highest set bit of the integer
|
||||
inline std::size_t floor_log2 (std::size_t x)
|
||||
@@ -492,6 +384,8 @@ inline std::size_t floor_log2 (std::size_t x)
|
||||
return log2;
|
||||
}
|
||||
|
||||
//Thanks to Laurent de Soras in
|
||||
//http://www.flipcode.com/archives/Fast_log_Function.shtml
|
||||
inline float fast_log2 (float val)
|
||||
{
|
||||
union caster_t
|
||||
@@ -502,13 +396,15 @@ inline float fast_log2 (float val)
|
||||
|
||||
caster.val = val;
|
||||
boost::uint32_t x = caster.x;
|
||||
const int log_2 = (int)(((x >> 23) & 255) - 128);
|
||||
x &= ~(255 << 23);
|
||||
x += 127 << 23;
|
||||
const int log_2 = int((x >> 23) & 255) - 128;
|
||||
x &= ~(boost::uint32_t(255u) << 23u);
|
||||
x += boost::uint32_t(127) << 23u;
|
||||
caster.x = x;
|
||||
val = caster.val;
|
||||
//1+log2(m), m ranging from 1 to 2
|
||||
//3rd degree polynomial keeping first derivate continuity.
|
||||
//For less precision the line can be commented out
|
||||
val = ((-1.0f/3.f) * val + 2.f) * val - (2.0f/3.f);
|
||||
|
||||
return (val + log_2);
|
||||
}
|
||||
|
||||
@@ -605,72 +501,47 @@ class exception_array_disposer
|
||||
}
|
||||
};
|
||||
|
||||
template<class ValueTraits, bool ExternalValueTraits>
|
||||
struct store_cont_ptr_on_it_impl
|
||||
{
|
||||
static const bool value = is_stateful_value_traits<ValueTraits>::value;
|
||||
};
|
||||
|
||||
template<class ValueTraits>
|
||||
struct store_cont_ptr_on_it_impl<ValueTraits, true>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <class Container>
|
||||
struct store_cont_ptr_on_it
|
||||
{
|
||||
typedef typename Container::value_traits value_traits;
|
||||
static const bool value = store_cont_ptr_on_it_impl
|
||||
<value_traits, external_value_traits_bool_is_true<value_traits>::value>::value;
|
||||
};
|
||||
|
||||
template<class Container, bool IsConst>
|
||||
template<class RealValueTraits, bool IsConst>
|
||||
struct node_to_value
|
||||
: public detail::select_constptr
|
||||
< typename pointer_traits
|
||||
<typename Container::pointer>::template rebind_pointer<void>::type
|
||||
, detail::store_cont_ptr_on_it<Container>::value
|
||||
<typename RealValueTraits::pointer>::template rebind_pointer<void>::type
|
||||
, is_stateful_value_traits<RealValueTraits>::value
|
||||
>::type
|
||||
{
|
||||
static const bool store_container_ptr =
|
||||
detail::store_cont_ptr_on_it<Container>::value;
|
||||
|
||||
typedef typename Container::real_value_traits real_value_traits;
|
||||
typedef typename real_value_traits::value_type value_type;
|
||||
static const bool stateful_value_traits = is_stateful_value_traits<RealValueTraits>::value;
|
||||
typedef typename detail::select_constptr
|
||||
< typename pointer_traits
|
||||
<typename Container::pointer>::template rebind_pointer<void>::type
|
||||
, store_container_ptr >::type Base;
|
||||
typedef typename real_value_traits::node_traits::node node;
|
||||
typedef typename detail::add_const_if_c
|
||||
<value_type, IsConst>::type vtype;
|
||||
typedef typename detail::add_const_if_c
|
||||
<node, IsConst>::type ntype;
|
||||
typedef typename pointer_traits
|
||||
<typename Container::pointer>::template rebind_pointer<ntype>::type npointer;
|
||||
<typename RealValueTraits::pointer>::
|
||||
template rebind_pointer<void>::type
|
||||
, stateful_value_traits >::type Base;
|
||||
|
||||
node_to_value(const Container *cont)
|
||||
: Base(cont)
|
||||
typedef RealValueTraits real_value_traits;
|
||||
typedef typename real_value_traits::value_type value_type;
|
||||
typedef typename real_value_traits::node_traits::node node;
|
||||
typedef typename detail::add_const_if_c
|
||||
<value_type, IsConst>::type vtype;
|
||||
typedef typename detail::add_const_if_c
|
||||
<node, IsConst>::type ntype;
|
||||
typedef typename pointer_traits
|
||||
<typename RealValueTraits::pointer>::
|
||||
template rebind_pointer<ntype>::type npointer;
|
||||
typedef typename pointer_traits<npointer>::
|
||||
template rebind_pointer<const RealValueTraits>::type const_real_value_traits_ptr;
|
||||
|
||||
node_to_value(const const_real_value_traits_ptr &ptr)
|
||||
: Base(ptr)
|
||||
{}
|
||||
|
||||
typedef vtype & result_type;
|
||||
typedef ntype & first_argument_type;
|
||||
|
||||
const Container *get_container() const
|
||||
const_real_value_traits_ptr get_real_value_traits() const
|
||||
{
|
||||
if(store_container_ptr)
|
||||
return static_cast<const Container*>(Base::get_ptr());
|
||||
if(stateful_value_traits)
|
||||
return pointer_traits<const_real_value_traits_ptr>::static_cast_from(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;
|
||||
return const_real_value_traits_ptr();
|
||||
}
|
||||
|
||||
result_type operator()(first_argument_type arg) const
|
||||
@@ -849,7 +720,346 @@ class reverse_iterator
|
||||
It m_current; // the wrapped iterator
|
||||
};
|
||||
|
||||
template<class ConstNodePtr>
|
||||
struct uncast_types
|
||||
{
|
||||
typedef typename pointer_traits<ConstNodePtr>::element_type element_type;
|
||||
typedef typename remove_const<element_type>::type non_const_type;
|
||||
typedef typename pointer_traits<ConstNodePtr>::
|
||||
template rebind_pointer<non_const_type>::type non_const_pointer;
|
||||
typedef pointer_traits<non_const_pointer> non_const_traits;
|
||||
};
|
||||
|
||||
template<class ConstNodePtr>
|
||||
static typename uncast_types<ConstNodePtr>::non_const_pointer
|
||||
uncast(const ConstNodePtr & ptr)
|
||||
{
|
||||
return uncast_types<ConstNodePtr>::non_const_traits::const_cast_from(ptr);
|
||||
}
|
||||
|
||||
} //namespace detail
|
||||
|
||||
template<class Node, class Tag, unsigned int>
|
||||
struct node_holder
|
||||
: public Node
|
||||
{};
|
||||
|
||||
template<class T, class NodePtr, class Tag, unsigned int Type>
|
||||
struct bhtraits_base
|
||||
{
|
||||
public:
|
||||
typedef NodePtr node_ptr;
|
||||
typedef typename pointer_traits<node_ptr>::element_type node;
|
||||
typedef node_holder<node, Tag, Type> node_holder_type;
|
||||
typedef T value_type;
|
||||
typedef typename pointer_traits<node_ptr>::
|
||||
template rebind_pointer<const node>::type const_node_ptr;
|
||||
typedef typename pointer_traits<node_ptr>::
|
||||
template rebind_pointer<T>::type pointer;
|
||||
typedef typename pointer_traits<node_ptr>::
|
||||
template rebind_pointer<const T>::type const_pointer;
|
||||
//typedef typename pointer_traits<pointer>::reference reference;
|
||||
//typedef typename pointer_traits<const_pointer>::reference const_reference;
|
||||
typedef T & reference;
|
||||
typedef const T & const_reference;
|
||||
typedef node_holder_type & node_holder_reference;
|
||||
typedef const node_holder_type & const_node_holder_reference;
|
||||
typedef node& node_reference;
|
||||
typedef const node & const_node_reference;
|
||||
|
||||
static pointer to_value_ptr(const node_ptr & n)
|
||||
{
|
||||
return pointer_traits<pointer>::pointer_to
|
||||
(static_cast<reference>(static_cast<node_holder_reference>(*n)));
|
||||
}
|
||||
|
||||
static const_pointer to_value_ptr(const const_node_ptr & n)
|
||||
{
|
||||
return pointer_traits<const_pointer>::pointer_to
|
||||
(static_cast<const_reference>(static_cast<const_node_holder_reference>(*n)));
|
||||
}
|
||||
|
||||
static node_ptr to_node_ptr(reference value)
|
||||
{
|
||||
return pointer_traits<node_ptr>::pointer_to
|
||||
(static_cast<node_reference>(static_cast<node_holder_reference>(value)));
|
||||
}
|
||||
|
||||
static const_node_ptr to_node_ptr(const_reference value)
|
||||
{
|
||||
return pointer_traits<const_node_ptr>::pointer_to
|
||||
(static_cast<const_node_reference>(static_cast<const_node_holder_reference>(value)));
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, class NodeTraits, link_mode_type LinkMode, class Tag, unsigned int Type>
|
||||
struct bhtraits
|
||||
: public bhtraits_base<T, typename NodeTraits::node_ptr, Tag, Type>
|
||||
{
|
||||
static const link_mode_type link_mode = LinkMode;
|
||||
typedef NodeTraits node_traits;
|
||||
};
|
||||
|
||||
/*
|
||||
template<class T, class NodePtr, typename pointer_traits<NodePtr>::element_type T::* P>
|
||||
struct mhtraits_base
|
||||
{
|
||||
public:
|
||||
typedef typename pointer_traits<NodePtr>::element_type node;
|
||||
typedef T value_type;
|
||||
typedef NodePtr node_ptr;
|
||||
typedef typename pointer_traits<node_ptr>::
|
||||
template rebind_pointer<const node>::type const_node_ptr;
|
||||
typedef typename pointer_traits<node_ptr>::
|
||||
template rebind_pointer<T>::type pointer;
|
||||
typedef typename pointer_traits<node_ptr>::
|
||||
template rebind_pointer<const T>::type const_pointer;
|
||||
typedef T & reference;
|
||||
typedef const T & const_reference;
|
||||
typedef node& node_reference;
|
||||
typedef const node & const_node_reference;
|
||||
|
||||
static node_ptr to_node_ptr(reference value)
|
||||
{
|
||||
return pointer_traits<node_ptr>::pointer_to
|
||||
(static_cast<node_reference>(value.*P));
|
||||
}
|
||||
|
||||
static const_node_ptr to_node_ptr(const_reference value)
|
||||
{
|
||||
return pointer_traits<const_node_ptr>::pointer_to
|
||||
(static_cast<const_node_reference>(value.*P));
|
||||
}
|
||||
|
||||
static pointer to_value_ptr(const node_ptr & n)
|
||||
{
|
||||
return pointer_traits<pointer>::pointer_to
|
||||
(*detail::parent_from_member<T, node>
|
||||
(boost::intrusive::detail::to_raw_pointer(n), P));
|
||||
}
|
||||
|
||||
static const_pointer to_value_ptr(const const_node_ptr & n)
|
||||
{
|
||||
return pointer_traits<const_pointer>::pointer_to
|
||||
(*detail::parent_from_member<T, node>
|
||||
(boost::intrusive::detail::to_raw_pointer(n), P));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class T, class NodeTraits, typename NodeTraits::node T::* P, link_mode_type LinkMode>
|
||||
struct mhtraits
|
||||
: public mhtraits_base<T, typename NodeTraits::node_ptr, P>
|
||||
{
|
||||
static const link_mode_type link_mode = LinkMode;
|
||||
typedef NodeTraits node_traits;
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
template<class T, class Hook, Hook T::* P>
|
||||
struct mhtraits
|
||||
{
|
||||
public:
|
||||
typedef Hook hook_type;
|
||||
typedef typename hook_type::hooktags::node_traits node_traits;
|
||||
typedef typename node_traits::node node;
|
||||
typedef T value_type;
|
||||
typedef typename node_traits::node_ptr node_ptr;
|
||||
typedef typename node_traits::const_node_ptr const_node_ptr;
|
||||
typedef typename pointer_traits<node_ptr>::
|
||||
template rebind_pointer<T>::type pointer;
|
||||
typedef typename pointer_traits<node_ptr>::
|
||||
template rebind_pointer<const T>::type const_pointer;
|
||||
typedef T & reference;
|
||||
typedef const T & const_reference;
|
||||
typedef node& node_reference;
|
||||
typedef const node & const_node_reference;
|
||||
typedef hook_type& hook_reference;
|
||||
typedef const hook_type & const_hook_reference;
|
||||
|
||||
static const link_mode_type link_mode = Hook::hooktags::link_mode;
|
||||
|
||||
static node_ptr to_node_ptr(reference value)
|
||||
{
|
||||
return pointer_traits<node_ptr>::pointer_to
|
||||
(static_cast<node_reference>(static_cast<hook_reference>(value.*P)));
|
||||
}
|
||||
|
||||
static const_node_ptr to_node_ptr(const_reference value)
|
||||
{
|
||||
return pointer_traits<const_node_ptr>::pointer_to
|
||||
(static_cast<const_node_reference>(static_cast<const_hook_reference>(value.*P)));
|
||||
}
|
||||
|
||||
static pointer to_value_ptr(const node_ptr & n)
|
||||
{
|
||||
return pointer_traits<pointer>::pointer_to
|
||||
(*detail::parent_from_member<T, Hook>
|
||||
(static_cast<Hook*>(boost::intrusive::detail::to_raw_pointer(n)), P));
|
||||
}
|
||||
|
||||
static const_pointer to_value_ptr(const const_node_ptr & n)
|
||||
{
|
||||
return pointer_traits<const_pointer>::pointer_to
|
||||
(*detail::parent_from_member<T, Hook>
|
||||
(static_cast<const Hook*>(boost::intrusive::detail::to_raw_pointer(n)), P));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<class Functor>
|
||||
struct fhtraits
|
||||
{
|
||||
public:
|
||||
typedef typename Functor::hook_type hook_type;
|
||||
typedef typename Functor::hook_ptr hook_ptr;
|
||||
typedef typename Functor::const_hook_ptr const_hook_ptr;
|
||||
typedef typename hook_type::hooktags::node_traits node_traits;
|
||||
typedef typename node_traits::node node;
|
||||
typedef typename Functor::value_type value_type;
|
||||
typedef typename node_traits::node_ptr node_ptr;
|
||||
typedef typename node_traits::const_node_ptr const_node_ptr;
|
||||
typedef typename pointer_traits<node_ptr>::
|
||||
template rebind_pointer<value_type>::type pointer;
|
||||
typedef typename pointer_traits<node_ptr>::
|
||||
template rebind_pointer<const value_type>::type const_pointer;
|
||||
typedef value_type & reference;
|
||||
typedef const value_type & const_reference;
|
||||
static const link_mode_type link_mode = hook_type::hooktags::link_mode;
|
||||
|
||||
static node_ptr to_node_ptr(reference value)
|
||||
{ return static_cast<node*>(boost::intrusive::detail::to_raw_pointer(Functor::to_hook_ptr(value))); }
|
||||
|
||||
static const_node_ptr to_node_ptr(const_reference value)
|
||||
{ return static_cast<const node*>(boost::intrusive::detail::to_raw_pointer(Functor::to_hook_ptr(value))); }
|
||||
|
||||
static pointer to_value_ptr(const node_ptr & n)
|
||||
{ return Functor::to_value_ptr(to_hook_ptr(n)); }
|
||||
|
||||
static const_pointer to_value_ptr(const const_node_ptr & n)
|
||||
{ return Functor::to_value_ptr(to_hook_ptr(n)); }
|
||||
|
||||
private:
|
||||
static hook_ptr to_hook_ptr(const node_ptr & n)
|
||||
{ return hook_ptr(&*static_cast<hook_type*>(&*n)); }
|
||||
|
||||
static const_hook_ptr to_hook_ptr(const const_node_ptr & n)
|
||||
{ return const_hook_ptr(&*static_cast<const hook_type*>(&*n)); }
|
||||
};
|
||||
|
||||
template<class RealValueTraits, bool IsConst, class Category>
|
||||
struct iiterator
|
||||
{
|
||||
typedef RealValueTraits real_value_traits;
|
||||
typedef typename real_value_traits::node_traits node_traits;
|
||||
typedef typename node_traits::node node;
|
||||
typedef typename node_traits::node_ptr node_ptr;
|
||||
typedef ::boost::intrusive::pointer_traits<node_ptr> nodepointer_traits_t;
|
||||
typedef typename nodepointer_traits_t::template
|
||||
rebind_pointer<void>::type void_pointer;
|
||||
typedef typename RealValueTraits::value_type value_type;
|
||||
typedef typename RealValueTraits::pointer nonconst_pointer;
|
||||
typedef typename RealValueTraits::const_pointer yesconst_pointer;
|
||||
typedef typename ::boost::intrusive::pointer_traits
|
||||
<nonconst_pointer>::reference nonconst_reference;
|
||||
typedef typename ::boost::intrusive::pointer_traits
|
||||
<yesconst_pointer>::reference yesconst_reference;
|
||||
typedef typename nodepointer_traits_t::difference_type difference_type;
|
||||
typedef typename detail::if_c
|
||||
<IsConst, yesconst_pointer, nonconst_pointer>::type pointer;
|
||||
typedef typename detail::if_c
|
||||
<IsConst, yesconst_reference, nonconst_reference>::type reference;
|
||||
typedef std::iterator
|
||||
< Category
|
||||
, value_type
|
||||
, difference_type
|
||||
, pointer
|
||||
, reference
|
||||
> iterator_base;
|
||||
static const bool stateful_value_traits =
|
||||
detail::is_stateful_value_traits<real_value_traits>::value;
|
||||
};
|
||||
|
||||
template<class NodePtr, bool StatefulValueTraits = true>
|
||||
struct iiterator_members
|
||||
{
|
||||
typedef ::boost::intrusive::pointer_traits<NodePtr> pointer_traits_t;
|
||||
typedef typename pointer_traits_t::template
|
||||
rebind_pointer<const void>::type const_void_pointer;
|
||||
|
||||
iiterator_members()
|
||||
{}
|
||||
|
||||
iiterator_members(const NodePtr &n_ptr, const const_void_pointer &data)
|
||||
: nodeptr_(n_ptr), ptr_(data)
|
||||
{}
|
||||
|
||||
const_void_pointer get_ptr() const
|
||||
{ return ptr_; }
|
||||
|
||||
NodePtr nodeptr_;
|
||||
const_void_pointer ptr_;
|
||||
};
|
||||
|
||||
template<class NodePtr>
|
||||
struct iiterator_members<NodePtr, false>
|
||||
{
|
||||
typedef ::boost::intrusive::pointer_traits<NodePtr> pointer_traits_t;
|
||||
typedef typename pointer_traits_t::template
|
||||
rebind_pointer<const void>::type const_void_pointer;
|
||||
|
||||
iiterator_members()
|
||||
{}
|
||||
|
||||
iiterator_members(const NodePtr &n_ptr, const const_void_pointer &)
|
||||
: nodeptr_(n_ptr)
|
||||
{}
|
||||
|
||||
const_void_pointer get_ptr() const
|
||||
{ return const_void_pointer(); }
|
||||
|
||||
NodePtr nodeptr_;
|
||||
};
|
||||
|
||||
template<class Less, class T>
|
||||
struct get_less
|
||||
{
|
||||
typedef Less type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct get_less<void, T>
|
||||
{
|
||||
typedef ::std::less<T> type;
|
||||
};
|
||||
|
||||
template<class EqualTo, class T>
|
||||
struct get_equal_to
|
||||
{
|
||||
typedef EqualTo type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct get_equal_to<void, T>
|
||||
{
|
||||
typedef ::std::equal_to<T> type;
|
||||
};
|
||||
|
||||
template<class Hash, class T>
|
||||
struct get_hash
|
||||
{
|
||||
typedef Hash type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct get_hash<void, T>
|
||||
{
|
||||
typedef ::boost::hash<T> type;
|
||||
};
|
||||
|
||||
struct empty{};
|
||||
|
||||
} //namespace intrusive
|
||||
} //namespace boost
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2005-2013. 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)
|
||||
//
|
||||
@@ -17,6 +17,10 @@
|
||||
#define BOOST_INTRUSIVE_PERFECT_FORWARDING
|
||||
#endif
|
||||
|
||||
//Macros for documentation purposes. For code, expands to the argument
|
||||
#define BOOST_INTRUSIVE_IMPDEF(TYPE) TYPE
|
||||
#define BOOST_INTRUSIVE_SEEDOC(TYPE) TYPE
|
||||
|
||||
#include <boost/intrusive/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_INTRUSIVE_DETAIL_WRKRND_HPP
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -19,15 +19,6 @@
|
||||
|
||||
/// @cond
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace intrusive {
|
||||
|
||||
struct none;
|
||||
|
||||
} //namespace intrusive{
|
||||
} //namespace boost{
|
||||
|
||||
namespace boost {
|
||||
namespace intrusive {
|
||||
|
||||
@@ -53,11 +44,11 @@ class rbtree_algorithms;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O5 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
, class O5 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -66,9 +57,9 @@ class slist;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
>
|
||||
#else
|
||||
template<class ...Options>
|
||||
@@ -77,9 +68,9 @@ class slist_base_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
>
|
||||
#else
|
||||
template<class ...Options>
|
||||
@@ -90,9 +81,9 @@ class slist_member_hook;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -101,9 +92,9 @@ class list;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
>
|
||||
#else
|
||||
template<class ...Options>
|
||||
@@ -112,9 +103,9 @@ class list_base_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
>
|
||||
#else
|
||||
template<class ...Options>
|
||||
@@ -123,9 +114,9 @@ class list_member_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
>
|
||||
#else
|
||||
template<class ...Options>
|
||||
@@ -136,10 +127,10 @@ class list_hook;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -149,10 +140,10 @@ class rbtree;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -162,10 +153,10 @@ class set;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -174,10 +165,10 @@ class multiset;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class ...Options>
|
||||
@@ -186,10 +177,10 @@ class set_base_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class ...Options>
|
||||
@@ -200,10 +191,10 @@ class set_member_hook;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -213,10 +204,10 @@ class splaytree;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -226,10 +217,10 @@ class splay_set;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -238,9 +229,9 @@ class splay_multiset;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
>
|
||||
#else
|
||||
template<class ...Options>
|
||||
@@ -249,9 +240,9 @@ class splay_set_base_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
>
|
||||
#else
|
||||
template<class ...Options>
|
||||
@@ -262,10 +253,10 @@ class splay_set_member_hook;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -275,10 +266,10 @@ class avltree;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -288,10 +279,10 @@ class avl_set;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -300,10 +291,10 @@ class avl_multiset;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class ...Options>
|
||||
@@ -312,10 +303,10 @@ class avl_set_base_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class ...Options>
|
||||
@@ -327,10 +318,10 @@ class avl_set_member_hook;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -340,10 +331,10 @@ class treap;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -353,10 +344,10 @@ class treap_set;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -371,10 +362,10 @@ struct priority_compare;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -384,10 +375,10 @@ class sgtree;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -397,10 +388,10 @@ class sg_set;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -409,9 +400,48 @@ class sg_multiset;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
< class T
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
#endif
|
||||
class bstree;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
#endif
|
||||
class bs_set;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
#endif
|
||||
class bs_multiset;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
>
|
||||
#else
|
||||
template<class ...Options>
|
||||
@@ -420,9 +450,9 @@ class bs_set_base_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
>
|
||||
#else
|
||||
template<class ...Options>
|
||||
@@ -434,16 +464,16 @@ class bs_set_member_hook;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O5 = none
|
||||
, class O6 = none
|
||||
, class O7 = none
|
||||
, class O8 = none
|
||||
, class O9 = none
|
||||
, class O10 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
, class O5 = void
|
||||
, class O6 = void
|
||||
, class O7 = void
|
||||
, class O8 = void
|
||||
, class O9 = void
|
||||
, class O10 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -453,16 +483,16 @@ class hashtable;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O5 = none
|
||||
, class O6 = none
|
||||
, class O7 = none
|
||||
, class O8 = none
|
||||
, class O9 = none
|
||||
, class O10 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
, class O5 = void
|
||||
, class O6 = void
|
||||
, class O7 = void
|
||||
, class O8 = void
|
||||
, class O9 = void
|
||||
, class O10 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -472,16 +502,16 @@ class unordered_set;
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O5 = none
|
||||
, class O6 = none
|
||||
, class O7 = none
|
||||
, class O8 = none
|
||||
, class O9 = none
|
||||
, class O10 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
, class O5 = void
|
||||
, class O6 = void
|
||||
, class O7 = void
|
||||
, class O8 = void
|
||||
, class O9 = void
|
||||
, class O10 = void
|
||||
>
|
||||
#else
|
||||
template<class T, class ...Options>
|
||||
@@ -490,10 +520,10 @@ class unordered_multiset;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class ...Options>
|
||||
@@ -502,10 +532,10 @@ class unordered_set_base_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
>
|
||||
#else
|
||||
template<class ...Options>
|
||||
@@ -514,9 +544,9 @@ class unordered_set_member_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
>
|
||||
#else
|
||||
template<class ...Options>
|
||||
@@ -525,9 +555,9 @@ class any_base_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
>
|
||||
#else
|
||||
template<class ...Options>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Olaf Krzikalla 2004-2006.
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/detail/common_slist_algorithms.hpp>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
@@ -319,6 +320,16 @@ class linear_slist_algorithms
|
||||
}
|
||||
};
|
||||
|
||||
/// @cond
|
||||
|
||||
template<class NodeTraits>
|
||||
struct get_algo<LinearSListAlgorithms, NodeTraits>
|
||||
{
|
||||
typedef linear_slist_algorithms<NodeTraits> type;
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
|
||||
} //namespace intrusive
|
||||
} //namespace boost
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Olaf Krzikalla 2004-2006.
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -38,24 +38,12 @@ namespace intrusive {
|
||||
|
||||
/// @cond
|
||||
|
||||
template <class ValueTraits, class SizeType, bool ConstantTimeSize>
|
||||
struct listopt
|
||||
{
|
||||
typedef ValueTraits value_traits;
|
||||
typedef SizeType size_type;
|
||||
static const bool constant_time_size = ConstantTimeSize;
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct list_defaults
|
||||
: pack_options
|
||||
< none
|
||||
, base_hook<detail::default_list_hook>
|
||||
, constant_time_size<true>
|
||||
, size_type<std::size_t>
|
||||
>::type
|
||||
{};
|
||||
{
|
||||
typedef detail::default_list_hook proto_value_traits;
|
||||
static const bool constant_time_size = true;
|
||||
typedef std::size_t size_type;
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
|
||||
@@ -72,23 +60,19 @@ struct list_defaults
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class Config>
|
||||
template <class ValueTraits, class SizeType, bool ConstantTimeSize>
|
||||
#endif
|
||||
class list_impl
|
||||
: private detail::clear_on_destructor_base< list_impl<Config> >
|
||||
: private detail::clear_on_destructor_base< list_impl<ValueTraits, SizeType, ConstantTimeSize> >
|
||||
{
|
||||
template<class C> friend class detail::clear_on_destructor_base;
|
||||
//Public typedefs
|
||||
public:
|
||||
typedef typename Config::value_traits value_traits;
|
||||
typedef ValueTraits value_traits;
|
||||
/// @cond
|
||||
static const bool external_value_traits =
|
||||
detail::external_value_traits_bool_is_true<value_traits>::value;
|
||||
typedef typename detail::eval_if_c
|
||||
< external_value_traits
|
||||
, detail::eval_value_traits<value_traits>
|
||||
, detail::identity<value_traits>
|
||||
>::type real_value_traits;
|
||||
typedef typename detail::get_real_value_traits<ValueTraits>::type real_value_traits;
|
||||
/// @endcond
|
||||
typedef typename real_value_traits::pointer pointer;
|
||||
typedef typename real_value_traits::const_pointer const_pointer;
|
||||
@@ -96,9 +80,9 @@ class list_impl
|
||||
typedef typename pointer_traits<pointer>::reference reference;
|
||||
typedef typename pointer_traits<const_pointer>::reference const_reference;
|
||||
typedef typename pointer_traits<pointer>::difference_type difference_type;
|
||||
typedef typename Config::size_type size_type;
|
||||
typedef list_iterator<list_impl, false> iterator;
|
||||
typedef list_iterator<list_impl, true> const_iterator;
|
||||
typedef SizeType size_type;
|
||||
typedef list_iterator<real_value_traits, false> iterator;
|
||||
typedef list_iterator<real_value_traits, true> const_iterator;
|
||||
typedef boost::intrusive::detail::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef boost::intrusive::detail::reverse_iterator<const_iterator>const_reverse_iterator;
|
||||
typedef typename real_value_traits::node_traits node_traits;
|
||||
@@ -107,7 +91,7 @@ class list_impl
|
||||
typedef typename node_traits::const_node_ptr const_node_ptr;
|
||||
typedef circular_list_algorithms<node_traits> node_algorithms;
|
||||
|
||||
static const bool constant_time_size = Config::constant_time_size;
|
||||
static const bool constant_time_size = ConstantTimeSize;
|
||||
static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
|
||||
|
||||
/// @cond
|
||||
@@ -118,19 +102,13 @@ class list_impl
|
||||
//noncopyable
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(list_impl)
|
||||
|
||||
enum { safemode_or_autounlink =
|
||||
(int)real_value_traits::link_mode == (int)auto_unlink ||
|
||||
(int)real_value_traits::link_mode == (int)safe_link };
|
||||
static const bool safemode_or_autounlink = is_safe_autounlink<real_value_traits::link_mode>::value;
|
||||
|
||||
//Constant-time size is incompatible with auto-unlink hooks!
|
||||
BOOST_STATIC_ASSERT(!(constant_time_size &&
|
||||
((int)real_value_traits::link_mode == (int)auto_unlink)
|
||||
));
|
||||
|
||||
//Const cast emulation for smart pointers
|
||||
static node_ptr uncast(const const_node_ptr & ptr)
|
||||
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
|
||||
|
||||
node_ptr get_root_node()
|
||||
{ return pointer_traits<node_ptr>::pointer_to(data_.root_plus_size_.root_); }
|
||||
|
||||
@@ -196,6 +174,11 @@ class list_impl
|
||||
real_value_traits &get_real_value_traits()
|
||||
{ return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
|
||||
|
||||
typedef typename pointer_traits<node_ptr>::template rebind_pointer<const real_value_traits>::type const_real_value_traits_ptr;
|
||||
|
||||
const_real_value_traits_ptr real_value_traits_ptr() const
|
||||
{ return pointer_traits<const_real_value_traits_ptr>::pointer_to(this->get_real_value_traits()); }
|
||||
|
||||
//! <b>Effects</b>: constructs an empty list.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant
|
||||
@@ -371,7 +354,7 @@ class list_impl
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reference front() const
|
||||
{ return *get_real_value_traits().to_value_ptr(uncast(node_traits::get_next(this->get_root_node()))); }
|
||||
{ return *get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); }
|
||||
|
||||
//! <b>Effects</b>: Returns a reference to the last element of the list.
|
||||
//!
|
||||
@@ -387,7 +370,7 @@ class list_impl
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reference back() const
|
||||
{ return *get_real_value_traits().to_value_ptr(uncast(node_traits::get_previous(this->get_root_node()))); }
|
||||
{ return *get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_previous(this->get_root_node()))); }
|
||||
|
||||
//! <b>Effects</b>: Returns an iterator to the first element contained in the list.
|
||||
//!
|
||||
@@ -395,7 +378,7 @@ class list_impl
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
iterator begin()
|
||||
{ return iterator(node_traits::get_next(this->get_root_node()), this); }
|
||||
{ return iterator(node_traits::get_next(this->get_root_node()), real_value_traits_ptr()); }
|
||||
|
||||
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
|
||||
//!
|
||||
@@ -411,7 +394,7 @@ class list_impl
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_iterator cbegin() const
|
||||
{ return const_iterator(node_traits::get_next(this->get_root_node()), this); }
|
||||
{ return const_iterator(node_traits::get_next(this->get_root_node()), real_value_traits_ptr()); }
|
||||
|
||||
//! <b>Effects</b>: Returns an iterator to the end of the list.
|
||||
//!
|
||||
@@ -419,7 +402,7 @@ class list_impl
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
iterator end()
|
||||
{ return iterator(this->get_root_node(), this); }
|
||||
{ return iterator(this->get_root_node(), real_value_traits_ptr()); }
|
||||
|
||||
//! <b>Effects</b>: Returns a const_iterator to the end of the list.
|
||||
//!
|
||||
@@ -435,7 +418,7 @@ class list_impl
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_iterator cend() const
|
||||
{ return const_iterator(uncast(this->get_root_node()), this); }
|
||||
{ return const_iterator(detail::uncast(this->get_root_node()), real_value_traits_ptr()); }
|
||||
|
||||
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
|
||||
//! of the reversed list.
|
||||
@@ -806,7 +789,7 @@ class list_impl
|
||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
|
||||
node_algorithms::link_before(p.pointed_node(), to_insert);
|
||||
this->priv_size_traits().increment();
|
||||
return iterator(to_insert, this);
|
||||
return iterator(to_insert, real_value_traits_ptr());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: Dereferencing iterator must yield
|
||||
@@ -1240,7 +1223,7 @@ class list_impl
|
||||
{
|
||||
BOOST_STATIC_ASSERT((!stateful_value_traits));
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value)));
|
||||
return iterator(real_value_traits::to_node_ptr(value), 0);
|
||||
return iterator(real_value_traits::to_node_ptr(value), const_real_value_traits_ptr());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: value must be a const reference to a value inserted in a list.
|
||||
@@ -1258,7 +1241,7 @@ class list_impl
|
||||
{
|
||||
BOOST_STATIC_ASSERT((!stateful_value_traits));
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(const_cast<reference> (value))));
|
||||
return const_iterator(real_value_traits::to_node_ptr(const_cast<reference> (value)), 0);
|
||||
return const_iterator(real_value_traits::to_node_ptr(const_cast<reference> (value)), const_real_value_traits_ptr());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: value must be a reference to a value inserted in a list.
|
||||
@@ -1273,7 +1256,7 @@ class list_impl
|
||||
iterator iterator_to(reference value)
|
||||
{
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value)));
|
||||
return iterator(real_value_traits::to_node_ptr(value), this);
|
||||
return iterator(real_value_traits::to_node_ptr(value), real_value_traits_ptr());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: value must be a const reference to a value inserted in a list.
|
||||
@@ -1288,7 +1271,7 @@ class list_impl
|
||||
const_iterator iterator_to(const_reference value) const
|
||||
{
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(const_cast<reference> (value))));
|
||||
return const_iterator(real_value_traits::to_node_ptr(const_cast<reference> (value)), this);
|
||||
return const_iterator(real_value_traits::to_node_ptr(const_cast<reference> (value)), real_value_traits_ptr());
|
||||
}
|
||||
|
||||
/// @cond
|
||||
@@ -1309,29 +1292,29 @@ class list_impl
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class Config>
|
||||
template <class ValueTraits, class SizeType, bool ConstantTimeSize>
|
||||
#endif
|
||||
inline bool operator<
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
|
||||
#else
|
||||
(const list_impl<Config> &x, const list_impl<Config> &y)
|
||||
(const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
|
||||
#endif
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class Config>
|
||||
template <class ValueTraits, class SizeType, bool ConstantTimeSize>
|
||||
#endif
|
||||
bool operator==
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
|
||||
#else
|
||||
(const list_impl<Config> &x, const list_impl<Config> &y)
|
||||
(const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
|
||||
#endif
|
||||
{
|
||||
typedef list_impl<Config> list_type;
|
||||
typedef list_impl<ValueTraits, SizeType, ConstantTimeSize> list_type;
|
||||
typedef typename list_type::const_iterator const_iterator;
|
||||
const bool C = list_type::constant_time_size;
|
||||
if(C && x.size() != y.size()){
|
||||
@@ -1361,65 +1344,65 @@ bool operator==
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class Config>
|
||||
template <class ValueTraits, class SizeType, bool ConstantTimeSize>
|
||||
#endif
|
||||
inline bool operator!=
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
|
||||
#else
|
||||
(const list_impl<Config> &x, const list_impl<Config> &y)
|
||||
(const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
|
||||
#endif
|
||||
{ return !(x == y); }
|
||||
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class Config>
|
||||
template <class ValueTraits, class SizeType, bool ConstantTimeSize>
|
||||
#endif
|
||||
inline bool operator>
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
|
||||
#else
|
||||
(const list_impl<Config> &x, const list_impl<Config> &y)
|
||||
(const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
|
||||
#endif
|
||||
{ return y < x; }
|
||||
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class Config>
|
||||
template <class ValueTraits, class SizeType, bool ConstantTimeSize>
|
||||
#endif
|
||||
inline bool operator<=
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
|
||||
#else
|
||||
(const list_impl<Config> &x, const list_impl<Config> &y)
|
||||
(const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
|
||||
#endif
|
||||
{ return !(y < x); }
|
||||
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class Config>
|
||||
template <class ValueTraits, class SizeType, bool ConstantTimeSize>
|
||||
#endif
|
||||
inline bool operator>=
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
(const list_impl<T, Options...> &x, const list_impl<T, Options...> &y)
|
||||
#else
|
||||
(const list_impl<Config> &x, const list_impl<Config> &y)
|
||||
(const list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, const list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
|
||||
#endif
|
||||
{ return !(x < y); }
|
||||
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class Config>
|
||||
template <class ValueTraits, class SizeType, bool ConstantTimeSize>
|
||||
#endif
|
||||
inline void swap
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
(list_impl<T, Options...> &x, list_impl<T, Options...> &y)
|
||||
#else
|
||||
(list_impl<Config> &x, list_impl<Config> &y)
|
||||
(list_impl<ValueTraits, SizeType, ConstantTimeSize> &x, list_impl<ValueTraits, SizeType, ConstantTimeSize> &y)
|
||||
#endif
|
||||
{ x.swap(y); }
|
||||
|
||||
@@ -1428,13 +1411,13 @@ inline void swap
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class T, class O1 = none, class O2 = none, class O3 = none>
|
||||
template<class T, class O1 = void, class O2 = void, class O3 = void>
|
||||
#endif
|
||||
struct make_list
|
||||
{
|
||||
/// @cond
|
||||
typedef typename pack_options
|
||||
< list_defaults<T>,
|
||||
< list_defaults,
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3
|
||||
#else
|
||||
@@ -1443,15 +1426,13 @@ struct make_list
|
||||
>::type packed_options;
|
||||
|
||||
typedef typename detail::get_value_traits
|
||||
<T, typename packed_options::value_traits>::type value_traits;
|
||||
<T, typename packed_options::proto_value_traits>::type value_traits;
|
||||
|
||||
typedef list_impl
|
||||
<
|
||||
listopt
|
||||
< value_traits
|
||||
, typename packed_options::size_type
|
||||
, packed_options::constant_time_size
|
||||
>
|
||||
value_traits,
|
||||
typename packed_options::size_type,
|
||||
packed_options::constant_time_size
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
@@ -1506,7 +1487,7 @@ class list
|
||||
{}
|
||||
|
||||
list& operator=(BOOST_RV_REF(list) x)
|
||||
{ this->Base::operator=(::boost::move(static_cast<Base&>(x))); return *this; }
|
||||
{ return static_cast<list &>(this->Base::operator=(::boost::move(static_cast<Base&>(x)))); }
|
||||
|
||||
static list &container_from_end_iterator(iterator end_iterator)
|
||||
{ return static_cast<list &>(Base::container_from_end_iterator(end_iterator)); }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Olaf Krzikalla 2004-2006.
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -38,7 +38,7 @@ struct get_list_node_algo
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = none, class O2 = none, class O3 = none>
|
||||
template<class O1 = void, class O2 = void, class O3 = void>
|
||||
#endif
|
||||
struct make_list_base_hook
|
||||
{
|
||||
@@ -52,11 +52,11 @@ struct make_list_base_hook
|
||||
#endif
|
||||
>::type packed_options;
|
||||
|
||||
typedef detail::generic_hook
|
||||
typedef generic_hook
|
||||
< get_list_node_algo<typename packed_options::void_pointer>
|
||||
, typename packed_options::tag
|
||||
, packed_options::link_mode
|
||||
, detail::ListBaseHook
|
||||
, ListBaseHookId
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
@@ -165,7 +165,7 @@ class list_base_hook
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = none, class O2 = none, class O3 = none>
|
||||
template<class O1 = void, class O2 = void, class O3 = void>
|
||||
#endif
|
||||
struct make_list_member_hook
|
||||
{
|
||||
@@ -179,11 +179,11 @@ struct make_list_member_hook
|
||||
#endif
|
||||
>::type packed_options;
|
||||
|
||||
typedef detail::generic_hook
|
||||
typedef generic_hook
|
||||
< get_list_node_algo<typename packed_options::void_pointer>
|
||||
, member_tag
|
||||
, packed_options::link_mode
|
||||
, detail::NoBaseHook
|
||||
, NoBaseHookId
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -26,6 +26,7 @@ namespace intrusive {
|
||||
|
||||
/// @cond
|
||||
|
||||
//typedef void default_tag;
|
||||
struct default_tag;
|
||||
struct member_tag;
|
||||
|
||||
@@ -45,11 +46,13 @@ struct BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER : public default_hook_tag\
|
||||
|
||||
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_list_hook);
|
||||
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_slist_hook);
|
||||
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_set_hook);
|
||||
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_uset_hook);
|
||||
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_avl_set_hook);
|
||||
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_splay_set_hook);
|
||||
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_bs_set_hook);
|
||||
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_rbtree_hook);
|
||||
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_hashtable_hook);
|
||||
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_avltree_hook);
|
||||
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_bstree_hook);
|
||||
//BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_splaytree_hook);
|
||||
//BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_sgtree_hook);
|
||||
//BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_treap_hook);
|
||||
|
||||
#undef BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION
|
||||
|
||||
@@ -61,6 +64,15 @@ struct eval_value_traits
|
||||
typedef typename ValueTraits::value_traits type;
|
||||
};
|
||||
|
||||
template<class ValueTraits>
|
||||
struct get_real_value_traits
|
||||
: public eval_if_c
|
||||
< external_value_traits_bool_is_true<ValueTraits>::value
|
||||
, eval_value_traits<ValueTraits>
|
||||
, identity<ValueTraits>
|
||||
>
|
||||
{};
|
||||
|
||||
template <class BucketTraits>
|
||||
struct eval_bucket_traits
|
||||
{
|
||||
@@ -70,29 +82,36 @@ struct eval_bucket_traits
|
||||
template <class T, class BaseHook>
|
||||
struct concrete_hook_base_value_traits
|
||||
{
|
||||
typedef typename BaseHook::boost_intrusive_tags tags;
|
||||
typedef detail::base_hook_traits
|
||||
typedef typename BaseHook::hooktags tags;
|
||||
typedef bhtraits
|
||||
< T
|
||||
, typename tags::node_traits
|
||||
, tags::link_mode
|
||||
, typename tags::tag
|
||||
, tags::hook_type> type;
|
||||
, tags::type> type;
|
||||
};
|
||||
|
||||
template <class BaseHook>
|
||||
struct concrete_hook_base_node_traits
|
||||
{ typedef typename BaseHook::boost_intrusive_tags::node_traits type; };
|
||||
{ typedef typename BaseHook::hooktags::node_traits type; };
|
||||
|
||||
template <class T, class BaseHook>
|
||||
template <class T, class AnyToSomeHook_ProtoValueTraits>
|
||||
struct any_hook_base_value_traits
|
||||
{
|
||||
typedef typename BaseHook::boost_intrusive_tags tags;
|
||||
typedef detail::base_hook_traits
|
||||
//AnyToSomeHook value_traits derive from a generic_hook
|
||||
//The generic_hook is configured with any_node_traits
|
||||
//and AnyToSomeHook::value_traits with the correct
|
||||
//node traits for the container, so use node_traits
|
||||
//from AnyToSomeHook_ProtoValueTraits and the rest of
|
||||
//elements from the hooktags member of the generic_hook
|
||||
typedef AnyToSomeHook_ProtoValueTraits proto_value_traits;
|
||||
typedef bhtraits
|
||||
< T
|
||||
, typename BaseHook::node_traits
|
||||
, tags::link_mode
|
||||
, typename tags::tag
|
||||
, tags::hook_type> type;
|
||||
, typename proto_value_traits::node_traits
|
||||
, proto_value_traits::hooktags::link_mode
|
||||
, typename proto_value_traits::hooktags::tag
|
||||
, proto_value_traits::hooktags::type
|
||||
> type;
|
||||
};
|
||||
|
||||
template <class BaseHook>
|
||||
@@ -139,6 +158,7 @@ struct get_value_traits
|
||||
,detail::apply<SupposedValueTraits, T>
|
||||
,detail::identity<SupposedValueTraits>
|
||||
>::type supposed_value_traits;
|
||||
|
||||
//...if it's a default hook
|
||||
typedef typename detail::eval_if_c
|
||||
< internal_base_hook_bool_is_true<supposed_value_traits>::value
|
||||
@@ -183,16 +203,6 @@ struct get_node_traits
|
||||
|
||||
} //namespace detail{
|
||||
|
||||
|
||||
//!This type indicates that no option is being used
|
||||
//!and that the default options should be used
|
||||
struct none
|
||||
{
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{ };
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
|
||||
//!This option setter specifies if the intrusive
|
||||
@@ -314,7 +324,7 @@ struct value_traits
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
typedef ValueTraits value_traits;
|
||||
typedef ValueTraits proto_value_traits;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
@@ -327,7 +337,22 @@ template< typename Parent
|
||||
struct member_hook
|
||||
{
|
||||
/// @cond
|
||||
typedef detail::member_hook_traits
|
||||
/*
|
||||
typedef typename MemberHook::hooktags::node_traits node_traits;
|
||||
typedef typename node_traits::node node_type;
|
||||
typedef node_type Parent::* Ptr2MemNode;
|
||||
typedef mhtraits
|
||||
< Parent
|
||||
, node_traits
|
||||
//This cast is really ugly but necessary to reduce template bloat.
|
||||
//Since we control the layout between the hook and the node, and there is
|
||||
//always single inheritance, the offset of the node is exactly the offset of
|
||||
//the hook. Since the node type is shared between all member hooks, this saves
|
||||
//quite a lot of symbol stuff.
|
||||
, (Ptr2MemNode)PtrToMember
|
||||
, MemberHook::hooktags::link_mode> member_value_traits;
|
||||
*/
|
||||
typedef mhtraits
|
||||
< Parent
|
||||
, MemberHook
|
||||
, PtrToMember
|
||||
@@ -335,7 +360,7 @@ struct member_hook
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
typedef member_value_traits value_traits;
|
||||
typedef member_value_traits proto_value_traits;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
@@ -348,12 +373,12 @@ template< typename Functor>
|
||||
struct function_hook
|
||||
{
|
||||
/// @cond
|
||||
typedef detail::function_hook_traits
|
||||
typedef fhtraits
|
||||
<Functor> function_value_traits;
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
typedef function_value_traits value_traits;
|
||||
typedef function_value_traits proto_value_traits;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
@@ -368,7 +393,7 @@ struct base_hook
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
typedef BaseHook value_traits;
|
||||
typedef BaseHook proto_value_traits;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
@@ -583,6 +608,13 @@ struct incremental
|
||||
|
||||
/// @cond
|
||||
|
||||
struct none
|
||||
{
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{};
|
||||
};
|
||||
|
||||
//To-do: pass to variadic templates
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
|
||||
@@ -594,25 +626,25 @@ struct do_pack
|
||||
};
|
||||
|
||||
template<class Prev>
|
||||
struct do_pack<Prev, none>
|
||||
struct do_pack<Prev, void>
|
||||
{
|
||||
//Avoid packing "none" to shorten template names
|
||||
//Avoid packing "void" to shorten template names
|
||||
typedef Prev type;
|
||||
};
|
||||
|
||||
template
|
||||
< class DefaultOptions
|
||||
, class O1 = none
|
||||
, class O2 = none
|
||||
, class O3 = none
|
||||
, class O4 = none
|
||||
, class O5 = none
|
||||
, class O6 = none
|
||||
, class O7 = none
|
||||
, class O8 = none
|
||||
, class O9 = none
|
||||
, class O10 = none
|
||||
, class O11 = none
|
||||
, class O1 = void
|
||||
, class O2 = void
|
||||
, class O3 = void
|
||||
, class O4 = void
|
||||
, class O5 = void
|
||||
, class O6 = void
|
||||
, class O7 = void
|
||||
, class O8 = void
|
||||
, class O9 = void
|
||||
, class O10 = void
|
||||
, class O11 = void
|
||||
>
|
||||
struct pack_options
|
||||
{
|
||||
@@ -788,17 +820,15 @@ struct pack_options
|
||||
#endif
|
||||
|
||||
struct hook_defaults
|
||||
: public pack_options
|
||||
< none
|
||||
, void_pointer<void*>
|
||||
, link_mode<safe_link>
|
||||
, tag<default_tag>
|
||||
, optimize_size<false>
|
||||
, store_hash<false>
|
||||
, linear<false>
|
||||
, optimize_multikey<false>
|
||||
>::type
|
||||
{};
|
||||
{
|
||||
typedef void* void_pointer;
|
||||
static const link_mode_type link_mode = safe_link;
|
||||
typedef default_tag tag;
|
||||
static const bool optimize_size = false;
|
||||
static const bool store_hash = false;
|
||||
static const bool linear = false;
|
||||
static const bool optimize_multikey = false;
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2010-2012
|
||||
// (C) Copyright Ion Gaztanaga 2010-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2011-2012. Distributed under the Boost
|
||||
// (C) Copyright Ion Gaztanaga 2011-2013. 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)
|
||||
//
|
||||
|
||||
@@ -31,6 +31,23 @@ struct priority_compare
|
||||
}
|
||||
};
|
||||
|
||||
/// @cond
|
||||
|
||||
template<class Less, class T>
|
||||
struct get_prio
|
||||
{
|
||||
typedef Less type;
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
struct get_prio<void, T>
|
||||
{
|
||||
typedef ::boost::intrusive::priority_compare<T> type;
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
|
||||
} //namespace intrusive
|
||||
} //namespace boost
|
||||
|
||||
|
||||
+249
-1499
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Olaf Krzikalla 2004-2006.
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012.
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -55,12 +55,50 @@
|
||||
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
#include <boost/intrusive/detail/tree_algorithms.hpp>
|
||||
#include <boost/intrusive/bstree_algorithms.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace intrusive {
|
||||
|
||||
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
template<class NodeTraits, class F>
|
||||
struct rbtree_node_cloner
|
||||
: private detail::ebo_functor_holder<F>
|
||||
{
|
||||
typedef typename NodeTraits::node_ptr node_ptr;
|
||||
typedef detail::ebo_functor_holder<F> base_t;
|
||||
|
||||
rbtree_node_cloner(F f)
|
||||
: base_t(f)
|
||||
{}
|
||||
|
||||
node_ptr operator()(const node_ptr & p)
|
||||
{
|
||||
node_ptr n = base_t::get()(p);
|
||||
NodeTraits::set_color(n, NodeTraits::get_color(p));
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
template<class NodeTraits>
|
||||
struct rbtree_erase_fixup
|
||||
{
|
||||
typedef typename NodeTraits::node_ptr node_ptr;
|
||||
typedef typename NodeTraits::color color;
|
||||
|
||||
void operator()(const node_ptr & to_erase, const node_ptr & successor)
|
||||
{
|
||||
//Swap color of y and z
|
||||
color tmp(NodeTraits::get_color(successor));
|
||||
NodeTraits::set_color(successor, NodeTraits::get_color(to_erase));
|
||||
NodeTraits::set_color(to_erase, tmp);
|
||||
}
|
||||
};
|
||||
|
||||
#endif //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! rbtree_algorithms provides basic algorithms to manipulate
|
||||
//! nodes forming a red-black tree. The insertion and deletion algorithms are
|
||||
//! based on those in Cormen, Leiserson, and Rivest, Introduction to Algorithms
|
||||
@@ -82,7 +120,7 @@ namespace intrusive {
|
||||
//!
|
||||
//! <b>Typedefs</b>:
|
||||
//!
|
||||
//! <tt>node</tt>: The type of the node that forms the circular list
|
||||
//! <tt>node</tt>: The type of the node that forms the binary search tree
|
||||
//!
|
||||
//! <tt>node_ptr</tt>: A pointer to a node
|
||||
//!
|
||||
@@ -113,6 +151,9 @@ namespace intrusive {
|
||||
//! <tt>static color red();</tt>
|
||||
template<class NodeTraits>
|
||||
class rbtree_algorithms
|
||||
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
: public bstree_algorithms<NodeTraits>
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
typedef NodeTraits node_traits;
|
||||
@@ -124,167 +165,71 @@ class rbtree_algorithms
|
||||
/// @cond
|
||||
private:
|
||||
|
||||
typedef detail::tree_algorithms<NodeTraits> tree_algorithms;
|
||||
typedef bstree_algorithms<NodeTraits> bstree_algorithms;
|
||||
|
||||
template<class F>
|
||||
struct rbtree_node_cloner
|
||||
: private detail::ebo_functor_holder<F>
|
||||
{
|
||||
typedef detail::ebo_functor_holder<F> base_t;
|
||||
|
||||
rbtree_node_cloner(F f)
|
||||
: base_t(f)
|
||||
{}
|
||||
|
||||
node_ptr operator()(const node_ptr & p)
|
||||
{
|
||||
node_ptr n = base_t::get()(p);
|
||||
NodeTraits::set_color(n, NodeTraits::get_color(p));
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
struct rbtree_erase_fixup
|
||||
{
|
||||
void operator()(const node_ptr & to_erase, const node_ptr & successor)
|
||||
{
|
||||
//Swap color of y and z
|
||||
color tmp(NodeTraits::get_color(successor));
|
||||
NodeTraits::set_color(successor, NodeTraits::get_color(to_erase));
|
||||
NodeTraits::set_color(to_erase, tmp);
|
||||
}
|
||||
};
|
||||
|
||||
static node_ptr uncast(const const_node_ptr & ptr)
|
||||
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
static node_ptr begin_node(const const_node_ptr & header)
|
||||
{ return tree_algorithms::begin_node(header); }
|
||||
|
||||
static node_ptr end_node(const const_node_ptr & header)
|
||||
{ return tree_algorithms::end_node(header); }
|
||||
|
||||
//! This type is the information that will be
|
||||
//! filled by insert_unique_check
|
||||
typedef typename tree_algorithms::insert_commit_data insert_commit_data;
|
||||
typedef typename bstree_algorithms::insert_commit_data insert_commit_data;
|
||||
|
||||
//! <b>Requires</b>: header1 and header2 must be the header nodes
|
||||
//! of two trees.
|
||||
//!
|
||||
//! <b>Effects</b>: Swaps two trees. After the function header1 will contain
|
||||
//! links to the second tree and header2 will have links to the first tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static void swap_tree(const node_ptr & header1, const node_ptr & header2)
|
||||
{ return tree_algorithms::swap_tree(header1, header2); }
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Requires</b>: node1 and node2 can't be header nodes
|
||||
//! of two trees.
|
||||
//!
|
||||
//! <b>Effects</b>: Swaps two nodes. After the function node1 will be inserted
|
||||
//! in the position node2 before the function. node2 will be inserted in the
|
||||
//! position node1 had before the function.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: This function will break container ordering invariants if
|
||||
//! node1 and node2 are not equivalent according to the ordering rules.
|
||||
//!
|
||||
//!Experimental function
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const const_node_ptr&)
|
||||
static node_ptr get_header(const const_node_ptr & n);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::begin_node
|
||||
static node_ptr begin_node(const const_node_ptr & header);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::end_node
|
||||
static node_ptr end_node(const const_node_ptr & header);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree
|
||||
static void swap_tree(const node_ptr & header1, const node_ptr & header2);
|
||||
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&)
|
||||
static void swap_nodes(const node_ptr & node1, const node_ptr & node2)
|
||||
{
|
||||
if(node1 == node2)
|
||||
return;
|
||||
|
||||
node_ptr header1(tree_algorithms::get_header(node1)), header2(tree_algorithms::get_header(node2));
|
||||
node_ptr header1(bstree_algorithms::get_header(node1)), header2(bstree_algorithms::get_header(node2));
|
||||
swap_nodes(node1, header1, node2, header2);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: node1 and node2 can't be header nodes
|
||||
//! of two trees with header header1 and header2.
|
||||
//!
|
||||
//! <b>Effects</b>: Swaps two nodes. After the function node1 will be inserted
|
||||
//! in the position node2 before the function. node2 will be inserted in the
|
||||
//! position node1 had before the function.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: This function will break container ordering invariants if
|
||||
//! node1 and node2 are not equivalent according to the ordering rules.
|
||||
//!
|
||||
//!Experimental function
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&,const node_ptr&,const node_ptr&)
|
||||
static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2)
|
||||
{
|
||||
if(node1 == node2) return;
|
||||
|
||||
tree_algorithms::swap_nodes(node1, header1, node2, header2);
|
||||
bstree_algorithms::swap_nodes(node1, header1, node2, header2);
|
||||
//Swap color
|
||||
color c = NodeTraits::get_color(node1);
|
||||
NodeTraits::set_color(node1, NodeTraits::get_color(node2));
|
||||
NodeTraits::set_color(node2, c);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: node_to_be_replaced must be inserted in a tree
|
||||
//! and new_node must not be inserted in a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Replaces node_to_be_replaced in its position in the
|
||||
//! tree with new_node. The tree does not need to be rebalanced
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: This function will break container ordering invariants if
|
||||
//! new_node is not equivalent to node_to_be_replaced according to the
|
||||
//! ordering rules. This function is faster than erasing and inserting
|
||||
//! the node, since no rebalancing and comparison is needed.
|
||||
//!
|
||||
//!Experimental function
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&)
|
||||
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node)
|
||||
{
|
||||
if(node_to_be_replaced == new_node)
|
||||
return;
|
||||
replace_node(node_to_be_replaced, tree_algorithms::get_header(node_to_be_replaced), new_node);
|
||||
replace_node(node_to_be_replaced, bstree_algorithms::get_header(node_to_be_replaced), new_node);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: node_to_be_replaced must be inserted in a tree
|
||||
//! with header "header" and new_node must not be inserted in a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Replaces node_to_be_replaced in its position in the
|
||||
//! tree with new_node. The tree does not need to be rebalanced
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: This function will break container ordering invariants if
|
||||
//! new_node is not equivalent to node_to_be_replaced according to the
|
||||
//! ordering rules. This function is faster than erasing and inserting
|
||||
//! the node, since no rebalancing or comparison is needed.
|
||||
//!
|
||||
//!Experimental function
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&,const node_ptr&)
|
||||
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node)
|
||||
{
|
||||
tree_algorithms::replace_node(node_to_be_replaced, header, new_node);
|
||||
bstree_algorithms::replace_node(node_to_be_replaced, header, new_node);
|
||||
NodeTraits::set_color(new_node, NodeTraits::get_color(node_to_be_replaced));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: node is a tree node but not the header.
|
||||
//!
|
||||
//! <b>Effects</b>: Unlinks the node and rebalances the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity is constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static void unlink(const node_ptr & node)
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::unlink(const node_ptr&)
|
||||
static void unlink(const node_ptr& node)
|
||||
{
|
||||
node_ptr x = NodeTraits::get_parent(node);
|
||||
if(x){
|
||||
@@ -294,517 +239,176 @@ class rbtree_algorithms
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: header is the header of a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Unlinks the leftmost node from the tree, and
|
||||
//! updates the header link to the new leftmost node.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity is constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Notes</b>: This function breaks the tree and the tree 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.
|
||||
static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header)
|
||||
{ return tree_algorithms::unlink_leftmost_without_rebalance(header); }
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance
|
||||
static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header);
|
||||
|
||||
//! <b>Requires</b>: node is a node of the tree or an node initialized
|
||||
//! by init(...).
|
||||
//!
|
||||
//! <b>Effects</b>: Returns true if the node is initialized by init().
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static bool unique(const const_node_ptr & node)
|
||||
{ return tree_algorithms::unique(node); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::unique(const const_node_ptr&)
|
||||
static bool unique(const const_node_ptr & node);
|
||||
|
||||
//! <b>Requires</b>: node is a node of the tree but it's not the header.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns the number of nodes of the subtree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static std::size_t count(const const_node_ptr & node)
|
||||
{ return tree_algorithms::count(node); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::size(const const_node_ptr&)
|
||||
static std::size_t size(const const_node_ptr & header);
|
||||
|
||||
//! <b>Requires</b>: header is the header node of the tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns the number of nodes above the header.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static std::size_t size(const const_node_ptr & header)
|
||||
{ return tree_algorithms::size(header); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const node_ptr&)
|
||||
static node_ptr next_node(const node_ptr & node);
|
||||
|
||||
//! <b>Requires</b>: p is a node from the tree except the header.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns the next node of the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static node_ptr next_node(const node_ptr & p)
|
||||
{ return tree_algorithms::next_node(p); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const node_ptr&)
|
||||
static node_ptr prev_node(const node_ptr & node);
|
||||
|
||||
//! <b>Requires</b>: p is a node from the tree except the leftmost node.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns the previous node of the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static node_ptr prev_node(const node_ptr & p)
|
||||
{ return tree_algorithms::prev_node(p); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::init(const node_ptr&)
|
||||
static void init(const node_ptr & node);
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Requires</b>: node must not be part of any tree.
|
||||
//!
|
||||
//! <b>Effects</b>: After the function unique(node) == true.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
|
||||
static void init(const node_ptr & node)
|
||||
{ tree_algorithms::init(node); }
|
||||
|
||||
//! <b>Requires</b>: node must not be part of any tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Initializes the header to represent an empty tree.
|
||||
//! unique(header) == true.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::init_header(const node_ptr&)
|
||||
static void init_header(const node_ptr & header)
|
||||
{
|
||||
tree_algorithms::init_header(header);
|
||||
bstree_algorithms::init_header(header);
|
||||
NodeTraits::set_color(header, NodeTraits::red());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: header must be the header of a tree, z a node
|
||||
//! of that tree and z != header.
|
||||
//!
|
||||
//! <b>Effects</b>: Erases node "z" from the tree with header "header".
|
||||
//!
|
||||
//! <b>Complexity</b>: Amortized constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::erase(const node_ptr&,const node_ptr&)
|
||||
static node_ptr erase(const node_ptr & header, const node_ptr & z)
|
||||
{
|
||||
typename tree_algorithms::data_for_rebalance info;
|
||||
tree_algorithms::erase(header, z, rbtree_erase_fixup(), info);
|
||||
node_ptr x = info.x;
|
||||
node_ptr x_parent = info.x_parent;
|
||||
typename bstree_algorithms::data_for_rebalance info;
|
||||
bstree_algorithms::erase(header, z, rbtree_erase_fixup<NodeTraits>(), info);
|
||||
|
||||
//Rebalance rbtree
|
||||
if(NodeTraits::get_color(z) != NodeTraits::red()){
|
||||
rebalance_after_erasure(header, x, x_parent);
|
||||
rebalance_after_erasure(header, info.x, info.x_parent);
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "cloner" must be a function
|
||||
//! object taking a node_ptr and returning a new cloned node of it. "disposer" must
|
||||
//! take a node_ptr and shouldn't throw.
|
||||
//!
|
||||
//! <b>Effects</b>: First empties target tree calling
|
||||
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
|
||||
//! except the header.
|
||||
//!
|
||||
//! Then, duplicates the entire tree pointed by "source_header" cloning each
|
||||
//! source node with <tt>node_ptr Cloner::operator()(const node_ptr &)</tt> to obtain
|
||||
//! the nodes of the target tree. If "cloner" throws, the cloned target nodes
|
||||
//! are disposed using <tt>void disposer(const node_ptr &)</tt>.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
|
||||
//! number of elements of tree target tree when calling this function.
|
||||
//!
|
||||
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::clone(const const_node_ptr&,const node_ptr&,Cloner,Disposer)
|
||||
template <class Cloner, class Disposer>
|
||||
static void clone
|
||||
(const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer)
|
||||
{
|
||||
rbtree_node_cloner<Cloner> new_cloner(cloner);
|
||||
tree_algorithms::clone(source_header, target_header, new_cloner, disposer);
|
||||
rbtree_node_cloner<NodeTraits, Cloner> new_cloner(cloner);
|
||||
bstree_algorithms::clone(source_header, target_header, new_cloner, disposer);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "disposer" must be an object function
|
||||
//! taking a node_ptr parameter and shouldn't throw.
|
||||
//!
|
||||
//! <b>Effects</b>: Empties the target tree calling
|
||||
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
|
||||
//! except the header.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
|
||||
//! number of elements of tree target tree when calling this function.
|
||||
//!
|
||||
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const node_ptr&,Disposer)
|
||||
template<class Disposer>
|
||||
static void clear_and_dispose(const node_ptr & header, Disposer disposer)
|
||||
{ tree_algorithms::clear_and_dispose(header, disposer); }
|
||||
static void clear_and_dispose(const node_ptr & header, Disposer disposer);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an node_ptr to the first element that is
|
||||
//! not less than "key" according to "comp" or "header" if that element does
|
||||
//! not exist.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr lower_bound
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return tree_algorithms::lower_bound(header, key, comp); }
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an node_ptr to the first element that is greater
|
||||
//! than "key" according to "comp" or "header" if that element does not exist.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr upper_bound
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return tree_algorithms::upper_bound(header, key, comp); }
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an node_ptr to the element that is equivalent to
|
||||
//! "key" according to "comp" or "header" if that element does not exist.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr find
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return tree_algorithms::find(header, key, comp); }
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an a pair of node_ptr delimiting a range containing
|
||||
//! all elements that are equivalent to "key" according to "comp" or an
|
||||
//! empty range that indicates the position where those elements would be
|
||||
//! if they there are no equivalent elements.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, node_ptr> equal_range
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return tree_algorithms::equal_range(header, key, comp); }
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If
|
||||
//! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an a pair with the following criteria:
|
||||
//!
|
||||
//! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise
|
||||
//!
|
||||
//! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//!
|
||||
//! <b>Note</b>: This function can be more efficient than calling upper_bound
|
||||
//! and lower_bound for lower_key and upper_key.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, node_ptr> bounded_range
|
||||
(const const_node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
|
||||
, bool left_closed, bool right_closed)
|
||||
{ return tree_algorithms::bounded_range(header, lower_key, upper_key, comp, left_closed, right_closed); }
|
||||
, bool left_closed, bool right_closed);
|
||||
|
||||
//! <b>Requires</b>: "h" 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.
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node into the tree before the upper bound
|
||||
//! according to "comp".
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity for insert element is at
|
||||
//! most logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(const node_ptr&,const node_ptr&,NodePtrCompare)
|
||||
template<class NodePtrCompare>
|
||||
static node_ptr insert_equal_upper_bound
|
||||
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp)
|
||||
{
|
||||
tree_algorithms::insert_equal_upper_bound(h, new_node, comp);
|
||||
bstree_algorithms::insert_equal_upper_bound(h, new_node, comp);
|
||||
rebalance_after_insertion(h, new_node);
|
||||
return new_node;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "h" 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.
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node into the tree before the lower bound
|
||||
//! according to "comp".
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity for insert element is at
|
||||
//! most logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(const node_ptr&,const node_ptr&,NodePtrCompare)
|
||||
template<class NodePtrCompare>
|
||||
static node_ptr insert_equal_lower_bound
|
||||
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp)
|
||||
{
|
||||
tree_algorithms::insert_equal_lower_bound(h, new_node, comp);
|
||||
bstree_algorithms::insert_equal_lower_bound(h, new_node, comp);
|
||||
rebalance_after_insertion(h, new_node);
|
||||
return new_node;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "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. "hint" is node from
|
||||
//! the "header"'s tree.
|
||||
//!
|
||||
//! <b>Effects</b>: 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).
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic in general, but it is amortized
|
||||
//! constant time if new_node is inserted immediately before "hint".
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(const node_ptr&,const node_ptr&,const node_ptr&,NodePtrCompare)
|
||||
template<class NodePtrCompare>
|
||||
static node_ptr insert_equal
|
||||
(const node_ptr & header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp)
|
||||
{
|
||||
tree_algorithms::insert_equal(header, hint, new_node, comp);
|
||||
bstree_algorithms::insert_equal(header, hint, new_node, comp);
|
||||
rebalance_after_insertion(header, new_node);
|
||||
return new_node;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "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.
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant-time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
|
||||
//! tree invariants might be broken.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(const node_ptr&,const node_ptr&,const node_ptr&)
|
||||
static node_ptr insert_before
|
||||
(const node_ptr & header, const node_ptr & pos, const node_ptr & new_node)
|
||||
{
|
||||
tree_algorithms::insert_before(header, pos, new_node);
|
||||
bstree_algorithms::insert_before(header, pos, new_node);
|
||||
rebalance_after_insertion(header, new_node);
|
||||
return new_node;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "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.
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant-time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: If "new_node" is less than the greatest inserted key
|
||||
//! tree invariants are broken. This function is slightly faster than
|
||||
//! using "insert_before".
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::push_back(const node_ptr&,const node_ptr&)
|
||||
static void push_back(const node_ptr & header, const node_ptr & new_node)
|
||||
{
|
||||
tree_algorithms::push_back(header, new_node);
|
||||
bstree_algorithms::push_back(header, new_node);
|
||||
rebalance_after_insertion(header, new_node);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "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.
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant-time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: If "new_node" is greater than the lowest inserted key
|
||||
//! tree invariants are broken. This function is slightly faster than
|
||||
//! using "insert_before".
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::push_front(const node_ptr&,const node_ptr&)
|
||||
static void push_front(const node_ptr & header, const node_ptr & new_node)
|
||||
{
|
||||
tree_algorithms::push_front(header, new_node);
|
||||
bstree_algorithms::push_front(header, new_node);
|
||||
rebalance_after_insertion(header, new_node);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. NodePtrCompare compares KeyType with a node_ptr.
|
||||
//!
|
||||
//! <b>Effects</b>: Checks if there is an equivalent node to "key" in the
|
||||
//! tree according to "comp" and obtains the needed information to realize
|
||||
//! a constant-time node insertion if there is no equivalent node.
|
||||
//!
|
||||
//! <b>Returns</b>: If there is an equivalent value
|
||||
//! returns a pair containing a node_ptr to the already present node
|
||||
//! and false. If there is not equivalent key can be inserted returns true
|
||||
//! in the returned pair's boolean and fills "commit_data" that is meant to
|
||||
//! be used with the "insert_commit" function to achieve a constant-time
|
||||
//! insertion function.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity is at most logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//!
|
||||
//! <b>Notes</b>: This function is used to improve performance when constructing
|
||||
//! a node is expensive and the user does not want to have two equivalent nodes
|
||||
//! in the tree: if there is an equivalent value
|
||||
//! the constructed object must be discarded. Many times, the part of the
|
||||
//! node that is used to impose the order is much cheaper to construct
|
||||
//! than the node and this function offers the possibility to use that part
|
||||
//! to check if the insertion will be successful.
|
||||
//!
|
||||
//! If the check is successful, the user can construct the node and use
|
||||
//! "insert_commit" to insert the node in constant-time. This gives a total
|
||||
//! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
|
||||
//!
|
||||
//! "commit_data" remains valid for a subsequent "insert_unique_commit" only
|
||||
//! if no more objects are inserted or erased from the set.
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, bool> insert_unique_check
|
||||
(const const_node_ptr & header, const KeyType &key
|
||||
,KeyNodePtrCompare comp, insert_commit_data &commit_data)
|
||||
{ return tree_algorithms::insert_unique_check(header, key, comp, commit_data); }
|
||||
,KeyNodePtrCompare comp, insert_commit_data &commit_data);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. NodePtrCompare compares KeyType with a node_ptr.
|
||||
//! "hint" is node from the "header"'s tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Checks if there is an equivalent node to "key" in the
|
||||
//! tree according to "comp" using "hint" as a hint to where it should be
|
||||
//! inserted and obtains the needed information to realize
|
||||
//! a constant-time node insertion if there is no equivalent node.
|
||||
//! If "hint" is the upper_bound the function has constant time
|
||||
//! complexity (two comparisons in the worst case).
|
||||
//!
|
||||
//! <b>Returns</b>: If there is an equivalent value
|
||||
//! returns a pair containing a node_ptr to the already present node
|
||||
//! and false. If there is not equivalent key can be inserted returns true
|
||||
//! in the returned pair's boolean and fills "commit_data" that is meant to
|
||||
//! be used with the "insert_commit" function to achieve a constant-time
|
||||
//! insertion function.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity is at most logarithmic, but it is
|
||||
//! amortized constant time if new_node should be inserted immediately before "hint".
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//!
|
||||
//! <b>Notes</b>: This function is used to improve performance when constructing
|
||||
//! a node is expensive and the user does not want to have two equivalent nodes
|
||||
//! in the tree: if there is an equivalent value
|
||||
//! the constructed object must be discarded. Many times, the part of the
|
||||
//! node that is used to impose the order is much cheaper to construct
|
||||
//! than the node and this function offers the possibility to use that part
|
||||
//! to check if the insertion will be successful.
|
||||
//!
|
||||
//! If the check is successful, the user can construct the node and use
|
||||
//! "insert_commit" to insert the node in constant-time. This gives a total
|
||||
//! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
|
||||
//!
|
||||
//! "commit_data" remains valid for a subsequent "insert_unique_commit" only
|
||||
//! if no more objects are inserted or erased from the set.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, bool> insert_unique_check
|
||||
(const const_node_ptr & header, const node_ptr &hint, const KeyType &key
|
||||
,KeyNodePtrCompare comp, insert_commit_data &commit_data)
|
||||
{ return tree_algorithms::insert_unique_check(header, hint, key, comp, commit_data); }
|
||||
,KeyNodePtrCompare comp, insert_commit_data &commit_data);
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Requires</b>: "header" must be the header node of a tree.
|
||||
//! "commit_data" must have been obtained from a previous call to
|
||||
//! "insert_unique_check". No objects should have been inserted or erased
|
||||
//! from the set between the "insert_unique_check" that filled "commit_data"
|
||||
//! and the call to "insert_commit".
|
||||
//!
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node in the set using the information obtained
|
||||
//! from the "commit_data" that a previous "insert_check" filled.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Notes</b>: This function has only sense if a "insert_unique_check" has been
|
||||
//! previously executed to fill "commit_data". No value should be inserted or
|
||||
//! erased between the "insert_check" and "insert_commit" calls.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(const node_ptr&,const node_ptr&,const insert_commit_data&)
|
||||
static void insert_unique_commit
|
||||
(const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data)
|
||||
{
|
||||
tree_algorithms::insert_unique_commit(header, new_value, commit_data);
|
||||
bstree_algorithms::insert_unique_commit(header, new_value, commit_data);
|
||||
rebalance_after_insertion(header, new_value);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "n" must be a node inserted in a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns a pointer to the header node of the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static node_ptr get_header(const node_ptr & n)
|
||||
{ return tree_algorithms::get_header(n); }
|
||||
|
||||
/// @cond
|
||||
private:
|
||||
|
||||
//! <b>Requires</b>: p is a node of a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns true if p is the header of the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::is_header
|
||||
static bool is_header(const const_node_ptr & p)
|
||||
{
|
||||
return NodeTraits::get_color(p) == NodeTraits::red() &&
|
||||
tree_algorithms::is_header(p);
|
||||
//return NodeTraits::get_color(p) == NodeTraits::red() &&
|
||||
// NodeTraits::get_parent(NodeTraits::get_parent(p)) == p;
|
||||
bstree_algorithms::is_header(p);
|
||||
}
|
||||
|
||||
/// @cond
|
||||
private:
|
||||
|
||||
static void rebalance_after_erasure(const node_ptr & header, node_ptr x, node_ptr x_parent)
|
||||
{
|
||||
while(x != NodeTraits::get_parent(header) && (!x || NodeTraits::get_color(x) == NodeTraits::black())){
|
||||
@@ -814,7 +418,7 @@ class rbtree_algorithms
|
||||
if(NodeTraits::get_color(w) == NodeTraits::red()){
|
||||
NodeTraits::set_color(w, NodeTraits::black());
|
||||
NodeTraits::set_color(x_parent, NodeTraits::red());
|
||||
tree_algorithms::rotate_left(x_parent, header);
|
||||
bstree_algorithms::rotate_left(x_parent, header);
|
||||
w = NodeTraits::get_right(x_parent);
|
||||
}
|
||||
if((!NodeTraits::get_left(w) || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()) &&
|
||||
@@ -827,14 +431,14 @@ class rbtree_algorithms
|
||||
if(!NodeTraits::get_right(w) || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()){
|
||||
NodeTraits::set_color(NodeTraits::get_left(w), NodeTraits::black());
|
||||
NodeTraits::set_color(w, NodeTraits::red());
|
||||
tree_algorithms::rotate_right(w, header);
|
||||
bstree_algorithms::rotate_right(w, header);
|
||||
w = NodeTraits::get_right(x_parent);
|
||||
}
|
||||
NodeTraits::set_color(w, NodeTraits::get_color(x_parent));
|
||||
NodeTraits::set_color(x_parent, NodeTraits::black());
|
||||
if(NodeTraits::get_right(w))
|
||||
NodeTraits::set_color(NodeTraits::get_right(w), NodeTraits::black());
|
||||
tree_algorithms::rotate_left(x_parent, header);
|
||||
bstree_algorithms::rotate_left(x_parent, header);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -844,7 +448,7 @@ class rbtree_algorithms
|
||||
if(NodeTraits::get_color(w) == NodeTraits::red()){
|
||||
NodeTraits::set_color(w, NodeTraits::black());
|
||||
NodeTraits::set_color(x_parent, NodeTraits::red());
|
||||
tree_algorithms::rotate_right(x_parent, header);
|
||||
bstree_algorithms::rotate_right(x_parent, header);
|
||||
w = NodeTraits::get_left(x_parent);
|
||||
}
|
||||
if((!NodeTraits::get_right(w) || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()) &&
|
||||
@@ -857,14 +461,14 @@ class rbtree_algorithms
|
||||
if(!NodeTraits::get_left(w) || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()){
|
||||
NodeTraits::set_color(NodeTraits::get_right(w), NodeTraits::black());
|
||||
NodeTraits::set_color(w, NodeTraits::red());
|
||||
tree_algorithms::rotate_left(w, header);
|
||||
bstree_algorithms::rotate_left(w, header);
|
||||
w = NodeTraits::get_left(x_parent);
|
||||
}
|
||||
NodeTraits::set_color(w, NodeTraits::get_color(x_parent));
|
||||
NodeTraits::set_color(x_parent, NodeTraits::black());
|
||||
if(NodeTraits::get_left(w))
|
||||
NodeTraits::set_color(NodeTraits::get_left(w), NodeTraits::black());
|
||||
tree_algorithms::rotate_right(x_parent, header);
|
||||
bstree_algorithms::rotate_right(x_parent, header);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -873,14 +477,13 @@ class rbtree_algorithms
|
||||
NodeTraits::set_color(x, NodeTraits::black());
|
||||
}
|
||||
|
||||
|
||||
static void rebalance_after_insertion(const node_ptr & header, node_ptr p)
|
||||
{
|
||||
NodeTraits::set_color(p, NodeTraits::red());
|
||||
while(p != NodeTraits::get_parent(header) && NodeTraits::get_color(NodeTraits::get_parent(p)) == NodeTraits::red()){
|
||||
node_ptr p_parent(NodeTraits::get_parent(p));
|
||||
node_ptr p_parent_parent(NodeTraits::get_parent(p_parent));
|
||||
if(tree_algorithms::is_left_child(p_parent)){
|
||||
if(bstree_algorithms::is_left_child(p_parent)){
|
||||
node_ptr x = NodeTraits::get_right(p_parent_parent);
|
||||
if(x && NodeTraits::get_color(x) == NodeTraits::red()){
|
||||
NodeTraits::set_color(p_parent, NodeTraits::black());
|
||||
@@ -889,15 +492,15 @@ class rbtree_algorithms
|
||||
p = p_parent_parent;
|
||||
}
|
||||
else {
|
||||
if(!tree_algorithms::is_left_child(p)){
|
||||
if(!bstree_algorithms::is_left_child(p)){
|
||||
p = p_parent;
|
||||
tree_algorithms::rotate_left(p, header);
|
||||
bstree_algorithms::rotate_left(p, header);
|
||||
}
|
||||
node_ptr new_p_parent(NodeTraits::get_parent(p));
|
||||
node_ptr new_p_parent_parent(NodeTraits::get_parent(new_p_parent));
|
||||
NodeTraits::set_color(new_p_parent, NodeTraits::black());
|
||||
NodeTraits::set_color(new_p_parent_parent, NodeTraits::red());
|
||||
tree_algorithms::rotate_right(new_p_parent_parent, header);
|
||||
bstree_algorithms::rotate_right(new_p_parent_parent, header);
|
||||
}
|
||||
}
|
||||
else{
|
||||
@@ -909,15 +512,15 @@ class rbtree_algorithms
|
||||
p = p_parent_parent;
|
||||
}
|
||||
else{
|
||||
if(tree_algorithms::is_left_child(p)){
|
||||
if(bstree_algorithms::is_left_child(p)){
|
||||
p = p_parent;
|
||||
tree_algorithms::rotate_right(p, header);
|
||||
bstree_algorithms::rotate_right(p, header);
|
||||
}
|
||||
node_ptr new_p_parent(NodeTraits::get_parent(p));
|
||||
node_ptr new_p_parent_parent(NodeTraits::get_parent(new_p_parent));
|
||||
NodeTraits::set_color(new_p_parent, NodeTraits::black());
|
||||
NodeTraits::set_color(new_p_parent_parent, NodeTraits::red());
|
||||
tree_algorithms::rotate_left(new_p_parent_parent, header);
|
||||
bstree_algorithms::rotate_left(new_p_parent_parent, header);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -926,6 +529,16 @@ class rbtree_algorithms
|
||||
/// @endcond
|
||||
};
|
||||
|
||||
/// @cond
|
||||
|
||||
template<class NodeTraits>
|
||||
struct get_algo<RbTreeAlgorithms, NodeTraits>
|
||||
{
|
||||
typedef rbtree_algorithms<NodeTraits> type;
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
|
||||
} //namespace intrusive
|
||||
} //namespace boost
|
||||
|
||||
|
||||
+379
-2010
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Olaf Krzikalla 2004-2006.
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -38,7 +38,7 @@ struct get_set_node_algo
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = none, class O2 = none, class O3 = none, class O4 = none>
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
|
||||
#endif
|
||||
struct make_set_base_hook
|
||||
{
|
||||
@@ -52,12 +52,12 @@ struct make_set_base_hook
|
||||
#endif
|
||||
>::type packed_options;
|
||||
|
||||
typedef detail::generic_hook
|
||||
typedef generic_hook
|
||||
< get_set_node_algo<typename packed_options::void_pointer
|
||||
,packed_options::optimize_size>
|
||||
, typename packed_options::tag
|
||||
, packed_options::link_mode
|
||||
, detail::SetBaseHook
|
||||
, RbTreeBaseHookId
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
@@ -170,7 +170,7 @@ class set_base_hook
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = none, class O2 = none, class O3 = none, class O4 = none>
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
|
||||
#endif
|
||||
struct make_set_member_hook
|
||||
{
|
||||
@@ -184,12 +184,12 @@ struct make_set_member_hook
|
||||
#endif
|
||||
>::type packed_options;
|
||||
|
||||
typedef detail::generic_hook
|
||||
typedef generic_hook
|
||||
< get_set_node_algo<typename packed_options::void_pointer
|
||||
,packed_options::optimize_size>
|
||||
, member_tag
|
||||
, packed_options::link_mode
|
||||
, detail::NoBaseHook
|
||||
, NoBaseHookId
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
|
||||
+415
-2068
File diff suppressed because it is too large
Load Diff
+403
-1445
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2007-2012
|
||||
// (C) Copyright Ion Gaztanaga 2007-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
#include <boost/intrusive/detail/tree_algorithms.hpp>
|
||||
#include <boost/intrusive/bstree_algorithms.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace intrusive {
|
||||
//!
|
||||
//! <b>Typedefs</b>:
|
||||
//!
|
||||
//! <tt>node</tt>: The type of the node that forms the circular list
|
||||
//! <tt>node</tt>: The type of the node that forms the binary search tree
|
||||
//!
|
||||
//! <tt>node_ptr</tt>: A pointer to a node
|
||||
//!
|
||||
@@ -57,6 +57,9 @@ namespace intrusive {
|
||||
//! <tt>static void set_right(node_ptr n, node_ptr right);</tt>
|
||||
template<class NodeTraits>
|
||||
class sgtree_algorithms
|
||||
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
: public bstree_algorithms<NodeTraits>
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
typedef typename NodeTraits::node node;
|
||||
@@ -67,490 +70,194 @@ class sgtree_algorithms
|
||||
/// @cond
|
||||
private:
|
||||
|
||||
typedef detail::tree_algorithms<NodeTraits> tree_algorithms;
|
||||
typedef bstree_algorithms<NodeTraits> bstree_algorithms;
|
||||
|
||||
static node_ptr uncast(const const_node_ptr & ptr)
|
||||
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
static node_ptr begin_node(const const_node_ptr & header)
|
||||
{ return tree_algorithms::begin_node(header); }
|
||||
|
||||
static node_ptr end_node(const const_node_ptr & header)
|
||||
{ return tree_algorithms::end_node(header); }
|
||||
|
||||
//! This type is the information that will be
|
||||
//! filled by insert_unique_check
|
||||
struct insert_commit_data
|
||||
: tree_algorithms::insert_commit_data
|
||||
: bstree_algorithms::insert_commit_data
|
||||
{
|
||||
std::size_t depth;
|
||||
};
|
||||
|
||||
//! <b>Requires</b>: header1 and header2 must be the header nodes
|
||||
//! of two trees.
|
||||
//!
|
||||
//! <b>Effects</b>: Swaps two trees. After the function header1 will contain
|
||||
//! links to the second tree and header2 will have links to the first tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static void swap_tree(const node_ptr & header1, const node_ptr & header2)
|
||||
{ return tree_algorithms::swap_tree(header1, header2); }
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const const_node_ptr&)
|
||||
static node_ptr get_header(const const_node_ptr & n);
|
||||
|
||||
//! <b>Requires</b>: node1 and node2 can't be header nodes
|
||||
//! of two trees.
|
||||
//!
|
||||
//! <b>Effects</b>: Swaps two nodes. After the function node1 will be inserted
|
||||
//! in the position node2 before the function. node2 will be inserted in the
|
||||
//! position node1 had before the function.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: This function will break container ordering invariants if
|
||||
//! node1 and node2 are not equivalent according to the ordering rules.
|
||||
//!
|
||||
//!Experimental function
|
||||
static void swap_nodes(const node_ptr & node1, const node_ptr & node2)
|
||||
{
|
||||
if(node1 == node2)
|
||||
return;
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::begin_node
|
||||
static node_ptr begin_node(const const_node_ptr & header);
|
||||
|
||||
node_ptr header1(tree_algorithms::get_header(node1)), header2(tree_algorithms::get_header(node2));
|
||||
swap_nodes(node1, header1, node2, header2);
|
||||
}
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::end_node
|
||||
static node_ptr end_node(const const_node_ptr & header);
|
||||
|
||||
//! <b>Requires</b>: node1 and node2 can't be header nodes
|
||||
//! of two trees with header header1 and header2.
|
||||
//!
|
||||
//! <b>Effects</b>: Swaps two nodes. After the function node1 will be inserted
|
||||
//! in the position node2 before the function. node2 will be inserted in the
|
||||
//! position node1 had before the function.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: This function will break container ordering invariants if
|
||||
//! node1 and node2 are not equivalent according to the ordering rules.
|
||||
//!
|
||||
//!Experimental function
|
||||
static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2)
|
||||
{ tree_algorithms::swap_nodes(node1, header1, node2, header2); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree
|
||||
static void swap_tree(const node_ptr & header1, const node_ptr & header2);
|
||||
|
||||
//! <b>Requires</b>: node_to_be_replaced must be inserted in a tree
|
||||
//! and new_node must not be inserted in a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Replaces node_to_be_replaced in its position in the
|
||||
//! tree with new_node. The tree does not need to be rebalanced
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: This function will break container ordering invariants if
|
||||
//! new_node is not equivalent to node_to_be_replaced according to the
|
||||
//! ordering rules. This function is faster than erasing and inserting
|
||||
//! the node, since no rebalancing and comparison is needed.
|
||||
//!
|
||||
//!Experimental function
|
||||
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node)
|
||||
{
|
||||
if(node_to_be_replaced == new_node)
|
||||
return;
|
||||
replace_node(node_to_be_replaced, tree_algorithms::get_header(node_to_be_replaced), new_node);
|
||||
}
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&)
|
||||
static void swap_nodes(const node_ptr & node1, const node_ptr & node2);
|
||||
|
||||
//! <b>Requires</b>: node_to_be_replaced must be inserted in a tree
|
||||
//! with header "header" and new_node must not be inserted in a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Replaces node_to_be_replaced in its position in the
|
||||
//! tree with new_node. The tree does not need to be rebalanced
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: This function will break container ordering invariants if
|
||||
//! new_node is not equivalent to node_to_be_replaced according to the
|
||||
//! ordering rules. This function is faster than erasing and inserting
|
||||
//! the node, since no rebalancing or comparison is needed.
|
||||
//!
|
||||
//!Experimental function
|
||||
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node)
|
||||
{ tree_algorithms::replace_node(node_to_be_replaced, header, new_node); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&,const node_ptr&,const node_ptr&)
|
||||
static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2);
|
||||
|
||||
//! <b>Requires</b>: node is a tree node but not the header.
|
||||
//!
|
||||
//! <b>Effects</b>: Unlinks the node and rebalances the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity is constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static void unlink(const node_ptr & node)
|
||||
{
|
||||
node_ptr x = NodeTraits::get_parent(node);
|
||||
if(x){
|
||||
while(!is_header(x))
|
||||
x = NodeTraits::get_parent(x);
|
||||
tree_algorithms::erase(x, node);
|
||||
}
|
||||
}
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&)
|
||||
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node);
|
||||
|
||||
//! <b>Requires</b>: header is the header of a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Unlinks the leftmost node from the tree, and
|
||||
//! updates the header link to the new leftmost node.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity is constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Notes</b>: This function breaks the tree and the tree 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.
|
||||
static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header)
|
||||
{ return tree_algorithms::unlink_leftmost_without_rebalance(header); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&,const node_ptr&)
|
||||
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node);
|
||||
|
||||
//! <b>Requires</b>: node is a node of the tree or an node initialized
|
||||
//! by init(...).
|
||||
//!
|
||||
//! <b>Effects</b>: Returns true if the node is initialized by init().
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static bool unique(const const_node_ptr & node)
|
||||
{ return tree_algorithms::unique(node); }
|
||||
//Unlink is not possible since tree metadata is needed to update the tree
|
||||
//!static void unlink(const node_ptr & node);
|
||||
|
||||
//! <b>Requires</b>: node is a node of the tree but it's not the header.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns the number of nodes of the subtree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static std::size_t count(const const_node_ptr & node)
|
||||
{ return tree_algorithms::count(node); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance
|
||||
static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header);
|
||||
|
||||
//! <b>Requires</b>: header is the header node of the tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns the number of nodes above the header.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static std::size_t size(const const_node_ptr & header)
|
||||
{ return tree_algorithms::size(header); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::unique(const const_node_ptr&)
|
||||
static bool unique(const const_node_ptr & node);
|
||||
|
||||
//! <b>Requires</b>: p is a node from the tree except the header.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns the next node of the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static node_ptr next_node(const node_ptr & p)
|
||||
{ return tree_algorithms::next_node(p); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::size(const const_node_ptr&)
|
||||
static std::size_t size(const const_node_ptr & header);
|
||||
|
||||
//! <b>Requires</b>: p is a node from the tree except the leftmost node.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns the previous node of the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static node_ptr prev_node(const node_ptr & p)
|
||||
{ return tree_algorithms::prev_node(p); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const node_ptr&)
|
||||
static node_ptr next_node(const node_ptr & node);
|
||||
|
||||
//! <b>Requires</b>: node must not be part of any tree.
|
||||
//!
|
||||
//! <b>Effects</b>: After the function unique(node) == true.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
|
||||
static void init(const node_ptr & node)
|
||||
{ tree_algorithms::init(node); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const node_ptr&)
|
||||
static node_ptr prev_node(const node_ptr & node);
|
||||
|
||||
//! <b>Requires</b>: node must not be part of any tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Initializes the header to represent an empty tree.
|
||||
//! unique(header) == true.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
|
||||
static void init_header(const node_ptr & header)
|
||||
{ tree_algorithms::init_header(header); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::init(const node_ptr&)
|
||||
static void init(const node_ptr & node);
|
||||
|
||||
//! <b>Requires</b>: header must be the header of a tree, z a node
|
||||
//! of that tree and z != header.
|
||||
//!
|
||||
//! <b>Effects</b>: Erases node "z" from the tree with header "header".
|
||||
//!
|
||||
//! <b>Complexity</b>: Amortized constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::init_header(const node_ptr&)
|
||||
static void init_header(const node_ptr & header);
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::erase(const node_ptr&,const node_ptr&)
|
||||
template<class AlphaByMaxSize>
|
||||
static node_ptr erase(const node_ptr & header, const node_ptr & z, std::size_t tree_size, std::size_t &max_tree_size, AlphaByMaxSize alpha_by_maxsize)
|
||||
{
|
||||
//typename tree_algorithms::data_for_rebalance info;
|
||||
tree_algorithms::erase(header, z);
|
||||
//typename bstree_algorithms::data_for_rebalance info;
|
||||
bstree_algorithms::erase(header, z);
|
||||
--tree_size;
|
||||
if (tree_size > 0 &&
|
||||
tree_size < alpha_by_maxsize(max_tree_size)){
|
||||
tree_algorithms::rebalance(header);
|
||||
bstree_algorithms::rebalance(header);
|
||||
max_tree_size = tree_size;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "cloner" must be a function
|
||||
//! object taking a node_ptr and returning a new cloned node of it. "disposer" must
|
||||
//! take a node_ptr and shouldn't throw.
|
||||
//!
|
||||
//! <b>Effects</b>: First empties target tree calling
|
||||
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
|
||||
//! except the header.
|
||||
//!
|
||||
//! Then, duplicates the entire tree pointed by "source_header" cloning each
|
||||
//! source node with <tt>node_ptr Cloner::operator()(const node_ptr &)</tt> to obtain
|
||||
//! the nodes of the target tree. If "cloner" throws, the cloned target nodes
|
||||
//! are disposed using <tt>void disposer(const node_ptr &)</tt>.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
|
||||
//! number of elements of tree target tree when calling this function.
|
||||
//!
|
||||
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::clone(const const_node_ptr&,const node_ptr&,Cloner,Disposer)
|
||||
template <class Cloner, class Disposer>
|
||||
static void clone
|
||||
(const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer)
|
||||
{
|
||||
tree_algorithms::clone(source_header, target_header, cloner, disposer);
|
||||
}
|
||||
(const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer);
|
||||
|
||||
//! <b>Requires</b>: "disposer" must be an object function
|
||||
//! taking a node_ptr parameter and shouldn't throw.
|
||||
//!
|
||||
//! <b>Effects</b>: Empties the target tree calling
|
||||
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
|
||||
//! except the header.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
|
||||
//! number of elements of tree target tree when calling this function.
|
||||
//!
|
||||
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const node_ptr&,Disposer)
|
||||
template<class Disposer>
|
||||
static void clear_and_dispose(const node_ptr & header, Disposer disposer)
|
||||
{ tree_algorithms::clear_and_dispose(header, disposer); }
|
||||
static void clear_and_dispose(const node_ptr & header, Disposer disposer);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an node_ptr to the first element that is
|
||||
//! not less than "key" according to "comp" or "header" if that element does
|
||||
//! not exist.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr lower_bound
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return tree_algorithms::lower_bound(header, key, comp); }
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an node_ptr to the first element that is greater
|
||||
//! than "key" according to "comp" or "header" if that element does not exist.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr upper_bound
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return tree_algorithms::upper_bound(header, key, comp); }
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an node_ptr to the element that is equivalent to
|
||||
//! "key" according to "comp" or "header" if that element does not exist.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr find
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return tree_algorithms::find(header, key, comp); }
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an a pair of node_ptr delimiting a range containing
|
||||
//! all elements that are equivalent to "key" according to "comp" or an
|
||||
//! empty range that indicates the position where those elements would be
|
||||
//! if they there are no equivalent elements.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, node_ptr> equal_range
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return tree_algorithms::equal_range(header, key, comp); }
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If
|
||||
//! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an a pair with the following criteria:
|
||||
//!
|
||||
//! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise
|
||||
//!
|
||||
//! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//!
|
||||
//! <b>Note</b>: This function can be more efficient than calling upper_bound
|
||||
//! and lower_bound for lower_key and upper_key.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, node_ptr> bounded_range
|
||||
(const const_node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
|
||||
, bool left_closed, bool right_closed)
|
||||
{ return tree_algorithms::bounded_range(header, lower_key, upper_key, comp, left_closed, right_closed); }
|
||||
, bool left_closed, bool right_closed);
|
||||
|
||||
//! <b>Requires</b>: "h" 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.
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node into the tree before the upper bound
|
||||
//! according to "comp".
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity for insert element is at
|
||||
//! most logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_upper_bound(const node_ptr&,const node_ptr&,NodePtrCompare)
|
||||
template<class NodePtrCompare, class H_Alpha>
|
||||
static node_ptr insert_equal_upper_bound
|
||||
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp
|
||||
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
|
||||
{
|
||||
std::size_t depth;
|
||||
tree_algorithms::insert_equal_upper_bound(h, new_node, comp, &depth);
|
||||
bstree_algorithms::insert_equal_upper_bound(h, new_node, comp, &depth);
|
||||
rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
|
||||
return new_node;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "h" 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.
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node into the tree before the lower bound
|
||||
//! according to "comp".
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity for insert element is at
|
||||
//! most logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal_lower_bound(const node_ptr&,const node_ptr&,NodePtrCompare)
|
||||
template<class NodePtrCompare, class H_Alpha>
|
||||
static node_ptr insert_equal_lower_bound
|
||||
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp
|
||||
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
|
||||
{
|
||||
std::size_t depth;
|
||||
tree_algorithms::insert_equal_lower_bound(h, new_node, comp, &depth);
|
||||
bstree_algorithms::insert_equal_lower_bound(h, new_node, comp, &depth);
|
||||
rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
|
||||
return new_node;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "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. "hint" is node from
|
||||
//! the "header"'s tree.
|
||||
//!
|
||||
//! <b>Effects</b>: 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).
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic in general, but it is amortized
|
||||
//! constant time if new_node is inserted immediately before "hint".
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_equal(const node_ptr&,const node_ptr&,const node_ptr&,NodePtrCompare)
|
||||
template<class NodePtrCompare, class H_Alpha>
|
||||
static node_ptr insert_equal
|
||||
(const node_ptr & header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp
|
||||
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
|
||||
{
|
||||
std::size_t depth;
|
||||
tree_algorithms::insert_equal(header, hint, new_node, comp, &depth);
|
||||
bstree_algorithms::insert_equal(header, hint, new_node, comp, &depth);
|
||||
rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
|
||||
return new_node;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. NodePtrCompare compares KeyType with a node_ptr.
|
||||
//!
|
||||
//! <b>Effects</b>: Checks if there is an equivalent node to "key" in the
|
||||
//! tree according to "comp" and obtains the needed information to realize
|
||||
//! a constant-time node insertion if there is no equivalent node.
|
||||
//!
|
||||
//! <b>Returns</b>: If there is an equivalent value
|
||||
//! returns a pair containing a node_ptr to the already present node
|
||||
//! and false. If there is not equivalent key can be inserted returns true
|
||||
//! in the returned pair's boolean and fills "commit_data" that is meant to
|
||||
//! be used with the "insert_commit" function to achieve a constant-time
|
||||
//! insertion function.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity is at most logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//!
|
||||
//! <b>Notes</b>: This function is used to improve performance when constructing
|
||||
//! a node is expensive and the user does not want to have two equivalent nodes
|
||||
//! in the tree: if there is an equivalent value
|
||||
//! the constructed object must be discarded. Many times, the part of the
|
||||
//! node that is used to impose the order is much cheaper to construct
|
||||
//! than the node and this function offers the possibility to use that part
|
||||
//! to check if the insertion will be successful.
|
||||
//!
|
||||
//! If the check is successful, the user can construct the node and use
|
||||
//! "insert_commit" to insert the node in constant-time. This gives a total
|
||||
//! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
|
||||
//!
|
||||
//! "commit_data" remains valid for a subsequent "insert_unique_commit" only
|
||||
//! if no more objects are inserted or erased from the set.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_before(const node_ptr&,const node_ptr&,const node_ptr&)
|
||||
template<class H_Alpha>
|
||||
static node_ptr insert_before
|
||||
(const node_ptr & header, const node_ptr & pos, const node_ptr & new_node
|
||||
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
|
||||
{
|
||||
std::size_t depth;
|
||||
bstree_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;
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::push_back(const node_ptr&,const node_ptr&)
|
||||
template<class H_Alpha>
|
||||
static void push_back(const node_ptr & header, const node_ptr & new_node
|
||||
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
|
||||
{
|
||||
std::size_t depth;
|
||||
bstree_algorithms::push_back(header, new_node, &depth);
|
||||
rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::push_front(const node_ptr&,const node_ptr&)
|
||||
template<class H_Alpha>
|
||||
static void push_front(const node_ptr & header, const node_ptr & new_node
|
||||
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
|
||||
{
|
||||
std::size_t depth;
|
||||
bstree_algorithms::push_front(header, new_node, &depth);
|
||||
rebalance_after_insertion(new_node, depth, tree_size+1, h_alpha, max_tree_size);
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, bool> insert_unique_check
|
||||
(const const_node_ptr & header, const KeyType &key
|
||||
@@ -558,120 +265,12 @@ class sgtree_algorithms
|
||||
{
|
||||
std::size_t depth;
|
||||
std::pair<node_ptr, bool> ret =
|
||||
tree_algorithms::insert_unique_check(header, key, comp, commit_data, &depth);
|
||||
bstree_algorithms::insert_unique_check(header, key, comp, commit_data, &depth);
|
||||
commit_data.depth = depth;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//! <b>Requires</b>: "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.
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant-time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
|
||||
//! tree invariants might be broken.
|
||||
template<class H_Alpha>
|
||||
static node_ptr insert_before
|
||||
(const node_ptr & header, const node_ptr & pos, const 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;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "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.
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant-time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: If "new_node" is less than the greatest inserted key
|
||||
//! tree invariants are broken. This function is slightly faster than
|
||||
//! using "insert_before".
|
||||
template<class H_Alpha>
|
||||
static void push_back(const node_ptr & header, const 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);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "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.
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node into the tree before "pos".
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant-time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: If "new_node" is greater than the lowest inserted key
|
||||
//! tree invariants are broken. This function is slightly faster than
|
||||
//! using "insert_before".
|
||||
template<class H_Alpha>
|
||||
static void push_front(const node_ptr & header, const 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);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. NodePtrCompare compares KeyType with a node_ptr.
|
||||
//! "hint" is node from the "header"'s tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Checks if there is an equivalent node to "key" in the
|
||||
//! tree according to "comp" using "hint" as a hint to where it should be
|
||||
//! inserted and obtains the needed information to realize
|
||||
//! a constant-time node insertion if there is no equivalent node.
|
||||
//! If "hint" is the upper_bound the function has constant time
|
||||
//! complexity (two comparisons in the worst case).
|
||||
//!
|
||||
//! <b>Returns</b>: If there is an equivalent value
|
||||
//! returns a pair containing a node_ptr to the already present node
|
||||
//! and false. If there is not equivalent key can be inserted returns true
|
||||
//! in the returned pair's boolean and fills "commit_data" that is meant to
|
||||
//! be used with the "insert_commit" function to achieve a constant-time
|
||||
//! insertion function.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity is at most logarithmic, but it is
|
||||
//! amortized constant time if new_node should be inserted immediately before "hint".
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//!
|
||||
//! <b>Notes</b>: This function is used to improve performance when constructing
|
||||
//! a node is expensive and the user does not want to have two equivalent nodes
|
||||
//! in the tree: if there is an equivalent value
|
||||
//! the constructed object must be discarded. Many times, the part of the
|
||||
//! node that is used to impose the order is much cheaper to construct
|
||||
//! than the node and this function offers the possibility to use that part
|
||||
//! to check if the insertion will be successful.
|
||||
//!
|
||||
//! If the check is successful, the user can construct the node and use
|
||||
//! "insert_commit" to insert the node in constant-time. This gives a total
|
||||
//! logarithmic complexity to the insertion: check(O(log(N)) + commit(O(1)).
|
||||
//!
|
||||
//! "commit_data" remains valid for a subsequent "insert_unique_commit" only
|
||||
//! if no more objects are inserted or erased from the set.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_check(const const_node_ptr&,const node_ptr&,const KeyType&,KeyNodePtrCompare,insert_commit_data&)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, bool> insert_unique_check
|
||||
(const const_node_ptr & header, const node_ptr &hint, const KeyType &key
|
||||
@@ -679,83 +278,36 @@ class sgtree_algorithms
|
||||
{
|
||||
std::size_t depth;
|
||||
std::pair<node_ptr, bool> ret =
|
||||
tree_algorithms::insert_unique_check
|
||||
bstree_algorithms::insert_unique_check
|
||||
(header, hint, key, comp, commit_data, &depth);
|
||||
commit_data.depth = depth;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "header" must be the header node of a tree.
|
||||
//! "commit_data" must have been obtained from a previous call to
|
||||
//! "insert_unique_check". No objects should have been inserted or erased
|
||||
//! from the set between the "insert_unique_check" that filled "commit_data"
|
||||
//! and the call to "insert_commit".
|
||||
//!
|
||||
//!
|
||||
//! <b>Effects</b>: Inserts new_node in the set using the information obtained
|
||||
//! from the "commit_data" that a previous "insert_check" filled.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Notes</b>: This function has only sense if a "insert_unique_check" has been
|
||||
//! previously executed to fill "commit_data". No value should be inserted or
|
||||
//! erased between the "insert_check" and "insert_commit" calls.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::insert_unique_commit(const node_ptr&,const node_ptr&,const insert_commit_data&)
|
||||
template<class H_Alpha>
|
||||
static void insert_unique_commit
|
||||
(const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data
|
||||
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
|
||||
{
|
||||
tree_algorithms::insert_unique_commit(header, new_value, commit_data);
|
||||
bstree_algorithms::insert_unique_commit(header, new_value, commit_data);
|
||||
rebalance_after_insertion(new_value, commit_data.depth, tree_size+1, h_alpha, max_tree_size);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: header must be the header of a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Rebalances the tree.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear.
|
||||
static void rebalance(const node_ptr & header)
|
||||
{ tree_algorithms::rebalance(header); }
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::is_header
|
||||
static bool is_header(const const_node_ptr & p);
|
||||
|
||||
//! <b>Requires</b>: old_root is a node of a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Rebalances the subtree rooted at old_root.
|
||||
//!
|
||||
//! <b>Returns</b>: The new root of the subtree.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::is_header
|
||||
static void rebalance(const node_ptr & header);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::rebalance_subtree
|
||||
static node_ptr rebalance_subtree(const node_ptr & old_root)
|
||||
{ return tree_algorithms::rebalance_subtree(old_root); }
|
||||
|
||||
//! <b>Requires</b>: "n" must be a node inserted in a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns a pointer to the header node of the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static node_ptr get_header(const node_ptr & n)
|
||||
{ return tree_algorithms::get_header(n); }
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
/// @cond
|
||||
private:
|
||||
|
||||
//! <b>Requires</b>: p is a node of a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns true if p is the header of the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static bool is_header(const const_node_ptr & p)
|
||||
{ return tree_algorithms::is_header(p); }
|
||||
|
||||
template<class H_Alpha>
|
||||
static void rebalance_after_insertion
|
||||
(const node_ptr &x, std::size_t depth
|
||||
@@ -764,7 +316,12 @@ class sgtree_algorithms
|
||||
if(tree_size > max_tree_size)
|
||||
max_tree_size = tree_size;
|
||||
|
||||
if(tree_size != 1 && depth > h_alpha(tree_size)){
|
||||
if(tree_size > 2 && //Nothing to do with only the root
|
||||
//Check if the root node is unbalanced
|
||||
//Scapegoat paper depth counts root depth as zero and "depth" counts root as 1,
|
||||
//but since "depth" is the depth of the ancestor of x, i == depth
|
||||
depth > h_alpha(tree_size)){
|
||||
|
||||
//Find the first non height-balanced node
|
||||
//as described in the section 4.2 of the paper.
|
||||
//This method is the alternative method described
|
||||
@@ -773,32 +330,40 @@ class sgtree_algorithms
|
||||
//than the weight balanced method.
|
||||
node_ptr s = x;
|
||||
std::size_t size = 1;
|
||||
|
||||
for(std::size_t i = 1; true; ++i){
|
||||
bool rebalance = false;
|
||||
if(i == depth){
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(tree_size == count(s));
|
||||
rebalance = true;
|
||||
}
|
||||
else if(i > h_alpha(size)){
|
||||
node_ptr s_parent = NodeTraits::get_parent(s);
|
||||
node_ptr s_parent_left = NodeTraits::get_left(s_parent);
|
||||
size += 1 + tree_algorithms::count
|
||||
( s_parent_left == s ? NodeTraits::get_right(s_parent) : s_parent_left );
|
||||
s = s_parent;
|
||||
rebalance = true;
|
||||
}
|
||||
if(rebalance){
|
||||
rebalance_subtree(s);
|
||||
for(std::size_t ancestor = 1; true; ++ancestor){
|
||||
if(ancestor == depth){ //Check if whole tree must be rebuilt
|
||||
max_tree_size = tree_size;
|
||||
bstree_algorithms::rebalance_subtree(NodeTraits::get_parent(s));
|
||||
break;
|
||||
}
|
||||
else{ //Go to the next scapegoat candidate
|
||||
const node_ptr s_parent = NodeTraits::get_parent(s);
|
||||
const node_ptr s_parent_left = NodeTraits::get_left(s_parent);
|
||||
//Obtain parent's size (previous size + parent + sibling tree)
|
||||
const node_ptr s_sibling = s_parent_left == s ? NodeTraits::get_right(s_parent) : s_parent_left;
|
||||
size += 1 + bstree_algorithms::subtree_size(s_sibling);
|
||||
s = s_parent;
|
||||
if(ancestor > h_alpha(size)){ //is 's' scapegoat?
|
||||
bstree_algorithms::rebalance_subtree(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
};
|
||||
|
||||
/// @cond
|
||||
|
||||
template<class NodeTraits>
|
||||
struct get_algo<SgTreeAlgorithms, NodeTraits>
|
||||
{
|
||||
typedef sgtree_algorithms<NodeTraits> type;
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
|
||||
} //namespace intrusive
|
||||
} //namespace boost
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Olaf Krzikalla 2004-2006.
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -38,16 +38,6 @@ namespace intrusive {
|
||||
|
||||
/// @cond
|
||||
|
||||
template <class ValueTraits, class SizeType, bool ConstantTimeSize, bool Linear, bool CacheLast>
|
||||
struct slistopt
|
||||
{
|
||||
typedef ValueTraits value_traits;
|
||||
typedef SizeType size_type;
|
||||
static const bool constant_time_size = ConstantTimeSize;
|
||||
static const bool linear = Linear;
|
||||
static const bool cache_last = CacheLast;
|
||||
};
|
||||
|
||||
template<class Node, class NodePtr, bool>
|
||||
struct root_plus_last
|
||||
{
|
||||
@@ -61,17 +51,22 @@ struct root_plus_last<Node, NodePtr, false>
|
||||
Node root_;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct slist_defaults
|
||||
: pack_options
|
||||
< none
|
||||
, base_hook<detail::default_slist_hook>
|
||||
, constant_time_size<true>
|
||||
, linear<false>
|
||||
, size_type<std::size_t>
|
||||
, cache_last<false>
|
||||
>::type
|
||||
{};
|
||||
{
|
||||
typedef detail::default_slist_hook proto_value_traits;
|
||||
static const bool constant_time_size = true;
|
||||
static const bool linear = false;
|
||||
typedef std::size_t size_type;
|
||||
static const bool cache_last = false;
|
||||
};
|
||||
|
||||
struct slist_bool_flags
|
||||
{
|
||||
static const std::size_t linear_pos = 1u;
|
||||
static const std::size_t constant_time_size_pos = 2u;
|
||||
static const std::size_t cache_last_pos = 4u;
|
||||
};
|
||||
|
||||
|
||||
/// @endcond
|
||||
|
||||
@@ -101,23 +96,19 @@ struct slist_defaults
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class Config>
|
||||
template<class ValueTraits, class SizeType, std::size_t BoolFlags>
|
||||
#endif
|
||||
class slist_impl
|
||||
: private detail::clear_on_destructor_base<slist_impl<Config> >
|
||||
: private detail::clear_on_destructor_base<slist_impl<ValueTraits, SizeType, BoolFlags> >
|
||||
{
|
||||
template<class C> friend class detail::clear_on_destructor_base;
|
||||
//Public typedefs
|
||||
public:
|
||||
typedef typename Config::value_traits value_traits;
|
||||
typedef ValueTraits value_traits;
|
||||
/// @cond
|
||||
static const bool external_value_traits =
|
||||
detail::external_value_traits_bool_is_true<value_traits>::value;
|
||||
typedef typename detail::eval_if_c
|
||||
< external_value_traits
|
||||
, detail::eval_value_traits<value_traits>
|
||||
, detail::identity<value_traits>
|
||||
>::type real_value_traits;
|
||||
typedef typename detail::get_real_value_traits<ValueTraits>::type real_value_traits;
|
||||
/// @endcond
|
||||
typedef typename real_value_traits::pointer pointer;
|
||||
typedef typename real_value_traits::const_pointer const_pointer;
|
||||
@@ -125,25 +116,25 @@ class slist_impl
|
||||
typedef typename pointer_traits<pointer>::reference reference;
|
||||
typedef typename pointer_traits<const_pointer>::reference const_reference;
|
||||
typedef typename pointer_traits<pointer>::difference_type difference_type;
|
||||
typedef typename Config::size_type size_type;
|
||||
typedef slist_iterator<slist_impl, false> iterator;
|
||||
typedef slist_iterator<slist_impl, true> const_iterator;
|
||||
typedef SizeType size_type;
|
||||
typedef slist_iterator<real_value_traits, false> iterator;
|
||||
typedef slist_iterator<real_value_traits, true> const_iterator;
|
||||
typedef typename real_value_traits::node_traits node_traits;
|
||||
typedef typename node_traits::node node;
|
||||
typedef typename node_traits::node_ptr node_ptr;
|
||||
typedef typename node_traits::const_node_ptr const_node_ptr;
|
||||
|
||||
static const bool constant_time_size = 0 != (BoolFlags & slist_bool_flags::constant_time_size_pos);
|
||||
static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
|
||||
static const bool linear = 0 != (BoolFlags & slist_bool_flags::linear_pos);
|
||||
static const bool cache_last = 0 != (BoolFlags & slist_bool_flags::cache_last_pos);
|
||||
|
||||
typedef typename detail::if_c
|
||||
< Config::linear
|
||||
< linear
|
||||
, linear_slist_algorithms<node_traits>
|
||||
, circular_slist_algorithms<node_traits>
|
||||
>::type node_algorithms;
|
||||
|
||||
static const bool constant_time_size = Config::constant_time_size;
|
||||
static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
|
||||
static const bool linear = Config::linear;
|
||||
static const bool cache_last = Config::cache_last;
|
||||
|
||||
/// @cond
|
||||
private:
|
||||
typedef detail::size_holder<constant_time_size, size_type> size_traits;
|
||||
@@ -151,9 +142,7 @@ class slist_impl
|
||||
//noncopyable
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(slist_impl)
|
||||
|
||||
enum { safemode_or_autounlink =
|
||||
(int)real_value_traits::link_mode == (int)auto_unlink ||
|
||||
(int)real_value_traits::link_mode == (int)safe_link };
|
||||
static const bool safemode_or_autounlink = is_safe_autounlink<real_value_traits::link_mode>::value;
|
||||
|
||||
//Constant-time size is incompatible with auto-unlink hooks!
|
||||
BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink)));
|
||||
@@ -207,9 +196,6 @@ class slist_impl
|
||||
void set_last_node(const node_ptr & n, detail::bool_<true>)
|
||||
{ data_.root_plus_size_.last_ = n; }
|
||||
|
||||
static node_ptr uncast(const const_node_ptr & ptr)
|
||||
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
|
||||
|
||||
void set_default_constructed_state()
|
||||
{
|
||||
node_algorithms::init_header(this->get_root_node());
|
||||
@@ -279,6 +265,11 @@ class slist_impl
|
||||
real_value_traits &get_real_value_traits()
|
||||
{ return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
|
||||
|
||||
typedef typename pointer_traits<node_ptr>::template rebind_pointer<const real_value_traits>::type const_real_value_traits_ptr;
|
||||
|
||||
const_real_value_traits_ptr real_value_traits_ptr() const
|
||||
{ return pointer_traits<const_real_value_traits_ptr>::pointer_to(this->get_real_value_traits()); }
|
||||
|
||||
public:
|
||||
|
||||
///@cond
|
||||
@@ -511,7 +502,7 @@ class slist_impl
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_reference front() const
|
||||
{ return *this->get_real_value_traits().to_value_ptr(uncast(node_traits::get_next(this->get_root_node()))); }
|
||||
{ return *this->get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); }
|
||||
|
||||
//! <b>Effects</b>: Returns a reference to the last element of the list.
|
||||
//!
|
||||
@@ -547,7 +538,7 @@ class slist_impl
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
iterator begin()
|
||||
{ return iterator (node_traits::get_next(this->get_root_node()), this); }
|
||||
{ return iterator (node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); }
|
||||
|
||||
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
|
||||
//!
|
||||
@@ -555,7 +546,7 @@ class slist_impl
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_iterator begin() const
|
||||
{ return const_iterator (node_traits::get_next(this->get_root_node()), this); }
|
||||
{ return const_iterator (node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); }
|
||||
|
||||
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
|
||||
//!
|
||||
@@ -563,7 +554,7 @@ class slist_impl
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_iterator cbegin() const
|
||||
{ return const_iterator(node_traits::get_next(this->get_root_node()), this); }
|
||||
{ return const_iterator(node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); }
|
||||
|
||||
//! <b>Effects</b>: Returns an iterator to the end of the list.
|
||||
//!
|
||||
@@ -571,7 +562,7 @@ class slist_impl
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
iterator end()
|
||||
{ return iterator(this->get_end_node(), this); }
|
||||
{ return iterator(this->get_end_node(), this->real_value_traits_ptr()); }
|
||||
|
||||
//! <b>Effects</b>: Returns a const_iterator to the end of the list.
|
||||
//!
|
||||
@@ -579,7 +570,7 @@ class slist_impl
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_iterator end() const
|
||||
{ return const_iterator(uncast(this->get_end_node()), this); }
|
||||
{ return const_iterator(detail::uncast(this->get_end_node()), this->real_value_traits_ptr()); }
|
||||
|
||||
//! <b>Effects</b>: Returns a const_iterator to the end of the list.
|
||||
//!
|
||||
@@ -596,7 +587,7 @@ class slist_impl
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
iterator before_begin()
|
||||
{ return iterator(this->get_root_node(), this); }
|
||||
{ return iterator(this->get_root_node(), this->real_value_traits_ptr()); }
|
||||
|
||||
//! <b>Effects</b>: Returns an iterator that points to a position
|
||||
//! before the first element. Equivalent to "end()"
|
||||
@@ -605,7 +596,7 @@ class slist_impl
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
const_iterator before_begin() const
|
||||
{ return const_iterator(uncast(this->get_root_node()), this); }
|
||||
{ return const_iterator(detail::uncast(this->get_root_node()), this->real_value_traits_ptr()); }
|
||||
|
||||
//! <b>Effects</b>: Returns an iterator that points to a position
|
||||
//! before the first element. Equivalent to "end()"
|
||||
@@ -627,7 +618,7 @@ class slist_impl
|
||||
{
|
||||
//This function shall not be used if cache_last is not true
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last);
|
||||
return iterator (this->get_last_node(), this);
|
||||
return iterator (this->get_last_node(), this->real_value_traits_ptr());
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Returns a const_iterator to the last element contained in the list.
|
||||
@@ -641,7 +632,7 @@ class slist_impl
|
||||
{
|
||||
//This function shall not be used if cache_last is not true
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last);
|
||||
return const_iterator (this->get_last_node(), this);
|
||||
return const_iterator (this->get_last_node(), this->real_value_traits_ptr());
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Returns a const_iterator to the last element contained in the list.
|
||||
@@ -652,7 +643,7 @@ class slist_impl
|
||||
//!
|
||||
//! <b>Note</b>: This function is present only if cached_last<> option is true.
|
||||
const_iterator clast() const
|
||||
{ return const_iterator(this->get_last_node(), this); }
|
||||
{ return const_iterator(this->get_last_node(), this->real_value_traits_ptr()); }
|
||||
|
||||
//! <b>Precondition</b>: end_iterator must be a valid end iterator
|
||||
//! of slist.
|
||||
@@ -801,7 +792,7 @@ class slist_impl
|
||||
this->set_last_node(n);
|
||||
}
|
||||
this->priv_size_traits().increment();
|
||||
return iterator (n, this);
|
||||
return iterator (n, this->real_value_traits_ptr());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: Dereferencing iterator must yield
|
||||
@@ -1696,7 +1687,7 @@ class slist_impl
|
||||
{
|
||||
BOOST_STATIC_ASSERT((!stateful_value_traits));
|
||||
//BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(value)));
|
||||
return iterator (value_traits::to_node_ptr(value), 0);
|
||||
return iterator (value_traits::to_node_ptr(value), const_real_value_traits_ptr());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: value must be a const reference to a value inserted in a list.
|
||||
@@ -1714,7 +1705,7 @@ class slist_impl
|
||||
{
|
||||
BOOST_STATIC_ASSERT((!stateful_value_traits));
|
||||
//BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast<reference> (value))));
|
||||
return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), 0);
|
||||
return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), const_real_value_traits_ptr());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: value must be a reference to a value inserted in a list.
|
||||
@@ -1729,7 +1720,7 @@ class slist_impl
|
||||
iterator iterator_to(reference value)
|
||||
{
|
||||
//BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(value)));
|
||||
return iterator (value_traits::to_node_ptr(value), this);
|
||||
return iterator (value_traits::to_node_ptr(value), this->real_value_traits_ptr());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: value must be a const reference to a value inserted in a list.
|
||||
@@ -1744,7 +1735,7 @@ class slist_impl
|
||||
const_iterator iterator_to(const_reference value) const
|
||||
{
|
||||
//BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast<reference> (value))));
|
||||
return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), this);
|
||||
return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), this->real_value_traits_ptr());
|
||||
}
|
||||
|
||||
//! <b>Returns</b>: The iterator to the element before i in the list.
|
||||
@@ -1793,11 +1784,11 @@ class slist_impl
|
||||
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(detail::uncast(this->get_last_node()), this->real_value_traits_ptr());
|
||||
}
|
||||
return const_iterator
|
||||
(node_algorithms::get_previous_node
|
||||
(prev_from.pointed_node(), i.pointed_node()), this);
|
||||
(prev_from.pointed_node(), i.pointed_node()), this->real_value_traits_ptr());
|
||||
}
|
||||
|
||||
///@cond
|
||||
@@ -1846,7 +1837,11 @@ class slist_impl
|
||||
{
|
||||
if(n){
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(n > 0);
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(size_type(std::distance(iterator(f, this), iterator(before_l, this)))+1 == n);
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT
|
||||
(size_type(std::distance
|
||||
( iterator(f, this->real_value_traits_ptr())
|
||||
, iterator(before_l, this->real_value_traits_ptr())))
|
||||
+1 == n);
|
||||
this->priv_incorporate_after(prev_pos.pointed_node(), f, before_l);
|
||||
if(constant_time_size){
|
||||
this->priv_size_traits().increase(n);
|
||||
@@ -1994,29 +1989,31 @@ class slist_impl
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class Config>
|
||||
template<class ValueTraits, class SizeType, std::size_t BoolFlags>
|
||||
#endif
|
||||
inline bool operator<
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
|
||||
#else
|
||||
(const slist_impl<Config> &x, const slist_impl<Config> &y)
|
||||
( const slist_impl<ValueTraits, SizeType, BoolFlags> &x
|
||||
, const slist_impl<ValueTraits, SizeType, BoolFlags> &y)
|
||||
#endif
|
||||
{ return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); }
|
||||
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class Config>
|
||||
template<class ValueTraits, class SizeType, std::size_t BoolFlags>
|
||||
#endif
|
||||
bool operator==
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
|
||||
#else
|
||||
(const slist_impl<Config> &x, const slist_impl<Config> &y)
|
||||
( const slist_impl<ValueTraits, SizeType, BoolFlags> &x
|
||||
, const slist_impl<ValueTraits, SizeType, BoolFlags> &y)
|
||||
#endif
|
||||
{
|
||||
typedef slist_impl<Config> slist_type;
|
||||
typedef slist_impl<ValueTraits, SizeType, BoolFlags> slist_type;
|
||||
typedef typename slist_type::const_iterator const_iterator;
|
||||
const bool C = slist_type::constant_time_size;
|
||||
if(C && x.size() != y.size()){
|
||||
@@ -2046,65 +2043,70 @@ bool operator==
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class Config>
|
||||
template<class ValueTraits, class SizeType, std::size_t BoolFlags>
|
||||
#endif
|
||||
inline bool operator!=
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
|
||||
#else
|
||||
(const slist_impl<Config> &x, const slist_impl<Config> &y)
|
||||
( const slist_impl<ValueTraits, SizeType, BoolFlags> &x
|
||||
, const slist_impl<ValueTraits, SizeType, BoolFlags> &y)
|
||||
#endif
|
||||
{ return !(x == y); }
|
||||
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class Config>
|
||||
template<class ValueTraits, class SizeType, std::size_t BoolFlags>
|
||||
#endif
|
||||
inline bool operator>
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
|
||||
#else
|
||||
(const slist_impl<Config> &x, const slist_impl<Config> &y)
|
||||
( const slist_impl<ValueTraits, SizeType, BoolFlags> &x
|
||||
, const slist_impl<ValueTraits, SizeType, BoolFlags> &y)
|
||||
#endif
|
||||
{ return y < x; }
|
||||
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class Config>
|
||||
template<class ValueTraits, class SizeType, std::size_t BoolFlags>
|
||||
#endif
|
||||
inline bool operator<=
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
|
||||
#else
|
||||
(const slist_impl<Config> &x, const slist_impl<Config> &y)
|
||||
( const slist_impl<ValueTraits, SizeType, BoolFlags> &x
|
||||
, const slist_impl<ValueTraits, SizeType, BoolFlags> &y)
|
||||
#endif
|
||||
{ return !(y < x); }
|
||||
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class Config>
|
||||
template<class ValueTraits, class SizeType, std::size_t BoolFlags>
|
||||
#endif
|
||||
inline bool operator>=
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
(const slist_impl<T, Options...> &x, const slist_impl<T, Options...> &y)
|
||||
#else
|
||||
(const slist_impl<Config> &x, const slist_impl<Config> &y)
|
||||
( const slist_impl<ValueTraits, SizeType, BoolFlags> &x
|
||||
, const slist_impl<ValueTraits, SizeType, BoolFlags> &y)
|
||||
#endif
|
||||
{ return !(x < y); }
|
||||
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class Config>
|
||||
template<class ValueTraits, class SizeType, std::size_t BoolFlags>
|
||||
#endif
|
||||
inline void swap
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
(slist_impl<T, Options...> &x, slist_impl<T, Options...> &y)
|
||||
#else
|
||||
(slist_impl<Config> &x, slist_impl<Config> &y)
|
||||
( slist_impl<ValueTraits, SizeType, BoolFlags> &x
|
||||
, slist_impl<ValueTraits, SizeType, BoolFlags> &y)
|
||||
#endif
|
||||
{ x.swap(y); }
|
||||
|
||||
@@ -2113,13 +2115,13 @@ inline void swap
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class T, class ...Options>
|
||||
#else
|
||||
template<class T, class O1 = none, class O2 = none, class O3 = none, class O4 = none, class O5 = none>
|
||||
template<class T, class O1 = void, class O2 = void, class O3 = void, class O4 = void, class O5 = void>
|
||||
#endif
|
||||
struct make_slist
|
||||
{
|
||||
/// @cond
|
||||
typedef typename pack_options
|
||||
< slist_defaults<T>,
|
||||
< slist_defaults,
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3, O4, O5
|
||||
#else
|
||||
@@ -2127,16 +2129,13 @@ struct make_slist
|
||||
#endif
|
||||
>::type packed_options;
|
||||
typedef typename detail::get_value_traits
|
||||
<T, typename packed_options::value_traits>::type value_traits;
|
||||
<T, typename packed_options::proto_value_traits>::type value_traits;
|
||||
typedef slist_impl
|
||||
<
|
||||
slistopt
|
||||
< value_traits
|
||||
, typename packed_options::size_type
|
||||
, packed_options::constant_time_size
|
||||
, packed_options::linear
|
||||
, packed_options::cache_last
|
||||
>
|
||||
< value_traits
|
||||
, typename packed_options::size_type
|
||||
, (std::size_t(packed_options::linear)*slist_bool_flags::linear_pos)
|
||||
|(std::size_t(packed_options::constant_time_size)*slist_bool_flags::constant_time_size_pos)
|
||||
|(std::size_t(packed_options::cache_last)*slist_bool_flags::cache_last_pos)
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
@@ -2200,7 +2199,7 @@ class slist
|
||||
{}
|
||||
|
||||
slist& operator=(BOOST_RV_REF(slist) x)
|
||||
{ this->Base::operator=(::boost::move(static_cast<Base&>(x))); return *this; }
|
||||
{ return static_cast<slist &>(this->Base::operator=(::boost::move(static_cast<Base&>(x)))); }
|
||||
|
||||
static slist &container_from_end_iterator(iterator end_iterator)
|
||||
{ return static_cast<slist &>(Base::container_from_end_iterator(end_iterator)); }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Olaf Krzikalla 2004-2006.
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -40,7 +40,7 @@ struct get_slist_node_algo
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = none, class O2 = none, class O3 = none>
|
||||
template<class O1 = void, class O2 = void, class O3 = void>
|
||||
#endif
|
||||
struct make_slist_base_hook
|
||||
{
|
||||
@@ -54,11 +54,11 @@ struct make_slist_base_hook
|
||||
#endif
|
||||
>::type packed_options;
|
||||
|
||||
typedef detail::generic_hook
|
||||
typedef generic_hook
|
||||
< get_slist_node_algo<typename packed_options::void_pointer>
|
||||
, typename packed_options::tag
|
||||
, packed_options::link_mode
|
||||
, detail::SlistBaseHook
|
||||
, SlistBaseHookId
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
@@ -168,7 +168,7 @@ class slist_base_hook
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = none, class O2 = none, class O3 = none>
|
||||
template<class O1 = void, class O2 = void, class O3 = void>
|
||||
#endif
|
||||
struct make_slist_member_hook
|
||||
{
|
||||
@@ -182,11 +182,11 @@ struct make_slist_member_hook
|
||||
#endif
|
||||
>::type packed_options;
|
||||
|
||||
typedef detail::generic_hook
|
||||
typedef generic_hook
|
||||
< get_slist_node_algo<typename packed_options::void_pointer>
|
||||
, member_tag
|
||||
, packed_options::link_mode
|
||||
, detail::NoBaseHook
|
||||
, NoBaseHookId
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
|
||||
+541
-2056
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Olaf Krzikalla 2004-2006.
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -14,49 +14,37 @@
|
||||
#define BOOST_INTRUSIVE_SPLAY_SET_HOOK_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
#include <boost/intrusive/detail/tree_node.hpp>
|
||||
#include <boost/intrusive/splaytree_algorithms.hpp>
|
||||
#include <boost/intrusive/options.hpp>
|
||||
#include <boost/intrusive/detail/generic_hook.hpp>
|
||||
#include <boost/intrusive/bs_set_hook.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace intrusive {
|
||||
|
||||
/// @cond
|
||||
template<class VoidPointer>
|
||||
struct get_splay_set_node_algo
|
||||
{
|
||||
typedef splaytree_algorithms<tree_node_traits<VoidPointer> > type;
|
||||
};
|
||||
/// @endcond
|
||||
|
||||
//! Helper metafunction to define a \c splay_set_base_hook that yields to the same
|
||||
//! type when the same options (either explicitly or implicitly) are used.
|
||||
//! <b>WARNING: </b> Deprecated class, use `make_bs_set_base_hook` instead.
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = none, class O2 = none, class O3 = none>
|
||||
template<class O1 = void, class O2 = void, class O3 = void>
|
||||
#endif
|
||||
struct make_splay_set_base_hook
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
#if defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
: public make_bs_set_base_hook<Options...>
|
||||
#else
|
||||
: public make_bs_set_base_hook<O1, O2, O3>
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
/// @cond
|
||||
typedef typename pack_options
|
||||
< hook_defaults,
|
||||
typedef typename make_bs_set_base_hook
|
||||
<
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3
|
||||
#else
|
||||
Options...
|
||||
#endif
|
||||
>::type packed_options;
|
||||
|
||||
typedef detail::generic_hook
|
||||
< get_splay_set_node_algo<typename packed_options::void_pointer>
|
||||
, typename packed_options::tag
|
||||
, packed_options::link_mode
|
||||
, detail::SplaySetBaseHook
|
||||
> implementation_defined;
|
||||
>::type implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
};
|
||||
@@ -78,6 +66,8 @@ struct make_splay_set_base_hook
|
||||
//!
|
||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||
//! \c auto_unlink or \c safe_link).
|
||||
//!
|
||||
//! <b>WARNING: </b> Deprecated class, use `bs_set_base_hook` instead.
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
@@ -162,29 +152,31 @@ class splay_set_base_hook
|
||||
|
||||
//! Helper metafunction to define a \c splay_set_member_hook that yields to the same
|
||||
//! type when the same options (either explicitly or implicitly) are used.
|
||||
//!
|
||||
//! <b>WARNING: </b> Deprecated class, use `make_bs_set_member_hook` instead.
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = none, class O2 = none, class O3 = none>
|
||||
template<class O1 = void, class O2 = void, class O3 = void>
|
||||
#endif
|
||||
struct make_splay_set_member_hook
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
#if defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
: public make_bs_set_member_hook<Options...>
|
||||
#else
|
||||
: public make_bs_set_member_hook<O1, O2, O3>
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
/// @cond
|
||||
typedef typename pack_options
|
||||
< hook_defaults,
|
||||
typedef typename make_bs_set_member_hook
|
||||
<
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3
|
||||
#else
|
||||
Options...
|
||||
#endif
|
||||
>::type packed_options;
|
||||
|
||||
typedef detail::generic_hook
|
||||
< get_splay_set_node_algo<typename packed_options::void_pointer>
|
||||
, member_tag
|
||||
, packed_options::link_mode
|
||||
, detail::NoBaseHook
|
||||
> implementation_defined;
|
||||
>::type implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
};
|
||||
@@ -202,6 +194,8 @@ struct make_splay_set_member_hook
|
||||
//!
|
||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||
//! \c auto_unlink or \c safe_link).
|
||||
//!
|
||||
//! <b>WARNING: </b> Deprecated class, use `bs_set_member_hook` instead.
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
|
||||
+398
-1486
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+320
-1028
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012.
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013.
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
#include <boost/intrusive/detail/tree_algorithms.hpp>
|
||||
#include <boost/intrusive/bstree_algorithms.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace intrusive {
|
||||
//!
|
||||
//! <b>Typedefs</b>:
|
||||
//!
|
||||
//! <tt>node</tt>: The type of the node that forms the circular list
|
||||
//! <tt>node</tt>: The type of the node that forms the treap
|
||||
//!
|
||||
//! <tt>node_ptr</tt>: A pointer to a node
|
||||
//!
|
||||
@@ -68,6 +68,9 @@ namespace intrusive {
|
||||
//! <tt>static void set_right(node_ptr n, node_ptr right);</tt>
|
||||
template<class NodeTraits>
|
||||
class treap_algorithms
|
||||
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
: public bstree_algorithms<NodeTraits>
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
typedef NodeTraits node_traits;
|
||||
@@ -78,32 +81,8 @@ class treap_algorithms
|
||||
/// @cond
|
||||
private:
|
||||
|
||||
class remove_on_destroy
|
||||
{
|
||||
remove_on_destroy(const remove_on_destroy&);
|
||||
remove_on_destroy& operator=(const remove_on_destroy&);
|
||||
public:
|
||||
remove_on_destroy(const node_ptr & header, const node_ptr & z)
|
||||
: header_(header), z_(z), remove_it_(true)
|
||||
{}
|
||||
~remove_on_destroy()
|
||||
{
|
||||
if(remove_it_){
|
||||
tree_algorithms::erase(header_, z_);
|
||||
}
|
||||
}
|
||||
|
||||
void release()
|
||||
{ remove_it_ = false; }
|
||||
|
||||
const node_ptr header_;
|
||||
const node_ptr z_;
|
||||
bool remove_it_;
|
||||
};
|
||||
|
||||
class rerotate_on_destroy
|
||||
{
|
||||
rerotate_on_destroy(const remove_on_destroy&);
|
||||
rerotate_on_destroy& operator=(const rerotate_on_destroy&);
|
||||
|
||||
public:
|
||||
@@ -134,33 +113,24 @@ class treap_algorithms
|
||||
; p_parent = NodeTraits::get_parent(p)){
|
||||
//Check if left child
|
||||
if(p == NodeTraits::get_left(p_parent)){
|
||||
tree_algorithms::rotate_right(p_parent, header);
|
||||
bstree_algorithms::rotate_right(p_parent, header);
|
||||
}
|
||||
else{ //Right child
|
||||
tree_algorithms::rotate_left(p_parent, header);
|
||||
bstree_algorithms::rotate_left(p_parent, header);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef detail::tree_algorithms<NodeTraits> tree_algorithms;
|
||||
|
||||
static node_ptr uncast(const const_node_ptr & ptr)
|
||||
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
|
||||
typedef bstree_algorithms<NodeTraits> bstree_algorithms;
|
||||
|
||||
/// @endcond
|
||||
|
||||
public:
|
||||
static node_ptr begin_node(const const_node_ptr & header)
|
||||
{ return tree_algorithms::begin_node(header); }
|
||||
|
||||
static node_ptr end_node(const const_node_ptr & header)
|
||||
{ return tree_algorithms::end_node(header); }
|
||||
|
||||
//! This type is the information that will be
|
||||
//! filled by insert_unique_check
|
||||
struct insert_commit_data
|
||||
/// @cond
|
||||
: public tree_algorithms::insert_commit_data
|
||||
: public bstree_algorithms::insert_commit_data
|
||||
/// @endcond
|
||||
{
|
||||
/// @cond
|
||||
@@ -168,360 +138,117 @@ class treap_algorithms
|
||||
/// @endcond
|
||||
};
|
||||
|
||||
//! <b>Requires</b>: header1 and header2 must be the header nodes
|
||||
//! of two trees.
|
||||
//!
|
||||
//! <b>Effects</b>: Swaps two trees. After the function header1 will contain
|
||||
//! links to the second tree and header2 will have links to the first tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static void swap_tree(const node_ptr & header1, const node_ptr & header2)
|
||||
{ return tree_algorithms::swap_tree(header1, header2); }
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Requires</b>: node1 and node2 can't be header nodes
|
||||
//! of two trees.
|
||||
//!
|
||||
//! <b>Effects</b>: Swaps two nodes. After the function node1 will be inserted
|
||||
//! in the position node2 before the function. node2 will be inserted in the
|
||||
//! position node1 had before the function.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: This function will break container ordering invariants if
|
||||
//! node1 and node2 are not equivalent according to the ordering rules.
|
||||
//!
|
||||
//!Experimental function
|
||||
static void swap_nodes(const node_ptr & node1, const node_ptr & node2)
|
||||
{
|
||||
if(node1 == node2)
|
||||
return;
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::get_header(const const_node_ptr&)
|
||||
static node_ptr get_header(const const_node_ptr & n);
|
||||
|
||||
node_ptr header1(tree_algorithms::get_header(node1)), header2(tree_algorithms::get_header(node2));
|
||||
swap_nodes(node1, header1, node2, header2);
|
||||
}
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::begin_node
|
||||
static node_ptr begin_node(const const_node_ptr & header);
|
||||
|
||||
//! <b>Requires</b>: node1 and node2 can't be header nodes
|
||||
//! of two trees with header header1 and header2.
|
||||
//!
|
||||
//! <b>Effects</b>: Swaps two nodes. After the function node1 will be inserted
|
||||
//! in the position node2 before the function. node2 will be inserted in the
|
||||
//! position node1 had before the function.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: This function will break container ordering invariants if
|
||||
//! node1 and node2 are not equivalent according to the ordering rules.
|
||||
//!
|
||||
//!Experimental function
|
||||
static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2)
|
||||
{ tree_algorithms::swap_nodes(node1, header1, node2, header2); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::end_node
|
||||
static node_ptr end_node(const const_node_ptr & header);
|
||||
|
||||
//! <b>Requires</b>: node_to_be_replaced must be inserted in a tree
|
||||
//! and new_node must not be inserted in a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Replaces node_to_be_replaced in its position in the
|
||||
//! tree with new_node. The tree does not need to be rebalanced
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: This function will break container ordering invariants if
|
||||
//! new_node is not equivalent to node_to_be_replaced according to the
|
||||
//! ordering rules. This function is faster than erasing and inserting
|
||||
//! the node, since no rebalancing and comparison is needed.
|
||||
//!
|
||||
//!Experimental function
|
||||
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node)
|
||||
{
|
||||
if(node_to_be_replaced == new_node)
|
||||
return;
|
||||
replace_node(node_to_be_replaced, tree_algorithms::get_header(node_to_be_replaced), new_node);
|
||||
}
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_tree
|
||||
static void swap_tree(const node_ptr & header1, const node_ptr & header2);
|
||||
|
||||
//! <b>Requires</b>: node_to_be_replaced must be inserted in a tree
|
||||
//! with header "header" and new_node must not be inserted in a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Replaces node_to_be_replaced in its position in the
|
||||
//! tree with new_node. The tree does not need to be rebalanced
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Note</b>: This function will break container ordering invariants if
|
||||
//! new_node is not equivalent to node_to_be_replaced according to the
|
||||
//! ordering rules. This function is faster than erasing and inserting
|
||||
//! the node, since no rebalancing or comparison is needed.
|
||||
//!
|
||||
//!Experimental function
|
||||
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node)
|
||||
{ tree_algorithms::replace_node(node_to_be_replaced, header, new_node); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&)
|
||||
static void swap_nodes(const node_ptr & node1, const node_ptr & node2);
|
||||
|
||||
//! <b>Requires</b>: node is a tree node but not the header.
|
||||
//!
|
||||
//! <b>Effects</b>: Unlinks the node and rebalances the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity is constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: If "pcomp" throws, strong guarantee
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::swap_nodes(const node_ptr&,const node_ptr&,const node_ptr&,const node_ptr&)
|
||||
static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&)
|
||||
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::replace_node(const node_ptr&,const node_ptr&,const node_ptr&)
|
||||
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node);
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::unlink(const node_ptr&)
|
||||
template<class NodePtrPriorityCompare>
|
||||
static void unlink(const node_ptr & node, NodePtrPriorityCompare pcomp)
|
||||
{
|
||||
node_ptr x = NodeTraits::get_parent(node);
|
||||
if(x){
|
||||
while(!is_header(x))
|
||||
while(!bstree_algorithms::is_header(x))
|
||||
x = NodeTraits::get_parent(x);
|
||||
erase(x, node, pcomp);
|
||||
}
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: header is the header of a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Unlinks the leftmost node from the tree, and
|
||||
//! updates the header link to the new leftmost node.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average complexity is constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Notes</b>: This function breaks the tree and the tree 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.
|
||||
static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header)
|
||||
{ return tree_algorithms::unlink_leftmost_without_rebalance(header); }
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::unlink_leftmost_without_rebalance
|
||||
static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header);
|
||||
|
||||
//! <b>Requires</b>: node is a node of the tree or an node initialized
|
||||
//! by init(...).
|
||||
//!
|
||||
//! <b>Effects</b>: Returns true if the node is initialized by init().
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static bool unique(const const_node_ptr & node)
|
||||
{ return tree_algorithms::unique(node); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::unique(const const_node_ptr&)
|
||||
static bool unique(const const_node_ptr & node);
|
||||
|
||||
//! <b>Requires</b>: node is a node of the tree but it's not the header.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns the number of nodes of the subtree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static std::size_t count(const const_node_ptr & node)
|
||||
{ return tree_algorithms::count(node); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::size(const const_node_ptr&)
|
||||
static std::size_t size(const const_node_ptr & header);
|
||||
|
||||
//! <b>Requires</b>: header is the header node of the tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns the number of nodes above the header.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static std::size_t size(const const_node_ptr & header)
|
||||
{ return tree_algorithms::size(header); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::next_node(const node_ptr&)
|
||||
static node_ptr next_node(const node_ptr & node);
|
||||
|
||||
//! <b>Requires</b>: p is a node from the tree except the header.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns the next node of the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static node_ptr next_node(const node_ptr & p)
|
||||
{ return tree_algorithms::next_node(p); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::prev_node(const node_ptr&)
|
||||
static node_ptr prev_node(const node_ptr & node);
|
||||
|
||||
//! <b>Requires</b>: p is a node from the tree except the leftmost node.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns the previous node of the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Average constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static node_ptr prev_node(const node_ptr & p)
|
||||
{ return tree_algorithms::prev_node(p); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::init(const node_ptr&)
|
||||
static void init(const node_ptr & node);
|
||||
|
||||
//! <b>Requires</b>: node must not be part of any tree.
|
||||
//!
|
||||
//! <b>Effects</b>: After the function unique(node) == true.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
|
||||
static void init(const node_ptr & node)
|
||||
{ tree_algorithms::init(node); }
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::init_header(const node_ptr&)
|
||||
static void init_header(const node_ptr & header);
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Requires</b>: node must not be part of any tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Initializes the header to represent an empty tree.
|
||||
//! unique(header) == true.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
|
||||
static void init_header(const node_ptr & header)
|
||||
{
|
||||
tree_algorithms::init_header(header);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: header must be the header of a tree, z a node
|
||||
//! of that tree and z != header.
|
||||
//!
|
||||
//! <b>Effects</b>: Erases node "z" from the tree with header "header".
|
||||
//!
|
||||
//! <b>Complexity</b>: Amortized constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: If "pcomp" throws, strong guarantee.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::erase(const node_ptr&,const node_ptr&)
|
||||
template<class NodePtrPriorityCompare>
|
||||
static node_ptr erase(const node_ptr & header, const node_ptr & z, NodePtrPriorityCompare pcomp)
|
||||
{
|
||||
rebalance_for_erasure(header, z, pcomp);
|
||||
tree_algorithms::erase(header, z);
|
||||
bstree_algorithms::erase(header, z);
|
||||
return z;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "cloner" must be a function
|
||||
//! object taking a node_ptr and returning a new cloned node of it. "disposer" must
|
||||
//! take a node_ptr and shouldn't throw.
|
||||
//!
|
||||
//! <b>Effects</b>: First empties target tree calling
|
||||
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
|
||||
//! except the header.
|
||||
//!
|
||||
//! Then, duplicates the entire tree pointed by "source_header" cloning each
|
||||
//! source node with <tt>node_ptr Cloner::operator()(const node_ptr &)</tt> to obtain
|
||||
//! the nodes of the target tree. If "cloner" throws, the cloned target nodes
|
||||
//! are disposed using <tt>void disposer(const node_ptr &)</tt>.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
|
||||
//! number of elements of tree target tree when calling this function.
|
||||
//!
|
||||
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::clone(const const_node_ptr&,const node_ptr&,Cloner,Disposer)
|
||||
template <class Cloner, class Disposer>
|
||||
static void clone
|
||||
(const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer)
|
||||
{
|
||||
tree_algorithms::clone(source_header, target_header, cloner, disposer);
|
||||
}
|
||||
(const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer);
|
||||
|
||||
//! <b>Requires</b>: "disposer" must be an object function
|
||||
//! taking a node_ptr parameter and shouldn't throw.
|
||||
//!
|
||||
//! <b>Effects</b>: Empties the target tree calling
|
||||
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
|
||||
//! except the header.
|
||||
//!
|
||||
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
|
||||
//! number of elements of tree target tree when calling this function.
|
||||
//!
|
||||
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::clear_and_dispose(const node_ptr&,Disposer)
|
||||
template<class Disposer>
|
||||
static void clear_and_dispose(const node_ptr & header, Disposer disposer)
|
||||
{ tree_algorithms::clear_and_dispose(header, disposer); }
|
||||
static void clear_and_dispose(const node_ptr & header, Disposer disposer);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an node_ptr to the first element that is
|
||||
//! not less than "key" according to "comp" or "header" if that element does
|
||||
//! not exist.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr lower_bound
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return tree_algorithms::lower_bound(header, key, comp); }
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an node_ptr to the first element that is greater
|
||||
//! than "key" according to "comp" or "header" if that element does not exist.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr upper_bound
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return tree_algorithms::upper_bound(header, key, comp); }
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an node_ptr to the element that is equivalent to
|
||||
//! "key" according to "comp" or "header" if that element does not exist.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr find
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return tree_algorithms::find(header, key, comp); }
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an a pair of node_ptr delimiting a range containing
|
||||
//! all elements that are equivalent to "key" according to "comp" or an
|
||||
//! empty range that indicates the position where those elements would be
|
||||
//! if they there are no equivalent elements.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, node_ptr> equal_range
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return tree_algorithms::equal_range(header, key, comp); }
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
|
||||
//! <b>Requires</b>: "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
|
||||
//! the tree. KeyNodePtrCompare can compare KeyType with tree's node_ptrs.
|
||||
//! 'lower_key' must not be greater than 'upper_key' according to 'comp'. If
|
||||
//! 'lower_key' == 'upper_key', ('left_closed' || 'right_closed') must be false.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns an a pair with the following criteria:
|
||||
//!
|
||||
//! first = lower_bound(lower_key) if left_closed, upper_bound(lower_key) otherwise
|
||||
//!
|
||||
//! second = upper_bound(upper_key) if right_closed, lower_bound(upper_key) otherwise
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
//!
|
||||
//! <b>Note</b>: This function can be more efficient than calling upper_bound
|
||||
//! and lower_bound for lower_key and upper_key.
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, node_ptr> bounded_range
|
||||
(const const_node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
|
||||
, bool left_closed, bool right_closed)
|
||||
{ return tree_algorithms::bounded_range(header, lower_key, upper_key, comp, left_closed, right_closed); }
|
||||
, bool left_closed, bool right_closed);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::size_t count(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp);
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! <b>Requires</b>: "h" must be the header node of a tree.
|
||||
//! NodePtrCompare is a function object that induces a strict weak
|
||||
@@ -543,7 +270,7 @@ class treap_algorithms
|
||||
(const node_ptr & h, const 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);
|
||||
bstree_algorithms::insert_equal_upper_bound_check(h, new_node, comp, commit_data);
|
||||
rebalance_check_and_commit(h, new_node, pcomp, commit_data);
|
||||
return new_node;
|
||||
}
|
||||
@@ -568,7 +295,7 @@ class treap_algorithms
|
||||
(const node_ptr & h, const 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);
|
||||
bstree_algorithms::insert_equal_lower_bound_check(h, new_node, comp, commit_data);
|
||||
rebalance_check_and_commit(h, new_node, pcomp, commit_data);
|
||||
return new_node;
|
||||
}
|
||||
@@ -596,7 +323,7 @@ class treap_algorithms
|
||||
(const node_ptr & h, const node_ptr & hint, const 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);
|
||||
bstree_algorithms::insert_equal_check(h, hint, new_node, comp, commit_data);
|
||||
rebalance_check_and_commit(h, new_node, pcomp, commit_data);
|
||||
return new_node;
|
||||
}
|
||||
@@ -624,7 +351,7 @@ class treap_algorithms
|
||||
(const node_ptr & header, const node_ptr & pos, const node_ptr & new_node, NodePtrPriorityCompare pcomp)
|
||||
{
|
||||
insert_commit_data commit_data;
|
||||
tree_algorithms::insert_before_check(header, pos, commit_data);
|
||||
bstree_algorithms::insert_before_check(header, pos, commit_data);
|
||||
rebalance_check_and_commit(header, new_node, pcomp, commit_data);
|
||||
return new_node;
|
||||
}
|
||||
@@ -650,7 +377,7 @@ class treap_algorithms
|
||||
static void push_back(const node_ptr & header, const node_ptr & new_node, NodePtrPriorityCompare pcomp)
|
||||
{
|
||||
insert_commit_data commit_data;
|
||||
tree_algorithms::push_back_check(header, commit_data);
|
||||
bstree_algorithms::push_back_check(header, commit_data);
|
||||
rebalance_check_and_commit(header, new_node, pcomp, commit_data);
|
||||
}
|
||||
|
||||
@@ -675,7 +402,7 @@ class treap_algorithms
|
||||
static void push_front(const node_ptr & header, const node_ptr & new_node, NodePtrPriorityCompare pcomp)
|
||||
{
|
||||
insert_commit_data commit_data;
|
||||
tree_algorithms::push_front_check(header, commit_data);
|
||||
bstree_algorithms::push_front_check(header, commit_data);
|
||||
rebalance_check_and_commit(header, new_node, pcomp, commit_data);
|
||||
}
|
||||
|
||||
@@ -720,7 +447,7 @@ class treap_algorithms
|
||||
,insert_commit_data &commit_data)
|
||||
{
|
||||
std::pair<node_ptr, bool> ret =
|
||||
tree_algorithms::insert_unique_check(header, key, comp, commit_data);
|
||||
bstree_algorithms::insert_unique_check(header, key, comp, commit_data);
|
||||
if(ret.second)
|
||||
rebalance_after_insertion_check(header, commit_data.node, key, pcomp, commit_data.rotations);
|
||||
return ret;
|
||||
@@ -771,7 +498,7 @@ class treap_algorithms
|
||||
,KeyNodePtrCompare comp, KeyNodePtrPrioCompare pcomp, insert_commit_data &commit_data)
|
||||
{
|
||||
std::pair<node_ptr, bool> ret =
|
||||
tree_algorithms::insert_unique_check(header, hint, key, comp, commit_data);
|
||||
bstree_algorithms::insert_unique_check(header, hint, key, comp, commit_data);
|
||||
if(ret.second)
|
||||
rebalance_after_insertion_check(header, commit_data.node, key, pcomp, commit_data.rotations);
|
||||
return ret;
|
||||
@@ -797,35 +524,19 @@ class treap_algorithms
|
||||
static void insert_unique_commit
|
||||
(const node_ptr & header, const node_ptr & new_node, const insert_commit_data &commit_data)
|
||||
{
|
||||
tree_algorithms::insert_unique_commit(header, new_node, commit_data);
|
||||
bstree_algorithms::insert_unique_commit(header, new_node, commit_data);
|
||||
rebalance_after_insertion_commit(header, new_node, commit_data.rotations);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "n" must be a node inserted in a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns a pointer to the header node of the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static node_ptr get_header(const node_ptr & n)
|
||||
{ return tree_algorithms::get_header(n); }
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::is_header
|
||||
static bool is_header(const const_node_ptr & p);
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
/// @cond
|
||||
private:
|
||||
|
||||
//! <b>Requires</b>: p is a node of a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns true if p is the header of the tree.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static bool is_header(const const_node_ptr & p)
|
||||
{
|
||||
return tree_algorithms::is_header(p);
|
||||
}
|
||||
|
||||
template<class NodePtrPriorityCompare>
|
||||
static void rebalance_for_erasure(const node_ptr & header, const node_ptr & z, NodePtrPriorityCompare pcomp)
|
||||
{
|
||||
@@ -836,10 +547,10 @@ class treap_algorithms
|
||||
node_ptr z_right = NodeTraits::get_right(z);
|
||||
while(z_left || z_right){
|
||||
if(!z_right || (z_left && pcomp(z_left, z_right))){
|
||||
tree_algorithms::rotate_right(z, header);
|
||||
bstree_algorithms::rotate_right(z, header);
|
||||
}
|
||||
else{
|
||||
tree_algorithms::rotate_left(z, header);
|
||||
bstree_algorithms::rotate_left(z, header);
|
||||
}
|
||||
++n;
|
||||
z_left = NodeTraits::get_left(z);
|
||||
@@ -854,7 +565,7 @@ class treap_algorithms
|
||||
{
|
||||
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);
|
||||
bstree_algorithms::insert_unique_commit(h, new_node, commit_data);
|
||||
rebalance_after_insertion_commit(h, new_node, commit_data.rotations);
|
||||
}
|
||||
|
||||
@@ -883,10 +594,10 @@ class treap_algorithms
|
||||
; p_parent = NodeTraits::get_parent(p)){
|
||||
//Check if left child
|
||||
if(p == NodeTraits::get_left(p_parent)){
|
||||
tree_algorithms::rotate_right(p_parent, header);
|
||||
bstree_algorithms::rotate_right(p_parent, header);
|
||||
}
|
||||
else{ //Right child
|
||||
tree_algorithms::rotate_left(p_parent, header);
|
||||
bstree_algorithms::rotate_left(p_parent, header);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -911,6 +622,16 @@ class treap_algorithms
|
||||
/// @endcond
|
||||
};
|
||||
|
||||
/// @cond
|
||||
|
||||
template<class NodeTraits>
|
||||
struct get_algo<TreapAlgorithms, NodeTraits>
|
||||
{
|
||||
typedef treap_algorithms<NodeTraits> type;
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
|
||||
} //namespace intrusive
|
||||
} //namespace boost
|
||||
|
||||
|
||||
+419
-2189
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Olaf Krzikalla 2004-2006.
|
||||
// (C) Copyright Ion Gaztanaga 2006-2012
|
||||
// (C) Copyright Ion Gaztanaga 2006-2013
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -120,8 +120,12 @@ struct unordered_algorithms
|
||||
: public circular_slist_algorithms<NodeTraits>
|
||||
{
|
||||
typedef circular_slist_algorithms<NodeTraits> base_type;
|
||||
typedef unordered_group_adapter<NodeTraits> group_traits;
|
||||
typedef unordered_group_adapter<NodeTraits> group_traits;
|
||||
typedef circular_slist_algorithms<group_traits> group_algorithms;
|
||||
typedef NodeTraits node_traits;
|
||||
typedef typename NodeTraits::node node;
|
||||
typedef typename NodeTraits::node_ptr node_ptr;
|
||||
typedef typename NodeTraits::const_node_ptr const_node_ptr;
|
||||
|
||||
static void init(typename base_type::node_ptr n)
|
||||
{
|
||||
@@ -163,7 +167,7 @@ struct get_uset_node_algo
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = none, class O2 = none, class O3 = none, class O4 = none>
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
|
||||
#endif
|
||||
struct make_unordered_set_base_hook
|
||||
{
|
||||
@@ -177,14 +181,14 @@ struct make_unordered_set_base_hook
|
||||
#endif
|
||||
>::type packed_options;
|
||||
|
||||
typedef detail::generic_hook
|
||||
typedef generic_hook
|
||||
< get_uset_node_algo<typename packed_options::void_pointer
|
||||
, packed_options::store_hash
|
||||
, packed_options::optimize_multikey
|
||||
>
|
||||
, typename packed_options::tag
|
||||
, packed_options::link_mode
|
||||
, detail::UsetBaseHook
|
||||
, HashBaseHookId
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
@@ -302,7 +306,7 @@ class unordered_set_base_hook
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
template<class O1 = none, class O2 = none, class O3 = none, class O4 = none>
|
||||
template<class O1 = void, class O2 = void, class O3 = void, class O4 = void>
|
||||
#endif
|
||||
struct make_unordered_set_member_hook
|
||||
{
|
||||
@@ -316,14 +320,14 @@ struct make_unordered_set_member_hook
|
||||
#endif
|
||||
>::type packed_options;
|
||||
|
||||
typedef detail::generic_hook
|
||||
typedef generic_hook
|
||||
< get_uset_node_algo< typename packed_options::void_pointer
|
||||
, packed_options::store_hash
|
||||
, packed_options::optimize_multikey
|
||||
>
|
||||
, member_tag
|
||||
, packed_options::link_mode
|
||||
, detail::NoBaseHook
|
||||
, NoBaseHookId
|
||||
> implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
|
||||
Reference in New Issue
Block a user