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>
17  struct make_array
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__)
armarx::meta::detail
Definition: create_macro.h:14
armarx::meta::detail::make_array
Definition: create_macro.h:17
element_details.h
armarx::meta::detail::make_array::value
static constexpr auto value
Definition: create_macro.h:19
std
Definition: Application.h:66
T
float T
Definition: UnscentedKalmanFilterTest.cpp:38