-
Notifications
You must be signed in to change notification settings - Fork 0
/
parameter_pack.hpp
74 lines (52 loc) · 2.21 KB
/
parameter_pack.hpp
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
//! Tools for parameter pack.
#pragma once
#include <cstddef>
#include <utility>
namespace misc {
using std::size_t;
using std::type_identity;
using std::type_identity_t;
using std::integral_constant;
// equivalent to std::type_identity<std::tuple_element<N, std::tuple<Ts...>>>
template<size_t N, typename ...Ts>
struct parameter_pack_Nth {
static_assert(sizeof...(Ts) /* always false */, "parameter pack index out of range");
};
template<size_t N, typename First, typename ...Rest>
struct parameter_pack_Nth<N, First, Rest...>
: type_identity<typename parameter_pack_Nth<N - 1, Rest...>::type> {
};
template<typename First, typename ...Rest>
struct parameter_pack_Nth<0, First, Rest...>
: type_identity<First> {
};
template<size_t N, typename ...Ts>
using parameter_pack_Nth_t = typename parameter_pack_Nth<N, Ts...>::type;
// TODO: Use constexpr function instead of class to deduct integer type?
template<size_t N, typename IntT, IntT ...Ints>
struct parameter_pack_Nth_integer {
static_assert(sizeof...(Ints) /* always false */, "integer parameter pack index out of range");
};
template<size_t N, typename IntT, IntT First, IntT ...Rest>
struct parameter_pack_Nth_integer<N, IntT, First, Rest...>
: integral_constant<IntT, parameter_pack_Nth_integer<N - 1, IntT, Rest...>::value> {
};
template<typename IntT, IntT First, IntT ...Rest>
struct parameter_pack_Nth_integer<0, IntT, First, Rest...>
: integral_constant<IntT, First> {
};
template<size_t N, typename IntT, IntT ...Ints>
static constexpr IntT parameter_pack_Nth_integer_v = parameter_pack_Nth_integer<N, IntT, Ints...>::value;
template<size_t N, typename Seq>
struct integer_sequence_Nth;
template<size_t N, template<typename T, T...> class IntSeq, typename IntT, IntT ...Ints>
struct integer_sequence_Nth<N, IntSeq<IntT, Ints...>>
: integral_constant<IntT, parameter_pack_Nth_integer<N, IntT, Ints...>::value> {
};
template<size_t N, typename Seq>
static constexpr auto integer_sequence_Nth_v = integer_sequence_Nth<N, Seq>::value;
template<typename Func, template<typename T, T...> class IntSeq, typename IntT, IntT ...Ints>
constexpr void integer_sequence_for_each(IntSeq<IntT, Ints...>, Func) {
(Func{}(Ints), ...);
}
}