NEMoSys  0.63.0
A modular, extensible resource with robust automated mesh generation, mesh quality analysis, adaptive mesh refinement, and data transfer between arbitrary meshes.
NemJsonMacros.H
Go to the documentation of this file.
1 /*******************************************************************************
2 * Promesh *
3 * Copyright (C) 2022, IllinoisRocstar LLC. All rights reserved. *
4 * *
5 * Promesh is the property of IllinoisRocstar LLC. *
6 * *
7 * IllinoisRocstar LLC *
8 * Champaign, IL *
9 * www.illinoisrocstar.com *
10 * promesh@illinoisrocstar.com *
11 *******************************************************************************/
12 /*******************************************************************************
13 * This file is part of Promesh *
14 * *
15 * This version of Promesh is free software: you can redistribute it and/or *
16 * modify it under the terms of the GNU Lesser General Public License as *
17 * published by the Free Software Foundation, either version 3 of the License, *
18 * or (at your option) any later version. *
19 * *
20 * Promesh is distributed in the hope that it will be useful, but WITHOUT ANY *
21 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more *
23 * details. *
24 * *
25 * You should have received a copy of the GNU Lesser General Public License *
26 * along with this program. If not, see <https://www.gnu.org/licenses/>. *
27 * *
28 *******************************************************************************/
29 #ifndef NEMOSYS_NEMJSONMACROS_H_
30 #define NEMOSYS_NEMJSONMACROS_H_
31 #include <jsoncons/json_traits_macros.hpp>
32 
33 #define NEM_JSON_UNPACK(...) __VA_ARGS__
34 
35 // Extending "Mode": NEM_JSON_RDONLY_OVERRIDE and NEM_JSON_RDWR_OVERRIDE act
36 // like JSONCONS_RDONLY and JSONCONS_RDWR in the "as" methods, but are no-ops in
37 // the "to_json" methods, as it is assumed that the parent to_json will
38 // serialize the member. Take care to use the same serialized name!
39 #define NEM_JSON_RDONLY_OVERRIDE(X)
40 #define NEM_JSON_RDWR_OVERRIDE(X) X
41 #define JSONCONS_RDONLY_TO_JSON_MODE(X) X
42 #define JSONCONS_RDWR_TO_JSON_MODE(X) X
43 #define NEM_JSON_RDONLY_OVERRIDE_TO_JSON_MODE(X)
44 #define NEM_JSON_RDWR_OVERRIDE_TO_JSON_MODE(X)
45 
46 #define NEM_JSON_MEMBER_NAME_IS(P1, P2, P3, Seq, Count) NEM_JSON_MEMBER_NAME_IS_LAST(P1, P2, P3, Seq, Count)
47 #define NEM_JSON_MEMBER_NAME_IS_LAST(P1, P2, P3, Seq, Count) if ((num_params-Count) < num_mandatory_params1 && JSONCONS_EXPAND(JSONCONS_CONCAT(NEM_JSON_MEMBER_NAME_IS_,JSONCONS_NARGS Seq) Seq)
48 #define NEM_JSON_MEMBER_NAME_IS_2(Member, Name) !ajson.contains(Name)) return false;
49 #define NEM_JSON_MEMBER_NAME_IS_3(Member, Name, Mode) !ajson.contains(Name)) return false; \
50  if (ajson.contains(Name) && !ajson.at(Name).template is<typename std::decay<decltype(((value_type*)nullptr)->Member)>::type>()) return false;
51 #define NEM_JSON_MEMBER_NAME_IS_4(Member, Name, Mode, Match) NEM_JSON_MEMBER_NAME_IS_6(Member, Name, Mode, Match, , )
52 #define NEM_JSON_MEMBER_NAME_IS_5(Member, Name, Mode, Match, Into) NEM_JSON_MEMBER_NAME_IS_6(Member, Name, Mode, Match, Into, )
53 #define NEM_JSON_MEMBER_NAME_IS_6(Member, Name, Mode, Match, Into, From) !ajson.contains(Name)) return false; \
54  JSONCONS_TRY{if (ajson.contains(Name) && !Match(ajson.at(Name).template as<typename std::decay<decltype(Into(((value_type*)nullptr)->Member))>::type>())) return false;} \
55  JSONCONS_CATCH(...) {return false;}
56 
57 #define NEM_JSON_N_MEMBER_NAME_AS(P1, P2, P3, Seq, Count) NEM_JSON_N_MEMBER_NAME_AS_LAST(P1, P2, P3, Seq, Count)
58 #define NEM_JSON_N_MEMBER_NAME_AS_LAST(P1, P2, P3, Seq, Count) JSONCONS_EXPAND(JSONCONS_CONCAT(NEM_JSON_N_MEMBER_NAME_AS_,JSONCONS_NARGS Seq) Seq)
59 #define NEM_JSON_N_MEMBER_NAME_AS_2(Member, Name) \
60  if (ajson.contains(Name)) {json_traits_helper<Json>::set_udt_member(ajson,Name,aval->Member);}
61 #define NEM_JSON_N_MEMBER_NAME_AS_3(Member, Name, Mode) Mode(NEM_JSON_N_MEMBER_NAME_AS_2(Member, Name))
62 #define NEM_JSON_N_MEMBER_NAME_AS_4(Member, Name, Mode, Match) \
63  Mode(if (ajson.contains(Name)) {json_traits_helper<Json>::set_udt_member(ajson,Name,aval->Member);})
64 #define NEM_JSON_N_MEMBER_NAME_AS_5(Member, Name, Mode, Match, Into) \
65  Mode(if (ajson.contains(Name)) {json_traits_helper<Json>::template set_udt_member<typename std::decay<decltype(Into(((value_type*)nullptr)->Member))>::type>(ajson,Name,aval->Member);})
66 #define NEM_JSON_N_MEMBER_NAME_AS_6(Member, Name, Mode, Match, Into, From) \
67  Mode(if (ajson.contains(Name)) {json_traits_helper<Json>::template set_udt_member<typename std::decay<decltype(Into(((value_type*)nullptr)->Member))>::type>(ajson,Name,From,aval->Member);})
68 
69 #define NEM_JSON_N_MEMBER_NAME_TO_JSON(P1, P2, P3, Seq, Count) NEM_JSON_N_MEMBER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count)
70 #define NEM_JSON_N_MEMBER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count) if ((num_params-Count) < num_mandatory_params2) JSONCONS_EXPAND(JSONCONS_CONCAT(NEM_JSON_N_MEMBER_NAME_TO_JSON_,JSONCONS_NARGS Seq) Seq)
71 #define NEM_JSON_N_MEMBER_NAME_TO_JSON_2(Member, Name) \
72  {ajson.try_emplace(Name, aval->Member);} \
73 else \
74  {json_traits_helper<Json>::set_optional_json_member(Name, aval->Member, ajson);}
75 #define NEM_JSON_N_MEMBER_NAME_TO_JSON_3(Member, Name, Mode) NEM_JSON_N_MEMBER_NAME_TO_JSON_2(Member, Name)
76 #define NEM_JSON_N_MEMBER_NAME_TO_JSON_4(Member, Name, Mode, Match) NEM_JSON_N_MEMBER_NAME_TO_JSON_6(Member, Name, Mode, Match,,)
77 #define NEM_JSON_N_MEMBER_NAME_TO_JSON_5(Member, Name, Mode, Match, Into) NEM_JSON_N_MEMBER_NAME_TO_JSON_6(Member, Name, Mode, Match, Into, )
78 #define NEM_JSON_N_MEMBER_NAME_TO_JSON_6(Member, Name, Mode, Match, Into, From) \
79  {Mode ## _TO_JSON_MODE(ajson.try_emplace(Name, Into(aval->Member));)} \
80 else \
81  {Mode ## _TO_JSON_MODE(json_traits_helper<Json>::set_optional_json_member(Name, Into(aval->Member), ajson);)}
82 
83 #define NEM_JSON_N_MEMBER_NAME_TRAITS_FINAL(ValueType, ParentType, NumMandatoryParams, ...) \
84  namespace jsoncons \
85 { \
86  template<typename Json> \
87  struct json_type_traits<Json, ValueType *> \
88  { \
89  using value_type = ValueType; \
90  using allocator_type = typename Json::allocator_type; \
91  using char_type = typename Json::char_type; \
92  using string_view_type = typename Json::string_view_type; \
93  constexpr static size_t num_params = JSONCONS_NARGS(__VA_ARGS__); \
94  constexpr static size_t num_mandatory_params1 = NumMandatoryParams; \
95  constexpr static size_t num_mandatory_params2 = NumMandatoryParams; \
96  static bool is(const Json& ajson) noexcept \
97  { \
98  if (!ajson.template is<ParentType *>()) return false; \
99  if (!ajson.is_object()) return false; \
100  JSONCONS_VARIADIC_REP_N(NEM_JSON_MEMBER_NAME_IS,,,, __VA_ARGS__)\
101  return true; \
102  } \
103  static value_type *as(const Json& ajson) \
104  { \
105  if (!is(ajson)) JSONCONS_THROW(convert_error(convert_errc::conversion_failed, "Not a " # ValueType)); \
106  value_type *aval = new value_type; \
107  JSONCONS_VARIADIC_REP_N(NEM_JSON_N_MEMBER_NAME_AS,,,, __VA_ARGS__) \
108  json_type_traits<Json, ParentType *>::as_from_child(ajson, aval); \
109  return aval; \
110  } \
111  static Json to_json(const value_type *const &aval, allocator_type alloc=allocator_type()) \
112  { \
113  Json ajson(json_object_arg, semantic_tag::none, alloc); \
114  JSONCONS_VARIADIC_REP_N(NEM_JSON_N_MEMBER_NAME_TO_JSON,,,, __VA_ARGS__) \
115  json_type_traits<Json, ParentType *>::to_json_from_child(aval, ajson); \
116  return ajson; \
117  } \
118  }; \
119  template <> struct is_json_type_traits_declared<ValueType *> : public std::true_type {};\
120 } \
121  /**/
122 
123 #define NEM_JSON_POLYMORPHIC_AS_RAW_PTR(BaseClass, P2, P3, DerivedClass, Count) NEM_JSON_POLYMORPHIC_AS_RAW_PTR_LAST(BaseClass, P2, P3, DerivedClass, Count)
124 #define NEM_JSON_POLYMORPHIC_AS_RAW_PTR_LAST(BaseClass, P2, P3, DerivedClass, Count) if (ajson.template is<DerivedClass *>()) return static_cast<BaseClass *>(ajson.template as<DerivedClass *>());
125 
126 #define NEM_JSON_POLYMORPHIC_TO_JSON(BaseClass, P2, P3, DerivedClass, Count) NEM_JSON_POLYMORPHIC_TO_JSON_LAST(BaseClass, P2, P3, DerivedClass, Count)
127 #define NEM_JSON_POLYMORPHIC_TO_JSON_LAST(BaseClass, P2, P3, DerivedClass, Count) { auto p = dynamic_cast<const DerivedClass *>(ptr); if (p) { return Json(const_cast<DerivedClass *>(p)); } }
128 
129 #define NEM_JSON_N_MEMBER_NAME_TRAITS_BASE(BaseClass, ChildClasses, NumMandatoryParams, ...) \
130 namespace jsoncons { \
131  template<class Json> \
132  struct json_type_traits<Json, BaseClass *> { \
133  using value_type = BaseClass; \
134  using allocator_type = typename Json::allocator_type; \
135  using char_type = typename Json::char_type; \
136  using string_view_type = typename Json::string_view_type; \
137  constexpr static size_t num_params = JSONCONS_NARGS(__VA_ARGS__); \
138  constexpr static size_t num_mandatory_params1 = NumMandatoryParams; \
139  constexpr static size_t num_mandatory_params2 = NumMandatoryParams; \
140  static bool is(const Json& ajson) noexcept { \
141  if (!ajson.is_object()) return false; \
142  JSONCONS_VARIADIC_REP_N(NEM_JSON_MEMBER_NAME_IS,,,, __VA_ARGS__)\
143  return true; \
144  } \
145 \
146  static BaseClass *as(const Json& ajson) { \
147  if (!ajson.is_object()) return nullptr; \
148  JSONCONS_VARIADIC_REP_N(NEM_JSON_POLYMORPHIC_AS_RAW_PTR, BaseClass,,, NEM_JSON_UNPACK ChildClasses) \
149  JSONCONS_THROW(convert_error(convert_errc::conversion_failed, "Not a " # BaseClass)); \
150  } \
151 \
152  static void as_from_child(const Json &ajson, value_type * const&aval) { \
153  JSONCONS_VARIADIC_REP_N(NEM_JSON_N_MEMBER_NAME_AS,,,, __VA_ARGS__) \
154  } \
155 \
156  static Json to_json(const BaseClass * const& ptr) { \
157  if (!ptr) {return Json::null();} \
158  JSONCONS_VARIADIC_REP_N(NEM_JSON_POLYMORPHIC_TO_JSON, BaseClass,,, NEM_JSON_UNPACK ChildClasses) \
159  return Json::null(); \
160  } \
161 \
162  static void to_json_from_child(const BaseClass * const& aval, Json &ajson) { \
163  JSONCONS_VARIADIC_REP_N(NEM_JSON_N_MEMBER_NAME_TO_JSON,,,, __VA_ARGS__) \
164  } \
165  }; \
166  template <> struct is_json_type_traits_declared<BaseClass *> : public std::true_type {}; \
167 } \
168  /**/
169 
170 #define NEM_JSON_N_MEMBER_NAME_TRAITS_INTERMEDIATE(BaseClass, ChildClasses, ParentClass, NumMandatoryParams, ...) \
171 namespace jsoncons { \
172  template<class Json> \
173  struct json_type_traits<Json, BaseClass *> { \
174  using value_type = BaseClass; \
175  using allocator_type = typename Json::allocator_type; \
176  using char_type = typename Json::char_type; \
177  using string_view_type = typename Json::string_view_type; \
178  constexpr static size_t num_params = JSONCONS_NARGS(__VA_ARGS__); \
179  constexpr static size_t num_mandatory_params1 = NumMandatoryParams; \
180  constexpr static size_t num_mandatory_params2 = NumMandatoryParams; \
181  static bool is(const Json& ajson) noexcept { \
182  if (!ajson.template is<ParentClass *>()) return false; \
183  if (!ajson.is_object()) return false; \
184  JSONCONS_VARIADIC_REP_N(NEM_JSON_MEMBER_NAME_IS,,,, __VA_ARGS__)\
185  return true; \
186  } \
187 \
188  static BaseClass * as(const Json& ajson) { \
189  if (!ajson.is_object()) return nullptr; \
190  JSONCONS_VARIADIC_REP_N(NEM_JSON_POLYMORPHIC_AS_RAW_PTR, BaseClass,,, NEM_JSON_UNPACK ChildClasses) \
191  JSONCONS_THROW(convert_error(convert_errc::conversion_failed, "Not a " # BaseClass)); \
192  } \
193 \
194  static void as_from_child(const Json &ajson, value_type * const &aval) { \
195  JSONCONS_VARIADIC_REP_N(NEM_JSON_N_MEMBER_NAME_AS,,,, __VA_ARGS__) \
196  json_type_traits<Json, ParentClass *>::as_from_child(ajson, aval); \
197  } \
198 \
199  static Json to_json(const BaseClass * const& ptr) { \
200  if (!ptr) {return Json::null();} \
201  JSONCONS_VARIADIC_REP_N(NEM_JSON_POLYMORPHIC_TO_JSON, BaseClass,,, NEM_JSON_UNPACK ChildClasses) \
202  return Json::null(); \
203  } \
204 \
205  static void to_json_from_child(const BaseClass * const& aval, Json &ajson) { \
206  JSONCONS_VARIADIC_REP_N(NEM_JSON_N_MEMBER_NAME_TO_JSON,,,, __VA_ARGS__) \
207  json_type_traits<Json, ParentClass *>::to_json_from_child(aval, ajson); \
208  } \
209  }; \
210  template <> struct is_json_type_traits_declared<BaseClass *> : public std::true_type {}; \
211 } \
212  /**/
213 
214 #define NEM_JSON_WRAP_SMART_PTR(BaseClass, PointerTempl) \
215 namespace jsoncons { \
216  template<class Json> \
217  struct json_type_traits<Json, PointerTempl<BaseClass>> { \
218  using allocator_type = typename Json::allocator_type; \
219 \
220  static bool is(const Json &ajson) noexcept { return ajson.template is<BaseClass *>(); }; \
221 \
222  static PointerTempl<BaseClass> as(const Json &ajson) { \
223  return PointerTempl<BaseClass>(ajson.template as<BaseClass *>()); \
224  }; \
225 \
226  static Json to_json(const PointerTempl<BaseClass> &aval) { \
227  return Json(aval.get()); \
228  } \
229  }; \
230 \
231  template<> \
232  struct is_json_type_traits_declared<PointerTempl<BaseClass>> : public std::true_type { \
233  }; \
234 } \
235  /**/
236 
237 #define NEM_JSON_SMART_PTR_VAL(BaseClass, PointerTempl) \
238 namespace jsoncons { \
239  template<class Json> \
240  struct json_type_traits<Json, PointerTempl<BaseClass>> { \
241  using allocator_type = typename Json::allocator_type; \
242 \
243  static bool is(const Json &ajson) noexcept { return ajson.template is<BaseClass>(); }; \
244 \
245  static PointerTempl<BaseClass> as(const Json &ajson) { \
246  return PointerTempl<BaseClass>(new BaseClass(ajson.template as<BaseClass>())); \
247  }; \
248 \
249  static Json to_json(const PointerTempl<BaseClass> &aval) { \
250  return aval ? Json(*aval) : Json::null(); \
251  } \
252  }; \
253 \
254  template<> \
255  struct is_json_type_traits_declared<PointerTempl<BaseClass>> : public std::true_type { \
256  }; \
257 } \
258  /**/
259 
260 #define NEM_JSON_GETTER_SETTER_NAME_IS(P1, P2, P3, Seq, Count) NEM_JSON_GETTER_SETTER_NAME_IS_LAST(P1, P2, P3, Seq, Count)
261 #define NEM_JSON_GETTER_SETTER_NAME_IS_LAST(P1, P2, P3, Seq, Count) if ((num_params-Count) < num_mandatory_params1 && JSONCONS_EXPAND(JSONCONS_CONCAT(NEM_JSON_GETTER_SETTER_NAME_IS_,JSONCONS_NARGS Seq) Seq)
262 #define NEM_JSON_GETTER_SETTER_NAME_IS_3(Getter, Setter, Name) !ajson.contains(Name)) return false;
263 #define NEM_JSON_GETTER_SETTER_NAME_IS_4(Getter, Setter, Name, Mode) !ajson.contains(Name)) return false; \
264  if (ajson.contains(Name) && !ajson.at(Name).template is<typename std::decay<decltype(((value_type*)nullptr)->Getter())>::type>()) return false;
265 #define NEM_JSON_GETTER_SETTER_NAME_IS_5(Getter, Setter, Name, Mode, Match) NEM_JSON_GETTER_SETTER_NAME_IS_7(Getter, Setter, Name, Mode, Match,, )
266 #define NEM_JSON_GETTER_SETTER_NAME_IS_6(Getter, Setter, Name, Mode, Match, Into) NEM_JSON_GETTER_SETTER_NAME_IS_7(Getter, Setter, Name, Mode, Match, Into, )
267 #define NEM_JSON_GETTER_SETTER_NAME_IS_7(Getter, Setter, Name, Mode, Match, Into, From) !ajson.contains(Name)) return false; \
268  JSONCONS_TRY{if (ajson.contains(Name) && !Match(ajson.at(Name).template as<typename std::decay<decltype(Into(((value_type*)nullptr)->Getter()))>::type>())) return false;} \
269  JSONCONS_CATCH(...) {return false;}
270 
271 #define NEM_JSON_N_GETTER_SETTER_NAME_AS(P1, P2, P3, Seq, Count) NEM_JSON_N_GETTER_SETTER_NAME_AS_LAST(P1, P2, P3, Seq, Count)
272 #define NEM_JSON_N_GETTER_SETTER_NAME_AS_LAST(P1, P2, P3, Seq, Count) JSONCONS_EXPAND(JSONCONS_CONCAT(NEM_JSON_N_GETTER_SETTER_NAME_AS_,JSONCONS_NARGS Seq) Seq)
273 #define NEM_JSON_N_GETTER_SETTER_NAME_AS_3(Getter, Setter, Name) if (ajson.contains(Name)) aval->Setter(ajson.at(Name).template as<typename std::decay<decltype(aval->Getter())>::type>());
274 #define NEM_JSON_N_GETTER_SETTER_NAME_AS_4(Getter, Setter, Name, Mode) Mode(NEM_JSON_N_GETTER_SETTER_NAME_AS_3(Getter, Setter, Name))
275 #define NEM_JSON_N_GETTER_SETTER_NAME_AS_5(Getter, Setter, Name, Mode, Match) NEM_JSON_N_GETTER_SETTER_NAME_AS_7(Getter, Setter, Name, Mode, Match, , )
276 #define NEM_JSON_N_GETTER_SETTER_NAME_AS_6(Getter, Setter, Name, Mode, Match, Into) NEM_JSON_N_GETTER_SETTER_NAME_AS_7(Getter, Setter, Name, Mode, Match, Into, )
277 #define NEM_JSON_N_GETTER_SETTER_NAME_AS_7(Getter, Setter, Name, Mode, Match, Into, From) Mode(if (ajson.contains(Name)) aval->Setter(From(ajson.at(Name).template as<typename std::decay<decltype(Into(aval->Getter()))>::type>()));)
278 
279 #define NEM_JSON_N_GETTER_SETTER_NAME_TO_JSON(P1, P2, P3, Seq, Count) NEM_JSON_N_GETTER_SETTER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count)
280 #define NEM_JSON_N_GETTER_SETTER_NAME_TO_JSON_LAST(P1, P2, P3, Seq, Count) JSONCONS_EXPAND(JSONCONS_CONCAT(NEM_JSON_N_GETTER_SETTER_NAME_TO_JSON_,JSONCONS_NARGS Seq) Seq)
281 #define NEM_JSON_N_GETTER_SETTER_NAME_TO_JSON_3(Getter, Setter, Name) ajson.try_emplace(Name, aval->Getter() );
282 #define NEM_JSON_N_GETTER_SETTER_NAME_TO_JSON_4(Getter, Setter, Name, Mode) NEM_JSON_N_GETTER_SETTER_NAME_TO_JSON_7(Getter, Setter, Name, Mode, , , )
283 #define NEM_JSON_N_GETTER_SETTER_NAME_TO_JSON_5(Getter, Setter, Name, Mode, Match) NEM_JSON_N_GETTER_SETTER_NAME_TO_JSON_7(Getter, Setter, Name, Mode, Match, , )
284 #define NEM_JSON_N_GETTER_SETTER_NAME_TO_JSON_6(Getter, Setter, Name, Mode, Match, Into) NEM_JSON_N_GETTER_SETTER_NAME_TO_JSON_7(Getter, Setter, Name, Mode, Match, Into, )
285 #define NEM_JSON_N_GETTER_SETTER_NAME_TO_JSON_7(Getter, Setter, Name, Mode, Match, Into, From) Mode ## _TO_JSON_MODE(ajson.try_emplace(Name, Into(aval->Getter()) );)
286 
287 #define NEM_JSON_N_GETTER_SETTER_NAME_TRAITS_BASE(BaseClass,ChildClasses,NumMandatoryParams, ...) \
288 namespace jsoncons \
289 { \
290  template<typename Json> \
291  struct json_type_traits<Json, BaseClass *> \
292  { \
293  using value_type = BaseClass; \
294  using allocator_type = typename Json::allocator_type; \
295  using char_type = typename Json::char_type; \
296  using string_view_type = typename Json::string_view_type; \
297  constexpr static size_t num_params = JSONCONS_NARGS(__VA_ARGS__); \
298  constexpr static size_t num_mandatory_params1 = NumMandatoryParams; \
299  constexpr static size_t num_mandatory_params2 = NumMandatoryParams; \
300  static bool is(const Json& ajson) noexcept \
301  { \
302  if (!ajson.is_object()) return false; \
303  JSONCONS_VARIADIC_REP_N(NEM_JSON_GETTER_SETTER_NAME_IS,,,, __VA_ARGS__)\
304  return true; \
305  } \
306  static value_type *as(const Json& ajson) { \
307  if (!ajson.is_object()) return nullptr; \
308  JSONCONS_VARIADIC_REP_N(NEM_JSON_POLYMORPHIC_AS_RAW_PTR, BaseClass,,, NEM_JSON_UNPACK ChildClasses) \
309  JSONCONS_THROW(convert_error(convert_errc::conversion_failed, "Not a " # BaseClass)); \
310  } \
311  static void as_from_child(const Json &ajson, value_type * const&aval) { \
312  JSONCONS_VARIADIC_REP_N(NEM_JSON_N_GETTER_SETTER_NAME_AS,,,, __VA_ARGS__) \
313  } \
314  static Json to_json(const BaseClass * const& ptr) { \
315  if (!ptr) {return Json::null();} \
316  JSONCONS_VARIADIC_REP_N(NEM_JSON_POLYMORPHIC_TO_JSON, BaseClass,,, NEM_JSON_UNPACK ChildClasses) \
317  return Json::null(); \
318  } \
319  static void to_json_from_child(const BaseClass * const& aval, Json &ajson) { \
320  JSONCONS_VARIADIC_REP_N(NEM_JSON_N_GETTER_SETTER_NAME_TO_JSON,,,, __VA_ARGS__) \
321  } \
322  }; \
323  template <> struct is_json_type_traits_declared<BaseClass *> : public std::true_type {};\
324 } \
325  /**/
326 #define NEM_JSON_N_GETTER_SETTER_NAME_TRAITS_INTERMEDIATE(BaseClass, ChildClasses, ParentClass, NumMandatoryParams, ...) \
327 namespace jsoncons { \
328  template<class Json> \
329  struct json_type_traits<Json, BaseClass *> { \
330  using value_type = BaseClass; \
331  using allocator_type = typename Json::allocator_type; \
332  using char_type = typename Json::char_type; \
333  using string_view_type = typename Json::string_view_type; \
334  constexpr static size_t num_params = JSONCONS_NARGS(__VA_ARGS__); \
335  constexpr static size_t num_mandatory_params1 = NumMandatoryParams; \
336  constexpr static size_t num_mandatory_params2 = NumMandatoryParams; \
337  static bool is(const Json& ajson) noexcept { \
338  if (!ajson.template is<ParentClass *>()) return false; \
339  if (!ajson.is_object()) return false; \
340  JSONCONS_VARIADIC_REP_N(NEM_JSON_GETTER_SETTER_NAME_IS,,,, __VA_ARGS__)\
341  return true; \
342  } \
343 \
344  static BaseClass * as(const Json& ajson) { \
345  if (!ajson.is_object()) return nullptr; \
346  JSONCONS_VARIADIC_REP_N(NEM_JSON_POLYMORPHIC_AS_RAW_PTR, BaseClass,,, NEM_JSON_UNPACK ChildClasses) \
347  JSONCONS_THROW(convert_error(convert_errc::conversion_failed, "Not a " # BaseClass)); \
348  } \
349 \
350  static void as_from_child(const Json &ajson, value_type * const &aval) { \
351  JSONCONS_VARIADIC_REP_N(NEM_JSON_N_GETTER_SETTER_NAME_AS,,,, __VA_ARGS__) \
352  json_type_traits<Json, ParentClass *>::as_from_child(ajson, aval); \
353  } \
354 \
355  static Json to_json(const BaseClass * const& ptr) { \
356  if (!ptr) {return Json::null();} \
357  JSONCONS_VARIADIC_REP_N(NEM_JSON_POLYMORPHIC_TO_JSON, BaseClass,,, NEM_JSON_UNPACK ChildClasses) \
358  return Json::null(); \
359  } \
360 \
361  static void to_json_from_child(const BaseClass * const& aval, Json &ajson) { \
362  JSONCONS_VARIADIC_REP_N(NEM_JSON_N_GETTER_SETTER_NAME_TO_JSON,,,, __VA_ARGS__) \
363  json_type_traits<Json, ParentClass *>::to_json_from_child(aval, ajson); \
364  } \
365  }; \
366  template <> struct is_json_type_traits_declared<BaseClass *> : public std::true_type {}; \
367 } \
368  /**/
369 
370 #define NEM_JSON_N_GETTER_SETTER_NAME_TRAITS_FINAL(ValueType,ParentType,NumMandatoryParams, ...) \
371 namespace jsoncons \
372 { \
373  template<typename Json> \
374  struct json_type_traits<Json, ValueType *> \
375  { \
376  using value_type = ValueType; \
377  using allocator_type = typename Json::allocator_type; \
378  using char_type = typename Json::char_type; \
379  using string_view_type = typename Json::string_view_type; \
380  constexpr static size_t num_params = JSONCONS_NARGS(__VA_ARGS__); \
381  constexpr static size_t num_mandatory_params1 = NumMandatoryParams; \
382  constexpr static size_t num_mandatory_params2 = NumMandatoryParams; \
383  static bool is(const Json& ajson) noexcept \
384  { \
385  if (!ajson.template is<ParentType *>()) return false; \
386  if (!ajson.is_object()) return false; \
387  JSONCONS_VARIADIC_REP_N(NEM_JSON_GETTER_SETTER_NAME_IS,,,, __VA_ARGS__)\
388  return true; \
389  } \
390  static value_type *as(const Json& ajson) \
391  { \
392  if (!is(ajson)) JSONCONS_THROW(convert_error(convert_errc::conversion_failed, "Not a " # ValueType)); \
393  value_type *aval = new value_type; \
394  JSONCONS_VARIADIC_REP_N(NEM_JSON_N_GETTER_SETTER_NAME_AS,,,, __VA_ARGS__) \
395  json_type_traits<Json, ParentType *>::as_from_child(ajson, aval); \
396  return aval; \
397  } \
398  static Json to_json(const value_type *const &aval, allocator_type alloc=allocator_type()) \
399  { \
400  Json ajson(json_object_arg, semantic_tag::none, alloc); \
401  JSONCONS_VARIADIC_REP_N(NEM_JSON_N_GETTER_SETTER_NAME_TO_JSON,,,, __VA_ARGS__) \
402  json_type_traits<Json, ParentType *>::to_json_from_child(aval, ajson); \
403  return ajson; \
404  } \
405  }; \
406  template <> struct is_json_type_traits_declared<ValueType *> : public std::true_type {};\
407 } \
408  /**/
409 
410 #define NEM_JSON_N_MEMBER_NAME_TO_JSON_VAL(P1, P2, P3, Seq, Count) NEM_JSON_N_MEMBER_NAME_TO_JSON_VAL_LAST(P1, P2, P3, Seq, Count)
411 #define NEM_JSON_N_MEMBER_NAME_TO_JSON_VAL_LAST(P1, P2, P3, Seq, Count) if ((num_params-Count) < num_mandatory_params2) JSONCONS_EXPAND(JSONCONS_CONCAT(NEM_JSON_N_MEMBER_NAME_TO_JSON_VAL_,JSONCONS_NARGS Seq) Seq)
412 #define NEM_JSON_N_MEMBER_NAME_TO_JSON_VAL_2(Member, Name) \
413  {ajson.try_emplace(Name, aval.Member);} \
414 else \
415  {json_traits_helper<Json>::set_optional_json_member(Name, aval.Member, ajson);}
416 #define NEM_JSON_N_MEMBER_NAME_TO_JSON_VAL_3(Member, Name, Mode) NEM_JSON_N_MEMBER_NAME_TO_JSON_VAL_2(Member, Name)
417 #define NEM_JSON_N_MEMBER_NAME_TO_JSON_VAL_4(Member, Name, Mode, Match) NEM_JSON_N_MEMBER_NAME_TO_JSON_VAL_6(Member, Name, Mode, Match,,)
418 #define NEM_JSON_N_MEMBER_NAME_TO_JSON_VAL_5(Member, Name, Mode, Match, Into) NEM_JSON_N_MEMBER_NAME_TO_JSON_VAL_6(Member, Name, Mode, Match, Into, )
419 #define NEM_JSON_N_MEMBER_NAME_TO_JSON_VAL_6(Member, Name, Mode, Match, Into, From) \
420  {Mode ## _TO_JSON_MODE(ajson.try_emplace(Name, Into(aval.Member));)} \
421 else \
422  {Mode ## _TO_JSON_MODE(json_traits_helper<Json>::set_optional_json_member(Name, Into(aval.Member), ajson);)}
423 
424 #define NEM_JSON_N_MEMBER_NAME_TRAITS_VAL(ValueType,NumMandatoryParams, ...) \
425  JSONCONS_MEMBER_NAME_TRAITS_BASE(JSONCONS_N_MEMBER_NAME_AS, NEM_JSON_N_MEMBER_NAME_TO_JSON_VAL, 0, ValueType,NumMandatoryParams,NumMandatoryParams, __VA_ARGS__) \
426  namespace jsoncons { template <> struct is_json_type_traits_declared<ValueType> : public std::true_type {}; } \
427  /**/
428 
429 #define NEM_JSON_CHECK_KEY_ONLY(x) true
430 
431 #endif // NEMOSYS_NEMJSONMACROS_H_