From 3a163b5449eb34f7238ce44053a4a64363aeb0a0 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Sat, 25 Aug 2012 21:52:28 +0000 Subject: [PATCH] Unordered: Move some things around. - Move `allocator_traits` before `construct_impl` so the `construct_impl` can be changed to use `allocator_traits`. - Moved some move utilities out of `allocate.hpp` because they're really nothing to do with allocation and construction. [SVN r80220] --- include/boost/unordered/detail/allocate.hpp | 656 ++++++++++---------- include/boost/unordered/detail/buckets.hpp | 30 + 2 files changed, 345 insertions(+), 341 deletions(-) diff --git a/include/boost/unordered/detail/allocate.hpp b/include/boost/unordered/detail/allocate.hpp index 83e650ed..df96c7d2 100644 --- a/include/boost/unordered/detail/allocate.hpp +++ b/include/boost/unordered/detail/allocate.hpp @@ -167,347 +167,6 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_UNORDERED_EMPLACE_LIMIT, BOOST_UNORDERED_EARGS, #endif - //////////////////////////////////////////////////////////////////////////// - // rvalue parameters when type can't be a BOOST_RV_REF(T) parameter - // e.g. for int - -#if !defined(BOOST_NO_RVALUE_REFERENCES) -# define BOOST_UNORDERED_RV_REF(T) BOOST_RV_REF(T) -#else - struct please_ignore_this_overload { - typedef please_ignore_this_overload type; - }; - - template - struct rv_ref_impl { - typedef BOOST_RV_REF(T) type; - }; - - template - struct rv_ref : - boost::detail::if_true< - boost::is_class::value - >::BOOST_NESTED_TEMPLATE then < - boost::unordered::detail::rv_ref_impl, - please_ignore_this_overload - >::type - {}; - -# define BOOST_UNORDERED_RV_REF(T) \ - typename boost::unordered::detail::rv_ref::type -#endif - - //////////////////////////////////////////////////////////////////////////// - // Construct from tuple - // - // Used for piecewise construction. - -#if !defined(__SUNPRO_CC) - -# define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(n, namespace_) \ - template \ - void construct_from_tuple(T* ptr, namespace_ tuple<>) \ - { \ - new ((void*) ptr) T(); \ - } \ - \ - 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(T* ptr, \ - namespace_ tuple const& x) \ - { \ - new ((void*) ptr) T( \ - BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_) \ - ); \ - } - -# define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, namespace_) \ - namespace_ get(x) - -#else - - template struct length {}; - -# define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(n, namespace_) \ - template \ - void construct_from_tuple_impl( \ - boost::unordered::detail::length<0>, T* ptr, \ - namespace_ tuple<>) \ - { \ - new ((void*) ptr) T(); \ - } \ - \ - 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_impl( \ - boost::unordered::detail::length, T* ptr, \ - namespace_ tuple const& x) \ - { \ - new ((void*) ptr) T( \ - BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_) \ - ); \ - } - -# define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, namespace_) \ - namespace_ get(x) - -#endif - -BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::) - -#if !defined(__SUNPRO_CC) && !defined(BOOST_NO_CXX11_HDR_TUPLE) - BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, std::) -#endif - -#undef BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE -#undef BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL -#undef BOOST_UNORDERED_GET_TUPLE_ARG - -#if defined(__SUNPRO_CC) - - template - void construct_from_tuple(T* ptr, Tuple const& x) - { - construct_from_tuple_impl( - boost::unordered::detail::length< - boost::tuples::length::value>(), - ptr, x); - } - -#endif - - //////////////////////////////////////////////////////////////////////////// - // SFINAE traits for construction. - - // Decide which construction method to use for a three argument - // call. Note that this is difficult to do using overloads because - // the arguments are packed into 'emplace_args3'. - // - // The decision is made on the first argument. - - -#if defined(BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT) - template - struct emulation1 { - static choice1::type test(choice1, std::pair const&); - static choice2::type test(choice2, A const&); - static choice3::type test(choice3, convert_from_anything const&); - - enum { value = - sizeof(test(choose(), boost::unordered::detail::make())) == - sizeof(choice2::type) }; - }; -#endif - - template - struct check3_base { - static choice1::type test(choice1, - boost::unordered::piecewise_construct_t); - -#if defined(BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT) - static choice2::type test(choice2, A const&); -#endif - - static choice3::type test(choice3, ...); - - enum { value = - sizeof(test(choose(), boost::unordered::detail::make())) }; - }; - - template - struct piecewise3 { - enum { value = check3_base::value == sizeof(choice1::type) }; - }; - -#if defined(BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT) - template - struct emulation3 { - enum { value = check3_base::value == sizeof(choice2::type) }; - }; - -#endif - -#if !defined(BOOST_NO_VARIADIC_TEMPLATES) - - //////////////////////////////////////////////////////////////////////////// - // Construct from variadic parameters - - template - inline void construct_impl(T* address, BOOST_FWD_REF(Args)... args) - { - new((void*) address) T(boost::forward(args)...); - } - - template - inline typename enable_if, void>::type - construct_impl(std::pair* address, - BOOST_FWD_REF(A0), BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2) - { - boost::unordered::detail::construct_from_tuple( - boost::addressof(address->first), boost::forward(a1)); - boost::unordered::detail::construct_from_tuple( - boost::addressof(address->second), boost::forward(a2)); - } - -#if defined(BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT) - - template - inline typename enable_if, void>::type - construct_impl(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(); - } - - template - inline typename enable_if, void>::type - construct_impl(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::forward(a1), - boost::forward(a2)); - } - - template - inline void construct_impl(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::forward(a1), - boost::forward(a2), - boost::forward(a3), - boost::forward(args)...); - } - -#endif // BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT - -#else // BOOST_NO_VARIADIC_TEMPLATES - -//////////////////////////////////////////////////////////////////////////////// -// Construct from emplace_args - -#define BOOST_UNORDERED_CONSTRUCT_IMPL(z, num_params, _) \ - template < \ - typename T, \ - BOOST_PP_ENUM_PARAMS_Z(z, num_params, typename A) \ - > \ - inline void construct_impl(T* address, \ - boost::unordered::detail::BOOST_PP_CAT(emplace_args,num_params) < \ - BOOST_PP_ENUM_PARAMS_Z(z, num_params, A) \ - > const& args) \ - { \ - new((void*) address) T( \ - BOOST_PP_ENUM_##z(num_params, BOOST_UNORDERED_CALL_FORWARD, \ - args.a)); \ - } - - template - inline void construct_impl(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) - { - new((void*) address) T( - boost::forward(args.a0), - boost::forward(args.a1) - ); - } - - template - inline void construct_impl(T* address, emplace_args3 const& args) - { - new((void*) address) T( - boost::forward(args.a0), - boost::forward(args.a1), - boost::forward(args.a2) - ); - } - - BOOST_PP_REPEAT_FROM_TO(4, BOOST_UNORDERED_EMPLACE_LIMIT, - BOOST_UNORDERED_CONSTRUCT_IMPL, _) - -#undef BOOST_UNORDERED_CONSTRUCT_IMPL - - template - inline void construct_impl(std::pair* address, - boost::unordered::detail::emplace_args3 const& args, - typename enable_if, void*>::type = 0) - { - boost::unordered::detail::construct_from_tuple( - boost::addressof(address->first), args.a1); - boost::unordered::detail::construct_from_tuple( - boost::addressof(address->second), args.a2); - } - -#if defined(BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT) - - template - inline void construct_impl(std::pair* address, - boost::unordered::detail::emplace_args1 const& args, - typename enable_if, void*>::type = 0) - { - new((void*) boost::addressof(address->first)) A( - boost::forward(args.a0)); - new((void*) boost::addressof(address->second)) B(); - } - - template - inline void construct_impl(std::pair* address, - boost::unordered::detail::emplace_args3 const& args, - typename enable_if, void*>::type = 0) - { - new((void*) boost::addressof(address->first)) A( - boost::forward(args.a0)); - new((void*) boost::addressof(address->second)) B( - boost::forward(args.a1), - boost::forward(args.a2)); - } - -#define BOOST_UNORDERED_CONSTRUCT_PAIR_IMPL(z, num_params, _) \ - template \ - inline void construct_impl(std::pair* address, \ - boost::unordered::detail::BOOST_PP_CAT(emplace_args, num_params) < \ - BOOST_PP_ENUM_PARAMS_Z(z, num_params, A) \ - > const& args) \ - { \ - new((void*) boost::addressof(address->first)) A( \ - boost::forward(args.a0)); \ - new((void*) boost::addressof(address->second)) B( \ - BOOST_PP_ENUM_##z(BOOST_PP_DEC(num_params), \ - BOOST_UNORDERED_CALL_FORWARD2, args.a)); \ - } - -#define BOOST_UNORDERED_CALL_FORWARD2(z, i, a) \ - BOOST_UNORDERED_CALL_FORWARD(z, BOOST_PP_INC(i), a) - - BOOST_UNORDERED_CONSTRUCT_PAIR_IMPL(1, 2, _) - BOOST_PP_REPEAT_FROM_TO(4, BOOST_UNORDERED_EMPLACE_LIMIT, - BOOST_UNORDERED_CONSTRUCT_PAIR_IMPL, _) - -#undef BOOST_UNORDERED_CONSTRUCT_PAIR_IMPL -#undef BOOST_UNORDERED_CALL_FORWARD2 - -#endif // BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT -#endif // BOOST_NO_VARIADIC_TEMPLATES - }}} //////////////////////////////////////////////////////////////////////////////// @@ -1098,6 +757,321 @@ namespace boost { namespace unordered { namespace detail { #endif + +namespace boost { namespace unordered { namespace detail { + + //////////////////////////////////////////////////////////////////////////// + // Construct from tuple + // + // Used for piecewise construction. + +#if !defined(__SUNPRO_CC) + +# define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(n, namespace_) \ + template \ + void construct_from_tuple(T* ptr, namespace_ tuple<>) \ + { \ + new ((void*) ptr) T(); \ + } \ + \ + 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(T* ptr, \ + namespace_ tuple const& x) \ + { \ + new ((void*) ptr) T( \ + BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_) \ + ); \ + } + +# define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, namespace_) \ + namespace_ get(x) + +#else + + template struct length {}; + +# define BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(n, namespace_) \ + template \ + void construct_from_tuple_impl( \ + boost::unordered::detail::length<0>, T* ptr, \ + namespace_ tuple<>) \ + { \ + new ((void*) ptr) T(); \ + } \ + \ + 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_impl( \ + boost::unordered::detail::length, T* ptr, \ + namespace_ tuple const& x) \ + { \ + new ((void*) ptr) T( \ + BOOST_PP_ENUM_##z(n, BOOST_UNORDERED_GET_TUPLE_ARG, namespace_) \ + ); \ + } + +# define BOOST_UNORDERED_GET_TUPLE_ARG(z, n, namespace_) \ + namespace_ get(x) + +#endif + +BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::) + +#if !defined(__SUNPRO_CC) && !defined(BOOST_NO_CXX11_HDR_TUPLE) + BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, std::) +#endif + +#undef BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE +#undef BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE_IMPL +#undef BOOST_UNORDERED_GET_TUPLE_ARG + +#if defined(__SUNPRO_CC) + + template + void construct_from_tuple(T* ptr, Tuple const& x) + { + construct_from_tuple_impl( + boost::unordered::detail::length< + boost::tuples::length::value>(), + ptr, x); + } + +#endif + + //////////////////////////////////////////////////////////////////////////// + // SFINAE traits for construction. + + // Decide which construction method to use for a three argument + // call. Note that this is difficult to do using overloads because + // the arguments are packed into 'emplace_args3'. + // + // The decision is made on the first argument. + + +#if defined(BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT) + template + struct emulation1 { + static choice1::type test(choice1, std::pair const&); + static choice2::type test(choice2, A const&); + static choice3::type test(choice3, convert_from_anything const&); + + enum { value = + sizeof(test(choose(), boost::unordered::detail::make())) == + sizeof(choice2::type) }; + }; +#endif + + template + struct check3_base { + static choice1::type test(choice1, + boost::unordered::piecewise_construct_t); + +#if defined(BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT) + static choice2::type test(choice2, A const&); +#endif + + static choice3::type test(choice3, ...); + + enum { value = + sizeof(test(choose(), boost::unordered::detail::make())) }; + }; + + template + struct piecewise3 { + enum { value = check3_base::value == sizeof(choice1::type) }; + }; + +#if defined(BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT) + template + struct emulation3 { + enum { value = check3_base::value == sizeof(choice2::type) }; + }; + +#endif + +#if !defined(BOOST_NO_VARIADIC_TEMPLATES) + + //////////////////////////////////////////////////////////////////////////// + // Construct from variadic parameters + + template + inline void construct_impl(T* address, BOOST_FWD_REF(Args)... args) + { + new((void*) address) T(boost::forward(args)...); + } + + template + inline typename enable_if, void>::type + construct_impl(std::pair* address, + BOOST_FWD_REF(A0), BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2) + { + boost::unordered::detail::construct_from_tuple( + boost::addressof(address->first), boost::forward(a1)); + boost::unordered::detail::construct_from_tuple( + boost::addressof(address->second), boost::forward(a2)); + } + +#if defined(BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT) + + template + inline typename enable_if, void>::type + construct_impl(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(); + } + + template + inline typename enable_if, void>::type + construct_impl(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::forward(a1), + boost::forward(a2)); + } + + template + inline void construct_impl(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::forward(a1), + boost::forward(a2), + boost::forward(a3), + boost::forward(args)...); + } + +#endif // BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT +#else // BOOST_NO_VARIADIC_TEMPLATES + +//////////////////////////////////////////////////////////////////////////////// +// Construct from emplace_args + +#define BOOST_UNORDERED_CONSTRUCT_IMPL(z, num_params, _) \ + template < \ + typename T, \ + BOOST_PP_ENUM_PARAMS_Z(z, num_params, typename A) \ + > \ + inline void construct_impl(T* address, \ + boost::unordered::detail::BOOST_PP_CAT(emplace_args,num_params) < \ + BOOST_PP_ENUM_PARAMS_Z(z, num_params, A) \ + > const& args) \ + { \ + new((void*) address) T( \ + BOOST_PP_ENUM_##z(num_params, BOOST_UNORDERED_CALL_FORWARD, \ + args.a)); \ + } + + template + inline void construct_impl(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) + { + new((void*) address) T( + boost::forward(args.a0), + boost::forward(args.a1) + ); + } + + template + inline void construct_impl(T* address, emplace_args3 const& args) + { + new((void*) address) T( + boost::forward(args.a0), + boost::forward(args.a1), + boost::forward(args.a2) + ); + } + + BOOST_PP_REPEAT_FROM_TO(4, BOOST_UNORDERED_EMPLACE_LIMIT, + BOOST_UNORDERED_CONSTRUCT_IMPL, _) + +#undef BOOST_UNORDERED_CONSTRUCT_IMPL + + template + inline void construct_impl(std::pair* address, + boost::unordered::detail::emplace_args3 const& args, + typename enable_if, void*>::type = 0) + { + boost::unordered::detail::construct_from_tuple( + boost::addressof(address->first), args.a1); + boost::unordered::detail::construct_from_tuple( + boost::addressof(address->second), args.a2); + } + +#if defined(BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT) + + template + inline void construct_impl(std::pair* address, + boost::unordered::detail::emplace_args1 const& args, + typename enable_if, void*>::type = 0) + { + new((void*) boost::addressof(address->first)) A( + boost::forward(args.a0)); + new((void*) boost::addressof(address->second)) B(); + } + + template + inline void construct_impl(std::pair* address, + boost::unordered::detail::emplace_args3 const& args, + typename enable_if, void*>::type = 0) + { + new((void*) boost::addressof(address->first)) A( + boost::forward(args.a0)); + new((void*) boost::addressof(address->second)) B( + boost::forward(args.a1), + boost::forward(args.a2)); + } + +#define BOOST_UNORDERED_CONSTRUCT_PAIR_IMPL(z, num_params, _) \ + template \ + inline void construct_impl(std::pair* address, \ + boost::unordered::detail::BOOST_PP_CAT(emplace_args, num_params) < \ + BOOST_PP_ENUM_PARAMS_Z(z, num_params, A) \ + > const& args) \ + { \ + new((void*) boost::addressof(address->first)) A( \ + boost::forward(args.a0)); \ + new((void*) boost::addressof(address->second)) B( \ + BOOST_PP_ENUM_##z(BOOST_PP_DEC(num_params), \ + BOOST_UNORDERED_CALL_FORWARD2, args.a)); \ + } + +#define BOOST_UNORDERED_CALL_FORWARD2(z, i, a) \ + BOOST_UNORDERED_CALL_FORWARD(z, BOOST_PP_INC(i), a) + + BOOST_UNORDERED_CONSTRUCT_PAIR_IMPL(1, 2, _) + BOOST_PP_REPEAT_FROM_TO(4, BOOST_UNORDERED_EMPLACE_LIMIT, + BOOST_UNORDERED_CONSTRUCT_PAIR_IMPL, _) + +#undef BOOST_UNORDERED_CONSTRUCT_PAIR_IMPL +#undef BOOST_UNORDERED_CALL_FORWARD2 + +#endif // BOOST_UNORDERED_DEPRECATED_PAIR_CONSTRUCT +#endif // BOOST_NO_VARIADIC_TEMPLATES + +}}} + //////////////////////////////////////////////////////////////////////////////// // // Some helper functions for allocating & constructing diff --git a/include/boost/unordered/detail/buckets.hpp b/include/boost/unordered/detail/buckets.hpp index 78ee0a56..a7e5ddbd 100644 --- a/include/boost/unordered/detail/buckets.hpp +++ b/include/boost/unordered/detail/buckets.hpp @@ -1031,6 +1031,36 @@ namespace boost { namespace unordered { namespace detail { tmp_functions_ = !tmp_functions_; } }; + + //////////////////////////////////////////////////////////////////////////// + // rvalue parameters when type can't be a BOOST_RV_REF(T) parameter + // e.g. for int + +#if !defined(BOOST_NO_RVALUE_REFERENCES) +# define BOOST_UNORDERED_RV_REF(T) BOOST_RV_REF(T) +#else + struct please_ignore_this_overload { + typedef please_ignore_this_overload type; + }; + + template + struct rv_ref_impl { + typedef BOOST_RV_REF(T) type; + }; + + template + struct rv_ref : + boost::detail::if_true< + boost::is_class::value + >::BOOST_NESTED_TEMPLATE then < + boost::unordered::detail::rv_ref_impl, + please_ignore_this_overload + >::type + {}; + +# define BOOST_UNORDERED_RV_REF(T) \ + typename boost::unordered::detail::rv_ref::type +#endif }}} #if defined(BOOST_MSVC)