forked from boostorg/intrusive
Reverted git mess.
This commit is contained in:
1 parent
27e5ad9183
commit
68fa82e5e8
59 files changed
+1937
-3049
No files matched your search
@@ -75,7 +75,7 @@ struct make_any_base_hook
|
||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link, \c safe_link).
|
||||
//!
|
||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||
//! and the the container configured to use this hook.
|
||||
//! and the container configured to use this hook.
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
@@ -175,7 +175,7 @@ struct make_any_member_hook
|
||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link or \c safe_link).
|
||||
//!
|
||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||
//! and the the container configured to use this hook.
|
||||
//! and the container configured to use this hook.
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
|
||||
@@ -249,13 +249,19 @@ class avl_set_impl
|
||||
template<class Disposer>
|
||||
void clear_and_dispose(Disposer disposer);
|
||||
|
||||
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::avltree::count(const_reference)const
|
||||
size_type count(const_reference value) const;
|
||||
size_type count(const_reference value) const
|
||||
{ return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::avltree::count(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
size_type count(const KeyType& key, KeyValueCompare comp) const
|
||||
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::avltree::lower_bound(const_reference)
|
||||
iterator lower_bound(const_reference value);
|
||||
|
||||
@@ -298,21 +304,29 @@ class avl_set_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::avltree::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> equal_range(const_reference value);
|
||||
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyValueCompare)
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> equal_range(const_reference value)
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
|
||||
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::avltree::equal_range(const_reference)const
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const_reference value) const;
|
||||
equal_range(const_reference value) const
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::avltree::equal_range(const KeyType&,KeyValueCompare)const
|
||||
//! @copydoc ::boost::intrusive::rbtree::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;
|
||||
equal_range(const KeyType& key, KeyValueCompare comp) const
|
||||
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::avltree::bounded_range(const_reference,const_reference,bool,bool)
|
||||
std::pair<iterator,iterator> bounded_range
|
||||
@@ -692,7 +706,7 @@ class avl_multiset_impl
|
||||
//! @copydoc ::boost::intrusive::avltree::count(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
|
||||
//! @copydoc ::boost::intrusive::avltree::lower_bound(const_reference)
|
||||
iterator lower_bound(const_reference value);
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ struct make_avl_set_base_hook
|
||||
//! unique tag.
|
||||
//!
|
||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||
//! and the the container configured to use this hook.
|
||||
//! and the container configured to use this hook.
|
||||
//!
|
||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||
//! \c auto_unlink or \c safe_link).
|
||||
@@ -200,7 +200,7 @@ struct make_avl_set_member_hook
|
||||
//! \c link_mode<> and \c optimize_size<>.
|
||||
//!
|
||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||
//! and the the container configured to use this hook.
|
||||
//! and the container configured to use this hook.
|
||||
//!
|
||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||
//! \c auto_unlink or \c safe_link).
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#define BOOST_INTRUSIVE_AVLTREE_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
@@ -21,7 +22,6 @@
|
||||
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/avl_set_hook.hpp>
|
||||
#include <boost/intrusive/detail/avltree_node.hpp>
|
||||
#include <boost/intrusive/bstree.hpp>
|
||||
@@ -296,7 +296,7 @@ class avltree_impl
|
||||
//! @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);
|
||||
|
||||
@@ -487,14 +487,13 @@ class avltree
|
||||
public:
|
||||
typedef typename Base::value_compare value_compare;
|
||||
typedef typename Base::value_traits value_traits;
|
||||
typedef typename Base::real_value_traits real_value_traits;
|
||||
typedef typename Base::iterator iterator;
|
||||
typedef typename Base::const_iterator const_iterator;
|
||||
typedef typename Base::reverse_iterator reverse_iterator;
|
||||
typedef typename Base::const_reverse_iterator const_reverse_iterator;
|
||||
|
||||
//Assert if passed value traits are compatible with the type
|
||||
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
|
||||
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
|
||||
|
||||
explicit avltree( const value_compare &cmp = value_compare()
|
||||
, const value_traits &v_traits = value_traits())
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
#define BOOST_INTRUSIVE_AVLTREE_ALGORITHMS_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
@@ -49,15 +49,6 @@ struct avltree_node_cloner
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
@@ -225,7 +216,10 @@ class avltree_algorithms
|
||||
static node_ptr erase(const node_ptr & header, const node_ptr & z)
|
||||
{
|
||||
typename bstree_algo::data_for_rebalance info;
|
||||
bstree_algo::erase(header, z, avltree_erase_fixup<NodeTraits>(), info);
|
||||
bstree_algo::erase(header, z, info);
|
||||
if(info.y != z){
|
||||
NodeTraits::set_balance(info.y, NodeTraits::get_balance(z));
|
||||
}
|
||||
//Rebalance avltree
|
||||
rebalance_after_erasure(header, info.x, info.x_parent);
|
||||
return z;
|
||||
@@ -274,6 +268,7 @@ class avltree_algorithms
|
||||
//! @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)
|
||||
@@ -357,40 +352,92 @@ class avltree_algorithms
|
||||
|
||||
|
||||
/// @cond
|
||||
static bool verify(const node_ptr &header)
|
||||
{
|
||||
std::size_t height;
|
||||
std::size_t count;
|
||||
return verify_recursion(NodeTraits::get_parent(header), count, height);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static void rebalance_after_erasure(const node_ptr & header, const node_ptr & xnode, const node_ptr & xnode_parent)
|
||||
static bool verify_recursion(node_ptr n, std::size_t &count, std::size_t &height)
|
||||
{
|
||||
if (!n){
|
||||
count = 0;
|
||||
height = 0;
|
||||
return true;
|
||||
}
|
||||
std::size_t leftcount, rightcount;
|
||||
std::size_t leftheight, rightheight;
|
||||
if(!verify_recursion(NodeTraits::get_left (n), leftcount, leftheight) ||
|
||||
!verify_recursion(NodeTraits::get_right(n), rightcount, rightheight) ){
|
||||
return false;
|
||||
}
|
||||
count = 1u + leftcount + rightcount;
|
||||
height = 1u + (leftheight > rightheight ? leftheight : rightheight);
|
||||
|
||||
//If equal height, balance must be zero
|
||||
if(rightheight == leftheight){
|
||||
if(NodeTraits::get_balance(n) != NodeTraits::zero()){
|
||||
BOOST_ASSERT(0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//If right is taller than left, then the difference must be at least 1 and the balance positive
|
||||
else if(rightheight > leftheight){
|
||||
if(rightheight - leftheight > 1 ){
|
||||
BOOST_ASSERT(0);
|
||||
return false;
|
||||
}
|
||||
else if(NodeTraits::get_balance(n) != NodeTraits::positive()){
|
||||
BOOST_ASSERT(0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//If left is taller than right, then the difference must be at least 1 and the balance negative
|
||||
else{
|
||||
if(leftheight - rightheight > 1 ){
|
||||
BOOST_ASSERT(0);
|
||||
return false;
|
||||
}
|
||||
else if(NodeTraits::get_balance(n) != NodeTraits::negative()){
|
||||
BOOST_ASSERT(0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void rebalance_after_erasure(const node_ptr & header, node_ptr x, node_ptr x_parent)
|
||||
{
|
||||
node_ptr x(xnode), x_parent(xnode_parent);
|
||||
for (node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)) {
|
||||
const balance x_parent_balance = NodeTraits::get_balance(x_parent);
|
||||
//Don't cache x_is_leftchild or similar because x can be null and
|
||||
//equal to both x_parent_left and x_parent_right
|
||||
const node_ptr x_parent_left (NodeTraits::get_left(x_parent));
|
||||
const node_ptr x_parent_right(NodeTraits::get_right(x_parent));
|
||||
|
||||
if(x_parent_balance == NodeTraits::zero()){
|
||||
NodeTraits::set_balance(x_parent,
|
||||
(x == NodeTraits::get_right(x_parent) ? NodeTraits::negative() : NodeTraits::positive()));
|
||||
NodeTraits::set_balance( x_parent, x == x_parent_right ? NodeTraits::negative() : NodeTraits::positive() );
|
||||
break; // the height didn't change, let's stop here
|
||||
}
|
||||
else if(x_parent_balance == NodeTraits::negative()){
|
||||
if (x == NodeTraits::get_left(x_parent)) {
|
||||
if (x == x_parent_left) { ////x is left child or x and sibling are null
|
||||
NodeTraits::set_balance(x_parent, NodeTraits::zero()); // balanced
|
||||
x = x_parent;
|
||||
x_parent = NodeTraits::get_parent(x_parent);
|
||||
}
|
||||
else {
|
||||
// x is right child
|
||||
// a is left child
|
||||
node_ptr a = NodeTraits::get_left(x_parent);
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(a);
|
||||
if (NodeTraits::get_balance(a) == NodeTraits::positive()) {
|
||||
// a MUST have a right child
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_right(a));
|
||||
rotate_left_right(x_parent, header);
|
||||
x = NodeTraits::get_parent(x_parent);
|
||||
x_parent = NodeTraits::get_parent(x);
|
||||
// x is right child (x_parent_left is the left child)
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(x_parent_left);
|
||||
if (NodeTraits::get_balance(x_parent_left) == NodeTraits::positive()) {
|
||||
// x_parent_left MUST have a right child
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_right(x_parent_left));
|
||||
x = avl_rotate_left_right(x_parent, x_parent_left, header);
|
||||
}
|
||||
else {
|
||||
rotate_right(x_parent, header);
|
||||
x = NodeTraits::get_parent(x_parent);
|
||||
x_parent = NodeTraits::get_parent(x);
|
||||
avl_rotate_right(x_parent, x_parent_left, header);
|
||||
x = x_parent_left;
|
||||
}
|
||||
|
||||
// if changed from negative to NodeTraits::positive(), no need to check above
|
||||
@@ -400,28 +447,22 @@ class avltree_algorithms
|
||||
}
|
||||
}
|
||||
else if(x_parent_balance == NodeTraits::positive()){
|
||||
if (x == NodeTraits::get_right(x_parent)) {
|
||||
if (x == x_parent_right) { //x is right child or x and sibling are null
|
||||
NodeTraits::set_balance(x_parent, NodeTraits::zero()); // balanced
|
||||
x = x_parent;
|
||||
x_parent = NodeTraits::get_parent(x_parent);
|
||||
}
|
||||
else {
|
||||
// x is left child
|
||||
// a is right child
|
||||
node_ptr a = NodeTraits::get_right(x_parent);
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(a);
|
||||
if (NodeTraits::get_balance(a) == NodeTraits::negative()) {
|
||||
// a MUST have then a left child
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_left(a));
|
||||
rotate_right_left(x_parent, header);
|
||||
|
||||
x = NodeTraits::get_parent(x_parent);
|
||||
x_parent = NodeTraits::get_parent(x);
|
||||
// x is left child (x_parent_right is the right child)
|
||||
const node_ptr x_parent_right(NodeTraits::get_right(x_parent));
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(x_parent_right);
|
||||
if (NodeTraits::get_balance(x_parent_right) == NodeTraits::negative()) {
|
||||
// x_parent_right MUST have then a left child
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(NodeTraits::get_left(x_parent_right));
|
||||
x = avl_rotate_right_left(x_parent, x_parent_right, header);
|
||||
}
|
||||
else {
|
||||
rotate_left(x_parent, header);
|
||||
x = NodeTraits::get_parent(x_parent);
|
||||
x_parent = NodeTraits::get_parent(x);
|
||||
avl_rotate_left(x_parent, x_parent_right, header);
|
||||
x = x_parent_right;
|
||||
}
|
||||
// if changed from NodeTraits::positive() to negative, no need to check above
|
||||
if (NodeTraits::get_balance(x) == NodeTraits::negative()){
|
||||
@@ -432,47 +473,47 @@ class avltree_algorithms
|
||||
else{
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached
|
||||
}
|
||||
x_parent = NodeTraits::get_parent(x);
|
||||
}
|
||||
}
|
||||
|
||||
static void rebalance_after_insertion(const node_ptr & header, const node_ptr & xnode)
|
||||
static void rebalance_after_insertion(const node_ptr & header, node_ptr x)
|
||||
{
|
||||
node_ptr x(xnode);
|
||||
NodeTraits::set_balance(x, NodeTraits::zero());
|
||||
// Rebalance.
|
||||
for(node_ptr root = NodeTraits::get_parent(header); x != root; root = NodeTraits::get_parent(header)){
|
||||
const balance x_parent_balance = NodeTraits::get_balance(NodeTraits::get_parent(x));
|
||||
|
||||
node_ptr const x_parent(NodeTraits::get_parent(x));
|
||||
node_ptr const x_parent_left(NodeTraits::get_left(x_parent));
|
||||
const balance x_parent_balance = NodeTraits::get_balance(x_parent);
|
||||
const bool x_is_leftchild(x == x_parent_left);
|
||||
if(x_parent_balance == NodeTraits::zero()){
|
||||
// if x is left, parent will have parent->bal_factor = negative
|
||||
// else, parent->bal_factor = NodeTraits::positive()
|
||||
NodeTraits::set_balance( NodeTraits::get_parent(x)
|
||||
, x == NodeTraits::get_left(NodeTraits::get_parent(x))
|
||||
? NodeTraits::negative() : NodeTraits::positive() );
|
||||
x = NodeTraits::get_parent(x);
|
||||
NodeTraits::set_balance( x_parent, x_is_leftchild ? NodeTraits::negative() : NodeTraits::positive() );
|
||||
x = x_parent;
|
||||
}
|
||||
else if(x_parent_balance == NodeTraits::positive()){
|
||||
// if x is a left child, parent->bal_factor = zero
|
||||
if (x == NodeTraits::get_left(NodeTraits::get_parent(x)))
|
||||
NodeTraits::set_balance(NodeTraits::get_parent(x), NodeTraits::zero());
|
||||
if (x_is_leftchild)
|
||||
NodeTraits::set_balance(x_parent, NodeTraits::zero());
|
||||
else{ // x is a right child, needs rebalancing
|
||||
if (NodeTraits::get_balance(x) == NodeTraits::negative())
|
||||
rotate_right_left(NodeTraits::get_parent(x), header);
|
||||
avl_rotate_right_left(x_parent, x, header);
|
||||
else
|
||||
rotate_left(NodeTraits::get_parent(x), header);
|
||||
avl_rotate_left(x_parent, x, header);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if(x_parent_balance == NodeTraits::negative()){
|
||||
// if x is a left child, needs rebalancing
|
||||
if (x == NodeTraits::get_left(NodeTraits::get_parent(x))) {
|
||||
if (x_is_leftchild) {
|
||||
if (NodeTraits::get_balance(x) == NodeTraits::positive())
|
||||
rotate_left_right(NodeTraits::get_parent(x), header);
|
||||
avl_rotate_left_right(x_parent, x, header);
|
||||
else
|
||||
rotate_right(NodeTraits::get_parent(x), header);
|
||||
avl_rotate_right(x_parent, x, header);
|
||||
}
|
||||
else
|
||||
NodeTraits::set_balance(NodeTraits::get_parent(x), NodeTraits::zero());
|
||||
NodeTraits::set_balance(x_parent, NodeTraits::zero());
|
||||
break;
|
||||
}
|
||||
else{
|
||||
@@ -486,26 +527,28 @@ class avltree_algorithms
|
||||
// balancing...
|
||||
const balance c_balance = NodeTraits::get_balance(c);
|
||||
const balance zero_balance = NodeTraits::zero();
|
||||
const balance posi_balance = NodeTraits::positive();
|
||||
const balance nega_balance = NodeTraits::negative();
|
||||
NodeTraits::set_balance(c, zero_balance);
|
||||
if(c_balance == NodeTraits::negative()){
|
||||
NodeTraits::set_balance(a, NodeTraits::positive());
|
||||
if(c_balance == nega_balance){
|
||||
NodeTraits::set_balance(a, posi_balance);
|
||||
NodeTraits::set_balance(b, zero_balance);
|
||||
}
|
||||
else if(c_balance == zero_balance){
|
||||
NodeTraits::set_balance(a, zero_balance);
|
||||
NodeTraits::set_balance(b, zero_balance);
|
||||
}
|
||||
else if(c_balance == NodeTraits::positive()){
|
||||
else if(c_balance == posi_balance){
|
||||
NodeTraits::set_balance(a, zero_balance);
|
||||
NodeTraits::set_balance(b, NodeTraits::negative());
|
||||
NodeTraits::set_balance(b, nega_balance);
|
||||
}
|
||||
else{
|
||||
BOOST_INTRUSIVE_INVARIANT_ASSERT(false); // never reached
|
||||
}
|
||||
}
|
||||
|
||||
static void rotate_left_right(const node_ptr a, const node_ptr & hdr)
|
||||
{
|
||||
static node_ptr avl_rotate_left_right(const node_ptr a, const node_ptr a_oldleft, const node_ptr & hdr)
|
||||
{ // [note: 'a_oldleft' is 'b']
|
||||
// | | //
|
||||
// a(-2) c //
|
||||
// / \ / \ //
|
||||
@@ -513,16 +556,19 @@ class avltree_algorithms
|
||||
// (pos)b [g] b a //
|
||||
// / \ / \ / \ //
|
||||
// [d] c [d] e f [g] //
|
||||
// / \ //
|
||||
// e f //
|
||||
node_ptr b = NodeTraits::get_left(a), c = NodeTraits::get_right(b);
|
||||
bstree_algo::rotate_left(b, hdr);
|
||||
bstree_algo::rotate_right(a, hdr);
|
||||
left_right_balancing(a, b, c);
|
||||
// / \ //
|
||||
// e f //
|
||||
const node_ptr c = NodeTraits::get_right(a_oldleft);
|
||||
bstree_algo::rotate_left_no_parent_fix(a_oldleft, c);
|
||||
//No need to link c with a [NodeTraits::set_parent(c, a) + NodeTraits::set_left(a, c)]
|
||||
//as c is not root and another rotation is coming
|
||||
bstree_algo::rotate_right(a, c, NodeTraits::get_parent(a), hdr);
|
||||
left_right_balancing(a, a_oldleft, c);
|
||||
return c;
|
||||
}
|
||||
|
||||
static void rotate_right_left(const node_ptr a, const node_ptr & hdr)
|
||||
{
|
||||
static node_ptr avl_rotate_right_left(const node_ptr a, const node_ptr a_oldright, const node_ptr & hdr)
|
||||
{ // [note: 'a_oldright' is 'b']
|
||||
// | | //
|
||||
// a(pos) c //
|
||||
// / \ / \ //
|
||||
@@ -532,41 +578,42 @@ class avltree_algorithms
|
||||
// c [g] [d] e f [g] //
|
||||
// / \ //
|
||||
// e f //
|
||||
node_ptr b = NodeTraits::get_right(a), c = NodeTraits::get_left(b);
|
||||
bstree_algo::rotate_right(b, hdr);
|
||||
bstree_algo::rotate_left(a, hdr);
|
||||
left_right_balancing(b, a, c);
|
||||
const node_ptr c (NodeTraits::get_left(a_oldright));
|
||||
bstree_algo::rotate_right_no_parent_fix(a_oldright, c);
|
||||
//No need to link c with a [NodeTraits::set_parent(c, a) + NodeTraits::set_right(a, c)]
|
||||
//as c is not root and another rotation is coming.
|
||||
bstree_algo::rotate_left(a, c, NodeTraits::get_parent(a), hdr);
|
||||
left_right_balancing(a_oldright, a, c);
|
||||
return c;
|
||||
}
|
||||
|
||||
static void rotate_left(const node_ptr x, const node_ptr & hdr)
|
||||
static void avl_rotate_left(const node_ptr &x, const node_ptr &x_oldright, const node_ptr & hdr)
|
||||
{
|
||||
const node_ptr y = NodeTraits::get_right(x);
|
||||
bstree_algo::rotate_left(x, hdr);
|
||||
bstree_algo::rotate_left(x, x_oldright, NodeTraits::get_parent(x), hdr);
|
||||
|
||||
// reset the balancing factor
|
||||
if (NodeTraits::get_balance(y) == NodeTraits::positive()) {
|
||||
if (NodeTraits::get_balance(x_oldright) == NodeTraits::positive()) {
|
||||
NodeTraits::set_balance(x, NodeTraits::zero());
|
||||
NodeTraits::set_balance(y, NodeTraits::zero());
|
||||
NodeTraits::set_balance(x_oldright, NodeTraits::zero());
|
||||
}
|
||||
else { // this doesn't happen during insertions
|
||||
NodeTraits::set_balance(x, NodeTraits::positive());
|
||||
NodeTraits::set_balance(y, NodeTraits::negative());
|
||||
NodeTraits::set_balance(x_oldright, NodeTraits::negative());
|
||||
}
|
||||
}
|
||||
|
||||
static void rotate_right(const node_ptr x, const node_ptr & hdr)
|
||||
static void avl_rotate_right(const node_ptr &x, const node_ptr &x_oldleft, const node_ptr & hdr)
|
||||
{
|
||||
const node_ptr y = NodeTraits::get_left(x);
|
||||
bstree_algo::rotate_right(x, hdr);
|
||||
bstree_algo::rotate_right(x, x_oldleft, NodeTraits::get_parent(x), hdr);
|
||||
|
||||
// reset the balancing factor
|
||||
if (NodeTraits::get_balance(y) == NodeTraits::negative()) {
|
||||
if (NodeTraits::get_balance(x_oldleft) == NodeTraits::negative()) {
|
||||
NodeTraits::set_balance(x, NodeTraits::zero());
|
||||
NodeTraits::set_balance(y, NodeTraits::zero());
|
||||
NodeTraits::set_balance(x_oldleft, NodeTraits::zero());
|
||||
}
|
||||
else { // this doesn't happen during insertions
|
||||
NodeTraits::set_balance(x, NodeTraits::negative());
|
||||
NodeTraits::set_balance(y, NodeTraits::positive());
|
||||
NodeTraits::set_balance(x_oldleft, NodeTraits::positive());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -247,13 +247,19 @@ class bs_set_impl
|
||||
template<class Disposer>
|
||||
void clear_and_dispose(Disposer disposer);
|
||||
|
||||
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::count(const_reference)const
|
||||
size_type count(const_reference value) const;
|
||||
size_type count(const_reference value) const
|
||||
{ return static_cast<size_type>(this->tree_type::find(value) == this->tree_type::cend()); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
size_type count(const KeyType& key, KeyValueCompare comp) const
|
||||
{ return static_cast<size_type>(this->tree_type::find(key, comp) == this->tree_type::cend()); }
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
|
||||
iterator lower_bound(const_reference value);
|
||||
|
||||
@@ -296,21 +302,29 @@ class bs_set_impl
|
||||
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);
|
||||
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> equal_range(const_reference value)
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
|
||||
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const_reference value) const;
|
||||
equal_range(const_reference value) const
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)const
|
||||
//! @copydoc ::boost::intrusive::rbtree::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;
|
||||
equal_range(const KeyType& key, KeyValueCompare comp) const
|
||||
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::bounded_range(const_reference,const_reference,bool,bool)
|
||||
std::pair<iterator,iterator> bounded_range
|
||||
|
||||
@@ -73,7 +73,7 @@ struct make_bs_set_base_hook
|
||||
//! unique tag.
|
||||
//!
|
||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||
//! and the the container configured to use this hook.
|
||||
//! and the container configured to use this hook.
|
||||
//!
|
||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||
//! \c auto_unlink or \c safe_link).
|
||||
@@ -196,7 +196,7 @@ struct make_bs_set_member_hook
|
||||
//! The hook admits the following options: \c void_pointer<>, \c link_mode<>.
|
||||
//!
|
||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||
//! and the the container configured to use this hook.
|
||||
//! and the container configured to use this hook.
|
||||
//!
|
||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||
//! \c auto_unlink or \c safe_link).
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
#define BOOST_INTRUSIVE_BSTREE_ALGORITHMS_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <cstddef>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
@@ -173,7 +173,20 @@ class bstree_algorithms
|
||||
static node_ptr end_node(const const_node_ptr & header)
|
||||
{ return detail::uncast(header); }
|
||||
|
||||
//! <b>Requires</b>: 'node' is a node of the tree or an node initialized
|
||||
//! <b>Requires</b>: 'header' is the header node of a tree.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns the root of the tree if any, header otherwise
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant time.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static node_ptr root_node(const const_node_ptr & header)
|
||||
{
|
||||
node_ptr p = node_traits::get_parent(header);
|
||||
return p ? p : detail::uncast(header);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: 'node' is a node of the tree or a node initialized
|
||||
//! by init(...) or init_node.
|
||||
//!
|
||||
//! <b>Effects</b>: Returns true if the node is initialized by init() or init_node().
|
||||
@@ -487,18 +500,18 @@ class bstree_algorithms
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static node_ptr next_node(const node_ptr & node)
|
||||
{
|
||||
node_ptr p_right(NodeTraits::get_right(node));
|
||||
if(p_right){
|
||||
return minimum(p_right);
|
||||
node_ptr const n_right(NodeTraits::get_right(node));
|
||||
if(n_right){
|
||||
return minimum(n_right);
|
||||
}
|
||||
else {
|
||||
node_ptr p(node);
|
||||
node_ptr x = NodeTraits::get_parent(p);
|
||||
while(p == NodeTraits::get_right(x)){
|
||||
p = x;
|
||||
x = NodeTraits::get_parent(x);
|
||||
node_ptr n(node);
|
||||
node_ptr p(NodeTraits::get_parent(n));
|
||||
while(n == NodeTraits::get_right(p)){
|
||||
n = p;
|
||||
p = NodeTraits::get_parent(p);
|
||||
}
|
||||
return NodeTraits::get_right(p) != x ? x : detail::uncast(p);
|
||||
return NodeTraits::get_right(n) != p ? p : n;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,7 +549,7 @@ class bstree_algorithms
|
||||
//! <b>Complexity</b>: Logarithmic to the size of the subtree.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
static node_ptr minimum (node_ptr node)
|
||||
static node_ptr minimum(node_ptr node)
|
||||
{
|
||||
for(node_ptr p_left = NodeTraits::get_left(node)
|
||||
;p_left
|
||||
@@ -766,7 +779,7 @@ class bstree_algorithms
|
||||
//! 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
|
||||
//! <b>Effects</b>: Returns a node_ptr to the first element that is equivalent to
|
||||
//! "key" according to "comp" or "header" if that element does not exist.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
@@ -825,7 +838,6 @@ class bstree_algorithms
|
||||
//If the upper_key is less than x, the target
|
||||
//range is on the left part
|
||||
else if(comp(upper_key, x)){
|
||||
//y > upper_key
|
||||
y = x;
|
||||
x = NodeTraits::get_left(x);
|
||||
}
|
||||
@@ -864,7 +876,7 @@ class bstree_algorithms
|
||||
//! 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 the number of elements with a key equivalent to "key"pair of node_ptr delimiting a range containing
|
||||
//! <b>Effects</b>: Returns the number of elements with a key equivalent to "key"
|
||||
//! according to "comp".
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
@@ -908,7 +920,32 @@ class bstree_algorithms
|
||||
//! 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
|
||||
//! <b>Effects</b>: Returns an a pair of node_ptr delimiting a range containing
|
||||
//! the first element that is equivalent to "key" according to "comp" or an
|
||||
//! empty range that indicates the position where that element would be
|
||||
//! if there are no equivalent elements.
|
||||
//!
|
||||
//! <b>Complexity</b>: Logarithmic.
|
||||
//!
|
||||
//! <b>Throws</b>: If "comp" throws.
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, node_ptr> lower_bound_range
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{
|
||||
node_ptr const lb(lower_bound(header, key, comp));
|
||||
std::pair<node_ptr, node_ptr> ret_ii(lb, lb);
|
||||
if(lb != header && !comp(key, lb)){
|
||||
ret_ii.second = next_node(ret_ii.second);
|
||||
}
|
||||
return ret_ii;
|
||||
}
|
||||
|
||||
//! <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 a node_ptr to the first element that is
|
||||
//! not less than "key" according to "comp" or "header" if that element does
|
||||
//! not exist.
|
||||
//!
|
||||
@@ -927,7 +964,7 @@ class bstree_algorithms
|
||||
//! 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
|
||||
//! <b>Effects</b>: Returns a 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.
|
||||
@@ -1025,16 +1062,12 @@ class bstree_algorithms
|
||||
//Since we've found the upper bound there is no other value with the same key if:
|
||||
// - There is no previous node
|
||||
// - The previous node is less than the key
|
||||
if(!prev || comp(prev, key)){
|
||||
const bool not_present = !prev || comp(prev, key);
|
||||
if(not_present){
|
||||
commit_data.link_left = left_child;
|
||||
commit_data.node = y;
|
||||
return std::pair<node_ptr, bool>(node_ptr(), true);
|
||||
}
|
||||
//If the previous value was not less than key, it means that it's equal
|
||||
//(because we've checked the upper bound)
|
||||
else{
|
||||
return std::pair<node_ptr, bool>(prev, false);
|
||||
}
|
||||
return std::pair<node_ptr, bool>(prev, not_present);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: "header" must be the header node of a tree.
|
||||
@@ -1325,7 +1358,7 @@ class bstree_algorithms
|
||||
static void erase(const node_ptr & header, const node_ptr & z)
|
||||
{
|
||||
data_for_rebalance ignored;
|
||||
erase_impl(header, z, ignored);
|
||||
erase(header, z, ignored);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: node is a tree node but not the header.
|
||||
@@ -1410,6 +1443,88 @@ class bstree_algorithms
|
||||
}
|
||||
|
||||
protected:
|
||||
static void erase(const node_ptr & header, const node_ptr & z, data_for_rebalance &info)
|
||||
{
|
||||
node_ptr y(z);
|
||||
node_ptr x;
|
||||
const node_ptr z_left(NodeTraits::get_left(z));
|
||||
const node_ptr z_right(NodeTraits::get_right(z));
|
||||
|
||||
if(!z_left){
|
||||
x = z_right; // x might be null.
|
||||
}
|
||||
else if(!z_right){ // z has exactly one non-null child. y == z.
|
||||
x = z_left; // x is not null.
|
||||
BOOST_ASSERT(x);
|
||||
}
|
||||
else{ //make y != z
|
||||
// y = find z's successor
|
||||
y = bstree_algorithms::minimum(z_right);
|
||||
x = NodeTraits::get_right(y); // x might be null.
|
||||
}
|
||||
|
||||
node_ptr x_parent;
|
||||
const node_ptr z_parent(NodeTraits::get_parent(z));
|
||||
const bool z_is_leftchild(NodeTraits::get_left(z_parent) == z);
|
||||
|
||||
if(y != z){ //has two children and y is the minimum of z
|
||||
//y is z's successor and it has a null left child.
|
||||
//x is the right child of y (it can be null)
|
||||
//Relink y in place of z and link x with y's old parent
|
||||
NodeTraits::set_parent(z_left, y);
|
||||
NodeTraits::set_left(y, z_left);
|
||||
if(y != z_right){
|
||||
//Link y with the right tree of z
|
||||
NodeTraits::set_right(y, z_right);
|
||||
NodeTraits::set_parent(z_right, y);
|
||||
//Link x with y's old parent (y must be a left child)
|
||||
x_parent = NodeTraits::get_parent(y);
|
||||
BOOST_ASSERT(NodeTraits::get_left(x_parent) == y);
|
||||
if(x)
|
||||
NodeTraits::set_parent(x, x_parent);
|
||||
//Since y was the successor and not the right child of z, it must be a left child
|
||||
NodeTraits::set_left(x_parent, x);
|
||||
}
|
||||
else{ //y was the right child of y so no need to fix x's position
|
||||
x_parent = y;
|
||||
}
|
||||
NodeTraits::set_parent(y, z_parent);
|
||||
bstree_algorithms::set_child(header, y, z_parent, z_is_leftchild);
|
||||
}
|
||||
else { // z has zero or one child, x is one child (it can be null)
|
||||
//Just link x to z's parent
|
||||
x_parent = z_parent;
|
||||
if(x)
|
||||
NodeTraits::set_parent(x, z_parent);
|
||||
bstree_algorithms::set_child(header, x, z_parent, z_is_leftchild);
|
||||
|
||||
//Now update leftmost/rightmost in case z was one of them
|
||||
if(NodeTraits::get_left(header) == z){
|
||||
//z_left must be null because z is the leftmost
|
||||
BOOST_ASSERT(!z_left);
|
||||
NodeTraits::set_left(header, !z_right ?
|
||||
z_parent : // makes leftmost == header if z == root
|
||||
bstree_algorithms::minimum(z_right));
|
||||
}
|
||||
if(NodeTraits::get_right(header) == z){
|
||||
//z_right must be null because z is the rightmost
|
||||
BOOST_ASSERT(!z_right);
|
||||
NodeTraits::set_right(header, !z_left ?
|
||||
z_parent : // makes rightmost == header if z == root
|
||||
bstree_algorithms::maximum(z_left));
|
||||
}
|
||||
}
|
||||
|
||||
//If z had 0/1 child, y == z and one of its children (and maybe null)
|
||||
//If z had 2 children, y is the successor of z and x is the right child of y
|
||||
info.x = x;
|
||||
info.y = y;
|
||||
//If z had 0/1 child, x_parent is the new parent of the old right child of y (z's successor)
|
||||
//If z had 2 children, x_parent is the new parent of y (z_parent)
|
||||
BOOST_ASSERT(!x || NodeTraits::get_parent(x) == x_parent);
|
||||
info.x_parent = x_parent;
|
||||
}
|
||||
|
||||
//! <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.
|
||||
@@ -1473,83 +1588,6 @@ class bstree_algorithms
|
||||
static bool is_right_child(const node_ptr & p)
|
||||
{ return NodeTraits::get_right(NodeTraits::get_parent(p)) == p; }
|
||||
|
||||
template<class F>
|
||||
static void erase(const node_ptr & header, const node_ptr & z, F z_and_successor_fixup, data_for_rebalance &info)
|
||||
{
|
||||
erase_impl(header, z, info);
|
||||
if(info.y != z){
|
||||
z_and_successor_fixup(z, info.y);
|
||||
}
|
||||
}
|
||||
|
||||
//Fix header and own's parent data when replacing x with own, providing own's old data with parent
|
||||
static void replace_own_impl(const node_ptr & own, const node_ptr & x, const node_ptr & header, const node_ptr & own_parent, bool own_was_left)
|
||||
{
|
||||
if(NodeTraits::get_parent(header) == own)
|
||||
NodeTraits::set_parent(header, x);
|
||||
else if(own_was_left)
|
||||
NodeTraits::set_left(own_parent, x);
|
||||
else
|
||||
NodeTraits::set_right(own_parent, x);
|
||||
}
|
||||
|
||||
//Fix header and own's parent data when replacing x with own, supposing own
|
||||
//links with its parent are still ok
|
||||
static void replace_own(const node_ptr & own, const node_ptr & x, const node_ptr & header)
|
||||
{
|
||||
node_ptr own_parent(NodeTraits::get_parent(own));
|
||||
bool own_is_left(NodeTraits::get_left(own_parent) == own);
|
||||
replace_own_impl(own, x, header, own_parent, own_is_left);
|
||||
}
|
||||
|
||||
// rotate parent p to left (no header and p's parent fixup)
|
||||
static node_ptr rotate_left(const node_ptr & p)
|
||||
{
|
||||
node_ptr x(NodeTraits::get_right(p));
|
||||
node_ptr x_left(NodeTraits::get_left(x));
|
||||
NodeTraits::set_right(p, x_left);
|
||||
if(x_left){
|
||||
NodeTraits::set_parent(x_left, p);
|
||||
}
|
||||
NodeTraits::set_left(x, p);
|
||||
NodeTraits::set_parent(p, x);
|
||||
return x;
|
||||
}
|
||||
|
||||
// rotate parent p to left (with header and p's parent fixup)
|
||||
static void rotate_left(const node_ptr & p, const node_ptr & header)
|
||||
{
|
||||
bool p_was_left(is_left_child(p));
|
||||
node_ptr p_old_parent(NodeTraits::get_parent(p));
|
||||
node_ptr x(rotate_left(p));
|
||||
NodeTraits::set_parent(x, p_old_parent);
|
||||
replace_own_impl(p, x, header, p_old_parent, p_was_left);
|
||||
}
|
||||
|
||||
// rotate parent p to right (no header and p's parent fixup)
|
||||
static node_ptr rotate_right(const node_ptr & p)
|
||||
{
|
||||
node_ptr x(NodeTraits::get_left(p));
|
||||
node_ptr x_right(NodeTraits::get_right(x));
|
||||
NodeTraits::set_left(p, x_right);
|
||||
if(x_right){
|
||||
NodeTraits::set_parent(x_right, p);
|
||||
}
|
||||
NodeTraits::set_right(x, p);
|
||||
NodeTraits::set_parent(p, x);
|
||||
return x;
|
||||
}
|
||||
|
||||
// rotate parent p to right (with header and p's parent fixup)
|
||||
static void rotate_right(const node_ptr & p, const node_ptr & header)
|
||||
{
|
||||
bool p_was_left(is_left_child(p));
|
||||
node_ptr p_old_parent(NodeTraits::get_parent(p));
|
||||
node_ptr x(rotate_right(p));
|
||||
NodeTraits::set_parent(x, p_old_parent);
|
||||
replace_own_impl(p, x, header, p_old_parent, p_was_left);
|
||||
}
|
||||
|
||||
static void insert_before_check
|
||||
(const node_ptr &header, const node_ptr & pos
|
||||
, insert_commit_data &commit_data
|
||||
@@ -1631,12 +1669,40 @@ class bstree_algorithms
|
||||
template<class NodePtrCompare>
|
||||
static void insert_equal_upper_bound_check
|
||||
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0)
|
||||
{ insert_equal_check_impl(true, h, new_node, comp, commit_data, pdepth); }
|
||||
{
|
||||
std::size_t depth = 0;
|
||||
node_ptr y(h);
|
||||
node_ptr x(NodeTraits::get_parent(y));
|
||||
|
||||
while(x){
|
||||
++depth;
|
||||
y = x;
|
||||
x = comp(new_node, x) ?
|
||||
NodeTraits::get_left(x) : NodeTraits::get_right(x);
|
||||
}
|
||||
if(pdepth) *pdepth = depth;
|
||||
commit_data.link_left = (y == h) || comp(new_node, y);
|
||||
commit_data.node = y;
|
||||
}
|
||||
|
||||
template<class NodePtrCompare>
|
||||
static void insert_equal_lower_bound_check
|
||||
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0)
|
||||
{ insert_equal_check_impl(false, h, new_node, comp, commit_data, pdepth); }
|
||||
{
|
||||
std::size_t depth = 0;
|
||||
node_ptr y(h);
|
||||
node_ptr x(NodeTraits::get_parent(y));
|
||||
|
||||
while(x){
|
||||
++depth;
|
||||
y = x;
|
||||
x = !comp(x, new_node) ?
|
||||
NodeTraits::get_left(x) : NodeTraits::get_right(x);
|
||||
}
|
||||
if(pdepth) *pdepth = depth;
|
||||
commit_data.link_left = (y == h) || !comp(y, new_node);
|
||||
commit_data.node = y;
|
||||
}
|
||||
|
||||
static void insert_commit
|
||||
(const node_ptr & header, const node_ptr & new_node, const insert_commit_data &commit_data)
|
||||
@@ -1664,7 +1730,61 @@ class bstree_algorithms
|
||||
NodeTraits::set_left(new_node, node_ptr());
|
||||
}
|
||||
|
||||
//Fix header and own's parent data when replacing x with own, providing own's old data with parent
|
||||
static void set_child(const node_ptr & header, const node_ptr & new_child, const node_ptr & new_parent, const bool link_left)
|
||||
{
|
||||
if(new_parent == header)
|
||||
NodeTraits::set_parent(header, new_child);
|
||||
else if(link_left)
|
||||
NodeTraits::set_left(new_parent, new_child);
|
||||
else
|
||||
NodeTraits::set_right(new_parent, new_child);
|
||||
}
|
||||
|
||||
// rotate p to left (no header and p's parent fixup)
|
||||
static void rotate_left_no_parent_fix(const node_ptr & p, const node_ptr &p_right)
|
||||
{
|
||||
node_ptr p_right_left(NodeTraits::get_left(p_right));
|
||||
NodeTraits::set_right(p, p_right_left);
|
||||
if(p_right_left){
|
||||
NodeTraits::set_parent(p_right_left, p);
|
||||
}
|
||||
NodeTraits::set_left(p_right, p);
|
||||
NodeTraits::set_parent(p, p_right);
|
||||
}
|
||||
|
||||
// rotate p to left (with header and p's parent fixup)
|
||||
static void rotate_left(const node_ptr & p, const node_ptr & p_right, const node_ptr & p_parent, const node_ptr & header)
|
||||
{
|
||||
const bool p_was_left(NodeTraits::get_left(p_parent) == p);
|
||||
rotate_left_no_parent_fix(p, p_right);
|
||||
NodeTraits::set_parent(p_right, p_parent);
|
||||
set_child(header, p_right, p_parent, p_was_left);
|
||||
}
|
||||
|
||||
// rotate p to right (no header and p's parent fixup)
|
||||
static void rotate_right_no_parent_fix(const node_ptr & p, const node_ptr &p_left)
|
||||
{
|
||||
node_ptr p_left_right(NodeTraits::get_right(p_left));
|
||||
NodeTraits::set_left(p, p_left_right);
|
||||
if(p_left_right){
|
||||
NodeTraits::set_parent(p_left_right, p);
|
||||
}
|
||||
NodeTraits::set_right(p_left, p);
|
||||
NodeTraits::set_parent(p, p_left);
|
||||
}
|
||||
|
||||
// rotate p to right (with header and p's parent fixup)
|
||||
static void rotate_right(const node_ptr & p, const node_ptr & p_left, const node_ptr & p_parent, const node_ptr & header)
|
||||
{
|
||||
const bool p_was_left(NodeTraits::get_left(p_parent) == p);
|
||||
rotate_right_no_parent_fix(p, p_left);
|
||||
NodeTraits::set_parent(p_left, p_parent);
|
||||
set_child(header, p_left, p_parent, p_was_left);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static void subtree_to_vine(node_ptr vine_tail, std::size_t &size)
|
||||
{
|
||||
//Inspired by LibAVL:
|
||||
@@ -1877,98 +1997,6 @@ class bstree_algorithms
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
template<class NodePtrCompare>
|
||||
static void insert_equal_check_impl
|
||||
(bool upper, const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0)
|
||||
{
|
||||
std::size_t depth = 0;
|
||||
node_ptr y(h);
|
||||
node_ptr x(NodeTraits::get_parent(y));
|
||||
bool link_left;
|
||||
|
||||
if(upper){
|
||||
while(x){
|
||||
++depth;
|
||||
y = x;
|
||||
x = comp(new_node, x) ?
|
||||
NodeTraits::get_left(x) : NodeTraits::get_right(x);
|
||||
}
|
||||
link_left = (y == h) || comp(new_node, y);
|
||||
}
|
||||
else{
|
||||
while(x){
|
||||
++depth;
|
||||
y = x;
|
||||
x = !comp(x, new_node) ?
|
||||
NodeTraits::get_left(x) : NodeTraits::get_right(x);
|
||||
}
|
||||
link_left = (y == h) || !comp(y, new_node);
|
||||
}
|
||||
|
||||
commit_data.link_left = link_left;
|
||||
commit_data.node = y;
|
||||
if(pdepth) *pdepth = depth;
|
||||
}
|
||||
|
||||
static void erase_impl(const node_ptr & header, const node_ptr & z, data_for_rebalance &info)
|
||||
{
|
||||
node_ptr y(z);
|
||||
node_ptr x;
|
||||
node_ptr x_parent = node_ptr();
|
||||
node_ptr z_left(NodeTraits::get_left(z));
|
||||
node_ptr z_right(NodeTraits::get_right(z));
|
||||
if(!z_left){
|
||||
x = z_right; // x might be null.
|
||||
}
|
||||
else if(!z_right){ // z has exactly one non-null child. y == z.
|
||||
x = z_left; // x is not null.
|
||||
}
|
||||
else{
|
||||
// find z's successor
|
||||
y = bstree_algorithms::minimum (z_right);
|
||||
x = NodeTraits::get_right(y); // x might be null.
|
||||
}
|
||||
|
||||
if(y != z){
|
||||
// relink y in place of z. y is z's successor
|
||||
NodeTraits::set_parent(NodeTraits::get_left(z), y);
|
||||
NodeTraits::set_left(y, NodeTraits::get_left(z));
|
||||
if(y != NodeTraits::get_right(z)){
|
||||
x_parent = NodeTraits::get_parent(y);
|
||||
if(x)
|
||||
NodeTraits::set_parent(x, x_parent);
|
||||
NodeTraits::set_left(x_parent, x); // y must be a child of left_
|
||||
NodeTraits::set_right(y, NodeTraits::get_right(z));
|
||||
NodeTraits::set_parent(NodeTraits::get_right(z), y);
|
||||
}
|
||||
else
|
||||
x_parent = y;
|
||||
bstree_algorithms::replace_own (z, y, header);
|
||||
NodeTraits::set_parent(y, NodeTraits::get_parent(z));
|
||||
}
|
||||
else { // y == z --> z has only one child, or void
|
||||
x_parent = NodeTraits::get_parent(z);
|
||||
if(x)
|
||||
NodeTraits::set_parent(x, x_parent);
|
||||
bstree_algorithms::replace_own (z, x, header);
|
||||
if(NodeTraits::get_left(header) == z){
|
||||
NodeTraits::set_left(header, !NodeTraits::get_right(z) ? // z->get_left() must be null also
|
||||
NodeTraits::get_parent(z) : // makes leftmost == header if z == root
|
||||
bstree_algorithms::minimum (x));
|
||||
}
|
||||
if(NodeTraits::get_right(header) == z){
|
||||
NodeTraits::set_right(header, !NodeTraits::get_left(z) ? // z->get_right() must be null also
|
||||
NodeTraits::get_parent(z) : // makes rightmost == header if z == root
|
||||
bstree_algorithms::maximum(x));
|
||||
}
|
||||
}
|
||||
|
||||
info.x = x;
|
||||
info.x_parent = x_parent;
|
||||
info.y = y;
|
||||
}
|
||||
};
|
||||
|
||||
/// @cond
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#ifndef BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
|
||||
#define BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
|
||||
#include <boost/intrusive/link_mode.hpp>
|
||||
#include <boost/pointer_cast.hpp>
|
||||
#include <boost/pointer_to_other.hpp>
|
||||
@@ -24,7 +27,12 @@ namespace intrusive {
|
||||
//!This value traits template is used to create value traits
|
||||
//!from user defined node traits where value_traits::value_type will
|
||||
//!derive from node_traits::node
|
||||
template<class T, class NodeTraits, link_mode_type LinkMode = safe_link>
|
||||
|
||||
template<class T, class NodeTraits, link_mode_type LinkMode
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
= safe_link
|
||||
#endif
|
||||
>
|
||||
struct derivation_value_traits
|
||||
{
|
||||
public:
|
||||
@@ -67,4 +75,6 @@ struct derivation_value_traits
|
||||
} //namespace intrusive
|
||||
} //namespace boost
|
||||
|
||||
#include <boost/intrusive/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTRUSIVE_DERIVATION_VALUE_TRAITS_HPP
|
||||
@@ -13,7 +13,7 @@
|
||||
#ifndef BOOST_INTRUSIVE_DETAIL_ASSERT_HPP
|
||||
#define BOOST_INTRUSIVE_DETAIL_ASSERT_HPP
|
||||
|
||||
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
@@ -33,9 +33,9 @@ enum base_hook_type
|
||||
, SlistBaseHookId
|
||||
, RbTreeBaseHookId
|
||||
, HashBaseHookId
|
||||
, SplayTreeBaseHookId
|
||||
, AvlTreeBaseHookId
|
||||
, BsTreeBaseHookId
|
||||
, TreapTreeBaseHookId
|
||||
, AnyBaseHookId
|
||||
};
|
||||
|
||||
@@ -59,10 +59,6 @@ template <class HookTags>
|
||||
struct hook_tags_definer<HookTags, HashBaseHookId>
|
||||
{ typedef HookTags default_hashtable_hook; };
|
||||
|
||||
template <class HookTags>
|
||||
struct hook_tags_definer<HookTags, SplayTreeBaseHookId>
|
||||
{ typedef HookTags default_splaytree_hook; };
|
||||
|
||||
template <class HookTags>
|
||||
struct hook_tags_definer<HookTags, AvlTreeBaseHookId>
|
||||
{ typedef HookTags default_avltree_hook; };
|
||||
|
||||
@@ -70,11 +70,11 @@
|
||||
#error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END not defined!"
|
||||
#endif
|
||||
|
||||
#if BOOST_PP_ITERATION_START() != 0
|
||||
#error "BOOST_PP_ITERATION_START() must be zero (0)"
|
||||
#if BOOST_PP_ITERATION_START() > BOOST_PP_ITERATION_FINISH()
|
||||
#error "BOOST_PP_ITERATION_START() must be <= BOOST_PP_ITERATION_FINISH()"
|
||||
#endif
|
||||
|
||||
#if BOOST_PP_ITERATION() == 0
|
||||
#if BOOST_PP_ITERATION() == BOOST_PP_ITERATION_START()
|
||||
|
||||
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
|
||||
|
||||
@@ -114,6 +114,119 @@
|
||||
};
|
||||
//!
|
||||
|
||||
#else //!defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
|
||||
|
||||
template<typename Fun, bool HasFunc, class ...Args>
|
||||
struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl);
|
||||
|
||||
template<typename Fun, class ...Args>
|
||||
struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
|
||||
<Fun, false, Args...>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
#ifdef BOOST_NO_CXX11_DECLTYPE
|
||||
|
||||
//Special case for 0 args
|
||||
template< class F
|
||||
, std::size_t N =
|
||||
sizeof((boost::move_detail::declval<F>().
|
||||
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME (), 0))>
|
||||
struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
|
||||
{
|
||||
boost_intrusive_has_member_function_callable_with::yes_type dummy;
|
||||
BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int);
|
||||
};
|
||||
|
||||
//For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not
|
||||
//SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0.
|
||||
template<class F>
|
||||
struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<F, 0>
|
||||
{
|
||||
boost_intrusive_has_member_function_callable_with::no_type dummy;
|
||||
BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int);
|
||||
};
|
||||
|
||||
#endif //#ifdef BOOST_NO_CXX11_DECLTYPE
|
||||
|
||||
template<typename Fun>
|
||||
struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
|
||||
<Fun, true>
|
||||
{
|
||||
#ifndef BOOST_NO_CXX11_DECLTYPE
|
||||
template<class U, class V = decltype(boost::move_detail::declval<U>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME()) >
|
||||
static boost_intrusive_has_member_function_callable_with::yes_type Test(U*);
|
||||
#else
|
||||
template<class U>
|
||||
static BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
|
||||
<U> Test(BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U>*);
|
||||
#endif
|
||||
|
||||
template <class U>
|
||||
static boost_intrusive_has_member_function_callable_with::no_type Test(...);
|
||||
|
||||
static const bool value = sizeof(Test< Fun >(0))
|
||||
== sizeof(boost_intrusive_has_member_function_callable_with::yes_type);
|
||||
};
|
||||
|
||||
template<typename Fun, class ...DontCares>
|
||||
struct BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )
|
||||
: Fun
|
||||
{
|
||||
BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )();
|
||||
using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME;
|
||||
|
||||
boost_intrusive_has_member_function_callable_with::private_type
|
||||
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
|
||||
( DontCares...) const;
|
||||
};
|
||||
|
||||
template<typename Fun, class ...Args>
|
||||
struct BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl)
|
||||
<Fun, true , Args...>
|
||||
{
|
||||
template<class T>
|
||||
struct make_dontcare
|
||||
{
|
||||
typedef boost_intrusive_has_member_function_callable_with::dont_care type;
|
||||
};
|
||||
|
||||
typedef BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )
|
||||
<Fun, typename make_dontcare<Args>::type...> FunWrap;
|
||||
|
||||
static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) ==
|
||||
sizeof(boost_intrusive_has_member_function_callable_with::is_private_type
|
||||
( (::boost::move_detail::declval< FunWrap >().
|
||||
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
|
||||
( ::boost::move_detail::declval<Args>()... ), 0) )
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
template<typename Fun, class ...Args>
|
||||
struct BOOST_PP_CAT( has_member_function_callable_with_
|
||||
, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
|
||||
: public BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_
|
||||
, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
|
||||
< Fun
|
||||
, BOOST_PP_CAT( has_member_function_named_
|
||||
, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )<Fun>::value
|
||||
, Args... >
|
||||
{};
|
||||
|
||||
#endif //!defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
|
||||
|
||||
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
|
||||
|
||||
#endif //BOOST_PP_ITERATION() == BOOST_PP_ITERATION_START()
|
||||
|
||||
#if BOOST_PP_ITERATION() == 0
|
||||
|
||||
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
|
||||
|
||||
#if !defined(_MSC_VER) || (_MSC_VER < 1600)
|
||||
|
||||
#if defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED)
|
||||
@@ -171,9 +284,9 @@
|
||||
<Fun, true BOOST_PP_ENUM_TRAILING(BOOST_PP_SUB(BOOST_PP_ITERATION_FINISH(), BOOST_PP_ITERATION()), BOOST_INTRUSIVE_PP_IDENTITY, void)>
|
||||
{
|
||||
template<class U>
|
||||
static decltype( boost::move_detail::declval<Fun>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME()
|
||||
static decltype( boost::move_detail::declval<U>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME()
|
||||
, boost_intrusive_has_member_function_callable_with::yes_type())
|
||||
Test(Fun*);
|
||||
Test(U*);
|
||||
|
||||
template<class U>
|
||||
static boost_intrusive_has_member_function_callable_with::no_type Test(...);
|
||||
@@ -185,96 +298,6 @@
|
||||
|
||||
#else //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
|
||||
|
||||
template<typename Fun, bool HasFunc, class ...Args>
|
||||
struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl);
|
||||
|
||||
template<typename Fun, class ...Args>
|
||||
struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
|
||||
<Fun, false, Args...>
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
//Special case for 0 args
|
||||
template< class F
|
||||
, std::size_t N =
|
||||
sizeof((boost::move_detail::declval<F>().
|
||||
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME (), 0))>
|
||||
struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
|
||||
{
|
||||
boost_intrusive_has_member_function_callable_with::yes_type dummy;
|
||||
BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int);
|
||||
};
|
||||
|
||||
//For buggy compilers like MSVC 7.1+ ((F*)0)->func() does not
|
||||
//SFINAE-out the zeroarg_checker_ instantiation but sizeof yields to 0.
|
||||
template<class F>
|
||||
struct BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<F, 0>
|
||||
{
|
||||
boost_intrusive_has_member_function_callable_with::no_type dummy;
|
||||
BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)(int);
|
||||
};
|
||||
|
||||
template<typename Fun>
|
||||
struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
|
||||
<Fun, true>
|
||||
{
|
||||
template<class U>
|
||||
static BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
|
||||
<U> Test(BOOST_PP_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U>*);
|
||||
|
||||
template <class U>
|
||||
static boost_intrusive_has_member_function_callable_with::no_type Test(...);
|
||||
|
||||
static const bool value = sizeof(Test< Fun >(0))
|
||||
== sizeof(boost_intrusive_has_member_function_callable_with::yes_type);
|
||||
};
|
||||
|
||||
template<typename Fun, class ...DontCares>
|
||||
struct BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )
|
||||
: Fun
|
||||
{
|
||||
BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )();
|
||||
using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME;
|
||||
|
||||
boost_intrusive_has_member_function_callable_with::private_type
|
||||
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
|
||||
( DontCares...) const;
|
||||
};
|
||||
|
||||
template<typename Fun, class ...Args>
|
||||
struct BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl)
|
||||
<Fun, true , Args...>
|
||||
{
|
||||
template<class T>
|
||||
struct make_dontcare
|
||||
{
|
||||
typedef boost_intrusive_has_member_function_callable_with::dont_care type;
|
||||
};
|
||||
|
||||
typedef BOOST_PP_CAT( funwrap_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )
|
||||
<Fun, typename make_dontcare<Args>::type...> FunWrap;
|
||||
|
||||
static bool const value = (sizeof(boost_intrusive_has_member_function_callable_with::no_type) ==
|
||||
sizeof(boost_intrusive_has_member_function_callable_with::is_private_type
|
||||
( (::boost::move_detail::declval< FunWrap >().
|
||||
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
|
||||
( ::boost::move_detail::declval<Args>()... ), 0) )
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
template<typename Fun, class ...Args>
|
||||
struct BOOST_PP_CAT( has_member_function_callable_with_
|
||||
, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
|
||||
: public BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_
|
||||
, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
|
||||
< Fun
|
||||
, BOOST_PP_CAT( has_member_function_named_
|
||||
, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME )<Fun>::value
|
||||
, Args... >
|
||||
{};
|
||||
|
||||
#endif //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
|
||||
|
||||
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#ifndef BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP
|
||||
#define BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
@@ -118,25 +118,25 @@ struct LowPriorityConversion
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME pointer_to
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME static_cast_from
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME const_cast_from
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME dynamic_cast_from
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN namespace boost { namespace intrusive { namespace detail {
|
||||
#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}}
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3, (1, 1, <boost/intrusive/detail/has_member_function_callable_with.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -29,6 +29,12 @@ struct bool_
|
||||
static const bool value = C_;
|
||||
};
|
||||
|
||||
template< class Integer, Integer Value >
|
||||
struct integer
|
||||
{
|
||||
static const Integer value = Value;
|
||||
};
|
||||
|
||||
typedef bool_<true> true_;
|
||||
typedef bool_<false> false_;
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#ifndef BOOST_INTRUSIVE_DETAIL_PREPROCESSOR_HPP
|
||||
#define BOOST_INTRUSIVE_DETAIL_PREPROCESSOR_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -13,12 +13,47 @@
|
||||
#ifndef BOOST_INTRUSIVE_FWD_HPP
|
||||
#define BOOST_INTRUSIVE_FWD_HPP
|
||||
|
||||
//! \file
|
||||
//! This header file forward declares most Intrusive classes.
|
||||
//!
|
||||
//! It forward declares the following containers and hooks:
|
||||
//! - boost::intrusive::slist / boost::intrusive::slist_base_hook / boost::intrusive::slist_member_hook
|
||||
//! - boost::intrusive::list / boost::intrusive::list_base_hook / boost::intrusive::list_member_hook
|
||||
//! - boost::intrusive::bstree / boost::intrusive::bs_set / boost::intrusive::bs_multiset /
|
||||
//! boost::intrusive::bs_set_base_hook / boost::intrusive::bs_set_member_hook
|
||||
//! - boost::intrusive::rbtree / boost::intrusive::set / boost::intrusive::multiset /
|
||||
//! boost::intrusive::set_base_hook / boost::intrusive::set_member_hook
|
||||
//! - boost::intrusive::avltree / boost::intrusive::avl_set / boost::intrusive::avl_multiset /
|
||||
//! boost::intrusive::avl_set_base_hook / boost::intrusive::avl_set_member_hook
|
||||
//! - boost::intrusive::splaytree / boost::intrusive::splay_set / boost::intrusive::splay_multiset
|
||||
//! - boost::intrusive::sgtree / boost::intrusive::sg_set / boost::intrusive::sg_multiset
|
||||
//! - boost::intrusive::treap / boost::intrusive::treap_set / boost::intrusive::treap_multiset
|
||||
//! - boost::intrusive::hashtable / boost::intrusive::unordered_set / boost::intrusive::unordered_multiset /
|
||||
//! boost::intrusive::unordered_set_base_hook / boost::intrusive::unordered_set_member_hook /
|
||||
//! - boost::intrusive::any_base_hook / boost::intrusive::any_member_hook
|
||||
//!
|
||||
//! It forward declares the following container or hook options:
|
||||
//! - boost::intrusive::constant_time_size / boost::intrusive::size_type / boost::intrusive::compare / boost::intrusive::equal
|
||||
//! - boost::intrusive::floating_point / boost::intrusive::priority / boost::intrusive::hash
|
||||
//! - boost::intrusive::value_traits / boost::intrusive::member_hook / boost::intrusive::function_hook / boost::intrusive::base_hook
|
||||
//! - boost::intrusive::void_pointer / boost::intrusive::tag / boost::intrusive::link_mode
|
||||
//! - boost::intrusive::optimize_size / boost::intrusive::linear / boost::intrusive::cache_last
|
||||
//! - boost::intrusive::bucket_traits / boost::intrusive::store_hash / boost::intrusive::optimize_multikey
|
||||
//! - boost::intrusive::power_2_buckets / boost::intrusive::cache_begin / boost::intrusive::compare_hash / boost::intrusive::incremental
|
||||
//!
|
||||
//! It forward declares the following value traits utilities:
|
||||
//! - boost::intrusive::value_traits / boost::intrusive::derivation_value_traits /
|
||||
//! boost::intrusive::trivial_value_traits
|
||||
//!
|
||||
//! Finally it forward declares the following general purpose utilities:
|
||||
//! - boost::intrusive::pointer_plus_bits / boost::intrusive::priority_compare.
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/intrusive/link_mode.hpp>
|
||||
#include <boost/intrusive/detail/workaround.hpp>
|
||||
|
||||
/// @cond
|
||||
|
||||
namespace boost {
|
||||
namespace intrusive {
|
||||
|
||||
@@ -33,15 +68,33 @@ class circular_list_algorithms;
|
||||
template<class NodeTraits>
|
||||
class circular_slist_algorithms;
|
||||
|
||||
template<class NodeTraits>
|
||||
class linear_slist_algorithms;
|
||||
|
||||
template<class NodeTraits>
|
||||
class bstree_algorithms;
|
||||
|
||||
template<class NodeTraits>
|
||||
class rbtree_algorithms;
|
||||
|
||||
template<class NodeTraits>
|
||||
class avltree_algorithms;
|
||||
|
||||
template<class NodeTraits>
|
||||
class sgtree_algorithms;
|
||||
|
||||
template<class NodeTraits>
|
||||
class splaytree_algorithms;
|
||||
|
||||
template<class NodeTraits>
|
||||
class treap_algorithms;
|
||||
|
||||
////////////////////////////
|
||||
// Containers
|
||||
////////////////////////////
|
||||
|
||||
//slist
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -55,7 +108,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class slist;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
@@ -66,7 +119,7 @@ template<class ...Options>
|
||||
#endif
|
||||
class slist_base_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
@@ -78,7 +131,7 @@ template<class ...Options>
|
||||
class slist_member_hook;
|
||||
|
||||
//list
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -90,7 +143,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class list;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
@@ -101,7 +154,7 @@ template<class ...Options>
|
||||
#endif
|
||||
class list_base_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
@@ -112,19 +165,8 @@ template<class ...Options>
|
||||
#endif
|
||||
class list_member_hook;
|
||||
|
||||
#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>
|
||||
#endif
|
||||
class list_hook;
|
||||
|
||||
//rbtree/set/multiset
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -137,7 +179,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class rbtree;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -150,7 +192,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class set;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -163,7 +205,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class multiset;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
@@ -175,7 +217,7 @@ template<class ...Options>
|
||||
#endif
|
||||
class set_base_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
@@ -188,7 +230,7 @@ template<class ...Options>
|
||||
class set_member_hook;
|
||||
|
||||
//splaytree/splay_set/splay_multiset
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -201,7 +243,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class splaytree;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -214,7 +256,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class splay_set;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -227,30 +269,8 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class splay_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>
|
||||
#endif
|
||||
class splay_set_base_hook;
|
||||
|
||||
#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>
|
||||
#endif
|
||||
class splay_set_member_hook;
|
||||
|
||||
//avltree/avl_set/avl_multiset
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -263,7 +283,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class avltree;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -276,7 +296,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class avl_set;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -289,7 +309,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class avl_multiset;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
@@ -301,7 +321,7 @@ template<class ...Options>
|
||||
#endif
|
||||
class avl_set_base_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
@@ -315,7 +335,7 @@ class avl_set_member_hook;
|
||||
|
||||
|
||||
//treap/treap_set/treap_multiset
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -328,7 +348,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class treap;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -341,7 +361,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class treap_set;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -354,12 +374,8 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class treap_multiset;
|
||||
|
||||
//Default priority comparison functor
|
||||
template <class T>
|
||||
struct priority_compare;
|
||||
|
||||
//sgtree/sg_set/sg_multiset
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -372,7 +388,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class sgtree;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -385,7 +401,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class sg_set;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -398,7 +414,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class sg_multiset;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -411,7 +427,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class bstree;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -424,7 +440,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class bs_set;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -437,7 +453,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class bs_multiset;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
@@ -448,7 +464,7 @@ template<class ...Options>
|
||||
#endif
|
||||
class bs_set_base_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
@@ -461,7 +477,7 @@ class bs_set_member_hook;
|
||||
|
||||
//hashtable/unordered_set/unordered_multiset
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -480,7 +496,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class hashtable;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -499,7 +515,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class unordered_set;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class T
|
||||
, class O1 = void
|
||||
@@ -518,7 +534,7 @@ template<class T, class ...Options>
|
||||
#endif
|
||||
class unordered_multiset;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
@@ -530,7 +546,7 @@ template<class ...Options>
|
||||
#endif
|
||||
class unordered_set_base_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
@@ -542,7 +558,7 @@ template<class ...Options>
|
||||
#endif
|
||||
class unordered_set_member_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
@@ -553,7 +569,7 @@ template<class ...Options>
|
||||
#endif
|
||||
class any_base_hook;
|
||||
|
||||
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) && !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template
|
||||
< class O1 = void
|
||||
, class O2 = void
|
||||
@@ -564,9 +580,126 @@ template<class ...Options>
|
||||
#endif
|
||||
class any_member_hook;
|
||||
|
||||
//Options
|
||||
|
||||
template<bool Enabled>
|
||||
struct constant_time_size;
|
||||
|
||||
template<typename SizeType>
|
||||
struct size_type;
|
||||
|
||||
template<typename Compare>
|
||||
struct compare;
|
||||
|
||||
template<bool Enabled>
|
||||
struct floating_point;
|
||||
|
||||
template<typename Equal>
|
||||
struct equal;
|
||||
|
||||
template<typename Priority>
|
||||
struct priority;
|
||||
|
||||
template<typename Hash>
|
||||
struct hash;
|
||||
|
||||
template<typename ValueTraits> struct value_traits;
|
||||
|
||||
template< typename Parent
|
||||
, typename MemberHook
|
||||
, MemberHook Parent::* PtrToMember>
|
||||
struct member_hook;
|
||||
|
||||
template<typename Functor>
|
||||
struct function_hook;
|
||||
|
||||
template<typename BaseHook>
|
||||
struct base_hook;
|
||||
|
||||
template<typename VoidPointer>
|
||||
struct void_pointer;
|
||||
|
||||
template<typename Tag>
|
||||
struct tag;
|
||||
|
||||
template<link_mode_type LinkType>
|
||||
struct link_mode;
|
||||
|
||||
template<bool Enabled> struct
|
||||
optimize_size;
|
||||
|
||||
template<bool Enabled>
|
||||
struct linear;
|
||||
|
||||
template<bool Enabled>
|
||||
struct cache_last;
|
||||
|
||||
template<typename BucketTraits>
|
||||
struct bucket_traits;
|
||||
|
||||
template<bool Enabled>
|
||||
struct store_hash;
|
||||
|
||||
template<bool Enabled>
|
||||
struct optimize_multikey;
|
||||
|
||||
template<bool Enabled>
|
||||
struct power_2_buckets;
|
||||
|
||||
template<bool Enabled>
|
||||
struct cache_begin;
|
||||
|
||||
template<bool Enabled>
|
||||
struct compare_hash;
|
||||
|
||||
template<bool Enabled>
|
||||
struct incremental;
|
||||
|
||||
//Value traits
|
||||
|
||||
template<typename ValueTraits>
|
||||
struct value_traits;
|
||||
|
||||
template< typename Parent
|
||||
, typename MemberHook
|
||||
, MemberHook Parent::* PtrToMember>
|
||||
struct member_hook;
|
||||
|
||||
template< typename Functor>
|
||||
struct function_hook;
|
||||
|
||||
template<typename BaseHook>
|
||||
struct base_hook;
|
||||
|
||||
template<class T, class NodeTraits, link_mode_type LinkMode = safe_link>
|
||||
struct derivation_value_traits;
|
||||
|
||||
template<class NodeTraits, link_mode_type LinkMode = normal_link>
|
||||
struct trivial_value_traits;
|
||||
|
||||
//Additional utilities
|
||||
|
||||
template<typename VoidPointer, std::size_t Alignment>
|
||||
struct max_pointer_plus_bits;
|
||||
|
||||
template<std::size_t Alignment>
|
||||
struct max_pointer_plus_bits<void *, Alignment>;
|
||||
|
||||
template<typename Pointer, std::size_t NumBits>
|
||||
struct pointer_plus_bits;
|
||||
|
||||
template<typename T, std::size_t NumBits>
|
||||
struct pointer_plus_bits<T *, NumBits>;
|
||||
|
||||
template<typename Ptr>
|
||||
struct pointer_traits;
|
||||
|
||||
template<typename T>
|
||||
struct pointer_traits<T *>;
|
||||
|
||||
} //namespace intrusive {
|
||||
} //namespace boost {
|
||||
|
||||
/// @endcond
|
||||
#endif //#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
|
||||
#endif //#ifndef BOOST_INTRUSIVE_FWD_HPP
|
||||
@@ -77,7 +77,7 @@ struct make_list_base_hook
|
||||
//! \c auto_unlink or \c safe_link).
|
||||
//!
|
||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||
//! and the the container configured to use this hook.
|
||||
//! and the container configured to use this hook.
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
@@ -199,7 +199,7 @@ struct make_list_member_hook
|
||||
//! \c auto_unlink or \c safe_link).
|
||||
//!
|
||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||
//! and the the container configured to use this hook.
|
||||
//! and the container configured to use this hook.
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#ifndef BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP
|
||||
#define BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
|
||||
#include <boost/intrusive/link_mode.hpp>
|
||||
#include <iterator>
|
||||
#include <boost/intrusive/detail/parent_from_member.hpp>
|
||||
@@ -26,7 +29,11 @@ namespace intrusive {
|
||||
//!store a node_traits::node
|
||||
template< class T, class NodeTraits
|
||||
, typename NodeTraits::node T::* PtrToMember
|
||||
, link_mode_type LinkMode = safe_link>
|
||||
, link_mode_type LinkMode
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
= safe_link
|
||||
#endif
|
||||
>
|
||||
struct member_value_traits
|
||||
{
|
||||
public:
|
||||
@@ -67,4 +74,6 @@ struct member_value_traits
|
||||
} //namespace intrusive
|
||||
} //namespace boost
|
||||
|
||||
#include <boost/intrusive/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTRUSIVE_MEMBER_VALUE_TRAITS_HPP
|
||||
@@ -16,15 +16,15 @@
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/link_mode.hpp>
|
||||
#include <boost/intrusive/pack_options.hpp>
|
||||
#include <boost/intrusive/detail/mpl.hpp>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace intrusive {
|
||||
|
||||
/// @cond
|
||||
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//typedef void default_tag;
|
||||
struct default_tag;
|
||||
@@ -34,8 +34,6 @@ namespace detail{
|
||||
|
||||
struct default_hook_tag{};
|
||||
|
||||
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
#define BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER) \
|
||||
struct BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER : public default_hook_tag\
|
||||
{\
|
||||
@@ -50,35 +48,9 @@ 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
|
||||
|
||||
#endif //BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
template <class ValueTraits>
|
||||
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
|
||||
{
|
||||
typedef typename BucketTraits::bucket_traits type;
|
||||
};
|
||||
|
||||
template <class T, class BaseHook>
|
||||
struct concrete_hook_base_value_traits
|
||||
{
|
||||
@@ -165,7 +137,7 @@ struct get_value_traits
|
||||
//...get it's internal value traits using
|
||||
//the provided T value type.
|
||||
, get_base_value_traits<T, supposed_value_traits>
|
||||
//...else use it's internal value traits tag
|
||||
//...else use its internal value traits tag
|
||||
//(member hooks and custom value traits are in this group)
|
||||
, detail::eval_if_c
|
||||
< internal_member_value_traits<supposed_value_traits>::value
|
||||
@@ -191,7 +163,7 @@ struct get_node_traits
|
||||
//...get it's internal value traits using
|
||||
//the provided T value type.
|
||||
, get_base_node_traits<supposed_value_traits>
|
||||
//...else use it's internal value traits tag
|
||||
//...else use its internal value traits tag
|
||||
//(member hooks and custom value traits are in this group)
|
||||
, detail::eval_if_c
|
||||
< internal_member_value_traits<supposed_value_traits>::value
|
||||
@@ -203,50 +175,20 @@ struct get_node_traits
|
||||
|
||||
} //namespace detail{
|
||||
|
||||
/// @endcond
|
||||
#endif //BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//!This option setter specifies if the intrusive
|
||||
//!container stores its size as a member to
|
||||
//!obtain constant-time size() member.
|
||||
template<bool Enabled>
|
||||
struct constant_time_size
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
static const bool constant_time_size = Enabled;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(constant_time_size, bool, Enabled, constant_time_size)
|
||||
|
||||
//!This option setter specifies the type that
|
||||
//!the container will use to store its size.
|
||||
template<class SizeType>
|
||||
struct size_type
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
typedef SizeType size_type;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_TYPE(size_type, SizeType, SizeType, size_type)
|
||||
|
||||
//!This option setter specifies the strict weak ordering
|
||||
//!comparison functor for the value type
|
||||
template<class Compare>
|
||||
struct compare
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
typedef Compare compare;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_TYPE(compare, Compare, Compare, compare)
|
||||
|
||||
//!This option setter for scapegoat containers specifies if
|
||||
//!the intrusive scapegoat container should use a non-variable
|
||||
@@ -260,74 +202,39 @@ struct compare
|
||||
//!If the user only needs an alpha value near 1/sqrt(2), this
|
||||
//!option also improves performance since avoids logarithm
|
||||
//!and division operations when rebalancing the tree.
|
||||
template<bool Enabled>
|
||||
struct floating_point
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
static const bool floating_point = Enabled;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(floating_point, bool, Enabled, floating_point)
|
||||
|
||||
//!This option setter specifies the equality
|
||||
//!functor for the value type
|
||||
template<class Equal>
|
||||
struct equal
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
typedef Equal equal;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_TYPE(equal, Equal, Equal, equal)
|
||||
|
||||
//!This option setter specifies the equality
|
||||
//!functor for the value type
|
||||
template<class Priority>
|
||||
struct priority
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
typedef Priority priority;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_TYPE(priority, Priority, Priority, priority)
|
||||
|
||||
//!This option setter specifies the hash
|
||||
//!functor for the value type
|
||||
template<class Hash>
|
||||
struct hash
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
typedef Hash hash;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_TYPE(hash, Hash, Hash, hash)
|
||||
|
||||
//!This option setter specifies the relationship between the type
|
||||
//!to be managed by the container (the value type) and the node to be
|
||||
//!used in the node algorithms. It also specifies the linking policy.
|
||||
template<typename ValueTraits>
|
||||
struct value_traits
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
typedef ValueTraits proto_value_traits;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_TYPE(value_traits, ValueTraits, ValueTraits, proto_value_traits)
|
||||
|
||||
//#define BOOST_INTRUSIVE_COMMA ,
|
||||
//#define BOOST_INTRUSIVE_LESS <
|
||||
//#define BOOST_INTRUSIVE_MORE >
|
||||
//BOOST_INTRUSIVE_OPTION_TYPE (member_hook, Parent BOOST_INTRUSIVE_COMMA class MemberHook BOOST_INTRUSIVE_COMMA MemberHook Parent::* PtrToMember , mhtraits BOOST_INTRUSIVE_LESS Parent BOOST_INTRUSIVE_COMMA MemberHook BOOST_INTRUSIVE_COMMA PtrToMember BOOST_INTRUSIVE_MORE , proto_value_traits)
|
||||
//template< class Parent , class MemberHook , MemberHook Parent::* PtrToMember>
|
||||
//struct member_hook {
|
||||
// template<class Base> struct pack : Base {
|
||||
// typedef mhtraits < Parent , MemberHook , PtrToMember > proto_value_traits;
|
||||
// };
|
||||
//};
|
||||
//
|
||||
//#undef BOOST_INTRUSIVE_COMMA
|
||||
//#undef BOOST_INTRUSIVE_LESS
|
||||
//#undef BOOST_INTRUSIVE_MORE
|
||||
|
||||
//!This option setter specifies the member hook the
|
||||
//!container must use.
|
||||
@@ -336,27 +243,21 @@ template< typename Parent
|
||||
, MemberHook Parent::* PtrToMember>
|
||||
struct member_hook
|
||||
{
|
||||
/// @cond
|
||||
/*
|
||||
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
|
||||
> member_value_traits;
|
||||
// @cond
|
||||
// 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> member_value_traits;
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
@@ -365,158 +266,55 @@ struct member_hook
|
||||
/// @endcond
|
||||
};
|
||||
|
||||
|
||||
//!This option setter specifies the function object that will
|
||||
//!be used to convert between values to be inserted in a container
|
||||
//!and the hook to be used for that purpose.
|
||||
template< typename Functor>
|
||||
struct function_hook
|
||||
{
|
||||
/// @cond
|
||||
typedef fhtraits
|
||||
<Functor> function_value_traits;
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
typedef function_value_traits proto_value_traits;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
|
||||
BOOST_INTRUSIVE_OPTION_TYPE(function_hook, Functor, fhtraits<Functor>, proto_value_traits)
|
||||
|
||||
//!This option setter specifies that the container
|
||||
//!must use the specified base hook
|
||||
template<typename BaseHook>
|
||||
struct base_hook
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
typedef BaseHook proto_value_traits;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_TYPE(base_hook, BaseHook, BaseHook, proto_value_traits)
|
||||
|
||||
//!This option setter specifies the type of
|
||||
//!a void pointer. This will instruct the hook
|
||||
//!to use this type of pointer instead of the
|
||||
//!default one
|
||||
template<class VoidPointer>
|
||||
struct void_pointer
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
typedef VoidPointer void_pointer;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_TYPE(void_pointer, VoidPointer, VoidPointer, void_pointer)
|
||||
|
||||
//!This option setter specifies the type of
|
||||
//!the tag of a base hook. A type cannot have two
|
||||
//!base hooks of the same type, so a tag can be used
|
||||
//!to differentiate two base hooks with otherwise same type
|
||||
template<class Tag>
|
||||
struct tag
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
typedef Tag tag;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_TYPE(tag, Tag, Tag, tag)
|
||||
|
||||
//!This option setter specifies the link mode
|
||||
//!(normal_link, safe_link or auto_unlink)
|
||||
template<link_mode_type LinkType>
|
||||
struct link_mode
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
static const link_mode_type link_mode = LinkType;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(link_mode, link_mode_type, LinkType, link_mode)
|
||||
|
||||
//!This option setter specifies if the hook
|
||||
//!should be optimized for size instead of for speed.
|
||||
template<bool Enabled>
|
||||
struct optimize_size
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
static const bool optimize_size = Enabled;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_size, bool, Enabled, optimize_size)
|
||||
|
||||
//!This option setter specifies if the list container should
|
||||
//!This option setter specifies if the slist container should
|
||||
//!use a linear implementation instead of a circular one.
|
||||
template<bool Enabled>
|
||||
struct linear
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
static const bool linear = Enabled;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(linear, bool, Enabled, linear)
|
||||
|
||||
//!This option setter specifies if the list container should
|
||||
//!use a linear implementation instead of a circular one.
|
||||
template<bool Enabled>
|
||||
struct cache_last
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
static const bool cache_last = Enabled;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
//!If true, slist also stores a pointer to the last element of the singly linked list.
|
||||
//!This allows O(1) swap and splice_after(iterator, slist &) for circular slists and makes
|
||||
//!possible new functions like push_back(reference) and back().
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(cache_last, bool, Enabled, cache_last)
|
||||
|
||||
//!This option setter specifies the bucket traits
|
||||
//!class for unordered associative containers. When this option is specified,
|
||||
//!instead of using the default bucket traits, a user defined holder will be defined
|
||||
template<class BucketTraits>
|
||||
struct bucket_traits
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
typedef BucketTraits bucket_traits;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_TYPE(bucket_traits, BucketTraits, BucketTraits, bucket_traits)
|
||||
|
||||
//!This option setter specifies if the unordered hook
|
||||
//!should offer room to store the hash value.
|
||||
//!Storing the hash in the hook will speed up rehashing
|
||||
//!processes in applications where rehashing is frequent,
|
||||
//!rehashing might throw or the value is heavy to hash.
|
||||
template<bool Enabled>
|
||||
struct store_hash
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
static const bool store_hash = Enabled;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(store_hash, bool, Enabled, store_hash)
|
||||
|
||||
//!This option setter specifies if the unordered hook
|
||||
//!should offer room to store another link to another node
|
||||
@@ -524,51 +322,20 @@ struct store_hash
|
||||
//!Storing this link will speed up lookups and insertions on
|
||||
//!unordered_multiset containers with a great number of elements
|
||||
//!with the same key.
|
||||
template<bool Enabled>
|
||||
struct optimize_multikey
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
static const bool optimize_multikey = Enabled;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_multikey, bool, Enabled, optimize_multikey)
|
||||
|
||||
//!This option setter specifies if the bucket array will be always power of two.
|
||||
//!This allows using masks instead of the default modulo operation to determine
|
||||
//!the bucket number from the hash value, leading to better performance.
|
||||
//!In debug mode, if power of two buckets mode is activated, the bucket length
|
||||
//!will be checked to through assertions to assure the bucket length is power of two.
|
||||
template<bool Enabled>
|
||||
struct power_2_buckets
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
static const bool power_2_buckets = Enabled;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(power_2_buckets, bool, Enabled, power_2_buckets)
|
||||
|
||||
//!This option setter specifies if the container will cache a pointer to the first
|
||||
//!non-empty bucket so that begin() is always constant-time.
|
||||
//!This is specially helpful when we can have containers with a few elements
|
||||
//!but with big bucket arrays (that is, hashtables with low load factors).
|
||||
template<bool Enabled>
|
||||
struct cache_begin
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
static const bool cache_begin = Enabled;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(cache_begin, bool, Enabled, cache_begin)
|
||||
|
||||
//!This option setter specifies if the container will compare the hash value
|
||||
//!before comparing objects. This option can't be specified if store_hash<>
|
||||
@@ -576,17 +343,7 @@ struct cache_begin
|
||||
//!This is specially helpful when we have containers with a high load factor.
|
||||
//!and the comparison function is much more expensive that comparing already
|
||||
//!stored hash values.
|
||||
template<bool Enabled>
|
||||
struct compare_hash
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
static const bool compare_hash = Enabled;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(compare_hash, bool, Enabled, compare_hash)
|
||||
|
||||
//!This option setter specifies if the hash container will use incremental
|
||||
//!hashing. With incremental hashing the cost of hash table expansion is spread
|
||||
@@ -594,17 +351,7 @@ struct compare_hash
|
||||
//!Therefore linear hashing is well suited for interactive applications or real-time
|
||||
//!appplications where the worst-case insertion time of non-incremental hash containers
|
||||
//!(rehashing the whole bucket array) is not admisible.
|
||||
template<bool Enabled>
|
||||
struct incremental
|
||||
{
|
||||
/// @cond
|
||||
template<class Base>
|
||||
struct pack : Base
|
||||
{
|
||||
static const bool incremental = Enabled;
|
||||
};
|
||||
/// @endcond
|
||||
};
|
||||
BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, incremental)
|
||||
|
||||
/// @cond
|
||||
|
||||
@@ -615,210 +362,6 @@ struct none
|
||||
{};
|
||||
};
|
||||
|
||||
//To-do: pass to variadic templates
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
|
||||
template<class Prev, class Next>
|
||||
struct do_pack
|
||||
{
|
||||
//Use "pack" member template to pack options
|
||||
typedef typename Next::template pack<Prev> type;
|
||||
};
|
||||
|
||||
template<class Prev>
|
||||
struct do_pack<Prev, void>
|
||||
{
|
||||
//Avoid packing "void" to shorten template names
|
||||
typedef Prev type;
|
||||
};
|
||||
|
||||
template
|
||||
< class DefaultOptions
|
||||
, 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
|
||||
{
|
||||
// join options
|
||||
typedef
|
||||
typename do_pack
|
||||
< typename do_pack
|
||||
< typename do_pack
|
||||
< typename do_pack
|
||||
< typename do_pack
|
||||
< typename do_pack
|
||||
< typename do_pack
|
||||
< typename do_pack
|
||||
< typename do_pack
|
||||
< typename do_pack
|
||||
< typename do_pack
|
||||
< DefaultOptions
|
||||
, O1
|
||||
>::type
|
||||
, O2
|
||||
>::type
|
||||
, O3
|
||||
>::type
|
||||
, O4
|
||||
>::type
|
||||
, O5
|
||||
>::type
|
||||
, O6
|
||||
>::type
|
||||
, O7
|
||||
>::type
|
||||
, O8
|
||||
>::type
|
||||
, O9
|
||||
>::type
|
||||
, O10
|
||||
>::type
|
||||
, O11
|
||||
>::type
|
||||
type;
|
||||
};
|
||||
#else
|
||||
|
||||
//index_tuple
|
||||
template<int... Indexes>
|
||||
struct index_tuple{};
|
||||
|
||||
//build_number_seq
|
||||
template<std::size_t Num, typename Tuple = index_tuple<> >
|
||||
struct build_number_seq;
|
||||
|
||||
template<std::size_t Num, int... Indexes>
|
||||
struct build_number_seq<Num, index_tuple<Indexes...> >
|
||||
: build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
|
||||
{};
|
||||
|
||||
template<int... Indexes>
|
||||
struct build_number_seq<0, index_tuple<Indexes...> >
|
||||
{ typedef index_tuple<Indexes...> type; };
|
||||
|
||||
template<class ...Types>
|
||||
struct typelist
|
||||
{};
|
||||
|
||||
//invert_typelist
|
||||
template<class T>
|
||||
struct invert_typelist;
|
||||
|
||||
template<int I, typename Tuple>
|
||||
struct typelist_element;
|
||||
|
||||
template<int I, typename Head, typename... Tail>
|
||||
struct typelist_element<I, typelist<Head, Tail...> >
|
||||
{
|
||||
typedef typename typelist_element<I-1, typelist<Tail...> >::type type;
|
||||
};
|
||||
|
||||
template<typename Head, typename... Tail>
|
||||
struct typelist_element<0, typelist<Head, Tail...> >
|
||||
{
|
||||
typedef Head type;
|
||||
};
|
||||
|
||||
template<int ...Ints, class ...Types>
|
||||
typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>
|
||||
inverted_typelist(index_tuple<Ints...>, typelist<Types...>)
|
||||
{
|
||||
return typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>();
|
||||
}
|
||||
|
||||
//sizeof_typelist
|
||||
template<class Typelist>
|
||||
struct sizeof_typelist;
|
||||
|
||||
template<class ...Types>
|
||||
struct sizeof_typelist< typelist<Types...> >
|
||||
{
|
||||
static const std::size_t value = sizeof...(Types);
|
||||
};
|
||||
|
||||
//invert_typelist_impl
|
||||
template<class Typelist, class Indexes>
|
||||
struct invert_typelist_impl;
|
||||
|
||||
|
||||
template<class Typelist, int ...Ints>
|
||||
struct invert_typelist_impl< Typelist, index_tuple<Ints...> >
|
||||
{
|
||||
static const std::size_t last_idx = sizeof_typelist<Typelist>::value - 1;
|
||||
typedef typelist
|
||||
<typename typelist_element<last_idx - Ints, Typelist>::type...> type;
|
||||
};
|
||||
|
||||
template<class Typelist, int Int>
|
||||
struct invert_typelist_impl< Typelist, index_tuple<Int> >
|
||||
{
|
||||
typedef Typelist type;
|
||||
};
|
||||
|
||||
template<class Typelist>
|
||||
struct invert_typelist_impl< Typelist, index_tuple<> >
|
||||
{
|
||||
typedef Typelist type;
|
||||
};
|
||||
|
||||
//invert_typelist
|
||||
template<class Typelist>
|
||||
struct invert_typelist;
|
||||
|
||||
template<class ...Types>
|
||||
struct invert_typelist< typelist<Types...> >
|
||||
{
|
||||
typedef typelist<Types...> typelist_t;
|
||||
typedef typename build_number_seq<sizeof...(Types)>::type indexes_t;
|
||||
typedef typename invert_typelist_impl<typelist_t, indexes_t>::type type;
|
||||
};
|
||||
|
||||
//Do pack
|
||||
template<class Typelist>
|
||||
struct do_pack;
|
||||
|
||||
template<>
|
||||
struct do_pack<typelist<> >;
|
||||
|
||||
template<class Prev>
|
||||
struct do_pack<typelist<Prev> >
|
||||
{
|
||||
typedef Prev type;
|
||||
};
|
||||
|
||||
template<class Prev, class Last>
|
||||
struct do_pack<typelist<Prev, Last> >
|
||||
{
|
||||
typedef typename Prev::template pack<Last> type;
|
||||
};
|
||||
|
||||
template<class Prev, class ...Others>
|
||||
struct do_pack<typelist<Prev, Others...> >
|
||||
{
|
||||
typedef typename Prev::template pack
|
||||
<typename do_pack<typelist<Others...> >::type> type;
|
||||
};
|
||||
|
||||
|
||||
template<class ...Options>
|
||||
struct pack_options
|
||||
{
|
||||
typedef typelist<Options...> typelist_t;
|
||||
typedef typename invert_typelist<typelist_t>::type inverted_typelist;
|
||||
typedef typename do_pack<inverted_typelist>::type type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
struct hook_defaults
|
||||
{
|
||||
typedef void* void_pointer;
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#define BOOST_INTRUSIVE_GET_PARENT_FROM_MEMBER_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
|
||||
#include <boost/intrusive/detail/parent_from_member.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#ifndef BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP
|
||||
#define BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/detail/mpl.hpp> //ls_zeros
|
||||
#include <boost/intrusive/detail/assert.hpp> //BOOST_INTRUSIVE_INVARIANT_ASSERT
|
||||
|
||||
@@ -83,4 +85,6 @@ struct pointer_plus_bits<T*, NumBits>
|
||||
} //namespace intrusive
|
||||
} //namespace boost
|
||||
|
||||
#include <boost/intrusive/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTRUSIVE_POINTER_PLUS_BITS_HPP
|
||||
@@ -17,11 +17,12 @@
|
||||
#ifndef BOOST_INTRUSIVE_POINTER_TRAITS_HPP
|
||||
#define BOOST_INTRUSIVE_POINTER_TRAITS_HPP
|
||||
|
||||
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
|
||||
#if defined(_MSC_VER)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/detail/workaround.hpp>
|
||||
#include <boost/intrusive/detail/memory_util.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
|
||||
@@ -23,8 +23,12 @@ namespace intrusive {
|
||||
|
||||
template <class T>
|
||||
struct priority_compare
|
||||
: public std::binary_function<T, T, bool>
|
||||
{
|
||||
//Compatibility with std::binary_function
|
||||
typedef T first_argument_type;
|
||||
typedef T second_argument_type;
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator()(const T &val, const T &val2) const
|
||||
{
|
||||
return priority_order(val, val2);
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
#define BOOST_INTRUSIVE_RBTREE_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/set_hook.hpp>
|
||||
#include <boost/intrusive/detail/rbtree_node.hpp>
|
||||
#include <boost/intrusive/bstree.hpp>
|
||||
@@ -292,7 +292,7 @@ class rbtree_impl
|
||||
//! @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);
|
||||
|
||||
@@ -483,14 +483,13 @@ class rbtree
|
||||
public:
|
||||
typedef typename Base::value_compare value_compare;
|
||||
typedef typename Base::value_traits value_traits;
|
||||
typedef typename Base::real_value_traits real_value_traits;
|
||||
typedef typename Base::iterator iterator;
|
||||
typedef typename Base::const_iterator const_iterator;
|
||||
typedef typename Base::reverse_iterator reverse_iterator;
|
||||
typedef typename Base::const_reverse_iterator const_reverse_iterator;
|
||||
|
||||
//Assert if passed value traits are compatible with the type
|
||||
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
|
||||
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
|
||||
|
||||
explicit rbtree( const value_compare &cmp = value_compare()
|
||||
, const value_traits &v_traits = value_traits())
|
||||
|
||||
@@ -10,31 +10,6 @@
|
||||
// See http://www.boost.org/libs/intrusive for documentation.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// The internal implementation of red-black trees is based on that of SGI STL
|
||||
// stl_tree.h file:
|
||||
//
|
||||
// Copyright (c) 1996,1997
|
||||
// Silicon Graphics Computer Systems, Inc.
|
||||
//
|
||||
// Permission to use, copy, modify, distribute and sell this software
|
||||
// and its documentation for any purpose is hereby granted without fee,
|
||||
// provided that the above copyright notice appear in all copies and
|
||||
// that both that copyright notice and this permission notice appear
|
||||
// in supporting documentation. Silicon Graphics makes no
|
||||
// representations about the suitability of this software for any
|
||||
// purpose. It is provided "as is" without express or implied warranty.
|
||||
//
|
||||
//
|
||||
// Copyright (c) 1994
|
||||
// Hewlett-Packard Company
|
||||
//
|
||||
// Permission to use, copy, modify, distribute and sell this software
|
||||
// and its documentation for any purpose is hereby granted without fee,
|
||||
// provided that the above copyright notice appear in all copies and
|
||||
// that both that copyright notice and this permission notice appear
|
||||
// in supporting documentation. Hewlett-Packard Company makes no
|
||||
// representations about the suitability of this software for any
|
||||
// purpose. It is provided "as is" without express or implied warranty.
|
||||
//
|
||||
// The tree destruction algorithm is based on Julienne Walker and The EC Team code:
|
||||
//
|
||||
@@ -49,9 +24,9 @@
|
||||
#define BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
@@ -82,21 +57,6 @@ struct rbtree_node_cloner
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
@@ -270,10 +230,18 @@ class rbtree_algorithms
|
||||
static node_ptr erase(const node_ptr & header, const node_ptr & z)
|
||||
{
|
||||
typename bstree_algo::data_for_rebalance info;
|
||||
bstree_algo::erase(header, z, rbtree_erase_fixup<NodeTraits>(), info);
|
||||
bstree_algo::erase(header, z, info);
|
||||
|
||||
//Rebalance rbtree
|
||||
if(NodeTraits::get_color(z) != NodeTraits::red()){
|
||||
color new_z_color;
|
||||
if(info.y != z){
|
||||
new_z_color = NodeTraits::get_color(info.y);
|
||||
NodeTraits::set_color(info.y, NodeTraits::get_color(z));
|
||||
}
|
||||
else{
|
||||
new_z_color = NodeTraits::get_color(z);
|
||||
}
|
||||
//Rebalance rbtree if needed
|
||||
if(new_z_color != NodeTraits::red()){
|
||||
rebalance_after_erasure(header, info.x, info.x_parent);
|
||||
}
|
||||
return z;
|
||||
@@ -322,6 +290,7 @@ class rbtree_algorithms
|
||||
//! @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)
|
||||
@@ -411,64 +380,76 @@ class rbtree_algorithms
|
||||
|
||||
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())){
|
||||
if(x == NodeTraits::get_left(x_parent)){
|
||||
while(1){
|
||||
if(x_parent == header || (x && NodeTraits::get_color(x) != NodeTraits::black())){
|
||||
break;
|
||||
}
|
||||
//Don't cache x_is_leftchild or similar because x can be null and
|
||||
//equal to both x_parent_left and x_parent_right
|
||||
const node_ptr x_parent_left(NodeTraits::get_left(x_parent));
|
||||
if(x == x_parent_left){ //x is left child
|
||||
node_ptr w = NodeTraits::get_right(x_parent);
|
||||
BOOST_ASSERT(w);
|
||||
if(NodeTraits::get_color(w) == NodeTraits::red()){
|
||||
NodeTraits::set_color(w, NodeTraits::black());
|
||||
NodeTraits::set_color(x_parent, NodeTraits::red());
|
||||
bstree_algo::rotate_left(x_parent, header);
|
||||
bstree_algo::rotate_left(x_parent, w, NodeTraits::get_parent(x_parent), header);
|
||||
w = NodeTraits::get_right(x_parent);
|
||||
}
|
||||
if((!NodeTraits::get_left(w) || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()) &&
|
||||
(!NodeTraits::get_right(w) || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black())){
|
||||
node_ptr const w_left (NodeTraits::get_left(w));
|
||||
node_ptr const w_right(NodeTraits::get_right(w));
|
||||
if((!w_left || NodeTraits::get_color(w_left) == NodeTraits::black()) &&
|
||||
(!w_right || NodeTraits::get_color(w_right) == NodeTraits::black())){
|
||||
NodeTraits::set_color(w, NodeTraits::red());
|
||||
x = x_parent;
|
||||
x_parent = NodeTraits::get_parent(x_parent);
|
||||
}
|
||||
else {
|
||||
if(!NodeTraits::get_right(w) || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()){
|
||||
NodeTraits::set_color(NodeTraits::get_left(w), NodeTraits::black());
|
||||
if(!w_right || NodeTraits::get_color(w_right) == NodeTraits::black()){
|
||||
NodeTraits::set_color(w_left, NodeTraits::black());
|
||||
NodeTraits::set_color(w, NodeTraits::red());
|
||||
bstree_algo::rotate_right(w, header);
|
||||
bstree_algo::rotate_right(w, w_left, NodeTraits::get_parent(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());
|
||||
bstree_algo::rotate_left(x_parent, header);
|
||||
const node_ptr new_wright(NodeTraits::get_right(w));
|
||||
if(new_wright)
|
||||
NodeTraits::set_color(new_wright, NodeTraits::black());
|
||||
bstree_algo::rotate_left(x_parent, NodeTraits::get_right(x_parent), NodeTraits::get_parent(x_parent), header);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// same as above, with right_ <-> left_.
|
||||
node_ptr w = NodeTraits::get_left(x_parent);
|
||||
node_ptr w = x_parent_left;
|
||||
if(NodeTraits::get_color(w) == NodeTraits::red()){
|
||||
NodeTraits::set_color(w, NodeTraits::black());
|
||||
NodeTraits::set_color(x_parent, NodeTraits::red());
|
||||
bstree_algo::rotate_right(x_parent, header);
|
||||
bstree_algo::rotate_right(x_parent, w, NodeTraits::get_parent(x_parent), header);
|
||||
w = NodeTraits::get_left(x_parent);
|
||||
}
|
||||
if((!NodeTraits::get_right(w) || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()) &&
|
||||
(!NodeTraits::get_left(w) || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black())){
|
||||
node_ptr const w_left (NodeTraits::get_left(w));
|
||||
node_ptr const w_right(NodeTraits::get_right(w));
|
||||
if((!w_right || NodeTraits::get_color(w_right) == NodeTraits::black()) &&
|
||||
(!w_left || NodeTraits::get_color(w_left) == NodeTraits::black())){
|
||||
NodeTraits::set_color(w, NodeTraits::red());
|
||||
x = x_parent;
|
||||
x_parent = NodeTraits::get_parent(x_parent);
|
||||
}
|
||||
else {
|
||||
if(!NodeTraits::get_left(w) || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()){
|
||||
NodeTraits::set_color(NodeTraits::get_right(w), NodeTraits::black());
|
||||
if(!w_left || NodeTraits::get_color(w_left) == NodeTraits::black()){
|
||||
NodeTraits::set_color(w_right, NodeTraits::black());
|
||||
NodeTraits::set_color(w, NodeTraits::red());
|
||||
bstree_algo::rotate_left(w, header);
|
||||
bstree_algo::rotate_left(w, w_right, NodeTraits::get_parent(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());
|
||||
bstree_algo::rotate_right(x_parent, header);
|
||||
const node_ptr new_wleft(NodeTraits::get_left(w));
|
||||
if(new_wleft)
|
||||
NodeTraits::set_color(new_wleft, NodeTraits::black());
|
||||
bstree_algo::rotate_right(x_parent, NodeTraits::get_left(x_parent), NodeTraits::get_parent(x_parent), header);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -480,48 +461,49 @@ class rbtree_algorithms
|
||||
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()){
|
||||
while(1){
|
||||
node_ptr p_parent(NodeTraits::get_parent(p));
|
||||
node_ptr p_parent_parent(NodeTraits::get_parent(p_parent));
|
||||
if(bstree_algo::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());
|
||||
NodeTraits::set_color(p_parent_parent, NodeTraits::red());
|
||||
NodeTraits::set_color(x, NodeTraits::black());
|
||||
p = p_parent_parent;
|
||||
}
|
||||
else {
|
||||
if(!bstree_algo::is_left_child(p)){
|
||||
p = p_parent;
|
||||
bstree_algo::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());
|
||||
bstree_algo::rotate_right(new_p_parent_parent, header);
|
||||
}
|
||||
const node_ptr p_grandparent(NodeTraits::get_parent(p_parent));
|
||||
if(p_parent == header || NodeTraits::get_color(p_parent) == NodeTraits::black() || p_grandparent == header){
|
||||
break;
|
||||
}
|
||||
else{
|
||||
node_ptr x = NodeTraits::get_left(p_parent_parent);
|
||||
if(x && NodeTraits::get_color(x) == NodeTraits::red()){
|
||||
NodeTraits::set_color(p_parent, NodeTraits::black());
|
||||
NodeTraits::set_color(p_parent_parent, NodeTraits::red());
|
||||
NodeTraits::set_color(x, NodeTraits::black());
|
||||
p = p_parent_parent;
|
||||
}
|
||||
else{
|
||||
if(bstree_algo::is_left_child(p)){
|
||||
p = p_parent;
|
||||
bstree_algo::rotate_right(p, header);
|
||||
|
||||
NodeTraits::set_color(p_grandparent, NodeTraits::red());
|
||||
node_ptr const p_grandparent_left (NodeTraits::get_left (p_grandparent));
|
||||
bool const p_parent_is_left_child = p_parent == p_grandparent_left;
|
||||
node_ptr const x(p_parent_is_left_child ? NodeTraits::get_right(p_grandparent) : p_grandparent_left);
|
||||
|
||||
if(x && NodeTraits::get_color(x) == NodeTraits::red()){
|
||||
NodeTraits::set_color(x, NodeTraits::black());
|
||||
NodeTraits::set_color(p_parent, NodeTraits::black());
|
||||
p = p_grandparent;
|
||||
}
|
||||
else{ //Final step
|
||||
const bool p_is_left_child(NodeTraits::get_left(p_parent) == p);
|
||||
if(p_parent_is_left_child){ //p_parent is left child
|
||||
if(!p_is_left_child){ //p is right child
|
||||
bstree_algo::rotate_left_no_parent_fix(p_parent, p);
|
||||
//No need to link p and p_grandparent:
|
||||
// [NodeTraits::set_parent(p, p_grandparent) + NodeTraits::set_left(p_grandparent, p)]
|
||||
//as p_grandparent is not the header, another rotation is coming and p_parent
|
||||
//will be the left child of p_grandparent
|
||||
p_parent = p;
|
||||
}
|
||||
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());
|
||||
bstree_algo::rotate_left(new_p_parent_parent, header);
|
||||
bstree_algo::rotate_right(p_grandparent, p_parent, NodeTraits::get_parent(p_grandparent), header);
|
||||
}
|
||||
else{ //p_parent is right child
|
||||
if(p_is_left_child){ //p is left child
|
||||
bstree_algo::rotate_right_no_parent_fix(p_parent, p);
|
||||
//No need to link p and p_grandparent:
|
||||
// [NodeTraits::set_parent(p, p_grandparent) + NodeTraits::set_right(p_grandparent, p)]
|
||||
//as p_grandparent is not the header, another rotation is coming and p_parent
|
||||
//will be the right child of p_grandparent
|
||||
p_parent = p;
|
||||
}
|
||||
bstree_algo::rotate_left(p_grandparent, p_parent, NodeTraits::get_parent(p_grandparent), header);
|
||||
}
|
||||
NodeTraits::set_color(p_parent, NodeTraits::black());
|
||||
break;
|
||||
}
|
||||
}
|
||||
NodeTraits::set_color(NodeTraits::get_parent(header), NodeTraits::black());
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
|
||||
#include <boost/intrusive/detail/mpl.hpp>
|
||||
#include <boost/intrusive/rbtree.hpp>
|
||||
#include <iterator>
|
||||
@@ -248,13 +249,19 @@ class set_impl
|
||||
template<class Disposer>
|
||||
void clear_and_dispose(Disposer disposer);
|
||||
|
||||
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::count(const_reference)const
|
||||
size_type count(const_reference value) const;
|
||||
size_type count(const_reference value) const
|
||||
{ return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
size_type count(const KeyType& key, KeyValueCompare comp) const
|
||||
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference)
|
||||
iterator lower_bound(const_reference value);
|
||||
|
||||
@@ -297,21 +304,29 @@ class set_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> equal_range(const_reference value);
|
||||
std::pair<iterator,iterator> equal_range(const_reference value)
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
|
||||
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const_reference value) const;
|
||||
equal_range(const_reference value) const
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::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;
|
||||
equal_range(const KeyType& key, KeyValueCompare comp) const
|
||||
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::bounded_range(const_reference,const_reference,bool,bool)
|
||||
std::pair<iterator,iterator> bounded_range
|
||||
@@ -691,7 +706,7 @@ class multiset_impl
|
||||
//! @copydoc ::boost::intrusive::rbtree::count(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::lower_bound(const_reference)
|
||||
iterator lower_bound(const_reference value);
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
#include <boost/intrusive/detail/rbtree_node.hpp>
|
||||
#include <boost/intrusive/rbtree_algorithms.hpp>
|
||||
@@ -76,7 +77,7 @@ struct make_set_base_hook
|
||||
//! unique tag.
|
||||
//!
|
||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||
//! and the the container configured to use this hook.
|
||||
//! and the container configured to use this hook.
|
||||
//!
|
||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||
//! \c auto_unlink or \c safe_link).
|
||||
@@ -203,7 +204,7 @@ struct make_set_member_hook
|
||||
//! \c link_mode<> and \c optimize_size<>.
|
||||
//!
|
||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||
//! and the the container configured to use this hook.
|
||||
//! and the container configured to use this hook.
|
||||
//!
|
||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||
//! \c auto_unlink or \c safe_link).
|
||||
|
||||
@@ -247,13 +247,19 @@ class sg_set_impl
|
||||
template<class Disposer>
|
||||
void clear_and_dispose(Disposer disposer);
|
||||
|
||||
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::sgtree::count(const_reference)const
|
||||
size_type count(const_reference value) const;
|
||||
size_type count(const_reference value) const
|
||||
{ return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::sgtree::count(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
size_type count(const KeyType& key, KeyValueCompare comp) const
|
||||
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::sgtree::lower_bound(const_reference)
|
||||
iterator lower_bound(const_reference value);
|
||||
|
||||
@@ -296,21 +302,29 @@ class sg_set_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::sgtree::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> equal_range(const_reference value);
|
||||
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::sgtree::equal_range(const KeyType&,KeyValueCompare)
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> equal_range(const_reference value)
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
|
||||
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::sgtree::equal_range(const_reference)const
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const_reference value) const;
|
||||
equal_range(const_reference value) const
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::sgtree::equal_range(const KeyType&,KeyValueCompare)const
|
||||
//! @copydoc ::boost::intrusive::rbtree::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;
|
||||
equal_range(const KeyType& key, KeyValueCompare comp) const
|
||||
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::sgtree::bounded_range(const_reference,const_reference,bool,bool)
|
||||
std::pair<iterator,iterator> bounded_range
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#define BOOST_INTRUSIVE_SGTREE_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
@@ -28,7 +29,6 @@
|
||||
#include <cstddef>
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/bs_set_hook.hpp>
|
||||
#include <boost/intrusive/bstree.hpp>
|
||||
#include <boost/intrusive/detail/tree_node.hpp>
|
||||
@@ -48,6 +48,12 @@ namespace intrusive {
|
||||
|
||||
namespace detail{
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Halpha for fixed floating_point<false> option
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
//! Returns floor(log2(n)/log2(sqrt(2))) -> floor(2*log2(n))
|
||||
//! Undefined if N is 0.
|
||||
//!
|
||||
@@ -55,7 +61,7 @@ namespace detail{
|
||||
inline std::size_t calculate_h_sqrt2 (std::size_t n)
|
||||
{
|
||||
std::size_t f_log2 = detail::floor_log2(n);
|
||||
return (2*f_log2) + (n >= detail::sqrt2_pow_2xplus1 (f_log2));
|
||||
return (2*f_log2) + static_cast<std::size_t>(n >= detail::sqrt2_pow_2xplus1(f_log2));
|
||||
}
|
||||
|
||||
struct h_alpha_sqrt2_t
|
||||
@@ -76,6 +82,12 @@ struct alpha_0_75_by_max_size_t
|
||||
}
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Halpha for fixed floating_point<true> option
|
||||
//
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
struct h_alpha_t
|
||||
{
|
||||
explicit h_alpha_t(float inv_minus_logalpha)
|
||||
@@ -84,9 +96,12 @@ struct h_alpha_t
|
||||
|
||||
std::size_t operator()(std::size_t n) const
|
||||
{
|
||||
//Returns floor(log2(1/alpha(n))) ->
|
||||
// floor(log2(n)/log(1/alpha)) ->
|
||||
// floor(log2(n)/(-log2(alpha)))
|
||||
////////////////////////////////////////////////////////////
|
||||
// This function must return "floor(log2(1/alpha(n)))" ->
|
||||
// floor(log2(n)/log(1/alpha)) ->
|
||||
// floor(log2(n)/-log2(alpha))
|
||||
// floor(log2(n)*(1/-log2(alpha)))
|
||||
////////////////////////////////////////////////////////////
|
||||
//return static_cast<std::size_t>(std::log(float(n))*inv_minus_logalpha_);
|
||||
return static_cast<std::size_t>(detail::fast_log2(float(n))*inv_minus_logalpha_);
|
||||
}
|
||||
@@ -119,7 +134,7 @@ struct alpha_holder
|
||||
typedef boost::intrusive::detail::alpha_by_max_size_t multiply_by_alpha_t;
|
||||
|
||||
alpha_holder() : max_tree_size_(0)
|
||||
{ set_alpha(0.7f); }
|
||||
{ set_alpha(0.70711f); } // ~1/sqrt(2)
|
||||
|
||||
float get_alpha() const
|
||||
{ return alpha_; }
|
||||
@@ -211,7 +226,6 @@ class sgtree_impl
|
||||
typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
|
||||
, true, SgTreeAlgorithms> tree_type;
|
||||
typedef tree_type implementation_defined;
|
||||
typedef typename tree_type::real_value_traits real_value_traits;
|
||||
|
||||
/// @endcond
|
||||
|
||||
@@ -248,11 +262,11 @@ class sgtree_impl
|
||||
typedef typename alpha_traits::multiply_by_alpha_t multiply_by_alpha_t;
|
||||
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(sgtree_impl)
|
||||
BOOST_STATIC_ASSERT(((int)real_value_traits::link_mode != (int)auto_unlink));
|
||||
BOOST_STATIC_ASSERT(((int)value_traits::link_mode != (int)auto_unlink));
|
||||
|
||||
enum { safemode_or_autounlink =
|
||||
(int)real_value_traits::link_mode == (int)auto_unlink ||
|
||||
(int)real_value_traits::link_mode == (int)safe_link };
|
||||
(int)value_traits::link_mode == (int)auto_unlink ||
|
||||
(int)value_traits::link_mode == (int)safe_link };
|
||||
|
||||
/// @endcond
|
||||
|
||||
@@ -397,9 +411,9 @@ class sgtree_impl
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
|
||||
iterator insert_equal(reference value)
|
||||
{
|
||||
detail::key_nodeptr_comp<value_compare, real_value_traits>
|
||||
key_node_comp(this->value_comp(), &this->get_real_value_traits());
|
||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
||||
detail::key_nodeptr_comp<value_compare, value_traits>
|
||||
key_node_comp(this->value_comp(), &this->get_value_traits());
|
||||
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||
if(safemode_or_autounlink)
|
||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
||||
@@ -408,15 +422,15 @@ class sgtree_impl
|
||||
, (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
|
||||
this->tree_type::sz_traits().increment();
|
||||
this->max_tree_size_ = (size_type)max_tree_size;
|
||||
return iterator(p, this->real_value_traits_ptr());
|
||||
return iterator(p, this->value_traits_ptr());
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_equal(const_iterator,reference)
|
||||
iterator insert_equal(const_iterator hint, reference value)
|
||||
{
|
||||
detail::key_nodeptr_comp<value_compare, real_value_traits>
|
||||
key_node_comp(this->value_comp(), &this->get_real_value_traits());
|
||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
||||
detail::key_nodeptr_comp<value_compare, value_traits>
|
||||
key_node_comp(this->value_comp(), &this->get_value_traits());
|
||||
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||
if(safemode_or_autounlink)
|
||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
||||
@@ -425,7 +439,7 @@ class sgtree_impl
|
||||
, (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size);
|
||||
this->tree_type::sz_traits().increment();
|
||||
this->max_tree_size_ = (size_type)max_tree_size;
|
||||
return iterator(p, this->real_value_traits_ptr());
|
||||
return iterator(p, this->value_traits_ptr());
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_equal(Iterator,Iterator)
|
||||
@@ -462,12 +476,12 @@ class sgtree_impl
|
||||
std::pair<iterator, bool> insert_unique_check
|
||||
(const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
|
||||
{
|
||||
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
|
||||
comp(key_value_comp, &this->get_real_value_traits());
|
||||
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
|
||||
comp(key_value_comp, &this->get_value_traits());
|
||||
std::pair<node_ptr, bool> ret =
|
||||
(node_algorithms::insert_unique_check
|
||||
(this->tree_type::header_ptr(), key, comp, commit_data));
|
||||
return std::pair<iterator, bool>(iterator(ret.first, this->real_value_traits_ptr()), ret.second);
|
||||
return std::pair<iterator, bool>(iterator(ret.first, this->value_traits_ptr()), ret.second);
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
|
||||
@@ -476,18 +490,18 @@ class sgtree_impl
|
||||
(const_iterator hint, const KeyType &key
|
||||
,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
|
||||
{
|
||||
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
|
||||
comp(key_value_comp, &this->get_real_value_traits());
|
||||
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
|
||||
comp(key_value_comp, &this->get_value_traits());
|
||||
std::pair<node_ptr, bool> ret =
|
||||
(node_algorithms::insert_unique_check
|
||||
(this->tree_type::header_ptr(), hint.pointed_node(), key, comp, commit_data));
|
||||
return std::pair<iterator, bool>(iterator(ret.first, this->real_value_traits_ptr()), ret.second);
|
||||
return std::pair<iterator, bool>(iterator(ret.first, this->value_traits_ptr()), ret.second);
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_unique_commit
|
||||
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
|
||||
{
|
||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
||||
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||
if(safemode_or_autounlink)
|
||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
||||
@@ -496,7 +510,7 @@ class sgtree_impl
|
||||
, (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size);
|
||||
this->tree_type::sz_traits().increment();
|
||||
this->max_tree_size_ = (size_type)max_tree_size;
|
||||
return iterator(to_insert, this->real_value_traits_ptr());
|
||||
return iterator(to_insert, this->value_traits_ptr());
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator)
|
||||
@@ -517,7 +531,7 @@ class sgtree_impl
|
||||
//! @copydoc ::boost::intrusive::bstree::insert_before
|
||||
iterator insert_before(const_iterator pos, reference value)
|
||||
{
|
||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
||||
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||
if(safemode_or_autounlink)
|
||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
||||
@@ -526,13 +540,13 @@ class sgtree_impl
|
||||
, (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
|
||||
this->tree_type::sz_traits().increment();
|
||||
this->max_tree_size_ = (size_type)max_tree_size;
|
||||
return iterator(p, this->real_value_traits_ptr());
|
||||
return iterator(p, this->value_traits_ptr());
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::push_back
|
||||
void push_back(reference value)
|
||||
{
|
||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
||||
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||
if(safemode_or_autounlink)
|
||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
||||
@@ -546,7 +560,7 @@ class sgtree_impl
|
||||
//! @copydoc ::boost::intrusive::bstree::push_front
|
||||
void push_front(reference value)
|
||||
{
|
||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
||||
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||
if(safemode_or_autounlink)
|
||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
|
||||
@@ -605,7 +619,7 @@ class sgtree_impl
|
||||
{
|
||||
node_ptr to_erase(i.pointed_node());
|
||||
iterator ret(this->erase(i));
|
||||
disposer(this->get_real_value_traits().to_value_ptr(to_erase));
|
||||
disposer(this->get_value_traits().to_value_ptr(to_erase));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -666,7 +680,7 @@ class sgtree_impl
|
||||
//! @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);
|
||||
|
||||
@@ -915,14 +929,13 @@ class sgtree
|
||||
public:
|
||||
typedef typename Base::value_compare value_compare;
|
||||
typedef typename Base::value_traits value_traits;
|
||||
typedef typename Base::real_value_traits real_value_traits;
|
||||
typedef typename Base::iterator iterator;
|
||||
typedef typename Base::const_iterator const_iterator;
|
||||
typedef typename Base::reverse_iterator reverse_iterator;
|
||||
typedef typename Base::const_reverse_iterator const_reverse_iterator;
|
||||
|
||||
//Assert if passed value traits are compatible with the type
|
||||
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
|
||||
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
|
||||
|
||||
explicit sgtree( const value_compare &cmp = value_compare()
|
||||
, const value_traits &v_traits = value_traits())
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
#define BOOST_INTRUSIVE_SGTREE_ALGORITHMS_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
#include <boost/intrusive/bstree_algorithms.hpp>
|
||||
@@ -187,6 +187,7 @@ class sgtree_algorithms
|
||||
//! @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)
|
||||
@@ -330,25 +331,21 @@ class sgtree_algorithms
|
||||
//than the weight balanced method.
|
||||
node_ptr s = x;
|
||||
std::size_t size = 1;
|
||||
for(std::size_t ancestor = 1; true; ++ancestor){
|
||||
if(ancestor == depth){ //Check if whole tree must be rebuilt
|
||||
max_tree_size = tree_size;
|
||||
bstree_algo::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_algo::subtree_size(s_sibling);
|
||||
s = s_parent;
|
||||
if(ancestor > h_alpha(size)){ //is 's' scapegoat?
|
||||
bstree_algo::rebalance_subtree(s);
|
||||
break;
|
||||
}
|
||||
for(std::size_t ancestor = 1; ancestor != depth; ++ancestor){
|
||||
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_algo::subtree_size(s_sibling);
|
||||
s = s_parent;
|
||||
if(ancestor > h_alpha(size)){ //is 's' scapegoat?
|
||||
bstree_algo::rebalance_subtree(s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
//The whole tree must be rebuilt
|
||||
max_tree_size = tree_size;
|
||||
bstree_algo::rebalance_subtree(NodeTraits::get_parent(s));
|
||||
}
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
@@ -80,7 +80,7 @@ struct make_slist_base_hook
|
||||
//! \c auto_unlink or \c safe_link).
|
||||
//!
|
||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||
//! and the the container configured to use this hook.
|
||||
//! and the container configured to use this hook.
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
@@ -203,7 +203,7 @@ struct make_slist_member_hook
|
||||
//! \c auto_unlink or \c safe_link).
|
||||
//!
|
||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||
//! and the the container configured to use this hook.
|
||||
//! and the container configured to use this hook.
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) || defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
template<class ...Options>
|
||||
#else
|
||||
|
||||
@@ -247,12 +247,18 @@ class splay_set_impl
|
||||
template<class Disposer>
|
||||
void clear_and_dispose(Disposer disposer);
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::count(const_reference)
|
||||
size_type count(const_reference value);
|
||||
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::count(const_reference)const
|
||||
size_type count(const_reference value) const
|
||||
{ return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::count(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count(const KeyType& key, KeyValueCompare comp);
|
||||
size_type count(const KeyType& key, KeyValueCompare comp) const
|
||||
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::count(const_reference)const
|
||||
size_type count(const_reference value) const;
|
||||
@@ -261,13 +267,6 @@ class splay_set_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::count_dont_splay(const_reference)const
|
||||
size_type count_dont_splay(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::count_dont_splay(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::lower_bound(const_reference)
|
||||
iterator lower_bound(const_reference value);
|
||||
|
||||
@@ -282,13 +281,6 @@ class splay_set_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::lower_bound_dont_splay(const_reference)const
|
||||
const_iterator lower_bound_dont_splay(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::lower_bound_dont_splay(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator lower_bound_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::upper_bound(const_reference)
|
||||
iterator upper_bound(const_reference value);
|
||||
|
||||
@@ -303,13 +295,6 @@ class splay_set_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::upper_bound_dont_splay(const_reference)const
|
||||
const_iterator upper_bound_dont_splay(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::upper_bound_dont_splay(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator upper_bound_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::find(const_reference)
|
||||
iterator find(const_reference value);
|
||||
|
||||
@@ -324,37 +309,29 @@ class splay_set_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::find_dont_splay(const_reference)const
|
||||
const_iterator find_dont_splay(const_reference value) const;
|
||||
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::find_dont_splay(const KeyType&,KeyValueCompare)const
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> equal_range(const_reference value)
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator find_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
|
||||
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> equal_range(const_reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::equal_range(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::equal_range(const_reference)const
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const_reference value) const;
|
||||
equal_range(const_reference value) const
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::equal_range(const KeyType&,KeyValueCompare)const
|
||||
//! @copydoc ::boost::intrusive::rbtree::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;
|
||||
equal_range(const KeyType& key, KeyValueCompare comp) const
|
||||
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::equal_range_dont_splay(const_reference)const
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range_dont_splay(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::equal_range_dont_splay(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::bounded_range(const_reference,const_reference,bool,bool)
|
||||
std::pair<iterator,iterator> bounded_range
|
||||
@@ -374,15 +351,6 @@ class splay_set_impl
|
||||
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::splaytree::bounded_range_dont_splay(const_reference,const_reference,bool,bool)const
|
||||
std::pair<const_iterator, const_iterator> bounded_range_dont_splay
|
||||
(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::bounded_range_dont_splay(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator> bounded_range_dont_splay
|
||||
(const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::s_iterator_to(reference)
|
||||
static iterator s_iterator_to(reference value);
|
||||
|
||||
@@ -760,20 +728,6 @@ class splay_multiset_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count(const KeyType& key, KeyValueCompare comp);
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::count(const_reference)const
|
||||
size_type count(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::count(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::count_dont_splay(const_reference)const
|
||||
size_type count_dont_splay(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::count_dont_splay(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::lower_bound(const_reference)
|
||||
iterator lower_bound(const_reference value);
|
||||
|
||||
@@ -788,13 +742,6 @@ class splay_multiset_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator lower_bound(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::lower_bound_dont_splay(const_reference)const
|
||||
const_iterator lower_bound_dont_splay(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::lower_bound_dont_splay(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator lower_bound_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::upper_bound(const_reference)
|
||||
iterator upper_bound(const_reference value);
|
||||
|
||||
@@ -809,13 +756,6 @@ class splay_multiset_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator upper_bound(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::upper_bound_dont_splay(const_reference)const
|
||||
const_iterator upper_bound_dont_splay(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::upper_bound_dont_splay(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator upper_bound_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::find(const_reference)
|
||||
iterator find(const_reference value);
|
||||
|
||||
@@ -830,13 +770,6 @@ class splay_multiset_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::find_dont_splay(const_reference)const
|
||||
const_iterator find_dont_splay(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::find_dont_splay(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator find_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> equal_range(const_reference value);
|
||||
|
||||
@@ -853,15 +786,6 @@ class splay_multiset_impl
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::equal_range_dont_splay(const_reference)const
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range_dont_splay(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::equal_range_dont_splay(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range_dont_splay(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::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);
|
||||
@@ -880,15 +804,6 @@ class splay_multiset_impl
|
||||
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::splaytree::bounded_range_dont_splay(const_reference,const_reference,bool,bool)const
|
||||
std::pair<const_iterator, const_iterator> bounded_range_dont_splay
|
||||
(const_reference lower_value, const_reference upper_value, bool left_closed, bool right_closed) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::bounded_range_dont_splay(const KeyType&,const KeyType&,KeyValueCompare,bool,bool)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator> bounded_range_dont_splay
|
||||
(const KeyType& lower_key, const KeyType& upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::splaytree::s_iterator_to(reference)
|
||||
static iterator s_iterator_to(reference value);
|
||||
|
||||
|
||||
@@ -1,286 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Olaf Krzikalla 2004-2006.
|
||||
// (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
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// See http://www.boost.org/libs/intrusive for documentation.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_INTRUSIVE_SPLAY_SET_HOOK_HPP
|
||||
#define BOOST_INTRUSIVE_SPLAY_SET_HOOK_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/bs_set_hook.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace intrusive {
|
||||
|
||||
//! 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 = 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 make_bs_set_base_hook
|
||||
<
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3
|
||||
#else
|
||||
Options...
|
||||
#endif
|
||||
>::type implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
};
|
||||
|
||||
//! Derive a class from splay_set_base_hook in order to store objects in
|
||||
//! in a splay_set/splay_multiset. splay_set_base_hook holds the data necessary to maintain
|
||||
//! the splay_set/splay_multiset and provides an appropriate value_traits class for splay_set/splay_multiset.
|
||||
//!
|
||||
//! The hook admits the following options: \c tag<>, \c void_pointer<>,
|
||||
//! \c link_mode<> and \c optimize_size<>.
|
||||
//!
|
||||
//! \c tag<> defines a tag to identify the node.
|
||||
//! The same tag value can be used in different classes, but if a class is
|
||||
//! derived from more than one \c list_base_hook, then each \c list_base_hook needs its
|
||||
//! unique tag.
|
||||
//!
|
||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||
//! and the the container configured to use this 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
|
||||
template<class O1, class O2, class O3>
|
||||
#endif
|
||||
class splay_set_base_hook
|
||||
: public make_splay_set_base_hook<
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3
|
||||
#else
|
||||
Options...
|
||||
#endif
|
||||
>::type
|
||||
{
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
public:
|
||||
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
|
||||
//! initializes the node to an unlinked state.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
splay_set_base_hook();
|
||||
|
||||
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
|
||||
//! initializes the node to an unlinked state. The argument is ignored.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Rationale</b>: Providing a copy-constructor
|
||||
//! makes classes using the hook STL-compliant without forcing the
|
||||
//! user to do some additional work. \c swap can be used to emulate
|
||||
//! move-semantics.
|
||||
splay_set_base_hook(const splay_set_base_hook& );
|
||||
|
||||
//! <b>Effects</b>: Empty function. The argument is ignored.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Rationale</b>: Providing an assignment operator
|
||||
//! makes classes using the hook STL-compliant without forcing the
|
||||
//! user to do some additional work. \c swap can be used to emulate
|
||||
//! move-semantics.
|
||||
splay_set_base_hook& operator=(const splay_set_base_hook& );
|
||||
|
||||
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
|
||||
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
|
||||
//! object is stored in a set an assertion is raised. If link_mode is
|
||||
//! \c auto_unlink and \c is_linked() is true, the node is unlinked.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
~splay_set_base_hook();
|
||||
|
||||
//! <b>Effects</b>: Swapping two nodes swaps the position of the elements
|
||||
//! related to those nodes in one or two containers. That is, if the node
|
||||
//! this is part of the element e1, the node x is part of the element e2
|
||||
//! and both elements are included in the containers s1 and s2, then after
|
||||
//! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
|
||||
//! at the position of e1. If one element is not in a container, then
|
||||
//! after the swap-operation the other element is not in a container.
|
||||
//! Iterators to e1 and e2 related to those nodes are invalidated.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
void swap_nodes(splay_set_base_hook &other);
|
||||
|
||||
//! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
|
||||
//!
|
||||
//! <b>Returns</b>: true, if the node belongs to a container, false
|
||||
//! otherwise. This function can be used to test whether \c set::iterator_to
|
||||
//! will return a valid iterator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant
|
||||
bool is_linked() const;
|
||||
|
||||
//! <b>Effects</b>: Removes the node if it's inserted in a container.
|
||||
//! This function is only allowed if link_mode is \c auto_unlink.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
void unlink();
|
||||
#endif
|
||||
};
|
||||
|
||||
//! 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 = 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 make_bs_set_member_hook
|
||||
<
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3
|
||||
#else
|
||||
Options...
|
||||
#endif
|
||||
>::type implementation_defined;
|
||||
/// @endcond
|
||||
typedef implementation_defined type;
|
||||
};
|
||||
|
||||
//! Put a public data member splay_set_member_hook in order to store objects of this
|
||||
//! class in a splay_set/splay_multiset. splay_set_member_hook holds the data
|
||||
//! necessary for maintaining the splay_set/splay_multiset and provides an appropriate
|
||||
//! value_traits class for splay_set/splay_multiset.
|
||||
//!
|
||||
//! The hook admits the following options: \c void_pointer<>,
|
||||
//! \c link_mode<> and \c optimize_size<>.
|
||||
//!
|
||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||
//! and the the container configured to use this 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
|
||||
template<class O1, class O2, class O3>
|
||||
#endif
|
||||
class splay_set_member_hook
|
||||
: public make_splay_set_member_hook<
|
||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||
O1, O2, O3
|
||||
#else
|
||||
Options...
|
||||
#endif
|
||||
>::type
|
||||
{
|
||||
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
|
||||
public:
|
||||
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
|
||||
//! initializes the node to an unlinked state.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
splay_set_member_hook();
|
||||
|
||||
//! <b>Effects</b>: If link_mode is \c auto_unlink or \c safe_link
|
||||
//! initializes the node to an unlinked state. The argument is ignored.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Rationale</b>: Providing a copy-constructor
|
||||
//! makes classes using the hook STL-compliant without forcing the
|
||||
//! user to do some additional work. \c swap can be used to emulate
|
||||
//! move-semantics.
|
||||
splay_set_member_hook(const splay_set_member_hook& );
|
||||
|
||||
//! <b>Effects</b>: Empty function. The argument is ignored.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
//!
|
||||
//! <b>Rationale</b>: Providing an assignment operator
|
||||
//! makes classes using the hook STL-compliant without forcing the
|
||||
//! user to do some additional work. \c swap can be used to emulate
|
||||
//! move-semantics.
|
||||
splay_set_member_hook& operator=(const splay_set_member_hook& );
|
||||
|
||||
//! <b>Effects</b>: If link_mode is \c normal_link, the destructor does
|
||||
//! nothing (ie. no code is generated). If link_mode is \c safe_link and the
|
||||
//! object is stored in a set an assertion is raised. If link_mode is
|
||||
//! \c auto_unlink and \c is_linked() is true, the node is unlinked.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
~splay_set_member_hook();
|
||||
|
||||
//! <b>Effects</b>: Swapping two nodes swaps the position of the elements
|
||||
//! related to those nodes in one or two containers. That is, if the node
|
||||
//! this is part of the element e1, the node x is part of the element e2
|
||||
//! and both elements are included in the containers s1 and s2, then after
|
||||
//! the swap-operation e1 is in s2 at the position of e2 and e2 is in s1
|
||||
//! at the position of e1. If one element is not in a container, then
|
||||
//! after the swap-operation the other element is not in a container.
|
||||
//! Iterators to e1 and e2 related to those nodes are invalidated.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
void swap_nodes(splay_set_member_hook &other);
|
||||
|
||||
//! <b>Precondition</b>: link_mode must be \c safe_link or \c auto_unlink.
|
||||
//!
|
||||
//! <b>Returns</b>: true, if the node belongs to a container, false
|
||||
//! otherwise. This function can be used to test whether \c set::iterator_to
|
||||
//! will return a valid iterator.
|
||||
//!
|
||||
//! <b>Complexity</b>: Constant
|
||||
bool is_linked() const;
|
||||
|
||||
//! <b>Effects</b>: Removes the node if it's inserted in a container.
|
||||
//! This function is only allowed if link_mode is \c auto_unlink.
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
void unlink();
|
||||
#endif
|
||||
};
|
||||
|
||||
} //namespace intrusive
|
||||
} //namespace boost
|
||||
|
||||
#include <boost/intrusive/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTRUSIVE_SPLAY_SET_HOOK_HPP
|
||||
@@ -13,6 +13,7 @@
|
||||
#define BOOST_INTRUSIVE_SPLAYTREE_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
@@ -20,8 +21,6 @@
|
||||
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/splay_set_hook.hpp>
|
||||
#include <boost/intrusive/bstree.hpp>
|
||||
#include <boost/intrusive/detail/tree_node.hpp>
|
||||
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
|
||||
@@ -77,7 +76,6 @@ class splaytree_impl
|
||||
/// @cond
|
||||
typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
|
||||
, ConstantTimeSize, SplayTreeAlgorithms> tree_type;
|
||||
typedef typename tree_type::real_value_traits real_value_traits;
|
||||
typedef tree_type implementation_defined;
|
||||
/// @endcond
|
||||
|
||||
@@ -267,7 +265,6 @@ class splaytree_impl
|
||||
|
||||
//! @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)
|
||||
@@ -293,60 +290,32 @@ class splaytree_impl
|
||||
template<class Disposer>
|
||||
void clear_and_dispose(Disposer disposer);
|
||||
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::count(const_reference)const
|
||||
//! Additional note: non-const function, splaying is performed for the first
|
||||
//! element of the equal range of "value"
|
||||
size_type count(const_reference value)
|
||||
{ return this->count(value, this->value_comp()); }
|
||||
//! Additional note: non-const function, splaying is performed.
|
||||
size_type count(const_reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
||||
//! Additional note: non-const function, splaying is performed for the first
|
||||
//! element of the equal range of "key"
|
||||
//! Additional note: non-const function, splaying is performed.
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count(const KeyType &key, KeyValueCompare comp)
|
||||
{
|
||||
std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
|
||||
return std::distance(ret.first, ret.second);
|
||||
}
|
||||
size_type count(const KeyType &key, KeyValueCompare comp);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::count(const_reference)const
|
||||
//! Additional note: Deprecated function, use count const overload instead.
|
||||
size_type count(const_reference value) const
|
||||
{ return tree_type::count(value); }
|
||||
//! Additional note: const function, no splaying is performed
|
||||
size_type count(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
||||
//! Additional note: Deprecated function, use count const overload instead.
|
||||
//! Additional note: const function, no splaying is performed
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count(const KeyType &key, KeyValueCompare comp) const
|
||||
{ return tree_type::count(key, comp); }
|
||||
size_type count(const KeyType &key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::count(const_reference)const
|
||||
//! Additional note: Deprecated function, use count const overload instead.
|
||||
size_type count_dont_splay(const_reference value) const
|
||||
{ return tree_type::count(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::count(const KeyType&,KeyValueCompare)const
|
||||
//! Additional note: Deprecated function, use count const overload instead.
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count_dont_splay(const KeyType &key, KeyValueCompare comp) const
|
||||
{ return tree_type::count(key, comp); }
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)
|
||||
//! Additional note: non-const function, splaying is performed for the first
|
||||
//! element of the equal range of "value"
|
||||
//! Additional note: non-const function, splaying is performed.
|
||||
iterator lower_bound(const_reference value);
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
|
||||
//! Additional note: const function, no splaying is performed
|
||||
const_iterator lower_bound(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const_reference)const
|
||||
//! Additional note: Deprecated function, use lower_bound const overload instead.
|
||||
const_iterator lower_bound_dont_splay(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
|
||||
//! Additional note: non-const function, splaying is performed for the first
|
||||
//! element of the equal range of "key"
|
||||
@@ -358,11 +327,6 @@ class splaytree_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::lower_bound(const KeyType&,KeyValueCompare)
|
||||
//! Additional note: Deprecated function, use lower_bound const overload instead.
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
iterator lower_bound_dont_splay(const KeyType &key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)
|
||||
//! Additional note: non-const function, splaying is performed for the first
|
||||
//! element of the equal range of "value"
|
||||
@@ -372,10 +336,6 @@ class splaytree_impl
|
||||
//! Additional note: const function, no splaying is performed
|
||||
const_iterator upper_bound(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::upper_bound(const_reference)const
|
||||
//! Additional note: Deprecated function, use upper_bound const overload instead.
|
||||
const_iterator upper_bound_dont_splay(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
|
||||
//! Additional note: non-const function, splaying is performed for the first
|
||||
//! element of the equal range of "key"
|
||||
@@ -387,11 +347,6 @@ class splaytree_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::upper_bound(const KeyType&,KeyValueCompare)
|
||||
//! Additional note: Deprecated function, use upper_bound const overload instead.
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator upper_bound_dont_splay(const KeyType &key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::find(const_reference)
|
||||
//! Additional note: non-const function, splaying is performed for the first
|
||||
//! element of the equal range of "value"
|
||||
@@ -401,10 +356,6 @@ class splaytree_impl
|
||||
//! Additional note: const function, no splaying is performed
|
||||
const_iterator find(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::find(const_reference)const
|
||||
//! Additional note: Deprecated function, use find const overload instead.
|
||||
const_iterator find_dont_splay(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)
|
||||
//! Additional note: non-const function, splaying is performed for the first
|
||||
//! element of the equal range of "key"
|
||||
@@ -416,11 +367,6 @@ class splaytree_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator find(const KeyType &key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::find(const KeyType&,KeyValueCompare)const
|
||||
//! Additional note: Deprecated function, use find const overload instead.
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator find_dont_splay(const KeyType &key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)
|
||||
//! Additional note: non-const function, splaying is performed for the first
|
||||
//! element of the equal range of "value"
|
||||
@@ -430,10 +376,6 @@ class splaytree_impl
|
||||
//! Additional note: const function, no splaying is performed
|
||||
std::pair<const_iterator, const_iterator> equal_range(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const_reference)const
|
||||
//! Additional note: Deprecated function, use equal_range const overload instead.
|
||||
std::pair<const_iterator, const_iterator> equal_range_dont_splay(const_reference value) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
|
||||
//! Additional note: non-const function, splaying is performed for the first
|
||||
//! element of the equal range of "key"
|
||||
@@ -445,11 +387,6 @@ class splaytree_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator> equal_range(const KeyType &key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree::equal_range(const KeyType&,KeyValueCompare)
|
||||
//! Additional note: Deprecated function, use equal_range const overload instead.
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator> equal_range_dont_splay(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);
|
||||
@@ -468,17 +405,6 @@ class splaytree_impl
|
||||
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::bounded_range(const_reference,const_reference,bool,bool)const
|
||||
//! Additional note: Deprecated function, use bounded_range const overload instead.
|
||||
std::pair<const_iterator, const_iterator> bounded_range_dont_splay
|
||||
(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
|
||||
//! Additional note: Deprecated function, use bounded_range const overload instead.
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<const_iterator, const_iterator> bounded_range_dont_splay
|
||||
(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);
|
||||
|
||||
@@ -529,10 +455,10 @@ class splaytree_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
iterator splay_down(const KeyType &key, KeyValueCompare comp)
|
||||
{
|
||||
detail::key_nodeptr_comp<value_compare, real_value_traits>
|
||||
key_node_comp(comp, &this->get_real_value_traits());
|
||||
detail::key_nodeptr_comp<value_compare, value_traits>
|
||||
key_node_comp(comp, &this->get_value_traits());
|
||||
node_ptr r = node_algorithms::splay_down(tree_type::header_ptr(), key, key_node_comp);
|
||||
return iterator(r, this->real_value_traits_ptr());
|
||||
return iterator(r, this->value_traits_ptr());
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Rearranges the container so that if *this stores an element
|
||||
@@ -644,14 +570,13 @@ class splaytree
|
||||
public:
|
||||
typedef typename Base::value_compare value_compare;
|
||||
typedef typename Base::value_traits value_traits;
|
||||
typedef typename Base::real_value_traits real_value_traits;
|
||||
typedef typename Base::iterator iterator;
|
||||
typedef typename Base::const_iterator const_iterator;
|
||||
typedef typename Base::reverse_iterator reverse_iterator;
|
||||
typedef typename Base::const_reverse_iterator const_reverse_iterator;
|
||||
|
||||
//Assert if passed value traits are compatible with the type
|
||||
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
|
||||
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
|
||||
|
||||
explicit splaytree( const value_compare &cmp = value_compare()
|
||||
, const value_traits &v_traits = value_traits())
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
#define BOOST_INTRUSIVE_SPLAYTREE_ALGORITHMS_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
#include <cstddef>
|
||||
#include <boost/intrusive/detail/utilities.hpp>
|
||||
@@ -45,33 +45,70 @@ namespace intrusive {
|
||||
namespace detail {
|
||||
|
||||
template<class NodeTraits>
|
||||
struct splaydown_rollback
|
||||
struct splaydown_assemble_and_fix_header
|
||||
{
|
||||
typedef typename NodeTraits::node_ptr node_ptr;
|
||||
splaydown_rollback( const node_ptr *pcur_subtree, const node_ptr & header
|
||||
, const node_ptr & leftmost , const node_ptr & rightmost)
|
||||
: pcur_subtree_(pcur_subtree) , header_(header)
|
||||
, leftmost_(leftmost) , rightmost_(rightmost)
|
||||
|
||||
splaydown_assemble_and_fix_header(const node_ptr & t, const node_ptr & header, const node_ptr &leftmost, const node_ptr &rightmost)
|
||||
: t_(t)
|
||||
, null_node_(header)
|
||||
, l_(null_node_)
|
||||
, r_(null_node_)
|
||||
, leftmost_(leftmost)
|
||||
, rightmost_(rightmost)
|
||||
{}
|
||||
|
||||
void release()
|
||||
{ pcur_subtree_ = 0; }
|
||||
|
||||
~splaydown_rollback()
|
||||
~splaydown_assemble_and_fix_header()
|
||||
{
|
||||
if(pcur_subtree_){
|
||||
//Exception can only be thrown by comp, but
|
||||
//tree invariants still hold. *pcur_subtree is the current root
|
||||
//so link it to the header.
|
||||
NodeTraits::set_parent(*pcur_subtree_, header_);
|
||||
NodeTraits::set_parent(header_, *pcur_subtree_);
|
||||
//Recover leftmost/rightmost pointers
|
||||
NodeTraits::set_left (header_, leftmost_);
|
||||
NodeTraits::set_right(header_, rightmost_);
|
||||
this->assemble();
|
||||
|
||||
//Now recover the original header except for the
|
||||
//splayed root node.
|
||||
//"t_" is the current root and "null_node_" is the header node
|
||||
NodeTraits::set_parent(null_node_, t_);
|
||||
NodeTraits::set_parent(t_, null_node_);
|
||||
//Recover leftmost/rightmost pointers
|
||||
NodeTraits::set_left (null_node_, leftmost_);
|
||||
NodeTraits::set_right(null_node_, rightmost_);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void assemble()
|
||||
{
|
||||
//procedure assemble;
|
||||
// left(r), right(l) := right(t), left(t);
|
||||
// left(t), right(t) := right(null), left(null);
|
||||
//end assemble;
|
||||
{ // left(r), right(l) := right(t), left(t);
|
||||
|
||||
node_ptr const old_t_left = NodeTraits::get_left(t_);
|
||||
node_ptr const old_t_right = NodeTraits::get_right(t_);
|
||||
NodeTraits::set_right(l_, old_t_left);
|
||||
NodeTraits::set_left (r_, old_t_right);
|
||||
if(old_t_left){
|
||||
NodeTraits::set_parent(old_t_left, l_);
|
||||
}
|
||||
if(old_t_right){
|
||||
NodeTraits::set_parent(old_t_right, r_);
|
||||
}
|
||||
}
|
||||
{ // left(t), right(t) := right(null), left(null);
|
||||
node_ptr const null_right = NodeTraits::get_right(null_node_);
|
||||
node_ptr const null_left = NodeTraits::get_left(null_node_);
|
||||
NodeTraits::set_left (t_, null_right);
|
||||
NodeTraits::set_right(t_, null_left);
|
||||
if(null_right){
|
||||
NodeTraits::set_parent(null_right, t_);
|
||||
}
|
||||
if(null_left){
|
||||
NodeTraits::set_parent(null_left, t_);
|
||||
}
|
||||
}
|
||||
}
|
||||
const node_ptr *pcur_subtree_;
|
||||
node_ptr header_, leftmost_, rightmost_;
|
||||
|
||||
public:
|
||||
node_ptr t_, null_node_, l_, r_, leftmost_, rightmost_;
|
||||
};
|
||||
|
||||
} //namespace detail {
|
||||
@@ -184,32 +221,28 @@ class splaytree_algorithms
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::erase(const node_ptr&,const node_ptr&)
|
||||
//! Additional notes: the previous node of z is splayed. The "splay" parameter which indicated if splaying
|
||||
//! should be performed, it's deprecated and will disappear in future versions.
|
||||
static void erase(const node_ptr & header, const node_ptr & z, bool splay = true)
|
||||
//! Additional notes: the previous node of z is splayed to speed up range deletions.
|
||||
static void erase(const node_ptr & header, const node_ptr & z)
|
||||
{
|
||||
//posibility 1
|
||||
if(splay && NodeTraits::get_left(z)){
|
||||
if(NodeTraits::get_left(z)){
|
||||
splay_up(bstree_algo::prev_node(z), header);
|
||||
}
|
||||
/*
|
||||
//possibility 2
|
||||
if(splay && NodeTraits::get_left(z)){
|
||||
if(NodeTraits::get_left(z)){
|
||||
node_ptr l = NodeTraits::get_left(z);
|
||||
splay_up(l, header);
|
||||
}*//*
|
||||
if(splay && NodeTraits::get_left(z)){
|
||||
}*/
|
||||
/*
|
||||
if(NodeTraits::get_left(z)){
|
||||
node_ptr l = bstree_algo::prev_node(z);
|
||||
splay_up_impl(l, z);
|
||||
}*/
|
||||
/*
|
||||
//possibility 4
|
||||
if(splay){
|
||||
splay_up(z, header);
|
||||
}*/
|
||||
|
||||
//if(splay)
|
||||
//splay_up(z, header);
|
||||
splay_up(z, header);
|
||||
*/
|
||||
bstree_algo::erase(header, z);
|
||||
}
|
||||
|
||||
@@ -225,7 +258,7 @@ class splaytree_algorithms
|
||||
|
||||
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::count(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
//! Additional notes: the first node of the range is splayed.
|
||||
//! Additional notes: an element with key `key` is splayed.
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::size_t count
|
||||
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
@@ -247,15 +280,14 @@ class splaytree_algorithms
|
||||
{ return bstree_algo::count(header, key, comp); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
//! Additional notes: the first node of the range is splayed. The "splay" parameter which indicated if splaying
|
||||
//! should be performed, it's deprecated and will disappear in future versions.
|
||||
//! Additional notes: the first node of the range is splayed.
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr lower_bound
|
||||
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true)
|
||||
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{
|
||||
//splay_down(detail::uncast(header), key, comp);
|
||||
splay_down(detail::uncast(header), key, comp);
|
||||
node_ptr y = bstree_algo::lower_bound(header, key, comp);
|
||||
if(splay) splay_up(y, detail::uncast(header));
|
||||
//splay_up(y, detail::uncast(header));
|
||||
return y;
|
||||
}
|
||||
|
||||
@@ -267,15 +299,14 @@ class splaytree_algorithms
|
||||
{ return bstree_algo::lower_bound(header, key, comp); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::upper_bound(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
//! Additional notes: the first node of the range is splayed. The "splay" parameter which indicated if splaying
|
||||
//! should be performed, it's deprecated and will disappear in future versions.
|
||||
//! Additional notes: the first node of the range is splayed.
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr upper_bound
|
||||
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true)
|
||||
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{
|
||||
//splay_down(detail::uncast(header), key, comp);
|
||||
splay_down(detail::uncast(header), key, comp);
|
||||
node_ptr y = bstree_algo::upper_bound(header, key, comp);
|
||||
if(splay) splay_up(y, detail::uncast(header));
|
||||
//splay_up(y, detail::uncast(header));
|
||||
return y;
|
||||
}
|
||||
|
||||
@@ -287,17 +318,13 @@ class splaytree_algorithms
|
||||
{ return bstree_algo::upper_bound(header, key, comp); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare)
|
||||
//! Additional notes: the found node of the lower bound is splayed. The "splay" parameter which indicated if splaying
|
||||
//! should be performed, it's deprecated and will disappear in future versions.
|
||||
//! Additional notes: the found node of the lower bound is splayed.
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr find
|
||||
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true)
|
||||
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{
|
||||
if(splay) splay_down(detail::uncast(header), key, comp);
|
||||
node_ptr end = detail::uncast(header);
|
||||
node_ptr y = bstree_algo::lower_bound(header, key, comp);
|
||||
node_ptr r = (y == end || comp(key, y)) ? end : y;
|
||||
return r;
|
||||
splay_down(detail::uncast(header), key, comp);
|
||||
return bstree_algo::find(header, key, comp);
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::find(const const_node_ptr&, const KeyType&,KeyNodePtrCompare)
|
||||
@@ -308,15 +335,14 @@ class splaytree_algorithms
|
||||
{ return bstree_algo::find(header, key, comp); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::equal_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
//! Additional notes: the first node of the range is splayed. The "splay" parameter which indicated if splaying
|
||||
//! should be performed, it's deprecated and will disappear in future versions.
|
||||
//! Additional notes: the first node of the range is splayed.
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, node_ptr> equal_range
|
||||
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true)
|
||||
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{
|
||||
//splay_down(detail::uncast(header), key, comp);
|
||||
splay_down(detail::uncast(header), key, comp);
|
||||
std::pair<node_ptr, node_ptr> ret = bstree_algo::equal_range(header, key, comp);
|
||||
if(splay) splay_up(ret.first, detail::uncast(header));
|
||||
//splay_up(ret.first, detail::uncast(header));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -327,17 +353,36 @@ class splaytree_algorithms
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return bstree_algo::equal_range(header, key, comp); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
//! Additional notes: the first node of the range is splayed.
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, node_ptr> lower_bound_range
|
||||
(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{
|
||||
splay_down(detail::uncast(header), key, comp);
|
||||
std::pair<node_ptr, node_ptr> ret = bstree_algo::lower_bound_range(header, key, comp);
|
||||
//splay_up(ret.first, detail::uncast(header));
|
||||
return ret;
|
||||
}
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::lower_bound_range(const const_node_ptr&,const KeyType&,KeyNodePtrCompare)
|
||||
//! Additional note: no splaying is performed
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, node_ptr> lower_bound_range
|
||||
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
{ return bstree_algo::lower_bound_range(header, key, comp); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::bstree_algorithms::bounded_range(const const_node_ptr&,const KeyType&,const KeyType&,KeyNodePtrCompare,bool,bool)
|
||||
//! Additional notes: the first node of the range is splayed. The "splay" parameter which indicated if splaying
|
||||
//! should be performed, it's deprecated and will disappear in future versions.
|
||||
//! Additional notes: the first node of the range is splayed.
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static std::pair<node_ptr, node_ptr> bounded_range
|
||||
(const node_ptr & header, const KeyType &lower_key, const KeyType &upper_key, KeyNodePtrCompare comp
|
||||
, bool left_closed, bool right_closed, bool splay = true)
|
||||
, bool left_closed, bool right_closed)
|
||||
{
|
||||
splay_down(detail::uncast(header), lower_key, comp);
|
||||
std::pair<node_ptr, node_ptr> ret =
|
||||
bstree_algo::bounded_range(header, lower_key, upper_key, comp, left_closed, right_closed);
|
||||
if(splay) splay_up(ret.first, detail::uncast(header));
|
||||
//splay_up(ret.first, detail::uncast(header));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -445,6 +490,20 @@ class splaytree_algorithms
|
||||
|
||||
// bottom-up splay, use data_ as parent for n | complexity : logarithmic | exception : nothrow
|
||||
static void splay_up(const node_ptr & node, const node_ptr & header)
|
||||
{ priv_splay_up<true>(node, header); }
|
||||
|
||||
// top-down splay | complexity : logarithmic | exception : strong, note A
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr splay_down(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool *pfound = 0)
|
||||
{ return priv_splay_down<true>(header, key, comp, pfound); }
|
||||
|
||||
private:
|
||||
|
||||
/// @cond
|
||||
|
||||
// bottom-up splay, use data_ as parent for n | complexity : logarithmic | exception : nothrow
|
||||
template<bool SimpleSplay>
|
||||
static void priv_splay_up(const node_ptr & node, const node_ptr & header)
|
||||
{
|
||||
// If (node == header) do a splay for the right most node instead
|
||||
// this is to boost performance of equal_range/count on equivalent containers in the case
|
||||
@@ -470,20 +529,19 @@ class splaytree_algorithms
|
||||
rotate(p);
|
||||
rotate(n);
|
||||
}
|
||||
else{
|
||||
else {
|
||||
// zig-zag
|
||||
rotate(n);
|
||||
rotate(n);
|
||||
if(!SimpleSplay){
|
||||
rotate(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// top-down splay | complexity : logarithmic | exception : strong, note A
|
||||
template<class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr splay_down(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
|
||||
template<bool SimpleSplay, class KeyType, class KeyNodePtrCompare>
|
||||
static node_ptr priv_splay_down(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool *pfound = 0)
|
||||
{
|
||||
if(!NodeTraits::get_parent(header))
|
||||
return header;
|
||||
//Most splay tree implementations use a dummy/null node to implement.
|
||||
//this function. This has some problems for a generic library like Intrusive:
|
||||
//
|
||||
@@ -494,118 +552,87 @@ class splaytree_algorithms
|
||||
//are not changed when splaying (because the invariants of the tree don't
|
||||
//change) We can back up them, use the header as the null node and
|
||||
//reassign old values after the function has been completed.
|
||||
node_ptr t = NodeTraits::get_parent(header);
|
||||
//Check if tree has a single node
|
||||
if(!NodeTraits::get_left(t) && !NodeTraits::get_right(t))
|
||||
return t;
|
||||
//Backup leftmost/rightmost
|
||||
node_ptr leftmost (NodeTraits::get_left(header));
|
||||
node_ptr rightmost(NodeTraits::get_right(header));
|
||||
{
|
||||
//Anti-exception rollback, recovers the original header node if an exception is thrown.
|
||||
detail::splaydown_rollback<NodeTraits> rollback(&t, header, leftmost, rightmost);
|
||||
node_ptr null_node = header;
|
||||
node_ptr l = null_node;
|
||||
node_ptr r = null_node;
|
||||
node_ptr const old_root = NodeTraits::get_parent(header);
|
||||
node_ptr const leftmost = NodeTraits::get_left(header);
|
||||
node_ptr const rightmost = NodeTraits::get_right(header);
|
||||
if(leftmost == rightmost){ //Empty or unique node
|
||||
if(pfound){
|
||||
*pfound = old_root && !comp(key, old_root) && !comp(old_root, key);
|
||||
}
|
||||
return old_root ? old_root : header;
|
||||
}
|
||||
else{
|
||||
//Initialize "null node" (the header in our case)
|
||||
NodeTraits::set_left (header, node_ptr());
|
||||
NodeTraits::set_right(header, node_ptr());
|
||||
//Class that will backup leftmost/rightmost from header, commit the assemble(),
|
||||
//and will restore leftmost/rightmost to header even if "comp" throws
|
||||
detail::splaydown_assemble_and_fix_header<NodeTraits> commit(old_root, header, leftmost, rightmost);
|
||||
bool found = false;
|
||||
|
||||
for( ;; ){
|
||||
if(comp(key, t)){
|
||||
if(NodeTraits::get_left(t) == node_ptr() )
|
||||
if(comp(key, commit.t_)){
|
||||
node_ptr const t_left = NodeTraits::get_left(commit.t_);
|
||||
if(!t_left)
|
||||
break;
|
||||
if(comp(key, NodeTraits::get_left(t))){
|
||||
t = bstree_algo::rotate_right(t);
|
||||
|
||||
if(NodeTraits::get_left(t) == node_ptr())
|
||||
if(comp(key, t_left)){
|
||||
bstree_algo::rotate_right_no_parent_fix(commit.t_, t_left);
|
||||
commit.t_ = t_left;
|
||||
if( !NodeTraits::get_left(commit.t_) )
|
||||
break;
|
||||
link_right(t, r);
|
||||
}
|
||||
else if(comp(NodeTraits::get_left(t), key)){
|
||||
link_right(t, r);
|
||||
|
||||
if(NodeTraits::get_right(t) == node_ptr() )
|
||||
break;
|
||||
link_left(t, l);
|
||||
link_right(commit.t_, commit.r_);
|
||||
}
|
||||
else{
|
||||
link_right(t, r);
|
||||
link_right(commit.t_, commit.r_);
|
||||
if(!SimpleSplay && comp(t_left, key)){
|
||||
if( !NodeTraits::get_right(commit.t_) )
|
||||
break;
|
||||
link_left(commit.t_, commit.l_);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(comp(t, key)){
|
||||
if(NodeTraits::get_right(t) == node_ptr() )
|
||||
else if(comp(commit.t_, key)){
|
||||
node_ptr const t_right = NodeTraits::get_right(commit.t_);
|
||||
if(!t_right)
|
||||
break;
|
||||
|
||||
if(comp(NodeTraits::get_right(t), key)){
|
||||
t = bstree_algo::rotate_left( t );
|
||||
|
||||
if(NodeTraits::get_right(t) == node_ptr() )
|
||||
if(comp(t_right, key)){
|
||||
bstree_algo::rotate_left_no_parent_fix(commit.t_, t_right);
|
||||
commit.t_ = t_right;
|
||||
if( !NodeTraits::get_right(commit.t_) )
|
||||
break;
|
||||
link_left(t, l);
|
||||
}
|
||||
else if(comp(key, NodeTraits::get_right(t))){
|
||||
link_left(t, l);
|
||||
|
||||
if(NodeTraits::get_left(t) == node_ptr())
|
||||
break;
|
||||
|
||||
link_right(t, r);
|
||||
link_left(commit.t_, commit.l_);
|
||||
}
|
||||
else{
|
||||
link_left(t, l);
|
||||
link_left(commit.t_, commit.l_);
|
||||
if(!SimpleSplay && comp(key, t_right)){
|
||||
if( !NodeTraits::get_left(commit.t_) )
|
||||
break;
|
||||
link_right(commit.t_, commit.r_);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assemble(t, l, r, null_node);
|
||||
rollback.release();
|
||||
}
|
||||
|
||||
//Now recover the original header except for the
|
||||
//splayed root node.
|
||||
//t is the current root
|
||||
NodeTraits::set_parent(header, t);
|
||||
NodeTraits::set_parent(t, header);
|
||||
//Recover leftmost/rightmost pointers
|
||||
NodeTraits::set_left (header, leftmost);
|
||||
NodeTraits::set_right(header, rightmost);
|
||||
return t;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/// @cond
|
||||
|
||||
// assemble the three sub-trees into new tree pointed to by t | complexity : constant | exception : nothrow
|
||||
static void assemble(const node_ptr &t, const node_ptr & l, const node_ptr & r, const const_node_ptr & null_node )
|
||||
{
|
||||
NodeTraits::set_right(l, NodeTraits::get_left(t));
|
||||
NodeTraits::set_left(r, NodeTraits::get_right(t));
|
||||
|
||||
if(NodeTraits::get_right(l) != node_ptr()){
|
||||
NodeTraits::set_parent(NodeTraits::get_right(l), l);
|
||||
}
|
||||
|
||||
if(NodeTraits::get_left(r) != node_ptr()){
|
||||
NodeTraits::set_parent(NodeTraits::get_left(r), r);
|
||||
}
|
||||
|
||||
NodeTraits::set_left (t, NodeTraits::get_right(null_node));
|
||||
NodeTraits::set_right(t, NodeTraits::get_left(null_node));
|
||||
|
||||
if( NodeTraits::get_left(t) != node_ptr() ){
|
||||
NodeTraits::set_parent(NodeTraits::get_left(t), t);
|
||||
}
|
||||
|
||||
if( NodeTraits::get_right(t) ){
|
||||
NodeTraits::set_parent(NodeTraits::get_right(t), t);
|
||||
//commit.~splaydown_assemble_and_fix_header<NodeTraits>() will first
|
||||
//"assemble()" + link the new root & recover header's leftmost & rightmost
|
||||
if(pfound){
|
||||
*pfound = found;
|
||||
}
|
||||
return commit.t_;
|
||||
}
|
||||
}
|
||||
|
||||
// break link to left child node and attach it to left tree pointed to by l | complexity : constant | exception : nothrow
|
||||
static void link_left(node_ptr & t, node_ptr & l)
|
||||
{
|
||||
//procedure link_left;
|
||||
// t, l, right(l) := right(t), t, t
|
||||
//end link_left
|
||||
NodeTraits::set_right(l, t);
|
||||
NodeTraits::set_parent(t, l);
|
||||
l = t;
|
||||
@@ -615,6 +642,9 @@ class splaytree_algorithms
|
||||
// break link to right child node and attach it to right tree pointed to by r | complexity : constant | exception : nothrow
|
||||
static void link_right(node_ptr & t, node_ptr & r)
|
||||
{
|
||||
//procedure link_right;
|
||||
// t, r, left(r) := left(t), t, t
|
||||
//end link_right;
|
||||
NodeTraits::set_left(r, t);
|
||||
NodeTraits::set_parent(t, r);
|
||||
r = t;
|
||||
@@ -624,6 +654,9 @@ class splaytree_algorithms
|
||||
// rotate n with its parent | complexity : constant | exception : nothrow
|
||||
static void rotate(const node_ptr & n)
|
||||
{
|
||||
//procedure rotate_left;
|
||||
// t, right(t), left(right(t)) := right(t), left(right(t)), t
|
||||
//end rotate_left;
|
||||
node_ptr p = NodeTraits::get_parent(n);
|
||||
node_ptr g = NodeTraits::get_parent(p);
|
||||
//Test if g is header before breaking tree
|
||||
@@ -632,13 +665,13 @@ class splaytree_algorithms
|
||||
|
||||
if(NodeTraits::get_left(p) == n){
|
||||
NodeTraits::set_left(p, NodeTraits::get_right(n));
|
||||
if(NodeTraits::get_left(p) != node_ptr())
|
||||
if(NodeTraits::get_left(p))
|
||||
NodeTraits::set_parent(NodeTraits::get_left(p), p);
|
||||
NodeTraits::set_right(n, p);
|
||||
}
|
||||
else{ // must be ( p->right == n )
|
||||
NodeTraits::set_right(p, NodeTraits::get_left(n));
|
||||
if(NodeTraits::get_right(p) != node_ptr())
|
||||
if(NodeTraits::get_right(p))
|
||||
NodeTraits::set_parent(NodeTraits::get_right(p), p);
|
||||
NodeTraits::set_left(n, p);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#define BOOST_INTRUSIVE_TREAP_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
@@ -21,7 +22,6 @@
|
||||
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
#include <boost/intrusive/bs_set_hook.hpp>
|
||||
#include <boost/intrusive/bstree.hpp>
|
||||
#include <boost/intrusive/detail/tree_node.hpp>
|
||||
@@ -72,8 +72,8 @@ template<class ValueTraits, class VoidOrKeyComp, class VoidOrPrioComp, class Siz
|
||||
#endif
|
||||
class treap_impl
|
||||
/// @cond
|
||||
: public bstree_impl<ValueTraits, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms>
|
||||
, public detail::ebo_functor_holder
|
||||
: public bstree_impl<ValueTraits, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms>
|
||||
, public detail::ebo_functor_holder
|
||||
< typename get_prio
|
||||
< VoidOrPrioComp
|
||||
, typename bstree_impl
|
||||
@@ -87,7 +87,6 @@ class treap_impl
|
||||
typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
|
||||
, ConstantTimeSize, BsTreeAlgorithms> tree_type;
|
||||
typedef tree_type implementation_defined;
|
||||
typedef typename tree_type::real_value_traits real_value_traits;
|
||||
typedef get_prio
|
||||
< VoidOrPrioComp
|
||||
, typename tree_type::value_type> get_prio_type;
|
||||
@@ -96,7 +95,7 @@ class treap_impl
|
||||
<typename get_prio_type::type> prio_base;
|
||||
|
||||
/// @endcond
|
||||
|
||||
|
||||
typedef typename implementation_defined::pointer pointer;
|
||||
typedef typename implementation_defined::const_pointer const_pointer;
|
||||
typedef typename implementation_defined::value_type value_type;
|
||||
@@ -120,7 +119,7 @@ class treap_impl
|
||||
|
||||
static const bool constant_time_size = implementation_defined::constant_time_size;
|
||||
static const bool stateful_value_traits = implementation_defined::stateful_value_traits;
|
||||
static const bool safemode_or_autounlink = is_safe_autounlink<real_value_traits::link_mode>::value;
|
||||
static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
|
||||
|
||||
/// @cond
|
||||
private:
|
||||
@@ -217,7 +216,7 @@ class treap_impl
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
iterator top()
|
||||
{ return this->empty() ? this->end() : iterator(node_traits::get_parent(this->tree_type::header_ptr()), this); }
|
||||
{ return this->tree_type::root(); }
|
||||
|
||||
//! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the treap..
|
||||
//!
|
||||
@@ -233,7 +232,7 @@ class treap_impl
|
||||
//!
|
||||
//! <b>Throws</b>: Nothing.
|
||||
const_iterator ctop() const
|
||||
{ return this->empty() ? this->cend() : const_iterator(node_traits::get_parent(this->tree_type::header_ptr()), this); }
|
||||
{ return this->tree_type::root(); }
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
//! @copydoc ::boost::intrusive::bstree::rbegin()
|
||||
@@ -363,15 +362,15 @@ class treap_impl
|
||||
//! No copy-constructors are called.
|
||||
iterator insert_equal(reference value)
|
||||
{
|
||||
detail::key_nodeptr_comp<value_compare, real_value_traits>
|
||||
key_node_comp(this->value_comp(), &this->get_real_value_traits());
|
||||
detail::key_nodeptr_comp<priority_compare, real_value_traits>
|
||||
key_node_pcomp(this->priv_pcomp(), &this->get_real_value_traits());
|
||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
||||
detail::key_nodeptr_comp<value_compare, value_traits>
|
||||
key_node_comp(this->value_comp(), &this->get_value_traits());
|
||||
detail::key_nodeptr_comp<priority_compare, value_traits>
|
||||
key_node_pcomp(this->priv_pcomp(), &this->get_value_traits());
|
||||
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||
if(safemode_or_autounlink)
|
||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||
iterator ret(node_algorithms::insert_equal_upper_bound
|
||||
(this->tree_type::header_ptr(), to_insert, key_node_comp, key_node_pcomp), this->real_value_traits_ptr());
|
||||
(this->tree_type::header_ptr(), to_insert, key_node_comp, key_node_pcomp), this->value_traits_ptr());
|
||||
this->tree_type::sz_traits().increment();
|
||||
return ret;
|
||||
}
|
||||
@@ -392,15 +391,15 @@ class treap_impl
|
||||
//! No copy-constructors are called.
|
||||
iterator insert_equal(const_iterator hint, reference value)
|
||||
{
|
||||
detail::key_nodeptr_comp<value_compare, real_value_traits>
|
||||
key_node_comp(this->value_comp(), &this->get_real_value_traits());
|
||||
detail::key_nodeptr_comp<priority_compare, real_value_traits>
|
||||
key_node_pcomp(this->priv_pcomp(), &this->get_real_value_traits());
|
||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
||||
detail::key_nodeptr_comp<value_compare, value_traits>
|
||||
key_node_comp(this->value_comp(), &this->get_value_traits());
|
||||
detail::key_nodeptr_comp<priority_compare, value_traits>
|
||||
key_node_pcomp(this->priv_pcomp(), &this->get_value_traits());
|
||||
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||
if(safemode_or_autounlink)
|
||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||
iterator ret (node_algorithms::insert_equal
|
||||
(this->tree_type::header_ptr(), hint.pointed_node(), to_insert, key_node_comp, key_node_pcomp), this->real_value_traits_ptr());
|
||||
(this->tree_type::header_ptr(), hint.pointed_node(), to_insert, key_node_comp, key_node_pcomp), this->value_traits_ptr());
|
||||
this->tree_type::sz_traits().increment();
|
||||
return ret;
|
||||
}
|
||||
@@ -540,14 +539,14 @@ class treap_impl
|
||||
( const KeyType &key, KeyValueCompare key_value_comp
|
||||
, KeyValuePrioCompare key_value_pcomp, insert_commit_data &commit_data)
|
||||
{
|
||||
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
|
||||
ocomp(key_value_comp, &this->get_real_value_traits());
|
||||
detail::key_nodeptr_comp<KeyValuePrioCompare, real_value_traits>
|
||||
pcomp(key_value_pcomp, &this->get_real_value_traits());
|
||||
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
|
||||
ocomp(key_value_comp, &this->get_value_traits());
|
||||
detail::key_nodeptr_comp<KeyValuePrioCompare, value_traits>
|
||||
pcomp(key_value_pcomp, &this->get_value_traits());
|
||||
std::pair<node_ptr, bool> ret =
|
||||
(node_algorithms::insert_unique_check
|
||||
(this->tree_type::header_ptr(), key, ocomp, pcomp, commit_data));
|
||||
return std::pair<iterator, bool>(iterator(ret.first, this->real_value_traits_ptr()), ret.second);
|
||||
return std::pair<iterator, bool>(iterator(ret.first, this->value_traits_ptr()), ret.second);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: key_value_comp must be a comparison function that induces
|
||||
@@ -592,14 +591,14 @@ class treap_impl
|
||||
, KeyValuePrioCompare key_value_pcomp
|
||||
, insert_commit_data &commit_data)
|
||||
{
|
||||
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
|
||||
ocomp(key_value_comp, &this->get_real_value_traits());
|
||||
detail::key_nodeptr_comp<KeyValuePrioCompare, real_value_traits>
|
||||
pcomp(key_value_pcomp, &this->get_real_value_traits());
|
||||
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
|
||||
ocomp(key_value_comp, &this->get_value_traits());
|
||||
detail::key_nodeptr_comp<KeyValuePrioCompare, value_traits>
|
||||
pcomp(key_value_pcomp, &this->get_value_traits());
|
||||
std::pair<node_ptr, bool> ret =
|
||||
(node_algorithms::insert_unique_check
|
||||
(this->tree_type::header_ptr(), hint.pointed_node(), key, ocomp, pcomp, commit_data));
|
||||
return std::pair<iterator, bool>(iterator(ret.first, this->real_value_traits_ptr()), ret.second);
|
||||
return std::pair<iterator, bool>(iterator(ret.first, this->value_traits_ptr()), ret.second);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
|
||||
@@ -621,12 +620,12 @@ class treap_impl
|
||||
//! erased between the "insert_check" and "insert_commit" calls.
|
||||
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
|
||||
{
|
||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
||||
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||
if(safemode_or_autounlink)
|
||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||
node_algorithms::insert_unique_commit(this->tree_type::header_ptr(), to_insert, commit_data);
|
||||
this->tree_type::sz_traits().increment();
|
||||
return iterator(to_insert, this->real_value_traits_ptr());
|
||||
return iterator(to_insert, this->value_traits_ptr());
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: value must be an lvalue, "pos" must be
|
||||
@@ -645,13 +644,13 @@ class treap_impl
|
||||
//! by advanced users.
|
||||
iterator insert_before(const_iterator pos, reference value)
|
||||
{
|
||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
||||
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||
if(safemode_or_autounlink)
|
||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||
detail::key_nodeptr_comp<priority_compare, real_value_traits>
|
||||
pcomp(this->priv_pcomp(), &this->get_real_value_traits());
|
||||
detail::key_nodeptr_comp<priority_compare, value_traits>
|
||||
pcomp(this->priv_pcomp(), &this->get_value_traits());
|
||||
iterator ret (node_algorithms::insert_before
|
||||
(this->tree_type::header_ptr(), pos.pointed_node(), to_insert, pcomp), this->real_value_traits_ptr());
|
||||
(this->tree_type::header_ptr(), pos.pointed_node(), to_insert, pcomp), this->value_traits_ptr());
|
||||
this->tree_type::sz_traits().increment();
|
||||
return ret;
|
||||
}
|
||||
@@ -672,11 +671,11 @@ class treap_impl
|
||||
//! by advanced users.
|
||||
void push_back(reference value)
|
||||
{
|
||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
||||
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||
if(safemode_or_autounlink)
|
||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||
detail::key_nodeptr_comp<priority_compare, real_value_traits>
|
||||
pcomp(this->priv_pcomp(), &this->get_real_value_traits());
|
||||
detail::key_nodeptr_comp<priority_compare, value_traits>
|
||||
pcomp(this->priv_pcomp(), &this->get_value_traits());
|
||||
node_algorithms::push_back(this->tree_type::header_ptr(), to_insert, pcomp);
|
||||
this->tree_type::sz_traits().increment();
|
||||
}
|
||||
@@ -697,11 +696,11 @@ class treap_impl
|
||||
//! by advanced users.
|
||||
void push_front(reference value)
|
||||
{
|
||||
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
|
||||
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
|
||||
if(safemode_or_autounlink)
|
||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
|
||||
detail::key_nodeptr_comp<priority_compare, real_value_traits>
|
||||
pcomp(this->priv_pcomp(), &this->get_real_value_traits());
|
||||
detail::key_nodeptr_comp<priority_compare, value_traits>
|
||||
pcomp(this->priv_pcomp(), &this->get_value_traits());
|
||||
node_algorithms::push_front(this->tree_type::header_ptr(), to_insert, pcomp);
|
||||
this->tree_type::sz_traits().increment();
|
||||
}
|
||||
@@ -721,8 +720,8 @@ class treap_impl
|
||||
node_ptr to_erase(i.pointed_node());
|
||||
if(safemode_or_autounlink)
|
||||
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
|
||||
detail::key_nodeptr_comp<priority_compare, real_value_traits>
|
||||
key_node_pcomp(this->priv_pcomp(), &this->get_real_value_traits());
|
||||
detail::key_nodeptr_comp<priority_compare, value_traits>
|
||||
key_node_pcomp(this->priv_pcomp(), &this->get_value_traits());
|
||||
node_algorithms::erase(this->tree_type::header_ptr(), to_erase, key_node_pcomp);
|
||||
this->tree_type::sz_traits().decrement();
|
||||
if(safemode_or_autounlink)
|
||||
@@ -796,7 +795,7 @@ class treap_impl
|
||||
{
|
||||
node_ptr to_erase(i.pointed_node());
|
||||
iterator ret(this->erase(i));
|
||||
disposer(this->get_real_value_traits().to_value_ptr(to_erase));
|
||||
disposer(this->get_value_traits().to_value_ptr(to_erase));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -898,7 +897,7 @@ class treap_impl
|
||||
void clear_and_dispose(Disposer disposer)
|
||||
{
|
||||
node_algorithms::clear_and_dispose(this->tree_type::header_ptr()
|
||||
, detail::node_disposer<Disposer, real_value_traits, TreapAlgorithms>(disposer, &this->get_real_value_traits()));
|
||||
, detail::node_disposer<Disposer, value_traits, TreapAlgorithms>(disposer, &this->get_value_traits()));
|
||||
node_algorithms::init_header(this->tree_type::header_ptr());
|
||||
this->tree_type::sz_traits().set_size(0);
|
||||
}
|
||||
@@ -910,7 +909,7 @@ class treap_impl
|
||||
//! @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);
|
||||
|
||||
@@ -1120,14 +1119,13 @@ class treap
|
||||
typedef typename Base::value_compare value_compare;
|
||||
typedef typename Base::priority_compare priority_compare;
|
||||
typedef typename Base::value_traits value_traits;
|
||||
typedef typename Base::real_value_traits real_value_traits;
|
||||
typedef typename Base::iterator iterator;
|
||||
typedef typename Base::const_iterator const_iterator;
|
||||
typedef typename Base::reverse_iterator reverse_iterator;
|
||||
typedef typename Base::const_reverse_iterator const_reverse_iterator;
|
||||
|
||||
//Assert if passed value traits are compatible with the type
|
||||
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
|
||||
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
|
||||
|
||||
explicit treap( const value_compare &cmp = value_compare()
|
||||
, const priority_compare &pcmp = priority_compare()
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
#define BOOST_INTRUSIVE_TREAP_ALGORITHMS_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
|
||||
#include <boost/intrusive/detail/assert.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
@@ -110,16 +110,17 @@ class treap_algorithms
|
||||
|
||||
static void rotate_up_n(const node_ptr header, const node_ptr p, std::size_t n)
|
||||
{
|
||||
for( node_ptr p_parent = NodeTraits::get_parent(p)
|
||||
; n--
|
||||
; p_parent = NodeTraits::get_parent(p)){
|
||||
//Check if left child
|
||||
if(p == NodeTraits::get_left(p_parent)){
|
||||
bstree_algo::rotate_right(p_parent, header);
|
||||
node_ptr p_parent(NodeTraits::get_parent(p));
|
||||
node_ptr p_grandparent(NodeTraits::get_parent(p_parent));
|
||||
while(n--){
|
||||
if(p == NodeTraits::get_left(p_parent)){ //p is left child
|
||||
bstree_algo::rotate_right(p_parent, p, p_grandparent, header);
|
||||
}
|
||||
else{ //Right child
|
||||
bstree_algo::rotate_left(p_parent, header);
|
||||
else{ //p is right child
|
||||
bstree_algo::rotate_left(p_parent, p, p_grandparent, header);
|
||||
}
|
||||
p_parent = p_grandparent;
|
||||
p_grandparent = NodeTraits::get_parent(p_parent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,6 +249,7 @@ class treap_algorithms
|
||||
//! @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.
|
||||
@@ -525,7 +527,7 @@ class treap_algorithms
|
||||
(const node_ptr & header, const node_ptr & new_node, const insert_commit_data &commit_data)
|
||||
{
|
||||
bstree_algo::insert_unique_commit(header, new_node, commit_data);
|
||||
rebalance_after_insertion_commit(header, new_node, commit_data.rotations);
|
||||
rotate_up_n(header, new_node, commit_data.rotations);
|
||||
}
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
@@ -546,11 +548,12 @@ class treap_algorithms
|
||||
node_ptr z_left = NodeTraits::get_left(z);
|
||||
node_ptr z_right = NodeTraits::get_right(z);
|
||||
while(z_left || z_right){
|
||||
const node_ptr z_parent(NodeTraits::get_parent(z));
|
||||
if(!z_right || (z_left && pcomp(z_left, z_right))){
|
||||
bstree_algo::rotate_right(z, header);
|
||||
bstree_algo::rotate_right(z, z_left, z_parent, header);
|
||||
}
|
||||
else{
|
||||
bstree_algo::rotate_left(z, header);
|
||||
bstree_algo::rotate_left(z, z_right, z_parent, header);
|
||||
}
|
||||
++n;
|
||||
z_left = NodeTraits::get_left(z);
|
||||
@@ -566,10 +569,9 @@ class treap_algorithms
|
||||
rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
|
||||
//No-throw
|
||||
bstree_algo::insert_unique_commit(h, new_node, commit_data);
|
||||
rebalance_after_insertion_commit(h, new_node, commit_data.rotations);
|
||||
rotate_up_n(h, new_node, commit_data.rotations);
|
||||
}
|
||||
|
||||
|
||||
template<class Key, class KeyNodePriorityCompare>
|
||||
static void rebalance_after_insertion_check
|
||||
(const const_node_ptr &header, const const_node_ptr & up, const Key &k
|
||||
@@ -586,22 +588,6 @@ class treap_algorithms
|
||||
num_rotations = n;
|
||||
}
|
||||
|
||||
static void rebalance_after_insertion_commit(const node_ptr & header, const node_ptr & p, std::size_t n)
|
||||
{
|
||||
// Now execute n rotations
|
||||
for( node_ptr p_parent = NodeTraits::get_parent(p)
|
||||
; n--
|
||||
; p_parent = NodeTraits::get_parent(p)){
|
||||
//Check if left child
|
||||
if(p == NodeTraits::get_left(p_parent)){
|
||||
bstree_algo::rotate_right(p_parent, header);
|
||||
}
|
||||
else{ //Right child
|
||||
bstree_algo::rotate_left(p_parent, header);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class NodePtrPriorityCompare>
|
||||
static bool check_invariant(const const_node_ptr & header, NodePtrPriorityCompare pcomp)
|
||||
{
|
||||
|
||||
@@ -44,6 +44,7 @@ class treap_set_impl
|
||||
#endif
|
||||
{
|
||||
/// @cond
|
||||
public:
|
||||
typedef treap_impl<ValueTraits, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize> tree_type;
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_set_impl)
|
||||
|
||||
@@ -291,13 +292,19 @@ class treap_set_impl
|
||||
template<class Disposer>
|
||||
void clear_and_dispose(Disposer disposer);
|
||||
|
||||
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::treap::count(const_reference)const
|
||||
size_type count(const_reference value) const;
|
||||
size_type count(const_reference value) const
|
||||
{ return static_cast<size_type>(this->tree_type::find(value) != this->tree_type::cend()); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::treap::count(const KeyType&,KeyValueCompare)const
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
size_type count(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
size_type count(const KeyType& key, KeyValueCompare comp) const
|
||||
{ return static_cast<size_type>(this->tree_type::find(key, comp) != this->tree_type::cend()); }
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::treap::lower_bound(const_reference)
|
||||
iterator lower_bound(const_reference value);
|
||||
|
||||
@@ -340,21 +347,29 @@ class treap_set_impl
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
const_iterator find(const KeyType& key, KeyValueCompare comp) const;
|
||||
|
||||
//! @copydoc ::boost::intrusive::treap::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> equal_range(const_reference value);
|
||||
#endif // #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::treap::equal_range(const KeyType&,KeyValueCompare)
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)
|
||||
std::pair<iterator,iterator> equal_range(const_reference value)
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const KeyType&,KeyValueCompare)
|
||||
template<class KeyType, class KeyValueCompare>
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp);
|
||||
std::pair<iterator,iterator> equal_range(const KeyType& key, KeyValueCompare comp)
|
||||
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::treap::equal_range(const_reference)const
|
||||
//! @copydoc ::boost::intrusive::rbtree::equal_range(const_reference)const
|
||||
std::pair<const_iterator, const_iterator>
|
||||
equal_range(const_reference value) const;
|
||||
equal_range(const_reference value) const
|
||||
{ return this->tree_type::lower_bound_range(value); }
|
||||
|
||||
//! @copydoc ::boost::intrusive::treap::equal_range(const KeyType&,KeyValueCompare)const
|
||||
//! @copydoc ::boost::intrusive::rbtree::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;
|
||||
equal_range(const KeyType& key, KeyValueCompare comp) const
|
||||
{ return this->tree_type::lower_bound_range(key, comp); }
|
||||
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
|
||||
//! @copydoc ::boost::intrusive::treap::bounded_range(const_reference,const_reference,bool,bool)
|
||||
std::pair<iterator,iterator> bounded_range
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#ifndef BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP
|
||||
#define BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP
|
||||
|
||||
#include <boost/intrusive/detail/config_begin.hpp>
|
||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||
|
||||
#include <boost/intrusive/link_mode.hpp>
|
||||
#include <boost/intrusive/pointer_traits.hpp>
|
||||
|
||||
@@ -22,7 +25,11 @@ namespace intrusive {
|
||||
//!This value traits template is used to create value traits
|
||||
//!from user defined node traits where value_traits::value_type and
|
||||
//!node_traits::node should be equal
|
||||
template<class NodeTraits, link_mode_type LinkMode = normal_link>
|
||||
template<class NodeTraits, link_mode_type LinkMode
|
||||
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||
= safe_link
|
||||
#endif
|
||||
>
|
||||
struct trivial_value_traits
|
||||
{
|
||||
typedef NodeTraits node_traits;
|
||||
@@ -43,4 +50,6 @@ struct trivial_value_traits
|
||||
} //namespace intrusive
|
||||
} //namespace boost
|
||||
|
||||
#include <boost/intrusive/detail/config_end.hpp>
|
||||
|
||||
#endif //BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP
|
||||
@@ -1029,15 +1029,15 @@ struct make_unordered_set
|
||||
typedef typename detail::get_value_traits
|
||||
<T, typename packed_options::proto_value_traits>::type value_traits;
|
||||
|
||||
typedef typename make_real_bucket_traits
|
||||
<T, true, packed_options>::type real_bucket_traits;
|
||||
typedef typename make_bucket_traits
|
||||
<T, true, packed_options>::type bucket_traits;
|
||||
|
||||
typedef unordered_set_impl
|
||||
< value_traits
|
||||
, typename packed_options::hash
|
||||
, typename packed_options::equal
|
||||
, typename packed_options::size_type
|
||||
, real_bucket_traits
|
||||
, bucket_traits
|
||||
, (std::size_t(true)*hash_bool_flags::unique_keys_pos)
|
||||
| (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
|
||||
| (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
|
||||
@@ -2066,15 +2066,15 @@ struct make_unordered_multiset
|
||||
typedef typename detail::get_value_traits
|
||||
<T, typename packed_options::proto_value_traits>::type value_traits;
|
||||
|
||||
typedef typename make_real_bucket_traits
|
||||
<T, true, packed_options>::type real_bucket_traits;
|
||||
typedef typename make_bucket_traits
|
||||
<T, true, packed_options>::type bucket_traits;
|
||||
|
||||
typedef unordered_multiset_impl
|
||||
< value_traits
|
||||
, typename packed_options::hash
|
||||
, typename packed_options::equal
|
||||
, typename packed_options::size_type
|
||||
, real_bucket_traits
|
||||
, bucket_traits
|
||||
, (std::size_t(false)*hash_bool_flags::unique_keys_pos)
|
||||
| (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
|
||||
| (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
|
||||
|
||||
@@ -207,7 +207,7 @@ struct make_unordered_set_base_hook
|
||||
//! unique tag.
|
||||
//!
|
||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||
//! and the the container configured to use this hook.
|
||||
//! and the container configured to use this hook.
|
||||
//!
|
||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||
//! \c auto_unlink or \c safe_link).
|
||||
@@ -341,7 +341,7 @@ struct make_unordered_set_member_hook
|
||||
//! \c link_mode<> and \c store_hash<>.
|
||||
//!
|
||||
//! \c void_pointer<> is the pointer type that will be used internally in the hook
|
||||
//! and the the container configured to use this hook.
|
||||
//! and the container configured to use this hook.
|
||||
//!
|
||||
//! \c link_mode<> will specify the linking mode of the hook (\c normal_link,
|
||||
//! \c auto_unlink or \c safe_link).
|
||||
|
||||
Reference in new issue
Block a user