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