Fixed ABI regression introduced in Boost 1.55

This commit is contained in:
Ion Gaztañaga 2014-01-30 14:22:04 +01:00
parent f162078264
commit 2ffe6b2f82
23 changed files with 971 additions and 1165 deletions

View File

@ -3788,6 +3788,8 @@ to be inserted in intrusive containers are allocated using `std::vector` or `std
* Improved Doxygen generated reference and updated and fixed forward-declaration header.
* [*ABI breaking]: Fixed ABI regression introduced in Boost 1.55 version, mainly noticeable on MSVC compilers.
* [*Source breaking]: Removed previously deprecated `xxx_dont_splay` functions from splay containers,
`splay_set_base_hook` and `splay_set_member_hook`from splay containers and `bool splay = true`
extra parameter is `splaytree_algorithms` functions.

View File

@ -1,129 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
//[doc_external_value_traits
#include <boost/intrusive/list.hpp>
#include <vector>
using namespace boost::intrusive;
//This type is not modifiable so we can't store hooks or custom nodes
typedef int identifier_t;
//This value traits will associate elements from an array of identifiers with
//elements of an array of nodes. The element i of the value array will use the
//node i of the node array:
class external_traits
{
//Non-copyable
external_traits(const external_traits &);
external_traits& operator=(const external_traits &);
public:
typedef list_node_traits<void*> node_traits;
typedef node_traits::node node;
typedef node * node_ptr;
typedef const node * const_node_ptr;
typedef identifier_t value_type;
typedef identifier_t * pointer;
typedef const identifier_t * const_pointer;
static const link_mode_type link_mode = normal_link;
external_traits(pointer ids, std::size_t NumElements)
: ids_(ids), nodes_(NumElements)
{}
///Note: non static functions!
node_ptr to_node_ptr (value_type &value)
{ return &this->nodes_[0] + (&value - this->ids_); }
const_node_ptr to_node_ptr (const value_type &value) const
{ return &this->nodes_[0] + (&value - this->ids_); }
pointer to_value_ptr(node_ptr n)
{ return this->ids_ + (n - &this->nodes_[0]); }
const_pointer to_value_ptr(const_node_ptr n) const
{ return this->ids_ + (n - &this->nodes_[0]); }
private:
pointer ids_;
//This is an array of nodes that is necessary to form the linked list
std::vector<list_node_traits<void*>::node> nodes_;
};
//This is the value traits class that will be stored in the container
//and that will lead to the external traits using the address
//of the container.
struct internal_traits
{
static const bool external_value_traits = true;
typedef external_traits value_traits;
template<class Container>
value_traits &get_value_traits(Container &cont);
template<class Container>
const value_traits &get_value_traits(const Container &cont) const;
};
//The intrusive list that will use external value traits
typedef list<identifier_t, value_traits<internal_traits> > List;
class data_holder
: public List
{
public:
data_holder(identifier_t *ids, std::size_t NumElements)
: List()
, external_traits_(ids, NumElements)
{}
external_traits external_traits_;
};
template<class Container>
internal_traits::value_traits &internal_traits::get_value_traits(Container &cont)
{ return static_cast<data_holder&>(cont).external_traits_; }
template<class Container>
const internal_traits::value_traits &internal_traits::get_value_traits(const Container &cont) const
{ return static_cast<const data_holder&>(cont).external_traits_; }
int main()
{
const int NumElements = 100;
//This is an array of ids that we want to "store"
identifier_t ids [NumElements];
//Initialize id objects, each one with a different number
for(int i = 0; i != NumElements; ++i) ids[i] = i;
//The data holding the list and the external traits
data_holder data(ids, NumElements);
//This list will store ids without modifying identifier_t instances
//Stateful value traits must be explicitly passed in the constructor.
List &my_list = data;
//Insert ids in reverse order in the list
for(identifier_t * it(&ids[0]), *itend(&ids[NumElements]); it != itend; ++it)
my_list.push_front(*it);
//Now test lists
List::const_iterator list_it (my_list.cbegin());
identifier_t *it_val(&ids[NumElements]-1), *it_rbeg_val(&ids[0] -1);
//Test the objects inserted in the base hook list
for(; it_val != it_rbeg_val; --it_val, ++list_it){
if(&*list_it != &*it_val) return 1;
}
return 0;
}
//]

View File

@ -487,14 +487,13 @@ class avltree
public:
typedef typename Base::value_compare value_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::real_value_traits real_value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
typedef typename Base::reverse_iterator reverse_iterator;
typedef typename Base::const_reverse_iterator const_reverse_iterator;
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
explicit avltree( const value_compare &cmp = value_compare()
, const value_traits &v_traits = value_traits())

View File

@ -34,6 +34,7 @@
#include <boost/intrusive/options.hpp>
#include <boost/intrusive/bstree_algorithms.hpp>
#include <boost/intrusive/link_mode.hpp>
#include <boost/intrusive/parent_from_member.hpp>
#include <boost/move/move.hpp>
namespace boost {
@ -53,91 +54,93 @@ struct bstree_defaults
template<class ValueTraits, algo_types AlgoType>
struct bstbase3
: public detail::get_real_value_traits<ValueTraits>::type::node_traits::node
, public ValueTraits
{
typedef ValueTraits value_traits;
typedef typename detail::get_real_value_traits<ValueTraits>::type real_value_traits;
typedef typename real_value_traits::node_traits node_traits;
typedef typename value_traits::node_traits node_traits;
typedef typename node_traits::node node_type;
typedef typename get_algo<AlgoType, node_traits>::type node_algorithms;
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr;
bstbase3(const ValueTraits &vtraits)
: ValueTraits(vtraits)
{}
struct holder_t : public ValueTraits
{
explicit holder_t(const ValueTraits &vtraits)
: ValueTraits(vtraits)
{}
node_type root;
} holder;
static const bool external_value_traits =
detail::external_value_traits_bool_is_true<ValueTraits>::value;
static bstbase3 &get_tree_base_from_root(node_type &root)
{
holder_t *holder = get_parent_from_member<holder_t, node_type>(&root, &holder_t::root);
bstbase3 *base = get_parent_from_member<bstbase3, holder_t> (holder, &bstbase3::holder);
return *base;
}
bstbase3(const ValueTraits &vtraits)
: holder(vtraits)
{
node_algorithms::init_header(this->header_ptr());
}
node_ptr header_ptr()
{ return pointer_traits<node_ptr>::pointer_to(static_cast<node_type&>(*this)); }
{ return pointer_traits<node_ptr>::pointer_to(this->holder.root); }
const_node_ptr header_ptr() const
{ return pointer_traits<const_node_ptr>::pointer_to(static_cast<const node_type&>(*this)); }
{ return pointer_traits<const_node_ptr>::pointer_to(this->holder.root); }
const value_traits &val_traits() const
{ return *this; }
const value_traits &get_value_traits() const
{ return this->holder; }
value_traits &val_traits()
{ return *this; }
value_traits &get_value_traits()
{ return this->holder; }
const real_value_traits &get_real_value_traits(detail::bool_<false>) const
{ return *this; }
typedef typename pointer_traits<node_ptr>::template
rebind_pointer<const value_traits>::type const_value_traits_ptr;
const real_value_traits &get_real_value_traits(detail::bool_<true>) const
{ return this->val_traits().get_value_traits(*this); }
const_value_traits_ptr value_traits_ptr() const
{ return pointer_traits<const_value_traits_ptr>::pointer_to(this->get_value_traits()); }
real_value_traits &get_real_value_traits(detail::bool_<false>)
{ return *this; }
real_value_traits &get_real_value_traits(detail::bool_<true>)
{ return this->val_traits().get_value_traits(*this); }
const real_value_traits &get_real_value_traits() const
{ return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
real_value_traits &get_real_value_traits()
{ return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
typedef typename pointer_traits<node_ptr>::template rebind_pointer<const real_value_traits>::type const_real_value_traits_ptr;
const_real_value_traits_ptr real_value_traits_ptr() const
{ return pointer_traits<const_real_value_traits_ptr>::pointer_to(this->get_real_value_traits()); }
typedef tree_iterator<real_value_traits, false> iterator;
typedef tree_iterator<real_value_traits, true> const_iterator;
typedef tree_iterator<value_traits, false> iterator;
typedef tree_iterator<value_traits, true> const_iterator;
typedef boost::intrusive::detail::reverse_iterator<iterator> reverse_iterator;
typedef boost::intrusive::detail::reverse_iterator<const_iterator> const_reverse_iterator;
typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::pointer) pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::const_pointer) const_pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::element_type) value_type;
typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference) reference;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::reference) const_reference;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<const_pointer>::difference_type) difference_type;
static const bool safemode_or_autounlink = is_safe_autounlink<real_value_traits::link_mode>::value;
static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
iterator begin()
{ return iterator (node_traits::get_left(this->header_ptr()), this->real_value_traits_ptr()); }
{ return iterator(node_algorithms::begin_node(this->header_ptr()), this->value_traits_ptr()); }
const_iterator begin() const
{ return cbegin(); }
const_iterator cbegin() const
{ return const_iterator (node_traits::get_left(this->header_ptr()), this->real_value_traits_ptr()); }
{ return const_iterator(node_algorithms::begin_node(this->header_ptr()), this->value_traits_ptr()); }
iterator end()
{ return iterator (this->header_ptr(), this->real_value_traits_ptr()); }
{ return iterator(node_algorithms::end_node(this->header_ptr()), this->value_traits_ptr()); }
const_iterator end() const
{ return cend(); }
const_iterator cend() const
{ return const_iterator (detail::uncast(this->header_ptr()), this->real_value_traits_ptr()); }
{ return const_iterator(node_algorithms::end_node(this->header_ptr()), this->value_traits_ptr()); }
iterator root()
{ return iterator(node_algorithms::root_node(this->header_ptr()), this->value_traits_ptr()); }
const_iterator root() const
{ return croot(); }
const_iterator croot() const
{ return const_iterator(node_algorithms::root_node(this->header_ptr()), this->value_traits_ptr()); }
reverse_iterator rbegin()
{ return reverse_iterator(end()); }
@ -159,9 +162,9 @@ struct bstbase3
void replace_node(iterator replace_this, reference with_this)
{
node_algorithms::replace_node( get_real_value_traits().to_node_ptr(*replace_this)
node_algorithms::replace_node( get_value_traits().to_node_ptr(*replace_this)
, this->header_ptr()
, get_real_value_traits().to_node_ptr(with_this));
, get_value_traits().to_node_ptr(with_this));
if(safemode_or_autounlink)
node_algorithms::init(replace_this.pointed_node());
}
@ -170,25 +173,25 @@ struct bstbase3
{ node_algorithms::rebalance(this->header_ptr()); }
iterator rebalance_subtree(iterator root)
{ return iterator(node_algorithms::rebalance_subtree(root.pointed_node()), this->real_value_traits_ptr()); }
{ return iterator(node_algorithms::rebalance_subtree(root.pointed_node()), this->value_traits_ptr()); }
static iterator s_iterator_to(reference value)
{
BOOST_STATIC_ASSERT((!stateful_value_traits));
return iterator (value_traits::to_node_ptr(value), const_real_value_traits_ptr());
return iterator (value_traits::to_node_ptr(value), const_value_traits_ptr());
}
static const_iterator s_iterator_to(const_reference value)
{
BOOST_STATIC_ASSERT((!stateful_value_traits));
return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), const_real_value_traits_ptr());
return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), const_value_traits_ptr());
}
iterator iterator_to(reference value)
{ return iterator (value_traits::to_node_ptr(value), this->real_value_traits_ptr()); }
{ return iterator (value_traits::to_node_ptr(value), this->value_traits_ptr()); }
const_iterator iterator_to(const_reference value) const
{ return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), this->real_value_traits_ptr()); }
{ return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), this->value_traits_ptr()); }
static void init_node(reference value)
{ node_algorithms::init(value_traits::to_node_ptr(value)); }
@ -197,16 +200,17 @@ struct bstbase3
template<class ValueTraits, class VoidOrKeyComp, algo_types AlgoType>
struct bstbase2
: public bstbase3<ValueTraits, AlgoType>
, public detail::ebo_functor_holder<typename get_less< VoidOrKeyComp
, typename detail::get_real_value_traits<ValueTraits>::type::value_type
//Put the (possibly empty) functor in the first position to get EBO in MSVC
: public detail::ebo_functor_holder<typename get_less< VoidOrKeyComp
, typename ValueTraits::value_type
>::type>
, public bstbase3<ValueTraits, AlgoType>
{
typedef bstbase3<ValueTraits, AlgoType> treeheader_t;
typedef typename treeheader_t::real_value_traits real_value_traits;
typedef typename treeheader_t::value_traits value_traits;
typedef typename treeheader_t::node_algorithms node_algorithms;
typedef typename get_less
< VoidOrKeyComp, typename real_value_traits::value_type>::type value_compare;
< VoidOrKeyComp, typename value_traits::value_type>::type value_compare;
typedef BOOST_INTRUSIVE_IMPDEF(value_compare) key_compare;
typedef typename treeheader_t::iterator iterator;
typedef typename treeheader_t::const_iterator const_iterator;
@ -214,7 +218,7 @@ struct bstbase2
typedef typename treeheader_t::const_node_ptr const_node_ptr;
bstbase2(const value_compare &comp, const ValueTraits &vtraits)
: treeheader_t(vtraits), detail::ebo_functor_holder<value_compare>(comp)
: detail::ebo_functor_holder<value_compare>(comp), treeheader_t(vtraits)
{}
const value_compare &comp() const
@ -223,8 +227,8 @@ struct bstbase2
value_compare &comp()
{ return this->get(); }
typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::pointer) pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::const_pointer) const_pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::element_type) value_type;
typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference) reference;
@ -248,19 +252,19 @@ struct bstbase2
template<class KeyType, class KeyValueCompare>
iterator lower_bound(const KeyType &key, KeyValueCompare comp)
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
key_node_comp(comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
key_node_comp(comp, &this->get_value_traits());
return iterator(node_algorithms::lower_bound
(this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr());
(this->header_ptr(), key, key_node_comp), this->value_traits_ptr());
}
template<class KeyType, class KeyValueCompare>
const_iterator lower_bound(const KeyType &key, KeyValueCompare comp) const
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
key_node_comp(comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
key_node_comp(comp, &this->get_value_traits());
return const_iterator(node_algorithms::lower_bound
(this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr());
(this->header_ptr(), key, key_node_comp), this->value_traits_ptr());
}
//upper_bound
@ -270,10 +274,10 @@ struct bstbase2
template<class KeyType, class KeyValueCompare>
iterator upper_bound(const KeyType &key, KeyValueCompare comp)
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
key_node_comp(comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
key_node_comp(comp, &this->get_value_traits());
return iterator(node_algorithms::upper_bound
(this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr());
(this->header_ptr(), key, key_node_comp), this->value_traits_ptr());
}
const_iterator upper_bound(const_reference value) const
@ -282,10 +286,10 @@ struct bstbase2
template<class KeyType, class KeyValueCompare>
const_iterator upper_bound(const KeyType &key, KeyValueCompare comp) const
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
key_node_comp(comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
key_node_comp(comp, &this->get_value_traits());
return const_iterator(node_algorithms::upper_bound
(this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr());
(this->header_ptr(), key, key_node_comp), this->value_traits_ptr());
}
//find
@ -295,10 +299,10 @@ struct bstbase2
template<class KeyType, class KeyValueCompare>
iterator find(const KeyType &key, KeyValueCompare comp)
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
key_node_comp(comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
key_node_comp(comp, &this->get_value_traits());
return iterator
(node_algorithms::find(this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr());
(node_algorithms::find(this->header_ptr(), key, key_node_comp), this->value_traits_ptr());
}
const_iterator find(const_reference value) const
@ -307,10 +311,10 @@ struct bstbase2
template<class KeyType, class KeyValueCompare>
const_iterator find(const KeyType &key, KeyValueCompare comp) const
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
key_node_comp(comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
key_node_comp(comp, &this->get_value_traits());
return const_iterator
(node_algorithms::find(this->header_ptr(), key, key_node_comp), this->real_value_traits_ptr());
(node_algorithms::find(this->header_ptr(), key, key_node_comp), this->value_traits_ptr());
}
//equal_range
@ -320,12 +324,12 @@ struct bstbase2
template<class KeyType, class KeyValueCompare>
std::pair<iterator,iterator> equal_range(const KeyType &key, KeyValueCompare comp)
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
key_node_comp(comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
(node_algorithms::equal_range(this->header_ptr(), key, key_node_comp));
return std::pair<iterator, iterator>( iterator(ret.first, this->real_value_traits_ptr())
, iterator(ret.second, this->real_value_traits_ptr()));
return std::pair<iterator, iterator>( iterator(ret.first, this->value_traits_ptr())
, iterator(ret.second, this->value_traits_ptr()));
}
std::pair<const_iterator, const_iterator>
@ -336,12 +340,12 @@ struct bstbase2
std::pair<const_iterator, const_iterator>
equal_range(const KeyType &key, KeyValueCompare comp) const
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
key_node_comp(comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
(node_algorithms::equal_range(this->header_ptr(), key, key_node_comp));
return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->real_value_traits_ptr())
, const_iterator(ret.second, this->real_value_traits_ptr()));
return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->value_traits_ptr())
, const_iterator(ret.second, this->value_traits_ptr()));
}
//lower_bound_range
@ -351,12 +355,12 @@ struct bstbase2
template<class KeyType, class KeyValueCompare>
std::pair<iterator,iterator> lower_bound_range(const KeyType &key, KeyValueCompare comp)
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
key_node_comp(comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
(node_algorithms::lower_bound_range(this->header_ptr(), key, key_node_comp));
return std::pair<iterator, iterator>( iterator(ret.first, this->real_value_traits_ptr())
, iterator(ret.second, this->real_value_traits_ptr()));
return std::pair<iterator, iterator>( iterator(ret.first, this->value_traits_ptr())
, iterator(ret.second, this->value_traits_ptr()));
}
std::pair<const_iterator, const_iterator>
@ -367,12 +371,12 @@ struct bstbase2
std::pair<const_iterator, const_iterator>
lower_bound_range(const KeyType &key, KeyValueCompare comp) const
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
key_node_comp(comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
(node_algorithms::lower_bound_range(this->header_ptr(), key, key_node_comp));
return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->real_value_traits_ptr())
, const_iterator(ret.second, this->real_value_traits_ptr()));
return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->value_traits_ptr())
, const_iterator(ret.second, this->value_traits_ptr()));
}
//bounded_range
@ -384,13 +388,13 @@ struct bstbase2
std::pair<iterator,iterator> bounded_range
(const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed)
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
key_node_comp(comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
(node_algorithms::bounded_range
(this->header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed));
return std::pair<iterator, iterator>( iterator(ret.first, this->real_value_traits_ptr())
, iterator(ret.second, this->real_value_traits_ptr()));
return std::pair<iterator, iterator>( iterator(ret.first, this->value_traits_ptr())
, iterator(ret.second, this->value_traits_ptr()));
}
std::pair<const_iterator,const_iterator> bounded_range
@ -401,13 +405,13 @@ struct bstbase2
std::pair<const_iterator,const_iterator> bounded_range
(const KeyType &lower_key, const KeyType &upper_key, KeyValueCompare comp, bool left_closed, bool right_closed) const
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
key_node_comp(comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
key_node_comp(comp, &this->get_value_traits());
std::pair<node_ptr, node_ptr> ret
(node_algorithms::bounded_range
(this->header_ptr(), lower_key, upper_key, key_node_comp, left_closed, right_closed));
return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->real_value_traits_ptr())
, const_iterator(ret.second, this->real_value_traits_ptr()));
return std::pair<const_iterator, const_iterator>( const_iterator(ret.first, this->value_traits_ptr())
, const_iterator(ret.second, this->value_traits_ptr()));
}
//insert_unique_check
@ -415,12 +419,12 @@ struct bstbase2
std::pair<iterator, bool> insert_unique_check
(const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
ocomp(key_value_comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
ocomp(key_value_comp, &this->get_value_traits());
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
(this->header_ptr(), key, ocomp, commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this->real_value_traits_ptr()), ret.second);
return std::pair<iterator, bool>(iterator(ret.first, this->value_traits_ptr()), ret.second);
}
template<class KeyType, class KeyValueCompare>
@ -428,76 +432,102 @@ struct bstbase2
(const_iterator hint, const KeyType &key
,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
ocomp(key_value_comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
ocomp(key_value_comp, &this->get_value_traits());
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
(this->header_ptr(), hint.pointed_node(), key, ocomp, commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this->real_value_traits_ptr()), ret.second);
return std::pair<iterator, bool>(iterator(ret.first, this->value_traits_ptr()), ret.second);
}
};
//Due to MSVC's EBO implementation, to save space and maintain the ABI, we must put the non-empty size member
//in the first position, but if size is not going to be stored then we'll use an specialization
//that doesn't inherit from size_holder
template<class ValueTraits, class VoidOrKeyComp, bool ConstantTimeSize, class SizeType, algo_types AlgoType>
struct bstbase
struct bstbase_hack
: public detail::size_holder<ConstantTimeSize, SizeType>
, public bstbase2 < ValueTraits, VoidOrKeyComp, AlgoType>
{
typedef typename detail::get_real_value_traits<ValueTraits>::type real_value_traits;
typedef bstbase2< ValueTraits, VoidOrKeyComp, AlgoType> base_type;
typedef typename base_type::value_compare value_compare;
typedef BOOST_INTRUSIVE_IMPDEF(value_compare) key_compare;
typedef SizeType size_type;
typedef typename base_type::node_traits node_traits;
typedef typename get_algo
<AlgoType, node_traits>::type algo_type;
bstbase_hack(const value_compare & comp, const ValueTraits &vtraits)
: base_type(comp, vtraits)
{
this->sz_traits().set_size(size_type(0));
}
typedef detail::size_holder<ConstantTimeSize, SizeType> size_traits;
size_traits &sz_traits()
{ return static_cast<size_traits &>(*this); }
const size_traits &sz_traits() const
{ return static_cast<const size_traits &>(*this); }
};
//Specialization for ConstantTimeSize == false
template<class ValueTraits, class VoidOrKeyComp, class SizeType, algo_types AlgoType>
struct bstbase_hack<ValueTraits, VoidOrKeyComp, false, SizeType, AlgoType>
: public bstbase2 < ValueTraits, VoidOrKeyComp, AlgoType>
{
typedef bstbase2< ValueTraits, VoidOrKeyComp, AlgoType> base_type;
typedef typename base_type::value_compare value_compare;
bstbase_hack(const value_compare & comp, const ValueTraits &vtraits)
: base_type(comp, vtraits)
{}
typedef detail::size_holder<true, SizeType> size_traits;
size_traits &sz_traits()
{ return s_size_traits; }
const size_traits &sz_traits() const
{ return s_size_traits; }
static size_traits s_size_traits;
};
template<class ValueTraits, class VoidOrKeyComp, class SizeType, algo_types AlgoType>
detail::size_holder<true, SizeType> bstbase_hack<ValueTraits, VoidOrKeyComp, false, SizeType, AlgoType>::s_size_traits;
//This class will
template<class ValueTraits, class VoidOrKeyComp, bool ConstantTimeSize, class SizeType, algo_types AlgoType>
struct bstbase
: public bstbase_hack< ValueTraits, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType>
{
typedef bstbase_hack< ValueTraits, VoidOrKeyComp, ConstantTimeSize, SizeType, AlgoType> base_type;
typedef ValueTraits value_traits;
typedef typename base_type::value_compare value_compare;
typedef value_compare key_compare;
typedef typename base_type::const_reference const_reference;
typedef typename base_type::reference reference;
typedef typename base_type::iterator iterator;
typedef typename base_type::const_iterator const_iterator;
typedef typename base_type::node_traits node_traits;
typedef typename get_algo
<AlgoType, node_traits>::type algo_type;
<AlgoType, node_traits>::type node_algorithms;
typedef SizeType size_type;
bstbase(const value_compare & comp, const ValueTraits &vtraits)
: base_type(comp, vtraits)
{}
public:
typedef detail::size_holder<ConstantTimeSize, SizeType> size_traits;
size_traits &sz_traits()
{ return *this; }
const size_traits &sz_traits() const
{ return *this; }
bool empty() const
//Detach all inserted nodes. This will add exception safety to bstree_impl
//constructors inserting elements.
~bstbase()
{
if(ConstantTimeSize){
return !this->sz_traits().get_size();
if(is_safe_autounlink<value_traits::link_mode>::value){
node_algorithms::clear_and_dispose
( this->header_ptr()
, detail::node_disposer<detail::null_disposer, value_traits, AlgoType>
(detail::null_disposer(), &this->get_value_traits()));
}
else{
return algo_type::unique(this->header_ptr());
}
}
size_type count(const_reference value) const
{ return size_type(this->count(value, this->comp())); }
template<class KeyType, class KeyValueCompare>
size_type count(const KeyType &key, KeyValueCompare comp) const
{
std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
return size_type(std::distance(ret.first, ret.second));
}
//Add non-const overloads to theoretically const members
//as some algorithms have different behavior when non-const versions are used (like splay trees).
size_type count(const_reference value)
{ return size_type(this->count(value, this->comp())); }
template<class KeyType, class KeyValueCompare>
size_type count(const KeyType &key, KeyValueCompare comp)
{
std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
return size_type(std::distance(ret.first, ret.second));
}
};
@ -526,25 +556,18 @@ template<class ValueTraits, class VoidKeyComp, class SizeType, bool ConstantTime
#endif
class bstree_impl
: public bstbase<ValueTraits, VoidKeyComp, ConstantTimeSize, SizeType, AlgoType>
, private detail::clear_on_destructor_base
< bstree_impl<ValueTraits, VoidKeyComp, SizeType, ConstantTimeSize, AlgoType>
, is_safe_autounlink<detail::get_real_value_traits<ValueTraits>::type::link_mode>::value
>
{
template<class C, bool> friend class detail::clear_on_destructor_base;
public:
typedef ValueTraits value_traits;
/// @cond
static const bool external_value_traits =
detail::external_value_traits_bool_is_true<value_traits>::value;
typedef typename detail::get_real_value_traits<ValueTraits>::type real_value_traits;
typedef bstbase<value_traits, VoidKeyComp, ConstantTimeSize, SizeType, AlgoType> data_type;
typedef tree_iterator<real_value_traits, false> iterator_type;
typedef tree_iterator<real_value_traits, true> const_iterator_type;
typedef bstbase<ValueTraits, VoidKeyComp, ConstantTimeSize, SizeType, AlgoType> data_type;
typedef tree_iterator<ValueTraits, false> iterator_type;
typedef tree_iterator<ValueTraits, true> const_iterator_type;
/// @endcond
typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::pointer) pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::const_pointer) const_pointer;
typedef BOOST_INTRUSIVE_IMPDEF(ValueTraits) value_traits;
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::pointer) pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::const_pointer) const_pointer;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::element_type) value_type;
typedef BOOST_INTRUSIVE_IMPDEF(value_type) key_type;
typedef BOOST_INTRUSIVE_IMPDEF(typename pointer_traits<pointer>::reference) reference;
@ -557,7 +580,7 @@ class bstree_impl
typedef BOOST_INTRUSIVE_IMPDEF(const_iterator_type) const_iterator;
typedef BOOST_INTRUSIVE_IMPDEF(boost::intrusive::detail::reverse_iterator<iterator>) reverse_iterator;
typedef BOOST_INTRUSIVE_IMPDEF(boost::intrusive::detail::reverse_iterator<const_iterator>) const_reverse_iterator;
typedef BOOST_INTRUSIVE_IMPDEF(typename real_value_traits::node_traits) node_traits;
typedef BOOST_INTRUSIVE_IMPDEF(typename value_traits::node_traits) node_traits;
typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::node) node;
typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::node_ptr) node_ptr;
typedef BOOST_INTRUSIVE_IMPDEF(typename node_traits::const_node_ptr) const_node_ptr;
@ -567,17 +590,17 @@ class bstree_impl
typedef BOOST_INTRUSIVE_IMPDEF(algo_type) node_algorithms;
static const bool constant_time_size = ConstantTimeSize;
static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
/// @cond
private:
//noncopyable
BOOST_MOVABLE_BUT_NOT_COPYABLE(bstree_impl)
static const bool safemode_or_autounlink = is_safe_autounlink<real_value_traits::link_mode>::value;
static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
//Constant-time size is incompatible with auto-unlink hooks!
BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink)));
BOOST_STATIC_ASSERT(!(constant_time_size && ((int)value_traits::link_mode == (int)auto_unlink)));
protected:
@ -599,10 +622,7 @@ class bstree_impl
explicit bstree_impl( const value_compare &cmp = value_compare()
, const value_traits &v_traits = value_traits())
: data_type(cmp, v_traits)
{
node_algorithms::init_header(this->header_ptr());
this->sz_traits().set_size(size_type(0));
}
{}
//! <b>Requires</b>: Dereferencing iterator must yield an lvalue of type value_type.
//! cmp must be a comparison function that induces a strict weak ordering.
@ -622,8 +642,6 @@ class bstree_impl
, const value_traits &v_traits = value_traits())
: data_type(cmp, v_traits)
{
node_algorithms::init_header(this->header_ptr());
this->sz_traits().set_size(size_type(0));
if(unique)
this->insert_unique(b, e);
else
@ -633,10 +651,8 @@ class bstree_impl
//! <b>Effects</b>: to-do
//!
bstree_impl(BOOST_RV_REF(bstree_impl) x)
: data_type(::boost::move(x.comp()), ::boost::move(x.val_traits()))
: data_type(::boost::move(x.comp()), ::boost::move(x.get_value_traits()))
{
node_algorithms::init_header(this->header_ptr());
this->sz_traits().set_size(size_type(0));
this->swap(x);
}
@ -758,8 +774,8 @@ class bstree_impl
//! <b>Complexity</b>: Constant.
static bstree_impl &container_from_end_iterator(iterator end_iterator)
{
return *static_cast<bstree_impl*>
(boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()));
return static_cast<bstree_impl&>
(data_type::get_tree_base_from_root(*boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node())));
}
//! <b>Precondition</b>: end_iterator must be a valid end const_iterator
@ -772,8 +788,8 @@ class bstree_impl
//! <b>Complexity</b>: Constant.
static const bstree_impl &container_from_end_iterator(const_iterator end_iterator)
{
return *static_cast<const bstree_impl*>
(boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node()));
return static_cast<bstree_impl&>
(data_type::get_tree_base_from_root(*boost::intrusive::detail::to_raw_pointer(end_iterator.pointed_node())));
}
//! <b>Precondition</b>: it must be a valid iterator
@ -814,14 +830,22 @@ class bstree_impl
//! <b>Throws</b>: If value_compare copy-constructor throws.
value_compare value_comp() const;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! <b>Effects</b>: Returns true if the container is empty.
//!
//! <b>Complexity</b>: Constant.
//!
//! <b>Throws</b>: Nothing.
bool empty() const;
#endif //#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
bool empty() const
{
if(ConstantTimeSize){
return !this->data_type::sz_traits().get_size();
}
else{
return algo_type::unique(this->header_ptr());
}
}
//! <b>Effects</b>: Returns the number of elements stored in the container.
//!
@ -881,8 +905,8 @@ class bstree_impl
node_algorithms::clone
(const_node_ptr(src.header_ptr())
,node_ptr(this->header_ptr())
,detail::node_cloner <Cloner, real_value_traits, AlgoType>(cloner, &this->get_real_value_traits())
,detail::node_disposer<Disposer, real_value_traits, AlgoType>(disposer, &this->get_real_value_traits()));
,detail::node_cloner <Cloner, value_traits, AlgoType>(cloner, &this->get_value_traits())
,detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits()));
this->sz_traits().set_size(src.sz_traits().get_size());
this->comp() = src.comp();
rollback.release();
@ -902,13 +926,13 @@ class bstree_impl
//! No copy-constructors are called.
iterator insert_equal(reference value)
{
detail::key_nodeptr_comp<value_compare, real_value_traits>
key_node_comp(this->comp(), &this->get_real_value_traits());
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
detail::key_nodeptr_comp<value_compare, value_traits>
key_node_comp(this->comp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
iterator ret(node_algorithms::insert_equal_upper_bound
(this->header_ptr(), to_insert, key_node_comp), this->real_value_traits_ptr());
(this->header_ptr(), to_insert, key_node_comp), this->value_traits_ptr());
this->sz_traits().increment();
return ret;
}
@ -929,13 +953,13 @@ class bstree_impl
//! No copy-constructors are called.
iterator insert_equal(const_iterator hint, reference value)
{
detail::key_nodeptr_comp<value_compare, real_value_traits>
key_node_comp(this->comp(), &this->get_real_value_traits());
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
detail::key_nodeptr_comp<value_compare, value_traits>
key_node_comp(this->comp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
iterator ret(node_algorithms::insert_equal
(this->header_ptr(), hint.pointed_node(), to_insert, key_node_comp), this->real_value_traits_ptr());
(this->header_ptr(), hint.pointed_node(), to_insert, key_node_comp), this->value_traits_ptr());
this->sz_traits().increment();
return ret;
}
@ -1127,13 +1151,13 @@ class bstree_impl
//! erased between the "insert_check" and "insert_commit" calls.
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
{
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
node_algorithms::insert_unique_commit
(this->header_ptr(), to_insert, commit_data);
this->sz_traits().increment();
return iterator(to_insert, this->real_value_traits_ptr());
return iterator(to_insert, this->value_traits_ptr());
}
//! <b>Requires</b>: value must be an lvalue, "pos" must be
@ -1152,12 +1176,12 @@ class bstree_impl
//! by advanced users.
iterator insert_before(const_iterator pos, reference value)
{
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->sz_traits().increment();
return iterator(node_algorithms::insert_before
(this->header_ptr(), pos.pointed_node(), to_insert), this->real_value_traits_ptr());
(this->header_ptr(), pos.pointed_node(), to_insert), this->value_traits_ptr());
}
//! <b>Requires</b>: value must be an lvalue, and it must be no less
@ -1176,7 +1200,7 @@ class bstree_impl
//! by advanced users.
void push_back(reference value)
{
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->sz_traits().increment();
@ -1199,7 +1223,7 @@ class bstree_impl
//! by advanced users.
void push_front(reference value)
{
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
this->sz_traits().increment();
@ -1293,7 +1317,7 @@ class bstree_impl
{
node_ptr to_erase(i.pointed_node());
iterator ret(this->erase(i));
disposer(this->get_real_value_traits().to_value_ptr(to_erase));
disposer(this->get_value_traits().to_value_ptr(to_erase));
return ret;
}
@ -1401,20 +1425,19 @@ class bstree_impl
void clear_and_dispose(Disposer disposer)
{
node_algorithms::clear_and_dispose(this->header_ptr()
, detail::node_disposer<Disposer, real_value_traits, AlgoType>(disposer, &this->get_real_value_traits()));
, detail::node_disposer<Disposer, value_traits, AlgoType>(disposer, &this->get_value_traits()));
node_algorithms::init_header(this->header_ptr());
this->sz_traits().set_size(0);
}
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! <b>Effects</b>: Returns the number of contained elements with the given value
//!
//! <b>Complexity</b>: Logarithmic to the number of elements contained plus lineal
//! to number of objects with the given value.
//!
//! <b>Throws</b>: If `value_compare` throws.
size_type count(const_reference value) const;
size_type count(const_reference value) const
{ return size_type(this->count(value, this->comp())); }
//! <b>Effects</b>: Returns the number of contained elements with the given key
//!
@ -1423,7 +1446,27 @@ class bstree_impl
//!
//! <b>Throws</b>: If `comp` throws.
template<class KeyType, class KeyValueCompare>
size_type count(const KeyType &key, KeyValueCompare comp) const;
size_type count(const KeyType &key, KeyValueCompare comp) const
{
std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
return size_type(std::distance(ret.first, ret.second));
}
#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//Add non-const overloads to theoretically const members
//as some algorithms have different behavior when non-const versions are used (like splay trees).
size_type count(const_reference value)
{ return size_type(this->count(value, this->comp())); }
template<class KeyType, class KeyValueCompare>
size_type count(const KeyType &key, KeyValueCompare comp)
{
std::pair<const_iterator, const_iterator> ret = this->equal_range(key, comp);
return size_type(std::distance(ret.first, ret.second));
}
#else //defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
//! <b>Effects</b>: Returns an iterator to the first element whose
//! key is not less than k or end() if that element does not exist.
@ -1741,7 +1784,7 @@ class bstree_impl
this->sz_traits().decrement();
if(safemode_or_autounlink)//If this is commented does not work with normal_link
node_algorithms::init(to_be_disposed);
return this->get_real_value_traits().to_value_ptr(to_be_disposed);
return this->get_value_traits().to_value_ptr(to_be_disposed);
}
#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED)
@ -2016,12 +2059,11 @@ class bstree
public:
typedef typename Base::value_compare value_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::real_value_traits real_value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
bstree( const value_compare &cmp = value_compare()
, const value_traits &v_traits = value_traits())

View File

@ -173,6 +173,19 @@ class bstree_algorithms
static node_ptr end_node(const const_node_ptr & header)
{ return detail::uncast(header); }
//! <b>Requires</b>: 'header' is the header node of a tree.
//!
//! <b>Effects</b>: Returns the root of the tree if any, header otherwise
//!
//! <b>Complexity</b>: Constant time.
//!
//! <b>Throws</b>: Nothing.
static node_ptr root_node(const const_node_ptr & header)
{
node_ptr p = node_traits::get_parent(header);
return p ? p : detail::uncast(header);
}
//! <b>Requires</b>: 'node' is a node of the tree or a node initialized
//! by init(...) or init_node.
//!

View File

@ -175,27 +175,27 @@ template<class BucketValueTraits, bool IsConst>
class hashtable_iterator
: public std::iterator
< std::forward_iterator_tag
, typename BucketValueTraits::real_value_traits::value_type
, typename pointer_traits<typename BucketValueTraits::real_value_traits::value_type*>::difference_type
, typename BucketValueTraits::value_traits::value_type
, typename pointer_traits<typename BucketValueTraits::value_traits::value_type*>::difference_type
, typename detail::add_const_if_c
<typename BucketValueTraits::real_value_traits::value_type, IsConst>::type *
<typename BucketValueTraits::value_traits::value_type, IsConst>::type *
, typename detail::add_const_if_c
<typename BucketValueTraits::real_value_traits::value_type, IsConst>::type &
<typename BucketValueTraits::value_traits::value_type, IsConst>::type &
>
{
typedef typename BucketValueTraits::real_value_traits real_value_traits;
typedef typename BucketValueTraits::real_bucket_traits real_bucket_traits;
typedef typename real_value_traits::node_traits node_traits;
typedef typename BucketValueTraits::value_traits value_traits;
typedef typename BucketValueTraits::bucket_traits bucket_traits;
typedef typename value_traits::node_traits node_traits;
typedef typename detail::get_slist_impl
<typename detail::reduced_slist_node_traits
<typename real_value_traits::node_traits>::type
<typename value_traits::node_traits>::type
>::type slist_impl;
typedef typename slist_impl::iterator siterator;
typedef typename slist_impl::const_iterator const_siterator;
typedef detail::bucket_impl<slist_impl> bucket_type;
typedef typename pointer_traits
<typename real_value_traits::pointer>::template rebind_pointer
<typename value_traits::pointer>::template rebind_pointer
< const BucketValueTraits >::type const_bucketvaltraits_ptr;
typedef typename slist_impl::size_type size_type;
@ -207,7 +207,7 @@ class hashtable_iterator
}
public:
typedef typename real_value_traits::value_type value_type;
typedef typename value_traits::value_type value_type;
typedef typename detail::add_const_if_c<value_type, IsConst>::type *pointer;
typedef typename detail::add_const_if_c<value_type, IsConst>::type &reference;
@ -250,23 +250,23 @@ class hashtable_iterator
pointer operator->() const
{
return boost::intrusive::detail::to_raw_pointer(this->priv_real_value_traits().to_value_ptr
return boost::intrusive::detail::to_raw_pointer(this->priv_value_traits().to_value_ptr
(downcast_bucket(slist_it_.pointed_node())));
}
const const_bucketvaltraits_ptr &get_bucket_value_traits() const
{ return traitsptr_; }
const real_value_traits &priv_real_value_traits() const
{ return traitsptr_->priv_real_value_traits(); }
const value_traits &priv_value_traits() const
{ return traitsptr_->priv_value_traits(); }
const real_bucket_traits &priv_real_bucket_traits() const
{ return traitsptr_->priv_real_bucket_traits(); }
const bucket_traits &priv_bucket_traits() const
{ return traitsptr_->priv_bucket_traits(); }
private:
void increment()
{
const real_bucket_traits &rbuck_traits = this->priv_real_bucket_traits();
const bucket_traits &rbuck_traits = this->priv_bucket_traits();
bucket_type* const buckets = boost::intrusive::detail::to_raw_pointer(rbuck_traits.bucket_begin());
const size_type buckets_len = rbuck_traits.bucket_count();

View File

@ -89,8 +89,6 @@ struct TRAITS_PREFIX##_bool_is_true\
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_base_hook, hooktags::is_base_hook)
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_any_hook, is_any_hook)
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(external_value_traits, external_value_traits)
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(external_bucket_traits, external_bucket_traits)
BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(resizable, resizable)
template <class T>
@ -163,8 +161,8 @@ struct size_holder
SizeType size_;
};
template<class SizeType>
struct size_holder<false, SizeType>
template<class SizeType, class Tag>
struct size_holder<false, SizeType, Tag>
{
static const bool constant_time_size = false;
typedef SizeType size_type;

File diff suppressed because it is too large Load Diff

View File

@ -65,37 +65,32 @@ template <class ValueTraits, class SizeType, bool ConstantTimeSize>
class list_impl
: private detail::clear_on_destructor_base
< list_impl<ValueTraits, SizeType, ConstantTimeSize>
, is_safe_autounlink<detail::get_real_value_traits<ValueTraits>::type::link_mode>::value
, is_safe_autounlink<ValueTraits::link_mode>::value
>
{
template<class C, bool> friend class detail::clear_on_destructor_base;
//Public typedefs
public:
typedef ValueTraits value_traits;
/// @cond
static const bool external_value_traits =
detail::external_value_traits_bool_is_true<value_traits>::value;
typedef typename detail::get_real_value_traits<ValueTraits>::type real_value_traits;
/// @endcond
typedef typename real_value_traits::pointer pointer;
typedef typename real_value_traits::const_pointer const_pointer;
typedef ValueTraits value_traits;
typedef typename value_traits::pointer pointer;
typedef typename value_traits::const_pointer const_pointer;
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 SizeType size_type;
typedef list_iterator<real_value_traits, false> iterator;
typedef list_iterator<real_value_traits, true> const_iterator;
typedef list_iterator<value_traits, false> iterator;
typedef list_iterator<value_traits, true> const_iterator;
typedef boost::intrusive::detail::reverse_iterator<iterator> reverse_iterator;
typedef boost::intrusive::detail::reverse_iterator<const_iterator>const_reverse_iterator;
typedef typename real_value_traits::node_traits node_traits;
typedef typename value_traits::node_traits node_traits;
typedef typename node_traits::node node;
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef circular_list_algorithms<node_traits> node_algorithms;
static const bool constant_time_size = ConstantTimeSize;
static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
/// @cond
@ -105,11 +100,11 @@ class list_impl
//noncopyable
BOOST_MOVABLE_BUT_NOT_COPYABLE(list_impl)
static const bool safemode_or_autounlink = is_safe_autounlink<real_value_traits::link_mode>::value;
static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
//Constant-time size is incompatible with auto-unlink hooks!
BOOST_STATIC_ASSERT(!(constant_time_size &&
((int)real_value_traits::link_mode == (int)auto_unlink)
((int)value_traits::link_mode == (int)auto_unlink)
));
node_ptr get_root_node()
@ -139,54 +134,27 @@ class list_impl
const size_traits &priv_size_traits() const
{ return data_.root_plus_size_; }
const real_value_traits &get_real_value_traits(detail::bool_<false>) const
{ return data_; }
const real_value_traits &get_real_value_traits(detail::bool_<true>) const
{ return data_.get_value_traits(*this); }
real_value_traits &get_real_value_traits(detail::bool_<false>)
{ return data_; }
real_value_traits &get_real_value_traits(detail::bool_<true>)
{ return data_.get_value_traits(*this); }
const value_traits &priv_value_traits() const
{ return data_; }
value_traits &priv_value_traits()
{ return data_; }
protected:
node &prot_root_node()
{ return data_.root_plus_size_.root_; }
typedef typename pointer_traits<node_ptr>::template
rebind_pointer<value_traits const>::type const_value_traits_ptr;
node const &prot_root_node() const
{ return data_.root_plus_size_.root_; }
void prot_set_size(size_type s)
{ data_.root_plus_size_.set_size(s); }
const_value_traits_ptr value_traits_ptr() const
{ return pointer_traits<const_value_traits_ptr>::pointer_to(this->priv_value_traits()); }
/// @endcond
public:
const real_value_traits &get_real_value_traits() const
{ return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
real_value_traits &get_real_value_traits()
{ return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
typedef typename pointer_traits<node_ptr>::template rebind_pointer<real_value_traits const>::type const_real_value_traits_ptr;
const_real_value_traits_ptr real_value_traits_ptr() const
{ return pointer_traits<const_real_value_traits_ptr>::pointer_to(this->get_real_value_traits()); }
//! <b>Effects</b>: constructs an empty list.
//!
//! <b>Complexity</b>: Constant
//!
//! <b>Throws</b>: If real_value_traits::node_traits::node
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks).
explicit list_impl(const value_traits &v_traits = value_traits())
: data_(v_traits)
@ -201,7 +169,7 @@ class list_impl
//!
//! <b>Complexity</b>: Linear in std::distance(b, e). No copy constructors are called.
//!
//! <b>Throws</b>: If real_value_traits::node_traits::node
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks).
template<class Iterator>
list_impl(Iterator b, Iterator e, const value_traits &v_traits = value_traits())
@ -253,7 +221,7 @@ class list_impl
//! <b>Note</b>: Does not affect the validity of iterators and references.
void push_back(reference value)
{
node_ptr to_insert = get_real_value_traits().to_node_ptr(value);
node_ptr to_insert = priv_value_traits().to_node_ptr(value);
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
node_algorithms::link_before(this->get_root_node(), to_insert);
@ -272,7 +240,7 @@ class list_impl
//! <b>Note</b>: Does not affect the validity of iterators and references.
void push_front(reference value)
{
node_ptr to_insert = get_real_value_traits().to_node_ptr(value);
node_ptr to_insert = priv_value_traits().to_node_ptr(value);
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
node_algorithms::link_before(node_traits::get_next(this->get_root_node()), to_insert);
@ -309,7 +277,7 @@ class list_impl
this->priv_size_traits().decrement();
if(safemode_or_autounlink)
node_algorithms::init(to_erase);
disposer(get_real_value_traits().to_value_ptr(to_erase));
disposer(priv_value_traits().to_value_ptr(to_erase));
}
//! <b>Effects</b>: Erases the first element of the list.
@ -342,7 +310,7 @@ class list_impl
this->priv_size_traits().decrement();
if(safemode_or_autounlink)
node_algorithms::init(to_erase);
disposer(get_real_value_traits().to_value_ptr(to_erase));
disposer(priv_value_traits().to_value_ptr(to_erase));
}
//! <b>Effects</b>: Returns a reference to the first element of the list.
@ -351,7 +319,7 @@ class list_impl
//!
//! <b>Complexity</b>: Constant.
reference front()
{ return *get_real_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); }
{ return *priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); }
//! <b>Effects</b>: Returns a const_reference to the first element of the list.
//!
@ -359,7 +327,7 @@ class list_impl
//!
//! <b>Complexity</b>: Constant.
const_reference front() const
{ return *get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); }
{ return *priv_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); }
//! <b>Effects</b>: Returns a reference to the last element of the list.
//!
@ -367,7 +335,7 @@ class list_impl
//!
//! <b>Complexity</b>: Constant.
reference back()
{ return *get_real_value_traits().to_value_ptr(node_traits::get_previous(this->get_root_node())); }
{ return *priv_value_traits().to_value_ptr(node_traits::get_previous(this->get_root_node())); }
//! <b>Effects</b>: Returns a const_reference to the last element of the list.
//!
@ -375,7 +343,7 @@ class list_impl
//!
//! <b>Complexity</b>: Constant.
const_reference back() const
{ return *get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_previous(this->get_root_node()))); }
{ return *priv_value_traits().to_value_ptr(detail::uncast(node_traits::get_previous(this->get_root_node()))); }
//! <b>Effects</b>: Returns an iterator to the first element contained in the list.
//!
@ -383,7 +351,7 @@ class list_impl
//!
//! <b>Complexity</b>: Constant.
iterator begin()
{ return iterator(node_traits::get_next(this->get_root_node()), real_value_traits_ptr()); }
{ return iterator(node_traits::get_next(this->get_root_node()), value_traits_ptr()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
//!
@ -399,7 +367,7 @@ class list_impl
//!
//! <b>Complexity</b>: Constant.
const_iterator cbegin() const
{ return const_iterator(node_traits::get_next(this->get_root_node()), real_value_traits_ptr()); }
{ return const_iterator(node_traits::get_next(this->get_root_node()), value_traits_ptr()); }
//! <b>Effects</b>: Returns an iterator to the end of the list.
//!
@ -407,7 +375,7 @@ class list_impl
//!
//! <b>Complexity</b>: Constant.
iterator end()
{ return iterator(this->get_root_node(), real_value_traits_ptr()); }
{ return iterator(this->get_root_node(), value_traits_ptr()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the list.
//!
@ -423,7 +391,7 @@ class list_impl
//!
//! <b>Complexity</b>: Constant.
const_iterator cend() const
{ return const_iterator(detail::uncast(this->get_root_node()), real_value_traits_ptr()); }
{ return const_iterator(detail::uncast(this->get_root_node()), value_traits_ptr()); }
//! <b>Effects</b>: Returns a reverse_iterator pointing to the beginning
//! of the reversed list.
@ -663,7 +631,7 @@ class list_impl
this->priv_size_traits().decrement();
if(safemode_or_autounlink)
node_algorithms::init(to_erase);
disposer(this->get_real_value_traits().to_value_ptr(to_erase));
disposer(this->priv_value_traits().to_value_ptr(to_erase));
return i.unconst();
}
@ -697,7 +665,7 @@ class list_impl
bp = node_traits::get_next(bp);
if(safemode_or_autounlink)
node_algorithms::init(to_erase);
disposer(get_real_value_traits().to_value_ptr(to_erase));
disposer(priv_value_traits().to_value_ptr(to_erase));
this->priv_size_traits().decrement();
}
return e.unconst();
@ -743,7 +711,7 @@ class list_impl
++it;
if(safemode_or_autounlink)
node_algorithms::init(to_erase);
disposer(get_real_value_traits().to_value_ptr(to_erase));
disposer(priv_value_traits().to_value_ptr(to_erase));
}
node_algorithms::init_header(this->get_root_node());
this->priv_size_traits().set_size(0);
@ -789,12 +757,12 @@ class list_impl
//! <b>Note</b>: Does not affect the validity of iterators and references.
iterator insert(const_iterator p, reference value)
{
node_ptr to_insert = this->get_real_value_traits().to_node_ptr(value);
node_ptr to_insert = this->priv_value_traits().to_node_ptr(value);
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
node_algorithms::link_before(p.pointed_node(), to_insert);
this->priv_size_traits().increment();
return iterator(to_insert, real_value_traits_ptr());
return iterator(to_insert, value_traits_ptr());
}
//! <b>Requires</b>: Dereferencing iterator must yield
@ -957,7 +925,7 @@ class list_impl
//! <b>Effects</b>: This function sorts the list *this according to std::less<value_type>.
//! The sort is stable, that is, the relative order of equivalent elements is preserved.
//!
//! <b>Throws</b>: If real_value_traits::node_traits::node
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
//! or std::less<value_type> throws. Basic guarantee.
//!
@ -973,7 +941,7 @@ class list_impl
//! <b>Effects</b>: This function sorts the list *this according to p. The sort is
//! stable, that is, the relative order of equivalent elements is preserved.
//!
//! <b>Throws</b>: If real_value_traits::node_traits::node
//! <b>Throws</b>: If value_traits::node_traits::node
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
//! or the predicate throws. Basic guarantee.
//!
@ -1227,8 +1195,8 @@ class list_impl
static iterator s_iterator_to(reference value)
{
BOOST_STATIC_ASSERT((!stateful_value_traits));
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value)));
return iterator(real_value_traits::to_node_ptr(value), const_real_value_traits_ptr());
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(value)));
return iterator(value_traits::to_node_ptr(value), const_value_traits_ptr());
}
//! <b>Requires</b>: value must be a const reference to a value inserted in a list.
@ -1245,8 +1213,8 @@ class list_impl
static const_iterator s_iterator_to(const_reference value)
{
BOOST_STATIC_ASSERT((!stateful_value_traits));
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(const_cast<reference> (value))));
return const_iterator(real_value_traits::to_node_ptr(const_cast<reference> (value)), const_real_value_traits_ptr());
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(const_cast<reference> (value))));
return const_iterator(value_traits::to_node_ptr(const_cast<reference> (value)), const_value_traits_ptr());
}
//! <b>Requires</b>: value must be a reference to a value inserted in a list.
@ -1260,8 +1228,8 @@ class list_impl
//! <b>Note</b>: Iterators and references are not invalidated.
iterator iterator_to(reference value)
{
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(value)));
return iterator(real_value_traits::to_node_ptr(value), real_value_traits_ptr());
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(value)));
return iterator(value_traits::to_node_ptr(value), value_traits_ptr());
}
//! <b>Requires</b>: value must be a const reference to a value inserted in a list.
@ -1275,8 +1243,8 @@ class list_impl
//! <b>Note</b>: Iterators and references are not invalidated.
const_iterator iterator_to(const_reference value) const
{
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(real_value_traits::to_node_ptr(const_cast<reference> (value))));
return const_iterator(real_value_traits::to_node_ptr(const_cast<reference> (value)), real_value_traits_ptr());
BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::inited(value_traits::to_node_ptr(const_cast<reference> (value))));
return const_iterator(value_traits::to_node_ptr(const_cast<reference> (value)), value_traits_ptr());
}
/// @cond
@ -1468,9 +1436,8 @@ class list
Options...
#endif
>::type Base;
typedef typename Base::real_value_traits real_value_traits;
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
BOOST_MOVABLE_BUT_NOT_COPYABLE(list)
public:

View File

@ -51,27 +51,6 @@ BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_bstree_hook);
#undef BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION
template <class ValueTraits>
struct eval_value_traits
{
typedef typename ValueTraits::value_traits type;
};
template<class ValueTraits>
struct get_real_value_traits
: public eval_if_c
< external_value_traits_bool_is_true<ValueTraits>::value
, eval_value_traits<ValueTraits>
, identity<ValueTraits>
>
{};
template <class BucketTraits>
struct eval_bucket_traits
{
typedef typename BucketTraits::bucket_traits type;
};
template <class T, class BaseHook>
struct concrete_hook_base_value_traits
{

View File

@ -23,8 +23,12 @@ namespace intrusive {
template <class T>
struct priority_compare
: public std::binary_function<T, T, bool>
{
//Compatibility with std::binary_function
typedef T first_argument_type;
typedef T second_argument_type;
typedef bool result_type;
bool operator()(const T &val, const T &val2) const
{
return priority_order(val, val2);

View File

@ -483,14 +483,13 @@ class rbtree
public:
typedef typename Base::value_compare value_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::real_value_traits real_value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
typedef typename Base::reverse_iterator reverse_iterator;
typedef typename Base::const_reverse_iterator const_reverse_iterator;
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
explicit rbtree( const value_compare &cmp = value_compare()
, const value_traits &v_traits = value_traits())

View File

@ -226,7 +226,6 @@ class sgtree_impl
typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
, true, SgTreeAlgorithms> tree_type;
typedef tree_type implementation_defined;
typedef typename tree_type::real_value_traits real_value_traits;
/// @endcond
@ -263,11 +262,11 @@ class sgtree_impl
typedef typename alpha_traits::multiply_by_alpha_t multiply_by_alpha_t;
BOOST_MOVABLE_BUT_NOT_COPYABLE(sgtree_impl)
BOOST_STATIC_ASSERT(((int)real_value_traits::link_mode != (int)auto_unlink));
BOOST_STATIC_ASSERT(((int)value_traits::link_mode != (int)auto_unlink));
enum { safemode_or_autounlink =
(int)real_value_traits::link_mode == (int)auto_unlink ||
(int)real_value_traits::link_mode == (int)safe_link };
(int)value_traits::link_mode == (int)auto_unlink ||
(int)value_traits::link_mode == (int)safe_link };
/// @endcond
@ -412,9 +411,9 @@ class sgtree_impl
//! @copydoc ::boost::intrusive::bstree::insert_equal(reference)
iterator insert_equal(reference value)
{
detail::key_nodeptr_comp<value_compare, real_value_traits>
key_node_comp(this->value_comp(), &this->get_real_value_traits());
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
detail::key_nodeptr_comp<value_compare, value_traits>
key_node_comp(this->value_comp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
@ -423,15 +422,15 @@ class sgtree_impl
, (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
this->tree_type::sz_traits().increment();
this->max_tree_size_ = (size_type)max_tree_size;
return iterator(p, this->real_value_traits_ptr());
return iterator(p, this->value_traits_ptr());
}
//! @copydoc ::boost::intrusive::bstree::insert_equal(const_iterator,reference)
iterator insert_equal(const_iterator hint, reference value)
{
detail::key_nodeptr_comp<value_compare, real_value_traits>
key_node_comp(this->value_comp(), &this->get_real_value_traits());
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
detail::key_nodeptr_comp<value_compare, value_traits>
key_node_comp(this->value_comp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
@ -440,7 +439,7 @@ class sgtree_impl
, (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size);
this->tree_type::sz_traits().increment();
this->max_tree_size_ = (size_type)max_tree_size;
return iterator(p, this->real_value_traits_ptr());
return iterator(p, this->value_traits_ptr());
}
//! @copydoc ::boost::intrusive::bstree::insert_equal(Iterator,Iterator)
@ -477,12 +476,12 @@ class sgtree_impl
std::pair<iterator, bool> insert_unique_check
(const KeyType &key, KeyValueCompare key_value_comp, insert_commit_data &commit_data)
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
comp(key_value_comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
comp(key_value_comp, &this->get_value_traits());
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
(this->tree_type::header_ptr(), key, comp, commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this->real_value_traits_ptr()), ret.second);
return std::pair<iterator, bool>(iterator(ret.first, this->value_traits_ptr()), ret.second);
}
//! @copydoc ::boost::intrusive::bstree::insert_unique_check(const_iterator,const KeyType&,KeyValueCompare,insert_commit_data&)
@ -491,18 +490,18 @@ class sgtree_impl
(const_iterator hint, const KeyType &key
,KeyValueCompare key_value_comp, insert_commit_data &commit_data)
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
comp(key_value_comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
comp(key_value_comp, &this->get_value_traits());
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
(this->tree_type::header_ptr(), hint.pointed_node(), key, comp, commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this->real_value_traits_ptr()), ret.second);
return std::pair<iterator, bool>(iterator(ret.first, this->value_traits_ptr()), ret.second);
}
//! @copydoc ::boost::intrusive::bstree::insert_unique_commit
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
{
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
@ -511,7 +510,7 @@ class sgtree_impl
, (std::size_t)this->size(), this->get_h_alpha_func(), max_tree_size);
this->tree_type::sz_traits().increment();
this->max_tree_size_ = (size_type)max_tree_size;
return iterator(to_insert, this->real_value_traits_ptr());
return iterator(to_insert, this->value_traits_ptr());
}
//! @copydoc ::boost::intrusive::bstree::insert_unique(Iterator,Iterator)
@ -532,7 +531,7 @@ class sgtree_impl
//! @copydoc ::boost::intrusive::bstree::insert_before
iterator insert_before(const_iterator pos, reference value)
{
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
@ -541,13 +540,13 @@ class sgtree_impl
, (size_type)this->size(), this->get_h_alpha_func(), max_tree_size);
this->tree_type::sz_traits().increment();
this->max_tree_size_ = (size_type)max_tree_size;
return iterator(p, this->real_value_traits_ptr());
return iterator(p, this->value_traits_ptr());
}
//! @copydoc ::boost::intrusive::bstree::push_back
void push_back(reference value)
{
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
@ -561,7 +560,7 @@ class sgtree_impl
//! @copydoc ::boost::intrusive::bstree::push_front
void push_front(reference value)
{
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
std::size_t max_tree_size = (std::size_t)this->max_tree_size_;
@ -620,7 +619,7 @@ class sgtree_impl
{
node_ptr to_erase(i.pointed_node());
iterator ret(this->erase(i));
disposer(this->get_real_value_traits().to_value_ptr(to_erase));
disposer(this->get_value_traits().to_value_ptr(to_erase));
return ret;
}
@ -930,14 +929,13 @@ class sgtree
public:
typedef typename Base::value_compare value_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::real_value_traits real_value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
typedef typename Base::reverse_iterator reverse_iterator;
typedef typename Base::const_reverse_iterator const_reverse_iterator;
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
explicit sgtree( const value_compare &cmp = value_compare()
, const value_traits &v_traits = value_traits())

View File

@ -101,34 +101,29 @@ template<class ValueTraits, class SizeType, std::size_t BoolFlags>
class slist_impl
: private detail::clear_on_destructor_base
< slist_impl<ValueTraits, SizeType, BoolFlags>
, is_safe_autounlink<detail::get_real_value_traits<ValueTraits>::type::link_mode>::value
, is_safe_autounlink<ValueTraits::link_mode>::value
>
{
template<class C, bool> friend class detail::clear_on_destructor_base;
//Public typedefs
public:
typedef ValueTraits value_traits;
/// @cond
static const bool external_value_traits =
detail::external_value_traits_bool_is_true<value_traits>::value;
typedef typename detail::get_real_value_traits<ValueTraits>::type real_value_traits;
/// @endcond
typedef typename real_value_traits::pointer pointer;
typedef typename real_value_traits::const_pointer const_pointer;
typedef typename value_traits::pointer pointer;
typedef typename value_traits::const_pointer const_pointer;
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 SizeType size_type;
typedef slist_iterator<real_value_traits, false> iterator;
typedef slist_iterator<real_value_traits, true> const_iterator;
typedef typename real_value_traits::node_traits node_traits;
typedef slist_iterator<value_traits, false> iterator;
typedef slist_iterator<value_traits, true> const_iterator;
typedef typename value_traits::node_traits node_traits;
typedef typename node_traits::node node;
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr;
static const bool constant_time_size = 0 != (BoolFlags & slist_bool_flags::constant_time_size_pos);
static const bool stateful_value_traits = detail::is_stateful_value_traits<real_value_traits>::value;
static const bool stateful_value_traits = detail::is_stateful_value_traits<value_traits>::value;
static const bool linear = 0 != (BoolFlags & slist_bool_flags::linear_pos);
static const bool cache_last = 0 != (BoolFlags & slist_bool_flags::cache_last_pos);
@ -145,14 +140,14 @@ class slist_impl
//noncopyable
BOOST_MOVABLE_BUT_NOT_COPYABLE(slist_impl)
static const bool safemode_or_autounlink = is_safe_autounlink<real_value_traits::link_mode>::value;
static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
//Constant-time size is incompatible with auto-unlink hooks!
BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink)));
BOOST_STATIC_ASSERT(!(constant_time_size && ((int)value_traits::link_mode == (int)auto_unlink)));
//Linear singly linked lists are incompatible with auto-unlink hooks!
BOOST_STATIC_ASSERT(!(linear && ((int)real_value_traits::link_mode == (int)auto_unlink)));
BOOST_STATIC_ASSERT(!(linear && ((int)value_traits::link_mode == (int)auto_unlink)));
//A list with cached last node is incompatible with auto-unlink hooks!
BOOST_STATIC_ASSERT(!(cache_last && ((int)real_value_traits::link_mode == (int)auto_unlink)));
BOOST_STATIC_ASSERT(!(cache_last && ((int)value_traits::link_mode == (int)auto_unlink)));
node_ptr get_end_node()
{ return node_ptr(linear ? node_ptr() : this->get_root_node()); }
@ -230,18 +225,6 @@ class slist_impl
const size_traits &priv_size_traits() const
{ return data_.root_plus_size_; }
const real_value_traits &get_real_value_traits(detail::bool_<false>) const
{ return data_; }
const real_value_traits &get_real_value_traits(detail::bool_<true>) const
{ return data_.get_value_traits(*this); }
real_value_traits &get_real_value_traits(detail::bool_<false>)
{ return data_; }
real_value_traits &get_real_value_traits(detail::bool_<true>)
{ return data_.get_value_traits(*this); }
const value_traits &priv_value_traits() const
{ return data_; }
@ -258,20 +241,15 @@ class slist_impl
void prot_set_size(size_type s)
{ data_.root_plus_size_.set_size(s); }
/// @endcond
public:
const real_value_traits &get_real_value_traits() const
{ return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
typedef typename pointer_traits<node_ptr>::template
rebind_pointer<const value_traits>::type const_value_traits_ptr;
real_value_traits &get_real_value_traits()
{ return this->get_real_value_traits(detail::bool_<external_value_traits>()); }
const_value_traits_ptr value_traits_ptr() const
{ return pointer_traits<const_value_traits_ptr>::pointer_to(this->priv_value_traits()); }
typedef typename pointer_traits<node_ptr>::template rebind_pointer<const real_value_traits>::type const_real_value_traits_ptr;
const_real_value_traits_ptr real_value_traits_ptr() const
{ return pointer_traits<const_real_value_traits_ptr>::pointer_to(this->get_real_value_traits()); }
/// @endcond
public:
@ -403,7 +381,7 @@ class slist_impl
++it;
if(safemode_or_autounlink)
node_algorithms::init(to_erase);
disposer(get_real_value_traits().to_value_ptr(to_erase));
disposer(priv_value_traits().to_value_ptr(to_erase));
}
this->set_default_constructed_state();
}
@ -420,7 +398,7 @@ class slist_impl
//! <b>Note</b>: Does not affect the validity of iterators and references.
void push_front(reference value)
{
node_ptr to_insert = get_real_value_traits().to_node_ptr(value);
node_ptr to_insert = priv_value_traits().to_node_ptr(value);
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(to_insert));
if(cache_last){
@ -446,7 +424,7 @@ class slist_impl
void push_back(reference value)
{
BOOST_STATIC_ASSERT((cache_last));
node_ptr n = get_real_value_traits().to_node_ptr(value);
node_ptr n = priv_value_traits().to_node_ptr(value);
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
node_algorithms::link_after(this->get_last_node(), n);
@ -485,7 +463,7 @@ class slist_impl
this->priv_size_traits().decrement();
if(safemode_or_autounlink)
node_algorithms::init(to_erase);
disposer(get_real_value_traits().to_value_ptr(to_erase));
disposer(priv_value_traits().to_value_ptr(to_erase));
if(cache_last){
if(this->empty()){
this->set_last_node(this->get_root_node());
@ -499,7 +477,7 @@ class slist_impl
//!
//! <b>Complexity</b>: Constant.
reference front()
{ return *this->get_real_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); }
{ return *this->priv_value_traits().to_value_ptr(node_traits::get_next(this->get_root_node())); }
//! <b>Effects</b>: Returns a const_reference to the first element of the list.
//!
@ -507,7 +485,7 @@ class slist_impl
//!
//! <b>Complexity</b>: Constant.
const_reference front() const
{ return *this->get_real_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); }
{ return *this->priv_value_traits().to_value_ptr(detail::uncast(node_traits::get_next(this->get_root_node()))); }
//! <b>Effects</b>: Returns a reference to the last element of the list.
//!
@ -520,7 +498,7 @@ class slist_impl
reference back()
{
BOOST_STATIC_ASSERT((cache_last));
return *this->get_real_value_traits().to_value_ptr(this->get_last_node());
return *this->priv_value_traits().to_value_ptr(this->get_last_node());
}
//! <b>Effects</b>: Returns a const_reference to the last element of the list.
@ -534,7 +512,7 @@ class slist_impl
const_reference back() const
{
BOOST_STATIC_ASSERT((cache_last));
return *this->get_real_value_traits().to_value_ptr(this->get_last_node());
return *this->priv_value_traits().to_value_ptr(this->get_last_node());
}
//! <b>Effects</b>: Returns an iterator to the first element contained in the list.
@ -543,7 +521,7 @@ class slist_impl
//!
//! <b>Complexity</b>: Constant.
iterator begin()
{ return iterator (node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); }
{ return iterator (node_traits::get_next(this->get_root_node()), this->value_traits_ptr()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
//!
@ -551,7 +529,7 @@ class slist_impl
//!
//! <b>Complexity</b>: Constant.
const_iterator begin() const
{ return const_iterator (node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); }
{ return const_iterator (node_traits::get_next(this->get_root_node()), this->value_traits_ptr()); }
//! <b>Effects</b>: Returns a const_iterator to the first element contained in the list.
//!
@ -559,7 +537,7 @@ class slist_impl
//!
//! <b>Complexity</b>: Constant.
const_iterator cbegin() const
{ return const_iterator(node_traits::get_next(this->get_root_node()), this->real_value_traits_ptr()); }
{ return const_iterator(node_traits::get_next(this->get_root_node()), this->value_traits_ptr()); }
//! <b>Effects</b>: Returns an iterator to the end of the list.
//!
@ -567,7 +545,7 @@ class slist_impl
//!
//! <b>Complexity</b>: Constant.
iterator end()
{ return iterator(this->get_end_node(), this->real_value_traits_ptr()); }
{ return iterator(this->get_end_node(), this->value_traits_ptr()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the list.
//!
@ -575,7 +553,7 @@ class slist_impl
//!
//! <b>Complexity</b>: Constant.
const_iterator end() const
{ return const_iterator(detail::uncast(this->get_end_node()), this->real_value_traits_ptr()); }
{ return const_iterator(detail::uncast(this->get_end_node()), this->value_traits_ptr()); }
//! <b>Effects</b>: Returns a const_iterator to the end of the list.
//!
@ -592,7 +570,7 @@ class slist_impl
//!
//! <b>Complexity</b>: Constant.
iterator before_begin()
{ return iterator(this->get_root_node(), this->real_value_traits_ptr()); }
{ return iterator(this->get_root_node(), this->value_traits_ptr()); }
//! <b>Effects</b>: Returns an iterator that points to a position
//! before the first element. Equivalent to "end()"
@ -601,7 +579,7 @@ class slist_impl
//!
//! <b>Complexity</b>: Constant.
const_iterator before_begin() const
{ return const_iterator(detail::uncast(this->get_root_node()), this->real_value_traits_ptr()); }
{ return const_iterator(detail::uncast(this->get_root_node()), this->value_traits_ptr()); }
//! <b>Effects</b>: Returns an iterator that points to a position
//! before the first element. Equivalent to "end()"
@ -623,7 +601,7 @@ class slist_impl
{
//This function shall not be used if cache_last is not true
BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last);
return iterator (this->get_last_node(), this->real_value_traits_ptr());
return iterator (this->get_last_node(), this->value_traits_ptr());
}
//! <b>Effects</b>: Returns a const_iterator to the last element contained in the list.
@ -637,7 +615,7 @@ class slist_impl
{
//This function shall not be used if cache_last is not true
BOOST_INTRUSIVE_INVARIANT_ASSERT(cache_last);
return const_iterator (this->get_last_node(), this->real_value_traits_ptr());
return const_iterator (this->get_last_node(), this->value_traits_ptr());
}
//! <b>Effects</b>: Returns a const_iterator to the last element contained in the list.
@ -648,7 +626,7 @@ class slist_impl
//!
//! <b>Note</b>: This function is present only if cached_last<> option is true.
const_iterator clast() const
{ return const_iterator(this->get_last_node(), this->real_value_traits_ptr()); }
{ return const_iterator(this->get_last_node(), this->value_traits_ptr()); }
//! <b>Precondition</b>: end_iterator must be a valid end iterator
//! of slist.
@ -788,7 +766,7 @@ class slist_impl
//! <b>Note</b>: Does not affect the validity of iterators and references.
iterator insert_after(const_iterator prev_p, reference value)
{
node_ptr n = get_real_value_traits().to_node_ptr(value);
node_ptr n = priv_value_traits().to_node_ptr(value);
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
node_ptr prev_n(prev_p.pointed_node());
@ -797,7 +775,7 @@ class slist_impl
this->set_last_node(n);
}
this->priv_size_traits().increment();
return iterator (n, this->real_value_traits_ptr());
return iterator (n, this->value_traits_ptr());
}
//! <b>Requires</b>: Dereferencing iterator must yield
@ -819,7 +797,7 @@ class slist_impl
size_type count = 0;
node_ptr prev_n(prev_p.pointed_node());
for (; f != l; ++f, ++count){
const node_ptr n = get_real_value_traits().to_node_ptr(*f);
const node_ptr n = priv_value_traits().to_node_ptr(*f);
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::inited(n));
node_algorithms::link_after(prev_n, n);
@ -1026,7 +1004,7 @@ class slist_impl
}
if(safemode_or_autounlink)
node_algorithms::init(to_erase);
disposer(get_real_value_traits().to_value_ptr(to_erase));
disposer(priv_value_traits().to_value_ptr(to_erase));
this->priv_size_traits().decrement();
return it.unconst();
}
@ -1045,7 +1023,7 @@ class slist_impl
node_algorithms::unlink_after(prev_n);
if(safemode_or_autounlink)
node_algorithms::init(to_erase);
disposer(real_value_traits::to_value_ptr(to_erase));
disposer(value_traits::to_value_ptr(to_erase));
return it.unconst();
}
@ -1079,7 +1057,7 @@ class slist_impl
fp = node_traits::get_next(fp);
if(safemode_or_autounlink)
node_algorithms::init(to_erase);
disposer(get_real_value_traits().to_value_ptr(to_erase));
disposer(priv_value_traits().to_value_ptr(to_erase));
this->priv_size_traits().decrement();
}
if(cache_last && (node_traits::get_next(bfp) == this->get_end_node())){
@ -1692,7 +1670,7 @@ class slist_impl
{
BOOST_STATIC_ASSERT((!stateful_value_traits));
//BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(value)));
return iterator (value_traits::to_node_ptr(value), const_real_value_traits_ptr());
return iterator (value_traits::to_node_ptr(value), const_value_traits_ptr());
}
//! <b>Requires</b>: value must be a const reference to a value inserted in a list.
@ -1710,7 +1688,7 @@ class slist_impl
{
BOOST_STATIC_ASSERT((!stateful_value_traits));
//BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast<reference> (value))));
return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), const_real_value_traits_ptr());
return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), const_value_traits_ptr());
}
//! <b>Requires</b>: value must be a reference to a value inserted in a list.
@ -1725,7 +1703,7 @@ class slist_impl
iterator iterator_to(reference value)
{
//BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(value)));
return iterator (value_traits::to_node_ptr(value), this->real_value_traits_ptr());
return iterator (value_traits::to_node_ptr(value), this->value_traits_ptr());
}
//! <b>Requires</b>: value must be a const reference to a value inserted in a list.
@ -1740,7 +1718,7 @@ class slist_impl
const_iterator iterator_to(const_reference value) const
{
//BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::inited(value_traits::to_node_ptr(const_cast<reference> (value))));
return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), this->real_value_traits_ptr());
return const_iterator (value_traits::to_node_ptr(const_cast<reference> (value)), this->value_traits_ptr());
}
//! <b>Returns</b>: The iterator to the element before i in the list.
@ -1789,11 +1767,11 @@ class slist_impl
const_iterator previous(const_iterator prev_from, const_iterator i) const
{
if(cache_last && (i.pointed_node() == this->get_end_node())){
return const_iterator(detail::uncast(this->get_last_node()), this->real_value_traits_ptr());
return const_iterator(detail::uncast(this->get_last_node()), this->value_traits_ptr());
}
return const_iterator
(node_algorithms::get_previous_node
(prev_from.pointed_node(), i.pointed_node()), this->real_value_traits_ptr());
(prev_from.pointed_node(), i.pointed_node()), this->value_traits_ptr());
}
///@cond
@ -1844,8 +1822,8 @@ class slist_impl
BOOST_INTRUSIVE_INVARIANT_ASSERT(n > 0);
BOOST_INTRUSIVE_INVARIANT_ASSERT
(size_type(std::distance
( iterator(f, this->real_value_traits_ptr())
, iterator(before_l, this->real_value_traits_ptr())))
( iterator(f, this->value_traits_ptr())
, iterator(before_l, this->value_traits_ptr())))
+1 == n);
this->priv_incorporate_after(prev_pos.pointed_node(), f, before_l);
if(constant_time_size){
@ -2171,9 +2149,8 @@ class slist
Options...
#endif
>::type Base;
typedef typename Base::real_value_traits real_value_traits;
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
BOOST_MOVABLE_BUT_NOT_COPYABLE(slist)
public:

View File

@ -76,7 +76,6 @@ class splaytree_impl
/// @cond
typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
, ConstantTimeSize, SplayTreeAlgorithms> tree_type;
typedef typename tree_type::real_value_traits real_value_traits;
typedef tree_type implementation_defined;
/// @endcond
@ -456,10 +455,10 @@ class splaytree_impl
template<class KeyType, class KeyValueCompare>
iterator splay_down(const KeyType &key, KeyValueCompare comp)
{
detail::key_nodeptr_comp<value_compare, real_value_traits>
key_node_comp(comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<value_compare, value_traits>
key_node_comp(comp, &this->get_value_traits());
node_ptr r = node_algorithms::splay_down(tree_type::header_ptr(), key, key_node_comp);
return iterator(r, this->real_value_traits_ptr());
return iterator(r, this->value_traits_ptr());
}
//! <b>Effects</b>: Rearranges the container so that if *this stores an element
@ -571,14 +570,13 @@ class splaytree
public:
typedef typename Base::value_compare value_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::real_value_traits real_value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
typedef typename Base::reverse_iterator reverse_iterator;
typedef typename Base::const_reverse_iterator const_reverse_iterator;
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
explicit splaytree( const value_compare &cmp = value_compare()
, const value_traits &v_traits = value_traits())

View File

@ -72,8 +72,8 @@ template<class ValueTraits, class VoidOrKeyComp, class VoidOrPrioComp, class Siz
#endif
class treap_impl
/// @cond
: public bstree_impl<ValueTraits, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms>
, public detail::ebo_functor_holder
: public bstree_impl<ValueTraits, VoidOrKeyComp, SizeType, ConstantTimeSize, BsTreeAlgorithms>
, public detail::ebo_functor_holder
< typename get_prio
< VoidOrPrioComp
, typename bstree_impl
@ -87,7 +87,6 @@ class treap_impl
typedef bstree_impl< ValueTraits, VoidOrKeyComp, SizeType
, ConstantTimeSize, BsTreeAlgorithms> tree_type;
typedef tree_type implementation_defined;
typedef typename tree_type::real_value_traits real_value_traits;
typedef get_prio
< VoidOrPrioComp
, typename tree_type::value_type> get_prio_type;
@ -96,7 +95,7 @@ class treap_impl
<typename get_prio_type::type> prio_base;
/// @endcond
typedef typename implementation_defined::pointer pointer;
typedef typename implementation_defined::const_pointer const_pointer;
typedef typename implementation_defined::value_type value_type;
@ -120,7 +119,7 @@ class treap_impl
static const bool constant_time_size = implementation_defined::constant_time_size;
static const bool stateful_value_traits = implementation_defined::stateful_value_traits;
static const bool safemode_or_autounlink = is_safe_autounlink<real_value_traits::link_mode>::value;
static const bool safemode_or_autounlink = is_safe_autounlink<value_traits::link_mode>::value;
/// @cond
private:
@ -217,7 +216,7 @@ class treap_impl
//!
//! <b>Throws</b>: Nothing.
iterator top()
{ return this->empty() ? this->end() : iterator(node_traits::get_parent(this->tree_type::header_ptr()), this); }
{ return this->tree_type::root(); }
//! <b>Effects</b>: Returns a const_iterator pointing to the highest priority object of the treap..
//!
@ -233,7 +232,7 @@ class treap_impl
//!
//! <b>Throws</b>: Nothing.
const_iterator ctop() const
{ return this->empty() ? this->cend() : const_iterator(node_traits::get_parent(this->tree_type::header_ptr()), this); }
{ return this->tree_type::root(); }
#ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
//! @copydoc ::boost::intrusive::bstree::rbegin()
@ -363,15 +362,15 @@ class treap_impl
//! No copy-constructors are called.
iterator insert_equal(reference value)
{
detail::key_nodeptr_comp<value_compare, real_value_traits>
key_node_comp(this->value_comp(), &this->get_real_value_traits());
detail::key_nodeptr_comp<priority_compare, real_value_traits>
key_node_pcomp(this->priv_pcomp(), &this->get_real_value_traits());
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
detail::key_nodeptr_comp<value_compare, value_traits>
key_node_comp(this->value_comp(), &this->get_value_traits());
detail::key_nodeptr_comp<priority_compare, value_traits>
key_node_pcomp(this->priv_pcomp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
iterator ret(node_algorithms::insert_equal_upper_bound
(this->tree_type::header_ptr(), to_insert, key_node_comp, key_node_pcomp), this->real_value_traits_ptr());
(this->tree_type::header_ptr(), to_insert, key_node_comp, key_node_pcomp), this->value_traits_ptr());
this->tree_type::sz_traits().increment();
return ret;
}
@ -392,15 +391,15 @@ class treap_impl
//! No copy-constructors are called.
iterator insert_equal(const_iterator hint, reference value)
{
detail::key_nodeptr_comp<value_compare, real_value_traits>
key_node_comp(this->value_comp(), &this->get_real_value_traits());
detail::key_nodeptr_comp<priority_compare, real_value_traits>
key_node_pcomp(this->priv_pcomp(), &this->get_real_value_traits());
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
detail::key_nodeptr_comp<value_compare, value_traits>
key_node_comp(this->value_comp(), &this->get_value_traits());
detail::key_nodeptr_comp<priority_compare, value_traits>
key_node_pcomp(this->priv_pcomp(), &this->get_value_traits());
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
iterator ret (node_algorithms::insert_equal
(this->tree_type::header_ptr(), hint.pointed_node(), to_insert, key_node_comp, key_node_pcomp), this->real_value_traits_ptr());
(this->tree_type::header_ptr(), hint.pointed_node(), to_insert, key_node_comp, key_node_pcomp), this->value_traits_ptr());
this->tree_type::sz_traits().increment();
return ret;
}
@ -540,14 +539,14 @@ class treap_impl
( const KeyType &key, KeyValueCompare key_value_comp
, KeyValuePrioCompare key_value_pcomp, insert_commit_data &commit_data)
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
ocomp(key_value_comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValuePrioCompare, real_value_traits>
pcomp(key_value_pcomp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
ocomp(key_value_comp, &this->get_value_traits());
detail::key_nodeptr_comp<KeyValuePrioCompare, value_traits>
pcomp(key_value_pcomp, &this->get_value_traits());
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
(this->tree_type::header_ptr(), key, ocomp, pcomp, commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this->real_value_traits_ptr()), ret.second);
return std::pair<iterator, bool>(iterator(ret.first, this->value_traits_ptr()), ret.second);
}
//! <b>Requires</b>: key_value_comp must be a comparison function that induces
@ -592,14 +591,14 @@ class treap_impl
, KeyValuePrioCompare key_value_pcomp
, insert_commit_data &commit_data)
{
detail::key_nodeptr_comp<KeyValueCompare, real_value_traits>
ocomp(key_value_comp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValuePrioCompare, real_value_traits>
pcomp(key_value_pcomp, &this->get_real_value_traits());
detail::key_nodeptr_comp<KeyValueCompare, value_traits>
ocomp(key_value_comp, &this->get_value_traits());
detail::key_nodeptr_comp<KeyValuePrioCompare, value_traits>
pcomp(key_value_pcomp, &this->get_value_traits());
std::pair<node_ptr, bool> ret =
(node_algorithms::insert_unique_check
(this->tree_type::header_ptr(), hint.pointed_node(), key, ocomp, pcomp, commit_data));
return std::pair<iterator, bool>(iterator(ret.first, this->real_value_traits_ptr()), ret.second);
return std::pair<iterator, bool>(iterator(ret.first, this->value_traits_ptr()), ret.second);
}
//! <b>Requires</b>: value must be an lvalue of type value_type. commit_data
@ -621,12 +620,12 @@ class treap_impl
//! erased between the "insert_check" and "insert_commit" calls.
iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
{
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
node_algorithms::insert_unique_commit(this->tree_type::header_ptr(), to_insert, commit_data);
this->tree_type::sz_traits().increment();
return iterator(to_insert, this->real_value_traits_ptr());
return iterator(to_insert, this->value_traits_ptr());
}
//! <b>Requires</b>: value must be an lvalue, "pos" must be
@ -645,13 +644,13 @@ class treap_impl
//! by advanced users.
iterator insert_before(const_iterator pos, reference value)
{
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
detail::key_nodeptr_comp<priority_compare, real_value_traits>
pcomp(this->priv_pcomp(), &this->get_real_value_traits());
detail::key_nodeptr_comp<priority_compare, value_traits>
pcomp(this->priv_pcomp(), &this->get_value_traits());
iterator ret (node_algorithms::insert_before
(this->tree_type::header_ptr(), pos.pointed_node(), to_insert, pcomp), this->real_value_traits_ptr());
(this->tree_type::header_ptr(), pos.pointed_node(), to_insert, pcomp), this->value_traits_ptr());
this->tree_type::sz_traits().increment();
return ret;
}
@ -672,11 +671,11 @@ class treap_impl
//! by advanced users.
void push_back(reference value)
{
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
detail::key_nodeptr_comp<priority_compare, real_value_traits>
pcomp(this->priv_pcomp(), &this->get_real_value_traits());
detail::key_nodeptr_comp<priority_compare, value_traits>
pcomp(this->priv_pcomp(), &this->get_value_traits());
node_algorithms::push_back(this->tree_type::header_ptr(), to_insert, pcomp);
this->tree_type::sz_traits().increment();
}
@ -697,11 +696,11 @@ class treap_impl
//! by advanced users.
void push_front(reference value)
{
node_ptr to_insert(this->get_real_value_traits().to_node_ptr(value));
node_ptr to_insert(this->get_value_traits().to_node_ptr(value));
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(to_insert));
detail::key_nodeptr_comp<priority_compare, real_value_traits>
pcomp(this->priv_pcomp(), &this->get_real_value_traits());
detail::key_nodeptr_comp<priority_compare, value_traits>
pcomp(this->priv_pcomp(), &this->get_value_traits());
node_algorithms::push_front(this->tree_type::header_ptr(), to_insert, pcomp);
this->tree_type::sz_traits().increment();
}
@ -721,8 +720,8 @@ class treap_impl
node_ptr to_erase(i.pointed_node());
if(safemode_or_autounlink)
BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(!node_algorithms::unique(to_erase));
detail::key_nodeptr_comp<priority_compare, real_value_traits>
key_node_pcomp(this->priv_pcomp(), &this->get_real_value_traits());
detail::key_nodeptr_comp<priority_compare, value_traits>
key_node_pcomp(this->priv_pcomp(), &this->get_value_traits());
node_algorithms::erase(this->tree_type::header_ptr(), to_erase, key_node_pcomp);
this->tree_type::sz_traits().decrement();
if(safemode_or_autounlink)
@ -796,7 +795,7 @@ class treap_impl
{
node_ptr to_erase(i.pointed_node());
iterator ret(this->erase(i));
disposer(this->get_real_value_traits().to_value_ptr(to_erase));
disposer(this->get_value_traits().to_value_ptr(to_erase));
return ret;
}
@ -898,7 +897,7 @@ class treap_impl
void clear_and_dispose(Disposer disposer)
{
node_algorithms::clear_and_dispose(this->tree_type::header_ptr()
, detail::node_disposer<Disposer, real_value_traits, TreapAlgorithms>(disposer, &this->get_real_value_traits()));
, detail::node_disposer<Disposer, value_traits, TreapAlgorithms>(disposer, &this->get_value_traits()));
node_algorithms::init_header(this->tree_type::header_ptr());
this->tree_type::sz_traits().set_size(0);
}
@ -1120,14 +1119,13 @@ class treap
typedef typename Base::value_compare value_compare;
typedef typename Base::priority_compare priority_compare;
typedef typename Base::value_traits value_traits;
typedef typename Base::real_value_traits real_value_traits;
typedef typename Base::iterator iterator;
typedef typename Base::const_iterator const_iterator;
typedef typename Base::reverse_iterator reverse_iterator;
typedef typename Base::const_reverse_iterator const_reverse_iterator;
//Assert if passed value traits are compatible with the type
BOOST_STATIC_ASSERT((detail::is_same<typename real_value_traits::value_type, T>::value));
BOOST_STATIC_ASSERT((detail::is_same<typename value_traits::value_type, T>::value));
explicit treap( const value_compare &cmp = value_compare()
, const priority_compare &pcmp = priority_compare()

View File

@ -44,6 +44,7 @@ class treap_set_impl
#endif
{
/// @cond
public:
typedef treap_impl<ValueTraits, VoidOrKeyComp, VoidOrPrioComp, SizeType, ConstantTimeSize> tree_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE(treap_set_impl)

View File

@ -1029,15 +1029,15 @@ struct make_unordered_set
typedef typename detail::get_value_traits
<T, typename packed_options::proto_value_traits>::type value_traits;
typedef typename make_real_bucket_traits
<T, true, packed_options>::type real_bucket_traits;
typedef typename make_bucket_traits
<T, true, packed_options>::type bucket_traits;
typedef unordered_set_impl
< value_traits
, typename packed_options::hash
, typename packed_options::equal
, typename packed_options::size_type
, real_bucket_traits
, bucket_traits
, (std::size_t(true)*hash_bool_flags::unique_keys_pos)
| (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
| (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)
@ -2066,15 +2066,15 @@ struct make_unordered_multiset
typedef typename detail::get_value_traits
<T, typename packed_options::proto_value_traits>::type value_traits;
typedef typename make_real_bucket_traits
<T, true, packed_options>::type real_bucket_traits;
typedef typename make_bucket_traits
<T, true, packed_options>::type bucket_traits;
typedef unordered_multiset_impl
< value_traits
, typename packed_options::hash
, typename packed_options::equal
, typename packed_options::size_type
, real_bucket_traits
, bucket_traits
, (std::size_t(false)*hash_bool_flags::unique_keys_pos)
| (std::size_t(packed_options::constant_time_size)*hash_bool_flags::constant_time_size_pos)
| (std::size_t(packed_options::power_2_buckets)*hash_bool_flags::power_2_buckets_pos)

View File

@ -31,10 +31,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "custom_bucket_traits", "cus
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "external_value_traits", "external_value_traits\external_value_traits.vcproj", "{97B69A72-B9D3-7389-17FB-74612F4A9543}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "splay_multiset", "splay_multiset\splay_multiset.vcproj", "{01E70176-B6C5-BF47-2C91-A949077BA323}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
@ -119,6 +115,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pack_options", "pack_option
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "container_size_test", "container_size_test\container_size_test.vcproj", "{9E721E26-45AF-192C-AD67-A4CC7D096497}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
@ -159,10 +159,6 @@ Global
{31C77B84-0B2C-9481-CB81-27A149F33825}.Debug.Build.0 = Debug|Win32
{31C77B84-0B2C-9481-CB81-27A149F33825}.Release.ActiveCfg = Release|Win32
{31C77B84-0B2C-9481-CB81-27A149F33825}.Release.Build.0 = Release|Win32
{97B69A72-B9D3-7389-17FB-74612F4A9543}.Debug.ActiveCfg = Debug|Win32
{97B69A72-B9D3-7389-17FB-74612F4A9543}.Debug.Build.0 = Debug|Win32
{97B69A72-B9D3-7389-17FB-74612F4A9543}.Release.ActiveCfg = Release|Win32
{97B69A72-B9D3-7389-17FB-74612F4A9543}.Release.Build.0 = Release|Win32
{01E70176-B6C5-BF47-2C91-A949077BA323}.Debug.ActiveCfg = Debug|Win32
{01E70176-B6C5-BF47-2C91-A949077BA323}.Debug.Build.0 = Debug|Win32
{01E70176-B6C5-BF47-2C91-A949077BA323}.Release.ActiveCfg = Release|Win32
@ -247,6 +243,10 @@ Global
{77F4139B-281B-F694-7CB1-3495467B4D35}.Debug.Build.0 = Debug|Win32
{77F4139B-281B-F694-7CB1-3495467B4D35}.Release.ActiveCfg = Release|Win32
{77F4139B-281B-F694-7CB1-3495467B4D35}.Release.Build.0 = Release|Win32
{9E721E26-45AF-192C-AD67-A4CC7D096497}.Debug.ActiveCfg = Debug|Win32
{9E721E26-45AF-192C-AD67-A4CC7D096497}.Debug.Build.0 = Debug|Win32
{9E721E26-45AF-192C-AD67-A4CC7D096497}.Release.ActiveCfg = Release|Win32
{9E721E26-45AF-192C-AD67-A4CC7D096497}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection

View File

@ -364,9 +364,6 @@
<File
RelativePath="..\..\..\example\doc_erasing_and_disposing.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_external_value_traits.cpp">
</File>
<File
RelativePath="..\..\..\example\doc_function_hooks.cpp">
</File>

View File

@ -2,9 +2,8 @@
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="external_value_traits"
ProjectGUID="{97B69A72-B9D3-7389-17FB-74612F4A9543}"
RootNamespace="external_value_traits"
Name="container_size_test"
ProjectGUID="{9E721E26-45AF-192C-AD67-A4CC7D096497}"
Keyword="Win32Proj">
<Platforms>
<Platform
@ -22,8 +21,6 @@
Optimization="0"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="BOOST_DATE_TIME_NO_LIB"
GeneratePreprocessedFile="0"
KeepComments="FALSE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
@ -38,11 +35,10 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/external_value_traits.exe"
OutputFile="$(OutDir)/container_size_test.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/external_value_traits.pdb"
GenerateMapFile="TRUE"
ProgramDatabaseFile="$(OutDir)/container_size_test.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
@ -75,10 +71,9 @@
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../../../"
PreprocessorDefinitions="BOOST_DATE_TIME_NO_LIB"
PreprocessorDefinitions="BOOST_DATE_TIME_NO_LIB,NDEBUG"
RuntimeLibrary="4"
DisableLanguageExtensions="FALSE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
@ -87,7 +82,7 @@
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/external_value_traits.exe"
OutputFile="$(OutDir)/container_size_test.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
@ -122,9 +117,9 @@
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{7FAFEA31-6364-FB35-16A6-77AF315C236A}">
UniqueIdentifier="{4F0C713E-750E-B78A-4373-52D2204C1ACA}">
<File
RelativePath="..\..\..\test\external_value_traits_test.cpp">
RelativePath="..\..\..\test\container_size_test.cpp">
</File>
</Filter>
</Files>

View File

@ -0,0 +1,187 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2014-2014
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <cstddef>
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/slist.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/intrusive/avl_set.hpp>
#include <boost/intrusive/bs_set.hpp>
#include <boost/intrusive/sg_set.hpp>
#include <boost/intrusive/splay_set.hpp>
#include <boost/intrusive/treap_set.hpp>
#include <boost/intrusive/unordered_set.hpp>
#include <boost/static_assert.hpp>
using namespace boost::intrusive;
template<bool Value>
struct boolean
{
static const bool value = Value;
};
template<class A, class B>
struct pow2_and_equal_sizes
{
static const std::size_t a_size = sizeof(A);
static const std::size_t b_size = sizeof(B);
static const bool a_b_sizes_equal = a_size == b_size;
static const bool value = !(a_size & (a_size - 1u));
};
template<class Hook>
struct node : Hook
{};
//Avoid testing for uncommon architectures
void test_sizes(boolean<false>, std::size_t)
{}
template<class C>
void test_iterator_sizes(C &, std::size_t size)
{
typedef typename C::iterator iterator;
typedef typename C::const_iterator const_iterator;
BOOST_TEST_EQ(sizeof(iterator), size);
BOOST_TEST_EQ(sizeof(const_iterator), size);
}
//Test sizes for common 32 and 64 bit architectures
void test_sizes(boolean<true>, std::size_t wordsize)
{
{ //list
list<node< node<list_base_hook<> > > > c;
BOOST_TEST_EQ(sizeof(c), wordsize*3);
test_iterator_sizes(c, wordsize);
}
{
list<node< node<list_base_hook<> > >, constant_time_size<false> > c;
BOOST_TEST_EQ(sizeof(c), wordsize*2);
test_iterator_sizes(c, wordsize);
}
{ //slist
slist<node< node< slist_base_hook<> > > > c;
BOOST_TEST_EQ(sizeof(c), wordsize*2);
test_iterator_sizes(c, wordsize);
}
{
slist<node< node< slist_base_hook<> > > , constant_time_size<false> > c;
BOOST_TEST_EQ(sizeof(c), wordsize*1);
test_iterator_sizes(c, wordsize);
}
{
slist<node< node< slist_base_hook<> > > , cache_last<true> > c;
BOOST_TEST_EQ(sizeof(c), wordsize*3);
test_iterator_sizes(c, wordsize);
}
{ //set
set<node< node< set_base_hook<> > > > c;
BOOST_TEST_EQ(sizeof(c), wordsize*5);
test_iterator_sizes(c, wordsize);
}
{
set<node< node< set_base_hook<> > > , constant_time_size<false> > c;
BOOST_TEST_EQ(sizeof(c), wordsize*4);
test_iterator_sizes(c, wordsize);
}
{
set<node< node< set_base_hook<optimize_size<true> > > > , constant_time_size<false> > c;
BOOST_TEST_EQ(sizeof(c), wordsize*3);
test_iterator_sizes(c, wordsize);
}
{ //avl
avl_set<node< node< avl_set_base_hook<> > > > c;
BOOST_TEST_EQ(sizeof(c), wordsize*5);
test_iterator_sizes(c, wordsize);
}
{
avl_set<node< node< avl_set_base_hook<> > > , constant_time_size<false> > c;
BOOST_TEST_EQ(sizeof(c), wordsize*4);
test_iterator_sizes(c, wordsize);
}
{
avl_set<node< node< avl_set_base_hook<optimize_size<true> > > > , constant_time_size<false> > c;
BOOST_TEST_EQ(sizeof(c), wordsize*3);
test_iterator_sizes(c, wordsize);
}
{ //splay
splay_set<node< node< bs_set_base_hook<> > > > c;
BOOST_TEST_EQ(sizeof(c), wordsize*4);
test_iterator_sizes(c, wordsize);
}
{
splay_set<node< node< bs_set_base_hook<> > > , constant_time_size<false> > c;
BOOST_TEST_EQ(sizeof(c), wordsize*3);
test_iterator_sizes(c, wordsize);
}
{ //scapegoat
sg_set<node< bs_set_base_hook<> > > c;
BOOST_TEST_EQ(sizeof(c), (wordsize*5+sizeof(float)*2));
test_iterator_sizes(c, wordsize);
}
{ //treap
treap_set<node< bs_set_base_hook<> > > c;
BOOST_TEST_EQ(sizeof(c), wordsize*4);
test_iterator_sizes(c, wordsize);
}
{
treap_set<node< bs_set_base_hook<> > , constant_time_size<false> > c;
BOOST_TEST_EQ(sizeof(c), wordsize*3);
test_iterator_sizes(c, wordsize);
}
{ //unordered
typedef unordered_set<node< unordered_set_base_hook<> > > cont_type;
cont_type::bucket_type buckets[1];
cont_type c(cont_type::bucket_traits(buckets, 1));
BOOST_TEST_EQ(sizeof(c), wordsize*3);
test_iterator_sizes(c, wordsize*2);
}
{
typedef unordered_set<node< unordered_set_base_hook<> > , power_2_buckets<true> > cont_type;
cont_type::bucket_type buckets[1];
cont_type c(cont_type::bucket_traits(buckets, 1));
BOOST_TEST_EQ(sizeof(c), wordsize*3);
test_iterator_sizes(c, wordsize*2);
}
{
typedef unordered_set<node< unordered_set_base_hook<> >, constant_time_size<false> > cont_type;
cont_type::bucket_type buckets[1];
cont_type c(cont_type::bucket_traits(buckets, 1));
BOOST_TEST_EQ(sizeof(c), wordsize*2);
test_iterator_sizes(c, wordsize*2);
}
{
typedef unordered_set<node< unordered_set_base_hook< optimize_multikey<true> > >, constant_time_size<false> > cont_type;
cont_type::bucket_type buckets[1];
cont_type c(cont_type::bucket_traits(buckets, 1));
BOOST_TEST_EQ(sizeof(c), wordsize*2);
test_iterator_sizes(c, wordsize*2);
}
{
typedef unordered_set<node< unordered_set_base_hook< optimize_multikey<true> > >, incremental<true> > cont_type;
cont_type::bucket_type buckets[1];
cont_type c(cont_type::bucket_traits(buckets, 1));
BOOST_TEST_EQ(sizeof(c), wordsize*4);
test_iterator_sizes(c, wordsize*2);
}
}
int main()
{
test_sizes(boolean< pow2_and_equal_sizes<std::size_t, void*>::value >(), sizeof(std::size_t));
return ::boost::report_errors();
}
#include <boost/intrusive/detail/config_end.hpp>

View File

@ -1,241 +0,0 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2013
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#include <boost/intrusive/list.hpp>
#include <boost/intrusive/slist.hpp>
#include <boost/intrusive/rbtree.hpp>
#include <boost/intrusive/hashtable.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <functional>
#include <vector>
using namespace boost::intrusive;
class MyClass
{
public:
int int_;
MyClass(int i = 0)
: int_(i)
{}
friend bool operator > (const MyClass &l, const MyClass &r)
{ return l.int_ > r.int_; }
friend bool operator == (const MyClass &l, const MyClass &r)
{ return l.int_ == r.int_; }
friend std::size_t hash_value(const MyClass &v)
{ return boost::hash_value(v.int_); }
};
const int NumElements = 100;
template<class NodeTraits>
struct external_traits
{
typedef NodeTraits node_traits;
typedef typename node_traits::node node;
typedef typename node_traits::node_ptr node_ptr;
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef MyClass value_type;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer<MyClass>::type pointer;
typedef typename pointer_traits<node_ptr>::
template rebind_pointer
<const MyClass>::type const_pointer;
static const link_mode_type link_mode = normal_link;
external_traits(pointer values, std::size_t NumElem)
: values_(values), node_array_(NumElem)
{}
node_ptr to_node_ptr (value_type &value)
{ return (&node_array_[0]) + (&value - values_); }
const_node_ptr to_node_ptr (const value_type &value) const
{ return &node_array_[0] + (&value - values_); }
pointer to_value_ptr(node_ptr n)
{ return values_ + (n - &node_array_[0]); }
const_pointer to_value_ptr(const_node_ptr n) const
{ return values_ + (n - &node_array_[0]); }
pointer values_;
std::vector<node> node_array_;
};
template<class NodeTraits>
struct value_traits_proxy;
template<class T>
struct traits_holder
: public T
{};
typedef value_traits_proxy<list_node_traits<void*> > list_value_traits_proxy;
typedef value_traits_proxy<slist_node_traits<void*> > slist_value_traits_proxy;
typedef value_traits_proxy<rbtree_node_traits<void*> > rbtree_value_traits_proxy;
typedef value_traits_proxy<traits_holder<slist_node_traits<void*> > > hash_value_traits_proxy;
struct uset_bucket_traits
{
private:
typedef unordered_bucket<value_traits<external_traits
<traits_holder<slist_node_traits<void*> > > > >::type bucket_type;
//Non-copyable
uset_bucket_traits(const uset_bucket_traits &other);
uset_bucket_traits & operator=(const uset_bucket_traits &other);
public:
static const std::size_t NumBuckets = 100;
uset_bucket_traits(){}
bucket_type * bucket_begin() const
{ return buckets_; }
std::size_t bucket_count() const
{ return NumBuckets; }
mutable bucket_type buckets_[NumBuckets];
};
struct bucket_traits_proxy
{
static const bool external_bucket_traits = true;
typedef uset_bucket_traits bucket_traits;
template<class Container>
bucket_traits &get_bucket_traits(Container &cont);
template<class Container>
const bucket_traits &get_bucket_traits(const Container &cont) const;
};
//Define a list that will store MyClass using the external hook
typedef list<MyClass, value_traits<list_value_traits_proxy> > List;
//Define a slist that will store MyClass using the external hook
typedef slist<MyClass, value_traits<slist_value_traits_proxy> > Slist;
//Define a rbtree that will store MyClass using the external hook
typedef rbtree< MyClass
, value_traits<rbtree_value_traits_proxy>
, compare<std::greater<MyClass> > > Rbtree;
//Define a hashtable that will store MyClass using the external hook
typedef hashtable< MyClass
, value_traits<hash_value_traits_proxy>
, bucket_traits<bucket_traits_proxy>
> Hash;
template<class NodeTraits>
struct value_traits_proxy
{
static const bool external_value_traits = true;
typedef external_traits<NodeTraits> value_traits;
template<class Container>
const value_traits &get_value_traits(const Container &cont) const;
template<class Container>
value_traits &get_value_traits(Container &cont);
};
struct ContainerHolder
: public uset_bucket_traits
, public List
, public external_traits<list_node_traits<void*> >
, public Slist
, public external_traits<slist_node_traits<void*> >
, public Rbtree
, public external_traits<rbtree_node_traits<void*> >
, public Hash
, public external_traits<traits_holder<slist_node_traits<void*> > >
{
static const std::size_t NumBucket = 100;
ContainerHolder(MyClass *values, std::size_t num_elem)
: uset_bucket_traits()
, List()
, external_traits<list_node_traits<void*> >(values, num_elem)
, Slist()
, external_traits<slist_node_traits<void*> >(values, num_elem)
, Rbtree()
, external_traits<rbtree_node_traits<void*> >(values, num_elem)
, Hash(Hash::bucket_traits())
, external_traits<traits_holder<slist_node_traits<void*> > >(values, num_elem)
{}
};
template<class NodeTraits>
template<class Container>
typename value_traits_proxy<NodeTraits>::value_traits &
value_traits_proxy<NodeTraits>::get_value_traits(Container &cont)
{ return static_cast<value_traits&>(static_cast<ContainerHolder&>(cont)); }
template<class NodeTraits>
template<class Container>
const typename value_traits_proxy<NodeTraits>::value_traits &
value_traits_proxy<NodeTraits>::get_value_traits(const Container &cont) const
{ return static_cast<const value_traits&>(static_cast<const ContainerHolder&>(cont)); }
template<class Container>
typename bucket_traits_proxy::bucket_traits &
bucket_traits_proxy::get_bucket_traits(Container &cont)
{ return static_cast<bucket_traits&>(static_cast<ContainerHolder&>(cont)); }
template<class Container>
const typename bucket_traits_proxy::bucket_traits &
bucket_traits_proxy::get_bucket_traits(const Container &cont) const
{ return static_cast<const bucket_traits&>(static_cast<const ContainerHolder&>(cont)); }
int main()
{
MyClass values [NumElements];
//Create several MyClass objects, each one with a different value
for(int i = 0; i < NumElements; ++i)
values[i].int_ = i;
ContainerHolder cont_holder(values, NumElements);
List &my_list = static_cast<List &> (cont_holder);
Slist &my_slist = static_cast<Slist &> (cont_holder);
Rbtree &my_rbtree = static_cast<Rbtree &> (cont_holder);
Hash &my_hash = static_cast<Hash &> (cont_holder);
//Now insert them in containers
for(MyClass * it(&values[0]), *itend(&values[NumElements])
; it != itend; ++it){
my_list.push_front(*it);
my_slist.push_front(*it);
my_rbtree.insert_unique(*it);
my_hash.insert_unique(*it);
}
//Now test containers
{
List::const_iterator list_it (my_list.cbegin());
Slist::const_iterator slist_it (my_slist.cbegin());
Rbtree::const_iterator rbtree_it (my_rbtree.cbegin());
Hash::const_iterator hash_it (my_hash.cbegin());
MyClass *it_val(&values[NumElements] - 1), *it_rbeg_val(&values[0]-1);
//Test inserted objects
for(; it_val != it_rbeg_val; --it_val, ++list_it, ++slist_it, ++rbtree_it){
if(&*list_it != &*it_val) return 1;
if(&*slist_it != &*it_val) return 1;
if(&*rbtree_it != &*it_val) return 1;
hash_it = my_hash.find(*it_val);
if(hash_it == my_hash.cend() || &*hash_it != &*it_val)
return 1;
}
}
return 0;
}