no message

[SVN r38075]
This commit is contained in:
Ion Gaztañaga
2007-06-23 13:01:38 +00:00
parent 2e9afca1f0
commit 7be768cf8e
22 changed files with 716 additions and 510 deletions

View File

@@ -0,0 +1,35 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2007
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_ASSERT_HPP
#define BOOST_INTRUSIVE_DETAIL_ASSERT_HPP
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
#pragma once
#endif
#if !defined(BOOST_INTRUSIVE_INVARIANT_ASSERT)
#include <boost/assert.hpp>
#define BOOST_INTRUSIVE_INVARIANT_ASSERT BOOST_ASSERT
#endif
#if !defined(BOOST_INTRUSIVE_SAFE_MODE_CONTAINER_INSERTION_ASSERT)
#include <boost/assert.hpp>
#define BOOST_INTRUSIVE_SAFE_MODE_CONTAINER_INSERTION_ASSERT BOOST_ASSERT
#endif
#if !defined(BOOST_INTRUSIVE_SAFE_MODE_HOOK_DESTRUCTOR_ASSERT)
#include <boost/assert.hpp>
#define BOOST_INTRUSIVE_SAFE_MODE_HOOK_DESTRUCTOR_ASSERT BOOST_ASSERT
#endif
#endif //BOOST_INTRUSIVE_DETAIL_ASSERT_HPP

View File

@@ -9,9 +9,18 @@
// See http://www.boost.org/libs/intrusive for documentation. // See http://www.boost.org/libs/intrusive for documentation.
// //
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_SELECT_COMPILER_INCLUDED
#ifndef BOOST_COMPILER_CONFIG
//#include <boost/config/select_compiler_config.hpp>
//#include BOOST_COMPILER_CONFIG
#include <boost/config.hpp> #include <boost/config.hpp>
#endif
#define BOOST_INTRUSIVE_SELECT_COMPILER_INCLUDED
#endif
#ifdef BOOST_MSVC #ifdef BOOST_MSVC
#pragma warning (push) #pragma warning (push)
// //
//'function' : resolved overload was found by argument-dependent lookup //'function' : resolved overload was found by argument-dependent lookup

View File

