-
Notifications
You must be signed in to change notification settings - Fork 0
/
tlist.hxx
92 lines (76 loc) · 2.55 KB
/
tlist.hxx
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
84
85
86
87
88
89
90
91
92
#include <cstddef>
#define MYCLASS MYTEMPL class
template<MYCLASS ...Elems>
struct TNAME;
template<MYCLASS ...Elems>
struct TNAME {
using type = TNAME<Elems...>;
template<template<MYCLASS...> class Templ, MYCLASS ...Args>
struct TParam {
using type = Templ<Args...>;
};
template<template<MYCLASS...> class Templ>
static constexpr auto apply() {
return typename TParam<Templ, Elems...>::type{};
}
template<MYCLASS T>
static constexpr auto push_front() {
return TNAME<T, Elems...>{};
}
template<MYCLASS T>
static constexpr auto push_back() {
return TNAME<Elems..., T>{};
}
// maps can only produce TLists, couldn't make it output a TTList
template<MYCLASS Key>
struct contains_c {
template<MYCLASS First, MYCLASS Second, MYCLASS ...More>
static constexpr auto contains() {
if constexpr (static_type_eq<Key, First>())
return true;
else
return contains_c<Key>::template contains<Second, More...>();
}
template<MYCLASS Elem>
static constexpr auto contains() {
return static_type_eq<Key, Elem>();
}
};
template<MYCLASS Key>
static constexpr auto contains() {
return contains_c<Key>::template contains<Elems...>();
}
// maps can only produce TLists, couldn't make it output a TTList
template<template <MYCLASS> class F>
struct Tmapper {
template<MYCLASS First, MYCLASS Second, MYCLASS ...More>
static constexpr auto map() {
auto tail = Tmapper<F>::template map<Second, More...>();
return tail.template push_front<typename F<First>::type>();
}
template<MYCLASS Elem>
static constexpr auto map() {
return TList<typename F<Elem>::type>{};
}
};
template<template <MYCLASS> class F>
static constexpr auto Tmap() {
return Tmapper<F>::template map<Elems...>();
}
template<template<MYCLASS> class Reducer>
struct reducer {
template<MYCLASS First, MYCLASS Second, MYCLASS ...More>
static constexpr auto reduce() {
auto tail = reducer<Reducer>::template reduce<Second, More...>();
return tail.template feed<First>();
}
template<MYCLASS Elem>
static constexpr auto reduce() {
return Reducer<Elem>{};
}
};
template<template<MYCLASS> class Reducer>
static constexpr auto reduce() {
return reducer<Reducer>::template reduce<Elems...>();
}
};