/
tuple_utils.h
79 lines (69 loc) · 2.27 KB
/
tuple_utils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*
* This file is subject to the terms and conditions defined in
* file 'LICENSE', which is part of this source code package.
*
* Authors: Gil Hoben
*
*/
#ifndef PROSTRUCT_TUPLE_UTILS_H
#define PROSTRUCT_TUPLE_UTILS_H
#include <tuple>
#include <type_traits>
#include <utility>
namespace prostruct
{
// taken from https://stackoverflow.com/a/12650100
template <size_t N>
struct Apply
{
template <typename F, typename T, typename... A>
static inline auto apply(F&& f, T&& t, A&&... a)
{
return Apply<N - 1>::apply(std::forward<F>(f), std::forward<T>(t),
std::get<N - 1>(std::forward<T>(t)), std::forward<A>(a)...);
}
};
template <>
struct Apply<0>
{
template <typename F, typename T, typename... A>
static inline auto apply(F&& f, T&&, A&&... a)
{
return std::forward<F>(f)(::std::forward<A>(a)...);
}
};
template <typename F, typename T, typename ResultType>
void apply(F&& f, T&& t, ResultType& result)
{
result = Apply<std::tuple_size<std::decay_t<T>>::value>::apply(
std::forward<F>(f), std::forward<T>(t));
}
// adapted from https://en.cppreference.com/w/cpp/utility/integer_sequence
template <typename LambdaTuple, typename... LambdaArgs, std::size_t... Idx, typename ResultType>
void execute_tuple_helper(const LambdaTuple& lambda_tuple,
const std::tuple<LambdaArgs...>& lambda_args, std::index_sequence<Idx...>,
ResultType&& result)
{
return (apply(std::get<Idx>(lambda_tuple), lambda_args, result(Idx)), ...);
}
template <typename... Args, typename... LambdaArgs, typename ResultType>
void execute_tuple(const std::tuple<Args...>& lambda_tuple,
const std::tuple<LambdaArgs...>& lambda_args, ResultType&& result)
{
return execute_tuple_helper(lambda_tuple, lambda_args, std::index_sequence_for<Args...> {},
std::forward<ResultType>(result));
}
template <typename T, std::size_t... Idx>
auto vector_to_tuple_helper(
const std::vector<T>& vec, std::index_sequence<Idx...>, size_t offset)
{
return std::forward_as_tuple(vec[Idx + offset]...);
}
template <typename T, std::size_t... Idx>
auto vector_to_tuple_helper(
const std::vector<T>& vec, std::index_sequence<Idx...>, size_t offset, size_t pair_offset)
{
return std::forward_as_tuple(vec[Idx + offset]..., vec[Idx + pair_offset]...);
}
}
#endif // PROSTRUCT_TUPLE_UTILS_H