Realm
A distributed, event-based tasking library
Loading...
Searching...
No Matches
dynamic_templates.h
Go to the documentation of this file.
1/*
2 * Copyright 2025 Stanford University, NVIDIA Corporation
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18// helper templates for dynamically packing/unpacking template parameters
19
20#ifndef REALM_DYNAMIC_TEMPLATES_H
21#define REALM_DYNAMIC_TEMPLATES_H
22
23#include "compiler_support.h"
24
25namespace Realm {
26 namespace DynamicTemplates {
27
28 // a TypeList is a linked list of templated types that captures a list of types
29 // and supports the following template-land operations:
30 // a) TL::TypePresent<T>::value - returns a boolean indicating if T is in the list
31 // b) TL::TypeToIndex<T>::INDEX - returns the 0-based index of a type in the list
32 // (compile error if not present)
33 // c) TL::IndexToType<N>::TYPE - returns the type in position N in the list
34 // (compile error if not present)
35 //
36 // and a family of dynamic operations:
37 // d) TL::demux<TARGET>(i, args...) - calls TARGET::demux<T>(args...) where T
38 // is the i'th type in the list
39
40 template <typename _HEAD, typename _TAIL>
41 struct TypeListElem;
42 struct TypeListTerm;
43
44 // variadic templates from C++11 would be more graceful
45 template <typename T1 = void, typename T2 = void, typename T3 = void,
46 typename T4 = void, typename T5 = void, typename T6 = void>
50
51 template <>
52 struct TypeList<void, void, void, void, void, void> {
54 };
55
56 template <typename _HEAD, typename _TAIL>
57 struct TypeListElem {
58 typedef _HEAD HEAD;
59 typedef _TAIL TAIL;
60
61 // TypePresent support
62 template <typename T, typename ORIG = TypeListElem<HEAD, TAIL>>
63 struct TypePresent {
64 static const bool value = _TAIL::template TypePresent<T, ORIG>::value;
65 };
66 template <typename ORIG>
67 struct TypePresent<HEAD, ORIG> {
68 static const bool value = true;
69 };
70
71 // TypeToIndex support
72 template <typename T, typename ORIG = TypeListElem<HEAD, TAIL>>
73 struct TypeToIndex {
74 static const int INDEX = 1 + _TAIL::template TypeToIndex<T, ORIG>::INDEX;
75 };
76 template <typename ORIG>
77 struct TypeToIndex<HEAD, ORIG> {
78 static const int INDEX = 0;
79 };
80
81 // IndexToType support
82 template <int N, typename ORIG = TypeListElem<HEAD, TAIL>>
83 struct IndexToType {
84 typedef typename _TAIL::template IndexToType<N - 1, ORIG>::TYPE TYPE;
85 };
86 template <typename ORIG>
87 struct IndexToType<0, ORIG> {
88 typedef _HEAD TYPE;
89 };
90
91 // MaxSize support
92 struct MaxSize {
93 // Unforuntately std::max is not constexpr until c++14
94 static constexpr size_t value =
95 sizeof(_HEAD) < _TAIL::MaxSize::value ? _TAIL::MaxSize::value : sizeof(_HEAD);
96 };
97
98 // MaxSizeType support
99 template <size_t SIZE>
100 struct MaxSizeType {
101 typedef
102 typename std::conditional<SIZE == sizeof(_HEAD), _HEAD,
103 typename _TAIL::template MaxSizeType<SIZE>>::type
105 };
106
107 // demux support
108 template <typename TARGET, int N>
109 struct DemuxHelper {
110 template <typename T1>
111 static void demux(int index, T1 arg1);
112
113 template <typename T1, typename T2>
114 static void demux(int index, T1 arg1, T2 arg2);
115
116 template <typename T1, typename T2, typename T3>
117 static void demux(int index, T1 arg1, T2 arg2, T3 arg3);
118
119 template <typename T1, typename T2, typename T3, typename T4>
120 static void demux(int index, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
121 };
122
123 template <typename TARGET, typename T1>
124 static void demux(int index, T1 arg1);
125
126 template <typename TARGET, typename T1, typename T2>
127 static void demux(int index, T1 arg1, T2 arg2);
128
129 template <typename TARGET, typename T1, typename T2, typename T3>
130 static void demux(int index, T1 arg1, T2 arg2, T3 arg3);
131
132 template <typename TARGET, typename T1, typename T2, typename T3, typename T4>
133 static void demux(int index, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
134 };
135
137 // TypePresent support
138 template <typename T, typename ORIG>
139 struct TypePresent {
140 static const bool value = false;
141 };
142
143 // TypeToIndex support
144 template <typename T, typename ORIG>
146
147 template <typename T, typename ORIG>
151
152 // IndexToType support
153 template <typename ORIG>
155 template <int N, typename ORIG>
156 struct IndexToType {
158 };
159
160 // MaxSize support
161 struct MaxSize {
162 static constexpr size_t value = 0;
163 };
164
166
167 template <size_t SIZE>
171
172 // demux support
173 template <typename TARGET, int N>
174 struct DemuxHelper {
175 template <typename T1>
176 static void demux(int index, T1 arg1);
177
178 template <typename T1, typename T2>
179 static void demux(int index, T1 arg1, T2 arg2);
180
181 template <typename T1, typename T2, typename T3>
182 static void demux(int index, T1 arg1, T2 arg2, T3 arg3);
183
184 template <typename T1, typename T2, typename T3, typename T4>
185 static void demux(int index, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
186 };
187 };
188
189 // an IntList is like a TypeList, but it conceptually holds a contiguous range of
190 // integers. For uniformity, it actually holds Int<N>'s and supports the same
191 // operations:
192 // a) TL::TypePresent<N>::value - returns a boolean indicating if N is in the list
193 // b) TL::TypeToIndex<Int<N>>::INDEX - returns N if it is in the list
194 // (compile error if not present)
195 // c) TL::IndexToType<N>::TYPE - returns Int<N> if N is in the list
196 // (compile error if not present)
197 //
198 // and a family of dynamic operations:
199 // d) TL::demux<TARGET>(i, args...) - calls TARGET::demux<Int<i>>(args...) if i is in
200 // the list
201
202 template <int _N>
203 struct Int {
204 static const int N = _N;
205 };
206
207 template <typename TARGET, int BASE, int DELTA>
209 template <typename T1>
210 static void demux(int index, T1 arg1)
211 {
212 if(index == (BASE + DELTA))
213 TARGET::template demux<Int<BASE + DELTA>>(arg1);
214 else
215 IntDemuxHelper<TARGET, BASE, DELTA - 1>::template demux<T1>(index, arg1);
216 }
217
218 template <typename T1, typename T2>
219 static void demux(int index, T1 arg1, T2 arg2)
220 {
221 if(index == (BASE + DELTA))
222 TARGET::template demux<Int<BASE + DELTA>>(arg1, arg2);
223 else
224 IntDemuxHelper<TARGET, BASE, DELTA - 1>::template demux<T1, T2>(index, arg1,
225 arg2);
226 }
227
228 template <typename T1, typename T2, typename T3>
229 static void demux(int index, T1 arg1, T2 arg2, T3 arg3)
230 {
231 if(index == (BASE + DELTA))
232 TARGET::template demux<Int<BASE + DELTA>>(arg1, arg2, arg3);
233 else
234 IntDemuxHelper<TARGET, BASE, DELTA - 1>::template demux<T1, T2, T3>(index, arg1,
235 arg2, arg3);
236 }
237
238 template <typename T1, typename T2, typename T3, typename T4>
239 static void demux(int index, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
240 {
241 if(index == (BASE + DELTA))
242 TARGET::template demux<Int<BASE + DELTA>>(arg1, arg2, arg3, arg4);
243 else
244 IntDemuxHelper<TARGET, BASE, DELTA - 1>::template demux<T1, T2, T3, T4>(
245 index, arg1, arg2, arg3, arg4);
246 }
247 };
248
249 template <typename TARGET, int BASE>
250 struct IntDemuxHelper<TARGET, BASE, 0> {
251 template <typename T1>
252 static void demux(int index, T1 arg1)
253 {
254 TARGET::template demux<Int<BASE>>(arg1);
255 }
256
257 template <typename T1, typename T2>
258 static void demux(int index, T1 arg1, T2 arg2)
259 {
260 TARGET::template demux<Int<BASE>>(arg1, arg2);
261 }
262
263 template <typename T1, typename T2, typename T3>
264 static void demux(int index, T1 arg1, T2 arg2, T3 arg3)
265 {
266 TARGET::template demux<Int<BASE>>(arg1, arg2, arg3);
267 }
268
269 template <typename T1, typename T2, typename T3, typename T4>
270 static void demux(int index, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
271 {
272 TARGET::template demux<Int<BASE>>(arg1, arg2, arg3, arg4);
273 }
274 };
275
276 template <int MIN, int MAX>
277 struct IntList {
278 template <int N>
279 struct TypePresent {
280 static const bool value = (MIN <= N) && (N <= MAX);
281 };
282
283 template <int N>
285
286 template <int N, bool OK>
291 template <int N>
292 struct TypeIndexHelper<N, true> {
293 static const int INDEX = N;
294 typedef Int<N> TYPE;
295 };
296
297 template <typename T>
301
302 template <int N>
306
307 template <typename TARGET, typename T1>
308 static void demux(int index, T1 arg1);
309
310 template <typename TARGET, typename T1, typename T2>
311 static void demux(int index, T1 arg1, T2 arg2);
312
313 template <typename TARGET, typename T1, typename T2, typename T3>
314 static void demux(int index, T1 arg1, T2 arg2, T3 arg3);
315
316 template <typename TARGET, typename T1, typename T2, typename T3, typename T4>
317 static void demux(int index, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
318 };
319
320 // templates with multiple arguments are supported via the following helpers
321
322 // nested demuxes require the use of several helper classes (each), in
323 // order to successively capture:
324 // a) the TARGET of the demux
325 // b) each looked up type
326 // each helper class has several overloaded versions of the demux method to
327 // support different argument lists on the TARGET
328
329 typedef unsigned TagType;
330
331 template <typename L1, typename L2>
333 template <typename T1, typename T2>
334 REALM_CUDA_HD static constexpr TagType encode_tag(void);
335
336 template <typename TARGET, typename T1>
338 template <typename T2, typename A1>
339 static void demux(A1 arg1);
340
341 template <typename T2, typename A1, typename A2>
342 static void demux(A1 arg1, A2 arg2);
343
344 template <typename T2, typename A1, typename A2, typename A3>
345 static void demux(A1 arg1, A2 arg2, A3 arg3);
346 };
347
348 template <typename TARGET>
350 template <typename T1, typename A1>
351 static void demux(TagType tag, A1 arg1);
352
353 template <typename T1, typename A1, typename A2>
354 static void demux(TagType tag, A1 arg1, A2 arg2);
355
356 template <typename T1, typename A1, typename A2, typename A3>
357 static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3);
358 };
359
360 template <typename TARGET, typename A1>
361 static void demux(TagType tag, A1 arg1);
362
363 template <typename TARGET, typename A1, typename A2>
364 static void demux(TagType tag, A1 arg1, A2 arg2);
365
366 template <typename TARGET, typename A1, typename A2, typename A3>
367 static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3);
368 };
369
370 template <typename L1, typename L2, typename L3>
372 template <typename T1, typename T2, typename T3>
373 REALM_CUDA_HD static constexpr TagType encode_tag(void);
374
375 template <typename TARGET, typename T1, typename T2>
377 template <typename T3, typename A1>
378 static void demux(A1 arg1);
379
380 template <typename T3, typename A1, typename A2>
381 static void demux(A1 arg1, A2 arg2);
382
383 template <typename T3, typename A1, typename A2, typename A3>
384 static void demux(A1 arg1, A2 arg2, A3 arg3);
385 };
386
387 template <typename TARGET, typename T1>
389 template <typename T2, typename A1>
390 static void demux(TagType tag, A1 arg1);
391
392 template <typename T2, typename A1, typename A2>
393 static void demux(TagType tag, A1 arg1, A2 arg2);
394
395 template <typename T2, typename A1, typename A2, typename A3>
396 static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3);
397 };
398
399 template <typename TARGET>
401 template <typename T1, typename A1>
402 static void demux(TagType tag, A1 arg1);
403
404 template <typename T1, typename A1, typename A2>
405 static void demux(TagType tag, A1 arg1, A2 arg2);
406
407 template <typename T1, typename A1, typename A2, typename A3>
408 static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3);
409 };
410
411 template <typename TARGET, typename A1>
412 static void demux(TagType tag, A1 arg1);
413
414 template <typename TARGET, typename A1, typename A2>
415 static void demux(TagType tag, A1 arg1, A2 arg2);
416
417 template <typename TARGET, typename A1, typename A2, typename A3>
418 static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3);
419 };
420
421 template <typename L1, typename L2, typename L3, typename L4>
423 template <typename T1, typename T2, typename T3, typename T4>
424 REALM_CUDA_HD static constexpr TagType encode_tag(void);
425
426 template <typename TARGET, typename T1, typename T2, typename T3>
428 template <typename T4, typename A1>
429 static void demux(A1 arg1);
430
431 template <typename T4, typename A1, typename A2>
432 static void demux(A1 arg1, A2 arg2);
433
434 template <typename T4, typename A1, typename A2, typename A3>
435 static void demux(A1 arg1, A2 arg2, A3 arg3);
436 };
437
438 template <typename TARGET, typename T1, typename T2>
440 template <typename T3, typename A1>
441 static void demux(TagType tag, A1 arg1);
442
443 template <typename T3, typename A1, typename A2>
444 static void demux(TagType tag, A1 arg1, A2 arg2);
445
446 template <typename T3, typename A1, typename A2, typename A3>
447 static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3);
448 };
449
450 template <typename TARGET, typename T1>
452 template <typename T2, typename A1>
453 static void demux(TagType tag, A1 arg1);
454
455 template <typename T2, typename A1, typename A2>
456 static void demux(TagType tag, A1 arg1, A2 arg2);
457
458 template <typename T2, typename A1, typename A2, typename A3>
459 static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3);
460 };
461
462 template <typename TARGET>
464 template <typename T1, typename A1>
465 static void demux(TagType tag, A1 arg1);
466
467 template <typename T1, typename A1, typename A2>
468 static void demux(TagType tag, A1 arg1, A2 arg2);
469
470 template <typename T1, typename A1, typename A2, typename A3>
471 static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3);
472 };
473
474 template <typename TARGET, typename A1>
475 static void demux(TagType tag, A1 arg1);
476
477 template <typename TARGET, typename A1, typename A2>
478 static void demux(TagType tag, A1 arg1, A2 arg2);
479
480 template <typename TARGET, typename A1, typename A2, typename A3>
481 static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3);
482 };
483
484 }; // namespace DynamicTemplates
485
486}; // namespace Realm
487
488#include "realm/dynamic_templates.inl"
489
490#endif
#define REALM_CUDA_HD
Definition compiler_support.h:95
unsigned TagType
Definition dynamic_templates.h:329
Definition activemsg.h:38
static void demux(int index, T1 arg1, T2 arg2, T3 arg3)
Definition dynamic_templates.h:264
static void demux(int index, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
Definition dynamic_templates.h:270
static void demux(int index, T1 arg1, T2 arg2)
Definition dynamic_templates.h:258
static void demux(int index, T1 arg1)
Definition dynamic_templates.h:252
Definition dynamic_templates.h:208
static void demux(int index, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
Definition dynamic_templates.h:239
static void demux(int index, T1 arg1, T2 arg2)
Definition dynamic_templates.h:219
static void demux(int index, T1 arg1)
Definition dynamic_templates.h:210
static void demux(int index, T1 arg1, T2 arg2, T3 arg3)
Definition dynamic_templates.h:229
Definition dynamic_templates.h:303
TypeIndexHelper< N, TypePresent< N >::value >::TYPE TYPE
Definition dynamic_templates.h:304
Int< N > TYPE
Definition dynamic_templates.h:294
Definition dynamic_templates.h:287
ERROR_INT_NOT_IN_LIST< N >::TYPE TYPE
Definition dynamic_templates.h:289
static const int INDEX
Definition dynamic_templates.h:288
Definition dynamic_templates.h:279
static const bool value
Definition dynamic_templates.h:280
Definition dynamic_templates.h:298
static const int INDEX
Definition dynamic_templates.h:299
Definition dynamic_templates.h:277
static void demux(int index, T1 arg1)
static void demux(int index, T1 arg1, T2 arg2, T3 arg3)
static void demux(int index, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
static void demux(int index, T1 arg1, T2 arg2)
Definition dynamic_templates.h:203
static const int N
Definition dynamic_templates.h:204
Definition dynamic_templates.h:349
static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3)
static void demux(TagType tag, A1 arg1, A2 arg2)
static void demux(TagType tag, A1 arg1)
Definition dynamic_templates.h:337
static void demux(A1 arg1, A2 arg2, A3 arg3)
Definition dynamic_templates.h:332
static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3)
static void demux(TagType tag, A1 arg1)
static void demux(TagType tag, A1 arg1, A2 arg2)
static REALM_CUDA_HD constexpr TagType encode_tag(void)
Definition dynamic_templates.h:400
static void demux(TagType tag, A1 arg1, A2 arg2)
static void demux(TagType tag, A1 arg1)
static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3)
Definition dynamic_templates.h:388
static void demux(TagType tag, A1 arg1, A2 arg2)
static void demux(TagType tag, A1 arg1)
static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3)
Definition dynamic_templates.h:376
static void demux(A1 arg1, A2 arg2, A3 arg3)
Definition dynamic_templates.h:371
static void demux(TagType tag, A1 arg1, A2 arg2)
static REALM_CUDA_HD constexpr TagType encode_tag(void)
static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3)
static void demux(TagType tag, A1 arg1)
Definition dynamic_templates.h:463
static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3)
static void demux(TagType tag, A1 arg1, A2 arg2)
static void demux(TagType tag, A1 arg1)
Definition dynamic_templates.h:451
static void demux(TagType tag, A1 arg1, A2 arg2)
static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3)
static void demux(TagType tag, A1 arg1)
Definition dynamic_templates.h:439
static void demux(TagType tag, A1 arg1)
static void demux(TagType tag, A1 arg1, A2 arg2)
static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3)
Definition dynamic_templates.h:427
static void demux(A1 arg1, A2 arg2, A3 arg3)
Definition dynamic_templates.h:422
static void demux(TagType tag, A1 arg1)
static REALM_CUDA_HD constexpr TagType encode_tag(void)
static void demux(TagType tag, A1 arg1, A2 arg2, A3 arg3)
static void demux(TagType tag, A1 arg1, A2 arg2)
Definition dynamic_templates.h:109
static void demux(int index, T1 arg1, T2 arg2)
static void demux(int index, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
static void demux(int index, T1 arg1, T2 arg2, T3 arg3)
_TAIL::template IndexToType< N-1, ORIG >::TYPE TYPE
Definition dynamic_templates.h:84
Definition dynamic_templates.h:100
std::conditional< SIZE==sizeof(_HEAD), _HEAD, typename_TAIL::templateMaxSizeType< SIZE > >::type TYPE
Definition dynamic_templates.h:104
Definition dynamic_templates.h:92
static constexpr size_t value
Definition dynamic_templates.h:94
static const bool value
Definition dynamic_templates.h:64
static const int INDEX
Definition dynamic_templates.h:74
Definition dynamic_templates.h:57
_TAIL TAIL
Definition dynamic_templates.h:59
static void demux(int index, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
static void demux(int index, T1 arg1, T2 arg2, T3 arg3)
static void demux(int index, T1 arg1)
_HEAD HEAD
Definition dynamic_templates.h:58
static void demux(int index, T1 arg1, T2 arg2)
Definition dynamic_templates.h:174
static void demux(int index, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
static void demux(int index, T1 arg1, T2 arg2, T3 arg3)
static void demux(int index, T1 arg1, T2 arg2)
Definition dynamic_templates.h:156
static const int INDEX
Definition dynamic_templates.h:157
Definition dynamic_templates.h:168
ERROR_SIZE_NOT_IN_LIST TYPE
Definition dynamic_templates.h:169
Definition dynamic_templates.h:161
static constexpr size_t value
Definition dynamic_templates.h:162
Definition dynamic_templates.h:139
static const bool value
Definition dynamic_templates.h:140
Definition dynamic_templates.h:148
static const int INDEX
Definition dynamic_templates.h:149
Definition dynamic_templates.h:136
Definition dynamic_templates.h:47
TypeListElem< T1, typename TypeList< T2, T3, T4, T5, T6 >::TL > TL
Definition dynamic_templates.h:48