-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexample_6_no_rec_array.cpp
More file actions
83 lines (71 loc) · 2.99 KB
/
example_6_no_rec_array.cpp
File metadata and controls
83 lines (71 loc) · 2.99 KB
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
80
81
82
83
#include <utility>
using namespace std;
#define BOOST_MAGIC_GET_REGISTER_TYPE(Type, Index) \
constexpr size_t type_to_id(type_identity<Type>) noexcept { \
return Index; \
} \
constexpr Type id_to_type(integral_constant<size_t, Index > ) noexcept { \
return {}; \
} \
// Register all base types here
BOOST_MAGIC_GET_REGISTER_TYPE(short , 7)
BOOST_MAGIC_GET_REGISTER_TYPE(int , 8)
BOOST_MAGIC_GET_REGISTER_TYPE(char , 11)
BOOST_MAGIC_GET_REGISTER_TYPE(float , 15)
BOOST_MAGIC_GET_REGISTER_TYPE(double , 16)
BOOST_MAGIC_GET_REGISTER_TYPE(long double , 17)
BOOST_MAGIC_GET_REGISTER_TYPE(bool , 18)
BOOST_MAGIC_GET_REGISTER_TYPE(void* , 19)
struct OurType {
double d;
};
BOOST_MAGIC_GET_REGISTER_TYPE(OurType , 20)
#undef BOOST_MAGIC_GET_REGISTER_TYPE
template <class...>
struct List {};
template <class>
struct IsList : false_type {};
template <class ... Ts>
struct IsList<List<Ts...>> : true_type {};
template <size_t N>
struct size_array {
size_t data[N];
constexpr size_array(initializer_list<size_t> il) {
size_t index= 0;
for (auto e : il)
data[index++] = e;
}
};
template <class...Ts, size_t... I>
constexpr auto make_ids(List<Ts...> lst, index_sequence<I...> is) {
size_array<sizeof...(I)> arr = {type_to_id(type_identity<Ts>{})...};
for (auto b = arr.data, e = &arr.data[sizeof...(I)] - 1; b < e; )
swap(*b++, *e--);
return arr;
}
template <class L, size_t... I>
constexpr auto reverse_impl(L lst, index_sequence<I...> is) {
constexpr auto ids = make_ids(lst, is);
return List<decltype(id_to_type(integral_constant<size_t, ids.data[I]>{}))... >{};
}
template <class... Ts, template <class...> class L, class = enable_if_t<IsList<L<Ts...>>::value> >
constexpr auto reverse(L<Ts...> tp) {
if constexpr(!sizeof...(Ts))
return L<>{};
else
return reverse_impl(tp, make_index_sequence<sizeof...(Ts)>{});
}
static_assert(is_same_v<decltype(reverse(List<>{})), List<> >);
static_assert(is_same_v<decltype(reverse(List<int>{})), List<int> >);
static_assert(is_same_v<decltype(reverse(List<int, char, double, bool, short, void*,
int, char, double, bool, short, void*,
int, char, double, bool, short, void*,
int, char, double, bool, short, void*,
int, char, double, bool, short, void*, OurType
>{})), List<OurType, void*, short, bool, double, char, int,
void*, short, bool, double, char, int,
void*, short, bool, double, char, int,
void*, short, bool, double, char, int,
void*, short, bool, double, char, int
> >);
int main() {}