Reverted git mess.

This commit is contained in:
Ion Gaztañaga committed 2014-02-15 00:28:41 +01:00
1 parent 27e5ad9183
commit 68fa82e5e8
59 files changed
+1937 -3049

No files matched your search

+2 -2
View File
@@ -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
+26 -12
View File
@@ -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);
+2 -2
View File
@@ -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).
+3 -4
View File
@@ -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())
+139 -92
View File
@@ -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());
}
}
+25 -11
View File
@@ -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
+2 -2
View File
@@ -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).
+224 -196
View File
@@ -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
+1 -1
View File
@@ -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 {
+6
View File
@@ -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
+210 -77
View File
@@ -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
+2 -2
View File
@@ -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
+62 -519
View File
@@ -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
+2 -1
View File
@@ -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>
+5 -1
View File
@@ -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);
+3 -4
View File
@@ -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())
+85 -103
View File
@@ -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());
+23 -8
View File
@@ -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);
+3 -2
View File
@@ -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).
+25 -11
View File
@@ -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
+47 -34
View File
@@ -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())
+15 -18
View File
@@ -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
+2 -2
View File
@@ -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
+24 -109
View File
@@ -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);
-286
View File
@@ -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
+14 -89
View File
@@ -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())
+190 -157
View File
@@ -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);
}
+47 -49
View File
@@ -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()
+16 -30
View File
@@ -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)
{
+26 -11
View File
@@ -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
+6 -6
View File
@@ -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).