Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81392 - in trunk: boost/unordered/detail libs/unordered/test/unordered
From: dnljms_at_[hidden]
Date: 2012-11-17 07:03:32


Author: danieljames
Date: 2012-11-17 07:03:32 EST (Sat, 17 Nov 2012)
New Revision: 81392
URL: http://svn.boost.org/trac/boost/changeset/81392

Log:
Unordered: Try to make the piecewise_construct emulation a little more readable.
Text files modified:
   trunk/boost/unordered/detail/allocate.hpp | 69 ++++++++++++++++++++-------------------
   trunk/libs/unordered/test/unordered/insert_tests.cpp | 14 +++++++
   2 files changed, 48 insertions(+), 35 deletions(-)

Modified: trunk/boost/unordered/detail/allocate.hpp
==============================================================================
--- trunk/boost/unordered/detail/allocate.hpp (original)
+++ trunk/boost/unordered/detail/allocate.hpp 2012-11-17 07:03:32 EST (Sat, 17 Nov 2012)
@@ -921,37 +921,26 @@
 #endif
 
     ////////////////////////////////////////////////////////////////////////////
- // SFINAE traits for construction.
+ // Trait to check for piecewise 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.
-
-
- template <typename A, typename B, typename A0>
- struct check3_base {
+ template <typename A0>
+ struct use_piecewise {
         static choice1::type test(choice1,
             boost::unordered::piecewise_construct_t);
 
- static choice3::type test(choice3, ...);
+ static choice2::type test(choice2, ...);
 
- enum { value =
+ enum { value = sizeof(choice1::type) ==
             sizeof(test(choose(), boost::unordered::detail::make<A0>())) };
     };
 
- template <typename A, typename B, typename A0>
- struct piecewise3 {
- enum { value = check3_base<A,B,A0>::value == sizeof(choice1::type) };
- };
-
-// TODO: Full construct?
 #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
 
     ////////////////////////////////////////////////////////////////////////////
     // Construct from variadic parameters
 
+ // For the standard pair constructor.
+
     template <typename Alloc, typename T, typename... Args>
     inline void construct_value_impl(Alloc& alloc, T* address,
         BOOST_FWD_REF(Args)... args)
@@ -960,9 +949,14 @@
             address, boost::forward<Args>(args)...);
     }
 
+ // Special case for piece_construct
+ //
+ // TODO: When possible, it might be better to use std::pair's
+ // constructor for std::piece_construct with std::tuple.
+
     template <typename Alloc, typename A, typename B,
         typename A0, typename A1, typename A2>
- inline typename enable_if<piecewise3<A, B, A0>, void>::type
+ inline typename enable_if<use_piecewise<A0>, void>::type
         construct_value_impl(Alloc& alloc, std::pair<A, B>* address,
             BOOST_FWD_REF(A0), BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
     {
@@ -977,20 +971,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Construct from emplace_args
 
-#define BOOST_UNORDERED_CONSTRUCT_IMPL(z, num_params, _) \
- template < \
- typename Alloc, typename T, \
- BOOST_PP_ENUM_PARAMS_Z(z, num_params, typename A) \
- > \
- inline void construct_value_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) \
- { \
- new((void*) address) T( \
- BOOST_PP_ENUM_##z(num_params, BOOST_UNORDERED_CALL_FORWARD, \
- args.a)); \
- }
+ // Explicitly write out first three overloads for the sake of sane
+ // error messages.
 
     template <typename Alloc, typename T, typename A0>
     inline void construct_value_impl(Alloc&, T* address,
@@ -1020,16 +1002,35 @@
         );
     }
 
+ // Use a macro for the rest.
+
+#define BOOST_UNORDERED_CONSTRUCT_IMPL(z, num_params, _) \
+ template < \
+ typename Alloc, typename T, \
+ BOOST_PP_ENUM_PARAMS_Z(z, num_params, typename A) \
+ > \
+ inline void construct_value_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) \
+ { \
+ new((void*) address) T( \
+ BOOST_PP_ENUM_##z(num_params, BOOST_UNORDERED_CALL_FORWARD, \
+ args.a)); \
+ }
+
     BOOST_PP_REPEAT_FROM_TO(4, BOOST_UNORDERED_EMPLACE_LIMIT,
         BOOST_UNORDERED_CONSTRUCT_IMPL, _)
 
 #undef BOOST_UNORDERED_CONSTRUCT_IMPL
 
+ // Construct with piece_construct
+
     template <typename Alloc, typename A, typename B,
         typename A0, typename A1, typename A2>
     inline void construct_value_impl(Alloc& alloc, std::pair<A, B>* address,
             boost::unordered::detail::emplace_args3<A0, A1, A2> const& args,
- typename enable_if<piecewise3<A, B, A0>, void*>::type = 0)
+ typename enable_if<use_piecewise<A0>, void*>::type = 0)
     {
         boost::unordered::detail::construct_from_tuple(alloc,
             boost::addressof(address->first), args.a1);

Modified: trunk/libs/unordered/test/unordered/insert_tests.cpp
==============================================================================
--- trunk/libs/unordered/test/unordered/insert_tests.cpp (original)
+++ trunk/libs/unordered/test/unordered/insert_tests.cpp 2012-11-17 07:03:32 EST (Sat, 17 Nov 2012)
@@ -691,6 +691,13 @@
     BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
 }
 
+struct derived_from_piecewise_construct_t :
+ boost::unordered::piecewise_construct_t {};
+
+derived_from_piecewise_construct_t piecewise_rvalue() {
+ return derived_from_piecewise_construct_t();
+}
+
 UNORDERED_AUTO_TEST(map_emplace_test2)
 {
     boost::unordered_map<overloaded_constructor, overloaded_constructor> x;
@@ -703,9 +710,14 @@
     BOOST_TEST(x.find(overloaded_constructor(1)) != x.end() &&
         x.find(overloaded_constructor(1))->second == overloaded_constructor());
 
- x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(2,3), boost::make_tuple(4,5,6));
+ x.emplace(piecewise_rvalue(), boost::make_tuple(2,3), boost::make_tuple(4,5,6));
     BOOST_TEST(x.find(overloaded_constructor(2,3)) != x.end() &&
         x.find(overloaded_constructor(2,3))->second == overloaded_constructor(4,5,6));
+
+ derived_from_piecewise_construct_t d;
+ x.emplace(d, boost::make_tuple(9,3,1), boost::make_tuple(10));
+ BOOST_TEST(x.find(overloaded_constructor(9,3,1)) != x.end() &&
+ x.find(overloaded_constructor(9,3,1))->second == overloaded_constructor(10));
 }
 
 UNORDERED_AUTO_TEST(set_emplace_test2)


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk