mirror of
https://github.com/boostorg/intrusive.git
synced 2025-05-09 23:03:56 +00:00
Fixed ABI regression introduced in Boost 1.55
This commit is contained in:
parent
f162078264
commit
2ffe6b2f82
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
//]
|
@ -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())
|
||||
|
@ -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())
|
||||
|
@ -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.
|
||||
//!
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
@ -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:
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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())
|
||||
|
@ -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())
|
||||
|
@ -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:
|
||||
|
@ -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())
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
187
test/container_size_test.cpp
Normal file
187
test/container_size_test.cpp
Normal 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>
|
@ -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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user