Changes for 1.49

[SVN r76179]
This commit is contained in:
Ion Gaztañaga
2011-12-26 17:10:27 +00:00
parent 21e694ea5f
commit 827f7c35a0
39 changed files with 2453 additions and 1337 deletions

View File

@@ -19,7 +19,7 @@
#include <boost/intrusive/detail/any_node_and_algorithms.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/intrusive/detail/generic_hook.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
namespace boost {
namespace intrusive {
@@ -244,15 +244,15 @@ namespace detail{
template<class ValueTraits>
struct any_to_get_base_pointer_type
{
typedef typename pointer_to_other
<typename ValueTraits::boost_intrusive_tags::node_traits::node_ptr, void>::type type;
typedef typename pointer_traits<typename ValueTraits::boost_intrusive_tags::node_traits::node_ptr>::template
rebind_pointer<void>::type type;
};
template<class ValueTraits>
struct any_to_get_member_pointer_type
{
typedef typename pointer_to_other
<typename ValueTraits::node_ptr, void>::type type;
typedef typename pointer_traits
<typename ValueTraits::node_ptr>::template rebind_pointer<void>::type type;
};
//!This option setter specifies that the container

View File

@@ -27,9 +27,11 @@
#include <boost/intrusive/detail/tree_node.hpp>
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/intrusive/detail/utilities.hpp>
#include <boost/intrusive/avltree_algorithms.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/move/move.hpp>
@@ -96,24 +98,30 @@ class avltree_impl
/// @endcond
typedef typename real_value_traits::pointer pointer;
typedef typename real_value_traits::const_pointer const_pointer;
typedef typename std::iterator_traits<pointer>::value_type value_type;
typedef typename boost::intrusive::
pointer_traits<pointer>::element_type value_type;
typedef value_type key_type;
typedef typename std::iterator_traits<pointer>::reference reference;
typedef typename std::iterator_traits<const_pointer>::reference const_reference;
typedef typename std::iterator_traits<pointer>::difference_type difference_type;
typedef typename boost::intrusive::
pointer_traits<pointer>::reference reference;
typedef typename boost::intrusive::
pointer_traits<const_pointer>::reference const_reference;
typedef typename boost::intrusive::
pointer_traits<pointer>::difference_type difference_type;
typedef typename Config::size_type size_type;
typedef typename Config::compare value_compare;
typedef value_compare key_compare;
typedef tree_iterator<avltree_impl, false> iterator;
typedef tree_iterator<avltree_impl, true> const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef tree_iterator<avltree_impl, false> iterator;
typedef tree_iterator<avltree_impl, true> const_iterator;
typedef boost::intrusive::detail::reverse_iterator<iterator> reverse_iterator;
typedef boost::intrusive::detail::reverse_iterator<const_iterator>const_reverse_iterator;
typedef typename real_value_traits::node_traits node_traits;
typedef typename node_traits::node node;
typedef typename boost::pointer_to_other
<pointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<node_ptr, const node>::type const_node_ptr;
typedef typename pointer_traits
<pointer>::template rebind_pointer
<node>::type node_ptr;
typedef typename pointer_traits
<pointer>::template rebind_pointer
<const node>::type const_node_ptr;
typedef avltree_algorithms<node_traits> node_algorithms;
static const bool constant_time_size = Config::constant_time_size;
@@ -165,16 +173,14 @@ class avltree_impl
value_traits &priv_value_traits()
{ return data_; }
const node &priv_header() const
{ return data_.node_plus_pred_.header_plus_size_.header_; }
node_ptr priv_header_ptr()
{ return pointer_traits<node_ptr>::pointer_to(data_.node_plus_pred_.header_plus_size_.header_); }
node &priv_header()
{ return data_.node_plus_pred_.header_plus_size_.header_; }
const_node_ptr priv_header_ptr() const
{ return pointer_traits<const_node_ptr>::pointer_to(data_.node_plus_pred_.header_plus_size_.header_); }
static node_ptr uncast(const_node_ptr ptr)
{
return node_ptr(const_cast<node*>(detail::boost_intrusive_get_pointer(ptr)));
}
static node_ptr uncast(const const_node_ptr & ptr)
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
size_traits &priv_size_traits()
{ return data_.node_plus_pred_.header_plus_size_; }
@@ -217,7 +223,7 @@ class avltree_impl
, const value_traits &v_traits = value_traits())
: data_(cmp, v_traits)
{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(size_type(0));
}
@@ -239,7 +245,7 @@ class avltree_impl
, const value_traits &v_traits = value_traits())
: data_(cmp, v_traits)
{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(size_type(0));
if(unique)
this->insert_unique(b, e);
@@ -252,7 +258,7 @@ class avltree_impl
avltree_impl(BOOST_RV_REF(avltree_impl) x)
: data_(::boost::move(x.priv_comp()), ::boost::move(x.priv_value_traits()))
{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(size_type(0));
this->swap(x);
}
@@ -278,7 +284,7 @@ class avltree_impl
//!
//! <b>Throws</b>: Nothing.
iterator begin()
{ return iterator (node_traits::get_left(node_ptr(&priv_header())), this); }
{ return iterator (node_traits::get_left(this->priv_header_ptr()), this); }
//! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the tree.
//!
@@ -294,7 +300,7 @@ class avltree_impl
//!
//! <b>Throws</b>: Nothing.
const_iterator cbegin() const
{ return const_iterator (node_traits::get_left(const_node_ptr(&priv_header())), this); }
{ return const_iterator (node_traits::get_left(this->priv_header_ptr()), this); }
//! <b>Effects</b>: Returns an iterator pointing to the end of the tree.
//!
@@ -302,7 +308,7 @@ class avltree_impl
//!
//! <b>Throws</b>: Nothing.
iterator end()
{ return iterator (node_ptr(&priv_header()), this); }
{ return iterator (this->priv_header_ptr(), this); }
//! <b>Effects</b>: Returns a const_iterator pointing to the end of the tree.
//!
@@ -318,7 +324,7 @@ class avltree_impl
//!
//! <b>Throws</b>: Nothing.
const_iterator cend() const
{ return const_iterator (uncast(const_node_ptr(&priv_header())), this); }
{ return const_iterator (uncast(this->priv_header_ptr()), this); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning of the
//! reversed tree.
@@ -432,7 +438,7 @@ class avltree_impl
//!
//! <b>Throws</b>: Nothing.
bool empty() const
{ return node_algorithms::unique(const_node_ptr(&priv_header())); }
{ return node_algorithms::unique(this->priv_header_ptr()); }
//! <b>Effects</b>: Returns the number of elements stored in the tree.
//!
@@ -445,7 +451,7 @@ class avltree_impl
if(constant_time_size)
return this->priv_size_traits().get_size();
else{
return (size_type)node_algorithms::size(const_node_ptr(&priv_header()));
return (size_type)node_algorithms::size(this->priv_header_ptr());
}
}
@@ -460,7 +466,7 @@ class avltree_impl
using std::swap;
swap(priv_comp(), priv_comp());
//These can't throw
node_algorithms::swap_tree(node_ptr(&priv_header()), node_ptr(&other.priv_header()));
node_algorithms::swap_tree(this->priv_header_ptr(), other.priv_header_ptr());
if(constant_time_size){
size_type backup = this->priv_size_traits().get_size();
this->priv_size_traits().set_size(other.priv_size_traits().get_size());
@@ -487,7 +493,7 @@ class avltree_impl
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
iterator ret(node_algorithms::insert_equal_upper_bound
(node_ptr(&priv_header()), to_insert, key_node_comp), this);
(this->priv_header_ptr(), to_insert, key_node_comp), this);
this->priv_size_traits().increment();
return ret;
}
@@ -514,7 +520,7 @@ class avltree_impl
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
iterator ret(node_algorithms::insert_equal
(node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp), this);
(this->priv_header_ptr(), hint.pointed_node(), to_insert, key_node_comp), this);
this->priv_size_traits().increment();
return ret;
}
@@ -650,7 +656,7 @@ class avltree_impl
comp(key_value_comp, this);
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
(node_ptr(&priv_header()), key, comp, commit_data));
(this->priv_header_ptr(), key, comp, commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
}
@@ -695,7 +701,7 @@ class avltree_impl
comp(key_value_comp, this);
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
(node_ptr(&priv_header()), hint.pointed_node(), key, comp, commit_data));
(this->priv_header_ptr(), hint.pointed_node(), key, comp, commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
}
@@ -722,7 +728,7 @@ class avltree_impl
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
node_algorithms::insert_unique_commit
(node_ptr(&priv_header()), to_insert, commit_data);
(this->priv_header_ptr(), to_insert, commit_data);
this->priv_size_traits().increment();
return iterator(to_insert, this);
}
@@ -747,7 +753,7 @@ class avltree_impl
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
iterator ret(node_algorithms::insert_before
(node_ptr(&priv_header()), pos.pointed_node(), to_insert), this);
(this->priv_header_ptr(), pos.pointed_node(), to_insert), this);
this->priv_size_traits().increment();
return ret;
}
@@ -771,7 +777,7 @@ class avltree_impl
node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
node_algorithms::push_back(node_ptr(&priv_header()), to_insert);
node_algorithms::push_back(this->priv_header_ptr(), to_insert);
this->priv_size_traits().increment();
}
@@ -794,7 +800,7 @@ class avltree_impl
node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
node_algorithms::push_front(node_ptr(&priv_header()), to_insert);
node_algorithms::push_front(this->priv_header_ptr(), to_insert);
this->priv_size_traits().increment();
}
@@ -813,7 +819,7 @@ class avltree_impl
node_ptr to_erase(i.pointed_node());
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
node_algorithms::erase(&priv_header(), to_erase);
node_algorithms::erase(this->priv_header_ptr(), to_erase);
this->priv_size_traits().decrement();
if(safemode_or_autounlink)
node_algorithms::init(to_erase);
@@ -975,7 +981,7 @@ class avltree_impl
this->clear_and_dispose(detail::null_disposer());
}
else{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(0);
}
}
@@ -992,9 +998,9 @@ class avltree_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer)
{
node_algorithms::clear_and_dispose(node_ptr(&priv_header())
node_algorithms::clear_and_dispose(this->priv_header_ptr()
, detail::node_disposer<Disposer, avltree_impl>(disposer, this));
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(0);
}
@@ -1050,7 +1056,7 @@ class avltree_impl
detail::key_nodeptr_comp<KeyValueCompare, avltree_impl>
key_node_comp(comp, this);
return iterator(node_algorithms::lower_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Returns a const iterator to the first element whose
@@ -1065,7 +1071,7 @@ class avltree_impl
detail::key_nodeptr_comp<KeyValueCompare, avltree_impl>
key_node_comp(comp, this);
return const_iterator(node_algorithms::lower_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Returns an iterator to the first element whose
@@ -1090,7 +1096,7 @@ class avltree_impl
detail::key_nodeptr_comp<KeyValueCompare, avltree_impl>
key_node_comp(comp, this);
return iterator(node_algorithms::upper_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Returns an iterator to the first element whose
@@ -1115,7 +1121,7 @@ class avltree_impl
detail::key_nodeptr_comp<KeyValueCompare, avltree_impl>
key_node_comp(comp, this);
return const_iterator(node_algorithms::upper_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Finds an iterator to the first element whose key is
@@ -1139,7 +1145,7 @@ class avltree_impl
detail::key_nodeptr_comp<KeyValueCompare, avltree_impl>
key_node_comp(comp, this);
return iterator
(node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this);
(node_algorithms::find(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Finds a const_iterator to the first element whose key is
@@ -1163,7 +1169,7 @@ class avltree_impl
detail::key_nodeptr_comp<KeyValueCompare, avltree_impl>
key_node_comp(comp, this);
return const_iterator
(node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this);
(node_algorithms::find(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Finds a range containing all elements whose key is k or
@@ -1189,7 +1195,7 @@ class avltree_impl
detail::key_nodeptr_comp<KeyValueCompare, avltree_impl>
key_node_comp(comp, this);
std::pair<node_ptr, node_ptr> ret
(node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp));
(node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp));
return std::pair<iterator, iterator>(iterator(ret.first, this), iterator(ret.second, this));
}
@@ -1218,7 +1224,7 @@ class avltree_impl
detail::key_nodeptr_comp<KeyValueCompare, avltree_impl>
key_node_comp(comp, this);
std::pair<node_ptr, node_ptr> ret
(node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp));
(node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp));
return std::pair<const_iterator, const_iterator>(const_iterator(ret.first, this), const_iterator(ret.second, this));
}
@@ -1244,8 +1250,8 @@ class avltree_impl
detail::exception_disposer<avltree_impl, Disposer>
rollback(*this, disposer);
node_algorithms::clone
(const_node_ptr(&src.priv_header())
,node_ptr(&this->priv_header())
(src.priv_header_ptr()
,this->priv_header_ptr()
,detail::node_cloner<Cloner, avltree_impl>(cloner, this)
,detail::node_disposer<Disposer, avltree_impl>(disposer, this));
this->priv_size_traits().set_size(src.priv_size_traits().get_size());
@@ -1267,7 +1273,7 @@ class avltree_impl
pointer unlink_leftmost_without_rebalance()
{
node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance
(node_ptr(&priv_header())));
(this->priv_header_ptr()));
if(!to_be_disposed)
return 0;
this->priv_size_traits().decrement();
@@ -1293,7 +1299,7 @@ class avltree_impl
void replace_node(iterator replace_this, reference with_this)
{
node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this)
, node_ptr(&priv_header())
, this->priv_header_ptr()
, get_real_value_traits().to_node_ptr(with_this));
if(safemode_or_autounlink)
node_algorithms::init(replace_this.pointed_node());
@@ -1424,7 +1430,7 @@ class avltree_impl
static avltree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
{
header_plus_size *r = detail::parent_from_member<header_plus_size, node>
( detail::boost_intrusive_get_pointer(end_iterator.pointed_node()), &header_plus_size::header_);
( boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()), &header_plus_size::header_);
node_plus_pred_t *n = detail::parent_from_member
<node_plus_pred_t, header_plus_size>(r, &node_plus_pred_t::header_plus_size_);
data_t *d = detail::parent_from_member<data_t, node_plus_pred_t>(n, &data_t::node_plus_pred_);

View File

@@ -22,6 +22,7 @@
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/utilities.hpp>
#include <boost/intrusive/detail/tree_algorithms.hpp>
#include <boost/intrusive/pointer_traits.hpp>
namespace boost {
@@ -88,7 +89,7 @@ class avltree_algorithms
: base_t(f)
{}
node_ptr operator()(node_ptr p)
node_ptr operator()(const node_ptr &p)
{
node_ptr n = base_t::get()(p);
NodeTraits::set_balance(n, NodeTraits::get_balance(p));
@@ -98,21 +99,19 @@ class avltree_algorithms
struct avltree_erase_fixup
{
void operator()(node_ptr to_erase, node_ptr successor)
void operator()(const node_ptr &to_erase, const node_ptr &successor)
{ NodeTraits::set_balance(successor, NodeTraits::get_balance(to_erase)); }
};
static node_ptr uncast(const_node_ptr ptr)
{
return node_ptr(const_cast<node*>(::boost::intrusive::detail::boost_intrusive_get_pointer(ptr)));
}
static node_ptr uncast(const const_node_ptr & ptr)
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
/// @endcond
public:
static node_ptr begin_node(const_node_ptr header)
static node_ptr begin_node(const const_node_ptr & header)
{ return tree_algorithms::begin_node(header); }
static node_ptr end_node(const_node_ptr header)
static node_ptr end_node(const const_node_ptr & header)
{ return tree_algorithms::end_node(header); }
//! This type is the information that will be
@@ -128,7 +127,7 @@ class avltree_algorithms
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
static void swap_tree(node_ptr header1, node_ptr header2)
static void swap_tree(const node_ptr & header1, const node_ptr & header2)
{ return tree_algorithms::swap_tree(header1, header2); }
//! <b>Requires</b>: node1 and node2 can't be header nodes
@@ -146,7 +145,7 @@ class avltree_algorithms
//! node1 and node2 are not equivalent according to the ordering rules.
//!
//!Experimental function
static void swap_nodes(node_ptr node1, node_ptr node2)
static void swap_nodes(const node_ptr & node1, const node_ptr & node2)
{
if(node1 == node2)
return;
@@ -170,7 +169,7 @@ class avltree_algorithms
//! node1 and node2 are not equivalent according to the ordering rules.
//!
//!Experimental function
static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2)
static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2)
{
if(node1 == node2) return;
@@ -197,7 +196,7 @@ class avltree_algorithms
//! the node, since no rebalancing and comparison is needed.
//!
//!Experimental function
static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node)
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node)
{
if(node_to_be_replaced == new_node)
return;
@@ -220,7 +219,7 @@ class avltree_algorithms
//! the node, since no rebalancing or comparison is needed.
//!
//!Experimental function
static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node)
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node)
{
tree_algorithms::replace_node(node_to_be_replaced, header, new_node);
NodeTraits::set_balance(new_node, NodeTraits::get_balance(node_to_be_replaced));
@@ -233,7 +232,7 @@ class avltree_algorithms
//! <b>Complexity</b>: Average complexity is constant time.
//!
//! <b>Throws</b>: Nothing.
static void unlink(node_ptr node)
static void unlink(const node_ptr & node)
{
node_ptr x = NodeTraits::get_parent(node);
if(x){
@@ -256,7 +255,7 @@ class avltree_algorithms
//! only be used for more unlink_leftmost_without_rebalance calls.
//! This function is normally used to achieve a step by step
//! controlled destruction of the tree.
static node_ptr unlink_leftmost_without_rebalance(node_ptr header)
static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header)
{ return tree_algorithms::unlink_leftmost_without_rebalance(header); }
//! <b>Requires</b>: node is a node of the tree or an node initialized
@@ -267,7 +266,7 @@ class avltree_algorithms
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
static bool unique(const_node_ptr node)
static bool unique(const const_node_ptr & node)
{ return tree_algorithms::unique(node); }
//! <b>Requires</b>: node is a node of the tree but it's not the header.
@@ -277,7 +276,7 @@ class avltree_algorithms
//! <b>Complexity</b>: Linear time.
//!
//! <b>Throws</b>: Nothing.
static std::size_t count(const_node_ptr node)
static std::size_t count(const const_node_ptr & node)
{ return tree_algorithms::count(node); }
//! <b>Requires</b>: header is the header node of the tree.
@@ -287,7 +286,7 @@ class avltree_algorithms
//! <b>Complexity</b>: Linear time.
//!
//! <b>Throws</b>: Nothing.
static std::size_t size(const_node_ptr header)
static std::size_t size(const const_node_ptr & header)
{ return tree_algorithms::size(header); }
//! <b>Requires</b>: p is a node from the tree except the header.
@@ -297,7 +296,7 @@ class avltree_algorithms
//! <b>Complexity</b>: Average constant time.
//!
//! <b>Throws</b>: Nothing.
static node_ptr next_node(node_ptr p)
static node_ptr next_node(const node_ptr & p)
{ return tree_algorithms::next_node(p); }
//! <b>Requires</b>: p is a node from the tree except the leftmost node.
@@ -307,7 +306,7 @@ class avltree_algorithms
//! <b>Complexity</b>: Average constant time.
//!
//! <b>Throws</b>: Nothing.
static node_ptr prev_node(node_ptr p)
static node_ptr prev_node(const node_ptr & p)
{ return tree_algorithms::prev_node(p); }
//! <b>Requires</b>: node must not be part of any tree.
@@ -319,7 +318,7 @@ class avltree_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
static void init(node_ptr node)
static void init(const node_ptr & node)
{ tree_algorithms::init(node); }
//! <b>Requires</b>: node must not be part of any tree.
@@ -332,7 +331,7 @@ class avltree_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
static void init_header(node_ptr header)
static void init_header(const node_ptr & header)
{
tree_algorithms::init_header(header);
NodeTraits::set_balance(header, NodeTraits::zero());
@@ -346,7 +345,7 @@ class avltree_algorithms
//! <b>Complexity</b>: Amortized constant time.
//!
//! <b>Throws</b>: Nothing.
static node_ptr erase(node_ptr header, node_ptr z)
static node_ptr erase(const node_ptr & header, const node_ptr & z)
{
typename tree_algorithms::data_for_rebalance info;
tree_algorithms::erase(header, z, avltree_erase_fixup(), info);
@@ -363,13 +362,13 @@ class avltree_algorithms
//! take a node_ptr and shouldn't throw.
//!
//! <b>Effects</b>: First empties target tree calling
//! <tt>void disposer::operator()(node_ptr)</tt> for every node of the tree
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
//! except the header.
//!
//! Then, duplicates the entire tree pointed by "source_header" cloning each
//! source node with <tt>node_ptr Cloner::operator()(node_ptr)</tt> to obtain
//! source node with <tt>node_ptr Cloner::operator()(const node_ptr &)</tt> to obtain
//! the nodes of the target tree. If "cloner" throws, the cloned target nodes
//! are disposed using <tt>void disposer(node_ptr)</tt>.
//! are disposed using <tt>void disposer(const node_ptr &)</tt>.
//!
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
//! number of elements of tree target tree when calling this function.
@@ -377,7 +376,7 @@ class avltree_algorithms
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
template <class Cloner, class Disposer>
static void clone
(const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer)
(const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer)
{
avltree_node_cloner<Cloner> new_cloner(cloner);
tree_algorithms::clone(source_header, target_header, new_cloner, disposer);
@@ -387,7 +386,7 @@ class avltree_algorithms
//! taking a node_ptr parameter and shouldn't throw.
//!
//! <b>Effects</b>: Empties the target tree calling
//! <tt>void disposer::operator()(node_ptr)</tt> for every node of the tree
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
//! except the header.
//!
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
@@ -395,7 +394,7 @@ class avltree_algorithms
//!
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
template<class Disposer>
static void clear_and_dispose(node_ptr header, Disposer disposer)
static void clear_and_dispose(const node_ptr & header, Disposer disposer)
{ tree_algorithms::clear_and_dispose(header, disposer); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -412,7 +411,7 @@ class avltree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr lower_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{ return tree_algorithms::lower_bound(header, key, comp); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -428,7 +427,7 @@ class avltree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr upper_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{ return tree_algorithms::upper_bound(header, key, comp); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -444,7 +443,7 @@ class avltree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr find
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{ return tree_algorithms::find(header, key, comp); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -462,7 +461,7 @@ class avltree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> equal_range
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{ return tree_algorithms::equal_range(header, key, comp); }
//! <b>Requires</b>: "h" must be the header node of a tree.
@@ -479,7 +478,7 @@ class avltree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare>
static node_ptr insert_equal_upper_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp)
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp)
{
tree_algorithms::insert_equal_upper_bound(h, new_node, comp);
rebalance_after_insertion(h, new_node);
@@ -500,7 +499,7 @@ class avltree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare>
static node_ptr insert_equal_lower_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp)
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp)
{
tree_algorithms::insert_equal_lower_bound(h, new_node, comp);
rebalance_after_insertion(h, new_node);
@@ -523,7 +522,7 @@ class avltree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare>
static node_ptr insert_equal
(node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp)
(const node_ptr & header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp)
{
tree_algorithms::insert_equal(header, hint, new_node, comp);
rebalance_after_insertion(header, new_node);
@@ -545,7 +544,7 @@ class avltree_algorithms
//! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
//! tree invariants might be broken.
static node_ptr insert_before
(node_ptr header, node_ptr pos, node_ptr new_node)
(const node_ptr & header, const node_ptr & pos, const node_ptr & new_node)
{
tree_algorithms::insert_before(header, pos, new_node);
rebalance_after_insertion(header, new_node);
@@ -565,7 +564,7 @@ class avltree_algorithms
//! <b>Note</b>: If "new_node" is less than the greatest inserted key
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
static void push_back(node_ptr header, node_ptr new_node)
static void push_back(const node_ptr & header, const node_ptr & new_node)
{
tree_algorithms::push_back(header, new_node);
rebalance_after_insertion(header, new_node);
@@ -584,7 +583,7 @@ class avltree_algorithms
//! <b>Note</b>: If "new_node" is greater than the lowest inserted key
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
static void push_front(node_ptr header, node_ptr new_node)
static void push_front(const node_ptr & header, const node_ptr & new_node)
{
tree_algorithms::push_front(header, new_node);
rebalance_after_insertion(header, new_node);
@@ -626,7 +625,7 @@ class avltree_algorithms
//! if no more objects are inserted or erased from the set.
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(const_node_ptr header, const KeyType &key
(const const_node_ptr & header, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data)
{ return tree_algorithms::insert_unique_check(header, key, comp, commit_data); }
@@ -671,7 +670,7 @@ class avltree_algorithms
//! if no more objects are inserted or erased from the set.
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(const_node_ptr header, node_ptr hint, const KeyType &key
(const const_node_ptr & header, const node_ptr &hint, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data)
{ return tree_algorithms::insert_unique_check(header, hint, key, comp, commit_data); }
@@ -693,7 +692,7 @@ class avltree_algorithms
//! previously executed to fill "commit_data". No value should be inserted or
//! erased between the "insert_check" and "insert_commit" calls.
static void insert_unique_commit
(node_ptr header, node_ptr new_value, const insert_commit_data &commit_data)
(const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data)
{
tree_algorithms::insert_unique_commit(header, new_value, commit_data);
rebalance_after_insertion(header, new_value);
@@ -706,7 +705,7 @@ class avltree_algorithms
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: Nothing.
static node_ptr get_header(node_ptr n)
static node_ptr get_header(const node_ptr & n)
{ return tree_algorithms::get_header(n); }
/// @cond
@@ -719,11 +718,12 @@ class avltree_algorithms
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
static bool is_header(const_node_ptr p)
static bool is_header(const const_node_ptr & p)
{ return NodeTraits::get_balance(p) == NodeTraits::zero() && tree_algorithms::is_header(p); }
static void rebalance_after_erasure(node_ptr header, node_ptr x, node_ptr x_parent)
static void rebalance_after_erasure(const node_ptr & header, const node_ptr & xnode, const node_ptr & xnode_parent)
{
node_ptr x(xnode), x_parent(xnode_parent);
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);
if(x_parent_balance == NodeTraits::zero()){
@@ -797,10 +797,10 @@ class avltree_algorithms
}
}
static void rebalance_after_insertion(node_ptr header, node_ptr x)
static void rebalance_after_insertion(const node_ptr & header, const node_ptr & xnode)
{
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));
@@ -843,7 +843,7 @@ class avltree_algorithms
}
}
static void left_right_balancing(node_ptr a, node_ptr b, node_ptr c)
static void left_right_balancing(const node_ptr & a, const node_ptr & b, const node_ptr & c)
{
// balancing...
const balance c_balance = NodeTraits::get_balance(c);
@@ -866,7 +866,7 @@ class avltree_algorithms
}
}
static void rotate_left_right(const node_ptr a, node_ptr hdr)
static void rotate_left_right(const node_ptr a, const node_ptr & hdr)
{
// | | //
// a(-2) c //
@@ -883,7 +883,7 @@ class avltree_algorithms
left_right_balancing(a, b, c);
}
static void rotate_right_left(const node_ptr a, node_ptr hdr)
static void rotate_right_left(const node_ptr a, const node_ptr & hdr)
{
// | | //
// a(pos) c //
@@ -900,7 +900,7 @@ class avltree_algorithms
left_right_balancing(b, a, c);
}
static void rotate_left(const node_ptr x, node_ptr hdr)
static void rotate_left(const node_ptr x, const node_ptr & hdr)
{
const node_ptr y = NodeTraits::get_right(x);
tree_algorithms::rotate_left(x, hdr);
@@ -916,7 +916,7 @@ class avltree_algorithms
}
}
static void rotate_right(const node_ptr x, node_ptr hdr)
static void rotate_right(const node_ptr x, const node_ptr & hdr)
{
const node_ptr y = NodeTraits::get_left(x);
tree_algorithms::rotate_right(x, hdr);

View File

@@ -61,10 +61,10 @@ class circular_list_algorithms
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void init(node_ptr this_node)
static void init(const node_ptr &this_node)
{
NodeTraits::set_next(this_node, node_ptr(0));
NodeTraits::set_previous(this_node, node_ptr(0));
NodeTraits::set_next(this_node, node_ptr());
NodeTraits::set_previous(this_node, node_ptr());
}
//! <b>Effects</b>: Returns true is "this_node" is in a non-used state
@@ -73,7 +73,7 @@ class circular_list_algorithms
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static bool inited(const_node_ptr this_node)
static bool inited(const const_node_ptr &this_node)
{ return !NodeTraits::get_next(this_node); }
//! <b>Effects</b>: Constructs an empty list, making this_node the only
@@ -84,7 +84,7 @@ class circular_list_algorithms
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void init_header(node_ptr this_node)
static void init_header(const node_ptr &this_node)
{
NodeTraits::set_next(this_node, this_node);
NodeTraits::set_previous(this_node, this_node);
@@ -99,7 +99,7 @@ class circular_list_algorithms
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static bool unique(const_node_ptr this_node)
static bool unique(const const_node_ptr &this_node)
{
node_ptr next = NodeTraits::get_next(this_node);
return !next || next == this_node;
@@ -113,7 +113,7 @@ class circular_list_algorithms
//! <b>Complexity</b>: Linear
//!
//! <b>Throws</b>: Nothing.
static std::size_t count(const_node_ptr this_node)
static std::size_t count(const const_node_ptr &this_node)
{
std::size_t result = 0;
const_node_ptr p = this_node;
@@ -131,10 +131,10 @@ class circular_list_algorithms
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static node_ptr unlink(node_ptr this_node)
static node_ptr unlink(const node_ptr &this_node)
{
if(NodeTraits::get_next(this_node)){
node_ptr next(NodeTraits::get_next(this_node));
node_ptr next(NodeTraits::get_next(this_node));
if(next){
node_ptr prev(NodeTraits::get_previous(this_node));
NodeTraits::set_next(prev, next);
NodeTraits::set_previous(next, prev);
@@ -152,7 +152,7 @@ class circular_list_algorithms
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void unlink(node_ptr b, node_ptr e)
static void unlink(const node_ptr &b, const node_ptr &e)
{
if (b != e) {
node_ptr prevb(NodeTraits::get_previous(b));
@@ -168,13 +168,16 @@ class circular_list_algorithms
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void link_before(node_ptr nxt_node, node_ptr this_node)
static void link_before(const node_ptr &nxt_node, const node_ptr &this_node)
{
node_ptr prev(NodeTraits::get_previous(nxt_node));
NodeTraits::set_previous(this_node, prev);
NodeTraits::set_next(prev, this_node);
NodeTraits::set_previous(nxt_node, this_node);
NodeTraits::set_next(this_node, nxt_node);
//nxt_node might be an alias for prev->next_
//so use it before update it before NodeTraits::set_next(prev, ...)
//is called and the reference changes it's value
NodeTraits::set_previous(nxt_node, this_node);
NodeTraits::set_next(prev, this_node);
}
//! <b>Requires</b>: prev_node must be a node of a circular list.
@@ -184,13 +187,16 @@ class circular_list_algorithms
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void link_after(node_ptr prev_node, node_ptr this_node)
static void link_after(const node_ptr &prev_node, const node_ptr &this_node)
{
node_ptr next(NodeTraits::get_next(prev_node));
NodeTraits::set_previous(this_node, prev_node);
NodeTraits::set_next(this_node, next);
NodeTraits::set_previous(next, this_node);
//prev_node might be an alias for next->next_
//so use it before update it before NodeTraits::set_previous(next, ...)
//is called and the reference changes it's value
NodeTraits::set_next(prev_node, this_node);
NodeTraits::set_previous(next, this_node);
}
//! <b>Requires</b>: this_node and other_node must be nodes inserted
@@ -204,7 +210,7 @@ class circular_list_algorithms
//!
//! <b>Throws</b>: Nothing.
/*
static void swap_nodes(node_ptr this_node, node_ptr other_node)
static void swap_nodes(const node_ptr &this_node, const node_ptr &other_node)
{
if (other_node == this_node)
@@ -243,13 +249,13 @@ class circular_list_algorithms
//Watanabe version
private:
static void swap_prev(node_ptr this_node, node_ptr other_node)
static void swap_prev(const node_ptr &this_node, const node_ptr &other_node)
{
node_ptr temp(NodeTraits::get_previous(this_node));
NodeTraits::set_previous(this_node, NodeTraits::get_previous(other_node));
NodeTraits::set_previous(other_node, temp);
}
static void swap_next(node_ptr this_node, node_ptr other_node)
static void swap_next(const node_ptr &this_node, const node_ptr &other_node)
{
node_ptr temp(NodeTraits::get_next(this_node));
NodeTraits::set_next(this_node, NodeTraits::get_next(other_node));
@@ -257,7 +263,7 @@ class circular_list_algorithms
}
public:
static void swap_nodes(node_ptr this_node, node_ptr other_node)
static void swap_nodes(const node_ptr &this_node, const node_ptr &other_node)
{
if (other_node == this_node)
return;
@@ -298,7 +304,7 @@ class circular_list_algorithms
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void transfer(node_ptr p, node_ptr b, node_ptr e)
static void transfer(const node_ptr &p, const node_ptr &b, const node_ptr &e)
{
if (b != e) {
node_ptr prev_p(NodeTraits::get_previous(p));
@@ -323,7 +329,7 @@ class circular_list_algorithms
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void transfer(node_ptr p, node_ptr i)
static void transfer(const node_ptr &p, const node_ptr &i)
{
node_ptr n(NodeTraits::get_next(i));
if(n != p && i != p){
@@ -344,7 +350,7 @@ class circular_list_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: This function is linear time.
static void reverse(node_ptr p)
static void reverse(const node_ptr &p)
{
node_ptr f(NodeTraits::get_next(p));
node_ptr i(NodeTraits::get_next(f)), e(p);
@@ -362,7 +368,7 @@ class circular_list_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of moved positions.
static void move_backwards(node_ptr p, std::size_t n)
static void move_backwards(const node_ptr &p, std::size_t n)
{
//Null shift, nothing to do
if(!n) return;
@@ -382,7 +388,7 @@ class circular_list_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of moved positions.
static void move_forward(node_ptr p, std::size_t n)
static void move_forward(const node_ptr &p, std::size_t n)
{
//Null shift, nothing to do
if(!n) return;

View File

@@ -63,7 +63,7 @@ class circular_slist_algorithms
//! <b>Effects</b>: Constructs an non-used list element, putting the next
//! pointer to null:
//! <tt>NodeTraits::get_next(this_node) == 0</tt>
//! <tt>NodeTraits::get_next(this_node) == node_ptr()</tt>
//!
//! <b>Complexity</b>: Constant
//!
@@ -74,7 +74,7 @@ class circular_slist_algorithms
//!
//! <b>Effects</b>: Returns true is "this_node" is the only node of a circular list:
//! or it's a not inserted node:
//! <tt>return !NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node</tt>
//! <tt>return false == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node</tt>
//!
//! <b>Complexity</b>: Constant
//!
@@ -137,7 +137,7 @@ class circular_slist_algorithms
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void init_header(node_ptr this_node)
static void init_header(const node_ptr &this_node)
{ NodeTraits::set_next(this_node, this_node); }
//! <b>Requires</b>: this_node and prev_init_node must be in the same circular list.
@@ -149,7 +149,7 @@ class circular_slist_algorithms
//! <b>Complexity</b>: Linear to the number of elements between prev_init_node and this_node.
//!
//! <b>Throws</b>: Nothing.
static node_ptr get_previous_node(node_ptr prev_init_node, node_ptr this_node)
static node_ptr get_previous_node(const node_ptr &prev_init_node, const node_ptr &this_node)
{ return base_t::get_previous_node(prev_init_node, this_node); }
//! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
@@ -159,7 +159,7 @@ class circular_slist_algorithms
//! <b>Complexity</b>: Linear to the number of elements in the circular list.
//!
//! <b>Throws</b>: Nothing.
static node_ptr get_previous_node(node_ptr this_node)
static node_ptr get_previous_node(const node_ptr & this_node)
{ return base_t::get_previous_node(this_node, this_node); }
//! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
@@ -169,7 +169,7 @@ class circular_slist_algorithms
//! <b>Complexity</b>: Linear to the number of elements in the circular list.
//!
//! <b>Throws</b>: Nothing.
static node_ptr get_previous_previous_node(node_ptr this_node)
static node_ptr get_previous_previous_node(const node_ptr & this_node)
{ return get_previous_previous_node(this_node, this_node); }
//! <b>Requires</b>: this_node and prev_prev_init_node must be in the same circular list.
@@ -181,7 +181,7 @@ class circular_slist_algorithms
//! <b>Complexity</b>: Linear to the number of elements in the circular list.
//!
//! <b>Throws</b>: Nothing.
static node_ptr get_previous_previous_node(node_ptr prev_prev_init_node, node_ptr this_node)
static node_ptr get_previous_previous_node(const node_ptr & prev_prev_init_node, const node_ptr & this_node)
{
node_ptr p = prev_prev_init_node;
node_ptr p_next = NodeTraits::get_next(p);
@@ -202,7 +202,7 @@ class circular_slist_algorithms
//! <b>Complexity</b>: Linear
//!
//! <b>Throws</b>: Nothing.
static std::size_t count(const_node_ptr this_node)
static std::size_t count(const const_node_ptr & this_node)
{
std::size_t result = 0;
const_node_ptr p = this_node;
@@ -220,7 +220,7 @@ class circular_slist_algorithms
//! <b>Complexity</b>: Linear to the number of elements in the circular list
//!
//! <b>Throws</b>: Nothing.
static void unlink(node_ptr this_node)
static void unlink(const node_ptr & this_node)
{
if(NodeTraits::get_next(this_node))
base_t::unlink_after(get_previous_node(this_node));
@@ -233,7 +233,7 @@ class circular_slist_algorithms
//! <b>Complexity</b>: Linear to the number of elements in the circular list.
//!
//! <b>Throws</b>: Nothing.
static void link_before (node_ptr nxt_node, node_ptr this_node)
static void link_before (const node_ptr & nxt_node, const node_ptr & this_node)
{ base_t::link_after(get_previous_node(nxt_node), this_node); }
//! <b>Requires</b>: this_node and other_node must be nodes inserted
@@ -246,7 +246,7 @@ class circular_slist_algorithms
//! <b>Complexity</b>: Linear to number of elements of both lists
//!
//! <b>Throws</b>: Nothing.
static void swap_nodes(node_ptr this_node, node_ptr other_node)
static void swap_nodes(const node_ptr & this_node, const node_ptr & other_node)
{
if (other_node == this_node)
return;
@@ -284,7 +284,7 @@ class circular_slist_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: This function is linear to the contained elements.
static void reverse(node_ptr p)
static void reverse(const node_ptr & p)
{
node_ptr i = NodeTraits::get_next(p), e(p);
for (;;) {
@@ -303,18 +303,18 @@ class circular_slist_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements plus the number moved positions.
static node_ptr move_backwards(node_ptr p, std::size_t n)
static node_ptr move_backwards(const node_ptr & p, std::size_t n)
{
//Null shift, nothing to do
if(!n) return node_ptr(0);
if(!n) return node_ptr();
node_ptr first = NodeTraits::get_next(p);
//count() == 1 or 2, nothing to do
if(NodeTraits::get_next(first) == p)
return node_ptr(0);
return node_ptr();
bool end_found = false;
node_ptr new_last(0);
node_ptr new_last = node_ptr();
//Now find the new last node according to the shift count.
//If we find p before finding the new last node
@@ -327,7 +327,7 @@ class circular_slist_algorithms
//Shortcut the shift with the modulo of the size of the list
n %= i;
if(!n)
return node_ptr(0);
return node_ptr();
i = 0;
//Unlink p and continue the new first node search
first = NodeTraits::get_next(p);
@@ -355,14 +355,14 @@ class circular_slist_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements plus the number moved positions.
static node_ptr move_forward(node_ptr p, std::size_t n)
static node_ptr move_forward(const node_ptr & p, std::size_t n)
{
//Null shift, nothing to do
if(!n) return node_ptr(0);
if(!n) return node_ptr();
node_ptr first = node_traits::get_next(p);
//count() == 1 or 2, nothing to do
if(node_traits::get_next(first) == p) return node_ptr(0);
if(node_traits::get_next(first) == p) return node_ptr();
//Iterate until p is found to know where the current last node is.
//If the shift count is less than the size of the list, we can also obtain
@@ -381,7 +381,7 @@ class circular_slist_algorithms
//Shortcut the shift with the modulo of the size of the list
std::size_t new_before_last_pos = (distance - (n % distance))% distance;
//If the shift is a multiple of the size there is nothing to do
if(!new_before_last_pos) return node_ptr(0);
if(!new_before_last_pos) return node_ptr();
for( new_last = p
; new_before_last_pos--

View File

@@ -34,8 +34,10 @@ struct derivation_value_traits
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef typename boost::pointer_to_other<node_ptr, T>::type pointer;
typedef typename boost::pointer_to_other<node_ptr, const T>::type const_pointer;
typedef typename std::iterator_traits<pointer>::reference reference;
typedef typename std::iterator_traits<const_pointer>::reference const_reference;
typedef typename boost::intrusive::
pointer_traits<pointer>::reference reference;
typedef typename boost::intrusive::
pointer_traits<const_pointer>::reference const_reference;
static const link_mode_type link_mode = LinkMode;
static node_ptr to_node_ptr(reference value)
@@ -44,7 +46,7 @@ struct derivation_value_traits
static const_node_ptr to_node_ptr(const_reference value)
{ return node_ptr(&value); }
static pointer to_value_ptr(node_ptr n)
static pointer to_value_ptr(const node_ptr &n)
{
// This still fails in gcc < 4.4 so forget about it
// using ::boost::static_pointer_cast;
@@ -52,7 +54,7 @@ struct derivation_value_traits
return pointer(&static_cast<value_type&>(*n));
}
static const_pointer to_value_ptr(const_node_ptr n)
static const_pointer to_value_ptr(const const_node_ptr &n)
{
// This still fails in gcc < 4.4 so forget about it
// using ::boost::static_pointer_cast;

View File

@@ -16,7 +16,7 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <iterator>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <cstddef>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/pointer_cast.hpp>
@@ -27,8 +27,8 @@ namespace intrusive {
template<class VoidPointer>
struct any_node
{
typedef typename boost::pointer_to_other
<VoidPointer, any_node>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<any_node>::type node_ptr;
node_ptr node_ptr_1;
node_ptr node_ptr_2;
node_ptr node_ptr_3;
@@ -39,21 +39,21 @@ template<class VoidPointer>
struct any_list_node_traits
{
typedef any_node<VoidPointer> node;
typedef typename boost::pointer_to_other
<VoidPointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<VoidPointer, const node>::type const_node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<node>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<const node>::type const_node_ptr;
static node_ptr get_next(const_node_ptr n)
static const node_ptr &get_next(const const_node_ptr & n)
{ return n->node_ptr_1; }
static void set_next(node_ptr n, node_ptr next)
static void set_next(const node_ptr & n, const node_ptr & next)
{ n->node_ptr_1 = next; }
static node_ptr get_previous(const_node_ptr n)
static const node_ptr &get_previous(const const_node_ptr & n)
{ return n->node_ptr_2; }
static void set_previous(node_ptr n, node_ptr prev)
static void set_previous(const node_ptr & n, const node_ptr & prev)
{ n->node_ptr_2 = prev; }
};
@@ -62,15 +62,15 @@ template<class VoidPointer>
struct any_slist_node_traits
{
typedef any_node<VoidPointer> node;
typedef typename boost::pointer_to_other
<VoidPointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<VoidPointer, const node>::type const_node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<node>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<const node>::type const_node_ptr;
static node_ptr get_next(const_node_ptr n)
static const node_ptr &get_next(const const_node_ptr & n)
{ return n->node_ptr_1; }
static void set_next(node_ptr n, node_ptr next)
static void set_next(const node_ptr & n, const node_ptr & next)
{ n->node_ptr_1 = next; }
};
@@ -87,25 +87,22 @@ struct any_unordered_node_traits
static const bool store_hash = true;
static const bool optimize_multikey = true;
static node_ptr get_next(const_node_ptr n)
{
using ::boost::static_pointer_cast;
return static_pointer_cast<node>(n->node_ptr_1);
}
static const node_ptr &get_next(const const_node_ptr & n)
{ return n->node_ptr_1; }
static void set_next(node_ptr n, node_ptr next)
static void set_next(const node_ptr & n, const node_ptr & next)
{ n->node_ptr_1 = next; }
static node_ptr get_prev_in_group(const_node_ptr n)
static node_ptr get_prev_in_group(const const_node_ptr & n)
{ return n->node_ptr_2; }
static void set_prev_in_group(node_ptr n, node_ptr prev)
static void set_prev_in_group(const node_ptr & n, const node_ptr & prev)
{ n->node_ptr_2 = prev; }
static std::size_t get_hash(const_node_ptr n)
static std::size_t get_hash(const const_node_ptr & n)
{ return n->size_t_1; }
static void set_hash(node_ptr n, std::size_t h)
static void set_hash(const node_ptr & n, std::size_t h)
{ n->size_t_1 = h; }
};
@@ -115,35 +112,35 @@ struct any_rbtree_node_traits
{
typedef any_node<VoidPointer> node;
typedef typename boost::pointer_to_other
<VoidPointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<VoidPointer, const node>::type const_node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<node>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<const node>::type const_node_ptr;
typedef std::size_t color;
static node_ptr get_parent(const_node_ptr n)
static const node_ptr &get_parent(const const_node_ptr & n)
{ return n->node_ptr_1; }
static void set_parent(node_ptr n, node_ptr p)
static void set_parent(const node_ptr & n, const node_ptr & p)
{ n->node_ptr_1 = p; }
static node_ptr get_left(const_node_ptr n)
static const node_ptr &get_left(const const_node_ptr & n)
{ return n->node_ptr_2; }
static void set_left(node_ptr n, node_ptr l)
static void set_left(const node_ptr & n, const node_ptr & l)
{ n->node_ptr_2 = l; }
static node_ptr get_right(const_node_ptr n)
static const node_ptr &get_right(const const_node_ptr & n)
{ return n->node_ptr_3; }
static void set_right(node_ptr n, node_ptr r)
static void set_right(const node_ptr & n, const node_ptr & r)
{ n->node_ptr_3 = r; }
static color get_color(const_node_ptr n)
static color get_color(const const_node_ptr & n)
{ return n->size_t_1; }
static void set_color(node_ptr n, color c)
static void set_color(const node_ptr & n, color c)
{ n->size_t_1 = c; }
static color black()
@@ -159,34 +156,34 @@ struct any_avltree_node_traits
{
typedef any_node<VoidPointer> node;
typedef typename boost::pointer_to_other
<VoidPointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<VoidPointer, const node>::type const_node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<node>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<const node>::type const_node_ptr;
typedef std::size_t balance;
static node_ptr get_parent(const_node_ptr n)
static const node_ptr &get_parent(const const_node_ptr & n)
{ return n->node_ptr_1; }
static void set_parent(node_ptr n, node_ptr p)
static void set_parent(const node_ptr & n, const node_ptr & p)
{ n->node_ptr_1 = p; }
static node_ptr get_left(const_node_ptr n)
static const node_ptr &get_left(const const_node_ptr & n)
{ return n->node_ptr_2; }
static void set_left(node_ptr n, node_ptr l)
static void set_left(const node_ptr & n, const node_ptr & l)
{ n->node_ptr_2 = l; }
static node_ptr get_right(const_node_ptr n)
static const node_ptr &get_right(const const_node_ptr & n)
{ return n->node_ptr_3; }
static void set_right(node_ptr n, node_ptr r)
static void set_right(const node_ptr & n, const node_ptr & r)
{ n->node_ptr_3 = r; }
static balance get_balance(const_node_ptr n)
static balance get_balance(const const_node_ptr & n)
{ return n->size_t_1; }
static void set_balance(node_ptr n, balance b)
static void set_balance(const node_ptr & n, balance b)
{ n->size_t_1 = b; }
static balance negative()
@@ -205,27 +202,27 @@ struct any_tree_node_traits
{
typedef any_node<VoidPointer> node;
typedef typename boost::pointer_to_other
<VoidPointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<VoidPointer, const node>::type const_node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<node>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<const node>::type const_node_ptr;
static node_ptr get_parent(const_node_ptr n)
static const node_ptr &get_parent(const const_node_ptr & n)
{ return n->node_ptr_1; }
static void set_parent(node_ptr n, node_ptr p)
static void set_parent(const node_ptr & n, const node_ptr & p)
{ n->node_ptr_1 = p; }
static node_ptr get_left(const_node_ptr n)
static const node_ptr &get_left(const const_node_ptr & n)
{ return n->node_ptr_2; }
static void set_left(node_ptr n, node_ptr l)
static void set_left(const node_ptr & n, const node_ptr & l)
{ n->node_ptr_2 = l; }
static node_ptr get_right(const_node_ptr n)
static const node_ptr &get_right(const const_node_ptr & n)
{ return n->node_ptr_3; }
static void set_right(node_ptr n, node_ptr r)
static void set_right(const node_ptr & n, const node_ptr & r)
{ n->node_ptr_3 = r; }
};
@@ -234,10 +231,10 @@ class any_node_traits
{
public:
typedef any_node<VoidPointer> node;
typedef typename boost::pointer_to_other
<VoidPointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<VoidPointer, const node>::type const_node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<node>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<const node>::type const_node_ptr;
};
template<class VoidPointer>
@@ -249,10 +246,10 @@ class any_algorithms
public:
typedef any_node<VoidPointer> node;
typedef typename boost::pointer_to_other
<VoidPointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<VoidPointer, const node>::type const_node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<node>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<const node>::type const_node_ptr;
typedef any_node_traits<VoidPointer> node_traits;
//! <b>Requires</b>: node must not be part of any tree.
@@ -264,7 +261,7 @@ class any_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
static void init(node_ptr node)
static void init(const node_ptr & node)
{ node->node_ptr_1 = 0; };
//! <b>Effects</b>: Returns true if node is in the same state as if called init(node)
@@ -272,19 +269,19 @@ class any_algorithms
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
static bool inited(const_node_ptr node)
static bool inited(const const_node_ptr & node)
{ return !node->node_ptr_1; };
static bool unique(const_node_ptr node)
static bool unique(const const_node_ptr & node)
{ return 0 == node->node_ptr_1; }
static void unlink(node_ptr)
static void unlink(const node_ptr &)
{
//Auto-unlink hooks and unlink() are not available for any hooks
any_algorithms<VoidPointer>::template function_not_available_for_any_hooks<node_ptr>();
}
static void swap_nodes(node_ptr l, node_ptr r)
static void swap_nodes(const node_ptr & l, const node_ptr & r)
{
//Any nodes have no swap_nodes capability because they don't know
//what algorithm they must use to unlink the node from the container

View File

@@ -15,7 +15,7 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <iterator>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/avltree_algorithms.hpp>
#include <boost/intrusive/pointer_plus_bits.hpp>
#include <boost/intrusive/detail/mpl.hpp>
@@ -33,9 +33,9 @@ namespace intrusive {
template<class VoidPointer>
struct compact_avltree_node
{
typedef typename pointer_to_other
<VoidPointer
,compact_avltree_node<VoidPointer> >::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
<compact_avltree_node<VoidPointer> >::type node_ptr;
enum balance { negative_t, zero_t, positive_t };
node_ptr parent_, left_, right_;
};
@@ -44,9 +44,9 @@ struct compact_avltree_node
template<class VoidPointer>
struct avltree_node
{
typedef typename pointer_to_other
<VoidPointer
,avltree_node<VoidPointer> >::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
<avltree_node<VoidPointer> >::type node_ptr;
enum balance { negative_t, zero_t, positive_t };
node_ptr parent_, left_, right_;
balance balance_;
@@ -59,34 +59,37 @@ struct default_avltree_node_traits_impl
{
typedef avltree_node<VoidPointer> node;
typedef typename boost::pointer_to_other
<VoidPointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<VoidPointer, const node>::type const_node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
<node>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
<const node>::type const_node_ptr;
typedef typename node::balance balance;
static node_ptr get_parent(const_node_ptr n)
static const node_ptr & get_parent(const const_node_ptr & n)
{ return n->parent_; }
static void set_parent(node_ptr n, node_ptr p)
static void set_parent(const node_ptr & n, const node_ptr & p)
{ n->parent_ = p; }
static node_ptr get_left(const_node_ptr n)
static const node_ptr & get_left(const const_node_ptr & n)
{ return n->left_; }
static void set_left(node_ptr n, node_ptr l)
static void set_left(const node_ptr & n, const node_ptr & l)
{ n->left_ = l; }
static node_ptr get_right(const_node_ptr n)
static const node_ptr & get_right(const const_node_ptr & n)
{ return n->right_; }
static void set_right(node_ptr n, node_ptr r)
static void set_right(const node_ptr & n, const node_ptr & r)
{ n->right_ = r; }
static balance get_balance(const_node_ptr n)
static balance get_balance(const const_node_ptr & n)
{ return n->balance_; }
static void set_balance(node_ptr n, balance b)
static void set_balance(const node_ptr & n, balance b)
{ n->balance_ = b; }
static balance negative()
@@ -105,36 +108,39 @@ template<class VoidPointer>
struct compact_avltree_node_traits_impl
{
typedef compact_avltree_node<VoidPointer> node;
typedef typename boost::pointer_to_other
<VoidPointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<VoidPointer, const node>::type const_node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
<node>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
<const node>::type const_node_ptr;
typedef typename node::balance balance;
typedef pointer_plus_bits<node_ptr, 2> ptr_bit;
static node_ptr get_parent(const_node_ptr n)
static node_ptr get_parent(const const_node_ptr & n)
{ return ptr_bit::get_pointer(n->parent_); }
static void set_parent(node_ptr n, node_ptr p)
static void set_parent(const node_ptr & n, const node_ptr & p)
{ ptr_bit::set_pointer(n->parent_, p); }
static node_ptr get_left(const_node_ptr n)
static const node_ptr & get_left(const const_node_ptr & n)
{ return n->left_; }
static void set_left(node_ptr n, node_ptr l)
static void set_left(const node_ptr & n, const node_ptr & l)
{ n->left_ = l; }
static node_ptr get_right(const_node_ptr n)
static const node_ptr & get_right(const const_node_ptr & n)
{ return n->right_; }
static void set_right(node_ptr n, node_ptr r)
static void set_right(const node_ptr & n, const node_ptr & r)
{ n->right_ = r; }
static balance get_balance(const_node_ptr n)
static balance get_balance(const const_node_ptr & n)
{ return (balance)ptr_bit::get_bits(n->parent_); }
static void set_balance(node_ptr n, balance b)
static void set_balance(const node_ptr & n, balance b)
{ ptr_bit::set_bits(n->parent_, (std::size_t)b); }
static balance negative()

View File

@@ -31,7 +31,7 @@ class common_slist_algorithms
typedef typename NodeTraits::const_node_ptr const_node_ptr;
typedef NodeTraits node_traits;
static node_ptr get_previous_node(node_ptr prev_init_node, node_ptr this_node)
static node_ptr get_previous_node(const node_ptr & prev_init_node, const node_ptr & this_node)
{
node_ptr p = prev_init_node;
for( node_ptr p_next
@@ -44,44 +44,44 @@ class common_slist_algorithms
return p;
}
static void init_header(node_ptr this_node)
static void init_header(const node_ptr & this_node)
{ NodeTraits::set_next(this_node, this_node); }
static void init(node_ptr this_node)
{ NodeTraits::set_next(this_node, node_ptr(0)); }
static void init(const node_ptr & this_node)
{ NodeTraits::set_next(this_node, node_ptr()); }
static bool unique(const_node_ptr this_node)
static bool unique(const const_node_ptr & this_node)
{
node_ptr next = NodeTraits::get_next(this_node);
return !next || next == this_node;
}
static bool inited(const_node_ptr this_node)
static bool inited(const const_node_ptr & this_node)
{ return !NodeTraits::get_next(this_node); }
static void unlink_after(node_ptr prev_node)
static void unlink_after(const node_ptr & prev_node)
{
node_ptr this_node(NodeTraits::get_next(prev_node));
const_node_ptr this_node(NodeTraits::get_next(prev_node));
NodeTraits::set_next(prev_node, NodeTraits::get_next(this_node));
}
static void unlink_after(node_ptr prev_node, node_ptr last_node)
static void unlink_after(const node_ptr & prev_node, const node_ptr & last_node)
{ NodeTraits::set_next(prev_node, last_node); }
static void link_after(node_ptr prev_node, node_ptr this_node)
static void link_after(const node_ptr & prev_node, const node_ptr & this_node)
{
NodeTraits::set_next(this_node, NodeTraits::get_next(prev_node));
NodeTraits::set_next(prev_node, this_node);
}
static void incorporate_after(node_ptr bp, node_ptr b, node_ptr be)
static void incorporate_after(const node_ptr & bp, const node_ptr & b, const node_ptr & be)
{
node_ptr p(NodeTraits::get_next(bp));
NodeTraits::set_next(bp, b);
NodeTraits::set_next(be, p);
}
static void transfer_after(node_ptr bp, node_ptr bb, node_ptr be)
static void transfer_after(const node_ptr & bp, const node_ptr & bb, const node_ptr & be)
{
if (bp != bb && bp != be && bb != be) {
node_ptr next_b = NodeTraits::get_next(bb);

View File

@@ -11,6 +11,7 @@
/////////////////////////////////////////////////////////////////////////////
// This code was modified from the code posted by Alexandre Courpron in his
// article "Interface Detection" in The Code Project:
// http://www.codeproject.com/KB/architecture/Detector.aspx
///////////////////////////////////////////////////////////////////////////////
// Copyright 2007 Alexandre Courpron
//

View File

@@ -15,10 +15,11 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/detail/utilities.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/static_assert.hpp>
namespace boost {
@@ -146,20 +147,26 @@ class generic_hook
(int)link_mode == (int)auto_unlink || (int)link_mode == (int)safe_link;
};
node_ptr this_ptr()
{ return pointer_traits<node_ptr>::pointer_to(static_cast<node&>(*this)); }
const_node_ptr this_ptr() const
{ return pointer_traits<const_node_ptr>::pointer_to(static_cast<const node&>(*this)); }
public:
/// @endcond
generic_hook()
{
if(boost_intrusive_tags::safemode_or_autounlink){
node_algorithms::init(static_cast<node*>(this));
node_algorithms::init(this->this_ptr());
}
}
generic_hook(const generic_hook& )
{
if(boost_intrusive_tags::safemode_or_autounlink){
node_algorithms::init(static_cast<node*>(this));
node_algorithms::init(this->this_ptr());
}
}
@@ -175,22 +182,21 @@ class generic_hook
void swap_nodes(generic_hook &other)
{
node_algorithms::swap_nodes
( static_cast<node*>(this), static_cast<node*>(&other));
(this->this_ptr(), other.this_ptr());
}
bool is_linked() const
{
//is_linked() can be only used in safe-mode or auto-unlink
BOOST_STATIC_ASSERT(( boost_intrusive_tags::safemode_or_autounlink ));
return !node_algorithms::unique
(static_cast<const node*>(this));
return !node_algorithms::unique(this->this_ptr());
}
void unlink()
{
BOOST_STATIC_ASSERT(( (int)boost_intrusive_tags::link_mode == (int)auto_unlink ));
node_algorithms::unlink(static_cast<node*>(this));
node_algorithms::init(static_cast<node*>(this));
node_algorithms::unlink(this->this_ptr());
node_algorithms::init(this->this_ptr());
}
};

View File

@@ -0,0 +1,334 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-2011. 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.
//
//////////////////////////////////////////////////////////////////////////////
// sample.h
#if !BOOST_PP_IS_ITERATING
#ifndef BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED
#define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/detail/preprocessor.hpp>
#include <boost/static_assert.hpp>
#include <boost/move/move.hpp>
namespace boost_intrusive_has_member_function_callable_with {
struct dont_care
{
dont_care(...);
};
struct private_type
{
static private_type p;
private_type const &operator,(int) const;
};
typedef char yes_type; // sizeof(yes_type) == 1
struct no_type{ char dummy[2]; }; // sizeof(no_type) == 2
template<typename T>
no_type is_private_type(T const &);
yes_type is_private_type(private_type const &);
} //boost_intrusive_has_member_function_callable_with
#include <boost/intrusive/detail/config_end.hpp>
#endif //BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_DETAILS_INCLUDED
#else //!BOOST_PP_IS_ITERATING
#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
#error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME not defined!"
#endif
#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
#error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN not defined!"
#endif
#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
#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)"
#endif
#if BOOST_PP_ITERATION() == 0
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
template <typename Type>
class BOOST_PP_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)
{
struct BaseMixin
{
void BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME();
};
struct Base : public Type, public BaseMixin { Base(); };
template <typename T, T t> class Helper{};
template <typename U>
static boost_intrusive_has_member_function_callable_with::no_type deduce
(U*, Helper<void (BaseMixin::*)(), &U::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME>* = 0);
static boost_intrusive_has_member_function_callable_with::yes_type deduce(...);
public:
static const bool value =
sizeof(boost_intrusive_has_member_function_callable_with::yes_type) == sizeof(deduce((Base*)(0)));
};
#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
template<typename Fun, bool HasFunc
BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION_FINISH(), BOOST_INTRUSIVE_PP_TEMPLATE_PARAM_VOID_DEFAULT, _)>
struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl);
//!
template<typename Fun BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION_FINISH(), class P)>
struct BOOST_PP_CAT(BOOST_PP_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME), _impl)
<Fun, false BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION_FINISH(), P)>
{
static const bool value = false;
};
//!
#if !defined(_MSC_VER) || (_MSC_VER != 1600)
//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 BOOST_PP_ENUM_TRAILING(BOOST_PP_SUB(BOOST_PP_ITERATION_FINISH(), BOOST_PP_ITERATION()), BOOST_INTRUSIVE_PP_IDENTITY, void)>
{
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);
};
#else //#if !defined(_MSC_VER) || (_MSC_VER != 1600)
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 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()
, boost_intrusive_has_member_function_callable_with::yes_type())
Test(Fun*);
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);
};
#endif //#if !defined(_MSC_VER) || (_MSC_VER != 1600)
#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
#else //BOOST_PP_ITERATION() == 0
#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
template<typename Fun>
struct BOOST_PP_CAT( BOOST_PP_CAT(funwrap, BOOST_PP_ITERATION())
, BOOST_PP_CAT(_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME))
: Fun
{
BOOST_PP_CAT( BOOST_PP_CAT(funwrap, BOOST_PP_ITERATION())
, BOOST_PP_CAT(_, 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
( BOOST_PP_ENUM(BOOST_PP_ITERATION()
, BOOST_INTRUSIVE_PP_IDENTITY
, boost_intrusive_has_member_function_callable_with::dont_care)) const;
};
template<typename Fun BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), class P)>
struct BOOST_PP_CAT( BOOST_PP_CAT(has_member_function_callable_with_
, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME),_impl)
<Fun, true
BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), P)
BOOST_PP_ENUM_TRAILING( BOOST_PP_SUB(BOOST_PP_ITERATION_FINISH(), BOOST_PP_ITERATION())
, BOOST_INTRUSIVE_PP_IDENTITY
, void)>
{
typedef BOOST_PP_CAT( BOOST_PP_CAT(funwrap, BOOST_PP_ITERATION())
, BOOST_PP_CAT(_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME))<Fun>
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_PP_ENUM( BOOST_PP_ITERATION(), BOOST_INTRUSIVE_PP_DECLVAL, _) ), 0
)
)
)
);
};
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
#endif //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
#endif //BOOST_PP_ITERATION() == 0
#if BOOST_PP_ITERATION() == BOOST_PP_ITERATION_FINISH()
#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
template<typename Fun
BOOST_PP_ENUM_TRAILING(BOOST_PP_ITERATION_FINISH(), BOOST_INTRUSIVE_PP_TEMPLATE_PARAM_VOID_DEFAULT, _)>
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
BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION_FINISH(), P) >
{};
BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
#endif //#if !defined(BOOST_INTRUSIVE_PERFECT_FORWARDING)
#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME
#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEGIN
#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END
#endif //#if BOOST_PP_ITERATION() == BOOST_PP_ITERATION_FINISH()
#endif //!BOOST_PP_IS_ITERATING

View File

@@ -16,11 +16,12 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <iterator>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/circular_list_algorithms.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/utilities.hpp>
#include <boost/intrusive/detail/slist_node.hpp> //remove-me
//#include <boost/intrusive/detail/slist_node.hpp> //remove-me
#include <boost/intrusive/pointer_traits.hpp>
#include <cstddef>
#include <boost/pointer_cast.hpp>
#include <boost/move/move.hpp>
@@ -84,8 +85,10 @@ struct bucket_traits_impl
public:
/// @cond
typedef typename boost::pointer_to_other
< typename Slist::pointer, bucket_impl<Slist> >::type bucket_ptr;
typedef typename pointer_traits
<typename Slist::pointer>::template rebind_pointer
< bucket_impl<Slist> >::type bucket_ptr;
typedef typename Slist::size_type size_type;
/// @endcond
@@ -93,14 +96,19 @@ struct bucket_traits_impl
: buckets_(buckets), buckets_len_(len)
{}
bucket_traits_impl(const bucket_traits_impl &x)
: buckets_(x.buckets_), buckets_len_(x.buckets_len_)
{}
bucket_traits_impl(BOOST_RV_REF(bucket_traits_impl) x)
: buckets_(x.buckets_), buckets_len_(x.buckets_len_)
{ x.buckets_ = bucket_ptr(0); x.buckets_len_ = 0; }
{ x.buckets_ = bucket_ptr(); x.buckets_len_ = 0; }
bucket_traits_impl& operator=(BOOST_RV_REF(bucket_traits_impl) x)
{
buckets_ = x.buckets_; buckets_len_ = x.buckets_len_;
x.buckets_ = bucket_ptr(0); x.buckets_len_ = 0; return *this;
x.buckets_ = bucket_ptr(); x.buckets_len_ = 0; return *this;
}
bucket_traits_impl& operator=(BOOST_COPY_ASSIGN_REF(bucket_traits_impl) x)
@@ -108,7 +116,7 @@ struct bucket_traits_impl
buckets_ = x.buckets_; buckets_len_ = x.buckets_len_; return *this;
}
bucket_ptr bucket_begin() const
const bucket_ptr &bucket_begin() const
{ return buckets_; }
size_type bucket_count() const
@@ -124,7 +132,7 @@ class hashtable_iterator
: public std::iterator
< std::forward_iterator_tag
, typename Container::value_type
, typename std::iterator_traits<typename Container::value_type*>::difference_type
, typename pointer_traits<typename Container::value_type*>::difference_type
, typename detail::add_const_if_c
<typename Container::value_type, IsConst>::type *
, typename detail::add_const_if_c
@@ -135,16 +143,16 @@ class hashtable_iterator
typedef typename Container::siterator siterator;
typedef typename Container::const_siterator const_siterator;
typedef typename Container::bucket_type bucket_type;
typedef typename boost::pointer_to_other
< typename Container::pointer, const Container>::type const_cont_ptr;
typedef typename pointer_traits
<typename Container::pointer>::template rebind_pointer
< const Container >::type const_cont_ptr;
typedef typename Container::size_type size_type;
static typename Container::node_ptr downcast_bucket(typename bucket_type::node_ptr p)
{
// This still fails in gcc < 4.4 so forget about it
// using ::boost::static_pointer_cast;
// return static_pointer_cast<typename Container::node>(p);
return typename Container::node_ptr(&static_cast<typename Container::node&>(*p));
return pointer_traits<typename Container::node_ptr>::
pointer_to(static_cast<typename Container::node&>(*p));
}
public:
@@ -158,7 +166,7 @@ class hashtable_iterator
{}
explicit hashtable_iterator(siterator ptr, const Container *cont)
: slist_it_ (ptr), cont_ (cont)
: slist_it_ (ptr), cont_ (cont ? pointer_traits<const_cont_ptr>::pointer_to(*cont) : const_cont_ptr() )
{}
hashtable_iterator(const hashtable_iterator<Container, false> &other)
@@ -192,10 +200,13 @@ class hashtable_iterator
{ return *this->operator ->(); }
pointer operator->() const
{ return detail::boost_intrusive_get_pointer(this->get_real_value_traits()->to_value_ptr(downcast_bucket(slist_it_.pointed_node()))); }
{
return boost::intrusive::detail::to_raw_pointer(this->get_real_value_traits()->to_value_ptr
(downcast_bucket(slist_it_.pointed_node())));
}
const Container *get_container() const
{ return detail::boost_intrusive_get_pointer(cont_); }
const const_cont_ptr &get_container() const
{ return cont_; }
const real_value_traits *get_real_value_traits() const
{ return &this->get_container()->get_real_value_traits(); }
@@ -203,8 +214,8 @@ class hashtable_iterator
private:
void increment()
{
const Container *cont = detail::boost_intrusive_get_pointer(cont_);
bucket_type* buckets = detail::boost_intrusive_get_pointer(cont->bucket_pointer());
const Container *cont = boost::intrusive::detail::to_raw_pointer(cont_);
bucket_type* buckets = boost::intrusive::detail::to_raw_pointer(cont->bucket_pointer());
size_type buckets_len = cont->bucket_count();
++slist_it_;

View File

@@ -17,7 +17,7 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <iterator>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
namespace boost {
namespace intrusive {
@@ -29,8 +29,8 @@ namespace intrusive {
template<class VoidPointer>
struct list_node
{
typedef typename boost::pointer_to_other
<VoidPointer, list_node>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>:: template rebind_pointer<list_node>::type node_ptr;
node_ptr next_;
node_ptr prev_;
};
@@ -39,21 +39,21 @@ template<class VoidPointer>
struct list_node_traits
{
typedef list_node<VoidPointer> node;
typedef typename boost::pointer_to_other
<VoidPointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<VoidPointer, const node>::type const_node_ptr;
typedef typename pointer_traits
<VoidPointer>:: template rebind_pointer<node>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>:: template rebind_pointer<const node>::type const_node_ptr;
static node_ptr get_previous(const_node_ptr n)
static const node_ptr &get_previous(const const_node_ptr & n)
{ return n->prev_; }
static void set_previous(node_ptr n, node_ptr prev)
static void set_previous(const node_ptr & n, const node_ptr & prev)
{ n->prev_ = prev; }
static node_ptr get_next(const_node_ptr n)
static const node_ptr &get_next(const const_node_ptr & n)
{ return n->next_; }
static void set_next(node_ptr n, node_ptr next)
static void set_next(const node_ptr & n, const node_ptr & next)
{ n->next_ = next; }
};
@@ -74,8 +74,8 @@ class list_iterator
typedef typename real_value_traits::node_traits node_traits;
typedef typename node_traits::node node;
typedef typename node_traits::node_ptr node_ptr;
typedef typename boost::pointer_to_other
<node_ptr, void>::type void_pointer;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<void>::type void_pointer;
static const bool store_container_ptr =
detail::store_cont_ptr_on_it<Container>::value;
@@ -85,10 +85,10 @@ class list_iterator
typedef typename detail::if_c<IsConst,typename Container::const_reference,typename Container::reference>::type reference;
list_iterator()
: members_ (node_ptr(0), 0)
: members_ (node_ptr(), 0)
{}
explicit list_iterator(node_ptr node, const Container *cont_ptr)
explicit list_iterator(const node_ptr & node, const Container *cont_ptr)
: members_ (node, cont_ptr)
{}
@@ -105,7 +105,9 @@ class list_iterator
public:
list_iterator& operator++()
{
members_.nodeptr_ = node_traits::get_next(members_.nodeptr_);
node_ptr p = node_traits::get_next(members_.nodeptr_);
members_.nodeptr_ = p;
//members_.nodeptr_ = node_traits::get_next(members_.nodeptr_);
return static_cast<list_iterator&> (*this);
}
@@ -139,7 +141,7 @@ class list_iterator
{ return *operator->(); }
pointer operator->() const
{ return detail::boost_intrusive_get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); }
{ return this->get_real_value_traits()->to_value_ptr(members_.nodeptr_); }
const Container *get_container() const
{

View File

@@ -0,0 +1,250 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Pablo Halpern 2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-2011. 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_ALLOCATOR_MEMORY_UTIL_HPP
#define BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/preprocessor.hpp>
namespace boost {
namespace intrusive {
namespace detail {
template <typename T>
inline T* addressof(T& obj)
{
return static_cast<T*>
(static_cast<void*>
(const_cast<char*>
(&reinterpret_cast<const char&>(obj))
)
);
}
template <typename T> struct unvoid { typedef T type; };
template <> struct unvoid<void> { struct type { }; };
template <> struct unvoid<const void> { struct type { }; };
template <typename T>
struct LowPriorityConversion
{
// Convertible from T with user-defined-conversion rank.
LowPriorityConversion(const T&) { }
};
// Infrastructure for providing a default type for T::TNAME if absent.
#define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \
template <typename T, typename DefaultType> \
struct boost_intrusive_default_type_ ## TNAME \
{ \
template <typename X> \
static char test(int, typename X::TNAME*); \
\
template <typename X> \
static int test(boost::intrusive::detail:: \
LowPriorityConversion<int>, void*); \
\
struct DefaultWrap { typedef DefaultType TNAME; }; \
\
static const bool value = (1 == sizeof(test<T>(0, 0))); \
\
typedef typename \
::boost::intrusive::detail::if_c<value, T, DefaultWrap>::type::TNAME type; \
} \
//
#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \
typename INSTANTIATION_NS_PREFIX \
boost_intrusive_default_type_ ## TNAME<T, TIMPL>::type \
//
}}} //namespace boost::intrusive::detail
#include <boost/intrusive/detail/has_member_function_callable_with.hpp>
#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>))
#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>))
#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>))
#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>))
#include BOOST_PP_ITERATE()
namespace boost {
namespace intrusive {
namespace detail {
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(element_type);
BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type);
//////////////////////
//struct first_param
//////////////////////
template <typename T> struct first_param
{ typedef void type; };
#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
template <template <typename, typename...> class TemplateClass, typename T, typename... Args>
struct first_param< TemplateClass<T, Args...> >
{
typedef T type;
};
#else //C++03 compilers
#define BOOST_PP_LOCAL_MACRO(n) \
template < template <typename \
BOOST_PP_ENUM_TRAILING(n, BOOST_INTRUSIVE_PP_IDENTITY, typename) > \
class TemplateClass \
, typename T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P)> \
struct first_param \
< TemplateClass<T BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> > \
{ \
typedef T type; \
}; \
//
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_INTRUSIVE_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //!defined(BOOST_NO_VARIADIC_TEMPLATES)
///////////////////////////
//struct type_rebind_mode
///////////////////////////
template <typename Ptr, typename T>
struct type_has_rebind
{
template <typename X>
static char test(int, typename X::template rebind<T>*);
template <typename X>
static int test(boost::intrusive::detail::LowPriorityConversion<int>, void*);
static const bool value = (1 == sizeof(test<Ptr>(0, 0)));
};
template <typename Ptr, typename T>
struct type_has_rebind_other
{
template <typename X>
static char test(int, typename X::template rebind<T>::other*);
template <typename X>
static int test(boost::intrusive::detail::LowPriorityConversion<int>, void*);
static const bool value = (1 == sizeof(test<Ptr>(0, 0)));
};
template <typename Ptr, typename T>
struct type_rebind_mode
{
template <typename X>
static char test(int, typename X::template rebind<T>::other*);
template <typename X>
static int test(boost::intrusive::detail::LowPriorityConversion<int>, void*);
static const unsigned int rebind = (unsigned int)type_has_rebind<Ptr, T>::value;
static const unsigned int rebind_other = (unsigned int)type_has_rebind_other<Ptr, T>::value;
static const unsigned int mode = rebind + rebind*rebind_other;
};
////////////////////////
//struct type_rebinder
////////////////////////
template <typename Ptr, typename U, unsigned int RebindMode = type_rebind_mode<Ptr, U>::mode>
struct type_rebinder;
// Implementation of pointer_traits<Ptr>::rebind if Ptr has
// its own rebind::other type (C++03)
template <typename Ptr, typename U>
struct type_rebinder< Ptr, U, 2u >
{
typedef typename Ptr::template rebind<U>::other type;
};
// Implementation of pointer_traits<Ptr>::rebind if Ptr has
// its own rebind template.
template <typename Ptr, typename U>
struct type_rebinder< Ptr, U, 1u >
{
typedef typename Ptr::template rebind<U> type;
};
// Specialization of pointer_traits<Ptr>::rebind if Ptr does not
// have its own rebind template but has a the form Ptr<class T,
// OtherArgs>, where OtherArgs comprises zero or more type parameters.
// Many pointers fit this form, hence many pointers will get a
// reasonable default for rebind.
#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
template <template <class, class...> class Ptr, typename T, class... Tn, class U>
struct type_rebinder<Ptr<T, Tn...>, U, 0u >
{
typedef Ptr<U, Tn...> type;
};
#else //C++03 compilers
#define BOOST_PP_LOCAL_MACRO(n) \
template < template <typename \
BOOST_PP_ENUM_TRAILING(n, BOOST_INTRUSIVE_PP_IDENTITY, typename) > \
class Ptr \
, typename T BOOST_PP_ENUM_TRAILING_PARAMS(n, class P) \
, class U> \
struct type_rebinder \
< Ptr<T BOOST_PP_ENUM_TRAILING_PARAMS(n, P)>, U, 0u > \
{ \
typedef Ptr<U BOOST_PP_ENUM_TRAILING_PARAMS(n, P)> type; \
}; \
//
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_INTRUSIVE_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE()
#endif //!defined(BOOST_NO_VARIADIC_TEMPLATES)
} //namespace detail {
} //namespace intrusive {
} //namespace boost {
#include <boost/intrusive/detail/config_end.hpp>
#endif // ! defined(BOOST_INTRUSIVE_ALLOCATOR_MEMORY_UTIL_HPP)

View File

@@ -1,65 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006. 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_POINTER_TO_OTHER_HPP
#define BOOST_INTRUSIVE_POINTER_TO_OTHER_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/version.hpp>
#if (BOOST_VERSION < 103400)
#ifndef BOOST_POINTER_TO_OTHER_HPP_INCLUDED
#define BOOST_POINTER_TO_OTHER_HPP_INCLUDED
namespace boost {
template<class T, class U>
struct pointer_to_other;
template<class T, class U, template <class> class Sp>
struct pointer_to_other< Sp<T>, U >
{
typedef Sp<U> type;
};
template<class T, class T2, class U,
template <class, class> class Sp>
struct pointer_to_other< Sp<T, T2>, U >
{
typedef Sp<U, T2> type;
};
template<class T, class T2, class T3, class U,
template <class, class, class> class Sp>
struct pointer_to_other< Sp<T, T2, T3>, U >
{
typedef Sp<U, T2, T3> type;
};
template<class T, class U>
struct pointer_to_other< T*, U >
{
typedef U* type;
};
} // namespace boost
#endif
#else
#include <boost/pointer_to_other.hpp>
#endif //#ifndef BOOST_POINTER_TO_OTHER_HPP_INCLUDED
#include <boost/intrusive/detail/config_end.hpp>
#endif //#ifndef BOOST_INTRUSIVE_POINTER_TO_OTHER_HPP

View File

@@ -0,0 +1,52 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2008-2011. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_PREPROCESSOR_HPP
#define BOOST_INTRUSIVE_DETAIL_PREPROCESSOR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/punctuation/paren_if.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/control/expr_if.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/logical/not.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/arithmetic/add.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#define BOOST_INTRUSIVE_MAX_CONSTRUCTOR_PARAMETERS 10
#define BOOST_INTRUSIVE_PP_IDENTITY(z, n, data) data
#define BOOST_INTRUSIVE_PP_DECLVAL(z, n, data) \
boost::move_detail::declval< BOOST_PP_CAT(P, n) >() \
//!
#define BOOST_INTRUSIVE_PP_TEMPLATE_PARAM_VOID_DEFAULT(z, n, data) \
BOOST_PP_CAT(class P, n) = void \
//!
#include <boost/intrusive/detail/config_end.hpp>
#endif //#ifndef BOOST_INTRUSIVE_DETAIL_PREPROCESSOR_HPP

View File

@@ -16,7 +16,7 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <iterator>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/rbtree_algorithms.hpp>
#include <boost/intrusive/pointer_plus_bits.hpp>
#include <boost/intrusive/detail/mpl.hpp>
@@ -34,9 +34,9 @@ namespace intrusive {
template<class VoidPointer>
struct compact_rbtree_node
{
typedef typename pointer_to_other
<VoidPointer
,compact_rbtree_node<VoidPointer> >::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
<compact_rbtree_node<VoidPointer> >::type node_ptr;
enum color { red_t, black_t };
node_ptr parent_, left_, right_;
};
@@ -45,9 +45,9 @@ struct compact_rbtree_node
template<class VoidPointer>
struct rbtree_node
{
typedef typename pointer_to_other
<VoidPointer
,rbtree_node<VoidPointer> >::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
<rbtree_node<VoidPointer> >::type node_ptr;
enum color { red_t, black_t };
node_ptr parent_, left_, right_;
@@ -61,35 +61,35 @@ struct default_rbtree_node_traits_impl
{
typedef rbtree_node<VoidPointer> node;
typedef typename boost::pointer_to_other
<VoidPointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<VoidPointer, const node>::type const_node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<node>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<const node>::type const_node_ptr;
typedef typename node::color color;
static node_ptr get_parent(const_node_ptr n)
static const node_ptr & get_parent(const const_node_ptr & n)
{ return n->parent_; }
static void set_parent(node_ptr n, node_ptr p)
static void set_parent(const node_ptr & n, const node_ptr & p)
{ n->parent_ = p; }
static node_ptr get_left(const_node_ptr n)
static const node_ptr & get_left(const const_node_ptr & n)
{ return n->left_; }
static void set_left(node_ptr n, node_ptr l)
static void set_left(const node_ptr & n, const node_ptr & l)
{ n->left_ = l; }
static node_ptr get_right(const_node_ptr n)
static const node_ptr & get_right(const const_node_ptr & n)
{ return n->right_; }
static void set_right(node_ptr n, node_ptr r)
static void set_right(const node_ptr & n, const node_ptr & r)
{ n->right_ = r; }
static color get_color(const_node_ptr n)
static color get_color(const const_node_ptr & n)
{ return n->color_; }
static void set_color(node_ptr n, color c)
static void set_color(const node_ptr & n, color c)
{ n->color_ = c; }
static color black()
@@ -105,37 +105,37 @@ template<class VoidPointer>
struct compact_rbtree_node_traits_impl
{
typedef compact_rbtree_node<VoidPointer> node;
typedef typename boost::pointer_to_other
<VoidPointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<VoidPointer, const node>::type const_node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<node>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<const node>::type const_node_ptr;
typedef pointer_plus_bits<node_ptr, 1> ptr_bit;
typedef typename node::color color;
static node_ptr get_parent(const_node_ptr n)
static node_ptr get_parent(const const_node_ptr & n)
{ return ptr_bit::get_pointer(n->parent_); }
static void set_parent(node_ptr n, node_ptr p)
static void set_parent(const node_ptr & n, const node_ptr & p)
{ ptr_bit::set_pointer(n->parent_, p); }
static node_ptr get_left(const_node_ptr n)
static const node_ptr & get_left(const const_node_ptr & n)
{ return n->left_; }
static void set_left(node_ptr n, node_ptr l)
static void set_left(const node_ptr & n, const node_ptr & l)
{ n->left_ = l; }
static node_ptr get_right(const_node_ptr n)
static const node_ptr & get_right(const const_node_ptr & n)
{ return n->right_; }
static void set_right(node_ptr n, node_ptr r)
static void set_right(const node_ptr & n, const node_ptr & r)
{ n->right_ = r; }
static color get_color(const_node_ptr n)
static color get_color(const const_node_ptr & n)
{ return (color)ptr_bit::get_bits(n->parent_); }
static void set_color(node_ptr n, color c)
static void set_color(const node_ptr & n, color c)
{ ptr_bit::set_bits(n->parent_, c != 0); }
static color black()

View File

@@ -17,7 +17,7 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <iterator>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
namespace boost {
namespace intrusive {
@@ -25,8 +25,8 @@ namespace intrusive {
template<class VoidPointer>
struct slist_node
{
typedef typename boost::pointer_to_other
<VoidPointer, slist_node>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<slist_node>::type node_ptr;
node_ptr next_;
};
@@ -37,15 +37,15 @@ template<class VoidPointer>
struct slist_node_traits
{
typedef slist_node<VoidPointer> node;
typedef typename boost::pointer_to_other
<VoidPointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<VoidPointer, const node>::type const_node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<node>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer<const node>::type const_node_ptr;
static node_ptr get_next(const_node_ptr n)
static const node_ptr &get_next(const const_node_ptr & n)
{ return n->next_; }
static void set_next(node_ptr n, node_ptr next)
static void set_next(const node_ptr & n, const node_ptr & next)
{ n->next_ = next; }
};
@@ -66,8 +66,8 @@ class slist_iterator
typedef typename real_value_traits::node_traits node_traits;
typedef typename node_traits::node node;
typedef typename node_traits::node_ptr node_ptr;
typedef typename boost::pointer_to_other
<node_ptr, void>::type void_pointer;
typedef typename pointer_traits
<node_ptr>::template rebind_pointer <void>::type void_pointer;
static const bool store_container_ptr =
detail::store_cont_ptr_on_it<Container>::value;
@@ -77,10 +77,10 @@ class slist_iterator
typedef typename detail::if_c<IsConst,typename Container::const_reference,typename Container::reference>::type reference;
slist_iterator()
: members_ (node_ptr(0), 0)
: members_ (node_ptr(), 0)
{}
explicit slist_iterator(node_ptr node, const Container *cont_ptr)
explicit slist_iterator(const node_ptr & node, const Container *cont_ptr)
: members_ (node, cont_ptr)
{}
@@ -118,7 +118,7 @@ class slist_iterator
{ return *operator->(); }
pointer operator->() const
{ return detail::boost_intrusive_get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); }
{ return this->get_real_value_traits()->to_value_ptr(members_.nodeptr_); }
const Container *get_container() const
{

View File

@@ -18,7 +18,7 @@
#include <boost/intrusive/intrusive_fwd.hpp>
#include <cstddef>
#include <boost/intrusive/detail/utilities.hpp>
//iG pending #include <boost/pointer_cast.hpp>
#include <boost/intrusive/pointer_traits.hpp>
namespace boost {
namespace intrusive {
@@ -106,7 +106,7 @@ class tree_algorithms
{
insert_commit_data()
: link_left(false)
, node(0)
, node()
{}
bool link_left;
node_ptr node;
@@ -114,7 +114,7 @@ class tree_algorithms
struct nop_erase_fixup
{
void operator()(node_ptr, node_ptr){}
void operator()(const node_ptr&, const node_ptr&){}
};
/// @cond
@@ -122,7 +122,7 @@ class tree_algorithms
template<class Disposer>
struct dispose_subtree_disposer
{
dispose_subtree_disposer(Disposer &disp, node_ptr subtree)
dispose_subtree_disposer(Disposer &disp, const node_ptr & subtree)
: disposer_(&disp), subtree_(subtree)
{}
@@ -139,21 +139,19 @@ class tree_algorithms
node_ptr subtree_;
};
static node_ptr uncast(const_node_ptr ptr)
{
return node_ptr(const_cast<node*>(::boost::intrusive::detail::boost_intrusive_get_pointer(ptr)));
//iG pending return node_ptr(boost::const_pointer_cast<node>(ptr));
}
static node_ptr uncast(const const_node_ptr & ptr)
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
/// @endcond
public:
static node_ptr begin_node(const_node_ptr header)
static node_ptr begin_node(const const_node_ptr & header)
{ return node_traits::get_left(header); }
static node_ptr end_node(const_node_ptr header)
static node_ptr end_node(const const_node_ptr & header)
{ return uncast(header); }
//! <b>Requires</b>: node is a node of the tree or an node initialized
//! <b>Requires</b>: 'node' is a node of the tree or an node initialized
//! by init(...) or init_node.
//!
//! <b>Effects</b>: Returns true if the node is initialized by init() or init_node().
@@ -161,10 +159,10 @@ class tree_algorithms
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
static bool unique(const_node_ptr node)
static bool unique(const const_node_ptr & node)
{ return !NodeTraits::get_parent(node); }
static node_ptr get_header(const_node_ptr node)
static node_ptr get_header(const const_node_ptr & node)
{
node_ptr h = uncast(node);
if(NodeTraits::get_parent(node)){
@@ -190,7 +188,7 @@ class tree_algorithms
//! node1 and node2 are not equivalent according to the ordering rules.
//!
//!Experimental function
static void swap_nodes(node_ptr node1, node_ptr node2)
static void swap_nodes(const node_ptr & node1, const node_ptr & node2)
{
if(node1 == node2)
return;
@@ -214,7 +212,7 @@ class tree_algorithms
//! node1 and node2 are not equivalent according to the ordering rules.
//!
//!Experimental function
static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2)
static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2)
{
if(node1 == node2)
return;
@@ -363,7 +361,7 @@ class tree_algorithms
//! the node, since no rebalancing and comparison is needed.
//!
//!Experimental function
static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node)
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node)
{
if(node_to_be_replaced == new_node)
return;
@@ -386,7 +384,7 @@ class tree_algorithms
//! the node, since no rebalancing or comparison is needed.
//!
//!Experimental function
static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node)
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node)
{
if(node_to_be_replaced == new_node)
return;
@@ -429,20 +427,21 @@ class tree_algorithms
}
}
//! <b>Requires</b>: p is a node from the tree except the header.
//! <b>Requires</b>: 'node' is a node from the tree except the header.
//!
//! <b>Effects</b>: Returns the next node of the tree.
//!
//! <b>Complexity</b>: Average constant time.
//!
//! <b>Throws</b>: Nothing.
static node_ptr next_node(node_ptr p)
static node_ptr next_node(const node_ptr & node)
{
node_ptr p_right(NodeTraits::get_right(p));
node_ptr p_right(NodeTraits::get_right(node));
if(p_right){
return minimum(p_right);
}
else {
node_ptr p(node);
node_ptr x = NodeTraits::get_parent(p);
while(p == NodeTraits::get_right(x)){
p = x;
@@ -452,23 +451,24 @@ class tree_algorithms
}
}
//! <b>Requires</b>: p is a node from the tree except the leftmost node.
//! <b>Requires</b>: 'node' is a node from the tree except the leftmost node.
//!
//! <b>Effects</b>: Returns the previous node of the tree.
//!
//! <b>Complexity</b>: Average constant time.
//!
//! <b>Throws</b>: Nothing.
static node_ptr prev_node(node_ptr p)
static node_ptr prev_node(const node_ptr & node)
{
if(is_header(p)){
return NodeTraits::get_right(p);
//return maximum(NodeTraits::get_parent(p));
if(is_header(node)){
return NodeTraits::get_right(node);
//return maximum(NodeTraits::get_parent(node));
}
else if(NodeTraits::get_left(p)){
return maximum(NodeTraits::get_left(p));
else if(NodeTraits::get_left(node)){
return maximum(NodeTraits::get_left(node));
}
else {
node_ptr p(node);
node_ptr x = NodeTraits::get_parent(p);
while(p == NodeTraits::get_left(x)){
p = x;
@@ -478,15 +478,16 @@ class tree_algorithms
}
}
//! <b>Requires</b>: p is a node of a tree but not the header.
//! <b>Requires</b>: 'node' is a node of a tree but not the header.
//!
//! <b>Effects</b>: Returns the minimum node of the subtree starting at p.
//!
//! <b>Complexity</b>: Logarithmic to the size of the subtree.
//!
//! <b>Throws</b>: Nothing.
static node_ptr minimum (node_ptr p)
static node_ptr minimum (const node_ptr & node)
{
node_ptr p(node);
for(node_ptr p_left = NodeTraits::get_left(p)
;p_left
;p_left = NodeTraits::get_left(p)){
@@ -495,15 +496,16 @@ class tree_algorithms
return p;
}
//! <b>Requires</b>: p is a node of a tree but not the header.
//! <b>Requires</b>: 'node' is a node of a tree but not the header.
//!
//! <b>Effects</b>: Returns the maximum node of the subtree starting at p.
//!
//! <b>Complexity</b>: Logarithmic to the size of the subtree.
//!
//! <b>Throws</b>: Nothing.
static node_ptr maximum(node_ptr p)
static node_ptr maximum(const node_ptr & node)
{
node_ptr p(node);
for(node_ptr p_right = NodeTraits::get_right(p)
;p_right
;p_right = NodeTraits::get_right(p)){
@@ -512,7 +514,7 @@ class tree_algorithms
return p;
}
//! <b>Requires</b>: node must not be part of any tree.
//! <b>Requires</b>: 'node' must not be part of any tree.
//!
//! <b>Effects</b>: After the function unique(node) == true.
//!
@@ -521,11 +523,11 @@ class tree_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
static void init(node_ptr node)
static void init(const node_ptr & node)
{
NodeTraits::set_parent(node, node_ptr(0));
NodeTraits::set_left(node, node_ptr(0));
NodeTraits::set_right(node, node_ptr(0));
NodeTraits::set_parent(node, node_ptr());
NodeTraits::set_left(node, node_ptr());
NodeTraits::set_right(node, node_ptr());
};
//! <b>Effects</b>: Returns true if node is in the same state as if called init(node)
@@ -533,7 +535,7 @@ class tree_algorithms
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
static bool inited(const_node_ptr node)
static bool inited(const const_node_ptr & node)
{
return !NodeTraits::get_parent(node) &&
!NodeTraits::get_left(node) &&
@@ -550,9 +552,9 @@ class tree_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
static void init_header(node_ptr header)
static void init_header(const node_ptr & header)
{
NodeTraits::set_parent(header, node_ptr(0));
NodeTraits::set_parent(header, node_ptr());
NodeTraits::set_left(header, header);
NodeTraits::set_right(header, header);
}
@@ -561,7 +563,7 @@ class tree_algorithms
//! taking a node_ptr parameter and shouldn't throw.
//!
//! <b>Effects</b>: Empties the target tree calling
//! <tt>void disposer::operator()(node_ptr)</tt> for every node of the tree
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
//! except the header.
//!
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
@@ -569,7 +571,7 @@ class tree_algorithms
//!
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
template<class Disposer>
static void clear_and_dispose(node_ptr header, Disposer disposer)
static void clear_and_dispose(const node_ptr & header, Disposer disposer)
{
node_ptr source_root = NodeTraits::get_parent(header);
if(!source_root)
@@ -591,11 +593,11 @@ class tree_algorithms
//! only be used for more unlink_leftmost_without_rebalance calls.
//! This function is normally used to achieve a step by step
//! controlled destruction of the tree.
static node_ptr unlink_leftmost_without_rebalance(node_ptr header)
static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header)
{
node_ptr leftmost = NodeTraits::get_left(header);
if (leftmost == header)
return node_ptr(0);
return node_ptr();
node_ptr leftmost_parent(NodeTraits::get_parent(leftmost));
node_ptr leftmost_right (NodeTraits::get_right(leftmost));
bool is_root = leftmost_parent == header;
@@ -610,12 +612,12 @@ class tree_algorithms
NodeTraits::set_left(NodeTraits::get_parent(header), leftmost_right);
}
else if (is_root){
NodeTraits::set_parent(header, node_ptr(0));
NodeTraits::set_parent(header, node_ptr());
NodeTraits::set_left(header, header);
NodeTraits::set_right(header, header);
}
else{
NodeTraits::set_left(leftmost_parent, node_ptr(0));
NodeTraits::set_left(leftmost_parent, node_ptr());
NodeTraits::set_left(header, leftmost_parent);
}
return leftmost;
@@ -628,7 +630,7 @@ class tree_algorithms
//! <b>Complexity</b>: Linear time.
//!
//! <b>Throws</b>: Nothing.
static std::size_t count(const_node_ptr subtree)
static std::size_t count(const const_node_ptr & subtree)
{
if(!subtree) return 0;
std::size_t count = 0;
@@ -664,7 +666,7 @@ class tree_algorithms
//! <b>Complexity</b>: Linear time.
//!
//! <b>Throws</b>: Nothing.
static std::size_t size(const_node_ptr header)
static std::size_t size(const const_node_ptr & header)
{
node_ptr beg(begin_node(header));
node_ptr end(end_node(header));
@@ -682,7 +684,7 @@ class tree_algorithms
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
static void swap_tree(node_ptr header1, node_ptr header2)
static void swap_tree(const node_ptr & header1, const node_ptr & header2)
{
if(header1 == header2)
return;
@@ -722,7 +724,7 @@ class tree_algorithms
}
}
static bool is_header(const_node_ptr p)
static bool is_header(const const_node_ptr & p)
{
node_ptr p_left (NodeTraits::get_left(p));
node_ptr p_right(NodeTraits::get_right(p));
@@ -752,7 +754,7 @@ class tree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr find
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{
node_ptr end = uncast(header);
node_ptr y = lower_bound(header, key, comp);
@@ -774,7 +776,7 @@ class tree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> equal_range
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{
node_ptr y = uncast(header);
node_ptr x = NodeTraits::get_parent(header);
@@ -831,7 +833,7 @@ class tree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr lower_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{
node_ptr y = uncast(header);
node_ptr x = NodeTraits::get_parent(header);
@@ -860,7 +862,7 @@ class tree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr upper_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{
node_ptr y = uncast(header);
node_ptr x = NodeTraits::get_parent(header);
@@ -894,14 +896,14 @@ class tree_algorithms
//! previously executed to fill "commit_data". No value should be inserted or
//! erased between the "insert_check" and "insert_commit" calls.
static void insert_unique_commit
(node_ptr header, node_ptr new_value, const insert_commit_data &commit_data)
(const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data)
{ return insert_commit(header, new_value, commit_data); }
static void insert_commit
(node_ptr header, node_ptr new_node, const insert_commit_data &commit_data)
(const node_ptr & header, const node_ptr & new_node, const insert_commit_data &commit_data)
{
//Check if commit_data has not been initialized by a insert_unique_check call.
BOOST_INTRUSIVE_INVARIANT_ASSERT(commit_data.node != 0);
BOOST_INTRUSIVE_INVARIANT_ASSERT(commit_data.node != node_ptr());
node_ptr parent_node(commit_data.node);
if(parent_node == header){
NodeTraits::set_parent(header, new_node);
@@ -919,8 +921,8 @@ class tree_algorithms
NodeTraits::set_right(header, new_node);
}
NodeTraits::set_parent(new_node, parent_node);
NodeTraits::set_right(new_node, node_ptr(0));
NodeTraits::set_left(new_node, node_ptr(0));
NodeTraits::set_right(new_node, node_ptr());
NodeTraits::set_left(new_node, node_ptr());
}
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -959,14 +961,14 @@ class tree_algorithms
//! if no more objects are inserted or erased from the set.
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(const_node_ptr header, const KeyType &key
(const const_node_ptr & header, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data, std::size_t *pdepth = 0)
{
std::size_t depth = 0;
node_ptr h(uncast(header));
node_ptr y(h);
node_ptr x(NodeTraits::get_parent(y));
node_ptr prev(0);
node_ptr prev = node_ptr();
//Find the upper bound, cache the previous value and if we should
//store it in the left or right node
@@ -997,7 +999,7 @@ class tree_algorithms
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(const_node_ptr header, node_ptr hint, const KeyType &key
(const const_node_ptr & header, const node_ptr &hint, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data, std::size_t *pdepth = 0)
{
//hint must be bigger than the key
@@ -1019,7 +1021,7 @@ class tree_algorithms
template<class NodePtrCompare>
static void insert_equal_check
( node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp
(const node_ptr &header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp
, insert_commit_data &commit_data, std::size_t *pdepth = 0)
{
if(hint == header || !comp(hint, new_node)){
@@ -1044,17 +1046,17 @@ class tree_algorithms
template<class NodePtrCompare>
static void insert_equal_upper_bound_check
(node_ptr h, node_ptr new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0)
(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); }
template<class NodePtrCompare>
static void insert_equal_lower_bound_check
(node_ptr h, node_ptr new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0)
(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); }
template<class NodePtrCompare>
static node_ptr insert_equal
(node_ptr h, node_ptr hint, node_ptr new_node, NodePtrCompare comp, std::size_t *pdepth = 0)
(const node_ptr & h, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp, std::size_t *pdepth = 0)
{
insert_commit_data commit_data;
insert_equal_check(h, hint, new_node, comp, commit_data, pdepth);
@@ -1064,7 +1066,7 @@ class tree_algorithms
template<class NodePtrCompare>
static node_ptr insert_equal_upper_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp, std::size_t *pdepth = 0)
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, std::size_t *pdepth = 0)
{
insert_commit_data commit_data;
insert_equal_upper_bound_check(h, new_node, comp, commit_data, pdepth);
@@ -1074,7 +1076,7 @@ class tree_algorithms
template<class NodePtrCompare>
static node_ptr insert_equal_lower_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp, std::size_t *pdepth = 0)
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, std::size_t *pdepth = 0)
{
insert_commit_data commit_data;
insert_equal_lower_bound_check(h, new_node, comp, commit_data, pdepth);
@@ -1083,7 +1085,7 @@ class tree_algorithms
}
static node_ptr insert_before
(node_ptr header, node_ptr pos, node_ptr new_node, std::size_t *pdepth = 0)
(const node_ptr & header, const node_ptr & pos, const node_ptr & new_node, std::size_t *pdepth = 0)
{
insert_commit_data commit_data;
insert_before_check(header, pos, commit_data, pdepth);
@@ -1092,7 +1094,7 @@ class tree_algorithms
}
static void insert_before_check
( node_ptr header, node_ptr pos
(const node_ptr &header, const node_ptr & pos
, insert_commit_data &commit_data, std::size_t *pdepth = 0)
{
node_ptr prev(pos);
@@ -1107,7 +1109,7 @@ class tree_algorithms
}
static void push_back
(node_ptr header, node_ptr new_node, std::size_t *pdepth = 0)
(const node_ptr & header, const node_ptr & new_node, std::size_t *pdepth = 0)
{
insert_commit_data commit_data;
push_back_check(header, commit_data, pdepth);
@@ -1115,7 +1117,7 @@ class tree_algorithms
}
static void push_back_check
(node_ptr header, insert_commit_data &commit_data, std::size_t *pdepth = 0)
(const node_ptr & header, insert_commit_data &commit_data, std::size_t *pdepth = 0)
{
node_ptr prev(NodeTraits::get_right(header));
if(pdepth){
@@ -1126,7 +1128,7 @@ class tree_algorithms
}
static void push_front
(node_ptr header, node_ptr new_node, std::size_t *pdepth = 0)
(const node_ptr & header, const node_ptr & new_node, std::size_t *pdepth = 0)
{
insert_commit_data commit_data;
push_front_check(header, commit_data, pdepth);
@@ -1134,7 +1136,7 @@ class tree_algorithms
}
static void push_front_check
(node_ptr header, insert_commit_data &commit_data, std::size_t *pdepth = 0)
(const node_ptr & header, insert_commit_data &commit_data, std::size_t *pdepth = 0)
{
node_ptr pos(NodeTraits::get_left(header));
if(pdepth){
@@ -1144,7 +1146,7 @@ class tree_algorithms
commit_data.node = pos;
}
//! <b>Requires</b>: p can't be a header node.
//! <b>Requires</b>: 'node' can't be a header node.
//!
//! <b>Effects</b>: Calculates the depth of a node: the depth of a
//! node is the length (number of edges) of the path from the root
@@ -1153,8 +1155,9 @@ class tree_algorithms
//! <b>Complexity</b>: Logarithmic to the number of nodes in the tree.
//!
//! <b>Throws</b>: Nothing.
static std::size_t depth(const_node_ptr p)
static std::size_t depth(const const_node_ptr & node)
{
const_node_ptr p(node);
std::size_t depth = 0;
node_ptr p_parent;
while(p != NodeTraits::get_parent(p_parent = NodeTraits::get_parent(p))){
@@ -1169,13 +1172,13 @@ class tree_algorithms
//! take a node_ptr and shouldn't throw.
//!
//! <b>Effects</b>: First empties target tree calling
//! <tt>void disposer::operator()(node_ptr)</tt> for every node of the tree
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
//! except the header.
//!
//! Then, duplicates the entire tree pointed by "source_header" cloning each
//! source node with <tt>node_ptr Cloner::operator()(node_ptr)</tt> to obtain
//! source node with <tt>node_ptr Cloner::operator()(const node_ptr &)</tt> to obtain
//! the nodes of the target tree. If "cloner" throws, the cloned target nodes
//! are disposed using <tt>void disposer(node_ptr)</tt>.
//! are disposed using <tt>void disposer(const node_ptr &)</tt>.
//!
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
//! number of elements of tree target tree when calling this function.
@@ -1183,7 +1186,7 @@ class tree_algorithms
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
template <class Cloner, class Disposer>
static void clone
(const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer)
(const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer)
{
if(!unique(target_header)){
clear_and_dispose(target_header, disposer);
@@ -1201,9 +1204,9 @@ class tree_algorithms
template <class Cloner, class Disposer>
static node_ptr clone_subtree
( const_node_ptr source_parent, node_ptr target_parent
, Cloner cloner, Disposer disposer
, node_ptr &leftmost_out, node_ptr &rightmost_out
(const const_node_ptr &source_parent, const node_ptr &target_parent
, Cloner cloner, Disposer disposer
, node_ptr &leftmost_out, node_ptr &rightmost_out
)
{
node_ptr target_sub_root = target_parent;
@@ -1221,8 +1224,8 @@ class tree_algorithms
node_ptr rightmost = target_sub_root;
//First set the subroot
NodeTraits::set_left(target_sub_root, node_ptr(0));
NodeTraits::set_right(target_sub_root, node_ptr(0));
NodeTraits::set_left(target_sub_root, node_ptr());
NodeTraits::set_right(target_sub_root, node_ptr());
NodeTraits::set_parent(target_sub_root, target_parent);
dispose_subtree_disposer<Disposer> rollback(disposer, target_sub_root);
@@ -1234,8 +1237,8 @@ class tree_algorithms
node_ptr temp = insertion_point;
//Clone and mark as leaf
insertion_point = cloner(current);
NodeTraits::set_left (insertion_point, node_ptr(0));
NodeTraits::set_right (insertion_point, node_ptr(0));
NodeTraits::set_left (insertion_point, node_ptr());
NodeTraits::set_right (insertion_point, node_ptr());
//Insert left
NodeTraits::set_parent(insertion_point, temp);
NodeTraits::set_left (temp, insertion_point);
@@ -1250,8 +1253,8 @@ class tree_algorithms
node_ptr temp = insertion_point;
//Clone and mark as leaf
insertion_point = cloner(current);
NodeTraits::set_left (insertion_point, node_ptr(0));
NodeTraits::set_right (insertion_point, node_ptr(0));
NodeTraits::set_left (insertion_point, node_ptr());
NodeTraits::set_right (insertion_point, node_ptr());
//Insert right
NodeTraits::set_parent(insertion_point, temp);
NodeTraits::set_right (temp, insertion_point);
@@ -1276,9 +1279,10 @@ class tree_algorithms
}
template<class Disposer>
static void dispose_subtree(node_ptr x, Disposer disposer)
static void dispose_subtree(const node_ptr & node, Disposer disposer)
{
node_ptr save;
node_ptr x(node);
while (x){
save = NodeTraits::get_left(x);
if (save) {
@@ -1302,7 +1306,7 @@ class tree_algorithms
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
static bool is_left_child(node_ptr p)
static bool is_left_child(const node_ptr & p)
{ return NodeTraits::get_left(NodeTraits::get_parent(p)) == p; }
//! <b>Requires</b>: p is a node of a tree.
@@ -1312,11 +1316,11 @@ class tree_algorithms
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
static bool is_right_child(node_ptr p)
static bool is_right_child(const node_ptr & p)
{ return NodeTraits::get_right(NodeTraits::get_parent(p)) == p; }
//Fix header and own's parent data when replacing x with own, providing own's old data with parent
static void replace_own_impl(node_ptr own, node_ptr x, node_ptr header, node_ptr own_parent, bool own_was_left)
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);
@@ -1328,7 +1332,7 @@ class tree_algorithms
//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(node_ptr own, node_ptr x, node_ptr header)
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);
@@ -1336,7 +1340,7 @@ class tree_algorithms
}
// rotate parent p to left (no header and p's parent fixup)
static node_ptr rotate_left(node_ptr p)
static node_ptr rotate_left(const node_ptr & p)
{
node_ptr x(NodeTraits::get_right(p));
node_ptr x_left(NodeTraits::get_left(x));
@@ -1350,7 +1354,7 @@ class tree_algorithms
}
// rotate parent p to left (with header and p's parent fixup)
static void rotate_left(node_ptr p, node_ptr header)
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));
@@ -1360,7 +1364,7 @@ class tree_algorithms
}
// rotate parent p to right (no header and p's parent fixup)
static node_ptr rotate_right(node_ptr p)
static node_ptr rotate_right(const node_ptr & p)
{
node_ptr x(NodeTraits::get_left(p));
node_ptr x_right(NodeTraits::get_right(x));
@@ -1374,7 +1378,7 @@ class tree_algorithms
}
// rotate parent p to right (with header and p's parent fixup)
static void rotate_right(node_ptr p, node_ptr header)
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));
@@ -1383,7 +1387,7 @@ class tree_algorithms
replace_own_impl(p, x, header, p_old_parent, p_was_left);
}
static void erase(node_ptr header, node_ptr z)
static void erase(const node_ptr & header, const node_ptr & z)
{
data_for_rebalance ignored;
erase_impl(header, z, ignored);
@@ -1397,7 +1401,7 @@ class tree_algorithms
};
template<class F>
static void erase(node_ptr header, node_ptr z, F z_and_successor_fixup, data_for_rebalance &info)
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){
@@ -1405,7 +1409,7 @@ class tree_algorithms
}
}
static void unlink(node_ptr node)
static void unlink(const node_ptr & node)
{
node_ptr x = NodeTraits::get_parent(node);
if(x){
@@ -1415,13 +1419,13 @@ class tree_algorithms
}
}
static void tree_to_vine(node_ptr header)
static void tree_to_vine(const node_ptr & header)
{ subtree_to_vine(NodeTraits::get_parent(header)); }
static void vine_to_tree(node_ptr header, std::size_t count)
static void vine_to_tree(const node_ptr & header, std::size_t count)
{ vine_to_subtree(NodeTraits::get_parent(header), count); }
static void rebalance(node_ptr header)
static void rebalance(const node_ptr & header)
{
//Taken from:
//"Tree rebalancing in optimal time and space"
@@ -1431,18 +1435,18 @@ class tree_algorithms
vine_to_subtree(NodeTraits::get_parent(header), len);
}
static node_ptr rebalance_subtree(node_ptr old_root)
static node_ptr rebalance_subtree(const node_ptr & old_root)
{
std::size_t len = 0;
node_ptr new_root = subtree_to_vine(old_root, &len);
return vine_to_subtree(new_root, len);
}
static node_ptr subtree_to_vine(node_ptr old_root, std::size_t *plen = 0)
static node_ptr subtree_to_vine(const node_ptr & old_root, std::size_t *plen = 0)
{
std::size_t len;
len = 0;
if(!old_root) return node_ptr(0);
if(!old_root) return node_ptr();
//To avoid irregularities in the algorithm (old_root can be a
//left or right child or even the root of the tree) just put the
@@ -1499,7 +1503,7 @@ class tree_algorithms
return new_root;
}
static node_ptr vine_to_subtree(node_ptr old_root, std::size_t count)
static node_ptr vine_to_subtree(const node_ptr & old_root, std::size_t count)
{
std::size_t leaf_nodes = count + 1 - ((std::size_t) 1 << floor_log2 (count + 1));
std::size_t vine_nodes = count - leaf_nodes;
@@ -1512,7 +1516,7 @@ class tree_algorithms
return new_root;
}
static node_ptr compress_subtree(node_ptr old_root, std::size_t count)
static node_ptr compress_subtree(const node_ptr & old_root, std::size_t count)
{
if(!old_root) return old_root;
@@ -1576,7 +1580,7 @@ class tree_algorithms
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: Nothing.
static node_ptr get_root(node_ptr node)
static node_ptr get_root(const node_ptr & node)
{
BOOST_INTRUSIVE_INVARIANT_ASSERT((!inited(node)));
node_ptr x = NodeTraits::get_parent(node);
@@ -1594,7 +1598,7 @@ class tree_algorithms
private:
template<class NodePtrCompare>
static void insert_equal_check_impl
(bool upper, node_ptr h, node_ptr new_node, NodePtrCompare comp, insert_commit_data & commit_data, std::size_t *pdepth = 0)
(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);
@@ -1625,11 +1629,11 @@ class tree_algorithms
if(pdepth) *pdepth = depth;
}
static void erase_impl(node_ptr header, node_ptr z, data_for_rebalance &info)
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(0);
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){

View File

@@ -15,7 +15,7 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <iterator>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/mpl.hpp>
namespace boost {
@@ -24,9 +24,9 @@ namespace intrusive {
template<class VoidPointer>
struct tree_node
{
typedef typename pointer_to_other
<VoidPointer
,tree_node<VoidPointer> >::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
<tree_node<VoidPointer> >::type node_ptr;
node_ptr parent_, left_, right_;
};
@@ -36,27 +36,27 @@ struct tree_node_traits
{
typedef tree_node<VoidPointer> node;
typedef typename boost::pointer_to_other
<VoidPointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<VoidPointer, const node>::type const_node_ptr;
typedef typename pointer_traits<VoidPointer>::template
rebind_pointer<node>::type node_ptr;
typedef typename pointer_traits<VoidPointer>::template
rebind_pointer<const node>::type const_node_ptr;
static node_ptr get_parent(const_node_ptr n)
static const node_ptr & get_parent(const const_node_ptr & n)
{ return n->parent_; }
static void set_parent(node_ptr n, node_ptr p)
static void set_parent(const node_ptr & n, const node_ptr & p)
{ n->parent_ = p; }
static node_ptr get_left(const_node_ptr n)
static const node_ptr & get_left(const const_node_ptr & n)
{ return n->left_; }
static void set_left(node_ptr n, node_ptr l)
static void set_left(const node_ptr & n, const node_ptr & l)
{ n->left_ = l; }
static node_ptr get_right(const_node_ptr n)
static const node_ptr & get_right(const const_node_ptr & n)
{ return n->right_; }
static void set_right(node_ptr n, node_ptr r)
static void set_right(const node_ptr & n, const node_ptr & r)
{ n->right_ = r; }
};
@@ -84,8 +84,8 @@ class tree_iterator
typedef typename real_value_traits::node_traits node_traits;
typedef typename node_traits::node node;
typedef typename node_traits::node_ptr node_ptr;
typedef typename boost::pointer_to_other
<node_ptr, void>::type void_pointer;
typedef typename pointer_traits<node_ptr>::template
rebind_pointer<void>::type void_pointer;
static const bool store_container_ptr =
detail::store_cont_ptr_on_it<Container>::value;
@@ -96,10 +96,10 @@ class tree_iterator
tree_iterator()
: members_ (node_ptr(0), (const void *)0)
: members_ (node_ptr(), (const void *)0)
{}
explicit tree_iterator(node_ptr nodeptr, const Container *cont_ptr)
explicit tree_iterator(const node_ptr & nodeptr, const Container *cont_ptr)
: members_ (nodeptr, cont_ptr)
{}
@@ -150,7 +150,7 @@ class tree_iterator
{ return *operator->(); }
pointer operator->() const
{ return detail::boost_intrusive_get_pointer(this->get_real_value_traits()->to_value_ptr(members_.nodeptr_)); }
{ return this->get_real_value_traits()->to_value_ptr(members_.nodeptr_); }
const Container *get_container() const
{ return static_cast<const Container*>(members_.get_ptr()); }

View File

@@ -14,13 +14,14 @@
#define BOOST_INTRUSIVE_DETAIL_UTILITIES_HPP
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/parent_from_member.hpp>
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/is_stateful_value_traits.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/cstdint.hpp>
#include <cstddef>
#include <climits>
@@ -104,29 +105,14 @@ struct node_holder
: public Node
{};
template<class SmartPtr>
struct smart_ptr_type
{
typedef typename SmartPtr::value_type value_type;
typedef value_type *pointer;
static pointer get (const SmartPtr &smartptr)
{ return smartptr.get();}
};
template <class T>
inline T* to_raw_pointer(T* p)
{ return p; }
template<class T>
struct smart_ptr_type<T*>
{
typedef T value_type;
typedef value_type *pointer;
static pointer get (pointer ptr)
{ return ptr;}
};
//!Overload for smart pointers to avoid ADL problems with boost_intrusive_get_pointer
template<class Ptr>
inline typename smart_ptr_type<Ptr>::pointer
boost_intrusive_get_pointer(const Ptr &ptr)
{ return smart_ptr_type<Ptr>::get(ptr); }
template <class Pointer>
inline typename boost::intrusive::pointer_traits<Pointer>::element_type*
to_raw_pointer(const Pointer &p)
{ return boost::intrusive::detail::to_raw_pointer(p.operator->()); }
//This functor compares a stored value
//and the one passed as an argument
@@ -158,7 +144,7 @@ class init_disposer
typedef typename NodeAlgorithms::node_ptr node_ptr;
public:
void operator()(node_ptr p)
void operator()(const node_ptr & p)
{ NodeAlgorithms::init(p); }
};
@@ -258,13 +244,14 @@ struct node_cloner
: base_t(f), cont_(cont)
{}
node_ptr operator()(node_ptr p)
node_ptr operator()(const node_ptr & p)
{ return this->operator()(*p); }
node_ptr operator()(const node &to_clone)
{
const value_type &v =
*cont_->get_real_value_traits().to_value_ptr(const_node_ptr(&to_clone));
*cont_->get_real_value_traits().to_value_ptr
(pointer_traits<const_node_ptr>::pointer_to(to_clone));
node_ptr n = cont_->get_real_value_traits().to_node_ptr(*base_t::get()(v));
//Cloned node must be in default mode if the linking mode requires it
if(safemode_or_autounlink)
@@ -291,7 +278,7 @@ struct node_disposer
: base_t(f), cont_(cont)
{}
void operator()(node_ptr p)
void operator()(const node_ptr & p)
{
if(safemode_or_autounlink)
node_algorithms::init(p);
@@ -312,15 +299,15 @@ struct dummy_constptr
template<class VoidPointer>
struct constptr
{
typedef typename boost::pointer_to_other
<VoidPointer, const void>::type ConstVoidPtr;
typedef typename boost::intrusive::pointer_traits<VoidPointer>::
template rebind_pointer<const void>::type ConstVoidPtr;
constptr(const void *ptr)
: const_void_ptr_(ptr)
{}
const void *get_ptr() const
{ return detail::boost_intrusive_get_pointer(const_void_ptr_); }
{ return boost::intrusive::detail::to_raw_pointer(const_void_ptr_); }
ConstVoidPtr const_void_ptr_;
};
@@ -371,27 +358,49 @@ struct base_hook_traits
public:
typedef detail::node_holder
<typename NodeTraits::node, Tag, LinkMode, HookType> node_holder;
typedef typename NodeTraits::node node;
typedef NodeTraits node_traits;
typedef T value_type;
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef typename boost::pointer_to_other<node_ptr, T>::type pointer;
typedef typename boost::pointer_to_other<node_ptr, const T>::type const_pointer;
typedef typename std::iterator_traits<pointer>::reference reference;
typedef typename std::iterator_traits<const_pointer>::reference const_reference;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<T>::type pointer;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<const T>::type const_pointer;
//typedef typename pointer_traits<pointer>::reference reference;
//typedef typename pointer_traits<const_pointer>::reference const_reference;
typedef T & reference;
typedef const T & const_reference;
typedef node_holder & node_holder_reference;
typedef const node_holder & const_node_holder_reference;
typedef node& node_reference;
typedef const node & const_node_reference;
static const link_mode_type link_mode = LinkMode;
static pointer to_value_ptr(const node_ptr & n)
{
return pointer_traits<pointer>::pointer_to
(static_cast<reference>(static_cast<node_holder_reference>(*n)));
}
static const_pointer to_value_ptr(const const_node_ptr & n)
{
return pointer_traits<const_pointer>::pointer_to
(static_cast<const_reference>(static_cast<const_node_holder_reference>(*n)));
}
static node_ptr to_node_ptr(reference value)
{ return static_cast<node_holder*>(&value); }
{
return pointer_traits<node_ptr>::pointer_to
(static_cast<node_reference>(static_cast<node_holder_reference>(value)));
}
static const_node_ptr to_node_ptr(const_reference value)
{ return static_cast<const node_holder*>(&value); }
static pointer to_value_ptr(node_ptr n)
{ return static_cast<T*>(static_cast<node_holder*>(&*n)); }
static const_pointer to_value_ptr(const_node_ptr n)
{ return static_cast<const T*>(static_cast<const node_holder*>(&*n)); }
{
return pointer_traits<const_node_ptr>::pointer_to
(static_cast<const_node_reference>(static_cast<const_node_holder_reference>(value)));
}
};
template<class T, class Hook, Hook T::* P>
@@ -404,28 +413,43 @@ struct member_hook_traits
typedef T value_type;
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef typename boost::pointer_to_other<node_ptr, T>::type pointer;
typedef typename boost::pointer_to_other<node_ptr, const T>::type const_pointer;
typedef typename std::iterator_traits<pointer>::reference reference;
typedef typename std::iterator_traits<const_pointer>::reference const_reference;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<T>::type pointer;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<const T>::type const_pointer;
typedef T & reference;
typedef const T & const_reference;
typedef node& node_reference;
typedef const node & const_node_reference;
typedef hook_type& hook_reference;
typedef const hook_type & const_hook_reference;
static const link_mode_type link_mode = Hook::boost_intrusive_tags::link_mode;
static node_ptr to_node_ptr(reference value)
{ return static_cast<node*>(&(value.*P)); }
static const_node_ptr to_node_ptr(const_reference value)
{ return static_cast<const node*>(&(value.*P)); }
static pointer to_value_ptr(node_ptr n)
{
return detail::parent_from_member<T, Hook>
(static_cast<Hook*>(detail::boost_intrusive_get_pointer(n)), P);
return pointer_traits<node_ptr>::pointer_to
(static_cast<node_reference>(static_cast<hook_reference>(value.*P)));
}
static const_pointer to_value_ptr(const_node_ptr n)
static const_node_ptr to_node_ptr(const_reference value)
{
return detail::parent_from_member<T, Hook>
(static_cast<const Hook*>(detail::boost_intrusive_get_pointer(n)), P);
return pointer_traits<const_node_ptr>::pointer_to
(static_cast<const_node_reference>(static_cast<const_hook_reference>(value.*P)));
}
static pointer to_value_ptr(const node_ptr & n)
{
return pointer_traits<pointer>::pointer_to
(*detail::parent_from_member<T, Hook>
(static_cast<Hook*>(boost::intrusive::detail::to_raw_pointer(n)), P));
}
static const_pointer to_value_ptr(const const_node_ptr & n)
{
return pointer_traits<const_pointer>::pointer_to
(*detail::parent_from_member<T, Hook>
(static_cast<const Hook*>(boost::intrusive::detail::to_raw_pointer(n)), P));
}
};
@@ -441,29 +465,31 @@ struct function_hook_traits
typedef typename Functor::value_type value_type;
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef typename boost::pointer_to_other<node_ptr, value_type>::type pointer;
typedef typename boost::pointer_to_other<node_ptr, const value_type>::type const_pointer;
typedef typename std::iterator_traits<pointer>::reference reference;
typedef typename std::iterator_traits<const_pointer>::reference const_reference;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<value_type>::type pointer;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<const value_type>::type const_pointer;
typedef value_type & reference;
typedef const value_type & const_reference;
static const link_mode_type link_mode = hook_type::boost_intrusive_tags::link_mode;
static node_ptr to_node_ptr(reference value)
{ return static_cast<node*>(&*Functor::to_hook_ptr(value)); }
{ return static_cast<node*>(boost::intrusive::detail::to_raw_pointer(Functor::to_hook_ptr(value))); }
static const_node_ptr to_node_ptr(const_reference value)
{ return static_cast<const node*>(&*Functor::to_hook_ptr(value)); }
{ return static_cast<const node*>(boost::intrusive::detail::to_raw_pointer(Functor::to_hook_ptr(value))); }
static pointer to_value_ptr(node_ptr n)
static pointer to_value_ptr(const node_ptr & n)
{ return Functor::to_value_ptr(to_hook_ptr(n)); }
static const_pointer to_value_ptr(const_node_ptr n)
static const_pointer to_value_ptr(const const_node_ptr & n)
{ return Functor::to_value_ptr(to_hook_ptr(n)); }
private:
static hook_ptr to_hook_ptr(node_ptr n)
static hook_ptr to_hook_ptr(const node_ptr & n)
{ return hook_ptr(&*static_cast<hook_type*>(&*n)); }
static const_hook_ptr to_hook_ptr(const_node_ptr n)
static const_hook_ptr to_hook_ptr(const const_node_ptr & n)
{ return const_hook_ptr(&*static_cast<const hook_type*>(&*n)); }
};
@@ -624,8 +650,8 @@ struct store_cont_ptr_on_it
template<class Container, bool IsConst>
struct node_to_value
: public detail::select_constptr
< typename boost::pointer_to_other
<typename Container::pointer, void>::type
< typename pointer_traits
<typename Container::pointer>::template rebind_pointer<void>::type
, detail::store_cont_ptr_on_it<Container>::value
>::type
{
@@ -635,16 +661,16 @@ struct node_to_value
typedef typename Container::real_value_traits real_value_traits;
typedef typename real_value_traits::value_type value_type;
typedef typename detail::select_constptr
< typename boost::pointer_to_other
<typename Container::pointer, void>::type
< typename pointer_traits
<typename Container::pointer>::template rebind_pointer<void>::type
, store_container_ptr >::type Base;
typedef typename real_value_traits::node_traits::node node;
typedef typename detail::add_const_if_c
<value_type, IsConst>::type vtype;
typedef typename detail::add_const_if_c
<node, IsConst>::type ntype;
typedef typename boost::pointer_to_other
<typename Container::pointer, ntype>::type npointer;
typedef typename pointer_traits
<typename Container::pointer>::template rebind_pointer<ntype>::type npointer;
node_to_value(const Container *cont)
: Base(cont)
@@ -670,7 +696,10 @@ struct node_to_value
}
result_type operator()(first_argument_type arg) const
{ return *(this->get_real_value_traits()->to_value_ptr(npointer(&arg))); }
{
return *(this->get_real_value_traits()->to_value_ptr
(pointer_traits<npointer>::pointer_to(arg)));
}
};
//This is not standard, but should work with all compilers
@@ -732,6 +761,115 @@ class array_initializer
detail::max_align rawbuf[(N*sizeof(T)-1)/sizeof(detail::max_align)+1];
};
template<class It>
class reverse_iterator
: public std::iterator<
typename std::iterator_traits<It>::iterator_category,
typename std::iterator_traits<It>::value_type,
typename std::iterator_traits<It>::difference_type,
typename std::iterator_traits<It>::pointer,
typename std::iterator_traits<It>::reference>
{
public:
typedef typename std::iterator_traits<It>::pointer pointer;
typedef typename std::iterator_traits<It>::reference reference;
typedef typename std::iterator_traits<It>::difference_type difference_type;
typedef It iterator_type;
reverse_iterator(){}
explicit reverse_iterator(It r)
: m_current(r)
{}
template<class OtherIt>
reverse_iterator(const reverse_iterator<OtherIt>& r)
: m_current(r.base())
{}
It base() const
{ return m_current; }
reference operator*() const
{ It temp(m_current); --temp; return *temp; }
pointer operator->() const
{ It temp(m_current); --temp; return temp.operator->(); }
reference operator[](difference_type off) const
{ return this->m_current[-off]; }
reverse_iterator& operator++()
{ --m_current; return *this; }
reverse_iterator operator++(int)
{
reverse_iterator temp = *this;
--m_current;
return temp;
}
reverse_iterator& operator--()
{
++m_current;
return *this;
}
reverse_iterator operator--(int)
{
reverse_iterator temp(*this);
++m_current;
return temp;
}
friend bool operator==(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current == r.m_current; }
friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current != r.m_current; }
friend bool operator<(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current < r.m_current; }
friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current <= r.m_current; }
friend bool operator>(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current > r.m_current; }
friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r)
{ return l.m_current >= r.m_current; }
reverse_iterator& operator+=(difference_type off)
{ m_current -= off; return *this; }
friend reverse_iterator operator+(const reverse_iterator & l, difference_type off)
{
reverse_iterator tmp(l.m_current);
tmp.m_current -= off;
return tmp;
}
reverse_iterator& operator-=(difference_type off)
{ m_current += off; return *this; }
friend reverse_iterator operator-(const reverse_iterator & l, difference_type off)
{
reverse_iterator tmp(l.m_current);
tmp.m_current += off;
return tmp;
}
friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r)
{ return r.m_current - l.m_current; }
private:
It m_current; // the wrapped iterator
};
} //namespace detail
} //namespace intrusive
} //namespace boost

View File

@@ -11,20 +11,12 @@
#ifndef BOOST_INTRUSIVE_DETAIL_WRKRND_HPP
#define BOOST_INTRUSIVE_DETAIL_WRKRND_HPP
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)
// C++0x features are only enabled when -std=c++0x or -std=gnu++0x are
// passed on the command line, which in turn defines
// __GXX_EXPERIMENTAL_CXX0X__. Note: __GXX_EXPERIMENTAL_CPP0X__ is
// defined by some very early development versions of GCC 4.3; we will
// remove this part of the check in the near future.
# if defined(__GXX_EXPERIMENTAL_CPP0X__) || defined(__GXX_EXPERIMENTAL_CXX0X__)
# define BOOST_INTRUSIVE_RVALUE_REFERENCE
# define BOOST_INTRUSIVE_VARIADIC_TEMPLATES
# endif
#include <boost/intrusive/detail/config_begin.hpp>
#if !defined(BOOST_NO_RVALUE_REFERENCES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
#define BOOST_INTRUSIVE_PERFECT_FORWARDING
#endif
#if defined(BOOST_INTRUSIVE_RVALUE_REFERENCE) && defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
#define BOOST_INTRUSIVE_PERFECT_FORWARDING
#endif
#include <boost/intrusive/detail/config_end.hpp>
#endif //#ifndef BOOST_INTRUSIVE_DETAIL_WRKRND_HPP

View File

@@ -18,7 +18,6 @@
#include <utility> //std::pair
#include <algorithm> //std::swap, std::lower_bound, std::upper_bound
#include <cstddef> //std::size_t
#include <iterator> //std::iterator_traits
//boost
#include <boost/intrusive/detail/assert.hpp>
#include <boost/static_assert.hpp>
@@ -26,7 +25,6 @@
#include <boost/pointer_cast.hpp>
//General intrusive utilities
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/detail/hashtable_node.hpp>
#include <boost/intrusive/detail/transform_iterator.hpp>
#include <boost/intrusive/link_mode.hpp>
@@ -36,6 +34,7 @@
#include <boost/intrusive/trivial_value_traits.hpp>
#include <boost/intrusive/unordered_set_hook.hpp>
#include <boost/intrusive/slist.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/type_traits.hpp>
#include <boost/move/move.hpp>
@@ -125,7 +124,8 @@ struct get_slist_impl
< typename NodeTraits::node
, boost::intrusive::value_traits<trivial_traits>
, boost::intrusive::constant_time_size<false>
, boost::intrusive::size_type<typename boost::make_unsigned<typename std::iterator_traits<typename NodeTraits::node_ptr>::difference_type>::type>
, boost::intrusive::size_type<typename boost::make_unsigned
<typename pointer_traits<typename NodeTraits::node_ptr>::difference_type>::type >
>::type
{};
};
@@ -174,8 +174,10 @@ struct unordered_bucket_ptr_impl
<SupposedValueTraits>::type::node_ptr node_ptr;
typedef typename unordered_bucket_impl
<SupposedValueTraits>::type bucket_type;
typedef typename boost::pointer_to_other
<node_ptr, bucket_type>::type implementation_defined;
typedef typename pointer_traits
<node_ptr>::template rebind_pointer
< bucket_type >::type implementation_defined;
typedef implementation_defined type;
};
@@ -267,6 +269,11 @@ struct bucket_hash_equal_t
: detail::ebo_functor_holder<typename Config::equal>(e)//equal()
, bucket_hash(::boost::forward<BucketTraits>(b_traits), h)
{}
template<class T>
void set_cache(T)
{}
bucket_hash_t<Config> bucket_hash;
};
@@ -285,6 +292,10 @@ struct bucket_hash_equal_t<Config, true>
: detail::ebo_functor_holder<typename Config::equal>(e) //equal()
, bucket_hash(::boost::forward<BucketTraits>(b_traits), h)
{}
void set_cache(const bucket_ptr & c)
{ cached_begin_ = c; }
bucket_hash_t<Config> bucket_hash;
bucket_ptr cached_begin_;
};
@@ -344,16 +355,11 @@ struct group_functions
typedef typename reduced_node_traits::node slist_node;
typedef circular_slist_algorithms<group_traits> group_algorithms;
static node_ptr dcast_bucket_ptr(slist_node_ptr p)
{
// This still fails in gcc < 4.4 so forget about it
// using ::boost::static_pointer_cast;
// return static_pointer_cast<node>(p);
return node_ptr(&static_cast<node&>(*p));
}
static node_ptr dcast_bucket_ptr(const slist_node_ptr &p)
{ return pointer_traits<node_ptr>::pointer_to(static_cast<node&>(*p)); }
static slist_node_ptr priv_get_bucket_before_begin
(slist_node_ptr bucket_beg, slist_node_ptr bucket_end, node_ptr p)
static slist_node_ptr get_bucket_before_begin
(const slist_node_ptr &bucket_beg, const slist_node_ptr &bucket_end, const node_ptr &p)
{
//First find the last node of p's group.
//This requires checking the first node of the next group or
@@ -384,7 +390,7 @@ struct group_functions
return possible_end;
}
static node_ptr priv_get_prev_to_first_in_group(slist_node_ptr bucket_node, node_ptr first_in_group)
static node_ptr get_prev_to_first_in_group(const slist_node_ptr &bucket_node, const node_ptr &first_in_group)
{
//Just iterate using group links and obtain the node
//before "first_in_group)"
@@ -397,7 +403,7 @@ struct group_functions
return prev_node;
}
static node_ptr priv_get_first_in_group_of_last_in_group(node_ptr last_in_group)
static node_ptr get_first_in_group_of_last_in_group(const node_ptr &last_in_group)
{
//Just iterate using group links and obtain the node
//before "last_in_group"
@@ -413,8 +419,7 @@ struct group_functions
return possible_first;
}
static void priv_erase_from_group(slist_node_ptr end_ptr, node_ptr to_erase_ptr, detail::true_)
static void erase_from_group(const slist_node_ptr &end_ptr, const node_ptr &to_erase_ptr, detail::true_)
{
node_ptr nxt_ptr(node_traits::get_next(to_erase_ptr));
node_ptr prev_in_group_ptr(group_traits::get_next(to_erase_ptr));
@@ -430,7 +435,7 @@ struct group_functions
}
else if(last_in_group){
node_ptr first_in_group =
priv_get_first_in_group_of_last_in_group(to_erase_ptr);
get_first_in_group_of_last_in_group(to_erase_ptr);
group_algorithms::unlink_after(first_in_group);
}
else{
@@ -438,14 +443,87 @@ struct group_functions
}
}
static void priv_erase_from_group(slist_node_ptr, node_ptr, detail::false_)
static void erase_from_group(const slist_node_ptr&, const node_ptr&, detail::false_)
{}
static node_ptr priv_get_last_in_group(node_ptr first_in_group, detail::true_)
static node_ptr get_last_in_group(const node_ptr &first_in_group, detail::true_)
{ return group_traits::get_next(first_in_group); }
static node_ptr priv_get_last_in_group(node_ptr n, detail::false_)
static node_ptr get_last_in_group(const node_ptr &n, detail::false_)
{ return n; }
static void init_group(const node_ptr &n, true_)
{ group_algorithms::init(n); }
static void init_group(const node_ptr &, false_)
{}
static void insert_in_group(const node_ptr &first_in_group, const node_ptr &n, true_)
{
if(first_in_group){
if(group_algorithms::unique(first_in_group))
group_algorithms::link_after(first_in_group, n);
else{
group_algorithms::link_after(group_algorithms::node_traits::get_next(first_in_group), n);
}
}
else{
group_algorithms::init_header(n);
}
}
static slist_node_ptr get_previous_and_next_in_group
( const slist_node_ptr &i, node_ptr &nxt_in_group
//If first_end_ptr == last_end_ptr, then first_end_ptr is the bucket of i
//Otherwise first_end_ptr is the first bucket and last_end_ptr the last one.
, const slist_node_ptr &first_end_ptr, const slist_node_ptr &last_end_ptr)
{
slist_node_ptr prev;
node_ptr elem(dcast_bucket_ptr(i));
//It's the last in group if the next_node is a bucket
slist_node_ptr nxt(node_traits::get_next(elem));
bool last_in_group = (first_end_ptr <= nxt && nxt <= last_end_ptr)/* ||
(group_traits::get_next(nxt) != elem)*/;
//It's the first in group if group_previous's next_node is not
//itself, as group list does not link bucket
node_ptr prev_in_group(group_traits::get_next(elem));
bool first_in_group = node_traits::get_next(prev_in_group) != elem;
if(first_in_group){
node_ptr start_pos;
if(last_in_group){
start_pos = elem;
nxt_in_group = node_ptr();
}
else{
start_pos = prev_in_group;
nxt_in_group = node_traits::get_next(elem);
}
slist_node_ptr bucket_node;
if(first_end_ptr != last_end_ptr){
bucket_node = group_functions::get_bucket_before_begin
(first_end_ptr, last_end_ptr, start_pos);
}
else{
bucket_node = first_end_ptr;
}
prev = group_functions::get_prev_to_first_in_group(bucket_node, elem);
}
else{
if(last_in_group){
nxt_in_group = group_functions::get_first_in_group_of_last_in_group(elem);
}
else{
nxt_in_group = node_traits::get_next(elem);
}
prev = group_traits::get_next(elem);
}
return prev;
}
static void insert_in_group(const node_ptr&, const node_ptr&, false_)
{}
};
template<class BucketType, class SplitTraits>
@@ -486,6 +564,16 @@ class incremental_rehash_rollback
bool released_;
};
template<class NodeTraits>
struct node_functions
{
static void store_hash(typename NodeTraits::node_ptr p, std::size_t h, true_)
{ return NodeTraits::set_hash(p, h); }
static void store_hash(typename NodeTraits::node_ptr, std::size_t, false_)
{}
};
} //namespace detail {
//!This metafunction will obtain the type of a bucket
@@ -620,27 +708,30 @@ class hashtable_impl
typedef typename real_value_traits::pointer pointer;
typedef typename real_value_traits::const_pointer const_pointer;
typedef typename real_value_traits::value_type value_type;
typedef typename std::iterator_traits<pointer>::reference reference;
typedef typename std::iterator_traits<const_pointer>::reference const_reference;
typedef typename std::iterator_traits<pointer>::difference_type difference_type;
typedef typename real_value_traits::value_type value_type;
typedef typename pointer_traits<pointer>::reference reference;
typedef typename pointer_traits<const_pointer>::reference const_reference;
typedef typename pointer_traits<pointer>::difference_type difference_type;
typedef typename Config::size_type size_type;
typedef value_type key_type;
typedef typename Config::equal key_equal;
typedef typename Config::hash hasher;
typedef detail::bucket_impl<slist_impl> bucket_type;
typedef typename boost::pointer_to_other
<pointer, bucket_type>::type bucket_ptr;
typedef typename pointer_traits
<pointer>::template rebind_pointer
< bucket_type >::type bucket_ptr;
typedef typename slist_impl::iterator siterator;
typedef typename slist_impl::const_iterator const_siterator;
typedef detail::hashtable_iterator<hashtable_impl, false> iterator;
typedef detail::hashtable_iterator<hashtable_impl, true> const_iterator;
typedef typename real_value_traits::node_traits node_traits;
typedef typename node_traits::node node;
typedef typename boost::pointer_to_other
<pointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<node_ptr, const node>::type const_node_ptr;
typedef typename pointer_traits
<pointer>::template rebind_pointer
< node >::type node_ptr;
typedef typename pointer_traits
<pointer>::template rebind_pointer
< const node >::type const_node_ptr;
typedef typename slist_impl::node_algorithms node_algorithms;
static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
@@ -664,8 +755,9 @@ class hashtable_impl
BOOST_STATIC_ASSERT((!compare_hash || store_hash));
typedef typename slist_impl::node_ptr slist_node_ptr;
typedef typename boost::pointer_to_other
<slist_node_ptr, void>::type void_pointer;
typedef typename pointer_traits
<slist_node_ptr>::template rebind_pointer
< void >::type void_pointer;
//We'll define group traits, but these won't be instantiated if
//optimize_multikey is not true
typedef unordered_group_adapter<node_traits> group_traits;
@@ -677,6 +769,7 @@ class hashtable_impl
typedef detail::size_holder<constant_time_size, size_type> size_traits;
typedef detail::size_holder<incremental, size_type> split_traits;
typedef detail::group_functions<node_traits> group_functions_t;
typedef detail::node_functions<node_traits> node_functions_t;
static const std::size_t hashtable_data_bool_flags_mask =
( detail::hash_bool_flags::cache_begin_pos
@@ -721,7 +814,9 @@ class hashtable_impl
{ return base_t::operator()(static_cast<const node &>(to_clone)); }
void operator()(typename slist_impl::node_ptr to_clone)
{ base_t::operator()(node_ptr(&static_cast<node &>(*to_clone))); }
{
base_t::operator()(pointer_traits<node_ptr>::pointer_to(static_cast<node &>(*to_clone)));
}
};
private:
@@ -757,16 +852,16 @@ class hashtable_impl
/// @cond
const real_value_traits &get_real_value_traits(detail::bool_<false>) const
const real_value_traits &get_real_value_traits(detail::false_) const
{ return this->data_; }
const real_value_traits &get_real_value_traits(detail::bool_<true>) const
const real_value_traits &get_real_value_traits(detail::true_) const
{ return data_.get_value_traits(*this); }
real_value_traits &get_real_value_traits(detail::bool_<false>)
real_value_traits &get_real_value_traits(detail::false_)
{ return this->data_; }
real_value_traits &get_real_value_traits(detail::bool_<true>)
real_value_traits &get_real_value_traits(detail::true_)
{ return data_.get_value_traits(*this); }
/// @endcond
@@ -931,7 +1026,7 @@ class hashtable_impl
}
else{
size_type buckets_len = this->priv_buckets_len();
const bucket_type *b = detail::boost_intrusive_get_pointer(this->priv_buckets());
const bucket_type *b = boost::intrusive::detail::to_raw_pointer(this->priv_buckets());
for (size_type n = 0; n < buckets_len; ++n, ++b){
if(!b->empty()){
return false;
@@ -954,7 +1049,7 @@ class hashtable_impl
else{
size_type len = 0;
size_type buckets_len = this->priv_buckets_len();
const bucket_type *b = detail::boost_intrusive_get_pointer(this->priv_buckets());
const bucket_type *b = boost::intrusive::detail::to_raw_pointer(this->priv_buckets());
for (size_type n = 0; n < buckets_len; ++n, ++b){
len += b->size();
}
@@ -1258,12 +1353,12 @@ class hashtable_impl
size_type bucket_num = priv_hash_to_bucket(commit_data.hash);
bucket_type &b = this->priv_buckets()[bucket_num];
this->priv_size_traits().increment();
node_ptr n = node_ptr(&priv_value_to_node(value));
this->priv_store_hash(n, commit_data.hash, store_hash_t());
node_ptr n = pointer_traits<node_ptr>::pointer_to(priv_value_to_node(value));
node_functions_t::store_hash(n, commit_data.hash, store_hash_t());
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
priv_insertion_update_cache(bucket_num);
this->priv_insert_in_group(node_ptr(0), n, optimize_multikey_t());
group_functions_t::insert_in_group(node_ptr(), n, optimize_multikey_t());
return iterator(b.insert_after(b.before_begin(), *n), this);
}
@@ -1442,7 +1537,7 @@ class hashtable_impl
}
else if(optimize_multikey){
siterator last = bucket_type::s_iterator_to
(*node_traits::get_next(group_functions_t::priv_get_last_in_group
(*node_traits::get_next(group_functions_t::get_last_in_group
(dcast_bucket_ptr(it.pointed_node()), optimize_multikey_t())));
this->priv_erase_range_impl(bucket_num, prev, last, disposer, count);
}
@@ -2012,7 +2107,7 @@ class hashtable_impl
if(cache_begin && new_n < new_first_bucket_num)
new_first_bucket_num = new_n;
siterator last = bucket_type::s_iterator_to
(*group_functions_t::priv_get_last_in_group
(*group_functions_t::get_last_in_group
(dcast_bucket_ptr(i.pointed_node()), optimize_multikey_t()));
if(same_buffer && new_n == n){
before_i = last;
@@ -2086,7 +2181,7 @@ class hashtable_impl
const std::size_t hash_value = this->priv_stored_or_compute_hash(v, store_hash_t());
const size_type new_n = priv_hash_to_bucket(hash_value);
siterator last = bucket_type::s_iterator_to
(*group_functions_t::priv_get_last_in_group
(*group_functions_t::get_last_in_group
(dcast_bucket_ptr(i.pointed_node()), optimize_multikey_t()));
if(new_n == bucket_to_rehash){
before_i = last;
@@ -2234,10 +2329,10 @@ class hashtable_impl
return bucket_number;
}
std::size_t priv_hash_to_bucket_impl(std::size_t hash_value, std::size_t bucket_len, detail::bool_<false>) const
std::size_t priv_hash_to_bucket_impl(std::size_t hash_value, std::size_t bucket_len, detail::false_) const
{ return hash_value % bucket_len; }
std::size_t priv_hash_to_bucket_impl(std::size_t hash_value, std::size_t bucket_len, detail::bool_<true>) const
std::size_t priv_hash_to_bucket_impl(std::size_t hash_value, std::size_t bucket_len, detail::true_) const
{ return hash_value & (bucket_len - 1); }
const key_equal &priv_equal() const
@@ -2258,16 +2353,16 @@ class hashtable_impl
const value_type &priv_value_from_slist_node(slist_node_ptr n) const
{ return *this->get_real_value_traits().to_value_ptr(dcast_bucket_ptr(n)); }
const real_bucket_traits &priv_real_bucket_traits(detail::bool_<false>) const
const real_bucket_traits &priv_real_bucket_traits(detail::false_) const
{ return this->data_.internal_.bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_; }
const real_bucket_traits &priv_real_bucket_traits(detail::bool_<true>) const
const real_bucket_traits &priv_real_bucket_traits(detail::true_) const
{ return this->data_.internal_.bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_.get_bucket_traits(*this); }
real_bucket_traits &priv_real_bucket_traits(detail::bool_<false>)
real_bucket_traits &priv_real_bucket_traits(detail::false_)
{ return this->data_.internal_.bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_; }
real_bucket_traits &priv_real_bucket_traits(detail::bool_<true>)
real_bucket_traits &priv_real_bucket_traits(detail::true_)
{ return this->data_.internal_.bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_.get_bucket_traits(*this); }
const real_bucket_traits &priv_real_bucket_traits() const
@@ -2294,8 +2389,8 @@ class hashtable_impl
size_type priv_buckets_len() const
{ return this->priv_real_bucket_traits().bucket_count(); }
static node_ptr uncast(const_node_ptr ptr)
{ return node_ptr(const_cast<node*>(detail::boost_intrusive_get_pointer(ptr))); }
static node_ptr uncast(const const_node_ptr & ptr)
{ return node_ptr(const_cast<node*>(boost::intrusive::detail::to_raw_pointer(ptr))); }
node &priv_value_to_node(value_type &v)
{ return *this->get_real_value_traits().to_node_ptr(v); }
@@ -2331,7 +2426,7 @@ class hashtable_impl
++to_erase;
slist_node_ptr end_ptr = end.pointed_node();
while(to_erase != end){
group_functions_t::priv_erase_from_group(end_ptr, dcast_bucket_ptr(to_erase.pointed_node()), optimize_multikey_t());
group_functions_t::erase_from_group(end_ptr, dcast_bucket_ptr(to_erase.pointed_node()), optimize_multikey_t());
to_erase = b.erase_after_and_dispose(before_first_it, make_node_disposer(disposer));
++num_erased;
}
@@ -2353,7 +2448,7 @@ class hashtable_impl
++nxt;
siterator end(b.end());
while(nxt != end){
priv_init_group(nxt.pointed_node(), optimize_multikey_t());
group_functions_t::init_group(dcast_bucket_ptr(nxt.pointed_node()), optimize_multikey_t());
nxt = b.erase_after_and_dispose
(b_begin, make_node_disposer(disposer));
this->priv_size_traits().decrement();
@@ -2381,12 +2476,7 @@ class hashtable_impl
}
static node_ptr dcast_bucket_ptr(typename slist_impl::node_ptr p)
{
// This still fails in gcc < 4.4 so forget about it
// using ::boost::static_pointer_cast;
// return static_pointer_cast<node>(p);
return node_ptr(&static_cast<node&>(*p));
}
{ return pointer_traits<node_ptr>::pointer_to(static_cast<node&>(*p)); }
std::size_t priv_stored_or_compute_hash(const value_type &v, detail::true_) const
{ return node_traits::get_hash(this->get_real_value_traits().to_node_ptr(v)); }
@@ -2404,12 +2494,6 @@ class hashtable_impl
return 0;
}
static void priv_store_hash(node_ptr p, std::size_t h, detail::true_)
{ return node_traits::set_hash(p, h); }
static void priv_store_hash(node_ptr, std::size_t, detail::false_)
{}
static void priv_clear_group_nodes(bucket_type &b, detail::true_)
{
siterator it(b.begin()), itend(b.end());
@@ -2438,7 +2522,7 @@ class hashtable_impl
std::size_t priv_get_bucket_num_no_hash_store(siterator it, detail::true_)
{
bucket_ptr f(priv_buckets()), l(f + priv_buckets_len() - 1);
slist_node_ptr bb = group_functions_t::priv_get_bucket_before_begin
slist_node_ptr bb = group_functions_t::get_bucket_before_begin
( f->end().pointed_node()
, l->end().pointed_node()
, dcast_bucket_ptr(it.pointed_node()));
@@ -2468,29 +2552,6 @@ class hashtable_impl
return static_cast<std::size_t>(&b - &*f);
}
void priv_init_group(slist_node_ptr n, detail::true_)
{ group_algorithms::init(dcast_bucket_ptr(n)); }
void priv_init_group(slist_node_ptr, detail::false_)
{}
void priv_insert_in_group(node_ptr first_in_group, node_ptr n, detail::true_)
{
if(first_in_group){
if(group_algorithms::unique(first_in_group))
group_algorithms::link_after(first_in_group, n);
else{
group_algorithms::link_after(node_traits::get_next(first_in_group), n);
}
}
else{
group_algorithms::init_header(n);
}
}
void priv_insert_in_group(node_ptr, node_ptr, detail::false_)
{}
siterator priv_get_previous
(bucket_type &b, siterator i)
{ return priv_get_previous(b, i, optimize_multikey_t()); }
@@ -2502,7 +2563,7 @@ class hashtable_impl
node_ptr prev_in_group(group_traits::get_next(elem));
bool first_in_group = node_traits::get_next(prev_in_group) != elem;
typename bucket_type::node &n = first_in_group
? *group_functions_t::priv_get_prev_to_first_in_group(b.end().pointed_node(), elem)
? *group_functions_t::get_prev_to_first_in_group(b.end().pointed_node(), elem)
: *group_traits::get_next(elem)
;
return bucket_type::s_iterator_to(n);
@@ -2533,7 +2594,7 @@ class hashtable_impl
static siterator priv_get_last(bucket_type &b, detail::false_)
{ return b.previous(b.end()); }
/*
siterator priv_get_previous_and_next_in_group
(siterator i, node_ptr &nxt_in_group)
{
@@ -2554,7 +2615,7 @@ class hashtable_impl
node_ptr start_pos;
if(last_in_group){
start_pos = elem;
nxt_in_group = 0;
nxt_in_group = node_ptr();
}
else{
start_pos = prev_in_group;
@@ -2568,15 +2629,15 @@ class hashtable_impl
].before_begin().pointed_node();
}
else{
bucket_node = group_functions_t::priv_get_bucket_before_begin
bucket_node = group_functions_t::get_bucket_before_begin
(first_end_ptr, last_end_ptr, start_pos);
}
prev = bucket_type::s_iterator_to
(*group_functions_t::priv_get_prev_to_first_in_group(bucket_node, elem));
(*group_functions_t::get_prev_to_first_in_group(bucket_node, elem));
}
else{
if(last_in_group){
nxt_in_group = group_functions_t::priv_get_first_in_group_of_last_in_group(elem);
nxt_in_group = group_functions_t::get_first_in_group_of_last_in_group(elem);
}
else{
nxt_in_group = node_traits::get_next(elem);
@@ -2585,7 +2646,9 @@ class hashtable_impl
}
return prev;
}
*/
/*
template<class Disposer>
void priv_erase(const_iterator i, Disposer disposer, detail::true_)
{
@@ -2598,6 +2661,47 @@ class hashtable_impl
if(safemode_or_autounlink)
group_algorithms::init(dcast_bucket_ptr(elem.pointed_node()));
}
*/
/*
if(store_hash){
bucket_node = this->priv_buckets()
[this->priv_hash_to_bucket
(this->priv_stored_hash(elem, store_hash_t()))
].before_begin().pointed_node();
}
else{
bucket_node = group_functions_t::get_bucket_before_begin
(first_end_ptr, last_end_ptr, start_pos);
}
*/
template<class Disposer>
void priv_erase(const_iterator i, Disposer disposer, detail::true_)
{
slist_node_ptr elem(i.slist_it().pointed_node());
slist_node_ptr f_bucket_end, l_bucket_end;
if(store_hash){
f_bucket_end = l_bucket_end =
(this->priv_buckets()
[this->priv_hash_to_bucket
(this->priv_stored_hash(elem, store_hash_t()))
]).before_begin().pointed_node();
}
else{
f_bucket_end = this->priv_buckets()->cend().pointed_node();
l_bucket_end = f_bucket_end + priv_buckets_len() - 1;
}
node_ptr nxt_in_group;
siterator prev = bucket_type::s_iterator_to
(*group_functions_t::get_previous_and_next_in_group
( elem, nxt_in_group, f_bucket_end, l_bucket_end)
);
bucket_type::s_erase_after_and_dispose(prev, make_node_disposer(disposer));
if(nxt_in_group)
group_algorithms::unlink_after(nxt_in_group);
if(safemode_or_autounlink)
group_algorithms::init(dcast_bucket_ptr(elem));
}
template <class Disposer>
void priv_erase(const_iterator i, Disposer disposer, detail::false_)
@@ -2620,7 +2724,7 @@ class hashtable_impl
siterator priv_begin() const
{ return priv_begin(cache_begin_t()); }
siterator priv_begin(detail::bool_<false>) const
siterator priv_begin(detail::false_) const
{
size_type n = 0;
size_type buckets_len = this->priv_buckets_len();
@@ -2633,7 +2737,7 @@ class hashtable_impl
return priv_invalid_local_it();
}
siterator priv_begin(detail::bool_<true>) const
siterator priv_begin(detail::true_) const
{
if(this->data_.internal_.bucket_hash_equal_.cached_begin_ == priv_invalid_bucket()){
return priv_invalid_local_it();
@@ -2646,16 +2750,16 @@ class hashtable_impl
void priv_initialize_cache()
{ priv_initialize_cache(cache_begin_t()); }
void priv_initialize_cache(detail::bool_<true>)
void priv_initialize_cache(detail::true_)
{ this->data_.internal_.bucket_hash_equal_.cached_begin_ = priv_invalid_bucket(); }
void priv_initialize_cache(detail::bool_<false>)
void priv_initialize_cache(detail::false_)
{}
void priv_insertion_update_cache(size_type insertion_bucket)
{ priv_insertion_update_cache(insertion_bucket, cache_begin_t()); }
void priv_insertion_update_cache(size_type insertion_bucket, detail::bool_<true>)
void priv_insertion_update_cache(size_type insertion_bucket, detail::true_)
{
bucket_ptr p = priv_buckets() + insertion_bucket;
if(p < this->data_.internal_.bucket_hash_equal_.cached_begin_){
@@ -2663,13 +2767,13 @@ class hashtable_impl
}
}
void priv_insertion_update_cache(size_type, detail::bool_<false>)
void priv_insertion_update_cache(size_type, detail::false_)
{}
void priv_erasure_update_cache(size_type first_bucket, size_type last_bucket)
{ priv_erasure_update_cache(first_bucket, last_bucket, cache_begin_t()); }
void priv_erasure_update_cache(size_type first_bucket_num, size_type last_bucket_num, detail::bool_<true>)
void priv_erasure_update_cache(size_type first_bucket_num, size_type last_bucket_num, detail::true_)
{
//If the last bucket is the end, the cache must be updated
//to the last position if all
@@ -2680,13 +2784,13 @@ class hashtable_impl
}
}
void priv_erasure_update_cache(size_type, size_type, detail::bool_<false>)
void priv_erasure_update_cache(size_type, size_type, detail::false_)
{}
void priv_erasure_update_cache()
{ priv_erasure_update_cache(cache_begin_t()); }
void priv_erasure_update_cache(detail::bool_<true>)
void priv_erasure_update_cache(detail::true_)
{
if(constant_time_size && !size()){
priv_initialize_cache();
@@ -2704,43 +2808,37 @@ class hashtable_impl
}
}
void priv_erasure_update_cache(detail::bool_<false>)
void priv_erasure_update_cache(detail::false_)
{}
void priv_swap_cache(detail::bool_<true>, hashtable_impl &other)
void priv_swap_cache(detail::true_, hashtable_impl &other)
{
std::swap( this->data_.internal_.bucket_hash_equal_.cached_begin_
, other.data_.internal_.bucket_hash_equal_.cached_begin_);
}
void priv_swap_cache(detail::bool_<false>, hashtable_impl &)
void priv_swap_cache(detail::false_, hashtable_impl &)
{}
bucket_ptr priv_get_cache()
{ return priv_get_cache(cache_begin_t()); }
bucket_ptr priv_get_cache(detail::bool_<true>)
bucket_ptr priv_get_cache(detail::true_)
{ return this->data_.internal_.bucket_hash_equal_.cached_begin_; }
bucket_ptr priv_get_cache(detail::bool_<false>)
bucket_ptr priv_get_cache(detail::false_)
{ return this->priv_buckets(); }
void priv_set_cache(bucket_ptr p)
{ priv_set_cache(p, cache_begin_t()); }
void priv_set_cache(bucket_ptr p, detail::bool_<true>)
{ this->data_.internal_.bucket_hash_equal_.cached_begin_ = p; }
void priv_set_cache(bucket_ptr, detail::bool_<false>)
{}
void priv_set_cache(const bucket_ptr &p)
{ this->data_.internal_.bucket_hash_equal_.set_cache(p); }
size_type priv_get_cache_bucket_num()
{ return priv_get_cache_bucket_num(cache_begin_t()); }
size_type priv_get_cache_bucket_num(detail::bool_<true>)
size_type priv_get_cache_bucket_num(detail::true_)
{ return this->data_.internal_.bucket_hash_equal_.cached_begin_ - this->priv_buckets(); }
size_type priv_get_cache_bucket_num(detail::bool_<false>)
size_type priv_get_cache_bucket_num(detail::false_)
{ return 0u; }
void priv_clear_buckets()
@@ -2803,7 +2901,7 @@ class hashtable_impl
}
if(optimize_multikey){
previt = bucket_type::s_iterator_to
(*group_functions_t::priv_get_last_in_group
(*group_functions_t::get_last_in_group
(dcast_bucket_ptr(it.pointed_node()), optimize_multikey_t()));
it = previt;
}
@@ -2833,16 +2931,16 @@ class hashtable_impl
it = b.before_begin();
}
//Now store hash if needed
node_ptr n = node_ptr(&priv_value_to_node(value));
this->priv_store_hash(n, hash_value, store_hash_t());
node_ptr n = pointer_traits<node_ptr>::pointer_to(priv_value_to_node(value));
node_functions_t::store_hash(n, hash_value, store_hash_t());
//Checks for some modes
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
//Shorcut for optimize_multikey cases
if(optimize_multikey){
node_ptr first_in_group = found_equal ?
dcast_bucket_ptr(it.pointed_node()) : node_ptr(0);
this->priv_insert_in_group(first_in_group, n, optimize_multikey_t());
dcast_bucket_ptr(it.pointed_node()) : node_ptr();
group_functions_t::insert_in_group(first_in_group, n, optimize_multikey_t());
}
//Update cache and increment size if needed
priv_insertion_update_cache(bucket_num);
@@ -2877,7 +2975,7 @@ class hashtable_impl
siterator it = to_return.first;
if(optimize_multikey){
to_return.second = bucket_type::s_iterator_to
(*node_traits::get_next(group_functions_t::priv_get_last_in_group
(*node_traits::get_next(group_functions_t::get_last_in_group
(dcast_bucket_ptr(it.pointed_node()), optimize_multikey_t())));
count = std::distance(it, to_return.second);
if(to_return.second != b.end()){

View File

@@ -62,18 +62,18 @@ class linear_slist_algorithms
//! <b>Effects</b>: Constructs an non-used list element, putting the next
//! pointer to null:
//! <tt>NodeTraits::get_next(this_node) == 0
//! <tt>NodeTraits::get_next(this_node) == node_ptr()</tt>
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void init(node_ptr this_node);
static void init(const node_ptr & this_node);
//! <b>Requires</b>: this_node must be in a circular list or be an empty circular list.
//!
//! <b>Effects</b>: Returns true is "this_node" is the only node of a circular list:
//! or it's a not inserted node:
//! <tt>return !NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node</tt>
//! <tt>return false == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node</tt>
//!
//! <b>Complexity</b>: Constant
//!
@@ -95,7 +95,7 @@ class linear_slist_algorithms
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void unlink_after(node_ptr prev_node);
static void unlink_after(const node_ptr & prev_node);
//! <b>Requires</b>: prev_node and last_node must be in a circular list
//! or be an empty circular list.
@@ -105,7 +105,7 @@ class linear_slist_algorithms
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void unlink_after(node_ptr prev_node, node_ptr last_node);
static void unlink_after(const node_ptr & prev_node, const node_ptr & last_node);
//! <b>Requires</b>: prev_node must be a node of a linear list.
//!
@@ -114,7 +114,7 @@ class linear_slist_algorithms
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void link_after(node_ptr prev_node, node_ptr this_node);
static void link_after(const node_ptr & prev_node, const node_ptr & this_node);
//! <b>Requires</b>: b and e must be nodes of the same linear list or an empty range.
//! and p must be a node of a different linear list.
@@ -125,7 +125,7 @@ class linear_slist_algorithms
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void transfer_after(node_ptr p, node_ptr b, node_ptr e);
static void transfer_after(const node_ptr & p, const node_ptr & b, const node_ptr & e);
#endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
@@ -136,8 +136,8 @@ class linear_slist_algorithms
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void init_header(node_ptr this_node)
{ NodeTraits::set_next(this_node, node_ptr(0)); }
static void init_header(const node_ptr & this_node)
{ NodeTraits::set_next(this_node, node_ptr ()); }
//! <b>Requires</b>: this_node and prev_init_node must be in the same linear list.
//!
@@ -148,7 +148,7 @@ class linear_slist_algorithms
//! <b>Complexity</b>: Linear to the number of elements between prev_init_node and this_node.
//!
//! <b>Throws</b>: Nothing.
static node_ptr get_previous_node(node_ptr prev_init_node, node_ptr this_node)
static node_ptr get_previous_node(const node_ptr & prev_init_node, const node_ptr & this_node)
{ return base_t::get_previous_node(prev_init_node, this_node); }
//! <b>Requires</b>: this_node must be in a linear list or be an empty linear list.
@@ -159,7 +159,7 @@ class linear_slist_algorithms
//! <b>Complexity</b>: Linear
//!
//! <b>Throws</b>: Nothing.
static std::size_t count(const_node_ptr this_node)
static std::size_t count(const const_node_ptr & this_node)
{
std::size_t result = 0;
const_node_ptr p = this_node;
@@ -179,7 +179,7 @@ class linear_slist_algorithms
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: Nothing.
static void swap_trailing_nodes(node_ptr this_node, node_ptr other_node)
static void swap_trailing_nodes(const node_ptr & this_node, const node_ptr & other_node)
{
node_ptr this_nxt = NodeTraits::get_next(this_node);
node_ptr other_nxt = NodeTraits::get_next(other_node);
@@ -194,9 +194,9 @@ class linear_slist_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: This function is linear to the contained elements.
static node_ptr reverse(node_ptr p)
static node_ptr reverse(const node_ptr & p)
{
if(!p) return node_ptr(0);
if(!p) return node_ptr();
node_ptr i = NodeTraits::get_next(p);
node_ptr first(p);
while(i){
@@ -217,9 +217,9 @@ class linear_slist_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements plus the number moved positions.
static std::pair<node_ptr, node_ptr> move_first_n_backwards(node_ptr p, std::size_t n)
static std::pair<node_ptr, node_ptr> move_first_n_backwards(const node_ptr & p, std::size_t n)
{
std::pair<node_ptr, node_ptr> ret(node_ptr(0), node_ptr(0));
std::pair<node_ptr, node_ptr> ret;
//Null shift, or count() == 0 or 1, nothing to do
if(!n || !p || !NodeTraits::get_next(p)){
return ret;
@@ -227,8 +227,8 @@ class linear_slist_algorithms
node_ptr first = p;
bool end_found = false;
node_ptr new_last(0);
node_ptr old_last(0);
node_ptr new_last = node_ptr();
node_ptr old_last = node_ptr();
//Now find the new last node according to the shift count.
//If we find 0 before finding the new last node
@@ -237,7 +237,7 @@ class linear_slist_algorithms
for(std::size_t i = 1; i <= n; ++i){
new_last = first;
first = NodeTraits::get_next(first);
if(first == 0){
if(first == node_ptr()){
//Shortcut the shift with the modulo of the size of the list
n %= i;
if(!n) return ret;
@@ -253,12 +253,12 @@ class linear_slist_algorithms
//If the p has not been found in the previous loop, find it
//starting in the new first node and unlink it
if(!end_found){
old_last = base_t::get_previous_node(first, node_ptr(0));
old_last = base_t::get_previous_node(first, node_ptr());
}
//Now link p after the new last node
NodeTraits::set_next(old_last, p);
NodeTraits::set_next(new_last, node_ptr(0));
NodeTraits::set_next(new_last, node_ptr());
ret.first = first;
ret.second = new_last;
return ret;
@@ -272,9 +272,9 @@ class linear_slist_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear to the number of elements plus the number moved positions.
static std::pair<node_ptr, node_ptr> move_first_n_forward(node_ptr p, std::size_t n)
static std::pair<node_ptr, node_ptr> move_first_n_forward(const node_ptr & p, std::size_t n)
{
std::pair<node_ptr, node_ptr> ret(node_ptr(0), node_ptr(0));
std::pair<node_ptr, node_ptr> ret;
//Null shift, or count() == 0 or 1, nothing to do
if(!n || !p || !NodeTraits::get_next(p))
return ret;
@@ -312,7 +312,7 @@ class linear_slist_algorithms
node_ptr new_first(node_traits::get_next(new_last));
//Now put the old beginning after the old end
NodeTraits::set_next(old_last, p);
NodeTraits::set_next(new_last, node_ptr(0));
NodeTraits::set_next(new_last, node_ptr());
ret.first = new_first;
ret.second = new_last;
return ret;

View File

@@ -19,12 +19,13 @@
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/list_hook.hpp>
#include <boost/intrusive/circular_list_algorithms.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/static_assert.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/utilities.hpp>
#include <iterator>
#include <algorithm>
@@ -91,15 +92,15 @@ class list_impl
/// @endcond
typedef typename real_value_traits::pointer pointer;
typedef typename real_value_traits::const_pointer const_pointer;
typedef typename std::iterator_traits<pointer>::value_type value_type;
typedef typename std::iterator_traits<pointer>::reference reference;
typedef typename std::iterator_traits<const_pointer>::reference const_reference;
typedef typename std::iterator_traits<pointer>::difference_type difference_type;
typedef typename pointer_traits<pointer>::element_type value_type;
typedef typename pointer_traits<pointer>::reference reference;
typedef typename pointer_traits<const_pointer>::reference const_reference;
typedef typename pointer_traits<pointer>::difference_type difference_type;
typedef typename Config::size_type size_type;
typedef list_iterator<list_impl, false> iterator;
typedef list_iterator<list_impl, true> const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef boost::intrusive::detail::reverse_iterator<iterator> reverse_iterator;
typedef boost::intrusive::detail::reverse_iterator<const_iterator>const_reverse_iterator;
typedef typename real_value_traits::node_traits node_traits;
typedef typename node_traits::node node;
typedef typename node_traits::node_ptr node_ptr;
@@ -127,17 +128,14 @@ class list_impl
));
//Const cast emulation for smart pointers
static node_ptr uncast(const_node_ptr ptr)
{
return const_cast<node*>(detail::boost_intrusive_get_pointer(ptr));
//iG pending return node_ptr(boost::const_pointer_cast<node>(ptr));
}
static node_ptr uncast(const const_node_ptr & ptr)
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
node_ptr get_root_node()
{ return node_ptr(&data_.root_plus_size_.root_); }
{ return pointer_traits<node_ptr>::pointer_to(data_.root_plus_size_.root_); }
const_node_ptr get_root_node() const
{ return const_node_ptr(&data_.root_plus_size_.root_); }
{ return pointer_traits<const_node_ptr>::pointer_to(data_.root_plus_size_.root_); }
struct root_plus_size : public size_traits
{
@@ -1299,7 +1297,7 @@ class list_impl
static list_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
{
root_plus_size *r = detail::parent_from_member<root_plus_size, node>
( detail::boost_intrusive_get_pointer(end_iterator.pointed_node()), &root_plus_size::root_);
( boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()), &root_plus_size::root_);
data_t *d = detail::parent_from_member<data_t, root_plus_size>
( r, &data_t::root_plus_size_);
list_impl *s = detail::parent_from_member<list_impl, data_t>(d, &list_impl::data_);

View File

@@ -16,6 +16,7 @@
#include <boost/intrusive/link_mode.hpp>
#include <iterator>
#include <boost/intrusive/detail/parent_from_member.hpp>
#include <boost/intrusive/pointer_traits.hpp>
namespace boost {
namespace intrusive {
@@ -29,15 +30,19 @@ template< class T, class NodeTraits
struct member_value_traits
{
public:
typedef NodeTraits node_traits;
typedef T value_type;
typedef typename node_traits::node node;
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef typename boost::pointer_to_other<node_ptr, T>::type pointer;
typedef typename boost::pointer_to_other<node_ptr, const T>::type const_pointer;
typedef typename std::iterator_traits<pointer>::reference reference;
typedef typename std::iterator_traits<const_pointer>::reference const_reference;
typedef NodeTraits node_traits;
typedef T value_type;
typedef typename node_traits::node node;
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef typename pointer_traits<node_ptr>::template
rebind_pointer<T>::type pointer;
typedef typename pointer_traits<node_ptr>::template
rebind_pointer<const T>::type const_pointer;
//typedef typename pointer_traits<pointer>::reference reference;
//typedef typename pointer_traits<const_pointer>::reference const_reference;
typedef value_type & reference;
typedef const value_type & const_reference;
static const link_mode_type link_mode = LinkMode;
static node_ptr to_node_ptr(reference value)
@@ -46,16 +51,16 @@ struct member_value_traits
static const_node_ptr to_node_ptr(const_reference value)
{ return node_ptr(&(value.*PtrToMember)); }
static pointer to_value_ptr(node_ptr n)
static pointer to_value_ptr(const node_ptr &n)
{
return pointer(detail::parent_from_member<value_type, node>
(detail::boost_intrusive_get_pointer(n), PtrToMember));
(boost::intrusive::detail::to_raw_pointer(n), PtrToMember));
}
static const_pointer to_value_ptr(const_node_ptr n)
static const_pointer to_value_ptr(const const_node_ptr &n)
{
return pointer(detail::parent_from_member<value_type, node>
(detail::boost_intrusive_get_pointer(n), PtrToMember));
(boost::intrusive::detail::to_raw_pointer(n), PtrToMember));
}
};

View File

@@ -0,0 +1,265 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Pablo Halpern 2009. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2011-2011. 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_POINTER_TRAITS_HPP
#define BOOST_INTRUSIVE_POINTER_TRAITS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/workaround.hpp>
#include <boost/intrusive/detail/memory_util.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <cstddef>
namespace boost {
namespace intrusive {
//! pointer_traits is the implementation of C++11 std::pointer_traits class with some
//! extensions like castings.
//!
//! pointer_traits supplies a uniform interface to certain attributes of pointer-like types.
template <typename Ptr>
struct pointer_traits
{
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//!The pointer type
//!queried by this pointer_traits instantiation
typedef Ptr pointer;
//!Ptr::element_type if such a type exists; otherwise, T if Ptr is a class
//!template instantiation of the form SomePointer<T, Args>, where Args is zero or
//!more type arguments ; otherwise , the specialization is ill-formed.
typedef unspecified_type element_type;
//!Ptr::difference_type if such a type exists; otherwise,
//!std::ptrdiff_t.
typedef unspecified_type difference_type;
//!Ptr::rebind<U> if such a type exists; otherwise, SomePointer<U, Args> if Ptr is
//!a class template instantiation of the form SomePointer<T, Args>, where Args is zero or
//!more type arguments ; otherwise, the instantiation of rebind is ill-formed.
//!
//!For portable code for C++03 and C++11, <pre>typename rebind_pointer<U>::type</pre>
//!shall be used instead of rebind<U> to obtain a pointer to U.
template <class U> using rebind = unspecified;
//!Ptr::rebind<U> if such a type exists; otherwise, SomePointer<U, Args> if Ptr is
//!a class template instantiation of the form SomePointer<T, Args>, where Args is zero or
//!more type arguments ; otherwise, the instantiation of rebind is ill-formed.
//!
typedef element_type &reference;
#else
typedef Ptr pointer;
//
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
( boost::intrusive::detail::, Ptr, element_type
, typename boost::intrusive::detail::first_param<Ptr>::type) element_type;
//
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT
(boost::intrusive::detail::, Ptr, difference_type, std::ptrdiff_t) difference_type;
//
typedef typename boost::intrusive::detail::unvoid<element_type>::type& reference;
//
template <class U> struct rebind_pointer
{
typedef typename boost::intrusive::detail::type_rebinder<Ptr, U>::type type;
};
#if !defined(BOOST_NO_TEMPLATE_ALIASES)
template <class U> using rebind = typename boost::intrusive::detail::type_rebinder<Ptr, U>::type;
#endif
#endif //#if !defined(BOOST_NO_TEMPLATE_ALIASES)
//! <b>Remark</b>: If element_type is (possibly cv-qualified) void, r type is unspecified; otherwise,
//! it is element_type &.
//!
//! <b>Returns</b>: A dereferenceable pointer to r obtained by calling Ptr::pointer_to(r).
//! Non-standard extension: If such function does not exist, returns pointer(addressof(r));
static pointer pointer_to(reference r)
{
//Non-standard extension, it does not require Ptr::pointer_to. If not present
//tries to converts &r to pointer.
const bool value = boost::intrusive::detail::
has_member_function_callable_with_pointer_to
<Ptr, typename boost::intrusive::detail::unvoid<element_type &>::type>::value;
::boost::integral_constant<bool, value> flag;
return pointer_traits::priv_pointer_to(flag, r);
}
//! <b>Remark</b>: Non-standard extension.
//!
//! <b>Returns</b>: A dereferenceable pointer to r obtained by calling Ptr::static_cast_from(r).
//! If such function does not exist, returns pointer_to(static_cast<element_type&>(*uptr))
template<class UPtr>
static pointer static_cast_from(const UPtr &uptr)
{
const bool value = boost::intrusive::detail::
has_member_function_callable_with_static_cast_from
<Ptr, const UPtr>::value;
::boost::integral_constant<bool, value> flag;
return pointer_traits::priv_static_cast_from(flag, uptr);
}
//! <b>Remark</b>: Non-standard extension.
//!
//! <b>Returns</b>: A dereferenceable pointer to r obtained by calling Ptr::const_cast_from(r).
//! If such function does not exist, returns pointer_to(const_cast<element_type&>(*uptr))
template<class UPtr>
static pointer const_cast_from(const UPtr &uptr)
{
const bool value = boost::intrusive::detail::
has_member_function_callable_with_const_cast_from
<Ptr, const UPtr>::value;
::boost::integral_constant<bool, value> flag;
return pointer_traits::priv_const_cast_from(flag, uptr);
}
//! <b>Remark</b>: Non-standard extension.
//!
//! <b>Returns</b>: A dereferenceable pointer to r obtained by calling Ptr::dynamic_cast_from(r).
//! If such function does not exist, returns pointer_to(*dynamic_cast<element_type*>(&*uptr))
template<class UPtr>
static pointer dynamic_cast_from(const UPtr &uptr)
{
const bool value = boost::intrusive::detail::
has_member_function_callable_with_dynamic_cast_from
<Ptr, const UPtr>::value;
::boost::integral_constant<bool, value> flag;
return pointer_traits::priv_dynamic_cast_from(flag, uptr);
}
///@cond
private:
//priv_to_raw_pointer
template <class T>
static T* to_raw_pointer(T* p)
{ return p; }
template <class Pointer>
static typename pointer_traits<Pointer>::element_type*
to_raw_pointer(const Pointer &p)
{ return pointer_traits::to_raw_pointer(p.operator->()); }
//priv_pointer_to
static pointer priv_pointer_to(boost::true_type, typename boost::intrusive::detail::unvoid<element_type>::type& r)
{ return Ptr::pointer_to(r); }
static pointer priv_pointer_to(boost::false_type, typename boost::intrusive::detail::unvoid<element_type>::type& r)
{ return pointer(boost::intrusive::detail::addressof(r)); }
//priv_static_cast_from
template<class UPtr>
static pointer priv_static_cast_from(boost::true_type, const UPtr &uptr)
{ return Ptr::static_cast_from(uptr); }
template<class UPtr>
static pointer priv_static_cast_from(boost::false_type, const UPtr &uptr)
{ return pointer_to(static_cast<element_type&>(*uptr)); }
//priv_const_cast_from
template<class UPtr>
static pointer priv_const_cast_from(boost::true_type, const UPtr &uptr)
{ return Ptr::const_cast_from(uptr); }
template<class UPtr>
static pointer priv_const_cast_from(boost::false_type, const UPtr &uptr)
{ return pointer_to(const_cast<element_type&>(*uptr)); }
//priv_dynamic_cast_from
template<class UPtr>
static pointer priv_dynamic_cast_from(boost::true_type, const UPtr &uptr)
{ return Ptr::dynamic_cast_from(uptr); }
template<class UPtr>
static pointer priv_dynamic_cast_from(boost::false_type, const UPtr &uptr)
{ return pointer_to(*dynamic_cast<element_type*>(&*uptr)); }
///@endcond
};
///@cond
// Remove cv qualification from Ptr parameter to pointer_traits:
template <typename Ptr>
struct pointer_traits<const Ptr> : pointer_traits<Ptr> {};
template <typename Ptr>
struct pointer_traits<volatile Ptr> : pointer_traits<Ptr> { };
template <typename Ptr>
struct pointer_traits<const volatile Ptr> : pointer_traits<Ptr> { };
// Remove reference from Ptr parameter to pointer_traits:
template <typename Ptr>
struct pointer_traits<Ptr&> : pointer_traits<Ptr> { };
///@endcond
//! Specialization of pointer_traits for raw pointers
//!
template <typename T>
struct pointer_traits<T*>
{
typedef T element_type;
typedef T* pointer;
typedef std::ptrdiff_t difference_type;
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
typedef T & reference;
//!typedef for <pre>U *</pre>
//!
//!For portable code for C++03 and C++11, <pre>typename rebind_pointer<U>::type</pre>
//!shall be used instead of rebind<U> to obtain a pointer to U.
template <class U> using rebind = U*;
#else
typedef typename boost::intrusive::detail::unvoid<element_type>::type& reference;
#if !defined(BOOST_NO_TEMPLATE_ALIASES)
template <class U> using rebind = U*;
#endif
#endif
template <class U> struct rebind_pointer
{ typedef U* type; };
//! <b>Returns</b>: addressof(r)
//!
static pointer pointer_to(reference r)
{ return boost::intrusive::detail::addressof(r); }
//! <b>Returns</b>: static_cast<pointer>(uptr)
//!
template<class U>
static pointer static_cast_from(U *uptr)
{ return static_cast<pointer>(uptr); }
//! <b>Returns</b>: const_cast<pointer>(uptr)
//!
template<class U>
static pointer const_cast_from(U *uptr)
{ return const_cast<pointer>(uptr); }
//! <b>Returns</b>: dynamic_cast<pointer>(uptr)
//!
template<class U>
static pointer dynamic_cast_from(U *uptr)
{ return dynamic_cast<pointer>(uptr); }
};
} //namespace container {
} //namespace boost {
#include <boost/intrusive/detail/config_end.hpp>
#endif // ! defined(BOOST_INTRUSIVE_POINTER_TRAITS_HPP)

View File

@@ -27,9 +27,10 @@
#include <boost/intrusive/detail/tree_node.hpp>
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
#include <boost/intrusive/detail/function_detector.hpp>
#include <boost/intrusive/detail/utilities.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/intrusive/rbtree_algorithms.hpp>
#include <boost/intrusive/link_mode.hpp>
@@ -97,18 +98,19 @@ class rbtree_impl
/// @endcond
typedef typename real_value_traits::pointer pointer;
typedef typename real_value_traits::const_pointer const_pointer;
typedef typename std::iterator_traits<pointer>::value_type value_type;
typedef typename pointer_traits<pointer>::element_type value_type;
typedef value_type key_type;
typedef typename std::iterator_traits<pointer>::reference reference;
typedef typename std::iterator_traits<const_pointer>::reference const_reference;
typedef typename std::iterator_traits<pointer>::difference_type difference_type;
typedef typename pointer_traits<pointer>::reference reference;
typedef typename pointer_traits<const_pointer>::reference const_reference;
typedef typename pointer_traits<const_pointer>::difference_type difference_type;
typedef typename Config::size_type size_type;
typedef typename Config::compare value_compare;
typedef value_compare key_compare;
typedef tree_iterator<rbtree_impl, false> iterator;
typedef tree_iterator<rbtree_impl, true> const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef boost::intrusive::detail::reverse_iterator<iterator> reverse_iterator;
typedef boost::intrusive::detail::reverse_iterator<const_iterator>const_reverse_iterator;
typedef typename real_value_traits::node_traits node_traits;
typedef typename node_traits::node node;
typedef typename node_traits::node_ptr node_ptr;
@@ -163,17 +165,14 @@ class rbtree_impl
value_traits &priv_value_traits()
{ return data_; }
const node &priv_header() const
{ return data_.node_plus_pred_.header_plus_size_.header_; }
node_ptr priv_header_ptr()
{ return pointer_traits<node_ptr>::pointer_to(data_.node_plus_pred_.header_plus_size_.header_); }
node &priv_header()
{ return data_.node_plus_pred_.header_plus_size_.header_; }
const_node_ptr priv_header_ptr() const
{ return pointer_traits<const_node_ptr>::pointer_to(data_.node_plus_pred_.header_plus_size_.header_); }
static node_ptr uncast(const_node_ptr ptr)
{
return node_ptr(const_cast<node*>(detail::boost_intrusive_get_pointer(ptr)));
//iG pending return node_ptr(boost::const_pointer_cast<node>(ptr));
}
static node_ptr uncast(const const_node_ptr & ptr)
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
size_traits &priv_size_traits()
{ return data_.node_plus_pred_.header_plus_size_; }
@@ -198,10 +197,10 @@ class rbtree_impl
{ return priv_comp(); }
const node &prot_header_node() const
{ return priv_header(); }
{ return data_.node_plus_pred_.header_plus_size_.header_; }
node &prot_header_node()
{ return priv_header(); }
{ return data_.node_plus_pred_.header_plus_size_.header_; }
void prot_set_size(size_type s)
{ this->priv_size_traits().set_size(s); }
@@ -229,7 +228,7 @@ class rbtree_impl
, const value_traits &v_traits = value_traits())
: data_(cmp, v_traits)
{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(size_type(0));
}
@@ -251,7 +250,7 @@ class rbtree_impl
, const value_traits &v_traits = value_traits())
: data_(cmp, v_traits)
{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(size_type(0));
if(unique)
this->insert_unique(b, e);
@@ -264,7 +263,7 @@ class rbtree_impl
rbtree_impl(BOOST_RV_REF(rbtree_impl) x)
: data_(::boost::move(x.priv_comp()), ::boost::move(x.priv_value_traits()))
{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(size_type(0));
this->swap(x);
}
@@ -290,7 +289,7 @@ class rbtree_impl
//!
//! <b>Throws</b>: Nothing.
iterator begin()
{ return iterator (node_traits::get_left(node_ptr(&priv_header())), this); }
{ return iterator (node_traits::get_left(this->priv_header_ptr()), this); }
//! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the tree.
//!
@@ -306,7 +305,7 @@ class rbtree_impl
//!
//! <b>Throws</b>: Nothing.
const_iterator cbegin() const
{ return const_iterator (node_traits::get_left(const_node_ptr(&priv_header())), this); }
{ return const_iterator (node_traits::get_left(this->priv_header_ptr()), this); }
//! <b>Effects</b>: Returns an iterator pointing to the end of the tree.
//!
@@ -314,7 +313,7 @@ class rbtree_impl
//!
//! <b>Throws</b>: Nothing.
iterator end()
{ return iterator (node_ptr(&priv_header()), this); }
{ return iterator (this->priv_header_ptr(), this); }
//! <b>Effects</b>: Returns a const_iterator pointing to the end of the tree.
//!
@@ -330,7 +329,7 @@ class rbtree_impl
//!
//! <b>Throws</b>: Nothing.
const_iterator cend() const
{ return const_iterator (uncast(const_node_ptr(&priv_header())), this); }
{ return const_iterator (uncast(this->priv_header_ptr()), this); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning of the
//! reversed tree.
@@ -444,7 +443,7 @@ class rbtree_impl
//!
//! <b>Throws</b>: Nothing.
bool empty() const
{ return node_algorithms::unique(const_node_ptr(&priv_header())); }
{ return node_algorithms::unique(this->priv_header_ptr()); }
//! <b>Effects</b>: Returns the number of elements stored in the tree.
//!
@@ -457,7 +456,7 @@ class rbtree_impl
if(constant_time_size)
return this->priv_size_traits().get_size();
else{
return (size_type)node_algorithms::size(const_node_ptr(&priv_header()));
return (size_type)node_algorithms::size(this->priv_header_ptr());
}
}
@@ -472,7 +471,7 @@ class rbtree_impl
using std::swap;
swap(priv_comp(), priv_comp());
//These can't throw
node_algorithms::swap_tree(node_ptr(&priv_header()), node_ptr(&other.priv_header()));
node_algorithms::swap_tree(this->priv_header_ptr(), node_ptr(other.priv_header_ptr()));
if(constant_time_size){
size_type backup = this->priv_size_traits().get_size();
this->priv_size_traits().set_size(other.priv_size_traits().get_size());
@@ -499,7 +498,7 @@ class rbtree_impl
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
iterator ret(node_algorithms::insert_equal_upper_bound
(node_ptr(&priv_header()), to_insert, key_node_comp), this);
(this->priv_header_ptr(), to_insert, key_node_comp), this);
this->priv_size_traits().increment();
return ret;
}
@@ -526,7 +525,7 @@ class rbtree_impl
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
iterator ret(node_algorithms::insert_equal
(node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp), this);
(this->priv_header_ptr(), hint.pointed_node(), to_insert, key_node_comp), this);
this->priv_size_traits().increment();
return ret;
}
@@ -662,7 +661,7 @@ class rbtree_impl
comp(key_value_comp, this);
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
(node_ptr(&priv_header()), key, comp, commit_data));
(this->priv_header_ptr(), key, comp, commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
}
@@ -707,7 +706,7 @@ class rbtree_impl
comp(key_value_comp, this);
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
(node_ptr(&priv_header()), hint.pointed_node(), key, comp, commit_data));
(this->priv_header_ptr(), hint.pointed_node(), key, comp, commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
}
@@ -734,7 +733,7 @@ class rbtree_impl
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
node_algorithms::insert_unique_commit
(node_ptr(&priv_header()), to_insert, commit_data);
(this->priv_header_ptr(), to_insert, commit_data);
this->priv_size_traits().increment();
return iterator(to_insert, this);
}
@@ -760,7 +759,7 @@ class rbtree_impl
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->priv_size_traits().increment();
return iterator(node_algorithms::insert_before
(node_ptr(&priv_header()), pos.pointed_node(), to_insert), this);
(this->priv_header_ptr(), pos.pointed_node(), to_insert), this);
}
//! <b>Requires</b>: value must be an lvalue, and it must be no less
@@ -783,7 +782,7 @@ class rbtree_impl
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->priv_size_traits().increment();
node_algorithms::push_back(node_ptr(&priv_header()), to_insert);
node_algorithms::push_back(this->priv_header_ptr(), to_insert);
}
//! <b>Requires</b>: value must be an lvalue, and it must be no greater
@@ -806,7 +805,7 @@ class rbtree_impl
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->priv_size_traits().increment();
node_algorithms::push_front(node_ptr(&priv_header()), to_insert);
node_algorithms::push_front(this->priv_header_ptr(), to_insert);
}
//! <b>Effects</b>: Erases the element pointed to by pos.
@@ -824,7 +823,7 @@ class rbtree_impl
node_ptr to_erase(i.pointed_node());
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
node_algorithms::erase(&priv_header(), to_erase);
node_algorithms::erase(this->priv_header_ptr(), to_erase);
this->priv_size_traits().decrement();
if(safemode_or_autounlink)
node_algorithms::init(to_erase);
@@ -986,7 +985,7 @@ class rbtree_impl
this->clear_and_dispose(detail::null_disposer());
}
else{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(0);
}
}
@@ -1003,9 +1002,9 @@ class rbtree_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer)
{
node_algorithms::clear_and_dispose(node_ptr(&priv_header())
node_algorithms::clear_and_dispose(this->priv_header_ptr()
, detail::node_disposer<Disposer, rbtree_impl>(disposer, this));
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(0);
}
@@ -1061,7 +1060,7 @@ class rbtree_impl
detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
key_node_comp(comp, this);
return iterator(node_algorithms::lower_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Returns a const iterator to the first element whose
@@ -1076,7 +1075,7 @@ class rbtree_impl
detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
key_node_comp(comp, this);
return const_iterator(node_algorithms::lower_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Returns an iterator to the first element whose
@@ -1101,7 +1100,7 @@ class rbtree_impl
detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
key_node_comp(comp, this);
return iterator(node_algorithms::upper_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Returns an iterator to the first element whose
@@ -1126,7 +1125,7 @@ class rbtree_impl
detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
key_node_comp(comp, this);
return const_iterator(node_algorithms::upper_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Finds an iterator to the first element whose key is
@@ -1150,7 +1149,7 @@ class rbtree_impl
detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
key_node_comp(comp, this);
return iterator
(node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this);
(node_algorithms::find(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Finds a const_iterator to the first element whose key is
@@ -1174,7 +1173,7 @@ class rbtree_impl
detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
key_node_comp(comp, this);
return const_iterator
(node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this);
(node_algorithms::find(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Finds a range containing all elements whose key is k or
@@ -1200,7 +1199,7 @@ class rbtree_impl
detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
key_node_comp(comp, this);
std::pair<node_ptr, node_ptr> ret
(node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp));
(node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp));
return std::pair<iterator, iterator>(iterator(ret.first, this), iterator(ret.second, this));
}
@@ -1229,7 +1228,7 @@ class rbtree_impl
detail::key_nodeptr_comp<KeyValueCompare, rbtree_impl>
key_node_comp(comp, this);
std::pair<node_ptr, node_ptr> ret
(node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp));
(node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp));
return std::pair<const_iterator, const_iterator>(const_iterator(ret.first, this), const_iterator(ret.second, this));
}
@@ -1255,8 +1254,8 @@ class rbtree_impl
detail::exception_disposer<rbtree_impl, Disposer>
rollback(*this, disposer);
node_algorithms::clone
(const_node_ptr(&src.priv_header())
,node_ptr(&this->priv_header())
(const_node_ptr(src.priv_header_ptr())
,node_ptr(this->priv_header_ptr())
,detail::node_cloner<Cloner, rbtree_impl>(cloner, this)
,detail::node_disposer<Disposer, rbtree_impl>(disposer, this));
this->priv_size_traits().set_size(src.priv_size_traits().get_size());
@@ -1278,7 +1277,7 @@ class rbtree_impl
pointer unlink_leftmost_without_rebalance()
{
node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance
(node_ptr(&priv_header())));
(this->priv_header_ptr()));
if(!to_be_disposed)
return 0;
this->priv_size_traits().decrement();
@@ -1304,7 +1303,7 @@ class rbtree_impl
void replace_node(iterator replace_this, reference with_this)
{
node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this)
, node_ptr(&priv_header())
, this->priv_header_ptr()
, get_real_value_traits().to_node_ptr(with_this));
if(safemode_or_autounlink)
node_algorithms::init(replace_this.pointed_node());
@@ -1427,7 +1426,7 @@ class rbtree_impl
static rbtree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
{
header_plus_size *r = detail::parent_from_member<header_plus_size, node>
( detail::boost_intrusive_get_pointer(end_iterator.pointed_node()), &header_plus_size::header_);
( boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()), &header_plus_size::header_);
node_plus_pred_t *n = detail::parent_from_member
<node_plus_pred_t, header_plus_size>(r, &node_plus_pred_t::header_plus_size_);
data_t *d = detail::parent_from_member<data_t, node_plus_pred_t>(n, &data_t::node_plus_pred_);

View File

@@ -56,6 +56,7 @@
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/utilities.hpp>
#include <boost/intrusive/detail/tree_algorithms.hpp>
#include <boost/intrusive/pointer_traits.hpp>
namespace boost {
namespace intrusive {
@@ -135,7 +136,7 @@ class rbtree_algorithms
: base_t(f)
{}
node_ptr operator()(node_ptr p)
node_ptr operator()(const node_ptr & p)
{
node_ptr n = base_t::get()(p);
NodeTraits::set_color(n, NodeTraits::get_color(p));
@@ -145,7 +146,7 @@ class rbtree_algorithms
struct rbtree_erase_fixup
{
void operator()(node_ptr to_erase, node_ptr successor)
void operator()(const node_ptr & to_erase, const node_ptr & successor)
{
//Swap color of y and z
color tmp(NodeTraits::get_color(successor));
@@ -154,17 +155,15 @@ class rbtree_algorithms
}
};
static node_ptr uncast(const_node_ptr ptr)
{
return node_ptr(const_cast<node*>(::boost::intrusive::detail::boost_intrusive_get_pointer(ptr)));
}
static node_ptr uncast(const const_node_ptr & ptr)
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
/// @endcond
public:
static node_ptr begin_node(const_node_ptr header)
static node_ptr begin_node(const const_node_ptr & header)
{ return tree_algorithms::begin_node(header); }
static node_ptr end_node(const_node_ptr header)
static node_ptr end_node(const const_node_ptr & header)
{ return tree_algorithms::end_node(header); }
//! This type is the information that will be
@@ -180,7 +179,7 @@ class rbtree_algorithms
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
static void swap_tree(node_ptr header1, node_ptr header2)
static void swap_tree(const node_ptr & header1, const node_ptr & header2)
{ return tree_algorithms::swap_tree(header1, header2); }
//! <b>Requires</b>: node1 and node2 can't be header nodes
@@ -198,7 +197,7 @@ class rbtree_algorithms
//! node1 and node2 are not equivalent according to the ordering rules.
//!
//!Experimental function
static void swap_nodes(node_ptr node1, node_ptr node2)
static void swap_nodes(const node_ptr & node1, const node_ptr & node2)
{
if(node1 == node2)
return;
@@ -222,7 +221,7 @@ class rbtree_algorithms
//! node1 and node2 are not equivalent according to the ordering rules.
//!
//!Experimental function
static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2)
static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2)
{
if(node1 == node2) return;
@@ -249,7 +248,7 @@ class rbtree_algorithms
//! the node, since no rebalancing and comparison is needed.
//!
//!Experimental function
static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node)
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node)
{
if(node_to_be_replaced == new_node)
return;
@@ -272,7 +271,7 @@ class rbtree_algorithms
//! the node, since no rebalancing or comparison is needed.
//!
//!Experimental function
static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node)
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node)
{
tree_algorithms::replace_node(node_to_be_replaced, header, new_node);
NodeTraits::set_color(new_node, NodeTraits::get_color(node_to_be_replaced));
@@ -285,7 +284,7 @@ class rbtree_algorithms
//! <b>Complexity</b>: Average complexity is constant time.
//!
//! <b>Throws</b>: Nothing.
static void unlink(node_ptr node)
static void unlink(const node_ptr & node)
{
node_ptr x = NodeTraits::get_parent(node);
if(x){
@@ -308,7 +307,7 @@ class rbtree_algorithms
//! only be used for more unlink_leftmost_without_rebalance calls.
//! This function is normally used to achieve a step by step
//! controlled destruction of the tree.
static node_ptr unlink_leftmost_without_rebalance(node_ptr header)
static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header)
{ return tree_algorithms::unlink_leftmost_without_rebalance(header); }
//! <b>Requires</b>: node is a node of the tree or an node initialized
@@ -319,7 +318,7 @@ class rbtree_algorithms
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
static bool unique(const_node_ptr node)
static bool unique(const const_node_ptr & node)
{ return tree_algorithms::unique(node); }
//! <b>Requires</b>: node is a node of the tree but it's not the header.
@@ -329,7 +328,7 @@ class rbtree_algorithms
//! <b>Complexity</b>: Linear time.
//!
//! <b>Throws</b>: Nothing.
static std::size_t count(const_node_ptr node)
static std::size_t count(const const_node_ptr & node)
{ return tree_algorithms::count(node); }
//! <b>Requires</b>: header is the header node of the tree.
@@ -339,7 +338,7 @@ class rbtree_algorithms
//! <b>Complexity</b>: Linear time.
//!
//! <b>Throws</b>: Nothing.
static std::size_t size(const_node_ptr header)
static std::size_t size(const const_node_ptr & header)
{ return tree_algorithms::size(header); }
//! <b>Requires</b>: p is a node from the tree except the header.
@@ -349,7 +348,7 @@ class rbtree_algorithms
//! <b>Complexity</b>: Average constant time.
//!
//! <b>Throws</b>: Nothing.
static node_ptr next_node(node_ptr p)
static node_ptr next_node(const node_ptr & p)
{ return tree_algorithms::next_node(p); }
//! <b>Requires</b>: p is a node from the tree except the leftmost node.
@@ -359,7 +358,7 @@ class rbtree_algorithms
//! <b>Complexity</b>: Average constant time.
//!
//! <b>Throws</b>: Nothing.
static node_ptr prev_node(node_ptr p)
static node_ptr prev_node(const node_ptr & p)
{ return tree_algorithms::prev_node(p); }
//! <b>Requires</b>: node must not be part of any tree.
@@ -371,7 +370,7 @@ class rbtree_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
static void init(node_ptr node)
static void init(const node_ptr & node)
{ tree_algorithms::init(node); }
//! <b>Requires</b>: node must not be part of any tree.
@@ -384,7 +383,7 @@ class rbtree_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
static void init_header(node_ptr header)
static void init_header(const node_ptr & header)
{
tree_algorithms::init_header(header);
NodeTraits::set_color(header, NodeTraits::red());
@@ -398,7 +397,7 @@ class rbtree_algorithms
//! <b>Complexity</b>: Amortized constant time.
//!
//! <b>Throws</b>: Nothing.
static node_ptr erase(node_ptr header, node_ptr z)
static node_ptr erase(const node_ptr & header, const node_ptr & z)
{
typename tree_algorithms::data_for_rebalance info;
tree_algorithms::erase(header, z, rbtree_erase_fixup(), info);
@@ -417,13 +416,13 @@ class rbtree_algorithms
//! take a node_ptr and shouldn't throw.
//!
//! <b>Effects</b>: First empties target tree calling
//! <tt>void disposer::operator()(node_ptr)</tt> for every node of the tree
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
//! except the header.
//!
//! Then, duplicates the entire tree pointed by "source_header" cloning each
//! source node with <tt>node_ptr Cloner::operator()(node_ptr)</tt> to obtain
//! source node with <tt>node_ptr Cloner::operator()(const node_ptr &)</tt> to obtain
//! the nodes of the target tree. If "cloner" throws, the cloned target nodes
//! are disposed using <tt>void disposer(node_ptr)</tt>.
//! are disposed using <tt>void disposer(const node_ptr &)</tt>.
//!
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
//! number of elements of tree target tree when calling this function.
@@ -431,7 +430,7 @@ class rbtree_algorithms
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
template <class Cloner, class Disposer>
static void clone
(const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer)
(const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer)
{
rbtree_node_cloner<Cloner> new_cloner(cloner);
tree_algorithms::clone(source_header, target_header, new_cloner, disposer);
@@ -441,7 +440,7 @@ class rbtree_algorithms
//! taking a node_ptr parameter and shouldn't throw.
//!
//! <b>Effects</b>: Empties the target tree calling
//! <tt>void disposer::operator()(node_ptr)</tt> for every node of the tree
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
//! except the header.
//!
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
@@ -449,7 +448,7 @@ class rbtree_algorithms
//!
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
template<class Disposer>
static void clear_and_dispose(node_ptr header, Disposer disposer)
static void clear_and_dispose(const node_ptr & header, Disposer disposer)
{ tree_algorithms::clear_and_dispose(header, disposer); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -466,7 +465,7 @@ class rbtree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr lower_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{ return tree_algorithms::lower_bound(header, key, comp); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -482,7 +481,7 @@ class rbtree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr upper_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{ return tree_algorithms::upper_bound(header, key, comp); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -498,7 +497,7 @@ class rbtree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr find
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{ return tree_algorithms::find(header, key, comp); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -516,7 +515,7 @@ class rbtree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> equal_range
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{ return tree_algorithms::equal_range(header, key, comp); }
//! <b>Requires</b>: "h" must be the header node of a tree.
@@ -533,7 +532,7 @@ class rbtree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare>
static node_ptr insert_equal_upper_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp)
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp)
{
tree_algorithms::insert_equal_upper_bound(h, new_node, comp);
rebalance_after_insertion(h, new_node);
@@ -554,7 +553,7 @@ class rbtree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare>
static node_ptr insert_equal_lower_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp)
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp)
{
tree_algorithms::insert_equal_lower_bound(h, new_node, comp);
rebalance_after_insertion(h, new_node);
@@ -577,7 +576,7 @@ class rbtree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare>
static node_ptr insert_equal
(node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp)
(const node_ptr & header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp)
{
tree_algorithms::insert_equal(header, hint, new_node, comp);
rebalance_after_insertion(header, new_node);
@@ -599,7 +598,7 @@ class rbtree_algorithms
//! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
//! tree invariants might be broken.
static node_ptr insert_before
(node_ptr header, node_ptr pos, node_ptr new_node)
(const node_ptr & header, const node_ptr & pos, const node_ptr & new_node)
{
tree_algorithms::insert_before(header, pos, new_node);
rebalance_after_insertion(header, new_node);
@@ -619,7 +618,7 @@ class rbtree_algorithms
//! <b>Note</b>: If "new_node" is less than the greatest inserted key
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
static void push_back(node_ptr header, node_ptr new_node)
static void push_back(const node_ptr & header, const node_ptr & new_node)
{
tree_algorithms::push_back(header, new_node);
rebalance_after_insertion(header, new_node);
@@ -638,7 +637,7 @@ class rbtree_algorithms
//! <b>Note</b>: If "new_node" is greater than the lowest inserted key
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
static void push_front(node_ptr header, node_ptr new_node)
static void push_front(const node_ptr & header, const node_ptr & new_node)
{
tree_algorithms::push_front(header, new_node);
rebalance_after_insertion(header, new_node);
@@ -680,7 +679,7 @@ class rbtree_algorithms
//! if no more objects are inserted or erased from the set.
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(const_node_ptr header, const KeyType &key
(const const_node_ptr & header, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data)
{ return tree_algorithms::insert_unique_check(header, key, comp, commit_data); }
@@ -725,7 +724,7 @@ class rbtree_algorithms
//! if no more objects are inserted or erased from the set.
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(const_node_ptr header, node_ptr hint, const KeyType &key
(const const_node_ptr & header, const node_ptr &hint, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data)
{ return tree_algorithms::insert_unique_check(header, hint, key, comp, commit_data); }
@@ -747,7 +746,7 @@ class rbtree_algorithms
//! previously executed to fill "commit_data". No value should be inserted or
//! erased between the "insert_check" and "insert_commit" calls.
static void insert_unique_commit
(node_ptr header, node_ptr new_value, const insert_commit_data &commit_data)
(const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data)
{
tree_algorithms::insert_unique_commit(header, new_value, commit_data);
rebalance_after_insertion(header, new_value);
@@ -760,7 +759,7 @@ class rbtree_algorithms
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: Nothing.
static node_ptr get_header(node_ptr n)
static node_ptr get_header(const node_ptr & n)
{ return tree_algorithms::get_header(n); }
/// @cond
@@ -773,7 +772,7 @@ class rbtree_algorithms
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
static bool is_header(const_node_ptr p)
static bool is_header(const const_node_ptr & p)
{
return NodeTraits::get_color(p) == NodeTraits::red() &&
tree_algorithms::is_header(p);
@@ -781,9 +780,10 @@ class rbtree_algorithms
// NodeTraits::get_parent(NodeTraits::get_parent(p)) == p;
}
static void rebalance_after_erasure(node_ptr header, node_ptr x, node_ptr x_parent)
static void rebalance_after_erasure(const node_ptr & header, const node_ptr &xnode, const node_ptr &xnode_parent)
{
while(x != NodeTraits::get_parent(header) && (x == 0 || NodeTraits::get_color(x) == NodeTraits::black())){
node_ptr x(xnode), x_parent(xnode_parent);
while(x != NodeTraits::get_parent(header) && (x == node_ptr() || NodeTraits::get_color(x) == NodeTraits::black())){
if(x == NodeTraits::get_left(x_parent)){
node_ptr w = NodeTraits::get_right(x_parent);
if(NodeTraits::get_color(w) == NodeTraits::red()){
@@ -792,14 +792,14 @@ class rbtree_algorithms
tree_algorithms::rotate_left(x_parent, header);
w = NodeTraits::get_right(x_parent);
}
if((NodeTraits::get_left(w) == 0 || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()) &&
(NodeTraits::get_right(w) == 0 || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black())){
if((NodeTraits::get_left(w) == node_ptr() || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()) &&
(NodeTraits::get_right(w) == node_ptr() || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black())){
NodeTraits::set_color(w, NodeTraits::red());
x = x_parent;
x_parent = NodeTraits::get_parent(x_parent);
}
else {
if(NodeTraits::get_right(w) == 0 || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()){
if(NodeTraits::get_right(w) == node_ptr() || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()){
NodeTraits::set_color(NodeTraits::get_left(w), NodeTraits::black());
NodeTraits::set_color(w, NodeTraits::red());
tree_algorithms::rotate_right(w, header);
@@ -822,14 +822,14 @@ class rbtree_algorithms
tree_algorithms::rotate_right(x_parent, header);
w = NodeTraits::get_left(x_parent);
}
if((NodeTraits::get_right(w) == 0 || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()) &&
(NodeTraits::get_left(w) == 0 || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black())){
if((NodeTraits::get_right(w) == node_ptr() || NodeTraits::get_color(NodeTraits::get_right(w)) == NodeTraits::black()) &&
(NodeTraits::get_left(w) == node_ptr() || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black())){
NodeTraits::set_color(w, NodeTraits::red());
x = x_parent;
x_parent = NodeTraits::get_parent(x_parent);
}
else {
if(NodeTraits::get_left(w) == 0 || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()){
if(NodeTraits::get_left(w) == node_ptr() || NodeTraits::get_color(NodeTraits::get_left(w)) == NodeTraits::black()){
NodeTraits::set_color(NodeTraits::get_right(w), NodeTraits::black());
NodeTraits::set_color(w, NodeTraits::red());
tree_algorithms::rotate_left(w, header);
@@ -849,8 +849,9 @@ class rbtree_algorithms
}
static void rebalance_after_insertion(node_ptr header, node_ptr p)
static void rebalance_after_insertion(const node_ptr & header, const node_ptr &pnode)
{
node_ptr p(pnode);
NodeTraits::set_color(p, NodeTraits::red());
while(p != NodeTraits::get_parent(header) && NodeTraits::get_color(NodeTraits::get_parent(p)) == NodeTraits::red()){
node_ptr p_parent(NodeTraits::get_parent(p));

View File

@@ -32,9 +32,10 @@
#include <boost/intrusive/bs_set_hook.hpp>
#include <boost/intrusive/detail/tree_node.hpp>
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/utilities.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/intrusive/sgtree_algorithms.hpp>
#include <boost/intrusive/link_mode.hpp>
@@ -223,24 +224,26 @@ class sgtree_impl
/// @endcond
typedef typename real_value_traits::pointer pointer;
typedef typename real_value_traits::const_pointer const_pointer;
typedef typename std::iterator_traits<pointer>::value_type value_type;
typedef typename pointer_traits<pointer>::element_type value_type;
typedef value_type key_type;
typedef typename std::iterator_traits<pointer>::reference reference;
typedef typename std::iterator_traits<const_pointer>::reference const_reference;
typedef typename std::iterator_traits<pointer>::difference_type difference_type;
typedef typename pointer_traits<pointer>::reference reference;
typedef typename pointer_traits<const_pointer>::reference const_reference;
typedef typename pointer_traits<const_pointer>::difference_type difference_type;
typedef typename Config::size_type size_type;
typedef typename Config::compare value_compare;
typedef value_compare key_compare;
typedef tree_iterator<sgtree_impl, false> iterator;
typedef tree_iterator<sgtree_impl, true> const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef boost::intrusive::detail::reverse_iterator<iterator> reverse_iterator;
typedef boost::intrusive::detail::reverse_iterator<const_iterator>const_reverse_iterator;
typedef typename real_value_traits::node_traits node_traits;
typedef typename node_traits::node node;
typedef typename boost::pointer_to_other
<pointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<node_ptr, const node>::type const_node_ptr;
typedef typename pointer_traits
<pointer>::template rebind_pointer
<node>::type node_ptr;
typedef typename pointer_traits
<pointer>::template rebind_pointer
<const node>::type const_node_ptr;
typedef sgtree_algorithms<node_traits> node_algorithms;
static const bool floating_point = Config::floating_point;
@@ -309,14 +312,14 @@ class sgtree_impl
value_traits &priv_value_traits()
{ return data_; }
const node &priv_header() const
{ return data_.node_plus_pred_.header_plus_alpha_.header_; }
node_ptr priv_header_ptr()
{ return pointer_traits<node_ptr>::pointer_to(data_.node_plus_pred_.header_plus_alpha_.header_); }
node &priv_header()
{ return data_.node_plus_pred_.header_plus_alpha_.header_; }
const_node_ptr priv_header_ptr() const
{ return pointer_traits<const_node_ptr>::pointer_to(data_.node_plus_pred_.header_plus_alpha_.header_); }
static node_ptr uncast(const_node_ptr ptr)
{ return node_ptr(const_cast<node*>(detail::boost_intrusive_get_pointer(ptr))); }
static node_ptr uncast(const const_node_ptr & ptr)
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
size_traits &priv_size_traits()
{ return data_.node_plus_pred_.size_traits_; }
@@ -371,7 +374,7 @@ class sgtree_impl
, const value_traits &v_traits = value_traits())
: data_(cmp, v_traits)
{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(size_type(0));
}
@@ -393,7 +396,7 @@ class sgtree_impl
, const value_traits &v_traits = value_traits())
: data_(cmp, v_traits)
{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(size_type(0));
if(unique)
this->insert_unique(b, e);
@@ -406,7 +409,7 @@ class sgtree_impl
sgtree_impl(BOOST_RV_REF(sgtree_impl) x)
: data_(::boost::move(x.priv_comp()), ::boost::move(x.priv_value_traits()))
{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(size_type(0));
this->swap(x);
}
@@ -432,7 +435,7 @@ class sgtree_impl
//!
//! <b>Throws</b>: Nothing.
iterator begin()
{ return iterator (node_traits::get_left(node_ptr(&priv_header())), this); }
{ return iterator (node_traits::get_left(this->priv_header_ptr()), this); }
//! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the tree.
//!
@@ -448,7 +451,7 @@ class sgtree_impl
//!
//! <b>Throws</b>: Nothing.
const_iterator cbegin() const
{ return const_iterator (node_traits::get_left(const_node_ptr(&priv_header())), this); }
{ return const_iterator (node_traits::get_left(this->priv_header_ptr()), this); }
//! <b>Effects</b>: Returns an iterator pointing to the end of the tree.
//!
@@ -456,7 +459,7 @@ class sgtree_impl
//!
//! <b>Throws</b>: Nothing.
iterator end()
{ return iterator (node_ptr(&priv_header()), this); }
{ return iterator (this->priv_header_ptr(), this); }
//! <b>Effects</b>: Returns a const_iterator pointing to the end of the tree.
//!
@@ -472,7 +475,7 @@ class sgtree_impl
//!
//! <b>Throws</b>: Nothing.
const_iterator cend() const
{ return const_iterator (uncast(const_node_ptr(&priv_header())), this); }
{ return const_iterator (uncast(this->priv_header_ptr()), this); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning of the
//! reversed tree.
@@ -586,7 +589,7 @@ class sgtree_impl
//!
//! <b>Throws</b>: Nothing.
bool empty() const
{ return node_algorithms::unique(const_node_ptr(&priv_header())); }
{ return node_algorithms::unique(this->priv_header_ptr()); }
//! <b>Effects</b>: Returns the number of elements stored in the tree.
//!
@@ -599,7 +602,7 @@ class sgtree_impl
if(constant_time_size)
return this->priv_size_traits().get_size();
else{
return (size_type)node_algorithms::size(const_node_ptr(&priv_header()));
return (size_type)node_algorithms::size(this->priv_header_ptr());
}
}
@@ -616,7 +619,7 @@ class sgtree_impl
swap(priv_alpha_traits(), priv_alpha_traits());
swap(data_.max_tree_size_, other.data_.max_tree_size_);
//These can't throw
node_algorithms::swap_tree(node_ptr(&priv_header()), node_ptr(&other.priv_header()));
node_algorithms::swap_tree(this->priv_header_ptr(), other.priv_header_ptr());
if(constant_time_size){
size_type backup = this->priv_size_traits().get_size();
this->priv_size_traits().set_size(other.priv_size_traits().get_size());
@@ -644,7 +647,7 @@ class sgtree_impl
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
node_ptr p = node_algorithms::insert_equal_upper_bound
(node_ptr(&priv_header()), to_insert, key_node_comp
(this->priv_header_ptr(), to_insert, key_node_comp
, (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
this->priv_size_traits().increment();
data_.max_tree_size_ = (size_type)max_tree_size;
@@ -674,7 +677,7 @@ class sgtree_impl
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
node_ptr p = node_algorithms::insert_equal
(node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp
(this->priv_header_ptr(), hint.pointed_node(), to_insert, key_node_comp
, (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size);
this->priv_size_traits().increment();
data_.max_tree_size_ = (size_type)max_tree_size;
@@ -812,7 +815,7 @@ class sgtree_impl
comp(key_value_comp, this);
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
(node_ptr(&priv_header()), key, comp, commit_data));
(this->priv_header_ptr(), key, comp, commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
}
@@ -857,7 +860,7 @@ class sgtree_impl
comp(key_value_comp, this);
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
(node_ptr(&priv_header()), hint.pointed_node(), key, comp, commit_data));
(this->priv_header_ptr(), hint.pointed_node(), key, comp, commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
}
@@ -885,7 +888,7 @@ class sgtree_impl
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
node_algorithms::insert_unique_commit
( node_ptr(&priv_header()), to_insert, commit_data
( this->priv_header_ptr(), to_insert, commit_data
, (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size);
this->priv_size_traits().increment();
data_.max_tree_size_ = (size_type)max_tree_size;
@@ -913,7 +916,7 @@ class sgtree_impl
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
node_ptr p = node_algorithms::insert_before
( node_ptr(&priv_header()), pos.pointed_node(), to_insert
( this->priv_header_ptr(), pos.pointed_node(), to_insert
, (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
this->priv_size_traits().increment();
data_.max_tree_size_ = (size_type)max_tree_size;
@@ -941,7 +944,7 @@ class sgtree_impl
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
node_algorithms::push_back
( node_ptr(&priv_header()), to_insert
( this->priv_header_ptr(), to_insert
, (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
this->priv_size_traits().increment();
data_.max_tree_size_ = (size_type)max_tree_size;
@@ -968,7 +971,7 @@ class sgtree_impl
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
std::size_t max_tree_size = (std::size_t)data_.max_tree_size_;
node_algorithms::push_front
( node_ptr(&priv_header()), to_insert
( this->priv_header_ptr(), to_insert
, (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
this->priv_size_traits().increment();
data_.max_tree_size_ = (size_type)max_tree_size;
@@ -991,7 +994,7 @@ class sgtree_impl
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
std::size_t max_tree_size = data_.max_tree_size_;
node_algorithms::erase
( &priv_header(), to_erase, (std::size_t)this->size()
( this->priv_header_ptr(), to_erase, (std::size_t)this->size()
, max_tree_size, this->get_alpha_by_max_size_func());
data_.max_tree_size_ = (size_type)max_tree_size;
this->priv_size_traits().decrement();
@@ -1155,7 +1158,7 @@ class sgtree_impl
this->clear_and_dispose(detail::null_disposer());
}
else{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(0);
}
}
@@ -1172,7 +1175,7 @@ class sgtree_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer)
{
node_algorithms::clear_and_dispose(node_ptr(&priv_header())
node_algorithms::clear_and_dispose(this->priv_header_ptr()
, detail::node_disposer<Disposer, sgtree_impl>(disposer, this));
this->priv_size_traits().set_size(0);
}
@@ -1229,7 +1232,7 @@ class sgtree_impl
detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
key_node_comp(comp, this);
return iterator(node_algorithms::lower_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Returns a const iterator to the first element whose
@@ -1244,7 +1247,7 @@ class sgtree_impl
detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
key_node_comp(comp, this);
return const_iterator(node_algorithms::lower_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Returns an iterator to the first element whose
@@ -1269,7 +1272,7 @@ class sgtree_impl
detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
key_node_comp(comp, this);
return iterator(node_algorithms::upper_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Returns an iterator to the first element whose
@@ -1294,7 +1297,7 @@ class sgtree_impl
detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
key_node_comp(comp, this);
return const_iterator(node_algorithms::upper_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Finds an iterator to the first element whose key is
@@ -1318,7 +1321,7 @@ class sgtree_impl
detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
key_node_comp(comp, this);
return iterator
(node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this);
(node_algorithms::find(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Finds a const_iterator to the first element whose key is
@@ -1342,7 +1345,7 @@ class sgtree_impl
detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
key_node_comp(comp, this);
return const_iterator
(node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this);
(node_algorithms::find(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Finds a range containing all elements whose key is k or
@@ -1368,7 +1371,7 @@ class sgtree_impl
detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
key_node_comp(comp, this);
std::pair<node_ptr, node_ptr> ret
(node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp));
(node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp));
return std::pair<iterator, iterator>(iterator(ret.first, this), iterator(ret.second, this));
}
@@ -1397,7 +1400,7 @@ class sgtree_impl
detail::key_nodeptr_comp<KeyValueCompare, sgtree_impl>
key_node_comp(comp, this);
std::pair<node_ptr, node_ptr> ret
(node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp));
(node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp));
return std::pair<const_iterator, const_iterator>(const_iterator(ret.first, this), const_iterator(ret.second, this));
}
@@ -1423,8 +1426,8 @@ class sgtree_impl
detail::exception_disposer<sgtree_impl, Disposer>
rollback(*this, disposer);
node_algorithms::clone
(const_node_ptr(&src.priv_header())
,node_ptr(&this->priv_header())
(src.priv_header_ptr()
,this->priv_header_ptr()
,detail::node_cloner<Cloner, sgtree_impl>(cloner, this)
,detail::node_disposer<Disposer, sgtree_impl>(disposer, this));
this->priv_size_traits().set_size(src.priv_size_traits().get_size());
@@ -1446,7 +1449,7 @@ class sgtree_impl
pointer unlink_leftmost_without_rebalance()
{
node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance
(node_ptr(&priv_header())));
(this->priv_header_ptr()));
if(!to_be_disposed)
return 0;
this->priv_size_traits().decrement();
@@ -1472,7 +1475,7 @@ class sgtree_impl
void replace_node(iterator replace_this, reference with_this)
{
node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this)
, node_ptr(&priv_header())
, this->priv_header_ptr()
, get_real_value_traits().to_node_ptr(with_this));
if(safemode_or_autounlink)
node_algorithms::init(replace_this.pointed_node());
@@ -1558,7 +1561,7 @@ class sgtree_impl
//!
//! <b>Complexity</b>: Linear.
void rebalance()
{ node_algorithms::rebalance(node_ptr(&priv_header())); }
{ node_algorithms::rebalance(this->priv_header_ptr()); }
//! <b>Requires</b>: old_root is a node of a tree.
//!
@@ -1654,7 +1657,7 @@ class sgtree_impl
static sgtree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
{
header_plus_alpha *r = detail::parent_from_member<header_plus_alpha, node>
( detail::boost_intrusive_get_pointer(end_iterator.pointed_node()), &header_plus_alpha::header_);
( boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()), &header_plus_alpha::header_);
node_plus_pred_t *n = detail::parent_from_member
<node_plus_pred_t, header_plus_alpha>(r, &node_plus_pred_t::header_plus_alpha_);
data_t *d = detail::parent_from_member<data_t, node_plus_pred_t>(n, &data_t::node_plus_pred_);

View File

@@ -24,6 +24,7 @@
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/utilities.hpp>
#include <boost/intrusive/detail/tree_algorithms.hpp>
#include <boost/intrusive/pointer_traits.hpp>
namespace boost {
@@ -68,17 +69,15 @@ class sgtree_algorithms
typedef detail::tree_algorithms<NodeTraits> tree_algorithms;
static node_ptr uncast(const_node_ptr ptr)
{
return node_ptr(const_cast<node*>(::boost::intrusive::detail::boost_intrusive_get_pointer(ptr)));
}
static node_ptr uncast(const const_node_ptr & ptr)
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
/// @endcond
public:
static node_ptr begin_node(const_node_ptr header)
static node_ptr begin_node(const const_node_ptr & header)
{ return tree_algorithms::begin_node(header); }
static node_ptr end_node(const_node_ptr header)
static node_ptr end_node(const const_node_ptr & header)
{ return tree_algorithms::end_node(header); }
//! This type is the information that will be
@@ -98,7 +97,7 @@ class sgtree_algorithms
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
static void swap_tree(node_ptr header1, node_ptr header2)
static void swap_tree(const node_ptr & header1, const node_ptr & header2)
{ return tree_algorithms::swap_tree(header1, header2); }
//! <b>Requires</b>: node1 and node2 can't be header nodes
@@ -116,7 +115,7 @@ class sgtree_algorithms
//! node1 and node2 are not equivalent according to the ordering rules.
//!
//!Experimental function
static void swap_nodes(node_ptr node1, node_ptr node2)
static void swap_nodes(const node_ptr & node1, const node_ptr & node2)
{
if(node1 == node2)
return;
@@ -140,7 +139,7 @@ class sgtree_algorithms
//! node1 and node2 are not equivalent according to the ordering rules.
//!
//!Experimental function
static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2)
static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2)
{ tree_algorithms::swap_nodes(node1, header1, node2, header2); }
//! <b>Requires</b>: node_to_be_replaced must be inserted in a tree
@@ -159,7 +158,7 @@ class sgtree_algorithms
//! the node, since no rebalancing and comparison is needed.
//!
//!Experimental function
static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node)
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node)
{
if(node_to_be_replaced == new_node)
return;
@@ -182,7 +181,7 @@ class sgtree_algorithms
//! the node, since no rebalancing or comparison is needed.
//!
//!Experimental function
static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node)
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node)
{ tree_algorithms::replace_node(node_to_be_replaced, header, new_node); }
//! <b>Requires</b>: node is a tree node but not the header.
@@ -192,7 +191,7 @@ class sgtree_algorithms
//! <b>Complexity</b>: Average complexity is constant time.
//!
//! <b>Throws</b>: Nothing.
static void unlink(node_ptr node)
static void unlink(const node_ptr & node)
{
node_ptr x = NodeTraits::get_parent(node);
if(x){
@@ -215,7 +214,7 @@ class sgtree_algorithms
//! only be used for more unlink_leftmost_without_rebalance calls.
//! This function is normally used to achieve a step by step
//! controlled destruction of the tree.
static node_ptr unlink_leftmost_without_rebalance(node_ptr header)
static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header)
{ return tree_algorithms::unlink_leftmost_without_rebalance(header); }
//! <b>Requires</b>: node is a node of the tree or an node initialized
@@ -226,7 +225,7 @@ class sgtree_algorithms
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
static bool unique(const_node_ptr node)
static bool unique(const const_node_ptr & node)
{ return tree_algorithms::unique(node); }
//! <b>Requires</b>: node is a node of the tree but it's not the header.
@@ -236,7 +235,7 @@ class sgtree_algorithms
//! <b>Complexity</b>: Linear time.
//!
//! <b>Throws</b>: Nothing.
static std::size_t count(const_node_ptr node)
static std::size_t count(const const_node_ptr & node)
{ return tree_algorithms::count(node); }
//! <b>Requires</b>: header is the header node of the tree.
@@ -246,7 +245,7 @@ class sgtree_algorithms
//! <b>Complexity</b>: Linear time.
//!
//! <b>Throws</b>: Nothing.
static std::size_t size(const_node_ptr header)
static std::size_t size(const const_node_ptr & header)
{ return tree_algorithms::size(header); }
//! <b>Requires</b>: p is a node from the tree except the header.
@@ -256,7 +255,7 @@ class sgtree_algorithms
//! <b>Complexity</b>: Average constant time.
//!
//! <b>Throws</b>: Nothing.
static node_ptr next_node(node_ptr p)
static node_ptr next_node(const node_ptr & p)
{ return tree_algorithms::next_node(p); }
//! <b>Requires</b>: p is a node from the tree except the leftmost node.
@@ -266,7 +265,7 @@ class sgtree_algorithms
//! <b>Complexity</b>: Average constant time.
//!
//! <b>Throws</b>: Nothing.
static node_ptr prev_node(node_ptr p)
static node_ptr prev_node(const node_ptr & p)
{ return tree_algorithms::prev_node(p); }
//! <b>Requires</b>: node must not be part of any tree.
@@ -278,7 +277,7 @@ class sgtree_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
static void init(node_ptr node)
static void init(const node_ptr & node)
{ tree_algorithms::init(node); }
//! <b>Requires</b>: node must not be part of any tree.
@@ -291,7 +290,7 @@ class sgtree_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
static void init_header(node_ptr header)
static void init_header(const node_ptr & header)
{ tree_algorithms::init_header(header); }
//! <b>Requires</b>: header must be the header of a tree, z a node
@@ -303,7 +302,7 @@ class sgtree_algorithms
//!
//! <b>Throws</b>: Nothing.
template<class AlphaByMaxSize>
static node_ptr erase(node_ptr header, node_ptr z, std::size_t tree_size, std::size_t &max_tree_size, AlphaByMaxSize alpha_by_maxsize)
static node_ptr erase(const node_ptr & header, const node_ptr & z, std::size_t tree_size, std::size_t &max_tree_size, AlphaByMaxSize alpha_by_maxsize)
{
//typename tree_algorithms::data_for_rebalance info;
tree_algorithms::erase(header, z);
@@ -321,13 +320,13 @@ class sgtree_algorithms
//! take a node_ptr and shouldn't throw.
//!
//! <b>Effects</b>: First empties target tree calling
//! <tt>void disposer::operator()(node_ptr)</tt> for every node of the tree
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
//! except the header.
//!
//! Then, duplicates the entire tree pointed by "source_header" cloning each
//! source node with <tt>node_ptr Cloner::operator()(node_ptr)</tt> to obtain
//! source node with <tt>node_ptr Cloner::operator()(const node_ptr &)</tt> to obtain
//! the nodes of the target tree. If "cloner" throws, the cloned target nodes
//! are disposed using <tt>void disposer(node_ptr)</tt>.
//! are disposed using <tt>void disposer(const node_ptr &)</tt>.
//!
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
//! number of elements of tree target tree when calling this function.
@@ -335,7 +334,7 @@ class sgtree_algorithms
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
template <class Cloner, class Disposer>
static void clone
(const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer)
(const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer)
{
tree_algorithms::clone(source_header, target_header, cloner, disposer);
}
@@ -344,7 +343,7 @@ class sgtree_algorithms
//! taking a node_ptr parameter and shouldn't throw.
//!
//! <b>Effects</b>: Empties the target tree calling
//! <tt>void disposer::operator()(node_ptr)</tt> for every node of the tree
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
//! except the header.
//!
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
@@ -352,7 +351,7 @@ class sgtree_algorithms
//!
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
template<class Disposer>
static void clear_and_dispose(node_ptr header, Disposer disposer)
static void clear_and_dispose(const node_ptr & header, Disposer disposer)
{ tree_algorithms::clear_and_dispose(header, disposer); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -369,7 +368,7 @@ class sgtree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr lower_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{ return tree_algorithms::lower_bound(header, key, comp); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -385,7 +384,7 @@ class sgtree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr upper_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{ return tree_algorithms::upper_bound(header, key, comp); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -401,7 +400,7 @@ class sgtree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr find
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{ return tree_algorithms::find(header, key, comp); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -419,7 +418,7 @@ class sgtree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> equal_range
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{ return tree_algorithms::equal_range(header, key, comp); }
//! <b>Requires</b>: "h" must be the header node of a tree.
@@ -436,7 +435,7 @@ class sgtree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare, class H_Alpha>
static node_ptr insert_equal_upper_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
{
std::size_t depth;
@@ -459,7 +458,7 @@ class sgtree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare, class H_Alpha>
static node_ptr insert_equal_lower_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
{
std::size_t depth;
@@ -484,7 +483,7 @@ class sgtree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare, class H_Alpha>
static node_ptr insert_equal
(node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp
(const node_ptr & header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
{
std::size_t depth;
@@ -529,7 +528,7 @@ class sgtree_algorithms
//! if no more objects are inserted or erased from the set.
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(const_node_ptr header, const KeyType &key
(const const_node_ptr & header, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data)
{
std::size_t depth;
@@ -556,7 +555,7 @@ class sgtree_algorithms
//! tree invariants might be broken.
template<class H_Alpha>
static node_ptr insert_before
(node_ptr header, node_ptr pos, node_ptr new_node
(const node_ptr & header, const node_ptr & pos, const node_ptr & new_node
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
{
std::size_t depth;
@@ -579,7 +578,7 @@ class sgtree_algorithms
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
template<class H_Alpha>
static void push_back(node_ptr header, node_ptr new_node
static void push_back(const node_ptr & header, const node_ptr & new_node
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
{
std::size_t depth;
@@ -601,7 +600,7 @@ class sgtree_algorithms
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
template<class H_Alpha>
static void push_front(node_ptr header, node_ptr new_node
static void push_front(const node_ptr & header, const node_ptr & new_node
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
{
std::size_t depth;
@@ -650,7 +649,7 @@ class sgtree_algorithms
//! if no more objects are inserted or erased from the set.
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(const_node_ptr header, node_ptr hint, const KeyType &key
(const const_node_ptr & header, const node_ptr &hint, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data)
{
std::size_t depth;
@@ -680,7 +679,7 @@ class sgtree_algorithms
//! erased between the "insert_check" and "insert_commit" calls.
template<class H_Alpha>
static void insert_unique_commit
(node_ptr header, node_ptr new_value, const insert_commit_data &commit_data
(const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data
,std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
{
tree_algorithms::insert_unique_commit(header, new_value, commit_data);
@@ -694,7 +693,7 @@ class sgtree_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear.
static void rebalance(node_ptr header)
static void rebalance(const node_ptr & header)
{ tree_algorithms::rebalance(header); }
//! <b>Requires</b>: old_root is a node of a tree.
@@ -706,7 +705,7 @@ class sgtree_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear.
static node_ptr rebalance_subtree(node_ptr old_root)
static node_ptr rebalance_subtree(const node_ptr & old_root)
{ return tree_algorithms::rebalance_subtree(old_root); }
//! <b>Requires</b>: "n" must be a node inserted in a tree.
@@ -716,7 +715,7 @@ class sgtree_algorithms
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: Nothing.
static node_ptr get_header(node_ptr n)
static node_ptr get_header(const node_ptr & n)
{ return tree_algorithms::get_header(n); }
/// @cond
@@ -729,12 +728,12 @@ class sgtree_algorithms
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
static bool is_header(const_node_ptr p)
static bool is_header(const const_node_ptr & p)
{ return tree_algorithms::is_header(p); }
template<class H_Alpha>
static void rebalance_after_insertion
( node_ptr x, std::size_t depth
(const node_ptr &x, std::size_t depth
, std::size_t tree_size, H_Alpha h_alpha, std::size_t &max_tree_size)
{
if(tree_size > max_tree_size)

View File

@@ -21,7 +21,7 @@
#include <boost/intrusive/slist_hook.hpp>
#include <boost/intrusive/circular_slist_algorithms.hpp>
#include <boost/intrusive/linear_slist_algorithms.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/options.hpp>
@@ -121,10 +121,10 @@ class slist_impl
/// @endcond
typedef typename real_value_traits::pointer pointer;
typedef typename real_value_traits::const_pointer const_pointer;
typedef typename std::iterator_traits<pointer>::value_type value_type;
typedef typename std::iterator_traits<pointer>::reference reference;
typedef typename std::iterator_traits<const_pointer>::reference const_reference;
typedef typename std::iterator_traits<pointer>::difference_type difference_type;
typedef typename pointer_traits<pointer>::element_type value_type;
typedef typename pointer_traits<pointer>::reference reference;
typedef typename pointer_traits<const_pointer>::reference const_reference;
typedef typename pointer_traits<pointer>::difference_type difference_type;
typedef typename Config::size_type size_type;
typedef slist_iterator<slist_impl, false> iterator;
typedef slist_iterator<slist_impl, true> const_iterator;
@@ -163,18 +163,18 @@ class slist_impl
BOOST_STATIC_ASSERT(!(cache_last && ((int)real_value_traits::link_mode == (int)auto_unlink)));
node_ptr get_end_node()
{ return node_ptr(linear ? node_ptr(0) : this->get_root_node()); }
{ return node_ptr(linear ? node_ptr() : this->get_root_node()); }
const_node_ptr get_end_node() const
{
return const_node_ptr
(linear ? const_node_ptr(0) : this->get_root_node()); }
(linear ? const_node_ptr() : this->get_root_node()); }
node_ptr get_root_node()
{ return node_ptr(&data_.root_plus_size_.root_); }
{ return pointer_traits<node_ptr>::pointer_to(data_.root_plus_size_.root_); }
const_node_ptr get_root_node() const
{ return const_node_ptr(&data_.root_plus_size_.root_); }
{ return pointer_traits<const_node_ptr>::pointer_to(data_.root_plus_size_.root_); }
node_ptr get_last_node()
{ return this->get_last_node(detail::bool_<cache_last>()); }
@@ -182,13 +182,13 @@ class slist_impl
const_node_ptr get_last_node() const
{ return this->get_last_node(detail::bool_<cache_last>()); }
void set_last_node(node_ptr n)
void set_last_node(const node_ptr &n)
{ return this->set_last_node(n, detail::bool_<cache_last>()); }
static node_ptr get_last_node(detail::bool_<false>)
{ return node_ptr(0); }
{ return node_ptr(); }
static void set_last_node(node_ptr, detail::bool_<false>)
static void set_last_node(const node_ptr &, detail::bool_<false>)
{}
node_ptr get_last_node(detail::bool_<true>)
@@ -197,12 +197,11 @@ class slist_impl
const_node_ptr get_last_node(detail::bool_<true>) const
{ return const_node_ptr(data_.root_plus_size_.last_); }
void set_last_node(node_ptr n, detail::bool_<true>)
void set_last_node(const node_ptr & n, detail::bool_<true>)
{ data_.root_plus_size_.last_ = n; }
static node_ptr uncast(const_node_ptr ptr)
{ return node_ptr(const_cast<node*>(detail::boost_intrusive_get_pointer(ptr))); }
//iG pending { return boost::const_pointer_cast<node>(ptr); }
static node_ptr uncast(const const_node_ptr & ptr)
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
void set_default_constructed_state()
{
@@ -406,7 +405,7 @@ class slist_impl
//! This function is only available is cache_last<> is true.
void push_back(reference value)
{
BOOST_STATIC_ASSERT((cache_last != 0));
BOOST_STATIC_ASSERT((cache_last));
this->insert_after(const_iterator(this->get_last_node(), this), value);
}
@@ -473,7 +472,7 @@ class slist_impl
//! This function is only available is cache_last<> is true.
reference back()
{
BOOST_STATIC_ASSERT((cache_last != 0));
BOOST_STATIC_ASSERT((cache_last));
return *this->get_real_value_traits().to_value_ptr(this->get_last_node());
}
@@ -487,7 +486,7 @@ class slist_impl
//! This function is only available is cache_last<> is true.
const_reference back() const
{
BOOST_STATIC_ASSERT((cache_last != 0));
BOOST_STATIC_ASSERT((cache_last));
return *this->get_real_value_traits().to_value_ptr(this->get_last_node());
}
@@ -835,7 +834,7 @@ class slist_impl
node_ptr bfp = before_first.pointed_node();
node_ptr lp = last.pointed_node();
if(cache_last){
if((lp == this->get_end_node())){
if(lp == this->get_end_node()){
this->set_last_node(bfp);
}
}
@@ -1110,7 +1109,8 @@ class slist_impl
this->insert_after(this->cbefore_begin(), b, e, disposer);
}
//! <b>Requires</b>: prev is an iterator to an element or x.end()/x.before_begin() in x.
//! <b>Requires</b>: prev must point to an element contained by this list or
//! to the before_begin() element
//!
//! <b>Effects</b>: Transfers all the elements of list x to this list, after the
//! the element pointed by prev. No destructors or copy constructors are called.
@@ -1226,7 +1226,7 @@ class slist_impl
}
}
//! <b>Requires</b>: it is an iterator to an element in x.
//! <b>Requires</b>: it is an iterator to an element in *this.
//!
//! <b>Effects</b>: Transfers all the elements of list x to this list, before the
//! the element pointed by it. No destructors or copy constructors are called.
@@ -1743,7 +1743,7 @@ class slist_impl
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void incorporate_after(const_iterator prev_from, node_ptr first, node_ptr before_last)
void incorporate_after(const_iterator prev_from, const node_ptr & first, const node_ptr & before_last)
{
if(constant_time_size)
this->incorporate_after(prev_from, first, before_last, std::distance(first, before_last)+1);
@@ -1766,7 +1766,7 @@ class slist_impl
//!
//! <b>Note</b>: Iterators of values obtained from list x now point to elements of this
//! list. Iterators of this list and all the references are not invalidated.
void incorporate_after(const_iterator prev_pos, node_ptr first, node_ptr before_last, difference_type n)
void incorporate_after(const_iterator prev_pos, const node_ptr & first, const node_ptr & before_last, difference_type n)
{
if(n){
BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(iterator(first, this), iterator(before_last, this))+1 == n);
@@ -1778,7 +1778,7 @@ class slist_impl
}
private:
void priv_splice_after(node_ptr prev_pos_n, slist_impl &x, node_ptr before_first_n, node_ptr before_last_n)
void priv_splice_after(const node_ptr & prev_pos_n, slist_impl &x, const node_ptr & before_first_n, const node_ptr & before_last_n)
{
if (before_first_n != before_last_n && prev_pos_n != before_first_n && prev_pos_n != before_last_n)
{
@@ -1794,7 +1794,7 @@ class slist_impl
}
}
void priv_incorporate_after(node_ptr prev_pos_n, node_ptr first_n, node_ptr before_last_n)
void priv_incorporate_after(const node_ptr & prev_pos_n, const node_ptr & first_n, const node_ptr & before_last_n)
{
if(cache_last){
if(node_traits::get_next(prev_pos_n) == this->get_end_node()){
@@ -1894,11 +1894,11 @@ class slist_impl
}
//circular version
static void priv_swap_lists(node_ptr this_node, node_ptr other_node, detail::bool_<false>)
static void priv_swap_lists(const node_ptr & this_node, const node_ptr & other_node, detail::bool_<false>)
{ node_algorithms::swap_nodes(this_node, other_node); }
//linear version
static void priv_swap_lists(node_ptr this_node, node_ptr other_node, detail::bool_<true>)
static void priv_swap_lists(const node_ptr & this_node, const node_ptr & other_node, detail::bool_<true>)
{ node_algorithms::swap_trailing_nodes(this_node, other_node); }
static slist_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
@@ -1907,7 +1907,7 @@ class slist_impl
//singly linked lists (because "end" is represented by the null pointer)
BOOST_STATIC_ASSERT(!linear);
root_plus_size *r = detail::parent_from_member<root_plus_size, node>
( detail::boost_intrusive_get_pointer(end_iterator.pointed_node()), (&root_plus_size::root_));
( boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()), (&root_plus_size::root_));
data_t *d = detail::parent_from_member<data_t, root_plus_size>
( r, &data_t::root_plus_size_);
slist_impl *s = detail::parent_from_member<slist_impl, data_t>(d, &slist_impl::data_);

View File

@@ -21,12 +21,14 @@
#include <boost/intrusive/detail/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/splay_set_hook.hpp>
#include <boost/intrusive/detail/tree_node.hpp>
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/detail/utilities.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/intrusive/splaytree_algorithms.hpp>
#include <boost/intrusive/link_mode.hpp>
@@ -95,24 +97,26 @@ class splaytree_impl
/// @endcond
typedef typename real_value_traits::pointer pointer;
typedef typename real_value_traits::const_pointer const_pointer;
typedef typename std::iterator_traits<pointer>::value_type value_type;
typedef value_type key_type;
typedef typename std::iterator_traits<pointer>::reference reference;
typedef typename std::iterator_traits<const_pointer>::reference const_reference;
typedef typename std::iterator_traits<pointer>::difference_type difference_type;
typedef typename pointer_traits<pointer>::element_type value_type;
typedef typename pointer_traits<pointer>::reference reference;
typedef typename pointer_traits<const_pointer>::reference const_reference;
typedef typename pointer_traits<pointer>::difference_type difference_type;
typedef typename Config::size_type size_type;
typedef value_type key_type;
typedef typename Config::compare value_compare;
typedef value_compare key_compare;
typedef tree_iterator<splaytree_impl, false> iterator;
typedef tree_iterator<splaytree_impl, true> const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef boost::intrusive::detail::reverse_iterator<iterator> reverse_iterator;
typedef boost::intrusive::detail::reverse_iterator<const_iterator>const_reverse_iterator;
typedef typename real_value_traits::node_traits node_traits;
typedef typename node_traits::node node;
typedef typename boost::pointer_to_other
<pointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<node_ptr, const node>::type const_node_ptr;
typedef typename pointer_traits
<pointer>::template rebind_pointer
<node>::type node_ptr;
typedef typename pointer_traits
<pointer>::template rebind_pointer
<const node>::type const_node_ptr;
typedef splaytree_algorithms<node_traits> node_algorithms;
static const bool constant_time_size = Config::constant_time_size;
@@ -164,16 +168,14 @@ class splaytree_impl
value_traits &priv_value_traits()
{ return data_; }
const node &priv_header() const
{ return data_.node_plus_pred_.header_plus_size_.header_; }
node_ptr priv_header_ptr()
{ return pointer_traits<node_ptr>::pointer_to(data_.node_plus_pred_.header_plus_size_.header_); }
node &priv_header()
{ return data_.node_plus_pred_.header_plus_size_.header_; }
const_node_ptr priv_header_ptr() const
{ return pointer_traits<const_node_ptr>::pointer_to(data_.node_plus_pred_.header_plus_size_.header_); }
static node_ptr uncast(const_node_ptr ptr)
{
return node_ptr(const_cast<node*>(detail::boost_intrusive_get_pointer(ptr)));
}
static node_ptr uncast(const const_node_ptr & ptr)
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
size_traits &priv_size_traits()
{ return data_.node_plus_pred_.header_plus_size_; }
@@ -216,7 +218,7 @@ class splaytree_impl
, const value_traits &v_traits = value_traits())
: data_(cmp, v_traits)
{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(size_type(0));
}
@@ -238,7 +240,7 @@ class splaytree_impl
, const value_traits &v_traits = value_traits())
: data_(cmp, v_traits)
{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(size_type(0));
if(unique)
this->insert_unique(b, e);
@@ -251,7 +253,7 @@ class splaytree_impl
splaytree_impl(BOOST_RV_REF(splaytree_impl) x)
: data_(::boost::move(x.priv_comp()), ::boost::move(x.priv_value_traits()))
{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(size_type(0));
this->swap(x);
}
@@ -278,7 +280,7 @@ class splaytree_impl
//!
//! <b>Throws</b>: Nothing.
iterator begin()
{ return iterator(node_algorithms::begin_node(&priv_header()), this); }
{ return iterator(node_algorithms::begin_node(this->priv_header_ptr()), this); }
//! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the tree.
//!
@@ -294,7 +296,7 @@ class splaytree_impl
//!
//! <b>Throws</b>: Nothing.
const_iterator cbegin() const
{ return const_iterator(node_algorithms::begin_node(&priv_header()), this); }
{ return const_iterator(node_algorithms::begin_node(this->priv_header_ptr()), this); }
//! <b>Effects</b>: Returns an iterator pointing to the end of the tree.
//!
@@ -302,7 +304,7 @@ class splaytree_impl
//!
//! <b>Throws</b>: Nothing.
iterator end()
{ return iterator (node_ptr(&priv_header()), this); }
{ return iterator (this->priv_header_ptr(), this); }
//! <b>Effects</b>: Returns a const_iterator pointing to the end of the tree.
//!
@@ -318,7 +320,7 @@ class splaytree_impl
//!
//! <b>Throws</b>: Nothing.
const_iterator cend() const
{ return const_iterator (uncast(const_node_ptr(&priv_header())), this); }
{ return const_iterator (uncast(this->priv_header_ptr()), this); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning of the
//! reversed tree.
@@ -446,7 +448,7 @@ class splaytree_impl
return this->priv_size_traits().get_size();
}
else{
return (size_type)node_algorithms::size(const_node_ptr(&priv_header()));
return (size_type)node_algorithms::size(this->priv_header_ptr());
}
}
@@ -461,7 +463,7 @@ class splaytree_impl
using std::swap;
swap(priv_comp(), priv_comp());
//These can't throw
node_algorithms::swap_tree(node_ptr(&priv_header()), node_ptr(&other.priv_header()));
node_algorithms::swap_tree(this->priv_header_ptr(), other.priv_header_ptr());
if(constant_time_size){
size_type backup = this->priv_size_traits().get_size();
this->priv_size_traits().set_size(other.priv_size_traits().get_size());
@@ -488,7 +490,7 @@ class splaytree_impl
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
iterator ret (node_algorithms::insert_equal_lower_bound
(node_ptr(&priv_header()), to_insert, key_node_comp), this);
(this->priv_header_ptr(), to_insert, key_node_comp), this);
this->priv_size_traits().increment();
return ret;
}
@@ -515,7 +517,7 @@ class splaytree_impl
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
iterator ret(node_algorithms::insert_equal
(node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp), this);
(this->priv_header_ptr(), hint.pointed_node(), to_insert, key_node_comp), this);
this->priv_size_traits().increment();
return ret;
}
@@ -645,7 +647,7 @@ class splaytree_impl
comp(key_value_comp, this);
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
(node_ptr(&priv_header()), key, comp, commit_data));
(this->priv_header_ptr(), key, comp, commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
}
@@ -690,7 +692,7 @@ class splaytree_impl
comp(key_value_comp, this);
std::pair<node_ptr, bool> ret =
node_algorithms::insert_unique_check
(node_ptr(&priv_header()), hint.pointed_node(), key, comp, commit_data);
(this->priv_header_ptr(), hint.pointed_node(), key, comp, commit_data);
return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
}
@@ -717,7 +719,7 @@ class splaytree_impl
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
node_algorithms::insert_unique_commit
(node_ptr(&priv_header()), to_insert, commit_data);
(this->priv_header_ptr(), to_insert, commit_data);
this->priv_size_traits().increment();
return iterator(to_insert, this);
}
@@ -737,7 +739,7 @@ class splaytree_impl
node_ptr to_erase(i.pointed_node());
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
node_algorithms::erase(&priv_header(), to_erase);
node_algorithms::erase(this->priv_header_ptr(), to_erase);
this->priv_size_traits().decrement();
if(safemode_or_autounlink)
node_algorithms::init(to_erase);
@@ -899,7 +901,7 @@ class splaytree_impl
this->clear_and_dispose(detail::null_disposer());
}
else{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(0);
}
}
@@ -916,7 +918,7 @@ class splaytree_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer)
{
node_algorithms::clear_and_dispose(node_ptr(&priv_header())
node_algorithms::clear_and_dispose(this->priv_header_ptr()
, detail::node_disposer<Disposer, splaytree_impl>(disposer, this));
this->priv_size_traits().set_size(0);
}
@@ -995,7 +997,7 @@ class splaytree_impl
detail::key_nodeptr_comp<KeyValueCompare, splaytree_impl>
key_node_comp(comp, this);
return iterator(node_algorithms::lower_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Returns a const iterator to the first element whose
@@ -1010,7 +1012,7 @@ class splaytree_impl
detail::key_nodeptr_comp<KeyValueCompare, splaytree_impl>
key_node_comp(comp, this);
return const_iterator(node_algorithms::lower_bound
(const_node_ptr(&priv_header()), key, key_node_comp, false), this);
(this->priv_header_ptr(), key, key_node_comp, false), this);
}
//! <b>Effects</b>: Returns an iterator to the first element whose
@@ -1035,7 +1037,7 @@ class splaytree_impl
detail::key_nodeptr_comp<KeyValueCompare, splaytree_impl>
key_node_comp(comp, this);
return iterator(node_algorithms::upper_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Returns an iterator to the first element whose
@@ -1060,7 +1062,7 @@ class splaytree_impl
detail::key_nodeptr_comp<KeyValueCompare, splaytree_impl>
key_node_comp(comp, this);
return const_iterator(node_algorithms::upper_bound_dont_splay
(const_node_ptr(&priv_header()), key, key_node_comp, false), this);
(this->priv_header_ptr(), key, key_node_comp, false), this);
}
//! <b>Effects</b>: Finds an iterator to the first element whose key is
@@ -1084,7 +1086,7 @@ class splaytree_impl
detail::key_nodeptr_comp<KeyValueCompare, splaytree_impl>
key_node_comp(comp, this);
return iterator
(node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this);
(node_algorithms::find(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Finds a const_iterator to the first element whose key is
@@ -1108,7 +1110,7 @@ class splaytree_impl
detail::key_nodeptr_comp<KeyValueCompare, splaytree_impl>
key_node_comp(comp, this);
return const_iterator
(node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp, false), this);
(node_algorithms::find(this->priv_header_ptr(), key, key_node_comp, false), this);
}
//! <b>Effects</b>: Finds a range containing all elements whose key is k or
@@ -1134,7 +1136,7 @@ class splaytree_impl
detail::key_nodeptr_comp<KeyValueCompare, splaytree_impl>
key_node_comp(comp, this);
std::pair<node_ptr, node_ptr> ret
(node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp));
(node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp));
return std::pair<iterator, iterator>(iterator(ret.first, this), iterator(ret.second, this));
}
@@ -1163,7 +1165,7 @@ class splaytree_impl
detail::key_nodeptr_comp<KeyValueCompare, splaytree_impl>
key_node_comp(comp, this);
std::pair<node_ptr, node_ptr> ret
(node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp, false));
(node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp, false));
return std::pair<const_iterator, const_iterator>(const_iterator(ret.first, this), const_iterator(ret.second, this));
}
@@ -1189,8 +1191,8 @@ class splaytree_impl
detail::exception_disposer<splaytree_impl, Disposer>
rollback(*this, disposer);
node_algorithms::clone
(const_node_ptr(&src.priv_header())
,node_ptr(&this->priv_header())
(src.priv_header_ptr()
,this->priv_header_ptr()
,detail::node_cloner<Cloner, splaytree_impl>(cloner, this)
,detail::node_disposer<Disposer, splaytree_impl>(disposer, this));
this->priv_size_traits().set_size(src.priv_size_traits().get_size());
@@ -1212,7 +1214,7 @@ class splaytree_impl
pointer unlink_leftmost_without_rebalance()
{
node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance
(node_ptr(&priv_header())));
(this->priv_header_ptr()));
if(!to_be_disposed)
return 0;
this->priv_size_traits().decrement();
@@ -1230,7 +1232,7 @@ class splaytree_impl
//!
//! <b>Throws</b>: Nothing.
void splay_up(iterator i)
{ return node_algorithms::splay_up(i.pointed_node(), &priv_header()); }
{ return node_algorithms::splay_up(i.pointed_node(), this->priv_header_ptr()); }
//! <b>Effects</b>: Rearranges the splay set so that if *this stores an element
//! with a key equivalent to value the element is placed as the root of the
@@ -1247,7 +1249,7 @@ class splaytree_impl
{
detail::key_nodeptr_comp<KeyValueCompare, splaytree_impl>
key_node_comp(comp, this);
node_ptr r = node_algorithms::splay_down(&priv_header(), key, key_node_comp);
node_ptr r = node_algorithms::splay_down(this->priv_header_ptr(), key, key_node_comp);
return iterator(r, this);
}
@@ -1280,7 +1282,7 @@ class splaytree_impl
void replace_node(iterator replace_this, reference with_this)
{
node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this)
, node_ptr(&priv_header())
, this->priv_header_ptr()
, get_real_value_traits().to_node_ptr(with_this));
if(safemode_or_autounlink)
node_algorithms::init(replace_this.pointed_node());
@@ -1366,7 +1368,7 @@ class splaytree_impl
//!
//! <b>Complexity</b>: Linear.
void rebalance()
{ node_algorithms::rebalance(node_ptr(&priv_header())); }
{ node_algorithms::rebalance(this->priv_header_ptr()); }
//! <b>Requires</b>: old_root is a node of a tree.
//!
@@ -1430,7 +1432,7 @@ class splaytree_impl
static splaytree_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
{
header_plus_size *r = detail::parent_from_member<header_plus_size, node>
( detail::boost_intrusive_get_pointer(end_iterator.pointed_node()), &header_plus_size::header_);
( boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()), &header_plus_size::header_);
node_plus_pred_t *n = detail::parent_from_member
<node_plus_pred_t, header_plus_size>(r, &node_plus_pred_t::header_plus_size_);
data_t *d = detail::parent_from_member<data_t, node_plus_pred_t>(n, &data_t::node_plus_pred_);

View File

@@ -49,6 +49,7 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <cstddef>
#include <boost/intrusive/detail/utilities.hpp>
#include <boost/intrusive/detail/tree_algorithms.hpp>
@@ -63,8 +64,8 @@ template<class NodeTraits>
struct splaydown_rollback
{
typedef typename NodeTraits::node_ptr node_ptr;
splaydown_rollback( const node_ptr *pcur_subtree, node_ptr header
, node_ptr leftmost , node_ptr rightmost)
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)
{}
@@ -145,17 +146,15 @@ class splaytree_algorithms
/// @cond
private:
static node_ptr uncast(const_node_ptr ptr)
{
return node_ptr(const_cast<node*>(::boost::intrusive::detail::boost_intrusive_get_pointer(ptr)));
}
static node_ptr uncast(const const_node_ptr & ptr)
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
/// @endcond
public:
static node_ptr begin_node(const_node_ptr header)
static node_ptr begin_node(const const_node_ptr & header)
{ return tree_algorithms::begin_node(header); }
static node_ptr end_node(const_node_ptr header)
static node_ptr end_node(const const_node_ptr & header)
{ return tree_algorithms::end_node(header); }
//! <b>Requires</b>: node is a node of the tree or an node initialized
@@ -166,10 +165,10 @@ class splaytree_algorithms
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
static bool unique(const_node_ptr node)
static bool unique(const const_node_ptr & node)
{ return tree_algorithms::unique(node); }
static void unlink(node_ptr node)
static void unlink(const node_ptr & node)
{ tree_algorithms::unlink(node); }
//! <b>Requires</b>: node1 and node2 can't be header nodes
@@ -187,7 +186,7 @@ class splaytree_algorithms
//! node1 and node2 are not equivalent according to the ordering rules.
//!
//!Experimental function
static void swap_nodes(node_ptr node1, node_ptr node2)
static void swap_nodes(const node_ptr & node1, const node_ptr & node2)
{
if(node1 == node2)
return;
@@ -211,7 +210,7 @@ class splaytree_algorithms
//! node1 and node2 are not equivalent according to the ordering rules.
//!
//!Experimental function
static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2)
static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2)
{ tree_algorithms::swap_nodes(node1, header1, node2, header2); }
//! <b>Requires</b>: node_to_be_replaced must be inserted in a tree
@@ -230,7 +229,7 @@ class splaytree_algorithms
//! the node, since no rebalancing and comparison is needed.
//!
//!Experimental function
static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node)
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node)
{
if(node_to_be_replaced == new_node)
return;
@@ -253,7 +252,7 @@ class splaytree_algorithms
//! the node, since no rebalancing or comparison is needed.
//!
//!Experimental function
static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node)
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node)
{ tree_algorithms::replace_node(node_to_be_replaced, header, new_node); }
//! <b>Requires</b>: p is a node from the tree except the header.
@@ -263,7 +262,7 @@ class splaytree_algorithms
//! <b>Complexity</b>: Average constant time.
//!
//! <b>Throws</b>: Nothing.
static node_ptr next_node(node_ptr p)
static node_ptr next_node(const node_ptr & p)
{ return tree_algorithms::next_node(p); }
//! <b>Requires</b>: p is a node from the tree except the leftmost node.
@@ -273,7 +272,7 @@ class splaytree_algorithms
//! <b>Complexity</b>: Average constant time.
//!
//! <b>Throws</b>: Nothing.
static node_ptr prev_node(node_ptr p)
static node_ptr prev_node(const node_ptr & p)
{ return tree_algorithms::prev_node(p); }
//! <b>Requires</b>: node must not be part of any tree.
@@ -285,7 +284,7 @@ class splaytree_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
static void init(node_ptr node)
static void init(const node_ptr & node)
{ tree_algorithms::init(node); }
//! <b>Requires</b>: node must not be part of any tree.
@@ -298,14 +297,14 @@ class splaytree_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
static void init_header(node_ptr header)
static void init_header(const node_ptr & header)
{ tree_algorithms::init_header(header); }
//! <b>Requires</b>: "disposer" must be an object function
//! taking a node_ptr parameter and shouldn't throw.
//!
//! <b>Effects</b>: Empties the target tree calling
//! <tt>void disposer::operator()(node_ptr)</tt> for every node of the tree
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
//! except the header.
//!
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
@@ -313,7 +312,7 @@ class splaytree_algorithms
//!
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
template<class Disposer>
static void clear_and_dispose(node_ptr header, Disposer disposer)
static void clear_and_dispose(const node_ptr & header, Disposer disposer)
{ tree_algorithms::clear_and_dispose(header, disposer); }
//! <b>Requires</b>: node is a node of the tree but it's not the header.
@@ -323,7 +322,7 @@ class splaytree_algorithms
//! <b>Complexity</b>: Linear time.
//!
//! <b>Throws</b>: Nothing.
static std::size_t count(const_node_ptr node)
static std::size_t count(const const_node_ptr & node)
{ return tree_algorithms::count(node); }
//! <b>Requires</b>: header is the header node of the tree.
@@ -333,7 +332,7 @@ class splaytree_algorithms
//! <b>Complexity</b>: Linear time.
//!
//! <b>Throws</b>: Nothing.
static std::size_t size(const_node_ptr header)
static std::size_t size(const const_node_ptr & header)
{ return tree_algorithms::size(header); }
//! <b>Requires</b>: header1 and header2 must be the header nodes
@@ -345,7 +344,7 @@ class splaytree_algorithms
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
static void swap_tree(node_ptr header1, node_ptr header2)
static void swap_tree(const node_ptr & header1, const node_ptr & header2)
{ return tree_algorithms::swap_tree(header1, header2); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -366,7 +365,7 @@ class splaytree_algorithms
//! previously executed to fill "commit_data". No value should be inserted or
//! erased between the "insert_check" and "insert_commit" calls.
static void insert_unique_commit
(node_ptr header, node_ptr new_value, const insert_commit_data &commit_data)
(const node_ptr & header, const node_ptr & new_value, const insert_commit_data &commit_data)
{ tree_algorithms::insert_unique_commit(header, new_value, commit_data); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -405,7 +404,7 @@ class splaytree_algorithms
//! if no more objects are inserted or erased from the set.
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(node_ptr header, const KeyType &key
(const node_ptr & header, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data)
{
splay_down(header, key, comp);
@@ -414,14 +413,14 @@ class splaytree_algorithms
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, bool> insert_unique_check
(node_ptr header, node_ptr hint, const KeyType &key
(const node_ptr & header, const node_ptr &hint, const KeyType &key
,KeyNodePtrCompare comp, insert_commit_data &commit_data)
{
splay_down(header, key, comp);
return tree_algorithms::insert_unique_check(header, hint, key, comp, commit_data);
}
static bool is_header(const_node_ptr p)
static bool is_header(const const_node_ptr & p)
{ return tree_algorithms::is_header(p); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -437,7 +436,7 @@ class splaytree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr find
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true)
{
if(splay)
splay_down(uncast(header), key, comp);
@@ -462,7 +461,7 @@ class splaytree_algorithms
//! <b>Throws</b>: If "comp" throws.
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 const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true)
{
//if(splay)
//splay_down(uncast(header), key, comp);
@@ -488,7 +487,7 @@ class splaytree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr lower_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true)
{
//if(splay)
//splay_down(uncast(header), key, comp);
@@ -511,7 +510,7 @@ class splaytree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr upper_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp, bool splay = true)
{
//if(splay)
//splay_down(uncast(header), key, comp);
@@ -537,7 +536,7 @@ class splaytree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare>
static node_ptr insert_equal
(node_ptr header, node_ptr hint, node_ptr new_node, NodePtrCompare comp)
(const node_ptr & header, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp)
{
splay_down(header, new_node, comp);
return tree_algorithms::insert_equal(header, hint, new_node, comp);
@@ -559,7 +558,7 @@ class splaytree_algorithms
//! <b>Note</b>: If "pos" is not the successor of the newly inserted "new_node"
//! tree invariants might be broken.
static node_ptr insert_before
(node_ptr header, node_ptr pos, node_ptr new_node)
(const node_ptr & header, const node_ptr & pos, const node_ptr & new_node)
{
tree_algorithms::insert_before(header, pos, new_node);
splay_up(new_node, header);
@@ -579,7 +578,7 @@ class splaytree_algorithms
//! <b>Note</b>: If "new_node" is less than the greatest inserted key
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
static void push_back(node_ptr header, node_ptr new_node)
static void push_back(const node_ptr & header, const node_ptr & new_node)
{
tree_algorithms::push_back(header, new_node);
splay_up(new_node, header);
@@ -598,7 +597,7 @@ class splaytree_algorithms
//! <b>Note</b>: If "new_node" is greater than the lowest inserted key
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
static void push_front(node_ptr header, node_ptr new_node)
static void push_front(const node_ptr & header, const node_ptr & new_node)
{
tree_algorithms::push_front(header, new_node);
splay_up(new_node, header);
@@ -618,7 +617,7 @@ class splaytree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare>
static node_ptr insert_equal_upper_bound
(node_ptr header, node_ptr new_node, NodePtrCompare comp)
(const node_ptr & header, const node_ptr & new_node, NodePtrCompare comp)
{
splay_down(header, new_node, comp);
return tree_algorithms::insert_equal_upper_bound(header, new_node, comp);
@@ -638,7 +637,7 @@ class splaytree_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare>
static node_ptr insert_equal_lower_bound
(node_ptr header, node_ptr new_node, NodePtrCompare comp)
(const node_ptr & header, const node_ptr & new_node, NodePtrCompare comp)
{
splay_down(header, new_node, comp);
return tree_algorithms::insert_equal_lower_bound(header, new_node, comp);
@@ -649,13 +648,13 @@ class splaytree_algorithms
//! take a node_ptr and shouldn't throw.
//!
//! <b>Effects</b>: First empties target tree calling
//! <tt>void disposer::operator()(node_ptr)</tt> for every node of the tree
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
//! except the header.
//!
//! Then, duplicates the entire tree pointed by "source_header" cloning each
//! source node with <tt>node_ptr Cloner::operator()(node_ptr)</tt> to obtain
//! source node with <tt>node_ptr Cloner::operator()(const node_ptr &)</tt> to obtain
//! the nodes of the target tree. If "cloner" throws, the cloned target nodes
//! are disposed using <tt>void disposer(node_ptr)</tt>.
//! are disposed using <tt>void disposer(const node_ptr &)</tt>.
//!
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
//! number of elements of tree target tree when calling this function.
@@ -663,23 +662,23 @@ class splaytree_algorithms
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
template <class Cloner, class Disposer>
static void clone
(const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer)
(const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer)
{ tree_algorithms::clone(source_header, target_header, cloner, disposer); }
// delete node | complexity : constant | exception : nothrow
static void erase(node_ptr header, node_ptr z, bool splay = true)
static void erase(const node_ptr & header, const node_ptr & z, bool splay = true)
{
// node_base* n = t->right;
// if( t->left != 0 ){
// if( t->left != node_ptr() ){
// node_base* l = t->previous();
// splay_up( l , t );
// n = t->left;
// n->right = t->right;
// if( n->right != 0 )
// if( n->right != node_ptr() )
// n->right->parent = n;
// }
//
// if( n != 0 )
// if( n != node_ptr() )
// n->parent = t->parent;
//
// if( t->parent->left == t )
@@ -695,11 +694,11 @@ class splaytree_algorithms
}
/*
//possibility 2
if(splay && NodeTraits::get_left(z) != 0 ){
if(splay && NodeTraits::get_left(z) != node_ptr() ){
node_ptr l = NodeTraits::get_left(z);
splay_up(l, header);
}*//*
if(splay && NodeTraits::get_left(z) != 0 ){
if(splay && NodeTraits::get_left(z) != node_ptr() ){
node_ptr l = prev_node(z);
splay_up_impl(l, z);
}*/
@@ -715,15 +714,13 @@ class splaytree_algorithms
}
// bottom-up splay, use data_ as parent for n | complexity : logarithmic | exception : nothrow
static void splay_up(node_ptr n, node_ptr header)
static void splay_up(const node_ptr & node, const node_ptr & header)
{
if(n == 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
// where there are many equal elements at the end
n = NodeTraits::get_right(header);
}
node_ptr t = 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
// where there are many equal elements at the end
node_ptr n((node == header) ? NodeTraits::get_right(header) : node);
node_ptr t(header);
if( n == t ) return;
@@ -753,7 +750,7 @@ class splaytree_algorithms
// top-down splay | complexity : logarithmic | exception : strong, note A
template<class KeyType, class KeyNodePtrCompare>
static node_ptr splay_down(node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
static node_ptr splay_down(const node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{
if(!NodeTraits::get_parent(header))
return header;
@@ -782,19 +779,19 @@ class splaytree_algorithms
for( ;; ){
if(comp(key, t)){
if(NodeTraits::get_left(t) == 0 )
if(NodeTraits::get_left(t) == node_ptr() )
break;
if(comp(key, NodeTraits::get_left(t))){
t = tree_algorithms::rotate_right(t);
if(NodeTraits::get_left(t) == 0)
if(NodeTraits::get_left(t) == node_ptr())
break;
link_right(t, r);
}
else if(comp(NodeTraits::get_left(t), key)){
link_right(t, r);
if(NodeTraits::get_right(t) == 0 )
if(NodeTraits::get_right(t) == node_ptr() )
break;
link_left(t, l);
}
@@ -803,20 +800,20 @@ class splaytree_algorithms
}
}
else if(comp(t, key)){
if(NodeTraits::get_right(t) == 0 )
if(NodeTraits::get_right(t) == node_ptr() )
break;
if(comp(NodeTraits::get_right(t), key)){
t = tree_algorithms::rotate_left( t );
if(NodeTraits::get_right(t) == 0 )
if(NodeTraits::get_right(t) == node_ptr() )
break;
link_left(t, l);
}
else if(comp(key, NodeTraits::get_right(t))){
link_left(t, l);
if(NodeTraits::get_left(t) == 0)
if(NodeTraits::get_left(t) == node_ptr())
break;
link_right(t, r);
@@ -850,7 +847,7 @@ class splaytree_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear.
static void rebalance(node_ptr header)
static void rebalance(const node_ptr & header)
{ tree_algorithms::rebalance(header); }
//! <b>Requires</b>: old_root is a node of a tree.
@@ -862,7 +859,7 @@ class splaytree_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Complexity</b>: Linear.
static node_ptr rebalance_subtree(node_ptr old_root)
static node_ptr rebalance_subtree(const node_ptr & old_root)
{ return tree_algorithms::rebalance_subtree(old_root); }
@@ -873,7 +870,7 @@ class splaytree_algorithms
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: Nothing.
static node_ptr get_header(node_ptr n)
static node_ptr get_header(const node_ptr & n)
{ return tree_algorithms::get_header(n); }
private:
@@ -881,23 +878,23 @@ class splaytree_algorithms
/// @cond
// assemble the three sub-trees into new tree pointed to by t | complexity : constant | exception : nothrow
static void assemble( node_ptr t, node_ptr l, node_ptr r, const_node_ptr null_node )
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) != 0){
if(NodeTraits::get_right(l) != node_ptr()){
NodeTraits::set_parent(NodeTraits::get_right(l), l);
}
if(NodeTraits::get_left(r) != 0){
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) != 0 ){
if( NodeTraits::get_left(t) != node_ptr() ){
NodeTraits::set_parent(NodeTraits::get_left(t), t);
}
@@ -907,7 +904,7 @@ class splaytree_algorithms
}
// 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)
static void link_left(node_ptr & t, node_ptr & l)
{
NodeTraits::set_right(l, t);
NodeTraits::set_parent(t, l);
@@ -916,7 +913,7 @@ 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)
static void link_right(node_ptr & t, node_ptr & r)
{
NodeTraits::set_left(r, t);
NodeTraits::set_parent(t, r);
@@ -925,7 +922,7 @@ class splaytree_algorithms
}
// rotate n with its parent | complexity : constant | exception : nothrow
static void rotate(node_ptr n)
static void rotate(const node_ptr & n)
{
node_ptr p = NodeTraits::get_parent(n);
node_ptr g = NodeTraits::get_parent(p);
@@ -935,13 +932,13 @@ class splaytree_algorithms
if(NodeTraits::get_left(p) == n){
NodeTraits::set_left(p, NodeTraits::get_right(n));
if(NodeTraits::get_left(p) != 0)
if(NodeTraits::get_left(p) != node_ptr())
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) != 0)
if(NodeTraits::get_right(p) != node_ptr())
NodeTraits::set_parent(NodeTraits::get_right(p), p);
NodeTraits::set_left(n, p);
}
@@ -953,7 +950,7 @@ class splaytree_algorithms
if(NodeTraits::get_parent(g) == p)
NodeTraits::set_parent(g, n);
else{//must be ( g->right == p )
BOOST_INTRUSIVE_INVARIANT_ASSERT(0);
BOOST_INTRUSIVE_INVARIANT_ASSERT(false);
NodeTraits::set_right(g, n);
}
}

View File

@@ -25,8 +25,10 @@
#include <boost/intrusive/bs_set_hook.hpp>
#include <boost/intrusive/detail/tree_node.hpp>
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/clear_on_destructor_base.hpp>
#include <boost/intrusive/detail/utilities.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <boost/intrusive/treap_algorithms.hpp>
@@ -98,25 +100,27 @@ class treap_impl
/// @endcond
typedef typename real_value_traits::pointer pointer;
typedef typename real_value_traits::const_pointer const_pointer;
typedef typename std::iterator_traits<pointer>::value_type value_type;
typedef typename pointer_traits<pointer>::element_type value_type;
typedef typename pointer_traits<pointer>::reference reference;
typedef typename pointer_traits<const_pointer>::reference const_reference;
typedef typename pointer_traits<pointer>::difference_type difference_type;
typedef value_type key_type;
typedef typename std::iterator_traits<pointer>::reference reference;
typedef typename std::iterator_traits<const_pointer>::reference const_reference;
typedef typename std::iterator_traits<pointer>::difference_type difference_type;
typedef typename Config::size_type size_type;
typedef typename Config::compare value_compare;
typedef typename Config::priority_compare priority_compare;
typedef value_compare key_compare;
typedef tree_iterator<treap_impl, false> iterator;
typedef tree_iterator<treap_impl, true> const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef tree_iterator<treap_impl, false> iterator;
typedef tree_iterator<treap_impl, true> const_iterator;
typedef boost::intrusive::detail::reverse_iterator<iterator> reverse_iterator;
typedef boost::intrusive::detail::reverse_iterator<const_iterator>const_reverse_iterator;
typedef typename real_value_traits::node_traits node_traits;
typedef typename node_traits::node node;
typedef typename boost::pointer_to_other
<pointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<node_ptr, const node>::type const_node_ptr;
typedef typename pointer_traits
<pointer>::template rebind_pointer
<node>::type node_ptr;
typedef typename pointer_traits
<pointer>::template rebind_pointer
<const node>::type const_node_ptr;
typedef treap_algorithms<node_traits> node_algorithms;
static const bool constant_time_size = Config::constant_time_size;
@@ -182,16 +186,14 @@ class treap_impl
value_traits &priv_value_traits()
{ return data_; }
const node &priv_header() const
{ return data_.node_plus_pred_.header_plus_priority_size_.header_plus_size_.header_; }
node_ptr priv_header_ptr()
{ return pointer_traits<node_ptr>::pointer_to(data_.node_plus_pred_.header_plus_priority_size_.header_plus_size_.header_); }
node &priv_header()
{ return data_.node_plus_pred_.header_plus_priority_size_.header_plus_size_.header_; }
const_node_ptr priv_header_ptr() const
{ return pointer_traits<const_node_ptr>::pointer_to(data_.node_plus_pred_.header_plus_priority_size_.header_plus_size_.header_); }
static node_ptr uncast(const_node_ptr ptr)
{
return node_ptr(const_cast<node*>(detail::boost_intrusive_get_pointer(ptr)));
}
static node_ptr uncast(const const_node_ptr & ptr)
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
size_traits &priv_size_traits()
{ return data_.node_plus_pred_.header_plus_priority_size_.header_plus_size_; }
@@ -235,7 +237,7 @@ class treap_impl
, const value_traits &v_traits = value_traits())
: data_(cmp, pcmp, v_traits)
{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(size_type(0));
}
@@ -259,7 +261,7 @@ class treap_impl
, const value_traits &v_traits = value_traits())
: data_(cmp, pcmp, v_traits)
{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(size_type(0));
if(unique)
this->insert_unique(b, e);
@@ -274,7 +276,7 @@ class treap_impl
, ::boost::move(x.priv_pcomp())
, ::boost::move(x.priv_value_traits()))
{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(size_type(0));
this->swap(x);
}
@@ -301,7 +303,7 @@ class treap_impl
//!
//! <b>Throws</b>: Nothing.
iterator begin()
{ return iterator (node_traits::get_left(node_ptr(&priv_header())), this); }
{ return iterator (node_traits::get_left(this->priv_header_ptr()), this); }
//! <b>Effects</b>: Returns a const_iterator pointing to the beginning of the treap.
//!
@@ -317,7 +319,7 @@ class treap_impl
//!
//! <b>Throws</b>: Nothing.
const_iterator cbegin() const
{ return const_iterator (node_traits::get_left(const_node_ptr(&priv_header())), this); }
{ return const_iterator (node_traits::get_left(this->priv_header_ptr()), this); }
//! <b>Effects</b>: Returns an iterator pointing to the end of the treap.
//!
@@ -325,7 +327,7 @@ class treap_impl
//!
//! <b>Throws</b>: Nothing.
iterator end()
{ return iterator (node_ptr(&priv_header()), this); }
{ return iterator (this->priv_header_ptr(), this); }
//! <b>Effects</b>: Returns a const_iterator pointing to the end of the treap.
//!
@@ -341,7 +343,7 @@ class treap_impl
//!
//! <b>Throws</b>: Nothing.
const_iterator cend() const
{ return const_iterator (uncast(const_node_ptr(&priv_header())), this); }
{ return const_iterator (uncast(this->priv_header_ptr()), this); }
//! <b>Effects</b>: Returns an iterator pointing to the highest priority object of the treap.
@@ -350,7 +352,7 @@ class treap_impl
//!
//! <b>Throws</b>: Nothing.
iterator top()
{ return this->empty() ? this->end() : iterator (node_traits::get_parent(node_ptr(&priv_header())), this); }
{ return this->empty() ? this->end() : iterator (node_traits::get_parent(this->priv_header_ptr()), this); }
//! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the treap..
//!
@@ -366,7 +368,7 @@ class treap_impl
//!
//! <b>Throws</b>: Nothing.
const_iterator ctop() const
{ return this->empty() ? this->cend() : const_iterator (node_traits::get_parent(const_node_ptr(&priv_header())), this); }
{ return this->empty() ? this->cend() : const_iterator (node_traits::get_parent(this->priv_header_ptr()), this); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning of the
//! reversed treap.
@@ -515,7 +517,7 @@ class treap_impl
//!
//! <b>Throws</b>: Nothing.
bool empty() const
{ return node_algorithms::unique(const_node_ptr(&priv_header())); }
{ return node_algorithms::unique(this->priv_header_ptr()); }
//! <b>Effects</b>: Returns the number of elements stored in the treap.
//!
@@ -528,7 +530,7 @@ class treap_impl
if(constant_time_size)
return this->priv_size_traits().get_size();
else{
return (size_type)node_algorithms::size(const_node_ptr(&priv_header()));
return (size_type)node_algorithms::size(this->priv_header_ptr());
}
}
@@ -544,7 +546,7 @@ class treap_impl
swap(priv_comp(), priv_comp());
swap(priv_pcomp(), priv_pcomp());
//These can't throw
node_algorithms::swap_tree(node_ptr(&priv_header()), node_ptr(&other.priv_header()));
node_algorithms::swap_tree(this->priv_header_ptr(), other.priv_header_ptr());
if(constant_time_size){
size_type backup = this->priv_size_traits().get_size();
this->priv_size_traits().set_size(other.priv_size_traits().get_size());
@@ -573,7 +575,7 @@ class treap_impl
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
iterator ret(node_algorithms::insert_equal_upper_bound
(node_ptr(&priv_header()), to_insert, key_node_comp, key_node_pcomp), this);
(this->priv_header_ptr(), to_insert, key_node_comp, key_node_pcomp), this);
this->priv_size_traits().increment();
return ret;
}
@@ -602,7 +604,7 @@ class treap_impl
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
iterator ret (node_algorithms::insert_equal
(node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp, key_node_pcomp), this);
(this->priv_header_ptr(), hint.pointed_node(), to_insert, key_node_comp, key_node_pcomp), this);
this->priv_size_traits().increment();
return ret;
}
@@ -748,7 +750,7 @@ class treap_impl
pcomp(key_value_pcomp, this);
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
(node_ptr(&priv_header()), key, comp, pcomp, commit_data));
(this->priv_header_ptr(), key, comp, pcomp, commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
}
@@ -800,7 +802,7 @@ class treap_impl
pcomp(key_value_pcomp, this);
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
(node_ptr(&priv_header()), hint.pointed_node(), key, comp, pcomp, commit_data));
(this->priv_header_ptr(), hint.pointed_node(), key, comp, pcomp, commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this), ret.second);
}
@@ -826,7 +828,7 @@ class treap_impl
node_ptr to_insert(get_real_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
node_algorithms::insert_unique_commit(node_ptr(&priv_header()), to_insert, commit_data);
node_algorithms::insert_unique_commit(this->priv_header_ptr(), to_insert, commit_data);
this->priv_size_traits().increment();
return iterator(to_insert, this);
}
@@ -853,7 +855,7 @@ class treap_impl
detail::key_nodeptr_comp<priority_compare, treap_impl>
pcomp(priv_pcomp(), this);
iterator ret (node_algorithms::insert_before
(node_ptr(&priv_header()), pos.pointed_node(), to_insert, pcomp), this);
(this->priv_header_ptr(), pos.pointed_node(), to_insert, pcomp), this);
this->priv_size_traits().increment();
return ret;
}
@@ -879,7 +881,7 @@ class treap_impl
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
detail::key_nodeptr_comp<priority_compare, treap_impl>
pcomp(priv_pcomp(), this);
node_algorithms::push_back(node_ptr(&priv_header()), to_insert, pcomp);
node_algorithms::push_back(this->priv_header_ptr(), to_insert, pcomp);
this->priv_size_traits().increment();
}
@@ -904,7 +906,7 @@ class treap_impl
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
detail::key_nodeptr_comp<priority_compare, treap_impl>
pcomp(priv_pcomp(), this);
node_algorithms::push_front(node_ptr(&priv_header()), to_insert, pcomp);
node_algorithms::push_front(this->priv_header_ptr(), to_insert, pcomp);
this->priv_size_traits().increment();
}
@@ -925,7 +927,7 @@ class treap_impl
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
detail::key_nodeptr_comp<priority_compare, treap_impl>
key_node_pcomp(priv_pcomp(), this);
node_algorithms::erase(&priv_header(), to_erase, key_node_pcomp);
node_algorithms::erase(this->priv_header_ptr(), to_erase, key_node_pcomp);
this->priv_size_traits().decrement();
if(safemode_or_autounlink)
node_algorithms::init(to_erase);
@@ -1090,7 +1092,7 @@ class treap_impl
this->clear_and_dispose(detail::null_disposer());
}
else{
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(priv_header_ptr());
this->priv_size_traits().set_size(0);
}
}
@@ -1107,9 +1109,9 @@ class treap_impl
template<class Disposer>
void clear_and_dispose(Disposer disposer)
{
node_algorithms::clear_and_dispose(node_ptr(&priv_header())
node_algorithms::clear_and_dispose(this->priv_header_ptr()
, detail::node_disposer<Disposer, treap_impl>(disposer, this));
node_algorithms::init_header(&priv_header());
node_algorithms::init_header(this->priv_header_ptr());
this->priv_size_traits().set_size(0);
}
@@ -1165,7 +1167,7 @@ class treap_impl
detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
key_node_comp(comp, this);
return iterator(node_algorithms::lower_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Returns a const iterator to the first element whose
@@ -1180,7 +1182,7 @@ class treap_impl
detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
key_node_comp(comp, this);
return const_iterator(node_algorithms::lower_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Returns an iterator to the first element whose
@@ -1205,7 +1207,7 @@ class treap_impl
detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
key_node_comp(comp, this);
return iterator(node_algorithms::upper_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Returns an iterator to the first element whose
@@ -1230,7 +1232,7 @@ class treap_impl
detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
key_node_comp(comp, this);
return const_iterator(node_algorithms::upper_bound
(const_node_ptr(&priv_header()), key, key_node_comp), this);
(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Finds an iterator to the first element whose key is
@@ -1254,7 +1256,7 @@ class treap_impl
detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
key_node_comp(comp, this);
return iterator
(node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this);
(node_algorithms::find(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Finds a const_iterator to the first element whose key is
@@ -1278,7 +1280,7 @@ class treap_impl
detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
key_node_comp(comp, this);
return const_iterator
(node_algorithms::find(const_node_ptr(&priv_header()), key, key_node_comp), this);
(node_algorithms::find(this->priv_header_ptr(), key, key_node_comp), this);
}
//! <b>Effects</b>: Finds a range containing all elements whose key is k or
@@ -1304,7 +1306,7 @@ class treap_impl
detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
key_node_comp(comp, this);
std::pair<node_ptr, node_ptr> ret
(node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp));
(node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp));
return std::pair<iterator, iterator>(iterator(ret.first, this), iterator(ret.second, this));
}
@@ -1333,7 +1335,7 @@ class treap_impl
detail::key_nodeptr_comp<KeyValueCompare, treap_impl>
key_node_comp(comp, this);
std::pair<node_ptr, node_ptr> ret
(node_algorithms::equal_range(const_node_ptr(&priv_header()), key, key_node_comp));
(node_algorithms::equal_range(this->priv_header_ptr(), key, key_node_comp));
return std::pair<const_iterator, const_iterator>(const_iterator(ret.first, this), const_iterator(ret.second, this));
}
@@ -1359,8 +1361,8 @@ class treap_impl
detail::exception_disposer<treap_impl, Disposer>
rollback(*this, disposer);
node_algorithms::clone
(const_node_ptr(&src.priv_header())
,node_ptr(&this->priv_header())
(src.priv_header_ptr()
,this->priv_header_ptr()
,detail::node_cloner<Cloner, treap_impl>(cloner, this)
,detail::node_disposer<Disposer, treap_impl>(disposer, this));
this->priv_size_traits().set_size(src.priv_size_traits().get_size());
@@ -1382,7 +1384,7 @@ class treap_impl
pointer unlink_leftmost_without_rebalance()
{
node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance
(node_ptr(&priv_header())));
(this->priv_header_ptr()));
if(!to_be_disposed)
return 0;
this->priv_size_traits().decrement();
@@ -1408,7 +1410,7 @@ class treap_impl
void replace_node(iterator replace_this, reference with_this)
{
node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this)
, node_ptr(&priv_header())
, this->priv_header_ptr()
, get_real_value_traits().to_node_ptr(with_this));
if(safemode_or_autounlink)
node_algorithms::init(replace_this.pointed_node());
@@ -1510,7 +1512,7 @@ class treap_impl
static treap_impl &priv_container_from_end_iterator(const const_iterator &end_iterator)
{
header_plus_size *r = detail::parent_from_member<header_plus_size, node>
( detail::boost_intrusive_get_pointer(end_iterator.pointed_node()), &header_plus_size::header_);
( boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()), &header_plus_size::header_);
typename node_plus_pred_t::header_plus_priority_size *n =
detail::parent_from_member
< typename node_plus_pred_t::header_plus_priority_size

View File

@@ -19,6 +19,7 @@
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/utilities.hpp>
#include <boost/intrusive/detail/tree_algorithms.hpp>
#include <algorithm>
@@ -82,7 +83,7 @@ class treap_algorithms
remove_on_destroy(const remove_on_destroy&);
remove_on_destroy& operator=(const remove_on_destroy&);
public:
remove_on_destroy(node_ptr header, node_ptr z)
remove_on_destroy(const node_ptr & header, const node_ptr & z)
: header_(header), z_(z), remove_it_(true)
{}
~remove_on_destroy()
@@ -106,7 +107,7 @@ class treap_algorithms
rerotate_on_destroy& operator=(const rerotate_on_destroy&);
public:
rerotate_on_destroy(node_ptr header, node_ptr p, std::size_t &n)
rerotate_on_destroy(const node_ptr & header, const node_ptr & p, std::size_t &n)
: header_(header), p_(p), n_(n), remove_it_(true)
{}
@@ -143,17 +144,16 @@ class treap_algorithms
typedef detail::tree_algorithms<NodeTraits> tree_algorithms;
static node_ptr uncast(const_node_ptr ptr)
{
return node_ptr(const_cast<node*>(::boost::intrusive::detail::boost_intrusive_get_pointer(ptr)));
}
static node_ptr uncast(const const_node_ptr & ptr)
{ return pointer_traits<node_ptr>::const_cast_from(ptr); }
/// @endcond
public:
static node_ptr begin_node(const_node_ptr header)
static node_ptr begin_node(const const_node_ptr & header)
{ return tree_algorithms::begin_node(header); }
static node_ptr end_node(const_node_ptr header)
static node_ptr end_node(const const_node_ptr & header)
{ return tree_algorithms::end_node(header); }
//! This type is the information that will be
@@ -177,7 +177,7 @@ class treap_algorithms
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
static void swap_tree(node_ptr header1, node_ptr header2)
static void swap_tree(const node_ptr & header1, const node_ptr & header2)
{ return tree_algorithms::swap_tree(header1, header2); }
//! <b>Requires</b>: node1 and node2 can't be header nodes
@@ -195,7 +195,7 @@ class treap_algorithms
//! node1 and node2 are not equivalent according to the ordering rules.
//!
//!Experimental function
static void swap_nodes(node_ptr node1, node_ptr node2)
static void swap_nodes(const node_ptr & node1, const node_ptr & node2)
{
if(node1 == node2)
return;
@@ -219,7 +219,7 @@ class treap_algorithms
//! node1 and node2 are not equivalent according to the ordering rules.
//!
//!Experimental function
static void swap_nodes(node_ptr node1, node_ptr header1, node_ptr node2, node_ptr header2)
static void swap_nodes(const node_ptr & node1, const node_ptr & header1, const node_ptr & node2, const node_ptr & header2)
{ tree_algorithms::swap_nodes(node1, header1, node2, header2); }
//! <b>Requires</b>: node_to_be_replaced must be inserted in a tree
@@ -238,7 +238,7 @@ class treap_algorithms
//! the node, since no rebalancing and comparison is needed.
//!
//!Experimental function
static void replace_node(node_ptr node_to_be_replaced, node_ptr new_node)
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & new_node)
{
if(node_to_be_replaced == new_node)
return;
@@ -261,7 +261,7 @@ class treap_algorithms
//! the node, since no rebalancing or comparison is needed.
//!
//!Experimental function
static void replace_node(node_ptr node_to_be_replaced, node_ptr header, node_ptr new_node)
static void replace_node(const node_ptr & node_to_be_replaced, const node_ptr & header, const node_ptr & new_node)
{ tree_algorithms::replace_node(node_to_be_replaced, header, new_node); }
//! <b>Requires</b>: node is a tree node but not the header.
@@ -272,7 +272,7 @@ class treap_algorithms
//!
//! <b>Throws</b>: If "pcomp" throws, strong guarantee
template<class NodePtrPriorityCompare>
static void unlink(node_ptr node, NodePtrPriorityCompare pcomp)
static void unlink(const node_ptr & node, NodePtrPriorityCompare pcomp)
{
node_ptr x = NodeTraits::get_parent(node);
if(x){
@@ -295,7 +295,7 @@ class treap_algorithms
//! only be used for more unlink_leftmost_without_rebalance calls.
//! This function is normally used to achieve a step by step
//! controlled destruction of the tree.
static node_ptr unlink_leftmost_without_rebalance(node_ptr header)
static node_ptr unlink_leftmost_without_rebalance(const node_ptr & header)
{ return tree_algorithms::unlink_leftmost_without_rebalance(header); }
//! <b>Requires</b>: node is a node of the tree or an node initialized
@@ -306,7 +306,7 @@ class treap_algorithms
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
static bool unique(const_node_ptr node)
static bool unique(const const_node_ptr & node)
{ return tree_algorithms::unique(node); }
//! <b>Requires</b>: node is a node of the tree but it's not the header.
@@ -316,7 +316,7 @@ class treap_algorithms
//! <b>Complexity</b>: Linear time.
//!
//! <b>Throws</b>: Nothing.
static std::size_t count(const_node_ptr node)
static std::size_t count(const const_node_ptr & node)
{ return tree_algorithms::count(node); }
//! <b>Requires</b>: header is the header node of the tree.
@@ -326,7 +326,7 @@ class treap_algorithms
//! <b>Complexity</b>: Linear time.
//!
//! <b>Throws</b>: Nothing.
static std::size_t size(const_node_ptr header)
static std::size_t size(const const_node_ptr & header)
{ return tree_algorithms::size(header); }
//! <b>Requires</b>: p is a node from the tree except the header.
@@ -336,7 +336,7 @@ class treap_algorithms
//! <b>Complexity</b>: Average constant time.
//!
//! <b>Throws</b>: Nothing.
static node_ptr next_node(node_ptr p)
static node_ptr next_node(const node_ptr & p)
{ return tree_algorithms::next_node(p); }
//! <b>Requires</b>: p is a node from the tree except the leftmost node.
@@ -346,7 +346,7 @@ class treap_algorithms
//! <b>Complexity</b>: Average constant time.
//!
//! <b>Throws</b>: Nothing.
static node_ptr prev_node(node_ptr p)
static node_ptr prev_node(const node_ptr & p)
{ return tree_algorithms::prev_node(p); }
//! <b>Requires</b>: node must not be part of any tree.
@@ -358,7 +358,7 @@ class treap_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
static void init(node_ptr node)
static void init(const node_ptr & node)
{ tree_algorithms::init(node); }
//! <b>Requires</b>: node must not be part of any tree.
@@ -371,7 +371,7 @@ class treap_algorithms
//! <b>Throws</b>: Nothing.
//!
//! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
static void init_header(node_ptr header)
static void init_header(const node_ptr & header)
{
tree_algorithms::init_header(header);
}
@@ -385,7 +385,7 @@ class treap_algorithms
//!
//! <b>Throws</b>: If "pcomp" throws, strong guarantee.
template<class NodePtrPriorityCompare>
static node_ptr erase(node_ptr header, node_ptr z, NodePtrPriorityCompare pcomp)
static node_ptr erase(const node_ptr & header, const node_ptr & z, NodePtrPriorityCompare pcomp)
{
rebalance_for_erasure(header, z, pcomp);
tree_algorithms::erase(header, z);
@@ -398,13 +398,13 @@ class treap_algorithms
//! take a node_ptr and shouldn't throw.
//!
//! <b>Effects</b>: First empties target tree calling
//! <tt>void disposer::operator()(node_ptr)</tt> for every node of the tree
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
//! except the header.
//!
//! Then, duplicates the entire tree pointed by "source_header" cloning each
//! source node with <tt>node_ptr Cloner::operator()(node_ptr)</tt> to obtain
//! source node with <tt>node_ptr Cloner::operator()(const node_ptr &)</tt> to obtain
//! the nodes of the target tree. If "cloner" throws, the cloned target nodes
//! are disposed using <tt>void disposer(node_ptr)</tt>.
//! are disposed using <tt>void disposer(const node_ptr &)</tt>.
//!
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
//! number of elements of tree target tree when calling this function.
@@ -412,7 +412,7 @@ class treap_algorithms
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
template <class Cloner, class Disposer>
static void clone
(const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer)
(const const_node_ptr & source_header, const node_ptr & target_header, Cloner cloner, Disposer disposer)
{
tree_algorithms::clone(source_header, target_header, cloner, disposer);
}
@@ -421,7 +421,7 @@ class treap_algorithms
//! taking a node_ptr parameter and shouldn't throw.
//!
//! <b>Effects</b>: Empties the target tree calling
//! <tt>void disposer::operator()(node_ptr)</tt> for every node of the tree
//! <tt>void disposer::operator()(const node_ptr &)</tt> for every node of the tree
//! except the header.
//!
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
@@ -429,7 +429,7 @@ class treap_algorithms
//!
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
template<class Disposer>
static void clear_and_dispose(node_ptr header, Disposer disposer)
static void clear_and_dispose(const node_ptr & header, Disposer disposer)
{ tree_algorithms::clear_and_dispose(header, disposer); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -446,7 +446,7 @@ class treap_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr lower_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{ return tree_algorithms::lower_bound(header, key, comp); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -462,7 +462,7 @@ class treap_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr upper_bound
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{ return tree_algorithms::upper_bound(header, key, comp); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -478,7 +478,7 @@ class treap_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static node_ptr find
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{ return tree_algorithms::find(header, key, comp); }
//! <b>Requires</b>: "header" must be the header node of a tree.
@@ -496,7 +496,7 @@ class treap_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class KeyType, class KeyNodePtrCompare>
static std::pair<node_ptr, node_ptr> equal_range
(const_node_ptr header, const KeyType &key, KeyNodePtrCompare comp)
(const const_node_ptr & header, const KeyType &key, KeyNodePtrCompare comp)
{ return tree_algorithms::equal_range(header, key, comp); }
//! <b>Requires</b>: "h" must be the header node of a tree.
@@ -516,7 +516,7 @@ class treap_algorithms
//! <b>Throws</b>: If "comp" throw or "pcomp" throw.
template<class NodePtrCompare, class NodePtrPriorityCompare>
static node_ptr insert_equal_upper_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
tree_algorithms::insert_equal_upper_bound_check(h, new_node, comp, commit_data);
@@ -541,7 +541,7 @@ class treap_algorithms
//! <b>Throws</b>: If "comp" throws.
template<class NodePtrCompare, class NodePtrPriorityCompare>
static node_ptr insert_equal_lower_bound
(node_ptr h, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
(const node_ptr & h, const node_ptr & new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
tree_algorithms::insert_equal_lower_bound_check(h, new_node, comp, commit_data);
@@ -569,7 +569,7 @@ class treap_algorithms
//! <b>Throws</b>: If "comp" throw or "pcomp" throw.
template<class NodePtrCompare, class NodePtrPriorityCompare>
static node_ptr insert_equal
(node_ptr h, node_ptr hint, node_ptr new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
(const node_ptr & h, const node_ptr & hint, const node_ptr & new_node, NodePtrCompare comp, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
tree_algorithms::insert_equal_check(h, hint, new_node, comp, commit_data);
@@ -597,7 +597,7 @@ class treap_algorithms
//! tree invariants might be broken.
template<class NodePtrPriorityCompare>
static node_ptr insert_before
(node_ptr header, node_ptr pos, node_ptr new_node, NodePtrPriorityCompare pcomp)
(const node_ptr & header, const node_ptr & pos, const node_ptr & new_node, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
tree_algorithms::insert_before_check(header, pos, commit_data);
@@ -623,7 +623,7 @@ class treap_algorithms
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
template<class NodePtrPriorityCompare>
static void push_back(node_ptr header, node_ptr new_node, NodePtrPriorityCompare pcomp)
static void push_back(const node_ptr & header, const node_ptr & new_node, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
tree_algorithms::push_back_check(header, commit_data);
@@ -648,7 +648,7 @@ class treap_algorithms
//! tree invariants are broken. This function is slightly faster than
//! using "insert_before".
template<class NodePtrPriorityCompare>
static void push_front(node_ptr header, node_ptr new_node, NodePtrPriorityCompare pcomp)
static void push_front(const node_ptr & header, const node_ptr & new_node, NodePtrPriorityCompare pcomp)
{
insert_commit_data commit_data;
tree_algorithms::push_front_check(header, commit_data);
@@ -691,7 +691,7 @@ class treap_algorithms
//! if no more objects are inserted or erased from the set.
template<class KeyType, class KeyNodePtrCompare, class KeyNodePtrPrioCompare>
static std::pair<node_ptr, bool> insert_unique_check
(const_node_ptr header, const KeyType &key
(const const_node_ptr & header, const KeyType &key
,KeyNodePtrCompare comp, KeyNodePtrPrioCompare pcomp
,insert_commit_data &commit_data)
{
@@ -743,7 +743,7 @@ class treap_algorithms
//! if no more objects are inserted or erased from the set.
template<class KeyType, class KeyNodePtrCompare, class KeyNodePtrPrioCompare>
static std::pair<node_ptr, bool> insert_unique_check
(const_node_ptr header, node_ptr hint, const KeyType &key
(const const_node_ptr & header, const node_ptr & hint, const KeyType &key
,KeyNodePtrCompare comp, KeyNodePtrPrioCompare pcomp, insert_commit_data &commit_data)
{
std::pair<node_ptr, bool> ret =
@@ -771,7 +771,7 @@ class treap_algorithms
//! previously executed to fill "commit_data". No value should be inserted or
//! erased between the "insert_check" and "insert_commit" calls.
static void insert_unique_commit
(node_ptr header, node_ptr new_node, const insert_commit_data &commit_data)
(const node_ptr & header, const node_ptr & new_node, const insert_commit_data &commit_data)
{
tree_algorithms::insert_unique_commit(header, new_node, commit_data);
rebalance_after_insertion_commit(header, new_node, commit_data.rotations);
@@ -784,7 +784,7 @@ class treap_algorithms
//! <b>Complexity</b>: Logarithmic.
//!
//! <b>Throws</b>: Nothing.
static node_ptr get_header(node_ptr n)
static node_ptr get_header(const node_ptr & n)
{ return tree_algorithms::get_header(n); }
/// @cond
@@ -797,13 +797,13 @@ class treap_algorithms
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
static bool is_header(const_node_ptr p)
static bool is_header(const const_node_ptr & p)
{
return tree_algorithms::is_header(p);
}
template<class NodePtrPriorityCompare>
static void rebalance_for_erasure(node_ptr header, node_ptr z, NodePtrPriorityCompare pcomp)
static void rebalance_for_erasure(const node_ptr & header, const node_ptr & z, NodePtrPriorityCompare pcomp)
{
std::size_t n = 0;
rerotate_on_destroy rb(header, z, n);
@@ -826,7 +826,7 @@ class treap_algorithms
template<class NodePtrPriorityCompare>
static void rebalance_check_and_commit
(node_ptr h, node_ptr new_node, NodePtrPriorityCompare pcomp, insert_commit_data &commit_data)
(const node_ptr & h, const node_ptr & new_node, NodePtrPriorityCompare pcomp, insert_commit_data &commit_data)
{
rebalance_after_insertion_check(h, commit_data.node, new_node, pcomp, commit_data.rotations);
//No-throw
@@ -837,9 +837,10 @@ class treap_algorithms
template<class Key, class KeyNodePriorityCompare>
static void rebalance_after_insertion_check
( const_node_ptr header, const_node_ptr upnode, const Key &k
(const const_node_ptr &header, const const_node_ptr & up, const Key &k
, KeyNodePriorityCompare pcomp, std::size_t &num_rotations)
{
const_node_ptr upnode(up);
//First check rotations since pcomp can throw
num_rotations = 0;
std::size_t n = 0;
@@ -850,7 +851,7 @@ class treap_algorithms
num_rotations = n;
}
static void rebalance_after_insertion_commit(node_ptr header, node_ptr p, std::size_t 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)
@@ -867,7 +868,7 @@ class treap_algorithms
}
template<class NodePtrPriorityCompare>
static bool check_invariant(const_node_ptr header, NodePtrPriorityCompare pcomp)
static bool check_invariant(const const_node_ptr & header, NodePtrPriorityCompare pcomp)
{
node_ptr beg = begin_node(header);
node_ptr end = end_node(header);

View File

@@ -14,6 +14,7 @@
#define BOOST_INTRUSIVE_TRIVIAL_VALUE_TRAITS_HPP
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/pointer_traits.hpp>
namespace boost {
namespace intrusive {
@@ -31,10 +32,12 @@ struct trivial_value_traits
typedef node_ptr pointer;
typedef const_node_ptr const_pointer;
static const link_mode_type link_mode = LinkMode;
static node_ptr to_node_ptr (value_type &value) { return node_ptr(&value); }
static const_node_ptr to_node_ptr (const value_type &value) { return const_node_ptr(&value); }
static pointer to_value_ptr(node_ptr n) { return pointer(n); }
static const_pointer to_value_ptr(const_node_ptr n) { return const_pointer(n); }
static node_ptr to_node_ptr (value_type &value)
{ return pointer_traits<node_ptr>::pointer_to(value); }
static const_node_ptr to_node_ptr (const value_type &value)
{ return pointer_traits<const_node_ptr>::pointer_to(value); }
static const pointer & to_value_ptr(const node_ptr &n) { return n; }
static const const_pointer &to_value_ptr(const const_node_ptr &n) { return n; }
};
} //namespace intrusive

View File

@@ -18,9 +18,10 @@
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/pointer_cast.hpp>
#include <boost/intrusive/detail/utilities.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/slist_hook.hpp>
#include <boost/intrusive/options.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/generic_hook.hpp>
namespace boost {
@@ -32,10 +33,10 @@ template<class VoidPointer, bool StoreHash, bool OptimizeMultiKey>
struct unordered_node
: public slist_node<VoidPointer>
{
typedef typename boost::pointer_to_other
< VoidPointer
, unordered_node<VoidPointer, StoreHash, OptimizeMultiKey>
>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
< unordered_node<VoidPointer, StoreHash, OptimizeMultiKey> >::type
node_ptr;
node_ptr prev_in_group_;
std::size_t hash_;
};
@@ -44,10 +45,10 @@ template<class VoidPointer>
struct unordered_node<VoidPointer, false, true>
: public slist_node<VoidPointer>
{
typedef typename boost::pointer_to_other
< VoidPointer
, unordered_node<VoidPointer, false, true>
>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
< unordered_node<VoidPointer, false, true> >::type
node_ptr;
node_ptr prev_in_group_;
};
@@ -55,10 +56,10 @@ template<class VoidPointer>
struct unordered_node<VoidPointer, true, false>
: public slist_node<VoidPointer>
{
typedef typename boost::pointer_to_other
< VoidPointer
, unordered_node<VoidPointer, true, false>
>::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
< unordered_node<VoidPointer, true, false> >::type
node_ptr;
std::size_t hash_;
};
@@ -68,35 +69,35 @@ struct unordered_node_traits
{
typedef slist_node_traits<VoidPointer> reduced_slist_node_traits;
typedef unordered_node<VoidPointer, StoreHash, OptimizeMultiKey> node;
typedef typename boost::pointer_to_other
<VoidPointer, node>::type node_ptr;
typedef typename boost::pointer_to_other
<VoidPointer, const node>::type const_node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
< node >::type node_ptr;
typedef typename pointer_traits
<VoidPointer>::template rebind_pointer
< const node >::type const_node_ptr;
static const bool store_hash = StoreHash;
static const bool optimize_multikey = OptimizeMultiKey;
static node_ptr get_next(const_node_ptr n)
static node_ptr get_next(const const_node_ptr & n)
{
// This still fails in gcc < 4.4 so forget about it
// using ::boost::static_pointer_cast;
// return static_pointer_cast<node>(n->next_);
return node_ptr(&static_cast<node&>(*n->next_));
return pointer_traits<node_ptr>::pointer_to(static_cast<node&>(*n->next_));
}
static void set_next(node_ptr n, node_ptr next)
static void set_next(const node_ptr & n, const node_ptr & next)
{ n->next_ = next; }
static node_ptr get_prev_in_group(const_node_ptr n)
static node_ptr get_prev_in_group(const const_node_ptr & n)
{ return n->prev_in_group_; }
static void set_prev_in_group(node_ptr n, node_ptr prev)
static void set_prev_in_group(const node_ptr & n, const node_ptr & prev)
{ n->prev_in_group_ = prev; }
static std::size_t get_hash(const_node_ptr n)
static std::size_t get_hash(const const_node_ptr & n)
{ return n->hash_; }
static void set_hash(node_ptr n, std::size_t h)
static void set_hash(const node_ptr & n, std::size_t h)
{ n->hash_ = h; }
};
@@ -107,10 +108,10 @@ struct unordered_group_adapter
typedef typename NodeTraits::node_ptr node_ptr;
typedef typename NodeTraits::const_node_ptr const_node_ptr;
static node_ptr get_next(const_node_ptr n)
static node_ptr get_next(const const_node_ptr & n)
{ return NodeTraits::get_prev_in_group(n); }
static void set_next(node_ptr n, node_ptr next)
static void set_next(const node_ptr & n, const node_ptr & next)
{ NodeTraits::set_prev_in_group(n, next); }
};