@@ -13,18 +13,18 @@
#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP #ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
#define BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP #define BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
#include <boost/type_traits/is_empty.hpp> #include <boost/intrusive/detail/mpl.hpp>
namespace boost { namespace boost {
namespace intrusive { namespace intrusive {
namespace detail { namespace detail {
template<typename T, bool IsEmpty = false> template<typename T, bool IsEmpty = true>
class ebo_holder_impl class ebo_functor_holder_impl
{ {
public: public:
ebo_holder_impl(){} ebo_functor_holder_impl(){}
ebo_holder_impl(const T& t):t(t){} ebo_functor_holder_impl(const T& t):t(t){}
T& get(){return t;} T& get(){return t;}
const T& get()const{return t;} const T& get()const{return t;}
@@ -34,29 +34,29 @@ class ebo_holder_impl
}; };
template<typename T> template<typename T>
class ebo_holder_impl<T, true> class ebo_functor_holder_impl<T, false>
: private T : private T
{ {
public: public:
ebo_holder_impl(){} ebo_functor_holder_impl(){}
ebo_holder_impl(const T& t):T(t){} ebo_functor_holder_impl(const T& t):T(t){}
T& get(){return *this;} T& get(){return *this;}
const T& get()const{return *this;} const T& get()const{return *this;}
}; };
template<typename T> template<typename T>
class ebo_holder class ebo_functor_holder
: public ebo_holder_impl<T,boost::is_empty<T>::value> : public ebo_functor_holder_impl<T, is_unary_or_binary_function<T>::value>
{ {
private: private:
typedef ebo_holder_impl<T,boost::is_empty<T>::value> super; typedef ebo_functor_holder_impl<T, is_unary_or_binary_function<T>::value> super;
public: public:
ebo_holder(){} ebo_functor_holder(){}
ebo_holder(const T& t):super(t){} ebo_functor_holder(const T& t):super(t){}
ebo_holder& operator=(const ebo_holder& x) ebo_functor_holder& operator=(const ebo_functor_holder& x)
{ {
this->get()=x.get(); this->get()=x.get();
return *this; return *this;

View File

@@ -15,7 +15,7 @@
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <iterator> #include <iterator>
#include <boost/assert.hpp> #include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp> #include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/circular_list_algorithms.hpp> #include <boost/intrusive/circular_list_algorithms.hpp>
#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE #ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE
@@ -25,6 +25,7 @@
#include <boost/utility/enable_if.hpp> #include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_convertible.hpp> #include <boost/type_traits/is_convertible.hpp>
#endif #endif
#include <boost/intrusive/detail/mpl.hpp>
#include <cstddef> #include <cstddef>
namespace boost { namespace boost {
@@ -261,9 +262,7 @@ class hashtable_iterator
#else #else
template <class OtherValue> template <class OtherValue>
hashtable_iterator(hashtable_iterator<OtherValue, SlistImpl> const& other, hashtable_iterator(hashtable_iterator<OtherValue, SlistImpl> const& other,
typename enable_if< typename enable_if<is_convertible<OtherValue*, T*> >::type* = 0)
is_convertible<OtherValue*,T*>
>::type* = 0)
: local_it_(other.local_it_), bucket_info_(other.bucket_info_) : local_it_(other.local_it_), bucket_info_(other.bucket_info_)
{} {}
#endif #endif

View File

@@ -16,7 +16,7 @@
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <iterator> #include <iterator>
#include <boost/assert.hpp> #include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp> #include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/circular_list_algorithms.hpp> #include <boost/intrusive/circular_list_algorithms.hpp>
#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE #ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE

View File

@@ -0,0 +1,177 @@
/////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2007
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
/////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_INTRUSIVE_DETAIL_MPL_HPP
#define BOOST_INTRUSIVE_DETAIL_MPL_HPP
namespace boost {
namespace intrusive {
namespace detail {
template< bool C_ >
struct bool_
{
static const bool value = C_;
};
typedef bool_<true> true_;
typedef bool_<false> false_;
typedef true_ true_type;
typedef false_ false_type;
typedef char yes_type;
struct no_type
{
char padding[8];
};
template <bool B, class T = void>
struct enable_if_c {
typedef T type;
};
template <class T>
struct enable_if_c<false, T> {};
template <class Cond, class T = void>
struct enable_if : public enable_if_c<Cond::value, T>{};
template <class T, class U>
class is_convertible
{
typedef char true_t;
class false_t { char dummy[2]; };
static true_t dispatch(U);
static false_t dispatch(...);
static T trigger();
public:
enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
};
#if defined(BOOST_MSVC) || defined(__BORLANDC_)
#define BOOST_INTRUSIVE_TT_DECL __cdecl
#else
#define BOOST_INTRUSIVE_TT_DECL
#endif
#if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__)
#define BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
#endif
no_type BOOST_INTRUSIVE_TT_DECL is_function_ptr_tester(...);
template <class R >
yes_type is_function_ptr_tester(R (*)());
template <class R >
yes_type is_function_ptr_tester(R (*)( ...));
#ifdef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
template <class R >
yes_type is_function_ptr_tester(R (__stdcall*)());
template <class R >
yes_type is_function_ptr_tester(R (__stdcall*)( ...));
template <class R >
yes_type is_function_ptr_tester(R (__fastcall*)());
template <class R >
yes_type is_function_ptr_tester(R (__fastcall*)( ...));
template <class R >
yes_type is_function_ptr_tester(R (__cdecl*)());
template <class R >
yes_type is_function_ptr_tester(R (__cdecl*)( ...));
#endif
template <class R , class T0 >
yes_type is_function_ptr_tester(R (*)( T0));
template <class R , class T0 >
yes_type is_function_ptr_tester(R (*)( T0 ...));
#ifdef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
template <class R , class T0 >
yes_type is_function_ptr_tester(R (__stdcall*)( T0));
template <class R , class T0 >
yes_type is_function_ptr_tester(R (__stdcall*)( T0 ...));
template <class R , class T0 >
yes_type is_function_ptr_tester(R (__fastcall*)( T0));
template <class R , class T0 >
yes_type is_function_ptr_tester(R (__fastcall*)( T0 ...));
template <class R , class T0 >
yes_type is_function_ptr_tester(R (__cdecl*)( T0));
#endif
template <class R , class T0 , class T1 >
yes_type is_function_ptr_tester(R (*)( T0 , T1));
#ifdef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
template <class R , class T0 , class T1 >
yes_type is_function_ptr_tester(R (__stdcall*)( T0 , T1));
template <class R , class T0 , class T1 >
yes_type is_function_ptr_tester(R (__fastcall*)( T0 , T1));
template <class R , class T0 , class T1 >
yes_type is_function_ptr_tester(R (__cdecl*)( T0 , T1));
#endif
template <typename T>
struct is_unary_or_binary_function_impl
{
static T* t;
enum{ value = sizeof(is_function_ptr_tester(t)) == sizeof(yes_type) };
};
template <typename T>
struct is_unary_or_binary_function_impl<T&>
{ enum {value = false }; };
template<typename T>
struct is_unary_or_binary_function
{
enum{ value = is_unary_or_binary_function_impl<T>::value };
};
//boost::alignment_of yields to 10K lines of preprocessed code, so we
//need an alternative
template <typename T> struct alignment_of;
template <typename T>
struct alignment_of_hack
{
char c;
T t;
alignment_of_hack();
};
template <unsigned A, unsigned S>
struct alignment_logic
{
enum{ value = A < S ? A : S };
};
template< typename T >
struct alignment_of
{
enum{ value = alignment_logic
< sizeof(alignment_of_hack<T>) - sizeof(T)
, sizeof(T)>::value };
};
} //namespace detail
} //namespace intrusive
} //namespace boost
#endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP

View File

@@ -13,7 +13,7 @@
#define BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP #define BOOST_INTRUSIVE_PARENT_FROM_MEMBER_HPP
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <cstddef>
namespace boost { namespace boost {
namespace intrusive { namespace intrusive {
namespace detail { namespace detail {
@@ -22,8 +22,7 @@ template<class Parent, class Member>
std::size_t offset_from_pointer_to_member(const Member Parent::* ptr_to_member) std::size_t offset_from_pointer_to_member(const Member Parent::* ptr_to_member)
{ {
//The implementation of a pointer to member is compiler dependent. //The implementation of a pointer to member is compiler dependent.
#if defined(BOOST_MSVC) || defined(__GNUC__) || \ #if (defined(_MSC_VER) || defined(__GNUC__) || defined(BOOST_INTEL) || defined(__HP_aCC))
defined(BOOST_INTEL) || defined(__HP_aCC)
//This works with gcc, msvc, ac++ //This works with gcc, msvc, ac++
return *(const std::size_t*)(const void*)&ptr_to_member; return *(const std::size_t*)(const void*)&ptr_to_member;
#else #else

View File

@@ -26,11 +26,10 @@
#include <boost/type_traits/is_convertible.hpp> #include <boost/type_traits/is_convertible.hpp>
#endif #endif
#include <boost/intrusive/pointer_plus_bit.hpp> #include <boost/intrusive/pointer_plus_bit.hpp>
#include <boost/type_traits/alignment_of.hpp> #include <boost/intrusive/detail/mpl.hpp>
namespace boost { namespace boost {
namespace intrusive { namespace intrusive {
namespace detail { namespace detail {
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@@ -171,7 +170,7 @@ struct rbtree_node_traits
: public rbtree_node_traits_dispatch : public rbtree_node_traits_dispatch
<VoidPointer <VoidPointer
,has_pointer_plus_bit ,has_pointer_plus_bit
<VoidPointer, boost::alignment_of<compact_rbtree_node<VoidPointer> <VoidPointer, detail::alignment_of<compact_rbtree_node<VoidPointer>
>::value >::value
>::value >::value
> >

View File

@@ -16,7 +16,7 @@
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <iterator> #include <iterator>
#include <boost/assert.hpp> #include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp> #include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/circular_slist_algorithms.hpp> #include <boost/intrusive/circular_slist_algorithms.hpp>
#ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE #ifdef BOOST_INTRUSIVE_USE_ITERATOR_FACADE

View File

@@ -16,9 +16,11 @@
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp> #include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/detail/parent_from_member.hpp> #include <boost/intrusive/detail/parent_from_member.hpp>
#include <boost/intrusive/detail/ebo_holder.hpp> #include <boost/intrusive/detail/ebo_functor_holder.hpp>
#include <boost/intrusive/linking_policy.hpp> #include <boost/intrusive/linking_policy.hpp>
#include <boost/intrusive/detail/mpl.hpp>
#include <cstddef> #include <cstddef>
#include <iterator>
namespace boost { namespace boost {
namespace intrusive { namespace intrusive {
@@ -65,7 +67,7 @@ class equal_to_value
{ return t_ == t; } { return t_ == t; }
}; };
class null_destroyer class null_disposer
{ {
public: public:
template <class Pointer> template <class Pointer>
@@ -155,8 +157,8 @@ struct member_value_traits
typedef typename node_traits::const_node_ptr const_node_ptr; typedef typename node_traits::const_node_ptr const_node_ptr;
typedef typename boost::pointer_to_other<node_ptr, T>::type pointer; typedef typename boost::pointer_to_other<node_ptr, T>::type pointer;
typedef typename boost::pointer_to_other<node_ptr, const T>::type const_pointer; typedef typename boost::pointer_to_other<node_ptr, const T>::type const_pointer;
typedef typename std::iterator_traits<pointer>::reference reference; typedef value_type & reference;
typedef typename std::iterator_traits<const_pointer>::reference const_reference; typedef const value_type & const_reference;
enum { linking_policy = MemberHookType::linking_policy }; enum { linking_policy = MemberHookType::linking_policy };
public: public:
@@ -192,10 +194,10 @@ struct member_value_traits
template<class KeyValueCompare, class ValueTraits> template<class KeyValueCompare, class ValueTraits>
struct key_node_ptr_compare struct key_node_ptr_compare
: private detail::ebo_holder<KeyValueCompare> : private detail::ebo_functor_holder<KeyValueCompare>
{ {
typedef typename ValueTraits::node_ptr node_ptr; typedef typename ValueTraits::node_ptr node_ptr;
typedef detail::ebo_holder<KeyValueCompare> base_t; typedef detail::ebo_functor_holder<KeyValueCompare> base_t;
key_node_ptr_compare(KeyValueCompare kcomp) key_node_ptr_compare(KeyValueCompare kcomp)
: base_t(kcomp) : base_t(kcomp)
{} {}
@@ -217,10 +219,10 @@ struct key_node_ptr_compare
template<class F, class ValueTraits> template<class F, class ValueTraits>
struct value_to_node_cloner struct value_to_node_cloner
: private detail::ebo_holder<F> : private detail::ebo_functor_holder<F>
{ {
typedef typename ValueTraits::node_ptr node_ptr; typedef typename ValueTraits::node_ptr node_ptr;
typedef detail::ebo_holder<F> base_t; typedef detail::ebo_functor_holder<F> base_t;
value_to_node_cloner(F f) value_to_node_cloner(F f)
: base_t(f) : base_t(f)
@@ -231,12 +233,12 @@ struct value_to_node_cloner
}; };
template<class F, class ValueTraits> template<class F, class ValueTraits>
struct value_to_node_destroyer struct value_to_node_disposer
: private detail::ebo_holder<F> : private detail::ebo_functor_holder<F>
{ {
typedef typename ValueTraits::node_ptr node_ptr; typedef typename ValueTraits::node_ptr node_ptr;
typedef detail::ebo_holder<F> base_t; typedef detail::ebo_functor_holder<F> base_t;
value_to_node_destroyer(F f) value_to_node_disposer(F f)
: base_t(f) : base_t(f)
{} {}
@@ -250,7 +252,7 @@ struct dispatcher
template<class Container> template<class Container>
void destructor_impl(Container &cont, dispatcher<safe_link>) void destructor_impl(Container &cont, dispatcher<safe_link>)
{ (void)cont; BOOST_ASSERT(!cont.is_linked()); } { (void)cont; BOOST_INTRUSIVE_SAFE_MODE_HOOK_DESTRUCTOR_ASSERT(!cont.is_linked()); }
template<class Container> template<class Container>
void destructor_impl(Container &cont, dispatcher<auto_unlink>) void destructor_impl(Container &cont, dispatcher<auto_unlink>)
@@ -262,26 +264,26 @@ void destructor_impl(Container &, dispatcher<normal_link>)
template<class Node, class MaybeClass> template<class Node, class MaybeClass>
struct node_plus_pred struct node_plus_pred
: public ebo_holder<MaybeClass> : public ebo_functor_holder<MaybeClass>
, public Node , public Node
{ {
node_plus_pred() node_plus_pred()
{} {}
node_plus_pred(const Node &x, const MaybeClass &y) node_plus_pred(const Node &x, const MaybeClass &y)
: Node(x), ebo_holder<MaybeClass>(y) {} : Node(x), ebo_functor_holder<MaybeClass>(y) {}
node_plus_pred(const MaybeClass &y) node_plus_pred(const MaybeClass &y)
: ebo_holder<MaybeClass>(y) {} : ebo_functor_holder<MaybeClass>(y) {}
Node &first() Node &first()
{ return *this; } { return *this; }
const Node &first() const const Node &first() const
{ return *this; } { return *this; }
MaybeClass &second() MaybeClass &second()
{ return ebo_holder<MaybeClass>::get(); } { return ebo_functor_holder<MaybeClass>::get(); }
const MaybeClass &second() const const MaybeClass &second() const
{ return ebo_holder<MaybeClass>::get(); } { return ebo_functor_holder<MaybeClass>::get(); }
static node_plus_pred *this_from_node(Node *n) static node_plus_pred *this_from_node(Node *n)
{ return static_cast<node_plus_pred*>(n); } { return static_cast<node_plus_pred*>(n); }
@@ -290,33 +292,6 @@ struct node_plus_pred
{ return static_cast<const node_plus_pred*>(n); } { return static_cast<const node_plus_pred*>(n); }
}; };
#ifndef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
template <bool B, class T = void>
struct enable_if_c {
typedef T type;
};
template <class T>
struct enable_if_c<false, T> {};
template <class Cond, class T = void>
struct enable_if : public enable_if_c<Cond::value, T> {};
template <class T, class U>
class is_convertible
{
typedef char true_t;
class false_t { char dummy[2]; };
static true_t dispatch(U);
static false_t dispatch(...);
static T trigger();
public:
enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
};
#endif //#ifndef BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE
} //namespace detail } //namespace detail
} //namespace intrusive } //namespace intrusive
} //namespace boost } //namespace boost

View File

@@ -17,10 +17,9 @@
#include <functional> #include <functional>
#include <utility> #include <utility>
#include <algorithm> #include <algorithm>
#include <cstddef>
//boost //boost
#include <boost/utility.hpp> #include <boost/intrusive/detail/assert.hpp>
#include <boost/compressed_pair.hpp>
#include <boost/assert.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/functional/hash.hpp> #include <boost/functional/hash.hpp>
//General intrusive utilities //General intrusive utilities
@@ -28,10 +27,10 @@
#include <boost/intrusive/detail/pointer_to_other.hpp> #include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/detail/hashtable_node.hpp> #include <boost/intrusive/detail/hashtable_node.hpp>
#include <boost/intrusive/linking_policy.hpp> #include <boost/intrusive/linking_policy.hpp>
#include <boost/intrusive/detail/ebo_functor_holder.hpp>
//Implementation utilities //Implementation utilities
#include <boost/intrusive/unordered_set_hook.hpp> #include <boost/intrusive/unordered_set_hook.hpp>
#include <boost/intrusive/slist.hpp> #include <boost/intrusive/slist.hpp>
#include <cstddef>
namespace boost { namespace boost {
namespace intrusive { namespace intrusive {
@@ -104,49 +103,66 @@ class hashtable
<pointer, const bucket_info_t>::type const_bucket_info_ptr; <pointer, const bucket_info_t>::type const_bucket_info_ptr;
//User scattered boost::compressed pair to get EBO all compilers //User scattered boost::compressed pair to get EBO all compilers
boost::compressed_pair // boost::compressed_pair
<boost::compressed_pair<bucket_info_t, Hash> // <boost::compressed_pair<bucket_info_t, Hash>
,Equal> members_; // ,Equal> members_;
struct bucket_hash_t
: public detail::ebo_functor_holder<Hash>
{
bucket_hash_t(const Hash & h)
: detail::ebo_functor_holder<Hash>(h)
{}
bucket_info_t bucket_info;
};
struct bucket_hash_equal_t
: public detail::ebo_functor_holder<Equal>
{
bucket_hash_equal_t(const Hash & h, const Equal &e)
: detail::ebo_functor_holder<Equal>(e), bucket_hash(h)
{}
bucket_hash_t bucket_hash;
} bucket_hash_equal_;
const Equal &priv_equal() const const Equal &priv_equal() const
{ return members_.second(); } { return static_cast<const Equal&>(bucket_hash_equal_.get()); }
Equal &priv_equal() Equal &priv_equal()
{ return members_.second(); } { return static_cast<Equal&>(bucket_hash_equal_.get()); }
const_bucket_info_ptr priv_bucket_info() const const bucket_info_t &priv_bucket_info() const
{ return &members_.first().first(); } { return bucket_hash_equal_.bucket_hash.bucket_info; }
bucket_info_ptr priv_bucket_info() bucket_info_t &priv_bucket_info()
{ return &members_.first().first(); } { return bucket_hash_equal_.bucket_hash.bucket_info; }
const Hash &priv_hasher() const const Hash &priv_hasher() const
{ return members_.first().second(); } { return static_cast<const Hash&>(bucket_hash_equal_.bucket_hash.get()); }
Hash &priv_hasher() Hash &priv_hasher()
{ return members_.first().second(); } { return static_cast<Hash&>(bucket_hash_equal_.bucket_hash.get()); }
const bucket_ptr &priv_buckets() const const bucket_ptr &priv_buckets() const
{ return members_.first().first().buckets_; } { return priv_bucket_info().buckets_; }
bucket_ptr &priv_buckets() bucket_ptr &priv_buckets()
{ return members_.first().first().buckets_; } { return priv_bucket_info().buckets_; }
const size_type &priv_buckets_len() const const size_type &priv_buckets_len() const
{ return members_.first().first().buckets_len_; } { return priv_bucket_info().buckets_len_; }
size_type &priv_buckets_len() size_type &priv_buckets_len()
{ return members_.first().first().buckets_len_; } { return priv_bucket_info().buckets_len_; }
static node_ptr uncast(const_node_ptr ptr) static node_ptr uncast(const_node_ptr ptr)
{ {
return node_ptr(const_cast<node*>(detail::get_pointer(ptr))); return node_ptr(const_cast<node*>(detail::get_pointer(ptr)));
} }
static bucket_info_ptr uncast(const_bucket_info_ptr ptr) // static bucket_info_ptr uncast(const_bucket_info_ptr ptr)
{ // {
return bucket_info_ptr(const_cast<bucket_info_t*>(detail::get_pointer(ptr))); // return bucket_info_ptr(const_cast<bucket_info_t*>(detail::get_pointer(ptr)));
} // }
static slist_impl &bucket_to_slist(bucket_type &b) static slist_impl &bucket_to_slist(bucket_type &b)
{ return static_cast<slist_impl &>(b); } { return static_cast<slist_impl &>(b); }
@@ -167,10 +183,10 @@ class hashtable
, size_type buckets_len , size_type buckets_len
, const Hash & hasher = Hash() , const Hash & hasher = Hash()
, const Equal &equal = Equal()) , const Equal &equal = Equal())
: members_(boost::compressed_pair<bucket_info_t, Hash>(hasher), equal) : bucket_hash_equal_(hasher, equal)
{ {
BOOST_ASSERT(buckets_len != 0); BOOST_INTRUSIVE_INVARIANT_ASSERT(buckets_len != 0);
priv_buckets() = buckets; priv_buckets() = buckets;
priv_buckets_len() = buckets_len; priv_buckets_len() = buckets_len;
priv_clear_buckets(); priv_clear_buckets();
@@ -184,7 +200,7 @@ class hashtable
{ {
size_type bucket_num; size_type bucket_num;
local_iterator local_it = priv_begin(bucket_num); local_iterator local_it = priv_begin(bucket_num);
return iterator( local_it, this->priv_bucket_info()); return iterator(local_it, const_bucket_info_ptr(&this->priv_bucket_info()));
} }
const_iterator begin() const const_iterator begin() const
@@ -194,23 +210,17 @@ class hashtable
{ {
size_type bucket_num; size_type bucket_num;
local_iterator local_it = priv_begin(bucket_num); local_iterator local_it = priv_begin(bucket_num);
return const_iterator( local_it, this->priv_bucket_info()); return const_iterator( local_it, const_bucket_info_ptr(&this->priv_bucket_info()));
} }
iterator end() iterator end()
{ { return iterator(invalid_local_it(this->priv_bucket_info()), 0); }
bucket_info_t *info = detail::get_pointer(this->priv_bucket_info());
return iterator(invalid_local_it(*info), 0);
}
const_iterator end() const const_iterator end() const
{ return cend(); } { return cend(); }
const_iterator cend() const const_iterator cend() const
{ { return const_iterator(invalid_local_it(this->priv_bucket_info()), 0); }
const bucket_info_t *info = detail::get_pointer(this->priv_bucket_info());
return const_iterator(invalid_local_it(*info), 0);
}
hasher hash_function() const hasher hash_function() const
{ return this->priv_hasher(); } { return this->priv_hasher(); }
@@ -266,10 +276,10 @@ class hashtable
} }
} }
template <class Cloner, class Destroyer> template <class Cloner, class Disposer>
void clone_from(const hashtable &src, Cloner cloner, Destroyer destroyer) void clone_from(const hashtable &src, Cloner cloner, Disposer disposer)
{ {
this->clear_and_destroy(destroyer); this->clear_and_dispose(disposer);
if(!ConstantTimeSize || !src.empty()){ if(!ConstantTimeSize || !src.empty()){
const size_type src_bucket_count = src.bucket_count(); const size_type src_bucket_count = src.bucket_count();
const size_type dst_bucket_count = this->bucket_count(); const size_type dst_bucket_count = this->bucket_count();
@@ -284,7 +294,7 @@ class hashtable
for( constructed = 0 for( constructed = 0
; constructed < dst_bucket_count ; constructed < dst_bucket_count
; ++constructed){ ; ++constructed){
dst_buckets[constructed].clone_from(src_buckets[constructed], cloner, destroyer); dst_buckets[constructed].clone_from(src_buckets[constructed], cloner, disposer);
} }
if(src_bucket_count != dst_bucket_count){ if(src_bucket_count != dst_bucket_count){
//Now insert the remaining ones using the modulo trick //Now insert the remaining ones using the modulo trick
@@ -303,7 +313,7 @@ class hashtable
} }
catch(...){ catch(...){
while(constructed--){ while(constructed--){
dst_buckets[constructed].clear_and_destroy(destroyer); dst_buckets[constructed].clear_and_dispose(disposer);
} }
throw; throw;
} }
@@ -319,7 +329,7 @@ class hashtable
} }
} }
catch(...){ catch(...){
this->clear_and_destroy(destroyer); this->clear_and_dispose(disposer);
throw; throw;
} }
} }
@@ -331,11 +341,11 @@ class hashtable
size_type bucket_num, hash; size_type bucket_num, hash;
local_iterator it = priv_find(value, this->priv_hasher(), this->priv_equal(), bucket_num, hash); local_iterator it = priv_find(value, this->priv_hasher(), this->priv_equal(), bucket_num, hash);
bucket_type &b = this->priv_buckets()[bucket_num]; bucket_type &b = this->priv_buckets()[bucket_num];
if(it == invalid_local_it(*this->priv_bucket_info())){ if(it == invalid_local_it(this->priv_bucket_info())){
it = b.before_begin(); it = b.before_begin();
} }
size_traits::increment(); size_traits::increment();
return iterator(b.insert_after(it, value), this->priv_bucket_info()); return iterator(b.insert_after(it, value), const_bucket_info_ptr(&this->priv_bucket_info()));
} }
template<class Iterator> template<class Iterator>
@@ -375,12 +385,12 @@ class hashtable
size_type bucket_num; size_type bucket_num;
local_iterator prev_pos = local_iterator prev_pos =
priv_find(key, hasher, key_value_eq, bucket_num, commit_data.hash); priv_find(key, hasher, key_value_eq, bucket_num, commit_data.hash);
bool success = prev_pos == invalid_local_it(*this->priv_bucket_info()); bool success = prev_pos == invalid_local_it(this->priv_bucket_info());
if(success){ if(success){
prev_pos = this->priv_buckets()[bucket_num].before_begin(); prev_pos = this->priv_buckets()[bucket_num].before_begin();
} }
return std::pair<iterator, bool> return std::pair<iterator, bool>
(iterator(prev_pos, this->priv_bucket_info()) (iterator(prev_pos, const_bucket_info_ptr(&this->priv_bucket_info()))
,success); ,success);
} }
@@ -390,34 +400,34 @@ class hashtable
bucket_type &b = this->priv_buckets()[bucket_num]; bucket_type &b = this->priv_buckets()[bucket_num];
size_traits::increment(); size_traits::increment();
return iterator( b.insert_after(b.before_begin(), value) return iterator( b.insert_after(b.before_begin(), value)
, this->priv_bucket_info()); , const_bucket_info_ptr(&this->priv_bucket_info()));
} }
void erase(const_iterator i) void erase(const_iterator i)
{ erase_and_destroy(i, detail::null_destroyer()); } { erase_and_dispose(i, detail::null_disposer()); }
void erase(const_iterator b, const_iterator e) void erase(const_iterator b, const_iterator e)
{ erase_and_destroy(b, e, detail::null_destroyer()); } { erase_and_dispose(b, e, detail::null_disposer()); }
size_type erase(const_reference value) size_type erase(const_reference value)
{ return this->erase(value, this->priv_hasher(), this->priv_equal()); } { return this->erase(value, this->priv_hasher(), this->priv_equal()); }
template<class KeyType, class KeyHasher, class KeyValueEqual> template<class KeyType, class KeyHasher, class KeyValueEqual>
size_type erase(const KeyType& key, KeyHasher hasher, KeyValueEqual equal) size_type erase(const KeyType& key, KeyHasher hasher, KeyValueEqual equal)
{ return erase_and_destroy(key, hasher, equal, detail::null_destroyer()); } { return erase_and_dispose(key, hasher, equal, detail::null_disposer()); }
template<class Destroyer> template<class Disposer>
void erase_and_destroy(const_iterator i, Destroyer destroyer) void erase_and_dispose(const_iterator i, Disposer disposer)
{ {
local_iterator to_erase(i.local()); local_iterator to_erase(i.local());
bucket_ptr f(priv_buckets()), l(f + priv_buckets_len()); bucket_ptr f(priv_buckets()), l(f + priv_buckets_len());
bucket_type &b = this->priv_buckets()[bucket_type::get_bucket_num(to_erase, *f, *l)]; bucket_type &b = this->priv_buckets()[bucket_type::get_bucket_num(to_erase, *f, *l)];
b.erase_after_and_destroy(b.previous(to_erase), destroyer); b.erase_after_and_dispose(b.previous(to_erase), disposer);
size_traits::decrement(); size_traits::decrement();
} }
template<class Destroyer> template<class Disposer>
void erase_and_destroy(const_iterator b, const_iterator e, Destroyer destroyer) void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
{ {
if(b == e) return; if(b == e) return;
@@ -448,7 +458,7 @@ class hashtable
local_iterator nxt(before_first_local_it); ++nxt; local_iterator nxt(before_first_local_it); ++nxt;
local_iterator end = first_b.end(); local_iterator end = first_b.end();
while(nxt != end){ while(nxt != end){
nxt = first_b.erase_after_and_destroy(before_first_local_it, destroyer); nxt = first_b.erase_after_and_dispose(before_first_local_it, disposer);
size_traits::decrement(); size_traits::decrement();
} }
} }
@@ -462,7 +472,7 @@ class hashtable
local_iterator nxt(b_begin); ++nxt; local_iterator nxt(b_begin); ++nxt;
local_iterator end = b.end(); local_iterator end = b.end();
while(nxt != end){ while(nxt != end){
nxt = b.erase_after_and_destroy(b_begin, destroyer); nxt = b.erase_after_and_dispose(b_begin, disposer);
size_traits::decrement(); size_traits::decrement();
} }
} }
@@ -473,19 +483,19 @@ class hashtable
local_iterator b_begin(last_b.before_begin()); local_iterator b_begin(last_b.before_begin());
local_iterator nxt(b_begin); ++nxt; local_iterator nxt(b_begin); ++nxt;
while(nxt != last_local_it){ while(nxt != last_local_it){
nxt = last_b.erase_after_and_destroy(b_begin, destroyer); nxt = last_b.erase_after_and_dispose(b_begin, disposer);
size_traits::decrement(); size_traits::decrement();
} }
} }
} }
template<class Destroyer> template<class Disposer>
size_type erase_and_destroy(const_reference value, Destroyer destroyer) size_type erase_and_dispose(const_reference value, Disposer disposer)
{ return erase_and_destroy(value, priv_hasher(), priv_equal(), destroyer); } { return erase_and_dispose(value, priv_hasher(), priv_equal(), disposer); }
template<class KeyType, class KeyHasher, class KeyValueEqual, class Destroyer> template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
size_type erase_and_destroy(const KeyType& key, KeyHasher hasher size_type erase_and_dispose(const KeyType& key, KeyHasher hasher
,KeyValueEqual equal, Destroyer destroyer) ,KeyValueEqual equal, Disposer disposer)
{ {
size_type count(0); size_type count(0);
@@ -513,7 +523,7 @@ class hashtable
//If found erase all equal values //If found erase all equal values
for(local_iterator end = b.end(); it != end && equal(key, *it); ++count){ for(local_iterator end = b.end(); it != end && equal(key, *it); ++count){
it = b.erase_after_and_destroy(prev, destroyer); it = b.erase_after_and_dispose(prev, disposer);
size_traits::decrement(); size_traits::decrement();
} }
return count; return count;
@@ -527,14 +537,14 @@ class hashtable
size_traits::set_size(size_type(0)); size_traits::set_size(size_type(0));
} }
template<class Destroyer> template<class Disposer>
void clear_and_destroy(Destroyer destroyer) void clear_and_dispose(Disposer disposer)
{ {
if(!ConstantTimeSize || !this->empty()){ if(!ConstantTimeSize || !this->empty()){
size_type num_buckets = this->bucket_count(); size_type num_buckets = this->bucket_count();
bucket_ptr b = this->priv_buckets(); bucket_ptr b = this->priv_buckets();
for(; num_buckets--; ++b){ for(; num_buckets--; ++b){
b->clear_and_destroy(destroyer); b->clear_and_dispose(disposer);
} }
size_traits::set_size(size_type(0)); size_traits::set_size(size_type(0));
} }
@@ -560,7 +570,7 @@ class hashtable
size_type bucket_n, hash; size_type bucket_n, hash;
local_iterator local_it = priv_find(key, hasher, equal, bucket_n, hash); local_iterator local_it = priv_find(key, hasher, equal, bucket_n, hash);
return iterator( local_it return iterator( local_it
, this->priv_bucket_info()); , const_bucket_info_ptr(&this->priv_bucket_info()));
} }
const_iterator find(const_reference value) const const_iterator find(const_reference value) const
@@ -573,7 +583,7 @@ class hashtable
size_type bucket_n, hash; size_type bucket_n, hash;
local_iterator local_it = priv_find(key, hasher, equal, bucket_n, hash); local_iterator local_it = priv_find(key, hasher, equal, bucket_n, hash);
return const_iterator( local_it return const_iterator( local_it
, uncast(this->priv_bucket_info())); , const_bucket_info_ptr(&this->priv_bucket_info()));
} }
std::pair<iterator,iterator> equal_range(const_reference value) std::pair<iterator,iterator> equal_range(const_reference value)
@@ -586,9 +596,10 @@ class hashtable
size_type bucket_n1, bucket_n2, count; size_type bucket_n1, bucket_n2, count;
std::pair<local_iterator, local_iterator> ret std::pair<local_iterator, local_iterator> ret
= priv_equal_range(key, hasher, equal, bucket_n1, bucket_n2, count); = priv_equal_range(key, hasher, equal, bucket_n1, bucket_n2, count);
const_bucket_info_ptr info_ptr (&this->priv_bucket_info());
return std::pair<iterator, iterator> return std::pair<iterator, iterator>
( iterator( ret.first, this->priv_bucket_info() ) ( iterator( ret.first, info_ptr)
, iterator( ret.second, this->priv_bucket_info()) ); , iterator( ret.second, info_ptr) );
} }
std::pair<const_iterator, const_iterator> std::pair<const_iterator, const_iterator>
@@ -602,9 +613,10 @@ class hashtable
size_type bucket_n1, bucket_n2, count; size_type bucket_n1, bucket_n2, count;
std::pair<local_iterator, local_iterator> ret std::pair<local_iterator, local_iterator> ret
= priv_equal_range(key, hasher, equal, bucket_n1, bucket_n2, count); = priv_equal_range(key, hasher, equal, bucket_n1, bucket_n2, count);
const_bucket_info_ptr info_ptr (&this->priv_bucket_info());
return std::pair<const_iterator, const_iterator> return std::pair<const_iterator, const_iterator>
( const_iterator( ret.first, uncast(this->priv_bucket_info()) ) ( const_iterator( ret.first, info_ptr)
, const_iterator( ret.second, uncast(this->priv_bucket_info()) ) ); , const_iterator( ret.second, info_ptr) );
} }
size_type bucket_count() const size_type bucket_count() const
@@ -703,13 +715,13 @@ class hashtable
iterator iterator_to(reference value) iterator iterator_to(reference value)
{ {
return iterator( bucket_type::iterator_to(value) return iterator( bucket_type::iterator_to(value)
, this->priv_bucket_info()); , const_bucket_info_ptr(&this->priv_bucket_info()));
} }
const_iterator iterator_to(const_reference value) const const_iterator iterator_to(const_reference value) const
{ {
return const_iterator( bucket_type::iterator_to(const_cast<reference>(value)) return const_iterator( bucket_type::iterator_to(const_cast<reference>(value))
, uncast(this->priv_bucket_info())); , const_bucket_info_ptr(&this->priv_bucket_info()));
} }
static local_iterator local_iterator_to(reference value) static local_iterator local_iterator_to(reference value)
@@ -755,7 +767,7 @@ class hashtable
if(!b.empty()) if(!b.empty())
return b.begin(); return b.begin();
} }
return invalid_local_it(*this->priv_bucket_info()); return invalid_local_it(this->priv_bucket_info());
} }
void priv_clear_buckets() void priv_clear_buckets()
@@ -778,7 +790,7 @@ class hashtable
bucket_number = hash % b_len; bucket_number = hash % b_len;
if(ConstantTimeSize && this->empty()){ if(ConstantTimeSize && this->empty()){
return invalid_local_it(*this->priv_bucket_info()); return invalid_local_it(this->priv_bucket_info());
} }
bucket_type &b = this->priv_buckets()[bucket_number]; bucket_type &b = this->priv_buckets()[bucket_number];
@@ -791,7 +803,7 @@ class hashtable
++it; ++it;
} }
return invalid_local_it(*this->priv_bucket_info()); return invalid_local_it(this->priv_bucket_info());
} }
template<class KeyType, class KeyHasher, class KeyValueEqual> template<class KeyType, class KeyHasher, class KeyValueEqual>
@@ -808,7 +820,7 @@ class hashtable
//Let's see if the element is present //Let's see if the element is present
std::pair<local_iterator, local_iterator> to_return std::pair<local_iterator, local_iterator> to_return
( priv_find(key, hasher, equal, bucket_number_first, hash) ( priv_find(key, hasher, equal, bucket_number_first, hash)
, invalid_local_it(*this->priv_bucket_info())); , invalid_local_it(this->priv_bucket_info()));
if(to_return.first == to_return.second){ if(to_return.first == to_return.second){
bucket_number_second = bucket_number_first; bucket_number_second = bucket_number_first;
return to_return; return to_return;
@@ -842,7 +854,7 @@ class hashtable
} }
//Otherwise, return the end node //Otherwise, return the end node
to_return.second = invalid_local_it(*this->priv_bucket_info()); to_return.second = invalid_local_it(this->priv_bucket_info());
return to_return; return to_return;
} }
/// @endcond /// @endcond

View File

@@ -14,7 +14,6 @@
#define BOOST_INTRUSIVE_FWD_HPP #define BOOST_INTRUSIVE_FWD_HPP
#include <cstddef> #include <cstddef>
#include <boost/functional/hash_fwd.hpp>
#include <boost/intrusive/tag.hpp> #include <boost/intrusive/tag.hpp>
#include <boost/intrusive/linking_policy.hpp> #include <boost/intrusive/linking_policy.hpp>
@@ -30,6 +29,11 @@ struct less;
} //namespace std{ } //namespace std{
namespace boost { namespace boost {
//Hash predeclaration
template<class T>
struct hash;
namespace intrusive { namespace intrusive {
//////////////////////////// ////////////////////////////

View File

@@ -15,8 +15,7 @@
#define BOOST_INTRUSIVE_LIST_HPP #define BOOST_INTRUSIVE_LIST_HPP
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <boost/utility.hpp> #include <boost/intrusive/detail/assert.hpp>
#include <boost/assert.hpp>
#include <boost/intrusive/intrusive_fwd.hpp> #include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/list_hook.hpp> #include <boost/intrusive/list_hook.hpp>
#include <boost/intrusive/circular_list_algorithms.hpp> #include <boost/intrusive/circular_list_algorithms.hpp>
@@ -165,7 +164,7 @@ class list
{ {
node_ptr to_insert = ValueTraits::to_node_ptr(value); node_ptr to_insert = ValueTraits::to_node_ptr(value);
if(safemode_or_autounlink) if(safemode_or_autounlink)
BOOST_ASSERT(node_algorithms::unique(to_insert)); BOOST_INTRUSIVE_SAFE_MODE_CONTAINER_INSERTION_ASSERT(node_algorithms::unique(to_insert));
node_algorithms::link_before(this->get_root_node(), to_insert); node_algorithms::link_before(this->get_root_node(), to_insert);
size_traits::increment(); size_traits::increment();
} }
@@ -184,7 +183,7 @@ class list
{ {
node_ptr to_insert = ValueTraits::to_node_ptr(value); node_ptr to_insert = ValueTraits::to_node_ptr(value);
if(safemode_or_autounlink) if(safemode_or_autounlink)
BOOST_ASSERT(node_algorithms::unique(to_insert)); BOOST_INTRUSIVE_SAFE_MODE_CONTAINER_INSERTION_ASSERT(node_algorithms::unique(to_insert));
node_algorithms::link_before(node_traits::get_next(this->get_root_node()), to_insert); node_algorithms::link_before(node_traits::get_next(this->get_root_node()), to_insert);
size_traits::increment(); size_traits::increment();
} }
@@ -206,26 +205,26 @@ class list
node_algorithms::init(to_erase); node_algorithms::init(to_erase);
} }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the last element of the list. //! <b>Effects</b>: Erases the last element of the list.
//! No destructors are called. //! No destructors are called.
//! Destroyer::operator()(pointer) is called for the removed element. //! Disposer::operator()(pointer) is called for the removed element.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
//! //!
//! <b>Note</b>: Invalidates the iterators to the erased element. //! <b>Note</b>: Invalidates the iterators to the erased element.
template<class Destroyer> template<class Disposer>
void pop_back_and_destroy(Destroyer destroyer) void pop_back_and_dispose(Disposer disposer)
{ {
node_ptr to_erase = node_traits::get_previous(this->get_root_node()); node_ptr to_erase = node_traits::get_previous(this->get_root_node());
node_algorithms::unlink(to_erase); node_algorithms::unlink(to_erase);
size_traits::decrement(); size_traits::decrement();
if(safemode_or_autounlink) if(safemode_or_autounlink)
node_algorithms::init(to_erase); node_algorithms::init(to_erase);
destroyer(ValueTraits::to_value_ptr(to_erase)); disposer(ValueTraits::to_value_ptr(to_erase));
} }
//! <b>Effects</b>: Erases the first element of the list. //! <b>Effects</b>: Erases the first element of the list.
@@ -245,26 +244,26 @@ class list
node_algorithms::init(to_erase); node_algorithms::init(to_erase);
} }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the first element of the list. //! <b>Effects</b>: Erases the first element of the list.
//! No destructors are called. //! No destructors are called.
//! Destroyer::operator()(pointer) is called for the removed element. //! Disposer::operator()(pointer) is called for the removed element.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
//! //!
//! <b>Note</b>: Invalidates the iterators to the erased element. //! <b>Note</b>: Invalidates the iterators to the erased element.
template<class Destroyer> template<class Disposer>
void pop_front_and_destroy(Destroyer destroyer) void pop_front_and_dispose(Disposer disposer)
{ {
node_ptr to_erase = node_traits::get_next(this->get_root_node()); node_ptr to_erase = node_traits::get_next(this->get_root_node());
node_algorithms::unlink(to_erase); node_algorithms::unlink(to_erase);
size_traits::decrement(); size_traits::decrement();
if(safemode_or_autounlink) if(safemode_or_autounlink)
node_algorithms::init(to_erase); node_algorithms::init(to_erase);
destroyer(ValueTraits::to_value_ptr(to_erase)); disposer(ValueTraits::to_value_ptr(to_erase));
} }
//! <b>Effects</b>: Returns a reference to the first element of the list. //! <b>Effects</b>: Returns a reference to the first element of the list.
@@ -570,11 +569,11 @@ class list
} }
} }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the element pointed by i of the list. //! <b>Effects</b>: Erases the element pointed by i of the list.
//! No destructors are called. //! No destructors are called.
//! Destroyer::operator()(pointer) is called for the removed element. //! Disposer::operator()(pointer) is called for the removed element.
//! //!
//! <b>Returns</b>: the first element remaining beyond the removed element, //! <b>Returns</b>: the first element remaining beyond the removed element,
//! or end() if no such element exists. //! or end() if no such element exists.
@@ -584,8 +583,8 @@ class list
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
//! //!
//! <b>Note</b>: Invalidates the iterators to the erased element. //! <b>Note</b>: Invalidates the iterators to the erased element.
template <class Destroyer> template <class Disposer>
iterator erase_and_destroy(iterator i, Destroyer destroyer) iterator erase_and_dispose(iterator i, Disposer disposer)
{ {
iterator erase = i; iterator erase = i;
++i; ++i;
@@ -594,15 +593,15 @@ class list
size_traits::decrement(); size_traits::decrement();
if(safemode_or_autounlink) if(safemode_or_autounlink)
node_algorithms::init(to_erase); node_algorithms::init(to_erase);
destroyer(ValueTraits::to_value_ptr(to_erase)); disposer(ValueTraits::to_value_ptr(to_erase));
return i; return i;
} }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the element range pointed by b and e //! <b>Effects</b>: Erases the element range pointed by b and e
//! No destructors are called. //! No destructors are called.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Returns</b>: the first element remaining beyond the removed elements, //! <b>Returns</b>: the first element remaining beyond the removed elements,
//! or end() if no such element exists. //! or end() if no such element exists.
@@ -612,11 +611,11 @@ class list
//! <b>Complexity</b>: Linear to the number of elements erased. //! <b>Complexity</b>: Linear to the number of elements erased.
//! //!
//! <b>Note</b>: Invalidates the iterators to the erased elements. //! <b>Note</b>: Invalidates the iterators to the erased elements.
template <class Destroyer> template <class Disposer>
iterator erase_and_destroy(iterator b, iterator e, Destroyer destroyer) iterator erase_and_dispose(iterator b, iterator e, Disposer disposer)
{ {
while(b != e){ while(b != e){
b = this->erase_and_destroy(b, destroyer); b = this->erase_and_dispose(b, disposer);
} }
return b; return b;
} }
@@ -641,38 +640,38 @@ class list
} }
} }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements of the container. //! <b>Effects</b>: Erases all the elements of the container.
//! No destructors are called. //! No destructors are called.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
//! //!
//! <b>Complexity</b>: Linear to the number of elements of the list. //! <b>Complexity</b>: Linear to the number of elements of the list.
//! //!
//! <b>Note</b>: Invalidates the iterators to the erased elements. //! <b>Note</b>: Invalidates the iterators to the erased elements.
template <class Destroyer> template <class Disposer>
void clear_and_destroy(Destroyer destroyer) void clear_and_dispose(Disposer disposer)
{ this->erase_and_destroy(this->begin(), this->end(), destroyer); } { this->erase_and_dispose(this->begin(), this->end(), disposer); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements from *this //! <b>Effects</b>: Erases all the elements from *this
//! calling Destroyer::operator()(pointer), clones all the //! calling Disposer::operator()(pointer), clones all the
//! elements from src calling Cloner::operator()(const_reference ) //! elements from src calling Cloner::operator()(const_reference )
//! and inserts them on *this. //! and inserts them on *this.
//! //!
//! If cloner throws, all cloned elements are unlinked and destroyed //! If cloner throws, all cloned elements are unlinked and disposed
//! calling Destroyer::operator()(pointer). //! calling Disposer::operator()(pointer).
//! //!
//! <b>Complexity</b>: Linear to erased plus inserted elements. //! <b>Complexity</b>: Linear to erased plus inserted elements.
//! //!
//! <b>Throws</b>: If cloner throws. Basic guarantee. //! <b>Throws</b>: If cloner throws. Basic guarantee.
template <class Cloner, class Destroyer> template <class Cloner, class Disposer>
void clone_from(const list &src, Cloner cloner, Destroyer destroyer) void clone_from(const list &src, Cloner cloner, Disposer disposer)
{ {
this->clear_and_destroy(destroyer); this->clear_and_dispose(disposer);
try{ try{
const_iterator b(src.begin()), e(src.end()); const_iterator b(src.begin()), e(src.end());
for(; b != e; ++b){ for(; b != e; ++b){
@@ -680,7 +679,7 @@ class list
} }
} }
catch(...){ catch(...){
clear_and_destroy(destroyer); clear_and_dispose(disposer);
throw; throw;
} }
} }
@@ -700,7 +699,7 @@ class list
{ {
node_ptr to_insert = ValueTraits::to_node_ptr(value); node_ptr to_insert = ValueTraits::to_node_ptr(value);
if(safemode_or_autounlink) if(safemode_or_autounlink)
BOOST_ASSERT(node_algorithms::unique(to_insert)); BOOST_INTRUSIVE_SAFE_MODE_CONTAINER_INSERTION_ASSERT(node_algorithms::unique(to_insert));
node_algorithms::link_before(p.pointed_node(), to_insert); node_algorithms::link_before(p.pointed_node(), to_insert);
size_traits::increment(); size_traits::increment();
return iterator(to_insert); return iterator(to_insert);
@@ -746,14 +745,14 @@ class list
this->insert(this->end(), b, e); this->insert(this->end(), b, e);
} }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Requires</b>: Dereferencing iterator must yield //! <b>Requires</b>: Dereferencing iterator must yield
//! an lvalue of type value_type. //! an lvalue of type value_type.
//! //!
//! <b>Effects</b>: Clears the list and inserts the range pointed by b and e. //! <b>Effects</b>: Clears the list and inserts the range pointed by b and e.
//! No destructors or copy constructors are called. //! No destructors or copy constructors are called.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
//! //!
@@ -762,10 +761,10 @@ class list
//! //!
//! <b>Note</b>: Invalidates the iterators (but not the references) //! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. //! to the erased elements.
template<class Iterator, class Destroyer> template<class Iterator, class Disposer>
void destroy_and_assign(Destroyer destroyer, Iterator b, Iterator e) void dispose_and_assign(Disposer disposer, Iterator b, Iterator e)
{ {
this->clear(destroyer); this->clear(disposer);
this->insert(this->end(), b, e); this->insert(this->end(), b, e);
} }
@@ -855,7 +854,7 @@ class list
{ {
if(n){ if(n){
if(ConstantTimeSize){ if(ConstantTimeSize){
BOOST_ASSERT(n == std::distance(start, end)); BOOST_INTRUSIVE_INVARIANT_ASSERT(n == std::distance(start, end));
node_algorithms::transfer(p.pointed_node(), start.pointed_node(), end.pointed_node()); node_algorithms::transfer(p.pointed_node(), start.pointed_node(), end.pointed_node());
size_traits::set_size(size_traits::get_size() + n); size_traits::set_size(size_traits::get_size() + n);
x.set_size(x.get_size() - n); x.set_size(x.get_size() - n);
@@ -989,10 +988,10 @@ class list
void remove(const_reference value) void remove(const_reference value)
{ remove_if(detail::equal_to_value<const_reference>(value)); } { remove_if(detail::equal_to_value<const_reference>(value)); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Removes all the elements that compare equal to value. //! <b>Effects</b>: Removes all the elements that compare equal to value.
//! Destroyer::operator()(pointer) is called for every removed element. //! Disposer::operator()(pointer) is called for every removed element.
//! //!
//! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee. //! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee.
//! //!
@@ -1000,9 +999,9 @@ class list
//! //!
//! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
template<class Destroyer> template<class Disposer>
void remove_and_destroy(const_reference value, Destroyer destroyer) void remove_and_dispose(const_reference value, Disposer disposer)
{ remove_and_destroy_if(detail::equal_to_value<const_reference>(value), destroyer); } { remove_and_dispose_if(detail::equal_to_value<const_reference>(value), disposer); }
//! <b>Effects</b>: Removes all the elements for which a specified //! <b>Effects</b>: Removes all the elements for which a specified
//! predicate is satisfied. No destructors are called. //! predicate is satisfied. No destructors are called.
@@ -1015,13 +1014,13 @@ class list
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
template<class Pred> template<class Pred>
void remove_if(Pred pred) void remove_if(Pred pred)
{ remove_and_destroy_if(pred, detail::null_destroyer()); } { remove_and_dispose_if(pred, detail::null_disposer()); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Removes all the elements for which a specified //! <b>Effects</b>: Removes all the elements for which a specified
//! predicate is satisfied. //! predicate is satisfied.
//! Destroyer::operator()(pointer) is called for every removed element. //! Disposer::operator()(pointer) is called for every removed element.
//! //!
//! <b>Throws</b>: If pred throws. Basic guarantee. //! <b>Throws</b>: If pred throws. Basic guarantee.
//! //!
@@ -1029,8 +1028,8 @@ class list
//! //!
//! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
template<class Pred, class Destroyer> template<class Pred, class Disposer>
void remove_and_destroy_if(Pred pred, Destroyer destroyer) void remove_and_dispose_if(Pred pred, Disposer disposer)
{ {
iterator first = begin(); iterator first = begin();
iterator last = end(); iterator last = end();
@@ -1040,7 +1039,7 @@ class list
if(pred(*first)){ if(pred(*first)){
pointer p = first.operator->(); pointer p = first.operator->();
this->erase(first); this->erase(first);
destroyer(p); disposer(p);
} }
first = next; first = next;
} }
@@ -1056,7 +1055,7 @@ class list
//! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
void unique() void unique()
{ unique_and_destroy(std::equal_to<value_type>(), detail::null_destroyer()); } { unique_and_dispose(std::equal_to<value_type>(), detail::null_disposer()); }
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
//! elements that satisfy some binary predicate from the list. //! elements that satisfy some binary predicate from the list.
@@ -1070,13 +1069,13 @@ class list
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
template<class BinaryPredicate> template<class BinaryPredicate>
void unique(BinaryPredicate pred) void unique(BinaryPredicate pred)
{ unique_and_destroy(pred, detail::null_destroyer()); } { unique_and_dispose(pred, detail::null_disposer()); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
//! elements that are equal from the list. //! elements that are equal from the list.
//! Destroyer::operator()(pointer) is called for every removed element. //! Disposer::operator()(pointer) is called for every removed element.
//! //!
//! <b>Throws</b>: If std::equal_to<value_type throws. Basic guarantee. //! <b>Throws</b>: If std::equal_to<value_type throws. Basic guarantee.
//! //!
@@ -1084,15 +1083,15 @@ class list
//! //!
//! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
template<class Destroyer> template<class Disposer>
void unique_and_destroy(Destroyer destroyer) void unique_and_dispose(Disposer disposer)
{ unique_and_destroy(std::equal_to<value_type>(), destroyer); } { unique_and_dispose(std::equal_to<value_type>(), disposer); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
//! elements that satisfy some binary predicate from the list. //! elements that satisfy some binary predicate from the list.
//! Destroyer::operator()(pointer) is called for every removed element. //! Disposer::operator()(pointer) is called for every removed element.
//! //!
//! <b>Throws</b>: If pred throws. Basic guarantee. //! <b>Throws</b>: If pred throws. Basic guarantee.
//! //!
@@ -1100,8 +1099,8 @@ class list
//! //!
//! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
template<class BinaryPredicate, class Destroyer> template<class BinaryPredicate, class Disposer>
void unique_and_destroy(BinaryPredicate pred, Destroyer destroyer) void unique_and_dispose(BinaryPredicate pred, Disposer disposer)
{ {
if(!this->empty()){ if(!this->empty()){
iterator first = begin(); iterator first = begin();
@@ -1111,7 +1110,7 @@ class list
if(pred(*first, *after)){ if(pred(*first, *after)){
pointer p = after.operator->(); pointer p = after.operator->();
after = erase(after); after = erase(after);
destroyer(p); disposer(p);
} }
else{ else{
first = after++; first = after++;
@@ -1131,7 +1130,7 @@ class list
//! <b>Note</b>: Iterators and references are not invalidated. //! <b>Note</b>: Iterators and references are not invalidated.
static iterator iterator_to(reference value) static iterator iterator_to(reference value)
{ {
BOOST_ASSERT(!node_algorithms::unique(ValueTraits::to_node_ptr(value))); BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::unique(ValueTraits::to_node_ptr(value)));
return iterator(ValueTraits::to_node_ptr(value)); return iterator(ValueTraits::to_node_ptr(value));
} }
@@ -1146,7 +1145,7 @@ class list
//! <b>Note</b>: Iterators and references are not invalidated. //! <b>Note</b>: Iterators and references are not invalidated.
static const_iterator iterator_to(const_reference value) static const_iterator iterator_to(const_reference value)
{ {
BOOST_ASSERT(!node_algorithms::unique(ValueTraits::to_node_ptr(const_cast<reference> (value)))); BOOST_INTRUSIVE_INVARIANT_ASSERT(!node_algorithms::unique(ValueTraits::to_node_ptr(const_cast<reference> (value))));
return const_iterator(ValueTraits::to_node_ptr(const_cast<reference> (value))); return const_iterator(ValueTraits::to_node_ptr(const_cast<reference> (value)));
} }
}; };

View File

@@ -23,7 +23,6 @@
#include <boost/intrusive/linking_policy.hpp> #include <boost/intrusive/linking_policy.hpp>
#include <boost/intrusive/tag.hpp> #include <boost/intrusive/tag.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <stdexcept>
namespace boost { namespace boost {
namespace intrusive { namespace intrusive {

View File

@@ -15,15 +15,14 @@
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <functional> #include <functional>
#include <iterator> #include <iterator>
#include <boost/utility.hpp>
#include <utility> #include <utility>
#include <boost/assert.hpp> #include <boost/intrusive/detail/assert.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/intrusive/intrusive_fwd.hpp> #include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp> #include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/set_hook.hpp> #include <boost/intrusive/set_hook.hpp>
#include <boost/intrusive/detail/rbtree_node.hpp> #include <boost/intrusive/detail/rbtree_node.hpp>
#include <boost/intrusive/detail/ebo_holder.hpp> #include <boost/intrusive/detail/ebo_functor_holder.hpp>
#include <boost/intrusive/rbtree_algorithms.hpp> #include <boost/intrusive/rbtree_algorithms.hpp>
#include <boost/intrusive/linking_policy.hpp> #include <boost/intrusive/linking_policy.hpp>
#include <cstddef> #include <cstddef>
@@ -353,7 +352,7 @@ class rbtree
detail::key_node_ptr_compare<value_compare, ValueTraits> key_node_comp(priv_comp()); detail::key_node_ptr_compare<value_compare, ValueTraits> key_node_comp(priv_comp());
node_ptr to_insert(ValueTraits::to_node_ptr(value)); node_ptr to_insert(ValueTraits::to_node_ptr(value));
if(safemode_or_autounlink) if(safemode_or_autounlink)
BOOST_ASSERT(node_algorithms::unique(to_insert)); BOOST_INTRUSIVE_SAFE_MODE_CONTAINER_INSERTION_ASSERT(node_algorithms::unique(to_insert));
size_traits::increment(); size_traits::increment();
return iterator(node_algorithms::insert_equal_upper_bound return iterator(node_algorithms::insert_equal_upper_bound
(node_ptr(&priv_header()), to_insert, key_node_comp)); (node_ptr(&priv_header()), to_insert, key_node_comp));
@@ -375,7 +374,7 @@ class rbtree
detail::key_node_ptr_compare<value_compare, ValueTraits> key_node_comp(priv_comp()); detail::key_node_ptr_compare<value_compare, ValueTraits> key_node_comp(priv_comp());
node_ptr to_insert(ValueTraits::to_node_ptr(value)); node_ptr to_insert(ValueTraits::to_node_ptr(value));
if(safemode_or_autounlink) if(safemode_or_autounlink)
BOOST_ASSERT(node_algorithms::unique(to_insert)); BOOST_INTRUSIVE_SAFE_MODE_CONTAINER_INSERTION_ASSERT(node_algorithms::unique(to_insert));
size_traits::increment(); size_traits::increment();
return iterator(node_algorithms::insert_equal_lower_bound return iterator(node_algorithms::insert_equal_lower_bound
(node_ptr(&priv_header()), to_insert, key_node_comp)); (node_ptr(&priv_header()), to_insert, key_node_comp));
@@ -400,7 +399,7 @@ class rbtree
detail::key_node_ptr_compare<value_compare, ValueTraits> key_node_comp(priv_comp()); detail::key_node_ptr_compare<value_compare, ValueTraits> key_node_comp(priv_comp());
node_ptr to_insert(ValueTraits::to_node_ptr(value)); node_ptr to_insert(ValueTraits::to_node_ptr(value));
if(safemode_or_autounlink) if(safemode_or_autounlink)
BOOST_ASSERT(node_algorithms::unique(to_insert)); BOOST_INTRUSIVE_SAFE_MODE_CONTAINER_INSERTION_ASSERT(node_algorithms::unique(to_insert));
size_traits::increment(); size_traits::increment();
return iterator(node_algorithms::insert_equal return iterator(node_algorithms::insert_equal
(node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp)); (node_ptr(&priv_header()), hint.pointed_node(), to_insert, key_node_comp));
@@ -540,7 +539,7 @@ class rbtree
{ {
node_ptr to_insert(ValueTraits::to_node_ptr(value)); node_ptr to_insert(ValueTraits::to_node_ptr(value));
if(safemode_or_autounlink) if(safemode_or_autounlink)
BOOST_ASSERT(node_algorithms::unique(to_insert)); BOOST_INTRUSIVE_SAFE_MODE_CONTAINER_INSERTION_ASSERT(node_algorithms::unique(to_insert));
size_traits::increment(); size_traits::increment();
node_algorithms::insert_unique_commit node_algorithms::insert_unique_commit
(node_ptr(&priv_header()), to_insert, commit_data); (node_ptr(&priv_header()), to_insert, commit_data);
@@ -561,7 +560,7 @@ class rbtree
++ret; ++ret;
node_ptr to_erase(i.pointed_node()); node_ptr to_erase(i.pointed_node());
if(safemode_or_autounlink) if(safemode_or_autounlink)
BOOST_ASSERT(!node_algorithms::unique(to_erase)); BOOST_INTRUSIVE_SAFE_MODE_CONTAINER_INSERTION_ASSERT(!node_algorithms::unique(to_erase));
node_algorithms::erase(&priv_header(), to_erase); node_algorithms::erase(&priv_header(), to_erase);
size_traits::decrement(); size_traits::decrement();
if(safemode_or_autounlink) if(safemode_or_autounlink)
@@ -614,10 +613,10 @@ class rbtree
return n; return n;
} }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the element pointed to by pos. //! <b>Effects</b>: Erases the element pointed to by pos.
//! Destroyer::operator()(pointer) is called for the removed element. //! Disposer::operator()(pointer) is called for the removed element.
//! //!
//! <b>Complexity</b>: Average complexity for erase element is constant time. //! <b>Complexity</b>: Average complexity for erase element is constant time.
//! //!
@@ -625,19 +624,19 @@ class rbtree
//! //!
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class Destroyer> template<class Disposer>
iterator erase_and_destroy(iterator i, Destroyer destroyer) iterator erase_and_dispose(iterator i, Disposer disposer)
{ {
node_ptr to_erase(i.pointed_node()); node_ptr to_erase(i.pointed_node());
iterator ret(this->erase(i)); iterator ret(this->erase(i));
destroyer(ValueTraits::to_value_ptr(to_erase)); disposer(ValueTraits::to_value_ptr(to_erase));
return ret; return ret;
} }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the range pointed to by b end e. //! <b>Effects</b>: Erases the range pointed to by b end e.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Complexity</b>: Average complexity for erase range is at most //! <b>Complexity</b>: Average complexity for erase range is at most
//! O(log(size() + N)), where N is the number of elements in the range. //! O(log(size() + N)), where N is the number of elements in the range.
@@ -646,14 +645,14 @@ class rbtree
//! //!
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class Destroyer> template<class Disposer>
iterator erase_and_destroy(iterator b, iterator e, Destroyer destroyer) iterator erase_and_dispose(iterator b, iterator e, Disposer disposer)
{ size_type n; return private_erase(b, e, n, destroyer); } { size_type n; return private_erase(b, e, n, disposer); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements with the given value. //! <b>Effects</b>: Erases all the elements with the given value.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Returns</b>: The number of erased elements. //! <b>Returns</b>: The number of erased elements.
//! //!
@@ -663,20 +662,20 @@ class rbtree
//! //!
//! <b>Note</b>: Invalidates the iterators (but not the references) //! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called. //! to the erased elements. No destructors are called.
template<class Destroyer> template<class Disposer>
size_type erase_and_destroy(const_reference value, Destroyer destroyer) size_type erase_and_dispose(const_reference value, Disposer disposer)
{ {
std::pair<iterator,iterator> p = this->equal_range(value); std::pair<iterator,iterator> p = this->equal_range(value);
size_type n; size_type n;
private_erase(p.first, p.second, n, destroyer); private_erase(p.first, p.second, n, disposer);
return n; return n;
} }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements with the given key. //! <b>Effects</b>: Erases all the elements with the given key.
//! according to the comparison functor "comp". //! according to the comparison functor "comp".
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Returns</b>: The number of erased elements. //! <b>Returns</b>: The number of erased elements.
//! //!
@@ -686,12 +685,12 @@ class rbtree
//! //!
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class KeyType, class KeyValueCompare, class Destroyer> template<class KeyType, class KeyValueCompare, class Disposer>
size_type erase_and_destroy(const KeyType& key, KeyValueCompare comp, Destroyer destroyer) size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
{ {
std::pair<iterator,iterator> p = this->equal_range(key, comp); std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n; size_type n;
private_erase(p.first, p.second, n, destroyer); private_erase(p.first, p.second, n, disposer);
return n; return n;
} }
@@ -724,7 +723,7 @@ class rbtree
} }
} }
//! <b>Effects</b>: Erases all of the elements calling destroyer(p) for //! <b>Effects</b>: Erases all of the elements calling disposer(p) for
//! each node to be erased. //! each node to be erased.
//! <b>Complexity</b>: Average complexity for is at most O(log(size() + N)), //! <b>Complexity</b>: Average complexity for is at most O(log(size() + N)),
//! where N is the number of elements in the container. //! where N is the number of elements in the container.
@@ -732,9 +731,9 @@ class rbtree
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
//! //!
//! <b>Note</b>: Invalidates the iterators (but not the references) //! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. Calls N times to destroyer functor. //! to the erased elements. Calls N times to disposer functor.
template<class Destroyer> template<class Disposer>
void clear_and_destroy(Destroyer destroyer) void clear_and_dispose(Disposer disposer)
{ {
while(1){ while(1){
node_ptr leftmost node_ptr leftmost
@@ -745,7 +744,7 @@ class rbtree
size_traits::decrement(); size_traits::decrement();
if(safemode_or_autounlink) if(safemode_or_autounlink)
node_algorithms::init(leftmost); node_algorithms::init(leftmost);
destroyer(ValueTraits::to_value_ptr(leftmost)); disposer(ValueTraits::to_value_ptr(leftmost));
} }
} }
@@ -965,30 +964,30 @@ class rbtree
return std::pair<const_iterator, const_iterator>(const_iterator(ret.first), const_iterator(ret.second)); return std::pair<const_iterator, const_iterator>(const_iterator(ret.first), const_iterator(ret.second));
} }
template <class Cloner, class Destroyer> template <class Cloner, class Disposer>
void clone_from(const rbtree &src, Cloner cloner, Destroyer destroyer) void clone_from(const rbtree &src, Cloner cloner, Disposer disposer)
{ {
this->clear_and_destroy(destroyer); this->clear_and_dispose(disposer);
if(!src.empty()){ if(!src.empty()){
node_algorithms::clone_tree node_algorithms::clone_tree
(const_node_ptr(&src.priv_header()) (const_node_ptr(&src.priv_header())
,node_ptr(&this->priv_header()) ,node_ptr(&this->priv_header())
,detail::value_to_node_cloner<Cloner, ValueTraits>(cloner) ,detail::value_to_node_cloner<Cloner, ValueTraits>(cloner)
,detail::value_to_node_destroyer<Destroyer, ValueTraits>(destroyer)); ,detail::value_to_node_disposer<Disposer, ValueTraits>(disposer));
size_traits::set_size(src.get_size()); size_traits::set_size(src.get_size());
} }
} }
pointer unlink_leftmost_without_rebalance() pointer unlink_leftmost_without_rebalance()
{ {
node_ptr to_destroy(node_algorithms::unlink_leftmost_without_rebalance node_ptr to_be_disposed(node_algorithms::unlink_leftmost_without_rebalance
(node_ptr(&priv_header()))); (node_ptr(&priv_header())));
if(!to_destroy) if(!to_be_disposed)
return 0; return 0;
size_traits::decrement(); size_traits::decrement();
if(safemode_or_autounlink) if(safemode_or_autounlink)
node_algorithms::init(to_destroy); node_algorithms::init(to_be_disposed);
return ValueTraits::to_value_ptr(to_destroy); return ValueTraits::to_value_ptr(to_be_disposed);
} }
//! <b>Requires</b>: value must be an lvalue and shall be in a set of //! <b>Requires</b>: value must be an lvalue and shall be in a set of
@@ -1059,11 +1058,11 @@ class rbtree
*/ */
/// @cond /// @cond
private: private:
template<class Destroyer> template<class Disposer>
iterator private_erase(iterator b, iterator e, size_type &n, Destroyer destroyer) iterator private_erase(iterator b, iterator e, size_type &n, Disposer disposer)
{ {
for(n = 0; b != e; ++n) for(n = 0; b != e; ++n)
this->erase_and_destroy(b++, destroyer); this->erase_and_dispose(b++, disposer);
return b; return b;
} }

View File

@@ -40,11 +40,11 @@
#define BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP #define BOOST_INTRUSIVE_RBTREE_ALGORITHMS_HPP
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <boost/assert.hpp> #include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/intrusive_fwd.hpp> #include <boost/intrusive/intrusive_fwd.hpp>
#include <cstddef> #include <cstddef>
#include <boost/detail/no_exceptions_support.hpp> #include <boost/detail/no_exceptions_support.hpp>
#include <boost/interprocess/detail/utilities.hpp> #include <boost/intrusive/detail/utilities.hpp>
namespace boost { namespace boost {
@@ -113,6 +113,16 @@ class rbtree_algorithms
typedef typename NodeTraits::const_node_ptr const_node_ptr; typedef typename NodeTraits::const_node_ptr const_node_ptr;
typedef typename NodeTraits::color color; typedef typename NodeTraits::color color;
/// @cond
private:
static node_ptr uncast(const_node_ptr ptr)
{
return node_ptr(const_cast<node*>(::boost::intrusive::detail::get_pointer(ptr)));
}
/// @endcond
public:
//! This type is the information that will be filled by insert_unique_check //! This type is the information that will be filled by insert_unique_check
struct insert_commit_data struct insert_commit_data
{ {
@@ -479,30 +489,30 @@ class rbtree_algorithms
} }
//! <b>Requires</b>: "cloner" must be a function //! <b>Requires</b>: "cloner" must be a function
//! object taking a node_ptr and returning a new cloned node of it. "destroyer" must //! object taking a node_ptr and returning a new cloned node of it. "disposer" must
//! take a node_ptr and shouldn't throw. //! take a node_ptr and shouldn't throw.
//! //!
//! <b>Effects</b>: First empties target tree calling //! <b>Effects</b>: First empties target tree calling
//! <tt>void destroyer::operator()(node_ptr)</tt> for every node of the tree //! <tt>void disposer::operator()(node_ptr)</tt> for every node of the tree
//! except the header. //! except the header.
//! //!
//! Then, duplicates the entire tree pointed by "source_header" cloning each //! Then, duplicates the entire tree pointed by "source_header" cloning each
//! source node with <tt>node_ptr Cloner::operator()(node_ptr)</tt> to obtain //! source node with <tt>node_ptr Cloner::operator()(node_ptr)</tt> to obtain
//! the nodes of the target tree. If "cloner" throws, the cloned target nodes //! the nodes of the target tree. If "cloner" throws, the cloned target nodes
//! are destroyed using <tt>void destroyer(node_ptr)</tt>. //! are disposed using <tt>void disposer(node_ptr)</tt>.
//! //!
//! <b>Complexity</b>: Linear to the number of element of the source tree plus the. //! <b>Complexity</b>: Linear to the number of element of the source tree plus the.
//! number of elements of tree target tree when calling this function. //! number of elements of tree target tree when calling this function.
//! //!
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are destroyed. //! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
template <class Cloner, class Destroyer> template <class Cloner, class Disposer>
static void clone_tree static void clone_tree
(const_node_ptr source_header, node_ptr target_header, Cloner cloner, Destroyer destroyer) (const_node_ptr source_header, node_ptr target_header, Cloner cloner, Disposer disposer)
{ {
if(!unique(target_header)){ if(!unique(target_header)){
node_ptr p; node_ptr p;
while((p = unlink_leftmost_without_rebalance(target_header))){ while((p = unlink_leftmost_without_rebalance(target_header))){
destroyer(p); disposer(p);
} }
} }
@@ -512,7 +522,7 @@ class rbtree_algorithms
NodeTraits::set_parent NodeTraits::set_parent
( target_header ( target_header
, deep_clone_node(source_root, target_header, cloner, destroyer)); , deep_clone_node(source_root, target_header, cloner, disposer));
NodeTraits::set_left(target_header, minimum(NodeTraits::get_parent(target_header))); NodeTraits::set_left(target_header, minimum(NodeTraits::get_parent(target_header)));
NodeTraits::set_right(target_header, maximum(NodeTraits::get_parent(target_header))); NodeTraits::set_right(target_header, maximum(NodeTraits::get_parent(target_header)));
} }
@@ -904,16 +914,11 @@ class rbtree_algorithms
(node_ptr header, node_ptr new_value, const insert_commit_data &commit_data) (node_ptr header, node_ptr new_value, const insert_commit_data &commit_data)
{ {
//Check if commit_data has not been initialized by a insert_unique_check call. //Check if commit_data has not been initialized by a insert_unique_check call.
BOOST_ASSERT(commit_data.node != 0); BOOST_INTRUSIVE_INVARIANT_ASSERT(commit_data.node != 0);
link_and_balance(new_value, commit_data.node, commit_data.link_left, header); link_and_balance(new_value, commit_data.node, commit_data.link_left, header);
} }
/// @cond /// @cond
private:
static node_ptr uncast(const_node_ptr ptr)
{
return node_ptr(const_cast<node*>(detail::get_pointer(ptr)));
}
//! <b>Requires</b>: z is the node to be inserted, par is its parent, //! <b>Requires</b>: z is the node to be inserted, par is its parent,
//! left, indicates if z should be a left node of par and header is the header //! left, indicates if z should be a left node of par and header is the header
@@ -1100,9 +1105,9 @@ class rbtree_algorithms
NodeTraits::set_color(NodeTraits::get_parent(header), NodeTraits::black()); NodeTraits::set_color(NodeTraits::get_parent(header), NodeTraits::black());
} }
template <class Cloner, class Destroyer> template <class Cloner, class Disposer>
static node_ptr deep_clone_node static node_ptr deep_clone_node
(node_ptr source_root, node_ptr new_parent, Cloner cloner, Destroyer destroyer) (node_ptr source_root, node_ptr new_parent, Cloner cloner, Disposer disposer)
{ {
// structural copy. source_root and new_parent must be non-null. // structural copy. source_root and new_parent must be non-null.
node_ptr top = cloner(source_root); node_ptr top = cloner(source_root);
@@ -1112,7 +1117,7 @@ class rbtree_algorithms
if(NodeTraits::get_right(source_root)){ if(NodeTraits::get_right(source_root)){
NodeTraits::set_right NodeTraits::set_right
(top, deep_clone_node(NodeTraits::get_right(source_root), top (top, deep_clone_node(NodeTraits::get_right(source_root), top
,cloner, destroyer)); ,cloner, disposer));
} }
new_parent = top; new_parent = top;
source_root = NodeTraits::get_left(source_root); source_root = NodeTraits::get_left(source_root);
@@ -1124,28 +1129,28 @@ class rbtree_algorithms
if(NodeTraits::get_right(source_root)){ if(NodeTraits::get_right(source_root)){
NodeTraits::set_right(y, deep_clone_node(NodeTraits::get_right(source_root), y NodeTraits::set_right(y, deep_clone_node(NodeTraits::get_right(source_root), y
,cloner, destroyer)); ,cloner, disposer));
} }
new_parent = y; new_parent = y;
source_root = NodeTraits::get_left(source_root); source_root = NodeTraits::get_left(source_root);
} }
} }
BOOST_CATCH(...){ BOOST_CATCH(...){
deep_destroy_node(top, destroyer); deep_dispose_node(top, disposer);
BOOST_RETHROW; BOOST_RETHROW;
} }
BOOST_CATCH_END BOOST_CATCH_END
return top; return top;
} }
template<class Destroyer> template<class Disposer>
static void deep_destroy_node(node_ptr x, Destroyer destroyer) static void deep_dispose_node(node_ptr x, Disposer disposer)
{ {
// erase without rebalancing // erase without rebalancing
while(x){ while(x){
deep_destroy_node(NodeTraits::get_right(x), destroyer); deep_dispose_node(NodeTraits::get_right(x), disposer);
node_ptr y = NodeTraits::get_left(x); node_ptr y = NodeTraits::get_left(x);
destroyer(x); disposer(x);
x = y; x = y;
} }
} }

View File

@@ -296,22 +296,22 @@ class set
void swap(set& other) void swap(set& other)
{ tree_.swap(other.tree_); } { tree_.swap(other.tree_); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements from *this //! <b>Effects</b>: Erases all the elements from *this
//! calling Destroyer::operator()(pointer), clones all the //! calling Disposer::operator()(pointer), clones all the
//! elements from src calling Cloner::operator()(const_reference ) //! elements from src calling Cloner::operator()(const_reference )
//! and inserts them on *this. //! and inserts them on *this.
//! //!
//! If cloner throws, all cloned elements are unlinked and destroyed //! If cloner throws, all cloned elements are unlinked and disposed
//! calling Destroyer::operator()(pointer). //! calling Disposer::operator()(pointer).
//! //!
//! <b>Complexity</b>: Linear to erased plus inserted elements. //! <b>Complexity</b>: Linear to erased plus inserted elements.
//! //!
//! <b>Throws</b>: If cloner throws. //! <b>Throws</b>: If cloner throws.
template <class Cloner, class Destroyer> template <class Cloner, class Disposer>
void clone_from(const set &src, Cloner cloner, Destroyer destroyer) void clone_from(const set &src, Cloner cloner, Disposer disposer)
{ tree_.clone_from(src.tree_, cloner, destroyer); } { tree_.clone_from(src.tree_, cloner, disposer); }
//! <b>Requires</b>: value must be an lvalue //! <b>Requires</b>: value must be an lvalue
//! //!
@@ -516,10 +516,10 @@ class set
size_type erase(const KeyType& key, KeyValueCompare comp) size_type erase(const KeyType& key, KeyValueCompare comp)
{ return tree_.erase(key, comp); } { return tree_.erase(key, comp); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the element pointed to by pos. //! <b>Effects</b>: Erases the element pointed to by pos.
//! Destroyer::operator()(pointer) is called for the removed element. //! Disposer::operator()(pointer) is called for the removed element.
//! //!
//! <b>Complexity</b>: Average complexity for erase element is constant time. //! <b>Complexity</b>: Average complexity for erase element is constant time.
//! //!
@@ -529,14 +529,14 @@ class set
//! //!
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class Destroyer> template<class Disposer>
iterator erase_and_destroy(iterator i, Destroyer destroyer) iterator erase_and_dispose(iterator i, Disposer disposer)
{ return tree_.erase_and_destroy(i, destroyer); } { return tree_.erase_and_dispose(i, disposer); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the range pointed to by b end e. //! <b>Effects</b>: Erases the range pointed to by b end e.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Complexity</b>: Average complexity for erase range is at most //! <b>Complexity</b>: Average complexity for erase range is at most
//! O(log(size() + N)), where N is the number of elements in the range. //! O(log(size() + N)), where N is the number of elements in the range.
@@ -547,14 +547,14 @@ class set
//! //!
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class Destroyer> template<class Disposer>
iterator erase_and_destroy(iterator b, iterator e, Destroyer destroyer) iterator erase_and_dispose(iterator b, iterator e, Disposer disposer)
{ return tree_.erase_and_destroy(b, e, destroyer); } { return tree_.erase_and_dispose(b, e, disposer); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements with the given value. //! <b>Effects</b>: Erases all the elements with the given value.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Throws</b>: If the internal Compare ordering function throws. //! <b>Throws</b>: If the internal Compare ordering function throws.
//! //!
@@ -564,15 +564,15 @@ class set
//! //!
//! <b>Note</b>: Invalidates the iterators (but not the references) //! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called. //! to the erased elements. No destructors are called.
template<class Destroyer> template<class Disposer>
size_type erase_and_destroy(const_reference value, Destroyer destroyer) size_type erase_and_dispose(const_reference value, Disposer disposer)
{ return tree_.erase_and_destroy(value, destroyer); } { return tree_.erase_and_dispose(value, disposer); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements with the given key. //! <b>Effects</b>: Erases all the elements with the given key.
//! according to the comparison functor "comp". //! according to the comparison functor "comp".
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Returns</b>: The number of erased elements. //! <b>Returns</b>: The number of erased elements.
//! //!
@@ -582,9 +582,9 @@ class set
//! //!
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class KeyType, class KeyValueCompare, class Destroyer> template<class KeyType, class KeyValueCompare, class Disposer>
size_type erase_and_destroy(const KeyType& key, KeyValueCompare comp, Destroyer destroyer) size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
{ return tree_.erase_and_destroy(key, comp, destroyer); } { return tree_.erase_and_dispose(key, comp, disposer); }
//! <b>Effects</b>: Erases all the elements of the container. //! <b>Effects</b>: Erases all the elements of the container.
//! //!
@@ -598,20 +598,20 @@ class set
void clear() void clear()
{ return tree_.clear(); } { return tree_.clear(); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements of the container. //! <b>Effects</b>: Erases all the elements of the container.
//! //!
//! <b>Complexity</b>: Linear to the number of elements on the container. //! <b>Complexity</b>: Linear to the number of elements on the container.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
//! //!
//! <b>Note</b>: Invalidates the iterators (but not the references) //! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called. //! to the erased elements. No destructors are called.
template<class Destroyer> template<class Disposer>
void clear_and_destroy(Destroyer destroyer) void clear_and_dispose(Disposer disposer)
{ return tree_.clear_and_destroy(destroyer); } { return tree_.clear_and_dispose(disposer); }
//! <b>Effects</b>: Returns the number of contained elements with the given key //! <b>Effects</b>: Returns the number of contained elements with the given key
//! //!
@@ -1188,22 +1188,22 @@ class multiset
void swap(multiset& other) void swap(multiset& other)
{ tree_.swap(other.tree_); } { tree_.swap(other.tree_); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements from *this //! <b>Effects</b>: Erases all the elements from *this
//! calling Destroyer::operator()(pointer), clones all the //! calling Disposer::operator()(pointer), clones all the
//! elements from src calling Cloner::operator()(const_reference ) //! elements from src calling Cloner::operator()(const_reference )
//! and inserts them on *this. //! and inserts them on *this.
//! //!
//! If cloner throws, all cloned elements are unlinked and destroyed //! If cloner throws, all cloned elements are unlinked and disposed
//! calling Destroyer::operator()(pointer). //! calling Disposer::operator()(pointer).
//! //!
//! <b>Complexity</b>: Linear to erased plus inserted elements. //! <b>Complexity</b>: Linear to erased plus inserted elements.
//! //!
//! <b>Throws</b>: If cloner throws. Basic guarantee. //! <b>Throws</b>: If cloner throws. Basic guarantee.
template <class Cloner, class Destroyer> template <class Cloner, class Disposer>
void clone_from(const multiset &src, Cloner cloner, Destroyer destroyer) void clone_from(const multiset &src, Cloner cloner, Disposer disposer)
{ tree_.clone_from(src.tree_, cloner, destroyer); } { tree_.clone_from(src.tree_, cloner, disposer); }
//! <b>Requires</b>: value must be an lvalue //! <b>Requires</b>: value must be an lvalue
//! //!
@@ -1315,12 +1315,12 @@ class multiset
size_type erase(const KeyType& key, KeyValueCompare comp) size_type erase(const KeyType& key, KeyValueCompare comp)
{ return tree_.erase(key, comp); } { return tree_.erase(key, comp); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Returns</b>: An iterator to the element after the erased element. //! <b>Returns</b>: An iterator to the element after the erased element.
//! //!
//! <b>Effects</b>: Erases the element pointed to by pos. //! <b>Effects</b>: Erases the element pointed to by pos.
//! Destroyer::operator()(pointer) is called for the removed element. //! Disposer::operator()(pointer) is called for the removed element.
//! //!
//! <b>Complexity</b>: Average complexity for erase element is constant time. //! <b>Complexity</b>: Average complexity for erase element is constant time.
//! //!
@@ -1328,16 +1328,16 @@ class multiset
//! //!
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class Destroyer> template<class Disposer>
iterator erase_and_destroy(iterator i, Destroyer destroyer) iterator erase_and_dispose(iterator i, Disposer disposer)
{ return tree_.erase_and_destroy(i, destroyer); } { return tree_.erase_and_dispose(i, disposer); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Returns</b>: An iterator to the element after the erased elements. //! <b>Returns</b>: An iterator to the element after the erased elements.
//! //!
//! <b>Effects</b>: Erases the range pointed to by b end e. //! <b>Effects</b>: Erases the range pointed to by b end e.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Complexity</b>: Average complexity for erase range is at most //! <b>Complexity</b>: Average complexity for erase range is at most
//! O(log(size() + N)), where N is the number of elements in the range. //! O(log(size() + N)), where N is the number of elements in the range.
@@ -1346,14 +1346,14 @@ class multiset
//! //!
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class Destroyer> template<class Disposer>
iterator erase_and_destroy(iterator b, iterator e, Destroyer destroyer) iterator erase_and_dispose(iterator b, iterator e, Disposer disposer)
{ return tree_.erase_and_destroy(b, e, destroyer); } { return tree_.erase_and_dispose(b, e, disposer); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements with the given value. //! <b>Effects</b>: Erases all the elements with the given value.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Returns</b>: The number of erased elements. //! <b>Returns</b>: The number of erased elements.
//! //!
@@ -1363,15 +1363,15 @@ class multiset
//! //!
//! <b>Note</b>: Invalidates the iterators (but not the references) //! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called. //! to the erased elements. No destructors are called.
template<class Destroyer> template<class Disposer>
size_type erase_and_destroy(const_reference value, Destroyer destroyer) size_type erase_and_dispose(const_reference value, Disposer disposer)
{ return tree_.erase_and_destroy(value, destroyer); } { return tree_.erase_and_dispose(value, disposer); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements with the given key. //! <b>Effects</b>: Erases all the elements with the given key.
//! according to the comparison functor "comp". //! according to the comparison functor "comp".
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Returns</b>: The number of erased elements. //! <b>Returns</b>: The number of erased elements.
//! //!
@@ -1381,9 +1381,9 @@ class multiset
//! //!
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class KeyType, class KeyValueCompare, class Destroyer> template<class KeyType, class KeyValueCompare, class Disposer>
size_type erase_and_destroy(const KeyType& key, KeyValueCompare comp, Destroyer destroyer) size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
{ return tree_.erase_and_destroy(key, comp, destroyer); } { return tree_.erase_and_dispose(key, comp, disposer); }
//! <b>Effects</b>: Erases all the elements of the container. //! <b>Effects</b>: Erases all the elements of the container.
//! //!
@@ -1397,20 +1397,20 @@ class multiset
void clear() void clear()
{ return tree_.clear(); } { return tree_.clear(); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements of the container. //! <b>Effects</b>: Erases all the elements of the container.
//! //!
//! <b>Complexity</b>: Linear to the number of elements on the container. //! <b>Complexity</b>: Linear to the number of elements on the container.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
//! //!
//! <b>Note</b>: Invalidates the iterators (but not the references) //! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called. //! to the erased elements. No destructors are called.
template<class Destroyer> template<class Disposer>
void clear_and_destroy(Destroyer destroyer) void clear_and_dispose(Disposer disposer)
{ return tree_.clear_and_destroy(destroyer); } { return tree_.clear_and_dispose(disposer); }
//! <b>Effects</b>: Returns the number of contained elements with the same key //! <b>Effects</b>: Returns the number of contained elements with the same key
//! compared with the given comparison functor. //! compared with the given comparison functor.

View File

@@ -23,7 +23,6 @@
#include <boost/intrusive/linking_policy.hpp> #include <boost/intrusive/linking_policy.hpp>
#include <boost/intrusive/tag.hpp> #include <boost/intrusive/tag.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <stdexcept>
namespace boost { namespace boost {
namespace intrusive { namespace intrusive {

View File

@@ -15,16 +15,14 @@
#define BOOST_INTRUSIVE_SLIST_HPP #define BOOST_INTRUSIVE_SLIST_HPP
#include <boost/intrusive/detail/config_begin.hpp> #include <boost/intrusive/detail/config_begin.hpp>
#include <boost/utility.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/assert.hpp> #include <boost/intrusive/detail/assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/intrusive/intrusive_fwd.hpp> #include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/slist_hook.hpp> #include <boost/intrusive/slist_hook.hpp>
#include <boost/intrusive/circular_slist_algorithms.hpp> #include <boost/intrusive/circular_slist_algorithms.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp> #include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/linking_policy.hpp> #include <boost/intrusive/linking_policy.hpp>
#include <iterator> #include <functional>
#include <cstddef> #include <cstddef>
namespace boost { namespace boost {
@@ -187,19 +185,19 @@ class slist
} }
} }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements of the container //! <b>Effects</b>: Erases all the elements of the container
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
//! //!
//! <b>Complexity</b>: Linear to the number of elements of the list. //! <b>Complexity</b>: Linear to the number of elements of the list.
//! //!
//! <b>Note</b>: Invalidates the iterators to the erased elements. //! <b>Note</b>: Invalidates the iterators to the erased elements.
template <class Destroyer> template <class Disposer>
void clear_and_destroy(Destroyer destroyer) void clear_and_dispose(Disposer disposer)
{ this->erase_after_and_destroy(this->before_begin(), this->end(), destroyer); } { this->erase_after_and_dispose(this->before_begin(), this->end(), disposer); }
//! <b>Requires</b>: value must be an lvalue. //! <b>Requires</b>: value must be an lvalue.
//! //!
@@ -215,7 +213,7 @@ class slist
{ {
node_ptr to_insert = ValueTraits::to_node_ptr(value); node_ptr to_insert = ValueTraits::to_node_ptr(value);
if(safemode_or_autounlink) if(safemode_or_autounlink)
BOOST_ASSERT(node_algorithms::unique(to_insert)); BOOST_INTRUSIVE_SAFE_MODE_CONTAINER_INSERTION_ASSERT(node_algorithms::unique(to_insert));
node_algorithms::link_after(this->get_root_node(), to_insert); node_algorithms::link_after(this->get_root_node(), to_insert);
size_traits::increment(); size_traits::increment();
} }
@@ -237,22 +235,22 @@ class slist
node_algorithms::init(to_erase); node_algorithms::init(to_erase);
} }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the first element of the list. //! <b>Effects</b>: Erases the first element of the list.
//! Destroyer::operator()(pointer) is called for the removed element. //! Disposer::operator()(pointer) is called for the removed element.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
//! //!
//! <b>Note</b>: Invalidates the iterators to the erased element. //! <b>Note</b>: Invalidates the iterators to the erased element.
template<class Destroyer> template<class Disposer>
void pop_front_and_destroy(Destroyer destroyer) void pop_front_and_dispose(Disposer disposer)
{ {
node_ptr to_erase = node_traits::get_next(this->get_root_node()); node_ptr to_erase = node_traits::get_next(this->get_root_node());
this->pop_front(); this->pop_front();
destroyer(ValueTraits::to_value_ptr(to_erase)); disposer(ValueTraits::to_value_ptr(to_erase));
} }
//! <b>Effects</b>: Returns a reference to the first element of the list. //! <b>Effects</b>: Returns a reference to the first element of the list.
@@ -511,23 +509,23 @@ class slist
node_algorithms::link_after(new_last, root); node_algorithms::link_after(new_last, root);
} }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements from *this //! <b>Effects</b>: Erases all the elements from *this
//! calling Destroyer::operator()(pointer), clones all the //! calling Disposer::operator()(pointer), clones all the
//! elements from src calling Cloner::operator()(const_reference ) //! elements from src calling Cloner::operator()(const_reference )
//! and inserts them on *this. //! and inserts them on *this.
//! //!
//! If cloner throws, all cloned elements are unlinked and destroyed //! If cloner throws, all cloned elements are unlinked and disposed
//! calling Destroyer::operator()(pointer). //! calling Disposer::operator()(pointer).
//! //!
//! <b>Complexity</b>: Linear to erased plus inserted elements. //! <b>Complexity</b>: Linear to erased plus inserted elements.
//! //!
//! <b>Throws</b>: If cloner throws. //! <b>Throws</b>: If cloner throws.
template <class Cloner, class Destroyer> template <class Cloner, class Disposer>
void clone_from(const slist &src, Cloner cloner, Destroyer destroyer) void clone_from(const slist &src, Cloner cloner, Disposer disposer)
{ {
this->clear_and_destroy(destroyer); this->clear_and_dispose(disposer);
try{ try{
iterator prev = this->before_begin(); iterator prev = this->before_begin();
const_iterator b(src.begin()), e(src.end()); const_iterator b(src.begin()), e(src.end());
@@ -536,7 +534,7 @@ class slist
} }
} }
catch(...){ catch(...){
clear_and_destroy(destroyer); clear_and_dispose(disposer);
throw; throw;
} }
} }
@@ -558,7 +556,7 @@ class slist
{ {
node_ptr n = ValueTraits::to_node_ptr(value); node_ptr n = ValueTraits::to_node_ptr(value);
if(safemode_or_autounlink) if(safemode_or_autounlink)
BOOST_ASSERT(node_algorithms::unique(n)); BOOST_INTRUSIVE_SAFE_MODE_CONTAINER_INSERTION_ASSERT(node_algorithms::unique(n));
node_algorithms::link_after(prev_p.pointed_node(), n); node_algorithms::link_after(prev_p.pointed_node(), n);
size_traits::increment(); size_traits::increment();
return iterator (n); return iterator (n);
@@ -692,11 +690,11 @@ class slist
iterator erase(iterator first, iterator last) iterator erase(iterator first, iterator last)
{ return erase_after(this->previous(first), last); } { return erase_after(this->previous(first), last); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the element after the element pointed by prev of //! <b>Effects</b>: Erases the element after the element pointed by prev of
//! the list. //! the list.
//! Destroyer::operator()(pointer) is called for the removed element. //! Disposer::operator()(pointer) is called for the removed element.
//! //!
//! <b>Returns</b>: the first element remaining beyond the removed elements, //! <b>Returns</b>: the first element remaining beyond the removed elements,
//! or end() if no such element exists. //! or end() if no such element exists.
@@ -706,21 +704,21 @@ class slist
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
//! //!
//! <b>Note</b>: Invalidates the iterators to the erased element. //! <b>Note</b>: Invalidates the iterators to the erased element.
template<class Destroyer> template<class Disposer>
iterator erase_after_and_destroy(iterator prev, Destroyer destroyer) iterator erase_after_and_dispose(iterator prev, Disposer disposer)
{ {
iterator it(prev); ++it; iterator it(prev); ++it;
node_ptr to_erase(it.pointed_node()); node_ptr to_erase(it.pointed_node());
iterator ret(this->erase_after(prev)); iterator ret(this->erase_after(prev));
destroyer(ValueTraits::to_value_ptr(to_erase)); disposer(ValueTraits::to_value_ptr(to_erase));
return ret; return ret;
} }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the range (before_first, last) from //! <b>Effects</b>: Erases the range (before_first, last) from
//! the list. //! the list.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Returns</b>: the first element remaining beyond the removed elements, //! <b>Returns</b>: the first element remaining beyond the removed elements,
//! or end() if no such element exists. //! or end() if no such element exists.
@@ -730,21 +728,21 @@ class slist
//! <b>Complexity</b>: Lineal to the elements (last - before_first). //! <b>Complexity</b>: Lineal to the elements (last - before_first).
//! //!
//! <b>Note</b>: Invalidates the iterators to the erased element. //! <b>Note</b>: Invalidates the iterators to the erased element.
template<class Destroyer> template<class Disposer>
iterator erase_after_and_destroy(iterator before_first, iterator last, Destroyer destroyer) iterator erase_after_and_dispose(iterator before_first, iterator last, Disposer disposer)
{ {
iterator first; iterator first;
while(++(first = before_first) != last){ while(++(first = before_first) != last){
this->erase_after_and_destroy(before_first, destroyer); this->erase_after_and_dispose(before_first, disposer);
} }
return last; return last;
} }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the element pointed by i of the list. //! <b>Effects</b>: Erases the element pointed by i of the list.
//! No destructors are called. //! No destructors are called.
//! Destroyer::operator()(pointer) is called for the removed element. //! Disposer::operator()(pointer) is called for the removed element.
//! //!
//! <b>Returns</b>: the first element remaining beyond the removed element, //! <b>Returns</b>: the first element remaining beyond the removed element,
//! or end() if no such element exists. //! or end() if no such element exists.
@@ -755,16 +753,16 @@ class slist
//! //!
//! <b>Note</b>: Invalidates the iterators (but not the references) to the //! <b>Note</b>: Invalidates the iterators (but not the references) to the
//! erased element. //! erased element.
template<class Destroyer> template<class Disposer>
iterator erase_and_destroy(iterator i, Destroyer destroyer) iterator erase_and_dispose(iterator i, Disposer disposer)
{ return this->erase_after_and_destroy(this->previous(i), destroyer); } { return this->erase_after_and_dispose(this->previous(i), disposer); }
//! <b>Requires</b>: first and last must be valid iterator to elements in *this. //! <b>Requires</b>: first and last must be valid iterator to elements in *this.
//! Destroyer::operator()(pointer) shouldn't throw. //! Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the range pointed by b and e. //! <b>Effects</b>: Erases the range pointed by b and e.
//! No destructors are called. //! No destructors are called.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Returns</b>: the first element remaining beyond the removed elements, //! <b>Returns</b>: the first element remaining beyond the removed elements,
//! or end() if no such element exists. //! or end() if no such element exists.
@@ -776,9 +774,9 @@ class slist
//! //!
//! <b>Note</b>: Invalidates the iterators (but not the references) to the //! <b>Note</b>: Invalidates the iterators (but not the references) to the
//! erased elements. //! erased elements.
template<class Destroyer> template<class Disposer>
iterator erase_and_destroy(iterator first, iterator last, Destroyer destroyer) iterator erase_and_dispose(iterator first, iterator last, Disposer disposer)
{ return erase_after_and_destroy(this->previous(first), last, destroyer); } { return erase_after_and_dispose(this->previous(first), last, disposer); }
//! <b>Requires</b>: Dereferencing iterator must yield //! <b>Requires</b>: Dereferencing iterator must yield
//! an lvalue of type value_type. //! an lvalue of type value_type.
@@ -802,14 +800,14 @@ class slist
this->insert_after(before_begin(), b, e); this->insert_after(before_begin(), b, e);
} }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Requires</b>: Dereferencing iterator must yield //! <b>Requires</b>: Dereferencing iterator must yield
//! an lvalue of type value_type. //! an lvalue of type value_type.
//! //!
//! <b>Effects</b>: Clears the list and inserts the range pointed by b and e. //! <b>Effects</b>: Clears the list and inserts the range pointed by b and e.
//! No destructors or copy constructors are called. //! No destructors or copy constructors are called.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
//! //!
@@ -818,11 +816,11 @@ class slist
//! //!
//! <b>Note</b>: Invalidates the iterators (but not the references) //! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. //! to the erased elements.
template<class Iterator, class Destroyer> template<class Iterator, class Disposer>
void destroy_and_assign(Destroyer destroyer, Iterator b, Iterator e) void dispose_and_assign(Disposer disposer, Iterator b, Iterator e)
{ {
this->clear_and_destroy(destroyer); this->clear_and_dispose(disposer);
this->insert_after_and_destroy(before_begin(), b, e, destroyer); this->insert_after_and_dispose(before_begin(), b, e, disposer);
} }
//! <b>Requires</b>: prev is an iterator to an element or x.end()/x.before_begin() in x. //! <b>Requires</b>: prev is an iterator to an element or x.end()/x.before_begin() in x.
@@ -932,7 +930,7 @@ class slist
{ {
if(n){ if(n){
if(ConstantTimeSize){ if(ConstantTimeSize){
BOOST_ASSERT(std::distance(before_first, before_last) == n); BOOST_INTRUSIVE_INVARIANT_ASSERT(std::distance(before_first, before_last) == n);
node_algorithms::transfer_after node_algorithms::transfer_after
(prev_pos.pointed_node(), before_first.pointed_node(), before_last.pointed_node()); (prev_pos.pointed_node(), before_first.pointed_node(), before_last.pointed_node());
size_traits::set_size(size_traits::get_size() + n); size_traits::set_size(size_traits::get_size() + n);
@@ -1042,7 +1040,7 @@ class slist
while(i < fill && !counter[i].empty()) { while(i < fill && !counter[i].empty()) {
last_inserted = carry.merge(counter[i++], p); last_inserted = carry.merge(counter[i++], p);
} }
BOOST_ASSERT(counter[i].empty()); BOOST_INTRUSIVE_INVARIANT_ASSERT(counter[i].empty());
iterator last_element(previous_node(last_inserted, carry.end())); iterator last_element(previous_node(last_inserted, carry.end()));
if(ConstantTimeSize){ if(ConstantTimeSize){
@@ -1063,7 +1061,7 @@ class slist
for (int i = 1; i < fill; ++i) for (int i = 1; i < fill; ++i)
last_inserted = counter[i].merge(counter[i-1], p); last_inserted = counter[i].merge(counter[i-1], p);
//this->swap(counter[fill-1]); //this->swap(counter[fill-1]);
BOOST_ASSERT(this->empty()); BOOST_INTRUSIVE_INVARIANT_ASSERT(this->empty());
iterator last_element(previous_node(last_inserted, counter[--fill].end())); iterator last_element(previous_node(last_inserted, counter[--fill].end()));
if(ConstantTimeSize){ if(ConstantTimeSize){
@@ -1174,10 +1172,10 @@ class slist
void remove(const_reference value) void remove(const_reference value)
{ remove_if(detail::equal_to_value<const_reference>(value)); } { remove_if(detail::equal_to_value<const_reference>(value)); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Removes all the elements that compare equal to value. //! <b>Effects</b>: Removes all the elements that compare equal to value.
//! Destroyer::operator()(pointer) is called for every removed element. //! Disposer::operator()(pointer) is called for every removed element.
//! //!
//! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee. //! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee.
//! //!
@@ -1185,9 +1183,9 @@ class slist
//! //!
//! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
template<class Destroyer> template<class Disposer>
void remove_and_destroy(const_reference value, Destroyer destroyer) void remove_and_dispose(const_reference value, Disposer disposer)
{ remove_and_destroy_if(detail::equal_to_value<const_reference>(value), destroyer); } { remove_and_dispose_if(detail::equal_to_value<const_reference>(value), disposer); }
//! <b>Effects</b>: Removes all the elements for which a specified //! <b>Effects</b>: Removes all the elements for which a specified
//! predicate is satisfied. No destructors are called. //! predicate is satisfied. No destructors are called.
@@ -1200,13 +1198,13 @@ class slist
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
template<class Pred> template<class Pred>
void remove_if(Pred pred) void remove_if(Pred pred)
{ remove_and_destroy_if(pred, detail::null_destroyer()); } { remove_and_dispose_if(pred, detail::null_disposer()); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Removes all the elements for which a specified //! <b>Effects</b>: Removes all the elements for which a specified
//! predicate is satisfied. //! predicate is satisfied.
//! Destroyer::operator()(pointer) is called for every removed element. //! Disposer::operator()(pointer) is called for every removed element.
//! //!
//! <b>Throws</b>: If pred throws. Basic guarantee. //! <b>Throws</b>: If pred throws. Basic guarantee.
//! //!
@@ -1214,8 +1212,8 @@ class slist
//! //!
//! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
template<class Pred, class Destroyer> template<class Pred, class Disposer>
void remove_and_destroy_if(Pred pred, Destroyer destroyer) void remove_and_dispose_if(Pred pred, Disposer disposer)
{ {
iterator bcur(this->before_begin()), cur, e(this->end()); iterator bcur(this->before_begin()), cur, e(this->end());
@@ -1223,7 +1221,7 @@ class slist
if (pred(*cur)){ if (pred(*cur)){
pointer p = cur.operator->(); pointer p = cur.operator->();
this->erase_after(bcur); this->erase_after(bcur);
destroyer(p); disposer(p);
} }
else{ else{
++bcur; ++bcur;
@@ -1241,7 +1239,7 @@ class slist
//! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
void unique() void unique()
{ unique_and_destroy(std::equal_to<value_type>(), detail::null_destroyer()); } { unique_and_dispose(std::equal_to<value_type>(), detail::null_disposer()); }
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
//! elements that satisfy some binary predicate from the list. //! elements that satisfy some binary predicate from the list.
@@ -1255,13 +1253,13 @@ class slist
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
template<class BinaryPredicate> template<class BinaryPredicate>
void unique(BinaryPredicate pred) void unique(BinaryPredicate pred)
{ unique_and_destroy(pred, detail::null_destroyer()); } { unique_and_dispose(pred, detail::null_disposer()); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
//! elements that satisfy some binary predicate from the list. //! elements that satisfy some binary predicate from the list.
//! Destroyer::operator()(pointer) is called for every removed element. //! Disposer::operator()(pointer) is called for every removed element.
//! //!
//! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee. //! <b>Throws</b>: If std::equal_to<value_type> throws. Basic guarantee.
//! //!
@@ -1269,15 +1267,15 @@ class slist
//! //!
//! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
template<class Destroyer> template<class Disposer>
void unique_and_destroy(Destroyer destroyer) void unique_and_dispose(Disposer disposer)
{ unique(std::equal_to<value_type>(), destroyer); } { unique(std::equal_to<value_type>(), disposer); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Removes adjacent duplicate elements or adjacent //! <b>Effects</b>: Removes adjacent duplicate elements or adjacent
//! elements that satisfy some binary predicate from the list. //! elements that satisfy some binary predicate from the list.
//! Destroyer::operator()(pointer) is called for every removed element. //! Disposer::operator()(pointer) is called for every removed element.
//! //!
//! <b>Throws</b>: If the predicate throws. Basic guarantee. //! <b>Throws</b>: If the predicate throws. Basic guarantee.
//! //!
@@ -1285,8 +1283,8 @@ class slist
//! //!
//! <b>Note</b>: The relative order of elements that are not removed is unchanged, //! <b>Note</b>: The relative order of elements that are not removed is unchanged,
//! and iterators to elements that are not removed remain valid. //! and iterators to elements that are not removed remain valid.
template<class BinaryPredicate, class Destroyer> template<class BinaryPredicate, class Disposer>
void unique_and_destroy(BinaryPredicate pred, Destroyer destroyer) void unique_and_dispose(BinaryPredicate pred, Disposer disposer)
{ {
iterator end_n(end()); iterator end_n(end());
iterator cur(begin()); iterator cur(begin());
@@ -1297,7 +1295,7 @@ class slist
if (pred(*cur, *cur_next)){ if (pred(*cur, *cur_next)){
pointer p = cur_next.operator->(); pointer p = cur_next.operator->();
this->erase_after(cur); this->erase_after(cur);
destroyer(p); disposer(p);
} }
else{ else{
++cur; ++cur;
@@ -1317,7 +1315,7 @@ class slist
//! <b>Note</b>: Iterators and references are not invalidated. //! <b>Note</b>: Iterators and references are not invalidated.
static iterator iterator_to(reference value) static iterator iterator_to(reference value)
{ {
BOOST_ASSERT (!node_algorithms::unique(ValueTraits::to_node_ptr(value))); BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::unique(ValueTraits::to_node_ptr(value)));
return iterator (ValueTraits::to_node_ptr(value)); return iterator (ValueTraits::to_node_ptr(value));
} }
@@ -1332,7 +1330,7 @@ class slist
//! <b>Note</b>: Iterators and references are not invalidated. //! <b>Note</b>: Iterators and references are not invalidated.
static const_iterator iterator_to(const_reference value) static const_iterator iterator_to(const_reference value)
{ {
BOOST_ASSERT (!node_algorithms::unique(ValueTraits::to_node_ptr(const_cast<reference> (value)))); BOOST_INTRUSIVE_INVARIANT_ASSERT (!node_algorithms::unique(ValueTraits::to_node_ptr(const_cast<reference> (value))));
return const_iterator (ValueTraits::to_node_ptr(const_cast<reference> (value))); return const_iterator (ValueTraits::to_node_ptr(const_cast<reference> (value)));
} }

View File

@@ -23,7 +23,6 @@
#include <boost/intrusive/linking_policy.hpp> #include <boost/intrusive/linking_policy.hpp>
#include <boost/intrusive/tag.hpp> #include <boost/intrusive/tag.hpp>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <stdexcept>
namespace boost { namespace boost {
namespace intrusive { namespace intrusive {

View File

@@ -121,8 +121,8 @@ class unordered_set
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks) //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
//! or the copy constructor or invocation of Hash or Equal throws. //! or the copy constructor or invocation of Hash or Equal throws.
//! //!
//! <b>Notes</b>: buckets array must be destroyed only after //! <b>Notes</b>: buckets array must be disposed only after
//! *this is destroyed. //! *this is disposed.
unordered_set( bucket_ptr buckets unordered_set( bucket_ptr buckets
, size_type buckets_len , size_type buckets_len
, const Hash & hasher = Hash() , const Hash & hasher = Hash()
@@ -143,8 +143,8 @@ class unordered_set
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks) //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
//! or the copy constructor or invocation of Hash or Equal throws. //! or the copy constructor or invocation of Hash or Equal throws.
//! //!
//! <b>Notes</b>: buckets array must be destroyed only after //! <b>Notes</b>: buckets array must be disposed only after
//! *this is destroyed. //! *this is disposed.
template<class Iterator> template<class Iterator>
unordered_set( bucket_ptr buckets unordered_set( bucket_ptr buckets
, size_type buckets_len , size_type buckets_len
@@ -266,22 +266,22 @@ class unordered_set
void swap(unordered_set& other) void swap(unordered_set& other)
{ table_.swap(other.table_); } { table_.swap(other.table_); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements from *this //! <b>Effects</b>: Erases all the elements from *this
//! calling Destroyer::operator()(pointer), clones all the //! calling Disposer::operator()(pointer), clones all the
//! elements from src calling Cloner::operator()(const_reference ) //! elements from src calling Cloner::operator()(const_reference )
//! and inserts them on *this. //! and inserts them on *this.
//! //!
//! If cloner throws, all cloned elements are unlinked and destroyed //! If cloner throws, all cloned elements are unlinked and disposed
//! calling Destroyer::operator()(pointer). //! calling Disposer::operator()(pointer).
//! //!
//! <b>Complexity</b>: Linear to erased plus inserted elements. //! <b>Complexity</b>: Linear to erased plus inserted elements.
//! //!
//! <b>Throws</b>: If cloner throws. Basic guarantee. //! <b>Throws</b>: If cloner throws. Basic guarantee.
template <class Cloner, class Destroyer> template <class Cloner, class Disposer>
void clone_from(const unordered_set &src, Cloner cloner, Destroyer destroyer) void clone_from(const unordered_set &src, Cloner cloner, Disposer disposer)
{ table_.clone_from(src.table_, cloner, destroyer); } { table_.clone_from(src.table_, cloner, disposer); }
//! <b>Requires</b>: value must be an lvalue //! <b>Requires</b>: value must be an lvalue
//! //!
@@ -441,10 +441,10 @@ class unordered_set
size_type erase(const KeyType& key, KeyHasher hasher, KeyValueEqual equal) size_type erase(const KeyType& key, KeyHasher hasher, KeyValueEqual equal)
{ return table_.erase(key, hasher, equal); } { return table_.erase(key, hasher, equal); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the element pointed to by i. //! <b>Effects</b>: Erases the element pointed to by i.
//! Destroyer::operator()(pointer) is called for the removed element. //! Disposer::operator()(pointer) is called for the removed element.
//! //!
//! <b>Complexity</b>: Average case O(1), worst case O(this->size()). //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
//! //!
@@ -452,14 +452,14 @@ class unordered_set
//! //!
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class Destroyer> template<class Disposer>
iterator erase_and_destroy(const_iterator i, Destroyer destroyer) iterator erase_and_dispose(const_iterator i, Disposer disposer)
{ return table_.erase_and_destroy(i, destroyer); } { return table_.erase_and_dispose(i, disposer); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the range pointed to by b end e. //! <b>Effects</b>: Erases the range pointed to by b end e.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Complexity</b>: Average case O(std::distance(b, e)), //! <b>Complexity</b>: Average case O(std::distance(b, e)),
//! worst case O(this->size()). //! worst case O(this->size()).
@@ -468,14 +468,14 @@ class unordered_set
//! //!
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class Destroyer> template<class Disposer>
iterator erase_and_destroy(const_iterator b, const_iterator e, Destroyer destroyer) iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
{ return table_.erase_and_destroy(b, e, destroyer); } { return table_.erase_and_dispose(b, e, disposer); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements with the given value. //! <b>Effects</b>: Erases all the elements with the given value.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Returns</b>: The number of erased elements. //! <b>Returns</b>: The number of erased elements.
//! //!
@@ -486,15 +486,15 @@ class unordered_set
//! //!
//! <b>Note</b>: Invalidates the iterators (but not the references) //! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called. //! to the erased elements. No destructors are called.
template<class Destroyer> template<class Disposer>
size_type erase_and_destroy(const_reference value, Destroyer destroyer) size_type erase_and_dispose(const_reference value, Disposer disposer)
{ return table_.erase_and_destroy(value, destroyer); } { return table_.erase_and_dispose(value, disposer); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements with the given key. //! <b>Effects</b>: Erases all the elements with the given key.
//! according to the comparison functor "equal". //! according to the comparison functor "equal".
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Returns</b>: The number of erased elements. //! <b>Returns</b>: The number of erased elements.
//! //!
@@ -505,9 +505,9 @@ class unordered_set
//! //!
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class KeyType, class KeyHasher, class KeyValueEqual, class Destroyer> template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
size_type erase_and_destroy(const KeyType& key, KeyHasher hasher, KeyValueEqual equal, Destroyer destroyer) size_type erase_and_dispose(const KeyType& key, KeyHasher hasher, KeyValueEqual equal, Disposer disposer)
{ return table_.erase_and_destroy(key, hasher, equal, destroyer); } { return table_.erase_and_dispose(key, hasher, equal, disposer); }
//! <b>Effects</b>: Erases all of the elements. //! <b>Effects</b>: Erases all of the elements.
//! //!
@@ -521,20 +521,20 @@ class unordered_set
void clear() void clear()
{ return table_.clear(); } { return table_.clear(); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all of the elements. //! <b>Effects</b>: Erases all of the elements.
//! //!
//! <b>Complexity</b>: Linear to the number of elements on the container. //! <b>Complexity</b>: Linear to the number of elements on the container.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
//! //!
//! <b>Note</b>: Invalidates the iterators (but not the references) //! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called. //! to the erased elements. No destructors are called.
template<class Destroyer> template<class Disposer>
void clear_and_destroy(Destroyer destroyer) void clear_and_dispose(Disposer disposer)
{ return table_.clear_and_destroy(destroyer); } { return table_.clear_and_dispose(disposer); }
//! <b>Effects</b>: Returns the number of contained elements with the given value //! <b>Effects</b>: Returns the number of contained elements with the given value
//! //!
@@ -557,7 +557,7 @@ class unordered_set
//! <b>Complexity</b>: Average case O(1), worst case O(this->size()). //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
//! //!
//! <b>Throws</b>: If hasher or equal throw. //! <b>Throws</b>: If hasher or equal throw.
template<class KeyType, class KeyHasher, class KeyValueEqual, class Destroyer> template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
size_type count(const KeyType& key, KeyHasher hasher, KeyValueEqual equal) const size_type count(const KeyType& key, KeyHasher hasher, KeyValueEqual equal) const
{ return table_.find(key, hasher, equal) != end(); } { return table_.find(key, hasher, equal) != end(); }
@@ -1019,8 +1019,8 @@ class unordered_multiset
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks) //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
//! or the copy constructor or invocation of Hash or Equal throws. //! or the copy constructor or invocation of Hash or Equal throws.
//! //!
//! <b>Notes</b>: buckets array must be destroyed only after //! <b>Notes</b>: buckets array must be disposed only after
//! *this is destroyed. //! *this is disposed.
unordered_multiset ( bucket_ptr buckets unordered_multiset ( bucket_ptr buckets
, size_type buckets_len , size_type buckets_len
, const Hash & hasher = Hash() , const Hash & hasher = Hash()
@@ -1041,8 +1041,8 @@ class unordered_multiset
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks) //! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
//! or the copy constructor or invocation of Hash or Equal throws. //! or the copy constructor or invocation of Hash or Equal throws.
//! //!
//! <b>Notes</b>: buckets array must be destroyed only after //! <b>Notes</b>: buckets array must be disposed only after
//! *this is destroyed. //! *this is disposed.
template<class Iterator> template<class Iterator>
unordered_multiset ( bucket_ptr buckets unordered_multiset ( bucket_ptr buckets
, size_type buckets_len , size_type buckets_len
@@ -1165,22 +1165,22 @@ class unordered_multiset
void swap(unordered_multiset& other) void swap(unordered_multiset& other)
{ table_.swap(other.table_); } { table_.swap(other.table_); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements from *this //! <b>Effects</b>: Erases all the elements from *this
//! calling Destroyer::operator()(pointer), clones all the //! calling Disposer::operator()(pointer), clones all the
//! elements from src calling Cloner::operator()(const_reference ) //! elements from src calling Cloner::operator()(const_reference )
//! and inserts them on *this. //! and inserts them on *this.
//! //!
//! If cloner throws, all cloned elements are unlinked and destroyed //! If cloner throws, all cloned elements are unlinked and disposed
//! calling Destroyer::operator()(pointer). //! calling Disposer::operator()(pointer).
//! //!
//! <b>Complexity</b>: Linear to erased plus inserted elements. //! <b>Complexity</b>: Linear to erased plus inserted elements.
//! //!
//! <b>Throws</b>: If cloner throws. //! <b>Throws</b>: If cloner throws.
template <class Cloner, class Destroyer> template <class Cloner, class Disposer>
void clone_from(const unordered_multiset &src, Cloner cloner, Destroyer destroyer) void clone_from(const unordered_multiset &src, Cloner cloner, Disposer disposer)
{ table_.clone_from(src.table_, cloner, destroyer); } { table_.clone_from(src.table_, cloner, disposer); }
//! <b>Requires</b>: value must be an lvalue //! <b>Requires</b>: value must be an lvalue
//! //!
@@ -1275,10 +1275,10 @@ class unordered_multiset
size_type erase(const KeyType& key, KeyHasher hasher, KeyValueEqual equal) size_type erase(const KeyType& key, KeyHasher hasher, KeyValueEqual equal)
{ return table_.erase(key, hasher, equal); } { return table_.erase(key, hasher, equal); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the element pointed to by i. //! <b>Effects</b>: Erases the element pointed to by i.
//! Destroyer::operator()(pointer) is called for the removed element. //! Disposer::operator()(pointer) is called for the removed element.
//! //!
//! <b>Complexity</b>: Average case O(1), worst case O(this->size()). //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
//! //!
@@ -1286,14 +1286,14 @@ class unordered_multiset
//! //!
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class Destroyer> template<class Disposer>
void erase_and_destroy(const_iterator i, Destroyer destroyer) void erase_and_dispose(const_iterator i, Disposer disposer)
{ table_.erase_and_destroy(i, destroyer); } { table_.erase_and_dispose(i, disposer); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases the range pointed to by b end e. //! <b>Effects</b>: Erases the range pointed to by b end e.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Complexity</b>: Average case O(std::distance(b, e)), //! <b>Complexity</b>: Average case O(std::distance(b, e)),
//! worst case O(this->size()). //! worst case O(this->size()).
@@ -1302,14 +1302,14 @@ class unordered_multiset
//! //!
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class Destroyer> template<class Disposer>
void erase_and_destroy(const_iterator b, const_iterator e, Destroyer destroyer) void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
{ table_.erase_and_destroy(b, e, destroyer); } { table_.erase_and_dispose(b, e, disposer); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements with the given value. //! <b>Effects</b>: Erases all the elements with the given value.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Returns</b>: The number of erased elements. //! <b>Returns</b>: The number of erased elements.
//! //!
@@ -1320,15 +1320,15 @@ class unordered_multiset
//! //!
//! <b>Note</b>: Invalidates the iterators (but not the references) //! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called. //! to the erased elements. No destructors are called.
template<class Destroyer> template<class Disposer>
size_type erase_and_destroy(const_reference value, Destroyer destroyer) size_type erase_and_dispose(const_reference value, Disposer disposer)
{ return table_.erase_and_destroy(value, destroyer); } { return table_.erase_and_dispose(value, disposer); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements with the given key. //! <b>Effects</b>: Erases all the elements with the given key.
//! according to the comparison functor "equal". //! according to the comparison functor "equal".
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Returns</b>: The number of erased elements. //! <b>Returns</b>: The number of erased elements.
//! //!
@@ -1339,9 +1339,9 @@ class unordered_multiset
//! //!
//! <b>Note</b>: Invalidates the iterators //! <b>Note</b>: Invalidates the iterators
//! to the erased elements. //! to the erased elements.
template<class KeyType, class KeyHasher, class KeyValueEqual, class Destroyer> template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
size_type erase_and_destroy(const KeyType& key, KeyHasher hasher, KeyValueEqual equal, Destroyer destroyer) size_type erase_and_dispose(const KeyType& key, KeyHasher hasher, KeyValueEqual equal, Disposer disposer)
{ return table_.erase_and_destroy(key, hasher, equal, destroyer); } { return table_.erase_and_dispose(key, hasher, equal, disposer); }
//! <b>Effects</b>: Erases all the elements of the container. //! <b>Effects</b>: Erases all the elements of the container.
//! //!
@@ -1355,20 +1355,20 @@ class unordered_multiset
void clear() void clear()
{ return table_.clear(); } { return table_.clear(); }
//! <b>Requires</b>: Destroyer::operator()(pointer) shouldn't throw. //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
//! //!
//! <b>Effects</b>: Erases all the elements of the container. //! <b>Effects</b>: Erases all the elements of the container.
//! //!
//! <b>Complexity</b>: Linear to the number of elements on the container. //! <b>Complexity</b>: Linear to the number of elements on the container.
//! Destroyer::operator()(pointer) is called for the removed elements. //! Disposer::operator()(pointer) is called for the removed elements.
//! //!
//! <b>Throws</b>: Nothing. //! <b>Throws</b>: Nothing.
//! //!
//! <b>Note</b>: Invalidates the iterators (but not the references) //! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called. //! to the erased elements. No destructors are called.
template<class Destroyer> template<class Disposer>
void clear_and_destroy(Destroyer destroyer) void clear_and_dispose(Disposer disposer)
{ return table_.clear_and_destroy(destroyer); } { return table_.clear_and_dispose(disposer); }
//! <b>Effects</b>: Returns the number of contained elements with the given key //! <b>Effects</b>: Returns the number of contained elements with the given key
//! //!
@@ -1391,7 +1391,7 @@ class unordered_multiset
//! <b>Complexity</b>: Average case O(1), worst case O(this->size()). //! <b>Complexity</b>: Average case O(1), worst case O(this->size()).
//! //!
//! <b>Throws</b>: If the internal hasher or the equality functor throws. //! <b>Throws</b>: If the internal hasher or the equality functor throws.
template<class KeyType, class KeyHasher, class KeyValueEqual, class Destroyer> template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
size_type count(const KeyType& key, KeyHasher hasher, KeyValueEqual equal) const size_type count(const KeyType& key, KeyHasher hasher, KeyValueEqual equal) const
{ return table_.count(key, hasher, equal); } { return table_.count(key, hasher, equal); }

View File

@@ -20,7 +20,6 @@
#include <boost/intrusive/detail/pointer_to_other.hpp> #include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/slist_hook.hpp> #include <boost/intrusive/slist_hook.hpp>
#include <boost/intrusive/linking_policy.hpp> #include <boost/intrusive/linking_policy.hpp>
#include <stdexcept>
namespace boost { namespace boost {
namespace intrusive { namespace intrusive {