merging intrusive from develop

This commit is contained in:
Ion Gaztañaga
2017-11-01 11:48:25 +01:00
7 changed files with 62 additions and 19 deletions

View File

@@ -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]

View File

@@ -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; }

View File

@@ -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);
} }

View File

@@ -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 \

View File

@@ -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; }

View File

@@ -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; }

View File

@@ -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; }