Mercurial > repos > rliterman > csp2
comparison CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/include/kj/one-of.h @ 69:33d812a61356
planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author | jpayne |
---|---|
date | Tue, 18 Mar 2025 17:55:14 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
67:0e9998148a16 | 69:33d812a61356 |
---|---|
1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors | |
2 // Licensed under the MIT License: | |
3 // | |
4 // Permission is hereby granted, free of charge, to any person obtaining a copy | |
5 // of this software and associated documentation files (the "Software"), to deal | |
6 // in the Software without restriction, including without limitation the rights | |
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
8 // copies of the Software, and to permit persons to whom the Software is | |
9 // furnished to do so, subject to the following conditions: | |
10 // | |
11 // The above copyright notice and this permission notice shall be included in | |
12 // all copies or substantial portions of the Software. | |
13 // | |
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
20 // THE SOFTWARE. | |
21 | |
22 #pragma once | |
23 | |
24 #include "common.h" | |
25 | |
26 KJ_BEGIN_HEADER | |
27 | |
28 namespace kj { | |
29 | |
30 namespace _ { // private | |
31 | |
32 template <uint i, template<uint> class Fail, typename Key, typename... Variants> | |
33 struct TypeIndex_; | |
34 template <uint i, template<uint> class Fail, typename Key, typename First, typename... Rest> | |
35 struct TypeIndex_<i, Fail, Key, First, Rest...> { | |
36 static constexpr uint value = TypeIndex_<i + 1, Fail, Key, Rest...>::value; | |
37 }; | |
38 template <uint i, template<uint> class Fail, typename Key, typename... Rest> | |
39 struct TypeIndex_<i, Fail, Key, Key, Rest...> { static constexpr uint value = i; }; | |
40 template <uint i, template<uint> class Fail, typename Key> | |
41 struct TypeIndex_<i, Fail, Key>: public Fail<i> {}; | |
42 | |
43 template <uint i> | |
44 struct OneOfFailError_ { | |
45 static_assert(i == -1, "type does not match any in OneOf"); | |
46 }; | |
47 template <uint i> | |
48 struct OneOfFailZero_ { | |
49 static constexpr int value = 0; | |
50 }; | |
51 | |
52 template <uint i> | |
53 struct SuccessIfNotZero { | |
54 typedef int Success; | |
55 }; | |
56 template <> | |
57 struct SuccessIfNotZero<0> {}; | |
58 | |
59 enum class Variants0 {}; | |
60 enum class Variants1 { _variant0 }; | |
61 enum class Variants2 { _variant0, _variant1 }; | |
62 enum class Variants3 { _variant0, _variant1, _variant2 }; | |
63 enum class Variants4 { _variant0, _variant1, _variant2, _variant3 }; | |
64 enum class Variants5 { _variant0, _variant1, _variant2, _variant3, _variant4 }; | |
65 enum class Variants6 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5 }; | |
66 enum class Variants7 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6 }; | |
67 enum class Variants8 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
68 _variant7 }; | |
69 enum class Variants9 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
70 _variant7, _variant8 }; | |
71 enum class Variants10 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
72 _variant7, _variant8, _variant9 }; | |
73 enum class Variants11 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
74 _variant7, _variant8, _variant9, _variant10 }; | |
75 enum class Variants12 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
76 _variant7, _variant8, _variant9, _variant10, _variant11 }; | |
77 enum class Variants13 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
78 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12 }; | |
79 enum class Variants14 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
80 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
81 _variant13 }; | |
82 enum class Variants15 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
83 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
84 _variant13, _variant14 }; | |
85 enum class Variants16 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
86 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
87 _variant13, _variant14, _variant15 }; | |
88 enum class Variants17 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
89 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
90 _variant13, _variant14, _variant15, _variant16 }; | |
91 enum class Variants18 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
92 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
93 _variant13, _variant14, _variant15, _variant16, _variant17 }; | |
94 enum class Variants19 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
95 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
96 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18 }; | |
97 enum class Variants20 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
98 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
99 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
100 _variant19 }; | |
101 enum class Variants21 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
102 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
103 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
104 _variant19, _variant20 }; | |
105 enum class Variants22 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
106 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
107 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
108 _variant19, _variant20, _variant21 }; | |
109 enum class Variants23 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
110 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
111 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
112 _variant19, _variant20, _variant21, _variant22 }; | |
113 enum class Variants24 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
114 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
115 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
116 _variant19, _variant20, _variant21, _variant22, _variant23 }; | |
117 enum class Variants25 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
118 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
119 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
120 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24 }; | |
121 enum class Variants26 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
122 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
123 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
124 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
125 _variant25 }; | |
126 enum class Variants27 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
127 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
128 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
129 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
130 _variant25, _variant26 }; | |
131 enum class Variants28 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
132 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
133 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
134 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
135 _variant25, _variant26, _variant27 }; | |
136 enum class Variants29 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
137 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
138 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
139 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
140 _variant25, _variant26, _variant27, _variant28 }; | |
141 enum class Variants30 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
142 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
143 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
144 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
145 _variant25, _variant26, _variant27, _variant28, _variant29 }; | |
146 enum class Variants31 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
147 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
148 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
149 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
150 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30 }; | |
151 enum class Variants32 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
152 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
153 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
154 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
155 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
156 _variant31 }; | |
157 enum class Variants33 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
158 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
159 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
160 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
161 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
162 _variant31, _variant32 }; | |
163 enum class Variants34 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
164 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
165 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
166 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
167 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
168 _variant31, _variant32, _variant33 }; | |
169 enum class Variants35 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
170 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
171 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
172 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
173 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
174 _variant31, _variant32, _variant33, _variant34 }; | |
175 enum class Variants36 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
176 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
177 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
178 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
179 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
180 _variant31, _variant32, _variant33, _variant34, _variant35 }; | |
181 enum class Variants37 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
182 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
183 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
184 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
185 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
186 _variant31, _variant32, _variant33, _variant34, _variant35, _variant36 }; | |
187 enum class Variants38 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
188 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
189 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
190 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
191 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
192 _variant31, _variant32, _variant33, _variant34, _variant35, _variant36, | |
193 _variant37 }; | |
194 enum class Variants39 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
195 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
196 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
197 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
198 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
199 _variant31, _variant32, _variant33, _variant34, _variant35, _variant36, | |
200 _variant37, _variant38 }; | |
201 enum class Variants40 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
202 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
203 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
204 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
205 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
206 _variant31, _variant32, _variant33, _variant34, _variant35, _variant36, | |
207 _variant37, _variant38, _variant39 }; | |
208 enum class Variants41 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
209 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
210 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
211 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
212 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
213 _variant31, _variant32, _variant33, _variant34, _variant35, _variant36, | |
214 _variant37, _variant38, _variant39, _variant40 }; | |
215 enum class Variants42 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
216 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
217 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
218 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
219 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
220 _variant31, _variant32, _variant33, _variant34, _variant35, _variant36, | |
221 _variant37, _variant38, _variant39, _variant40, _variant41 }; | |
222 enum class Variants43 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
223 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
224 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
225 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
226 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
227 _variant31, _variant32, _variant33, _variant34, _variant35, _variant36, | |
228 _variant37, _variant38, _variant39, _variant40, _variant41, _variant42 }; | |
229 enum class Variants44 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
230 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
231 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
232 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
233 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
234 _variant31, _variant32, _variant33, _variant34, _variant35, _variant36, | |
235 _variant37, _variant38, _variant39, _variant40, _variant41, _variant42, | |
236 _variant43 }; | |
237 enum class Variants45 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
238 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
239 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
240 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
241 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
242 _variant31, _variant32, _variant33, _variant34, _variant35, _variant36, | |
243 _variant37, _variant38, _variant39, _variant40, _variant41, _variant42, | |
244 _variant43, _variant44 }; | |
245 enum class Variants46 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
246 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
247 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
248 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
249 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
250 _variant31, _variant32, _variant33, _variant34, _variant35, _variant36, | |
251 _variant37, _variant38, _variant39, _variant40, _variant41, _variant42, | |
252 _variant43, _variant44, _variant45 }; | |
253 enum class Variants47 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
254 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
255 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
256 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
257 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
258 _variant31, _variant32, _variant33, _variant34, _variant35, _variant36, | |
259 _variant37, _variant38, _variant39, _variant40, _variant41, _variant42, | |
260 _variant43, _variant44, _variant45, _variant46 }; | |
261 enum class Variants48 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
262 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
263 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
264 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
265 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
266 _variant31, _variant32, _variant33, _variant34, _variant35, _variant36, | |
267 _variant37, _variant38, _variant39, _variant40, _variant41, _variant42, | |
268 _variant43, _variant44, _variant45, _variant46, _variant47 }; | |
269 enum class Variants49 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
270 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
271 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
272 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
273 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
274 _variant31, _variant32, _variant33, _variant34, _variant35, _variant36, | |
275 _variant37, _variant38, _variant39, _variant40, _variant41, _variant42, | |
276 _variant43, _variant44, _variant45, _variant46, _variant47, _variant48 }; | |
277 enum class Variants50 { _variant0, _variant1, _variant2, _variant3, _variant4, _variant5, _variant6, | |
278 _variant7, _variant8, _variant9, _variant10, _variant11, _variant12, | |
279 _variant13, _variant14, _variant15, _variant16, _variant17, _variant18, | |
280 _variant19, _variant20, _variant21, _variant22, _variant23, _variant24, | |
281 _variant25, _variant26, _variant27, _variant28, _variant29, _variant30, | |
282 _variant31, _variant32, _variant33, _variant34, _variant35, _variant36, | |
283 _variant37, _variant38, _variant39, _variant40, _variant41, _variant42, | |
284 _variant43, _variant44, _variant45, _variant46, _variant47, _variant48, | |
285 _variant49 }; | |
286 | |
287 template <uint i> struct Variants_; | |
288 template <> struct Variants_<0> { typedef Variants0 Type; }; | |
289 template <> struct Variants_<1> { typedef Variants1 Type; }; | |
290 template <> struct Variants_<2> { typedef Variants2 Type; }; | |
291 template <> struct Variants_<3> { typedef Variants3 Type; }; | |
292 template <> struct Variants_<4> { typedef Variants4 Type; }; | |
293 template <> struct Variants_<5> { typedef Variants5 Type; }; | |
294 template <> struct Variants_<6> { typedef Variants6 Type; }; | |
295 template <> struct Variants_<7> { typedef Variants7 Type; }; | |
296 template <> struct Variants_<8> { typedef Variants8 Type; }; | |
297 template <> struct Variants_<9> { typedef Variants9 Type; }; | |
298 template <> struct Variants_<10> { typedef Variants10 Type; }; | |
299 template <> struct Variants_<11> { typedef Variants11 Type; }; | |
300 template <> struct Variants_<12> { typedef Variants12 Type; }; | |
301 template <> struct Variants_<13> { typedef Variants13 Type; }; | |
302 template <> struct Variants_<14> { typedef Variants14 Type; }; | |
303 template <> struct Variants_<15> { typedef Variants15 Type; }; | |
304 template <> struct Variants_<16> { typedef Variants16 Type; }; | |
305 template <> struct Variants_<17> { typedef Variants17 Type; }; | |
306 template <> struct Variants_<18> { typedef Variants18 Type; }; | |
307 template <> struct Variants_<19> { typedef Variants19 Type; }; | |
308 template <> struct Variants_<20> { typedef Variants20 Type; }; | |
309 template <> struct Variants_<21> { typedef Variants21 Type; }; | |
310 template <> struct Variants_<22> { typedef Variants22 Type; }; | |
311 template <> struct Variants_<23> { typedef Variants23 Type; }; | |
312 template <> struct Variants_<24> { typedef Variants24 Type; }; | |
313 template <> struct Variants_<25> { typedef Variants25 Type; }; | |
314 template <> struct Variants_<26> { typedef Variants26 Type; }; | |
315 template <> struct Variants_<27> { typedef Variants27 Type; }; | |
316 template <> struct Variants_<28> { typedef Variants28 Type; }; | |
317 template <> struct Variants_<29> { typedef Variants29 Type; }; | |
318 template <> struct Variants_<30> { typedef Variants30 Type; }; | |
319 template <> struct Variants_<31> { typedef Variants31 Type; }; | |
320 template <> struct Variants_<32> { typedef Variants32 Type; }; | |
321 template <> struct Variants_<33> { typedef Variants33 Type; }; | |
322 template <> struct Variants_<34> { typedef Variants34 Type; }; | |
323 template <> struct Variants_<35> { typedef Variants35 Type; }; | |
324 template <> struct Variants_<36> { typedef Variants36 Type; }; | |
325 template <> struct Variants_<37> { typedef Variants37 Type; }; | |
326 template <> struct Variants_<38> { typedef Variants38 Type; }; | |
327 template <> struct Variants_<39> { typedef Variants39 Type; }; | |
328 template <> struct Variants_<40> { typedef Variants40 Type; }; | |
329 template <> struct Variants_<41> { typedef Variants41 Type; }; | |
330 template <> struct Variants_<42> { typedef Variants42 Type; }; | |
331 template <> struct Variants_<43> { typedef Variants43 Type; }; | |
332 template <> struct Variants_<44> { typedef Variants44 Type; }; | |
333 template <> struct Variants_<45> { typedef Variants45 Type; }; | |
334 template <> struct Variants_<46> { typedef Variants46 Type; }; | |
335 template <> struct Variants_<47> { typedef Variants47 Type; }; | |
336 template <> struct Variants_<48> { typedef Variants48 Type; }; | |
337 template <> struct Variants_<49> { typedef Variants49 Type; }; | |
338 template <> struct Variants_<50> { typedef Variants50 Type; }; | |
339 | |
340 template <uint i> | |
341 using Variants = typename Variants_<i>::Type; | |
342 | |
343 } // namespace _ (private) | |
344 | |
345 template <typename... Variants> | |
346 class OneOf { | |
347 template <typename Key> | |
348 static inline constexpr uint typeIndex() { | |
349 return _::TypeIndex_<1, _::OneOfFailError_, Key, Variants...>::value; | |
350 } | |
351 // Get the 1-based index of Key within the type list Types, or static_assert with a nice error. | |
352 | |
353 template <typename Key> | |
354 static inline constexpr uint typeIndexOrZero() { | |
355 return _::TypeIndex_<1, _::OneOfFailZero_, Key, Variants...>::value; | |
356 } | |
357 | |
358 template <uint i, typename... OtherVariants> | |
359 struct HasAll; | |
360 // Has a member type called "Success" if and only if all of `OtherVariants` are types that | |
361 // appear in `Variants`. Used with SFINAE to enable subset constructors. | |
362 | |
363 public: | |
364 inline OneOf(): tag(0) {} | |
365 | |
366 OneOf(const OneOf& other) { copyFrom(other); } | |
367 OneOf(OneOf& other) { copyFrom(other); } | |
368 OneOf(OneOf&& other) { moveFrom(other); } | |
369 // Copy/move from same OneOf type. | |
370 | |
371 template <typename... OtherVariants, typename = typename HasAll<1, OtherVariants...>::Success> | |
372 OneOf(const OneOf<OtherVariants...>& other) { copyFromSubset(other); } | |
373 template <typename... OtherVariants, typename = typename HasAll<1, OtherVariants...>::Success> | |
374 OneOf(OneOf<OtherVariants...>& other) { copyFromSubset(other); } | |
375 template <typename... OtherVariants, typename = typename HasAll<1, OtherVariants...>::Success> | |
376 OneOf(OneOf<OtherVariants...>&& other) { moveFromSubset(other); } | |
377 // Copy/move from OneOf that contains a subset of the types we do. | |
378 | |
379 template <typename T, typename = typename HasAll<0, Decay<T>>::Success> | |
380 OneOf(T&& other): tag(typeIndex<Decay<T>>()) { | |
381 ctor(*reinterpret_cast<Decay<T>*>(space), kj::fwd<T>(other)); | |
382 } | |
383 // Copy/move from a value that matches one of the individual types in the OneOf. | |
384 | |
385 ~OneOf() { destroy(); } | |
386 | |
387 OneOf& operator=(const OneOf& other) { if (tag != 0) destroy(); copyFrom(other); return *this; } | |
388 OneOf& operator=(OneOf&& other) { if (tag != 0) destroy(); moveFrom(other); return *this; } | |
389 | |
390 inline bool operator==(decltype(nullptr)) const { return tag == 0; } | |
391 inline bool operator!=(decltype(nullptr)) const { return tag != 0; } | |
392 | |
393 template <typename T> | |
394 bool is() const { | |
395 return tag == typeIndex<T>(); | |
396 } | |
397 | |
398 template <typename T> | |
399 T& get() & { | |
400 KJ_IREQUIRE(is<T>(), "Must check OneOf::is<T>() before calling get<T>()."); | |
401 return *reinterpret_cast<T*>(space); | |
402 } | |
403 template <typename T> | |
404 T&& get() && { | |
405 KJ_IREQUIRE(is<T>(), "Must check OneOf::is<T>() before calling get<T>()."); | |
406 return kj::mv(*reinterpret_cast<T*>(space)); | |
407 } | |
408 template <typename T> | |
409 const T& get() const& { | |
410 KJ_IREQUIRE(is<T>(), "Must check OneOf::is<T>() before calling get<T>()."); | |
411 return *reinterpret_cast<const T*>(space); | |
412 } | |
413 template <typename T> | |
414 const T&& get() const&& { | |
415 KJ_IREQUIRE(is<T>(), "Must check OneOf::is<T>() before calling get<T>()."); | |
416 return kj::mv(*reinterpret_cast<const T*>(space)); | |
417 } | |
418 | |
419 template <typename T, typename... Params> | |
420 T& init(Params&&... params) { | |
421 if (tag != 0) destroy(); | |
422 ctor(*reinterpret_cast<T*>(space), kj::fwd<Params>(params)...); | |
423 tag = typeIndex<T>(); | |
424 return *reinterpret_cast<T*>(space); | |
425 } | |
426 | |
427 template <typename T> | |
428 Maybe<T&> tryGet() { | |
429 if (is<T>()) { | |
430 return *reinterpret_cast<T*>(space); | |
431 } else { | |
432 return nullptr; | |
433 } | |
434 } | |
435 template <typename T> | |
436 Maybe<const T&> tryGet() const { | |
437 if (is<T>()) { | |
438 return *reinterpret_cast<const T*>(space); | |
439 } else { | |
440 return nullptr; | |
441 } | |
442 } | |
443 | |
444 template <uint i> | |
445 KJ_NORETURN(void allHandled()); | |
446 // After a series of if/else blocks handling each variant of the OneOf, have the final else | |
447 // block call allHandled<n>() where n is the number of variants. This will fail to compile | |
448 // if new variants are added in the future. | |
449 | |
450 typedef _::Variants<sizeof...(Variants)> Tag; | |
451 | |
452 Tag which() const { | |
453 KJ_IREQUIRE(tag != 0, "Can't KJ_SWITCH_ONEOF() on uninitialized value."); | |
454 return static_cast<Tag>(tag - 1); | |
455 } | |
456 | |
457 template <typename T> | |
458 static constexpr Tag tagFor() { | |
459 return static_cast<Tag>(typeIndex<T>() - 1); | |
460 } | |
461 | |
462 OneOf* _switchSubject() & { return this; } | |
463 const OneOf* _switchSubject() const& { return this; } | |
464 _::NullableValue<OneOf> _switchSubject() && { return kj::mv(*this); } | |
465 | |
466 private: | |
467 uint tag; | |
468 | |
469 static inline constexpr size_t maxSize(size_t a) { | |
470 return a; | |
471 } | |
472 template <typename... Rest> | |
473 static inline constexpr size_t maxSize(size_t a, size_t b, Rest... rest) { | |
474 return maxSize(kj::max(a, b), rest...); | |
475 } | |
476 // Returns the maximum of all the parameters. | |
477 // TODO(someday): Generalize the above template and make it common. I tried, but C++ decided to | |
478 // be difficult so I cut my losses. | |
479 | |
480 static constexpr auto spaceSize = maxSize(sizeof(Variants)...); | |
481 // TODO(msvc): This constant could just as well go directly inside space's bracket's, where it's | |
482 // used, but MSVC suffers a parse error on `...`. | |
483 | |
484 union { | |
485 byte space[spaceSize]; | |
486 | |
487 void* forceAligned; | |
488 // TODO(someday): Use C++11 alignas() once we require GCC 4.8 / Clang 3.3. | |
489 }; | |
490 | |
491 template <typename... T> | |
492 inline void doAll(T... t) {} | |
493 | |
494 template <typename T> | |
495 inline bool destroyVariant() { | |
496 if (tag == typeIndex<T>()) { | |
497 tag = 0; | |
498 dtor(*reinterpret_cast<T*>(space)); | |
499 } | |
500 return false; | |
501 } | |
502 void destroy() { | |
503 doAll(destroyVariant<Variants>()...); | |
504 } | |
505 | |
506 template <typename T> | |
507 inline bool copyVariantFrom(const OneOf& other) { | |
508 if (other.is<T>()) { | |
509 ctor(*reinterpret_cast<T*>(space), other.get<T>()); | |
510 } | |
511 return false; | |
512 } | |
513 void copyFrom(const OneOf& other) { | |
514 // Initialize as a copy of `other`. Expects that `this` starts out uninitialized, so the tag | |
515 // is invalid. | |
516 tag = other.tag; | |
517 doAll(copyVariantFrom<Variants>(other)...); | |
518 } | |
519 | |
520 template <typename T> | |
521 inline bool copyVariantFrom(OneOf& other) { | |
522 if (other.is<T>()) { | |
523 ctor(*reinterpret_cast<T*>(space), other.get<T>()); | |
524 } | |
525 return false; | |
526 } | |
527 void copyFrom(OneOf& other) { | |
528 // Initialize as a copy of `other`. Expects that `this` starts out uninitialized, so the tag | |
529 // is invalid. | |
530 tag = other.tag; | |
531 doAll(copyVariantFrom<Variants>(other)...); | |
532 } | |
533 | |
534 template <typename T> | |
535 inline bool moveVariantFrom(OneOf& other) { | |
536 if (other.is<T>()) { | |
537 ctor(*reinterpret_cast<T*>(space), kj::mv(other.get<T>())); | |
538 } | |
539 return false; | |
540 } | |
541 void moveFrom(OneOf& other) { | |
542 // Initialize as a copy of `other`. Expects that `this` starts out uninitialized, so the tag | |
543 // is invalid. | |
544 tag = other.tag; | |
545 doAll(moveVariantFrom<Variants>(other)...); | |
546 } | |
547 | |
548 template <typename T, typename... OtherVariants> | |
549 inline bool copySubsetVariantFrom(const OneOf<OtherVariants...>& other) { | |
550 if (other.template is<T>()) { | |
551 tag = typeIndex<Decay<T>>(); | |
552 ctor(*reinterpret_cast<T*>(space), other.template get<T>()); | |
553 } | |
554 return false; | |
555 } | |
556 template <typename... OtherVariants> | |
557 void copyFromSubset(const OneOf<OtherVariants...>& other) { | |
558 doAll(copySubsetVariantFrom<OtherVariants>(other)...); | |
559 } | |
560 | |
561 template <typename T, typename... OtherVariants> | |
562 inline bool copySubsetVariantFrom(OneOf<OtherVariants...>& other) { | |
563 if (other.template is<T>()) { | |
564 tag = typeIndex<Decay<T>>(); | |
565 ctor(*reinterpret_cast<T*>(space), other.template get<T>()); | |
566 } | |
567 return false; | |
568 } | |
569 template <typename... OtherVariants> | |
570 void copyFromSubset(OneOf<OtherVariants...>& other) { | |
571 doAll(copySubsetVariantFrom<OtherVariants>(other)...); | |
572 } | |
573 | |
574 template <typename T, typename... OtherVariants> | |
575 inline bool moveSubsetVariantFrom(OneOf<OtherVariants...>& other) { | |
576 if (other.template is<T>()) { | |
577 tag = typeIndex<Decay<T>>(); | |
578 ctor(*reinterpret_cast<T*>(space), kj::mv(other.template get<T>())); | |
579 } | |
580 return false; | |
581 } | |
582 template <typename... OtherVariants> | |
583 void moveFromSubset(OneOf<OtherVariants...>& other) { | |
584 doAll(moveSubsetVariantFrom<OtherVariants>(other)...); | |
585 } | |
586 }; | |
587 | |
588 template <typename... Variants> | |
589 template <uint i, typename First, typename... Rest> | |
590 struct OneOf<Variants...>::HasAll<i, First, Rest...> | |
591 : public HasAll<typeIndexOrZero<First>(), Rest...> {}; | |
592 template <typename... Variants> | |
593 template <uint i> | |
594 struct OneOf<Variants...>::HasAll<i>: public _::SuccessIfNotZero<i> {}; | |
595 | |
596 template <typename... Variants> | |
597 template <uint i> | |
598 void OneOf<Variants...>::allHandled() { | |
599 // After a series of if/else blocks handling each variant of the OneOf, have the final else | |
600 // block call allHandled<n>() where n is the number of variants. This will fail to compile | |
601 // if new variants are added in the future. | |
602 | |
603 static_assert(i == sizeof...(Variants), "new OneOf variants need to be handled here"); | |
604 KJ_UNREACHABLE; | |
605 } | |
606 | |
607 #if KJ_CPP_STD > 201402L | |
608 #define KJ_SWITCH_ONEOF(value) \ | |
609 switch (auto _kj_switch_subject = (value)._switchSubject(); _kj_switch_subject->which()) | |
610 #else | |
611 #define KJ_SWITCH_ONEOF(value) \ | |
612 /* Without C++17, we can only support one switch per containing block. Deal with it. */ \ | |
613 auto _kj_switch_subject = (value)._switchSubject(); \ | |
614 switch (_kj_switch_subject->which()) | |
615 #endif | |
616 #if !_MSC_VER || defined(__clang__) | |
617 #define KJ_CASE_ONEOF(name, ...) \ | |
618 break; \ | |
619 case ::kj::Decay<decltype(*_kj_switch_subject)>::template tagFor<__VA_ARGS__>(): \ | |
620 for (auto& name = _kj_switch_subject->template get<__VA_ARGS__>(), *_kj_switch_done = &name; \ | |
621 _kj_switch_done; _kj_switch_done = nullptr) | |
622 #else | |
623 // TODO(msvc): The latest MSVC which ships with VS2019 now ICEs on the implementation above. It | |
624 // appears we can hack around the problem by moving the `->template get<>()` syntax to an outer | |
625 // `if`. (This unfortunately allows wonky syntax like `KJ_CASE_ONEOF(a, B) { } else { }`.) | |
626 // https://developercommunity.visualstudio.com/content/problem/1143733/internal-compiler-error-on-v1670.html | |
627 #define KJ_CASE_ONEOF(name, ...) \ | |
628 break; \ | |
629 case ::kj::Decay<decltype(*_kj_switch_subject)>::template tagFor<__VA_ARGS__>(): \ | |
630 if (auto* _kj_switch_done = &_kj_switch_subject->template get<__VA_ARGS__>()) \ | |
631 for (auto& name = *_kj_switch_done; _kj_switch_done; _kj_switch_done = nullptr) | |
632 #endif | |
633 #define KJ_CASE_ONEOF_DEFAULT break; default: | |
634 // Allows switching over a OneOf. | |
635 // | |
636 // Example: | |
637 // | |
638 // kj::OneOf<int, float, const char*> variant; | |
639 // KJ_SWITCH_ONEOF(variant) { | |
640 // KJ_CASE_ONEOF(i, int) { | |
641 // doSomethingWithInt(i); | |
642 // } | |
643 // KJ_CASE_ONEOF(s, const char*) { | |
644 // doSomethingWithString(s); | |
645 // } | |
646 // KJ_CASE_ONEOF_DEFAULT { | |
647 // doSomethingElse(); | |
648 // } | |
649 // } | |
650 // | |
651 // Notes: | |
652 // - If you don't handle all possible types and don't include a default branch, you'll get a | |
653 // compiler warning, just like a regular switch() over an enum where one of the enum values is | |
654 // missing. | |
655 // - There's no need for a `break` statement in a KJ_CASE_ONEOF; it is implied. | |
656 // - Under C++11 and C++14, only one KJ_SWITCH_ONEOF() can appear in a block. Wrap the switch in | |
657 // a pair of braces if you need a second switch in the same block. If C++17 is enabled, this is | |
658 // not an issue. | |
659 // | |
660 // Implementation notes: | |
661 // - The use of __VA_ARGS__ is to account for template types that have commas separating type | |
662 // parameters, since macros don't recognize <> as grouping. | |
663 // - _kj_switch_done is really used as a boolean flag to prevent the for() loop from actually | |
664 // looping, but it's defined as a pointer since that's all we can define in this context. | |
665 | |
666 } // namespace kj | |
667 | |
668 KJ_END_HEADER |