mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-29 19:07:15 +02:00
Unordered: Try to make the piecewise_construct emulation a little more readable.
[SVN r81392]
This commit is contained in:
@ -921,37 +921,26 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::)
|
||||
#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 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::)
|
||||
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 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 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 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::)
|
||||
);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
@ -691,6 +691,13 @@ UNORDERED_AUTO_TEST(set_emplace_test)
|
||||
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 @@ UNORDERED_AUTO_TEST(map_emplace_test2)
|
||||
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)
|
||||
|
Reference in New Issue
Block a user