-
Notifications
You must be signed in to change notification settings - Fork 0
/
type_lists.hh
155 lines (121 loc) · 3.47 KB
/
type_lists.hh
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#ifndef TYPE_LISTS_HH_
# define TYPE_LISTS_HH_
/* Needed for SortedInsert. */
# include <boost/mpl/if.hpp>
/* Type definitions. */
template<typename... Types>
struct TypeList;
template<typename Head, typename... Tail>
struct TypeList<Head, Tail...>
{
typedef Head type;
typedef TypeList<Tail...> next;
};
template<typename Head>
struct TypeList<Head>
{
typedef Head type;
};
/* Size operation. */
template<typename TL>
struct TypeList_Size;
template<>
struct TypeList_Size<TypeList<>>
{
static const int value = 0;
};
template<typename Head, typename... Tail>
struct TypeList_Size<TypeList<Head, Tail...>>
{
static const int value = 1 + TypeList_Size<TypeList<Tail...>>::value;
};
/* IndexOf operation. */
template<typename TL, typename T>
struct TypeList_IndexOf;
template<typename T>
struct TypeList_IndexOf<TypeList<>, T>
{
static const int value = -1;
};
template<typename T, typename... Tail>
struct TypeList_IndexOf<TypeList<T, Tail...>, T>
{
static const int value = 0;
};
template<typename Head, typename... Tail, typename T>
struct TypeList_IndexOf<TypeList<Head, Tail...>, T>
{
private:
static const int tail_value = TypeList_IndexOf<TypeList<Tail...>, T>::value;
public:
static const int value = tail_value == -1 ? -1 : 1 + tail_value;
};
/* At operation. */
template<typename TL, int Pos>
struct TypeList_At;
template<typename Head, typename... Tail>
struct TypeList_At<TypeList<Head, Tail...>, 0>
{
typedef Head value;
};
template<typename Head, typename... Tail, int Pos>
struct TypeList_At<TypeList<Head, Tail...>, Pos>
{
typedef typename TypeList_At<TypeList<Tail...>, Pos - 1>::value value;
};
/* Merge operation. */
template<typename TL1, typename TL2>
struct TypeList_Merge;
template<typename... L1, typename... L2>
struct TypeList_Merge<TypeList<L1...>, TypeList<L2...>>
{
typedef TypeList<L1..., L2...> value;
};
/* Sub operation. */
template<typename TL, typename T>
struct TypeList_Sub;
template<typename T, typename... Tail>
struct TypeList_Sub<TypeList<T, Tail...>, T>
{
typedef TypeList<T, Tail...> value;
};
template<typename Head, typename... Tail, typename T>
struct TypeList_Sub<TypeList<Head, Tail...>, T>
{
typedef typename TypeList_Sub<TypeList<Tail...>, T>::value value;
};
/* SortedInsert operation. */
template<typename T, typename TL, template<typename, typename> class Compare>
struct TypeList_SortedInsert;
template<typename T, template<typename, typename> class Compare>
struct TypeList_SortedInsert<T, TypeList<>, Compare>
{
typedef TypeList<T> value;
};
template<typename T, typename Head, typename... Tail, template<typename, typename> class Compare>
struct TypeList_SortedInsert<T, TypeList<Head, Tail...>, Compare>
{
typedef typename boost::mpl::if_c<
Compare<T, Head>::value,
typename TypeList_Merge<TypeList<Head>, typename TypeList_SortedInsert<T, TypeList<Tail...>, Compare>::value>::value,
TypeList<T, Head, Tail...>
>::type value;
};
/* Sort operation. */
template<typename TL, template<typename, typename> class Compare>
struct TypeList_Sort;
template<template<typename, typename> class Compare>
struct TypeList_Sort<TypeList<>, Compare>
{
typedef TypeList<> value;
};
template<typename Head, typename... Tail, template<typename, typename> class Compare>
struct TypeList_Sort<TypeList<Head, Tail...>, Compare>
{
typedef typename TypeList_SortedInsert<
Head,
typename TypeList_Sort<TypeList<Tail...>, Compare>::value,
Compare
>::value value;
};
#endif /* !TYPE_LISTS_HH_ */