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.
//
/////////////////////////////////////////////////////////////////////////////
#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>
#endif
#define BOOST_INTRUSIVE_SELECT_COMPILER_INCLUDED
#endif
#ifdef BOOST_MSVC
#pragma warning (push)
//
//'function' : resolved overload was found by argument-dependent lookup

View File

@@ -13,18 +13,18 @@
#ifndef 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 intrusive {
namespace detail {
template<typename T, bool IsEmpty = false>
class ebo_holder_impl
template<typename T, bool IsEmpty = true>
class ebo_functor_holder_impl
{
public:
ebo_holder_impl(){}
ebo_holder_impl(const T& t):t(t){}
ebo_functor_holder_impl(){}
ebo_functor_holder_impl(const T& t):t(t){}
T& get(){return t;}
const T& get()const{return t;}
@@ -34,29 +34,29 @@ class ebo_holder_impl
};
template<typename T>
class ebo_holder_impl<T, true>
class ebo_functor_holder_impl<T, false>
: private T
{
public:
ebo_holder_impl(){}
ebo_holder_impl(const T& t):T(t){}
ebo_functor_holder_impl(){}
ebo_functor_holder_impl(const T& t):T(t){}
T& get(){return *this;}
const T& get()const{return *this;}
};
template<typename T>
class ebo_holder
: public ebo_holder_impl<T,boost::is_empty<T>::value>
class ebo_functor_holder
: public ebo_functor_holder_impl<T, is_unary_or_binary_function<T>::value>
{
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:
ebo_holder(){}
ebo_holder(const T& t):super(t){}
ebo_functor_holder(){}
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();
return *this;

View File

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

View File

@@ -16,7 +16,7 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <iterator>
#include <boost/assert.hpp>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/circular_list_algorithms.hpp>
#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
#include <boost/intrusive/detail/config_begin.hpp>
#include <cstddef>
namespace boost {
namespace intrusive {
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)
{
//The implementation of a pointer to member is compiler dependent.
#if defined(BOOST_MSVC) || defined(__GNUC__) || \
defined(BOOST_INTEL) || defined(__HP_aCC)
#if (defined(_MSC_VER) || defined(__GNUC__) || defined(BOOST_INTEL) || defined(__HP_aCC))
//This works with gcc, msvc, ac++
return *(const std::size_t*)(const void*)&ptr_to_member;
#else

View File

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

View File

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

View File

@@ -16,9 +16,11 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <boost/intrusive/detail/pointer_to_other.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/detail/mpl.hpp>
#include <cstddef>
#include <iterator>
namespace boost {
namespace intrusive {
@@ -65,7 +67,7 @@ class equal_to_value
{ return t_ == t; }
};
class null_destroyer
class null_disposer
{
public:
template <class Pointer>
@@ -155,8 +157,8 @@ struct member_value_traits
typedef typename node_traits::const_node_ptr const_node_ptr;
typedef typename boost::pointer_to_other<node_ptr, T>::type pointer;
typedef typename boost::pointer_to_other<node_ptr, const T>::type const_pointer;
typedef typename std::iterator_traits<pointer>::reference reference;
typedef typename std::iterator_traits<const_pointer>::reference const_reference;
typedef value_type & reference;
typedef const value_type & const_reference;
enum { linking_policy = MemberHookType::linking_policy };
public:
@@ -192,10 +194,10 @@ struct member_value_traits
template<class KeyValueCompare, class ValueTraits>
struct key_node_ptr_compare
: private detail::ebo_holder<KeyValueCompare>
: private detail::ebo_functor_holder<KeyValueCompare>
{
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)
: base_t(kcomp)
{}
@@ -217,10 +219,10 @@ struct key_node_ptr_compare
template<class F, class ValueTraits>
struct value_to_node_cloner
: private detail::ebo_holder<F>
: private detail::ebo_functor_holder<F>
{
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)
: base_t(f)
@@ -231,12 +233,12 @@ struct value_to_node_cloner
};
template<class F, class ValueTraits>
struct value_to_node_destroyer
: private detail::ebo_holder<F>
struct value_to_node_disposer
: private detail::ebo_functor_holder<F>
{
typedef typename ValueTraits::node_ptr node_ptr;
typedef detail::ebo_holder<F> base_t;
value_to_node_destroyer(F f)
typedef detail::ebo_functor_holder<F> base_t;
value_to_node_disposer(F f)
: base_t(f)
{}
@@ -250,7 +252,7 @@ struct dispatcher
template<class Container>
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>
void destructor_impl(Container &cont, dispatcher<auto_unlink>)
@@ -262,26 +264,26 @@ void destructor_impl(Container &, dispatcher<normal_link>)
template<class Node, class MaybeClass>
struct node_plus_pred
: public ebo_holder<MaybeClass>
: public ebo_functor_holder<MaybeClass>
, public Node
{
node_plus_pred()
{}
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)
: ebo_holder<MaybeClass>(y) {}
: ebo_functor_holder<MaybeClass>(y) {}
Node &first()
{ return *this; }
const Node &first() const
{ return *this; }
MaybeClass &second()
{ return ebo_holder<MaybeClass>::get(); }
{ return ebo_functor_holder<MaybeClass>::get(); }
const MaybeClass &second() const
{ return ebo_holder<MaybeClass>::get(); }
{ return ebo_functor_holder<MaybeClass>::get(); }
static node_plus_pred *this_from_node(Node *n)
{ return static_cast<node_plus_pred*>(n); }
@@ -290,33 +292,6 @@ struct node_plus_pred
{ 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 intrusive
} //namespace boost

View File

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

View File

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

View File

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

View File

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

View File

@@ -15,15 +15,14 @@
#include <boost/intrusive/detail/config_begin.hpp>
#include <functional>
#include <iterator>
#include <boost/utility.hpp>
#include <utility>
#include <boost/assert.hpp>
#include <boost/intrusive/detail/assert.hpp>
#include <boost/static_assert.hpp>
#include <boost/intrusive/intrusive_fwd.hpp>
#include <boost/intrusive/detail/pointer_to_other.hpp>
#include <boost/intrusive/set_hook.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/linking_policy.hpp>
#include <cstddef>
@@ -353,7 +352,7 @@ class rbtree
detail::key_node_ptr_compare<value_compare, ValueTraits> key_node_comp(priv_comp());
node_ptr to_insert(ValueTraits::to_node_ptr(value));
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();
return iterator(node_algorithms::insert_equal_upper_bound
(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());
node_ptr to_insert(ValueTraits::to_node_ptr(value));
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();
return iterator(node_algorithms::insert_equal_lower_bound
(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());
node_ptr to_insert(ValueTraits::to_node_ptr(value));
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();
return iterator(node_algorithms::insert_equal
(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));
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();
node_algorithms::insert_unique_commit
(node_ptr(&priv_header()), to_insert, commit_data);
@@ -561,7 +560,7 @@ class rbtree
++ret;
node_ptr to_erase(i.pointed_node());
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);
size_traits::decrement();
if(safemode_or_autounlink)
@@ -614,10 +613,10 @@ class rbtree
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.
//! 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.
//!
@@ -625,19 +624,19 @@ class rbtree
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class Destroyer>
iterator erase_and_destroy(iterator i, Destroyer destroyer)
template<class Disposer>
iterator erase_and_dispose(iterator i, Disposer disposer)
{
node_ptr to_erase(i.pointed_node());
iterator ret(this->erase(i));
destroyer(ValueTraits::to_value_ptr(to_erase));
disposer(ValueTraits::to_value_ptr(to_erase));
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.
//! 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
//! 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
//! to the erased elements.
template<class Destroyer>
iterator erase_and_destroy(iterator b, iterator e, Destroyer destroyer)
{ size_type n; return private_erase(b, e, n, destroyer); }
template<class Disposer>
iterator erase_and_dispose(iterator b, iterator e, Disposer disposer)
{ 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.
//! 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.
//!
@@ -663,20 +662,20 @@ class rbtree
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
template<class Destroyer>
size_type erase_and_destroy(const_reference value, Destroyer destroyer)
template<class Disposer>
size_type erase_and_dispose(const_reference value, Disposer disposer)
{
std::pair<iterator,iterator> p = this->equal_range(value);
size_type n;
private_erase(p.first, p.second, n, destroyer);
private_erase(p.first, p.second, n, disposer);
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.
//! 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.
//!
@@ -686,12 +685,12 @@ class rbtree
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class KeyType, class KeyValueCompare, class Destroyer>
size_type erase_and_destroy(const KeyType& key, KeyValueCompare comp, Destroyer destroyer)
template<class KeyType, class KeyValueCompare, class Disposer>
size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
{
std::pair<iterator,iterator> p = this->equal_range(key, comp);
size_type n;
private_erase(p.first, p.second, n, destroyer);
private_erase(p.first, p.second, n, disposer);
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.
//! <b>Complexity</b>: Average complexity for is at most O(log(size() + N)),
//! where N is the number of elements in the container.
@@ -732,9 +731,9 @@ class rbtree
//! <b>Throws</b>: Nothing.
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. Calls N times to destroyer functor.
template<class Destroyer>
void clear_and_destroy(Destroyer destroyer)
//! to the erased elements. Calls N times to disposer functor.
template<class Disposer>
void clear_and_dispose(Disposer disposer)
{
while(1){
node_ptr leftmost
@@ -745,7 +744,7 @@ class rbtree
size_traits::decrement();
if(safemode_or_autounlink)
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));
}
template <class Cloner, class Destroyer>
void clone_from(const rbtree &src, Cloner cloner, Destroyer destroyer)
template <class Cloner, class Disposer>
void clone_from(const rbtree &src, Cloner cloner, Disposer disposer)
{
this->clear_and_destroy(destroyer);
this->clear_and_dispose(disposer);
if(!src.empty()){
node_algorithms::clone_tree
(const_node_ptr(&src.priv_header())
,node_ptr(&this->priv_header())
,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());
}
}
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())));
if(!to_destroy)
if(!to_be_disposed)
return 0;
size_traits::decrement();
if(safemode_or_autounlink)
node_algorithms::init(to_destroy);
return ValueTraits::to_value_ptr(to_destroy);
node_algorithms::init(to_be_disposed);
return ValueTraits::to_value_ptr(to_be_disposed);
}
//! <b>Requires</b>: value must be an lvalue and shall be in a set of
@@ -1059,11 +1058,11 @@ class rbtree
*/
/// @cond
private:
template<class Destroyer>
iterator private_erase(iterator b, iterator e, size_type &n, Destroyer destroyer)
template<class Disposer>
iterator private_erase(iterator b, iterator e, size_type &n, Disposer disposer)
{
for(n = 0; b != e; ++n)
this->erase_and_destroy(b++, destroyer);
this->erase_and_dispose(b++, disposer);
return b;
}

View File

@@ -40,11 +40,11 @@
#define BOOST_INTRUSIVE_RBTREE_ALGORITHMS_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 <cstddef>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/intrusive/detail/utilities.hpp>
namespace boost {
@@ -113,6 +113,16 @@ class rbtree_algorithms
typedef typename NodeTraits::const_node_ptr const_node_ptr;
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
struct insert_commit_data
{
@@ -479,30 +489,30 @@ class rbtree_algorithms
}
//! <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.
//!
//! <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.
//!
//! Then, duplicates the entire tree pointed by "source_header" cloning each
//! 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
//! 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.
//! 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.
template <class Cloner, class Destroyer>
//! <b>Throws</b>: If cloner functor throws. If this happens target nodes are disposed.
template <class Cloner, class Disposer>
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)){
node_ptr p;
while((p = unlink_leftmost_without_rebalance(target_header))){
destroyer(p);
disposer(p);
}
}
@@ -512,7 +522,7 @@ class rbtree_algorithms
NodeTraits::set_parent
( 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_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)
{
//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);
}
/// @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,
//! 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());
}
template <class Cloner, class Destroyer>
template <class Cloner, class Disposer>
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.
node_ptr top = cloner(source_root);
@@ -1112,7 +1117,7 @@ class rbtree_algorithms
if(NodeTraits::get_right(source_root)){
NodeTraits::set_right
(top, deep_clone_node(NodeTraits::get_right(source_root), top
,cloner, destroyer));
,cloner, disposer));
}
new_parent = top;
source_root = NodeTraits::get_left(source_root);
@@ -1124,28 +1129,28 @@ class rbtree_algorithms
if(NodeTraits::get_right(source_root)){
NodeTraits::set_right(y, deep_clone_node(NodeTraits::get_right(source_root), y
,cloner, destroyer));
,cloner, disposer));
}
new_parent = y;
source_root = NodeTraits::get_left(source_root);
}
}
BOOST_CATCH(...){
deep_destroy_node(top, destroyer);
deep_dispose_node(top, disposer);
BOOST_RETHROW;
}
BOOST_CATCH_END
return top;
}
template<class Destroyer>
static void deep_destroy_node(node_ptr x, Destroyer destroyer)
template<class Disposer>
static void deep_dispose_node(node_ptr x, Disposer disposer)
{
// erase without rebalancing
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);
destroyer(x);
disposer(x);
x = y;
}
}

