summaryrefslogtreecommitdiff
path: root/boost/container/detail/node_alloc_holder.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/container/detail/node_alloc_holder.hpp')
-rw-r--r--boost/container/detail/node_alloc_holder.hpp225
1 files changed, 139 insertions, 86 deletions
diff --git a/boost/container/detail/node_alloc_holder.hpp b/boost/container/detail/node_alloc_holder.hpp
index 250c559..98c8e62 100644
--- a/boost/container/detail/node_alloc_holder.hpp
+++ b/boost/container/detail/node_alloc_holder.hpp
@@ -11,82 +11,63 @@
#ifndef BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
#define BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
-#if defined(_MSC_VER)
+#ifndef BOOST_CONFIG_HPP
+# include <boost/config.hpp>
+#endif
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
-#include <utility>
-#include <functional>
-
-#include <boost/move/utility_core.hpp>
-#include <boost/intrusive/options.hpp>
-
-#include <boost/container/detail/version_type.hpp>
-#include <boost/container/detail/type_traits.hpp>
-#include <boost/container/detail/utilities.hpp>
+// container
#include <boost/container/allocator_traits.hpp>
+// container/detail
+#include <boost/container/detail/addressof.hpp>
+#include <boost/container/detail/alloc_helpers.hpp>
#include <boost/container/detail/allocator_version_traits.hpp>
-#include <boost/container/detail/mpl.hpp>
+#include <boost/container/detail/construct_in_place.hpp>
#include <boost/container/detail/destroyers.hpp>
-#include <boost/container/detail/memory_util.hpp>
+#include <boost/container/detail/iterator_to_raw_pointer.hpp>
+#include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/placement_new.hpp>
-#include <boost/core/no_exceptions_support.hpp>
-
-#ifndef BOOST_CONTAINER_PERFECT_FORWARDING
-#include <boost/container/detail/preprocessor.hpp>
+#include <boost/container/detail/to_raw_pointer.hpp>
+#include <boost/container/detail/type_traits.hpp>
+#include <boost/container/detail/version_type.hpp>
+// intrusive
+#include <boost/intrusive/detail/mpl.hpp>
+#include <boost/intrusive/options.hpp>
+// move
+#include <boost/move/utility_core.hpp>
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+#include <boost/move/detail/fwd_macros.hpp>
#endif
-
-#include <boost/container/detail/algorithms.hpp>
-
+// other
+#include <boost/core/no_exceptions_support.hpp>
namespace boost {
namespace container {
namespace container_detail {
-template<class ValueCompare, class Node>
-struct node_compare
- : private ValueCompare
-{
- typedef ValueCompare wrapped_value_compare;
- typedef typename wrapped_value_compare::key_type key_type;
- typedef typename wrapped_value_compare::value_type value_type;
- typedef typename wrapped_value_compare::key_of_value key_of_value;
-
- explicit node_compare(const wrapped_value_compare &pred)
- : wrapped_value_compare(pred)
- {}
-
- node_compare()
- : wrapped_value_compare()
- {}
-
- wrapped_value_compare &value_comp()
- { return static_cast<wrapped_value_compare &>(*this); }
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(value_compare)
+BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(predicate_type)
- wrapped_value_compare &value_comp() const
- { return static_cast<const wrapped_value_compare &>(*this); }
-
- bool operator()(const Node &a, const Node &b) const
- { return wrapped_value_compare::operator()(a.get_data(), b.get_data()); }
-};
-
-template<class A, class ICont>
+template<class Allocator, class ICont>
struct node_alloc_holder
{
//If the intrusive container is an associative container, obtain the predicate, which will
//be of type node_compare<>. If not an associative container value_compare will be a "nat" type.
typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, ICont,
value_compare, container_detail::nat) intrusive_value_compare;
- //In that case obtain the value predicate from the node predicate via wrapped_value_compare
+ //In that case obtain the value predicate from the node predicate via predicate_type
//if intrusive_value_compare is node_compare<>, nat otherwise
- typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, ICont,
- wrapped_value_compare, container_detail::nat) value_compare;
+ typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::container_detail::, intrusive_value_compare,
+ predicate_type, container_detail::nat) value_compare;
- typedef allocator_traits<A> allocator_traits_type;
+ typedef allocator_traits<Allocator> allocator_traits_type;
typedef typename allocator_traits_type::value_type value_type;
typedef ICont intrusive_container;
typedef typename ICont::value_type Node;
@@ -94,13 +75,11 @@ struct node_alloc_holder
portable_rebind_alloc<Node>::type NodeAlloc;
typedef allocator_traits<NodeAlloc> node_allocator_traits_type;
typedef container_detail::allocator_version_traits<NodeAlloc> node_allocator_version_traits_type;
- typedef A ValAlloc;
+ typedef Allocator ValAlloc;
typedef typename node_allocator_traits_type::pointer NodePtr;
typedef container_detail::scoped_deallocator<NodeAlloc> Deallocator;
typedef typename node_allocator_traits_type::size_type size_type;
typedef typename node_allocator_traits_type::difference_type difference_type;
- typedef container_detail::integral_constant<unsigned, 1> allocator_v1;
- typedef container_detail::integral_constant<unsigned, 2> allocator_v2;
typedef container_detail::integral_constant<unsigned,
boost::container::container_detail::
version<NodeAlloc>::value> alloc_version;
@@ -133,11 +112,11 @@ struct node_alloc_holder
{ this->icont().swap(x.icont()); }
//Constructors for associative containers
- explicit node_alloc_holder(const ValAlloc &a, const value_compare &c)
+ explicit node_alloc_holder(const value_compare &c, const ValAlloc &a)
: members_(a, c)
{}
- explicit node_alloc_holder(const node_alloc_holder &x, const value_compare &c)
+ explicit node_alloc_holder(const value_compare &c, const node_alloc_holder &x)
: members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c)
{}
@@ -176,7 +155,7 @@ struct node_alloc_holder
void deallocate_one(const NodePtr &p)
{ AllocVersionTraits::deallocate_one(this->node_alloc(), p); }
- #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class ...Args>
NodePtr create_node(Args &&...args)
@@ -193,28 +172,90 @@ struct node_alloc_holder
return (p);
}
- #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
-
- #define BOOST_PP_LOCAL_MACRO(n) \
- \
- BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
- NodePtr create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
- { \
- NodePtr p = this->allocate_one(); \
- Deallocator node_deallocator(p, this->node_alloc()); \
- allocator_traits<NodeAlloc>::construct \
- (this->node_alloc(), container_detail::addressof(p->m_data) \
- BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _)); \
- node_deallocator.release(); \
- typedef typename Node::hook_type hook_type; \
- ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type; \
- return (p); \
- } \
- //!
- #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
- #include BOOST_PP_LOCAL_ITERATE()
-
- #endif //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
+ #else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ NodePtr create_node()
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ allocator_traits<NodeAlloc>::construct
+ (this->node_alloc(), container_detail::addressof(p->m_data));
+ node_deallocator.release();
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+ return (p);
+ }
+
+ template<BOOST_MOVE_CLASS1>
+ NodePtr create_node(BOOST_MOVE_UREF1)
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ allocator_traits<NodeAlloc>::construct
+ (this->node_alloc(), container_detail::addressof(p->m_data)
+ , BOOST_MOVE_FWD1);
+ node_deallocator.release();
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+ return (p);
+ }
+
+ template<BOOST_MOVE_CLASS2>
+ NodePtr create_node(BOOST_MOVE_UREF2)
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ allocator_traits<NodeAlloc>::construct
+ (this->node_alloc(), container_detail::addressof(p->m_data)
+ , BOOST_MOVE_FWD2);
+ node_deallocator.release();
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+ return (p);
+ }
+
+ template<BOOST_MOVE_CLASS3>
+ NodePtr create_node(BOOST_MOVE_UREF3)
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ allocator_traits<NodeAlloc>::construct
+ (this->node_alloc(), container_detail::addressof(p->m_data)
+ , BOOST_MOVE_FWD3);
+ node_deallocator.release();
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+ return (p);
+ }
+
+ template<BOOST_MOVE_CLASS4>
+ NodePtr create_node(BOOST_MOVE_UREF4)
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ allocator_traits<NodeAlloc>::construct
+ (this->node_alloc(), container_detail::addressof(p->m_data)
+ , BOOST_MOVE_FWD4);
+ node_deallocator.release();
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+ return (p);
+ }
+
+ template<BOOST_MOVE_CLASS5>
+ NodePtr create_node(BOOST_MOVE_UREF5)
+ {
+ NodePtr p = this->allocate_one();
+ Deallocator node_deallocator(p, this->node_alloc());
+ allocator_traits<NodeAlloc>::construct
+ (this->node_alloc(), container_detail::addressof(p->m_data)
+ , BOOST_MOVE_FWD5);
+ node_deallocator.release();
+ typedef typename Node::hook_type hook_type;
+ ::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p)), boost_container_new_t()) hook_type;
+ return (p);
+ }
+
+ #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class It>
NodePtr create_node_from_it(const It &it)
@@ -261,7 +302,7 @@ struct node_alloc_holder
Deallocator node_deallocator(NodePtr(), nalloc);
container_detail::scoped_destructor<NodeAlloc> sdestructor(nalloc, 0);
while(n--){
- p = container_detail::to_raw_pointer(iterator_to_pointer(itbeg));
+ p = container_detail::iterator_to_raw_pointer(itbeg);
node_deallocator.set(p);
++itbeg;
//This can throw
@@ -288,10 +329,10 @@ struct node_alloc_holder
}
}
- void clear(allocator_v1)
+ void clear(version_1)
{ this->icont().clear_and_dispose(Destroyer(this->node_alloc())); }
- void clear(allocator_v2)
+ void clear(version_2)
{
typename NodeAlloc::multiallocation_chain chain;
allocator_destroyer_and_chain_builder<NodeAlloc> builder(this->node_alloc(), chain);
@@ -301,10 +342,10 @@ struct node_alloc_holder
this->node_alloc().deallocate_individual(chain);
}
- icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v1)
+ icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_1)
{ return this->icont().erase_and_dispose(first, last, Destroyer(this->node_alloc())); }
- icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, allocator_v2)
+ icont_iterator erase_range(const icont_iterator &first, const icont_iterator &last, version_2)
{
typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
NodeAlloc & nalloc = this->node_alloc();
@@ -316,11 +357,11 @@ struct node_alloc_holder
}
template<class Key, class Comparator>
- size_type erase_key(const Key& k, const Comparator &comp, allocator_v1)
+ size_type erase_key(const Key& k, const Comparator &comp, version_1)
{ return this->icont().erase_and_dispose(k, comp, Destroyer(this->node_alloc())); }
template<class Key, class Comparator>
- size_type erase_key(const Key& k, const Comparator &comp, allocator_v2)
+ size_type erase_key(const Key& k, const Comparator &comp, version_2)
{
allocator_multialloc_chain_node_deallocator<NodeAlloc> chain_holder(this->node_alloc());
return this->icont().erase_and_dispose(k, comp, chain_holder.get_chain_builder());
@@ -329,7 +370,7 @@ struct node_alloc_holder
protected:
struct cloner
{
- cloner(node_alloc_holder &holder)
+ explicit cloner(node_alloc_holder &holder)
: m_holder(holder)
{}
@@ -339,6 +380,18 @@ struct node_alloc_holder
node_alloc_holder &m_holder;
};
+ struct move_cloner
+ {
+ move_cloner(node_alloc_holder &holder)
+ : m_holder(holder)
+ {}
+
+ NodePtr operator()(Node &other)
+ { return m_holder.create_node(::boost::move(other.get_data())); }
+
+ node_alloc_holder &m_holder;
+ };
+
struct members_holder
: public NodeAlloc
{