mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-30 11:27: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
|
#endif
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// SFINAE traits for construction.
|
// Trait to check for piecewise construction.
|
||||||
|
|
||||||
// Decide which construction method to use for a three argument
|
template <typename A0>
|
||||||
// call. Note that this is difficult to do using overloads because
|
struct use_piecewise {
|
||||||
// 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 {
|
|
||||||
static choice1::type test(choice1,
|
static choice1::type test(choice1,
|
||||||
boost::unordered::piecewise_construct_t);
|
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>())) };
|
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)
|
#if !defined(BOOST_NO_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Construct from variadic parameters
|
// Construct from variadic parameters
|
||||||
|
|
||||||
|
// For the standard pair constructor.
|
||||||
|
|
||||||
template <typename Alloc, typename T, typename... Args>
|
template <typename Alloc, typename T, typename... Args>
|
||||||
inline void construct_value_impl(Alloc& alloc, T* address,
|
inline void construct_value_impl(Alloc& alloc, T* address,
|
||||||
BOOST_FWD_REF(Args)... args)
|
BOOST_FWD_REF(Args)... args)
|
||||||
@ -960,9 +949,14 @@ BOOST_UNORDERED_CONSTRUCT_FROM_TUPLE(10, boost::)
|
|||||||
address, boost::forward<Args>(args)...);
|
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,
|
template <typename Alloc, typename A, typename B,
|
||||||
typename A0, typename A1, typename A2>
|
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,
|
construct_value_impl(Alloc& alloc, std::pair<A, B>* address,
|
||||||
BOOST_FWD_REF(A0), BOOST_FWD_REF(A1) a1, BOOST_FWD_REF(A2) a2)
|
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
|
// Construct from emplace_args
|
||||||
|
|
||||||
#define BOOST_UNORDERED_CONSTRUCT_IMPL(z, num_params, _) \
|
// Explicitly write out first three overloads for the sake of sane
|
||||||
template < \
|
// error messages.
|
||||||
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)); \
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Alloc, typename T, typename A0>
|
template <typename Alloc, typename T, typename A0>
|
||||||
inline void construct_value_impl(Alloc&, T* address,
|
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_PP_REPEAT_FROM_TO(4, BOOST_UNORDERED_EMPLACE_LIMIT,
|
||||||
BOOST_UNORDERED_CONSTRUCT_IMPL, _)
|
BOOST_UNORDERED_CONSTRUCT_IMPL, _)
|
||||||
|
|
||||||
#undef BOOST_UNORDERED_CONSTRUCT_IMPL
|
#undef BOOST_UNORDERED_CONSTRUCT_IMPL
|
||||||
|
|
||||||
|
// Construct with piece_construct
|
||||||
|
|
||||||
template <typename Alloc, typename A, typename B,
|
template <typename Alloc, typename A, typename B,
|
||||||
typename A0, typename A1, typename A2>
|
typename A0, typename A1, typename A2>
|
||||||
inline void construct_value_impl(Alloc& alloc, std::pair<A, B>* address,
|
inline void construct_value_impl(Alloc& alloc, std::pair<A, B>* address,
|
||||||
boost::unordered::detail::emplace_args3<A0, A1, A2> const& args,
|
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::unordered::detail::construct_from_tuple(alloc,
|
||||||
boost::addressof(address->first), args.a1);
|
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);
|
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)
|
UNORDERED_AUTO_TEST(map_emplace_test2)
|
||||||
{
|
{
|
||||||
boost::unordered_map<overloaded_constructor, overloaded_constructor> x;
|
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() &&
|
BOOST_TEST(x.find(overloaded_constructor(1)) != x.end() &&
|
||||||
x.find(overloaded_constructor(1))->second == overloaded_constructor());
|
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() &&
|
BOOST_TEST(x.find(overloaded_constructor(2,3)) != x.end() &&
|
||||||
x.find(overloaded_constructor(2,3))->second == overloaded_constructor(4,5,6));
|
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)
|
UNORDERED_AUTO_TEST(set_emplace_test2)
|
||||||
|
Reference in New Issue
Block a user