mirror of
https://github.com/boostorg/intrusive.git
synced 2025-08-03 14:34:44 +02:00
Introducing allocator_traits and pointer_traits changes into several libraries.
[SVN r76106]
This commit is contained in:
@@ -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
|
||||
|
@@ -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_);
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
//!
|
||||
@@ -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--
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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()
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
//
|
||||
|
@@ -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());
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -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
|
@@ -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_;
|
||||
|
@@ -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)
|
||||
{}
|
||||
|
||||
@@ -104,8 +104,10 @@ 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
|
||||
{
|
||||
|
250
include/boost/intrusive/detail/memory_util.hpp
Normal file
250
include/boost/intrusive/detail/memory_util.hpp
Normal 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)
|
@@ -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
|
52
include/boost/intrusive/detail/preprocessor.hpp
Normal file
52
include/boost/intrusive/detail/preprocessor.hpp
Normal 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
|
@@ -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()
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -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){
|
||||
|
@@ -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()); }
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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()){
|
||||
|
@@ -62,12 +62,12 @@ 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()
|
||||
//!
|
||||
//! <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.
|
||||
//!
|
||||
@@ -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;
|
||||
|
@@ -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_);
|
||||
|
@@ -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));
|
||||
}
|
||||
};
|
||||
|
||||
|
265
include/boost/intrusive/pointer_traits.hpp
Normal file
265
include/boost/intrusive/pointer_traits.hpp
Normal 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
|
||||
//!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::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)
|
@@ -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_);
|
||||
|
@@ -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));
|
||||
|
@@ -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_);
|
||||
|
@@ -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)
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1226,7 +1225,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 +1742,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 +1765,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 +1777,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 +1793,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 +1893,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 +1906,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_);
|
||||
|
@@ -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_);
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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); }
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user