ATLAS Offline Software
MacroHelpers.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 //
4 // Dear emacs, this is -*- c++ -*-
5 //
6 
7 #ifndef CALORECGPU_MACROHELPERS_H
8 #define CALORECGPU_MACROHELPERS_H
9 
14 #define CRGPU_EMPTY()
15 
18 #define CRGPU_DEFER(...) __VA_ARGS__ CRGPU_EMPTY()
19 
23 #define CRGPU_IGNORE(...)
24 
27 #define CRGPU_CONCAT(X, Y) CRGPU_CONCAT_HELPER(X, Y)
28 
31 #define CRGPU_CONCAT_HELPER(X,...) X ## __VA_ARGS__
32 
33 
36 #define CRGPU_STRINGIFY(X) CRGPU_STRINGIFY_HELPER(X)
37 
40 #define CRGPU_STRINGIFY_HELPER(...) #__VA_ARGS__
41 
42 
45 #define CRGPU_GET_FIRST(X, ...) X
46 
49 #define CRGPU_GET_SECOND(X, ...) CRGPU_GET_FIRST(__VA_ARGS__, X)
50 
53 #define CRGPU_TEST_CRGPU_END ,1
54 
56 #define CRGPU_TEST_ ,1
57 
60 #define CRGPU_CHECK_FOR_END(X) CRGPU_CHECK_FOR_END_CHECK(CRGPU_TEST_ ## X, 0)
61 
64 #define CRGPU_CHECK_FOR_END_CHECK(...) CRGPU_GET_SECOND(__VA_ARGS__,)
65 
68 #define CRGPU_RECURSIVE_MACRO(...) CR_GPU_MACRO_RECURSE1(CR_GPU_MACRO_RECURSE1(CR_GPU_MACRO_RECURSE1(CR_GPU_MACRO_RECURSE1(__VA_ARGS__))))
69 
72 #define CR_GPU_MACRO_RECURSE1(...) CR_GPU_MACRO_RECURSE2(CR_GPU_MACRO_RECURSE2(CR_GPU_MACRO_RECURSE2(CR_GPU_MACRO_RECURSE2(__VA_ARGS__))))
73 
76 #define CR_GPU_MACRO_RECURSE2(...) CR_GPU_MACRO_RECURSE3(CR_GPU_MACRO_RECURSE3(CR_GPU_MACRO_RECURSE3(CR_GPU_MACRO_RECURSE3(__VA_ARGS__))))
77 
80 #define CR_GPU_MACRO_RECURSE3(...) CR_GPU_MACRO_RECURSE4(CR_GPU_MACRO_RECURSE4(CR_GPU_MACRO_RECURSE4(CR_GPU_MACRO_RECURSE4(__VA_ARGS__))))
81 
84 #define CR_GPU_MACRO_RECURSE4(...) CR_GPU_MACRO_RECURSE_BASE(CR_GPU_MACRO_RECURSE_BASE(CR_GPU_MACRO_RECURSE_BASE(CR_GPU_MACRO_RECURSE_BASE(__VA_ARGS__))))
85 
88 #define CR_GPU_MACRO_RECURSE_BASE(...) __VA_ARGS__
89 
94 #define CRGPU_MACRO_EXPANSION(MACRO, EXTRA_ARG, ... ) \
95  CRGPU_MACRO_EXPANSION_IMPL(MACRO, EXTRA_ARG, __VA_ARGS__, CRGPU_END, CRGPU_END)
96 
97 #define CRGPU_MACRO_EXPANSION_IMPL(MACRO, EXTRA_ARG, ONE, NEXT, ... ) \
98  CRGPU_DEFER(CRGPU_CONCAT(CRGPU_MACRO_INSTANTIATION_IMPL_, CRGPU_CHECK_FOR_END(ONE))) (MACRO) (ONE, EXTRA_ARG, (NEXT, __VA_ARGS__) ) \
99  CRGPU_DEFER(CRGPU_CONCAT(CRGPU_MACRO_EXPANSION_IMPL_, CRGPU_CHECK_FOR_END(NEXT))) () (MACRO, EXTRA_ARG, NEXT, __VA_ARGS__ )
100 
103 #define CRGPU_MACRO_EXPANSION_IMPL_0 CRGPU_MACRO_EXPANSION_IMPL_DO
104 
107 #define CRGPU_MACRO_EXPANSION_IMPL_DO() CRGPU_MACRO_EXPANSION_IMPL
108 
111 #define CRGPU_MACRO_EXPANSION_IMPL_1 CRGPU_MACRO_EXPANSION_IMPL_DONT
112 
115 #define CRGPU_MACRO_EXPANSION_IMPL_DONT() CRGPU_IGNORE
116 
119 #define CRGPU_MACRO_INSTANTIATION_IMPL_0 CRGPU_MACRO_INSTANTIATION_DO
120 
123 #define CRGPU_MACRO_INSTANTIATION_IMPL_1 CRGPU_MACRO_INSTANTIATION_DONT
124 
127 #define CRGPU_MACRO_INSTANTIATION_DO(...) __VA_ARGS__
128 
131 #define CRGPU_MACRO_INSTANTIATION_DONT(...) CRGPU_IGNORE
132 
135 #define CRGPU_STRING_TO_ENUM_OP(TYPE, VAR_PREFIX_PAIR, IGNORE) \
136  else if (CRGPU_GET_FIRST VAR_PREFIX_PAIR == CRGPU_STRINGIFY(TYPE)) \
137  { return CRGPU_GET_SECOND VAR_PREFIX_PAIR::TYPE; }
138 
139 
146 #define CRGPU_CHEAP_STRING_TO_ENUM(VAR, PREFIX, ONE, ...) \
147  if (false) { return PREFIX::ONE; } CRGPU_MACRO_EXPANSION(CRGPU_STRING_TO_ENUM_OP, (VAR, PREFIX), ONE, __VA_ARGS__)
148 
149 
150 //Implements this in any C++ compiler that supports variadic macros
151 //(MSVC had some problems in the past, not sure how it is now...)
152 
153 
154 //To call this, wrap in CRGPU_RECURSIVE_MACRO( ... ) to ensure correct expansion.
155 //If there are too many items and the final macros come unexpanded,
156 //thus leading to "weird" compilation errors, maybe wrap it in two or three...
157 //Any question, reach me at nuno.dos.santos.fernandes@cern.ch
158 
159 
160 #endif //CALORECGPU_MACROHELPERS_H