forked from boostorg/intrusive
no message
[SVN r38075]
This commit is contained in:
35
include/boost/intrusive/detail/assert.hpp
Normal file
35
include/boost/intrusive/detail/assert.hpp
Normal 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
|
@@ -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
|
||||
|
@@ -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;
|
@@ -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
|
||||
|
@@ -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
|
||||
|
177
include/boost/intrusive/detail/mpl.hpp
Normal file
177
include/boost/intrusive/detail/mpl.hpp
Normal 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
|
@@ -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
|
||||
|
@@ -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
|
||||
>
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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 {
|
||||
|
||||
////////////////////////////
|
||||
|
@@ -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)));
|
||||
}
|
||||
};
|
||||
|
@@ -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 {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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.
|
||||
|
@@ -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 {
|
||||
|
@@ -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)));
|
||||
}
|
||||
|
||||
|
@@ -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 {
|
||||
|
@@ -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); }
|
||||
|
||||
|
@@ -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 {
|
||||
|
Reference in New Issue
Block a user