diff options
Diffstat (limited to 'boost/container/detail/node_alloc_holder.hpp')
-rw-r--r-- | boost/container/detail/node_alloc_holder.hpp | 225 |
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 250c559765..98c8e62baa 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 { |