Fix some SFINAE failures in map_pack

* Make unpack capable of SFINAE
This commit is contained in:
Denis Blank 2018-02-07 01:57:22 +01:00
parent 0da8d1206f
commit a0a0619953
3 changed files with 40 additions and 31 deletions

View File

@ -315,41 +315,48 @@ constexpr decltype(auto) unpack(std::integer_sequence<std::size_t, I...>,
/// Calls the given unpacker with the content of the given sequenceable
template <typename F, typename U, std::size_t... I>
constexpr decltype(auto) unpack(F&& firstSequenceable, U&& unpacker,
std::integer_sequence<std::size_t, I...>) {
using std::get;
(void)firstSequenceable;
constexpr auto unpack(F&& first_sequenceable, U&& unpacker,
std::integer_sequence<std::size_t, I...>)
-> decltype(std::forward<U>(unpacker)(
get<I>(std::forward<F>(first_sequenceable))...)) {
return std::forward<U>(unpacker)(
get<I>(std::forward<F>(firstSequenceable))...);
get<I>(std::forward<F>(first_sequenceable))...);
}
/// Calls the given unpacker with the content of the given sequenceable
template <typename F, typename S, typename U, std::size_t... IF,
std::size_t... IS>
constexpr decltype(auto) unpack(F&& firstSequenceable, S&& secondSequenceable,
U&& unpacker,
std::integer_sequence<std::size_t, IF...>,
std::integer_sequence<std::size_t, IS...>) {
using std::get;
(void)firstSequenceable;
(void)secondSequenceable;
constexpr auto unpack(F&& first_sequenceable, S&& second_sequenceable,
U&& unpacker, std::integer_sequence<std::size_t, IF...>,
std::integer_sequence<std::size_t, IS...>)
-> decltype(std::forward<U>(unpacker)(
get<IF>(std::forward<F>(first_sequenceable))...,
get<IS>(std::forward<S>(second_sequenceable))...)) {
return std::forward<U>(unpacker)(
get<IF>(std::forward<F>(firstSequenceable))...,
get<IS>(std::forward<S>(secondSequenceable))...);
get<IF>(std::forward<F>(first_sequenceable))...,
get<IS>(std::forward<S>(second_sequenceable))...);
}
/// Calls the given unpacker with the content of the given sequenceable
template <typename F, typename U>
constexpr decltype(auto) unpack(F&& firstSequenceable, U&& unpacker) {
return unpack(std::forward<F>(firstSequenceable), std::forward<U>(unpacker),
sequence_of(identify<decltype(firstSequenceable)>{}));
constexpr auto unpack(F&& first_sequenceable, U&& unpacker)
-> decltype(unpack(std::forward<F>(first_sequenceable),
std::forward<U>(unpacker),
sequence_of(identify<decltype(first_sequenceable)>{}))) {
return unpack(std::forward<F>(first_sequenceable), std::forward<U>(unpacker),
sequence_of(identify<decltype(first_sequenceable)>{}));
}
/// Calls the given unpacker with the content of the given sequenceables
template <typename F, typename S, typename U>
constexpr decltype(auto) unpack(F&& firstSequenceable, S&& secondSequenceable,
U&& unpacker) {
return unpack(std::forward<F>(firstSequenceable),
std::forward<S>(secondSequenceable), std::forward<U>(unpacker),
sequence_of(identity_of(firstSequenceable)),
sequence_of(identity_of(secondSequenceable)));
constexpr auto unpack(F&& first_sequenceable, S&& second_sequenceable,
U&& unpacker)
-> decltype(unpack(std::forward<F>(first_sequenceable),
std::forward<S>(second_sequenceable),
std::forward<U>(unpacker),
sequence_of(identity_of(first_sequenceable)),
sequence_of(identity_of(second_sequenceable)))) {
return unpack(std::forward<F>(first_sequenceable),
std::forward<S>(second_sequenceable), std::forward<U>(unpacker),
sequence_of(identity_of(first_sequenceable)),
sequence_of(identity_of(second_sequenceable)));
}
/// Applies the handler function to each element contained in the sequenceable

View File

@ -191,8 +191,8 @@ struct flat_arraylizer {
template <typename C, typename... T>
constexpr auto apply_spread_impl(std::true_type, C&& callable, T&&... args)
-> decltype(
traits::unpack(std::tuple_cat(undecorate(std::forward<T>(args))...)),
std::forward<C>(callable)) {
traits::unpack(std::tuple_cat(undecorate(std::forward<T>(args))...),
std::forward<C>(callable))) {
return traits::unpack(std::tuple_cat(undecorate(std::forward<T>(args))...),
std::forward<C>(callable));
}

View File

@ -686,13 +686,13 @@ static void test_strategic_tuple_like_traverse() {
}
// Fixed size homogeneous container
/* TODO Fix this test
{
std::array<int, 3> values{{1, 2, 3}};
std::array<float, 3> res = map_pack([](int) { return 1.f; }, values);
// TODO Fix this test
//{
// std::array<int, 3> values{{1, 2, 3}};
// std::array<float, 3> res = map_pack([](int) { return 1.f; }, values);
EXPECT_TRUE((res == std::array<float, 3>{{1.f, 1.f, 1.f}}));
}*/
// EXPECT_TRUE((res == std::array<float, 3>{{1.f, 1.f, 1.f}}));
//}
// Make it possible to pass tuples containing move only objects
// in as reference, while returning those as reference.
@ -769,6 +769,7 @@ static void test_spread_container_traverse() {
}
}
/*
static void test_spread_tuple_like_traverse() {
// 1:2 mappings (multiple arguments)
{
@ -805,6 +806,7 @@ static void test_spread_tuple_like_traverse() {
static_assert(std::is_void<Result>::value, "Failed...");
}
}
*/
/*
TODO Convert this to gtest