mirror of
https://github.com/boostorg/intrusive.git
synced 2025-08-03 06:24:44 +02:00
merging intrusive from develop
This commit is contained in:
@@ -144,9 +144,11 @@ A non-intrusive container has some limitations:
|
|||||||
a size overhead for each allocation to store bookkeeping information and a
|
a size overhead for each allocation to store bookkeeping information and a
|
||||||
synchronization to protected concurrent allocation from different threads.
|
synchronization to protected concurrent allocation from different threads.
|
||||||
|
|
||||||
* Only copies of objects are stored in non-intrusive containers. Hence copy
|
* Before C++11, only copies of objects could be stored in non-intrusive containers. Still
|
||||||
or move constructors and copy or move assignment operators are required. Non-copyable
|
copy or move constructors and copy or move assignment operators are required
|
||||||
and non-movable objects can't be stored in non-intrusive containers.
|
and non-copyable and non-movable objects can't be stored in some containers. In any case,
|
||||||
|
[*new] objects have to be created inside the container using constructors and the same
|
||||||
|
object can't be shared between two containers.
|
||||||
|
|
||||||
* It's not possible to store a derived object in a STL-container while
|
* It's not possible to store a derived object in a STL-container while
|
||||||
retaining its original type.
|
retaining its original type.
|
||||||
@@ -156,6 +158,9 @@ Intrusive containers have some important advantages:
|
|||||||
* Operating with intrusive containers doesn't invoke any memory management at all.
|
* Operating with intrusive containers doesn't invoke any memory management at all.
|
||||||
The time and size overhead associated with dynamic memory can be minimized.
|
The time and size overhead associated with dynamic memory can be minimized.
|
||||||
|
|
||||||
|
* The same object can be inserted in more than one container at the same time with
|
||||||
|
a tiny overhead in the object size.
|
||||||
|
|
||||||
* Iterating an Intrusive container needs less memory accesses than the semantically
|
* Iterating an Intrusive container needs less memory accesses than the semantically
|
||||||
equivalent container of pointers: iteration is faster.
|
equivalent container of pointers: iteration is faster.
|
||||||
|
|
||||||
@@ -208,7 +213,7 @@ Intrusive containers have also downsides:
|
|||||||
[[Memory management] [External] [Internal through allocator]]
|
[[Memory management] [External] [Internal through allocator]]
|
||||||
[[Insertion/Erasure time] [Faster] [Slower]]
|
[[Insertion/Erasure time] [Faster] [Slower]]
|
||||||
[[Memory locality] [Better] [Worse]]
|
[[Memory locality] [Better] [Worse]]
|
||||||
[[Can hold non-copyable and non-movable objects by value] [Yes] [No]]
|
[[Can insert the same object in more than one container] [Yes] [No]]
|
||||||
[[Exception guarantees] [Better] [Worse]]
|
[[Exception guarantees] [Better] [Worse]]
|
||||||
[[Computation of iterator from value] [Constant] [Non-constant]]
|
[[Computation of iterator from value] [Constant] [Non-constant]]
|
||||||
[[Insertion/erasure predictability] [High] [Low]]
|
[[Insertion/erasure predictability] [High] [Low]]
|
||||||
@@ -2419,7 +2424,7 @@ This section will expand the explanation of previously presented basic concepts
|
|||||||
before explaining the customization options of [*Boost.Intrusive].
|
before explaining the customization options of [*Boost.Intrusive].
|
||||||
|
|
||||||
* [*Node Algorithms]: A set of static functions that implement basic operations
|
* [*Node Algorithms]: A set of static functions that implement basic operations
|
||||||
on a group of nodes: initialize a node, link_mode_type a node to a group of nodes,
|
on a group of nodes: initialize a node, link a node to a group of nodes,
|
||||||
unlink a node from another group of nodes, etc. For example, a circular
|
unlink a node from another group of nodes, etc. For example, a circular
|
||||||
singly linked list is a group of nodes, where each node has a pointer to the
|
singly linked list is a group of nodes, where each node has a pointer to the
|
||||||
next node. [*Node Algorithms] just require a [*NodeTraits]
|
next node. [*Node Algorithms] just require a [*NodeTraits]
|
||||||
|
@@ -725,15 +725,22 @@ class bstree_impl
|
|||||||
this->insert_equal(b, e);
|
this->insert_equal(b, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: to-do
|
//! <b>Effects</b>: Constructs a container moving resources from another container.
|
||||||
|
//! Internal comparison object and value traits are move constructed and
|
||||||
|
//! nodes belonging to x (except the node representing the "end") are linked to *this.
|
||||||
//!
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: If value_traits::node_traits::node's
|
||||||
|
//! move constructor throws (this does not happen with predefined Boost.Intrusive hooks)
|
||||||
|
//! or the move constructor of the comparison objet throws.
|
||||||
bstree_impl(BOOST_RV_REF(bstree_impl) x)
|
bstree_impl(BOOST_RV_REF(bstree_impl) x)
|
||||||
: data_type(::boost::move(x.comp()), ::boost::move(x.get_value_traits()))
|
: data_type(::boost::move(x.comp()), ::boost::move(x.get_value_traits()))
|
||||||
{
|
{
|
||||||
this->swap(x);
|
this->swap(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: to-do
|
//! <b>Effects</b>: Equivalent to swap
|
||||||
//!
|
//!
|
||||||
BOOST_INTRUSIVE_FORCEINLINE bstree_impl& operator=(BOOST_RV_REF(bstree_impl) x)
|
BOOST_INTRUSIVE_FORCEINLINE bstree_impl& operator=(BOOST_RV_REF(bstree_impl) x)
|
||||||
{ this->swap(x); return *this; }
|
{ this->swap(x); return *this; }
|
||||||
|
@@ -69,7 +69,7 @@ class circular_list_algorithms
|
|||||||
//! <b>Throws</b>: Nothing.
|
//! <b>Throws</b>: Nothing.
|
||||||
BOOST_INTRUSIVE_FORCEINLINE static void init(const node_ptr &this_node)
|
BOOST_INTRUSIVE_FORCEINLINE static void init(const node_ptr &this_node)
|
||||||
{
|
{
|
||||||
const node_ptr null_node((node_ptr()));
|
const node_ptr null_node = node_ptr();
|
||||||
NodeTraits::set_next(this_node, null_node);
|
NodeTraits::set_next(this_node, null_node);
|
||||||
NodeTraits::set_previous(this_node, null_node);
|
NodeTraits::set_previous(this_node, null_node);
|
||||||
}
|
}
|
||||||
|
@@ -86,8 +86,8 @@ struct ls_zeros<1>
|
|||||||
|
|
||||||
// Infrastructure for providing a default type for T::TNAME if absent.
|
// Infrastructure for providing a default type for T::TNAME if absent.
|
||||||
#define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \
|
#define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \
|
||||||
template <typename T, typename DefaultType> \
|
template <typename T> \
|
||||||
struct boost_intrusive_default_type_ ## TNAME \
|
struct boost_intrusive_has_type_ ## TNAME \
|
||||||
{ \
|
{ \
|
||||||
template <typename X> \
|
template <typename X> \
|
||||||
static char test(int, typename X::TNAME*); \
|
static char test(int, typename X::TNAME*); \
|
||||||
@@ -95,13 +95,18 @@ struct ls_zeros<1>
|
|||||||
template <typename X> \
|
template <typename X> \
|
||||||
static int test(...); \
|
static int test(...); \
|
||||||
\
|
\
|
||||||
struct DefaultWrap { typedef DefaultType TNAME; }; \
|
|
||||||
\
|
|
||||||
static const bool value = (1 == sizeof(test<T>(0, 0))); \
|
static const bool value = (1 == sizeof(test<T>(0, 0))); \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
template <typename T, typename DefaultType> \
|
||||||
|
struct boost_intrusive_default_type_ ## TNAME \
|
||||||
|
{ \
|
||||||
|
struct DefaultWrap { typedef DefaultType TNAME; }; \
|
||||||
\
|
\
|
||||||
typedef typename \
|
typedef typename \
|
||||||
::boost::intrusive::detail::if_c \
|
::boost::intrusive::detail::if_c \
|
||||||
<value, T, DefaultWrap>::type::TNAME type; \
|
< boost_intrusive_has_type_ ## TNAME<T>::value \
|
||||||
|
, T, DefaultWrap>::type::TNAME type; \
|
||||||
}; \
|
}; \
|
||||||
//
|
//
|
||||||
|
|
||||||
@@ -110,6 +115,11 @@ struct ls_zeros<1>
|
|||||||
boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \
|
boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#define BOOST_INTRUSIVE_HAS_TYPE(INSTANTIATION_NS_PREFIX, T, TNAME) \
|
||||||
|
INSTANTIATION_NS_PREFIX \
|
||||||
|
boost_intrusive_has_type_ ## TNAME< T >::value \
|
||||||
|
//
|
||||||
|
|
||||||
#define BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(TNAME)\
|
#define BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(TNAME)\
|
||||||
template <typename T, typename DefaultType> \
|
template <typename T, typename DefaultType> \
|
||||||
struct boost_intrusive_eval_default_type_ ## TNAME \
|
struct boost_intrusive_eval_default_type_ ## TNAME \
|
||||||
|
@@ -1798,8 +1798,15 @@ class hashtable_impl
|
|||||||
this->insert_equal(b, e);
|
this->insert_equal(b, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: to-do
|
//! <b>Effects</b>: Constructs a container moving resources from another container.
|
||||||
|
//! Internal value traits, bucket traits, hasher and comparison are move constructed and
|
||||||
|
//! nodes belonging to x are linked to *this.
|
||||||
//!
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: If value_traits::node_traits::node's
|
||||||
|
//! move constructor throws (this does not happen with predefined Boost.Intrusive hooks)
|
||||||
|
//! or the move constructor of value traits, bucket traits, hasher or comparison throws.
|
||||||
hashtable_impl(BOOST_RV_REF(hashtable_impl) x)
|
hashtable_impl(BOOST_RV_REF(hashtable_impl) x)
|
||||||
: internal_type( ::boost::move(x.priv_value_traits())
|
: internal_type( ::boost::move(x.priv_value_traits())
|
||||||
, ::boost::move(x.priv_bucket_traits())
|
, ::boost::move(x.priv_bucket_traits())
|
||||||
@@ -1815,7 +1822,7 @@ class hashtable_impl
|
|||||||
x.priv_split_traits().set_size(size_type(0));
|
x.priv_split_traits().set_size(size_type(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: to-do
|
//! <b>Effects</b>: Equivalent to swap.
|
||||||
//!
|
//!
|
||||||
hashtable_impl& operator=(BOOST_RV_REF(hashtable_impl) x)
|
hashtable_impl& operator=(BOOST_RV_REF(hashtable_impl) x)
|
||||||
{ this->swap(x); return *this; }
|
{ this->swap(x); return *this; }
|
||||||
|
@@ -215,8 +215,15 @@ class list_impl
|
|||||||
this->insert(this->cend(), b, e);
|
this->insert(this->cend(), b, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: to-do
|
//! <b>Effects</b>: Constructs a container moving resources from another container.
|
||||||
|
//! Internal value traits are move constructed and
|
||||||
|
//! nodes belonging to x (except the node representing the "end") are linked to *this.
|
||||||
//!
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: If value_traits::node_traits::node's
|
||||||
|
//! move constructor throws (this does not happen with predefined Boost.Intrusive hooks)
|
||||||
|
//! or the move constructor of value traits throws.
|
||||||
list_impl(BOOST_RV_REF(list_impl) x)
|
list_impl(BOOST_RV_REF(list_impl) x)
|
||||||
: data_(::boost::move(x.priv_value_traits()))
|
: data_(::boost::move(x.priv_value_traits()))
|
||||||
{
|
{
|
||||||
@@ -226,7 +233,7 @@ class list_impl
|
|||||||
this->swap(x);
|
this->swap(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: to-do
|
//! <b>Effects</b>: Equivalent to swap
|
||||||
//!
|
//!
|
||||||
list_impl& operator=(BOOST_RV_REF(list_impl) x)
|
list_impl& operator=(BOOST_RV_REF(list_impl) x)
|
||||||
{ this->swap(x); return *this; }
|
{ this->swap(x); return *this; }
|
||||||
|
@@ -338,8 +338,15 @@ class slist_impl
|
|||||||
this->insert_after(this->cbefore_begin(), b, e);
|
this->insert_after(this->cbefore_begin(), b, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: to-do
|
//! <b>Effects</b>: Constructs a container moving resources from another container.
|
||||||
|
//! Internal value traits are move constructed and
|
||||||
|
//! nodes belonging to x (except the node representing the "end") are linked to *this.
|
||||||
//!
|
//!
|
||||||
|
//! <b>Complexity</b>: Constant.
|
||||||
|
//!
|
||||||
|
//! <b>Throws</b>: If value_traits::node_traits::node's
|
||||||
|
//! move constructor throws (this does not happen with predefined Boost.Intrusive hooks)
|
||||||
|
//! or the move constructor of value traits throws.
|
||||||
slist_impl(BOOST_RV_REF(slist_impl) x)
|
slist_impl(BOOST_RV_REF(slist_impl) x)
|
||||||
: data_(::boost::move(x.priv_value_traits()))
|
: data_(::boost::move(x.priv_value_traits()))
|
||||||
{
|
{
|
||||||
@@ -348,7 +355,7 @@ class slist_impl
|
|||||||
this->swap(x);
|
this->swap(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! <b>Effects</b>: to-do
|
//! <b>Effects</b>: Equivalent to swap
|
||||||
//!
|
//!
|
||||||
slist_impl& operator=(BOOST_RV_REF(slist_impl) x)
|
slist_impl& operator=(BOOST_RV_REF(slist_impl) x)
|
||||||
{ this->swap(x); return *this; }
|
{ this->swap(x); return *this; }
|
||||||
|
Reference in New Issue
Block a user