create_macro.h
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <experimental/array>
5
6#include <boost/hana/adapt_struct.hpp>
7#include <boost/preprocessor/seq/for_each.hpp>
8#include <boost/preprocessor/variadic/to_seq.hpp>
9
10#include <SimoxUtility/meta/eigen.h>
11
12#include "element_details.h"
13
15{
16 template <typename T, typename = void>
18 {
19 static constexpr auto value = [](auto... t)
20 { return std::experimental::make_array<T>(std::forward<decltype(t)>(t)...); };
21 };
22
23 template <typename T>
24 struct make_array<T, std::enable_if_t<simox::meta::is_eigen_matrix_v<T>>>
25 {
26 static constexpr auto value = [](auto... t)
27 { return std::experimental::make_array<float>(std::forward<decltype(t)>(t)...); };
28 };
29} // namespace armarx::meta::detail
30
31// ////////////////////////////////////////////////////////////////////////// //
32// ////////////////////////////////////////////////////////////////////////// //
33//base
34//remove the parentheses around a tuple
35#define _detail_AX_MK_CFG_rem_paren(...) __VA_ARGS__
36
37//get the first element of a tuple
38#define _detail_AX_MK_CFG_t0(e0, ...) e0
39//get the second element of a tuple
40#define _detail_AX_MK_CFG_tail(e0, ...) __VA_ARGS__
41
42#define _detail_AX_MK_CFG_applicator_i2(m, ...) m(__VA_ARGS__)
43#define _detail_AX_MK_CFG_applicator_i1(...) _detail_AX_MK_CFG_applicator_i2(__VA_ARGS__)
44
45// see _detail_AX_MK_CFG_appl_FOR_EACH
46#define _detail_AX_MK_CFG_applicator(r, tup, elem) \
47 _detail_AX_MK_CFG_applicator_i1( \
48 _detail_AX_MK_CFG_t0 tup, r, _detail_AX_MK_CFG_tail tup, _detail_AX_MK_CFG_rem_paren elem)
49
50// call macro(stype, ELEMS_i) for each tuple of ELEMS in the parameterlist
51// eg:
52// _detail_AX_MK_CFG_appl_FOR_EACH(stype, macro, (0,1), (2,3))
53// -> macro(r, stype,0,1) macro(r+1, stype,2,3)
54#define _detail_AX_MK_CFG_appl_FOR_EACH(stype, elemmacro, ...) \
55 BOOST_PP_SEQ_FOR_EACH( \
56 _detail_AX_MK_CFG_applicator, (elemmacro, stype), BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
57
58// ////////////////////////////////////////////////////////////////////////// //
59// ////////////////////////////////////////////////////////////////////////// //
60//define struct
61#define _detail_AX_MK_CFG_member_def(R, sname, type, vname, ...) type vname;
62#define _detail_AX_MK_CFG_struct_def(Namespace, Name, ...) \
63 namespace Namespace \
64 { \
65 struct Name \
66 { \
67 BOOST_PP_EXPAND(_detail_AX_MK_CFG_appl_FOR_EACH(Namespace::Name, \
68 _detail_AX_MK_CFG_member_def, \
69 __VA_ARGS__)) \
70 Name(); \
71 Name(Name&&) = default; \
72 Name(const Name&) = default; \
73 Name& operator=(Name&&) = default; \
74 Name& operator=(const Name&) = default; \
75 }; \
76 } \
77 static_assert(true, "force the usage of a trailing semicolon")
78
79#define _detail_AX_MK_CFG_ctor_def(Namespace, Name, ...) \
80 namespace Namespace \
81 { \
82 inline Name::Name() \
83 { \
84 armarx::meta::cfg::struct_default<Name>::set(*this); \
85 } \
86 } \
87 static_assert(true, "force the usage of a trailing semicolon")
88// ////////////////////////////////////////////////////////////////////////// //
89// ////////////////////////////////////////////////////////////////////////// //
90//configure elements
91#define ARMARX_CONFIG_STRUCT_CONFIGURE(Namespace, Name, ...) \
92 namespace armarx::meta::cfg \
93 { \
94 BOOST_PP_EXPAND(_detail_AX_MK_CFG_appl_FOR_EACH(Namespace::Name, \
95 _detail_AX_MK_CFG_cfg_elem, \
96 __VA_ARGS__)) \
97 } \
98 static_assert(true, "force the usage of a trailing semicolon")
99// ////////////////////////////////////////////////////////////////////////// //
100//configure element
101#define _detail_AX_MK_CFG_cfg_elem_app_i4(sname, type, vname, m, ...) \
102 m(sname, type, vname, __VA_ARGS__)
103
104#define _detail_AX_MK_CFG_cfg_elem_app_i3(...) _detail_AX_MK_CFG_cfg_elem_app_i4(__VA_ARGS__)
105
106#define _detail_AX_MK_CFG_cfg_elem_app_i2(sname, type, vname, ...) \
107 _detail_AX_MK_CFG_cfg_elem_app_i3( \
108 sname, type, vname, _detail_AX_MK_CFG_cfg_elem_app_##__VA_ARGS__)
109
110#define _detail_AX_MK_CFG_cfg_elem_app_i1(...) _detail_AX_MK_CFG_cfg_elem_app_i2(__VA_ARGS__)
111
112// see _detail_AX_MK_CFG_appl_FOR_EACH
113#define _detail_AX_MK_CFG_cfg_elem_app(r, tup, elem) \
114 _detail_AX_MK_CFG_cfg_elem_app_i1(_detail_AX_MK_CFG_rem_paren tup, elem)
115
116// 2 lvl BOOST_PP_SEQ_FOR_EACH recursion
117//see https://stackoverflow.com/a/35755736
118//see http://boost.2283326.n4.nabble.com/preprocessor-nested-for-each-not-working-like-expected-td4650470.html
119#define _detail_AX_MK_CFG_DEFER(x) x BOOST_PP_EMPTY()
120#define _detail_AX_MK_CFG_SEQ_FOR_EACH_R_ID() BOOST_PP_SEQ_FOR_EACH_R
121
122#define _detail_AX_MK_CFG_cfg_elem(R, sname, type, vname, ...) \
123 _detail_AX_MK_CFG_DEFER(_detail_AX_MK_CFG_SEQ_FOR_EACH_R_ID)()( \
124 R, \
125 _detail_AX_MK_CFG_cfg_elem_app, \
126 (sname, type, vname), \
127 BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
128// ////////////////////////////////////////////////////////////////////////// //
129//default
130#define _detail_AX_MK_CFG_cfg_elem_app_AX_DEFAULT(...) \
131 _detail_AX_MK_CFG_cfg_elem_app_AX_DEFAULT_i, __VA_ARGS__
132
133#define _detail_AX_MK_CFG_cfg_elem_app_AX_DEFAULT_i(sname, type, vname, ...) \
134 template <> \
135 struct element_default<sname, type, &sname::vname> : \
136 std::true_type /* IN CASE OF AN ERROR: You might have two AX_DEFAULT */ \
137 { \
138 static type \
139 get() \
140 { \
141 return type(__VA_ARGS__); \
142 } \
143 static void \
144 set(sname& s) \
145 { \
146 s.vname = get(); \
147 } \
148 };
149// ////////////////////////////////////////////////////////////////////////// //
150//min/max....
151#define _detail_AX_MK_CFG_cfg_elem_app_(...)
152
153
154#define _detail_AX_MK_CFG_cfg_elem_app_AX_MIN(...) \
155 _detail_AX_MK_CFG_cfg_elem_app_AX_MIN_i, __VA_ARGS__
156
157#define _detail_AX_MK_CFG_cfg_elem_app_AX_MIN_i(sname, type, vname, ...) \
158 template <> \
159 constexpr auto element_min<sname, type, &sname::vname> = \
160 armarx::meta::detail::make_array<type>::value(__VA_ARGS__);
161
162
163#define _detail_AX_MK_CFG_cfg_elem_app_AX_MAX(...) \
164 _detail_AX_MK_CFG_cfg_elem_app_AX_MAX_i, __VA_ARGS__
165
166#define _detail_AX_MK_CFG_cfg_elem_app_AX_MAX_i(sname, type, vname, ...) \
167 template <> \
168 constexpr auto element_max<sname, type, &sname::vname> = \
169 armarx::meta::detail::make_array<type>::value(__VA_ARGS__);
170
171
172#define _detail_AX_MK_CFG_cfg_elem_app_AX_DESCRIPTION(...) \
173 _detail_AX_MK_CFG_cfg_elem_app_AX_DESCRIPTION_i, __VA_ARGS__
174
175#define _detail_AX_MK_CFG_cfg_elem_app_AX_DESCRIPTION_i(sname, type, vname, ...) \
176 template <> \
177 constexpr const char* element_description<sname, type, &sname::vname> = __VA_ARGS__;
178
179
180#define _detail_AX_MK_CFG_cfg_elem_app_AX_PROPERTY_NAME(...) \
181 _detail_AX_MK_CFG_cfg_elem_app_AX_PROP_NAME_i, __VA_ARGS__
182
183#define _detail_AX_MK_CFG_cfg_elem_app_AX_PROP_NAME_i(sname, type, vname, ...) \
184 template <> \
185 constexpr const char* element_property_name<sname, type, &sname::vname> = __VA_ARGS__;
186
187
188#define _detail_AX_MK_CFG_cfg_elem_app_AX_DECIMALS(...) \
189 _detail_AX_MK_CFG_cfg_elem_app_AX_DECIMALS_i, __VA_ARGS__
190
191#define _detail_AX_MK_CFG_cfg_elem_app_AX_DECIMALS_i(sname, type, vname, ...) \
192 template <> \
193 constexpr auto element_decimals<sname, type, &sname::vname> = \
194 std::experimental::make_array<int>(__VA_ARGS__);
195
196
197#define _detail_AX_MK_CFG_cfg_elem_app_AX_STEPS(...) \
198 _detail_AX_MK_CFG_cfg_elem_app_AX_STEPS_i, __VA_ARGS__
199
200#define _detail_AX_MK_CFG_cfg_elem_app_AX_STEPS_i(sname, type, vname, ...) \
201 template <> \
202 constexpr auto element_steps<sname, type, &sname::vname> = \
203 std::experimental::make_array<int>(__VA_ARGS__);
204
205
206#define _detail_AX_MK_CFG_cfg_elem_app_AX_LABEL(...) \
207 _detail_AX_MK_CFG_cfg_elem_app_AX_LABEL_i, __VA_ARGS__
208
209#define _detail_AX_MK_CFG_cfg_elem_app_AX_LABEL_i(sname, type, vname, ...) \
210 template <> \
211 constexpr const char* element_label<sname, type, &sname::vname> = {__VA_ARGS__};
212
213
214#define _detail_AX_MK_CFG_cfg_elem_app_AX_NO_PROPERTY(...) \
215 _detail_AX_MK_CFG_cfg_elem_app_AX_NO_PROPERTY_i, __VA_ARGS__
216
217#define _detail_AX_MK_CFG_cfg_elem_app_AX_NO_PROPERTY_i(sname, type, vname, ...) \
218 template <> \
219 constexpr std::true_type element_no_prop<sname, type, &sname::vname> = {};
220
221#define _detail_AX_MK_CFG_cfg_elem_app_AX_NO_REMOTE_GUI(...) \
222 _detail_AX_MK_CFG_cfg_elem_app_AX_NO_REMOTE_GUI_i, __VA_ARGS__
223
224#define _detail_AX_MK_CFG_cfg_elem_app_AX_NO_REMOTE_GUI_i(sname, type, vname, ...) \
225 template <> \
226 constexpr std::true_type element_no_rem_gui<sname, type, &sname::vname> = {};
227
228#define _detail_AX_MK_CFG_cfg_elem_app_AX_EXCLUDE_FROM_ALL(...) \
229 _detail_AX_MK_CFG_cfg_elem_app_AX_EXCLUDE_FROM_ALL_i, __VA_ARGS__
230
231#define _detail_AX_MK_CFG_cfg_elem_app_AX_EXCLUDE_FROM_ALL_i(sname, type, vname, ...) \
232 template <> \
233 constexpr std::true_type element_no_prop<sname, type, &sname::vname> = {}; \
234 template <> \
235 constexpr std::true_type element_no_rem_gui<sname, type, &sname::vname> = {}; \
236 // ////////////////////////////////////////////////////////////////////////// //
237// ////////////////////////////////////////////////////////////////////////// //
238//hana adapt
239#define _detail_AX_MK_CFG_member_names(R, sname, type, name, ...) , name
240#define ARMARX_CONFIG_STRUCT_ADAPT(Namespace, Name, ...) \
241 BOOST_HANA_ADAPT_STRUCT(Namespace::Name /* , will con from next macro*/ \
242 _detail_AX_MK_CFG_appl_FOR_EACH( \
243 Namespace::Name, _detail_AX_MK_CFG_member_names, __VA_ARGS__))
244// ////////////////////////////////////////////////////////////////////////// //
245// ////////////////////////////////////////////////////////////////////////// //
246/**
247 * Usage
248 * ARMARX_CONFIG_STRUCT_DEFINE_ADAPT(
249 * foospace, foo,
250 * (float, flooat, AX_DEFAULT(1234), AX_MIN(-42), AX_MAX(1337))
251 * )
252 */
253#define ARMARX_CONFIG_STRUCT_DEFINE_ADAPT(Namespace, Name, ...) \
254 _detail_AX_MK_CFG_struct_def(Namespace, Name, __VA_ARGS__); \
255 ARMARX_CONFIG_STRUCT_ADAPT(Namespace, Name, __VA_ARGS__); \
256 _detail_AX_MK_CFG_ctor_def(Namespace, Name, __VA_ARGS__)
257
258/**
259 * Usage
260 * ARMARX_CONFIG_STRUCT_DEFINE_ADAPT_CONFIGURE(
261 * foospace, foo,
262 * (float, flooat, AX_DEFAULT(1234), AX_MIN(-42), AX_MAX(1337))
263 * )
264 */
265#define ARMARX_CONFIG_STRUCT_DEFINE_ADAPT_CONFIGURE(Namespace, Name, ...) \
266 ARMARX_CONFIG_STRUCT_DEFINE_ADAPT(Namespace, Name, __VA_ARGS__); \
267 ARMARX_CONFIG_STRUCT_CONFIGURE(Namespace, Name, __VA_ARGS__)
268
269/**
270 * Usage
271 * ARMARX_CONFIG_STRUCT_CONFIGURE_ADAPT(
272 * foospace, foo,
273 * (float, flooat, AX_DEFAULT(1234), AX_MIN(-42), AX_MAX(1337))
274 * )
275 */
276#define ARMARX_CONFIG_STRUCT_CONFIGURE_ADAPT(Namespace, Name, ...) \
277 ARMARX_CONFIG_STRUCT_ADAPT(Namespace, Name, __VA_ARGS__); \
278 ARMARX_CONFIG_STRUCT_CONFIGURE(Namespace, Name, __VA_ARGS__)
279
280#define ARMARX_CONFIG_STRUCT_ADAPT_CONFIGURE(Namespace, Name, ...) \
281 ARMARX_CONFIG_STRUCT_CONFIGURE_ADAPT(Namespace, Name, __VA_ARGS__)
static constexpr auto value