View File

@@ -296,22 +296,22 @@ class set
void swap(set& other)
{ 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
//! calling Destroyer::operator()(pointer), clones all the
//! calling Disposer::operator()(pointer), clones all the
//! elements from src calling Cloner::operator()(const_reference )
//! and inserts them on *this.
//!
//! If cloner throws, all cloned elements are unlinked and destroyed
//! calling Destroyer::operator()(pointer).
//! If cloner throws, all cloned elements are unlinked and disposed
//! calling Disposer::operator()(pointer).
//!
//! <b>Complexity</b>: Linear to erased plus inserted elements.
//!
//! <b>Throws</b>: If cloner throws.
template <class Cloner, class Destroyer>
void clone_from(const set &src, Cloner cloner, Destroyer destroyer)
{ tree_.clone_from(src.tree_, cloner, destroyer); }
template <class Cloner, class Disposer>
void clone_from(const set &src, Cloner cloner, Disposer disposer)
{ tree_.clone_from(src.tree_, cloner, disposer); }
//! <b>Requires</b>: value must be an lvalue
//!
@@ -516,10 +516,10 @@ class set
size_type erase(const KeyType& key, KeyValueCompare 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.
//! 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.
//!
@@ -529,14 +529,14 @@ class set
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class Destroyer>
iterator erase_and_destroy(iterator i, Destroyer destroyer)
{ return tree_.erase_and_destroy(i, destroyer); }
template<class Disposer>
iterator erase_and_dispose(iterator i, Disposer disposer)
{ 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.
//! 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
//! 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
//! to the erased elements.
template<class Destroyer>
iterator erase_and_destroy(iterator b, iterator e, Destroyer destroyer)
{ return tree_.erase_and_destroy(b, e, destroyer); }
template<class Disposer>
iterator erase_and_dispose(iterator b, iterator e, Disposer disposer)
{ 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.
//! 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.
//!
@@ -564,15 +564,15 @@ class set
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
template<class Destroyer>
size_type erase_and_destroy(const_reference value, Destroyer destroyer)
{ return tree_.erase_and_destroy(value, destroyer); }
template<class Disposer>
size_type erase_and_dispose(const_reference value, Disposer disposer)
{ 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.
//! 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.
//!
@@ -582,9 +582,9 @@ class set
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class KeyType, class KeyValueCompare, class Destroyer>
size_type erase_and_destroy(const KeyType& key, KeyValueCompare comp, Destroyer destroyer)
{ return tree_.erase_and_destroy(key, comp, destroyer); }
template<class KeyType, class KeyValueCompare, class Disposer>
size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
{ return tree_.erase_and_dispose(key, comp, disposer); }
//! <b>Effects</b>: Erases all the elements of the container.
//!
@@ -598,20 +598,20 @@ class set
void 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>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>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
template<class Destroyer>
void clear_and_destroy(Destroyer destroyer)
{ return tree_.clear_and_destroy(destroyer); }
template<class Disposer>
void clear_and_dispose(Disposer disposer)
{ return tree_.clear_and_dispose(disposer); }
//! <b>Effects</b>: Returns the number of contained elements with the given key
//!
@@ -1188,22 +1188,22 @@ class multiset
void swap(multiset& other)
{ 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
//! calling Destroyer::operator()(pointer), clones all the
//! calling Disposer::operator()(pointer), clones all the
//! elements from src calling Cloner::operator()(const_reference )
//! and inserts them on *this.
//!
//! If cloner throws, all cloned elements are unlinked and destroyed
//! calling Destroyer::operator()(pointer).
//! If cloner throws, all cloned elements are unlinked and disposed
//! calling Disposer::operator()(pointer).
//!
//! <b>Complexity</b>: Linear to erased plus inserted elements.
//!
//! <b>Throws</b>: If cloner throws. Basic guarantee.
template <class Cloner, class Destroyer>
void clone_from(const multiset &src, Cloner cloner, Destroyer destroyer)
{ tree_.clone_from(src.tree_, cloner, destroyer); }
template <class Cloner, class Disposer>
void clone_from(const multiset &src, Cloner cloner, Disposer disposer)
{ tree_.clone_from(src.tree_, cloner, disposer); }
//! <b>Requires</b>: value must be an lvalue
//!
@@ -1315,12 +1315,12 @@ class multiset
size_type erase(const KeyType& key, KeyValueCompare 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>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.
//!
@@ -1328,16 +1328,16 @@ class multiset
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class Destroyer>
iterator erase_and_destroy(iterator i, Destroyer destroyer)
{ return tree_.erase_and_destroy(i, destroyer); }
template<class Disposer>
iterator erase_and_dispose(iterator i, Disposer disposer)
{ 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>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
//! 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
//! to the erased elements.
template<class Destroyer>
iterator erase_and_destroy(iterator b, iterator e, Destroyer destroyer)
{ return tree_.erase_and_destroy(b, e, destroyer); }
template<class Disposer>
iterator erase_and_dispose(iterator b, iterator e, Disposer disposer)
{ 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.
//! 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.
//!
@@ -1363,15 +1363,15 @@ class multiset
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
template<class Destroyer>
size_type erase_and_destroy(const_reference value, Destroyer destroyer)
{ return tree_.erase_and_destroy(value, destroyer); }
template<class Disposer>
size_type erase_and_dispose(const_reference value, Disposer disposer)
{ 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.
//! 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.
//!
@@ -1381,9 +1381,9 @@ class multiset
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class KeyType, class KeyValueCompare, class Destroyer>
size_type erase_and_destroy(const KeyType& key, KeyValueCompare comp, Destroyer destroyer)
{ return tree_.erase_and_destroy(key, comp, destroyer); }
template<class KeyType, class KeyValueCompare, class Disposer>
size_type erase_and_dispose(const KeyType& key, KeyValueCompare comp, Disposer disposer)
{ return tree_.erase_and_dispose(key, comp, disposer); }
//! <b>Effects</b>: Erases all the elements of the container.
//!
@@ -1397,20 +1397,20 @@ class multiset
void 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>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>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
template<class Destroyer>
void clear_and_destroy(Destroyer destroyer)
{ return tree_.clear_and_destroy(destroyer); }
template<class Disposer>
void clear_and_dispose(Disposer disposer)
{ return tree_.clear_and_dispose(disposer); }
//! <b>Effects</b>: Returns the number of contained elements with the same key
//! compared with the given comparison functor.

View File

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

View File

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

View File

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

View File

@@ -121,8 +121,8 @@ class unordered_set
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
//! or the copy constructor or invocation of Hash or Equal throws.
//!
//! <b>Notes</b>: buckets array must be destroyed only after
//! *this is destroyed.
//! <b>Notes</b>: buckets array must be disposed only after
//! *this is disposed.
unordered_set( bucket_ptr buckets
, size_type buckets_len
, const Hash & hasher = Hash()
@@ -143,8 +143,8 @@ class unordered_set
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
//! or the copy constructor or invocation of Hash or Equal throws.
//!
//! <b>Notes</b>: buckets array must be destroyed only after
//! *this is destroyed.
//! <b>Notes</b>: buckets array must be disposed only after
//! *this is disposed.
template<class Iterator>
unordered_set( bucket_ptr buckets
, size_type buckets_len
@@ -266,22 +266,22 @@ class unordered_set
void swap(unordered_set& other)
{ 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
//! calling Destroyer::operator()(pointer), clones all the
//! calling Disposer::operator()(pointer), clones all the
//! elements from src calling Cloner::operator()(const_reference )
//! and inserts them on *this.
//!
//! If cloner throws, all cloned elements are unlinked and destroyed
//! calling Destroyer::operator()(pointer).
//! If cloner throws, all cloned elements are unlinked and disposed
//! calling Disposer::operator()(pointer).
//!
//! <b>Complexity</b>: Linear to erased plus inserted elements.
//!
//! <b>Throws</b>: If cloner throws. Basic guarantee.
template <class Cloner, class Destroyer>
void clone_from(const unordered_set &src, Cloner cloner, Destroyer destroyer)
{ table_.clone_from(src.table_, cloner, destroyer); }
template <class Cloner, class Disposer>
void clone_from(const unordered_set &src, Cloner cloner, Disposer disposer)
{ table_.clone_from(src.table_, cloner, disposer); }
//! <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)
{ 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.
//! 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()).
//!
@@ -452,14 +452,14 @@ class unordered_set
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class Destroyer>
iterator erase_and_destroy(const_iterator i, Destroyer destroyer)
{ return table_.erase_and_destroy(i, destroyer); }
template<class Disposer>
iterator erase_and_dispose(const_iterator i, Disposer disposer)
{ 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.
//! 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)),
//! worst case O(this->size()).
@@ -468,14 +468,14 @@ class unordered_set
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class Destroyer>
iterator erase_and_destroy(const_iterator b, const_iterator e, Destroyer destroyer)
{ return table_.erase_and_destroy(b, e, destroyer); }
template<class Disposer>
iterator erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
{ 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.
//! 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.
//!
@@ -486,15 +486,15 @@ class unordered_set
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
template<class Destroyer>
size_type erase_and_destroy(const_reference value, Destroyer destroyer)
{ return table_.erase_and_destroy(value, destroyer); }
template<class Disposer>
size_type erase_and_dispose(const_reference value, Disposer disposer)
{ 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.
//! 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.
//!
@@ -505,9 +505,9 @@ class unordered_set
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class KeyType, class KeyHasher, class KeyValueEqual, class Destroyer>
size_type erase_and_destroy(const KeyType& key, KeyHasher hasher, KeyValueEqual equal, Destroyer destroyer)
{ return table_.erase_and_destroy(key, hasher, equal, destroyer); }
template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
size_type erase_and_dispose(const KeyType& key, KeyHasher hasher, KeyValueEqual equal, Disposer disposer)
{ return table_.erase_and_dispose(key, hasher, equal, disposer); }
//! <b>Effects</b>: Erases all of the elements.
//!
@@ -521,20 +521,20 @@ class unordered_set
void 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>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>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
template<class Destroyer>
void clear_and_destroy(Destroyer destroyer)
{ return table_.clear_and_destroy(destroyer); }
template<class Disposer>
void clear_and_dispose(Disposer disposer)
{ return table_.clear_and_dispose(disposer); }
//! <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>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
{ 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)
//! or the copy constructor or invocation of Hash or Equal throws.
//!
//! <b>Notes</b>: buckets array must be destroyed only after
//! *this is destroyed.
//! <b>Notes</b>: buckets array must be disposed only after
//! *this is disposed.
unordered_multiset ( bucket_ptr buckets
, size_type buckets_len
, const Hash & hasher = Hash()
@@ -1041,8 +1041,8 @@ class unordered_multiset
//! constructor throws (this does not happen with predefined Boost.Intrusive hooks)
//! or the copy constructor or invocation of Hash or Equal throws.
//!
//! <b>Notes</b>: buckets array must be destroyed only after
//! *this is destroyed.
//! <b>Notes</b>: buckets array must be disposed only after
//! *this is disposed.
template<class Iterator>
unordered_multiset ( bucket_ptr buckets
, size_type buckets_len
@@ -1165,22 +1165,22 @@ class unordered_multiset
void swap(unordered_multiset& other)
{ 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
//! calling Destroyer::operator()(pointer), clones all the
//! calling Disposer::operator()(pointer), clones all the
//! elements from src calling Cloner::operator()(const_reference )
//! and inserts them on *this.
//!
//! If cloner throws, all cloned elements are unlinked and destroyed
//! calling Destroyer::operator()(pointer).
//! If cloner throws, all cloned elements are unlinked and disposed
//! calling Disposer::operator()(pointer).
//!
//! <b>Complexity</b>: Linear to erased plus inserted elements.
//!
//! <b>Throws</b>: If cloner throws.
template <class Cloner, class Destroyer>
void clone_from(const unordered_multiset &src, Cloner cloner, Destroyer destroyer)
{ table_.clone_from(src.table_, cloner, destroyer); }
template <class Cloner, class Disposer>
void clone_from(const unordered_multiset &src, Cloner cloner, Disposer disposer)
{ table_.clone_from(src.table_, cloner, disposer); }
//! <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)
{ 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.
//! 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()).
//!
@@ -1286,14 +1286,14 @@ class unordered_multiset
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class Destroyer>
void erase_and_destroy(const_iterator i, Destroyer destroyer)
{ table_.erase_and_destroy(i, destroyer); }
template<class Disposer>
void erase_and_dispose(const_iterator i, Disposer disposer)
{ 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.
//! 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)),
//! worst case O(this->size()).
@@ -1302,14 +1302,14 @@ class unordered_multiset
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class Destroyer>
void erase_and_destroy(const_iterator b, const_iterator e, Destroyer destroyer)
{ table_.erase_and_destroy(b, e, destroyer); }
template<class Disposer>
void erase_and_dispose(const_iterator b, const_iterator e, Disposer disposer)
{ 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.
//! 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.
//!
@@ -1320,15 +1320,15 @@ class unordered_multiset
//!
//! <b>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
template<class Destroyer>
size_type erase_and_destroy(const_reference value, Destroyer destroyer)
{ return table_.erase_and_destroy(value, destroyer); }
template<class Disposer>
size_type erase_and_dispose(const_reference value, Disposer disposer)
{ 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.
//! 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.
//!
@@ -1339,9 +1339,9 @@ class unordered_multiset
//!
//! <b>Note</b>: Invalidates the iterators
//! to the erased elements.
template<class KeyType, class KeyHasher, class KeyValueEqual, class Destroyer>
size_type erase_and_destroy(const KeyType& key, KeyHasher hasher, KeyValueEqual equal, Destroyer destroyer)
{ return table_.erase_and_destroy(key, hasher, equal, destroyer); }
template<class KeyType, class KeyHasher, class KeyValueEqual, class Disposer>
size_type erase_and_dispose(const KeyType& key, KeyHasher hasher, KeyValueEqual equal, Disposer disposer)
{ return table_.erase_and_dispose(key, hasher, equal, disposer); }
//! <b>Effects</b>: Erases all the elements of the container.
//!
@@ -1355,20 +1355,20 @@ class unordered_multiset
void 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>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>Note</b>: Invalidates the iterators (but not the references)
//! to the erased elements. No destructors are called.
template<class Destroyer>
void clear_and_destroy(Destroyer destroyer)
{ return table_.clear_and_destroy(destroyer); }
template<class Disposer>
void clear_and_dispose(Disposer disposer)
{ return table_.clear_and_dispose(disposer); }
//! <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>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
{ return table_.count(key, hasher, equal); }

View File

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