diff --git a/include/boost/unordered/detail/allocate.hpp b/include/boost/unordered/detail/allocate.hpp index df96c7d2..7a0e28a1 100644 --- a/include/boost/unordered/detail/allocate.hpp +++ b/include/boost/unordered/detail/allocate.hpp @@ -760,16 +760,70 @@ namespace boost { namespace unordered { namespace detail { namespace boost { namespace unordered { namespace detail { + //////////////////////////////////////////////////////////////////////////// + // call_construct + +#if !defined(BOOST_NO_VARIADIC_TEMPLATES) + +# if BOOST_UNORDERED_DETAIL_FULL_CONSTRUCT + + template + inline void call_construct(Alloc& alloc, T* address, + BOOST_FWD_REF(Args)... args) + { + boost::unordered::detail::allocator_traits::construct(alloc, + address, boost::forward(args)...); + } + +# else + + template + inline void call_construct(Alloc&, T* address, + BOOST_FWD_REF(Args)... args) + { + new((void*) address) T(boost::forward(args)...); + } + +# endif + +#endif + //////////////////////////////////////////////////////////////////////////// // Construct from tuple // // Used for piecewise construction. -#if !defined(__SUNPRO_CC) +#if !defined(BOOST_NO_VARIADIC_TEMPLATES) # define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(n, namespace_) \ - template \ - void construct_from_tuple(T* ptr, namespace_ tuple<>) \ + template \ + void construct_from_tuple(Alloc& alloc, T* ptr, namespace_ tuple<>) \ + { \ + boost::unordered::detail::call_construct(alloc, ptr); \ + } \ + \ + BOOST_PP_REPEAT_FROM_TO(1, n, \ + BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL, namespace_) + +# define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL(z, n, namespace_) \ + template \ + void construct_from_tuple(Alloc& alloc, T* ptr, \ + namespace_ tuple const& x) \ + { \ + boost::unordered::detail::call_construct(alloc, ptr, \ + BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_) \ + ); \ + } + +# define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, namespace_) \ + namespace_ get(x) + +#elif !defined(__SUNPRO_CC) + +# define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(n, namespace_) \ + template \ + void construct_from_tuple(Alloc&, T* ptr, namespace_ tuple<>) \ { \ new ((void*) ptr) T(); \ } \ @@ -778,8 +832,9 @@ namespace boost { namespace unordered { namespace detail { BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL, namespace_) # define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL(z, n, namespace_) \ - template \ - void construct_from_tuple(T* ptr, \ + template \ + void construct_from_tuple(Alloc&, T* ptr, \ namespace_ tuple const& x) \ { \ new ((void*) ptr) T( \ @@ -795,9 +850,9 @@ namespace boost { namespace unordered { namespace detail { template struct length {}; # define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(n, namespace_) \ - template \ + template \ void construct_from_tuple_impl( \ - boost::unordered::detail::length<0>, T* ptr, \ + boost::unordered::detail::length<0>, Alloc&, T* ptr, \ namespace_ tuple<>) \ { \ new ((void*) ptr) T(); \ @@ -807,9 +862,10 @@ namespace boost { namespace unordered { namespace detail { BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL, namespace_) # define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL(z, n, namespace_) \ - template \ + template \ void construct_from_tuple_impl( \ - boost::unordered::detail::length, T* ptr, \ + boost::unordered::detail::length, Alloc&, T* ptr, \ namespace_ tuple const& x) \ { \ new ((void*) ptr) T( \ @@ -834,13 +890,13 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::) #if defined(__SUNPRO_CC) - template - void construct_from_tuple(T* ptr, Tuple const& x) + template + void construct_from_tuple(Alloc& alloc, T* ptr, Tuple const& x) { construct_from_tuple_impl( boost::unordered::detail::length< boost::tuples::length::value>(), - ptr, x); + alloc, ptr, x); } #endif @@ -896,59 +952,70 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::) #endif +// TODO: Full construct? #if !defined(BOOST_NO_VARIADIC_TEMPLATES) //////////////////////////////////////////////////////////////////////////// // Construct from variadic parameters - template - inline void construct_impl(T* address, BOOST_FWD_REF(Args)... args) + template + inline void construct_impl(Alloc& alloc, T* address, + BOOST_FWD_REF(Args)... args) { - new((void*) address) T(boost::forward(args)...); + boost::unordered::detail::call_construct(alloc, + address, boost::forward(args)...); } - template + template inline typename enable_if, void>::type - construct_impl(std::pair* address, + construct_impl(Alloc& alloc, std::pair* address, BOOST_FWD_REF(A0), BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2) { - boost::unordered::detail::construct_from_tuple( + boost::unordered::detail::construct_from_tuple(alloc, boost::addressof(address->first), boost::forward(a1)); - boost::unordered::detail::construct_from_tuple( + boost::unordered::detail::construct_from_tuple(alloc, boost::addressof(address->second), boost::forward(a2)); } #if defined(BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT) - template + template inline typename enable_if, void>::type - construct_impl(std::pair* address, BOOST_FWD_REF(A0) a0) + construct_impl(Alloc& alloc, std::pair* address, + BOOST_FWD_REF(A0) a0) { - new((void*) boost::addressof(address->first)) A(boost::forward(a0)); - new((void*) boost::addressof(address->second)) B(); + boost::unordered::detail::call_construct(alloc, + boost::addressof(address->first),boost::forward(a0)); + boost::unordered::detail::call_construct(alloc, + boost::addressof(address->second)); } - template + template inline typename enable_if, void>::type - construct_impl(std::pair* address, + construct_impl(Alloc& alloc, std::pair* address, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2) { - new((void*) boost::addressof(address->first)) A(boost::forward(a0)); - new((void*) boost::addressof(address->second)) B( + boost::unordered::detail::call_construct(alloc, + boost::addressof(address->first),boost::forward(a0)); + boost::unordered::detail::call_construct(alloc, + boost::addressof(address->second), boost::forward(a1), boost::forward(a2)); } - template - inline void construct_impl(std::pair* address, + inline void construct_impl(Alloc& alloc, std::pair* address, BOOST_FWD_REF(A0) a0, BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2, BOOST_FWD_REF(A3) a3, BOOST_FWD_REF(Args)... args) { - new((void*) boost::addressof(address->first)) A(boost::forward(a0)); - - new((void*) boost::addressof(address->second)) B( + boost::unordered::detail::call_construct(alloc, + boost::addressof(address->first),boost::forward(a0)); + boost::unordered::detail::call_construct(alloc, + boost::addressof(address->second), boost::forward(a1), boost::forward(a2), boost::forward(a3), @@ -963,10 +1030,10 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::) #define BOOST_UNORDERED_CONSTRUCT_IMPL(z, num_params, _) \ template < \ - typename T, \ + typename Alloc, typename T, \ BOOST_PP_ENUM_PARAMS_Z(z, num_params, typename A) \ > \ - inline void construct_impl(T* address, \ + inline void construct_impl(Alloc&, T* address, \ boost::unordered::detail::BOOST_PP_CAT(emplace_args,num_params) < \ BOOST_PP_ENUM_PARAMS_Z(z, num_params, A) \ > const& args) \ @@ -976,14 +1043,16 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::) args.a)); \ } - template - inline void construct_impl(T* address, emplace_args1 const& args) + template + inline void construct_impl(Alloc&, T* address, + emplace_args1 const& args) { new((void*) address) T(boost::forward(args.a0)); } - template - inline void construct_impl(T* address, emplace_args2 const& args) + template + inline void construct_impl(Alloc&, T* address, + emplace_args2 const& args) { new((void*) address) T( boost::forward(args.a0), @@ -991,8 +1060,9 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::) ); } - template - inline void construct_impl(T* address, emplace_args3 const& args) + template + inline void construct_impl(Alloc&, T* address, + emplace_args3 const& args) { new((void*) address) T( boost::forward(args.a0), @@ -1006,21 +1076,22 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::) #undef BOOST_UNORDERED_CONSTRUCT_IMPL - template - inline void construct_impl(std::pair* address, + template + inline void construct_impl(Alloc& alloc, std::pair* address, boost::unordered::detail::emplace_args3 const& args, typename enable_if, void*>::type = 0) { - boost::unordered::detail::construct_from_tuple( + boost::unordered::detail::construct_from_tuple(alloc, boost::addressof(address->first), args.a1); - boost::unordered::detail::construct_from_tuple( + boost::unordered::detail::construct_from_tuple(alloc, boost::addressof(address->second), args.a2); } #if defined(BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT) - template - inline void construct_impl(std::pair* address, + template + inline void construct_impl(Alloc&, std::pair* address, boost::unordered::detail::emplace_args1 const& args, typename enable_if, void*>::type = 0) { @@ -1029,8 +1100,9 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::) new((void*) boost::addressof(address->second)) B(); } - template - inline void construct_impl(std::pair* address, + template + inline void construct_impl(Alloc&, std::pair* address, boost::unordered::detail::emplace_args3 const& args, typename enable_if, void*>::type = 0) { @@ -1042,10 +1114,10 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::) } #define BOOST_UNORDERED_CONSTRUCT_PAIR_IMPL(z, num_params, _) \ - template \ - inline void construct_impl(std::pair* address, \ + inline void construct_impl(Alloc&, std::pair* address, \ boost::unordered::detail::BOOST_PP_CAT(emplace_args, num_params) < \ BOOST_PP_ENUM_PARAMS_Z(z, num_params, A) \ > const& args) \ diff --git a/include/boost/unordered/detail/buckets.hpp b/include/boost/unordered/detail/buckets.hpp index a7e5ddbd..3fd6f910 100644 --- a/include/boost/unordered/detail/buckets.hpp +++ b/include/boost/unordered/detail/buckets.hpp @@ -75,7 +75,7 @@ namespace boost { namespace unordered { namespace detail { { BOOST_ASSERT(node_ && node_constructed_ && !value_constructed_); boost::unordered::detail::construct_impl( - node_->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD); + alloc_, node_->value_ptr(), BOOST_UNORDERED_EMPLACE_FORWARD); value_constructed_ = true; } @@ -84,7 +84,7 @@ namespace boost { namespace unordered { namespace detail { { BOOST_ASSERT(node_ && node_constructed_ && !value_constructed_); boost::unordered::detail::construct_impl( - node_->value_ptr(), + alloc_, node_->value_ptr(), BOOST_UNORDERED_EMPLACE_ARGS1(boost::forward(a0))); value_constructed_ = true; }