Reflection for RapidJSON  0.0.15
Reflection for serializing/deserializing with RapidJSON
reflector.h
Go to the documentation of this file.
1 #ifndef REFLECTIVE_RAPIDJSON_JSON_REFLECTOR_H
2 #define REFLECTIVE_RAPIDJSON_JSON_REFLECTOR_H
3 
10 #include "../traits.h"
11 
12 #include <c++utilities/application/global.h>
13 
14 #include <rapidjson/document.h>
15 #include <rapidjson/rapidjson.h>
16 #include <rapidjson/stringbuffer.h>
17 #include <rapidjson/writer.h>
18 
19 #include <limits>
20 #include <map>
21 #include <memory>
22 #include <set>
23 #include <string>
24 #include <tuple>
25 #include <unordered_map>
26 #include <unordered_set>
27 #include <variant>
28 
29 #include "./errorhandling.h"
30 
31 namespace ReflectiveRapidJSON {
32 
33 template <typename Type> struct JsonSerializable;
34 
38 template <typename T> struct AdaptedJsonSerializable : public Traits::Bool<false> {
39  static constexpr const char *name = "AdaptedJsonSerializable";
40  static constexpr const char *qualifiedName = "ReflectiveRapidJSON::AdaptedJsonSerializable";
41 };
42 
46 namespace JsonReflector {
47 
51 constexpr RAPIDJSON_NAMESPACE::SizeType rapidJsonSize(std::size_t size)
52 {
53  return size > std::numeric_limits<RAPIDJSON_NAMESPACE::SizeType>::max() ? std::numeric_limits<RAPIDJSON_NAMESPACE::SizeType>::max()
54  : static_cast<RAPIDJSON_NAMESPACE::SizeType>(size);
55 }
56 
60 inline RAPIDJSON_NAMESPACE::StringBuffer serializeJsonDocToString(RAPIDJSON_NAMESPACE::Document &document)
61 {
62  RAPIDJSON_NAMESPACE::StringBuffer buffer;
63  RAPIDJSON_NAMESPACE::Writer<RAPIDJSON_NAMESPACE::StringBuffer> writer(buffer);
64  document.Accept(writer);
65  return buffer;
66 }
67 
71 inline RAPIDJSON_NAMESPACE::Document parseJsonDocFromString(const char *json, std::size_t jsonSize)
72 {
73  RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kObjectType);
74  const RAPIDJSON_NAMESPACE::ParseResult parseRes = document.Parse(json, jsonSize);
75  if (parseRes.IsError()) {
76  throw parseRes;
77  }
78  return document;
79 }
80 
81 // define traits to distinguish between "built-in" types like int, std::string, std::vector, ... and custom structs/classes
82 template <typename Type>
83 using IsBuiltInType = Traits::Any<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>, std::is_enum<Type>,
84  Traits::IsSpecializationOf<Type, std::tuple>, Traits::IsSpecializationOf<Type, std::pair>, Traits::IsIteratable<Type>,
85  Traits::IsSpecializationOf<Type, std::unique_ptr>, Traits::IsSpecializationOf<Type, std::shared_ptr>,
86  Traits::IsSpecializationOf<Type, std::weak_ptr>, IsVariant<Type>>;
87 template <typename Type> using IsCustomType = Traits::Not<IsBuiltInType<Type>>;
88 
89 // define trait to check for custom structs/classes which are JSON serializable
90 // NOTE: the check for Traits::IsComplete is required because std::is_base_of fails for incomplete types when using GCC
91 template <typename Type>
93  = Traits::Any<Traits::Not<Traits::IsComplete<Type>>, std::is_base_of<JsonSerializable<Type>, Type>, AdaptedJsonSerializable<Type>>;
94 
95 // define functions to "push" values to a RapidJSON array or object
96 
100 template <typename Type, Traits::DisableIf<IsBuiltInType<Type>> * = nullptr>
101 void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
102 
106 template <typename Type, Traits::DisableIf<IsJsonSerializable<Type>> * = nullptr>
107 void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
108 
112 template <typename Type, Traits::EnableIf<IsJsonSerializable<Type>> * = nullptr>
113 void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
114 
118 template <typename Type, Traits::EnableIf<IsJsonSerializable<Type>> * = nullptr>
119 void push(
120  const Type &reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
121 
125 template <typename Type, Traits::DisableIf<IsJsonSerializable<Type>> * = nullptr>
126 void push(
127  const Type &reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
128 
133 template <typename Type, Traits::DisableIf<IsBuiltInType<Type>> * = nullptr>
134 void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
135 
139 template <typename Type, Traits::DisableIf<IsBuiltInType<Type>> *>
140 inline void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
141 {
142  value.SetObject();
143  RAPIDJSON_NAMESPACE::Value::Object obj(value.GetObject());
144  push(reflectable, obj, allocator);
145 }
146 
150 template <typename Type, Traits::EnableIfAny<std::is_integral<Type>, std::is_floating_point<Type>> * = nullptr>
151 inline void push(Type reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
152 {
153  value.Set(reflectable, allocator);
154 }
155 
159 template <typename Type, Traits::EnableIfAny<std::is_enum<Type>> * = nullptr>
160 inline void push(Type reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
161 {
162  value.Set(static_cast<Traits::Conditional<std::is_unsigned<typename std::underlying_type<Type>::type>, std::uint64_t, std::int64_t>>(reflectable),
163  allocator);
164 }
165 
169 template <typename Type, Traits::EnableIfAny<std::is_same<Type, const char *>, std::is_same<Type, const char *const &>> * = nullptr>
170 inline void push(Type reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
171 {
172  if (reflectable) {
173  value.SetString(reflectable, allocator);
174  } else {
175  value.SetNull();
176  }
177 }
178 
182 template <typename Type, Traits::EnableIf<std::is_same<Type, std::string_view>> * = nullptr>
183 inline void push(Type reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
184 {
185  if (reflectable.data()) {
186  value.SetString(reflectable.data(), rapidJsonSize(reflectable.size()), allocator);
187  } else {
188  value.SetNull();
189  }
190 }
191 
195 template <typename Type, Traits::EnableIf<std::is_same<Type, std::string>> * = nullptr>
196 inline void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
197 {
198  value.SetString(reflectable.data(), rapidJsonSize(reflectable.size()), allocator);
199 }
200 
204 template <typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::HasSize<Type>> * = nullptr>
205 void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
206 {
207  value.SetArray();
208  RAPIDJSON_NAMESPACE::Value::Array array(value.GetArray());
209  array.Reserve(reflectable.size(), allocator);
210  for (const auto &item : reflectable) {
211  push(item, array, allocator);
212  }
213 }
214 
218 template <typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::Not<Traits::HasSize<Type>>> * = nullptr>
219 void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
220 {
221  value.SetArray();
222  RAPIDJSON_NAMESPACE::Value::Array array(value.GetArray());
223  for (const auto &item : reflectable) {
224  push(item, array, allocator);
225  }
226 }
227 
231 template <typename Type, Traits::EnableIfAny<IsMapOrHash<Type>> * = nullptr>
232 void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
233 {
234  value.SetObject();
235  RAPIDJSON_NAMESPACE::Value::Object object(value.GetObject());
236  for (const auto &item : reflectable) {
237  push(item.second, item.first.data(), object, allocator);
238  }
239 }
240 
244 template <typename Type, Traits::EnableIfAny<IsMultiMapOrHash<Type>> * = nullptr>
245 void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
246 {
247  value.SetObject();
248  for (const auto &item : reflectable) {
249  const auto memberName = RAPIDJSON_NAMESPACE::Value::StringRefType(item.first.data(), rapidJsonSize(item.first.size()));
250  const auto existingMember = value.FindMember(memberName);
251  const auto arrayAlreadyExists
252  = existingMember != value.MemberEnd() && existingMember->value.GetType() == RAPIDJSON_NAMESPACE::Type::kArrayType;
253  auto newArrayValue = RAPIDJSON_NAMESPACE::Value{ RAPIDJSON_NAMESPACE::kArrayType };
254  RAPIDJSON_NAMESPACE::Value::Array array = arrayAlreadyExists ? existingMember->value.GetArray() : newArrayValue.GetArray();
255  push(item.second, array, allocator);
256  if (!arrayAlreadyExists) {
257  value.AddMember(memberName, newArrayValue, allocator);
258  }
259  }
260 }
261 
262 namespace Detail {
263 
267 template <class Tuple, std::size_t N> struct TuplePushHelper {
268  static void push(const Tuple &tuple, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
269  {
270  TuplePushHelper<Tuple, N - 1>::push(tuple, value, allocator);
271  JsonReflector::push(std::get<N - 1>(tuple), value, allocator);
272  }
273 };
274 
275 template <class Tuple> struct TuplePushHelper<Tuple, 1> {
276  static void push(const Tuple &tuple, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
277  {
278  JsonReflector::push(std::get<0>(tuple), value, allocator);
279  }
280 };
281 } // namespace Detail
282 
286 template <typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::tuple>> * = nullptr>
287 void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
288 {
289  value.SetArray();
290  RAPIDJSON_NAMESPACE::Value::Array array(value.GetArray());
291  array.Reserve(std::tuple_size<Type>::value, allocator);
292  Detail::TuplePushHelper<Type, std::tuple_size<Type>::value>::push(reflectable, array, allocator);
293 }
294 
298 template <typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::pair>> * = nullptr>
299 void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
300 {
301  value.SetArray();
302  RAPIDJSON_NAMESPACE::Value::Array array(value.GetArray());
303  array.Reserve(2, allocator);
304  push(reflectable.first, array, allocator);
305  push(reflectable.second, array, allocator);
306 }
307 
311 template <typename Type,
312  Traits::EnableIfAny<Traits::IsSpecializationOf<Type, std::unique_ptr>, Traits::IsSpecializationOf<Type, std::shared_ptr>,
313  Traits::IsSpecializationOf<Type, std::weak_ptr>> * = nullptr>
314 void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
315 {
316  if (!reflectable) {
317  value.SetNull();
318  return;
319  }
320  push(*reflectable, value, allocator);
321 }
322 
326 template <typename Type, Traits::EnableIf<IsVariant<Type>> * = nullptr>
327 void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
328 {
329  if (reflectable.valueless_by_exception()) {
330  value.SetNull();
331  return;
332  }
333 
334  RAPIDJSON_NAMESPACE::Value index, data;
335  index.SetInt(reflectable.index());
336  std::visit(
337  [&data, &allocator](const auto &reflectableOfActualType) {
338  if constexpr (!std::is_same_v<std::decay_t<decltype(reflectableOfActualType)>, std::monostate>) {
339  push(reflectableOfActualType, data, allocator);
340  } else {
341  CPP_UTILITIES_UNUSED(data)
342  CPP_UTILITIES_UNUSED(allocator)
343  }
344  },
345  reflectable);
346 
347  value.SetObject();
348  value.AddMember("index", index, allocator);
349  value.AddMember("data", data, allocator);
350 }
351 
355 template <typename Type, Traits::EnableIf<IsJsonSerializable<Type>> *>
356 void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
357 {
358  RAPIDJSON_NAMESPACE::Value objectValue(RAPIDJSON_NAMESPACE::kObjectType);
359  RAPIDJSON_NAMESPACE::Value::Object object(objectValue.GetObject());
360  push(reflectable, object, allocator);
361  value.PushBack(objectValue, allocator);
362 }
363 
367 template <typename Type, Traits::DisableIf<IsJsonSerializable<Type>> *>
368 void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
369 {
370  RAPIDJSON_NAMESPACE::Value genericValue;
371  push(reflectable, genericValue, allocator);
372  value.PushBack(genericValue, allocator);
373 }
374 
378 template <typename Type, Traits::EnableIf<IsJsonSerializable<Type>> *>
379 void push(
380  const Type &reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
381 {
382  RAPIDJSON_NAMESPACE::Value objectValue(RAPIDJSON_NAMESPACE::kObjectType);
383  RAPIDJSON_NAMESPACE::Value::Object object(objectValue.GetObject());
384  push(reflectable, object, allocator);
385  value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), objectValue, allocator);
386 }
387 
391 template <typename Type, Traits::DisableIf<IsJsonSerializable<Type>> *>
392 void push(
393  const Type &reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
394 {
395  RAPIDJSON_NAMESPACE::Value genericValue;
396  push(reflectable, genericValue, allocator);
397  value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), genericValue, allocator);
398 }
399 
400 // define functions to "pull" values from a RapidJSON array or object
401 
406 template <typename Type, Traits::DisableIf<IsBuiltInType<Type>> * = nullptr>
407 void pull(Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value,
408  JsonDeserializationErrors *errors);
409 
413 template <typename Type, Traits::DisableIf<IsBuiltInType<Type>> * = nullptr>
414 void pull(Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
415 
419 template <typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::Not<Traits::IsReservable<Type>>> * = nullptr>
420 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
421 
425 template <typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::IsReservable<Type>> * = nullptr>
426 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
427 
431 template <typename Type, Traits::EnableIf<IsArray<Type>> * = nullptr>
432 void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors);
433 
437 template <typename Type, Traits::EnableIf<IsSet<Type>> * = nullptr>
438 void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors);
439 
443 template <typename Type, Traits::EnableIf<IsMultiSet<Type>> * = nullptr>
444 void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors);
445 
449 template <typename Type, Traits::EnableIf<IsMapOrHash<Type>> * = nullptr>
450 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
451 
455 template <typename Type, Traits::EnableIf<IsMultiMapOrHash<Type>> * = nullptr>
456 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
457 
461 template <typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::tuple>> * = nullptr>
462 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
463 
467 template <typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::pair>> * = nullptr>
468 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
469 
473 template <typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::unique_ptr>> * = nullptr>
474 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
475 
479 template <typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::shared_ptr>> * = nullptr>
480 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
481 
485 template <typename Type, Traits::EnableIf<IsVariant<Type>> * = nullptr>
486 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
487 
491 template <typename Type>
492 inline void pull(
493  Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ValueIterator &value, JsonDeserializationErrors *errors);
494 
500 template <typename Type>
501 inline void pull(Type &reflectable, const char *name, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value,
502  JsonDeserializationErrors *errors);
503 
507 template <typename Type, Traits::DisableIf<IsBuiltInType<Type>> *>
508 void pull(Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
509 
513 template <typename Type,
514  Traits::EnableIf<Traits::Not<std::is_same<Type, bool>>, Traits::Any<std::is_integral<Type>, std::is_floating_point<Type>>> * = nullptr>
515 inline void pull(
516  Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
517 {
518  if (!value.IsNumber()) {
519  if (errors) {
520  errors->reportTypeMismatch<Type>(value.GetType());
521  }
522  return;
523  }
524  reflectable = value.Is<Type>() ? value.Get<Type>() : static_cast<Type>(value.GetDouble());
525 }
526 
530 template <typename Type, Traits::EnableIf<std::is_same<Type, bool>> * = nullptr>
531 inline void pull(
532  Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
533 {
534  if (!value.IsBool()) {
535  if (errors) {
536  errors->reportTypeMismatch<Type>(value.GetType());
537  }
538  return;
539  }
540  reflectable = value.GetBool();
541 }
542 
547 template <typename Type, Traits::EnableIfAny<std::is_enum<Type>> * = nullptr>
548 inline void pull(
549  Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
550 {
551  using ExpectedType = Traits::Conditional<std::is_unsigned<typename std::underlying_type<Type>::type>, std::uint64_t, std::int64_t>;
552  if (!value.Is<ExpectedType>()) {
553  if (errors) {
554  errors->reportTypeMismatch<ExpectedType>(value.GetType());
555  }
556  return;
557  }
558  reflectable = static_cast<Type>(value.Get<ExpectedType>());
559 }
560 
564 template <typename Type, Traits::EnableIf<std::is_same<Type, std::string>> * = nullptr>
565 inline void pull(
566  Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
567 {
568  if (!value.IsString()) {
569  if (errors) {
570  errors->reportTypeMismatch<std::string>(value.GetType());
571  }
572  return;
573  }
574  reflectable = value.GetString();
575 }
576 
581 template <typename Type,
582  Traits::EnableIfAny<std::is_same<Type, const char *>, std::is_same<Type, const char *const &>, std::is_same<Type, std::string_view>> * = nullptr>
583 inline void pull(Type &, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
584 {
585  if (!value.IsString()) {
586  if (errors) {
587  errors->reportTypeMismatch<std::string>(value.GetType());
588  }
589  return;
590  }
591 }
592 
596 template <typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::Not<Traits::IsReservable<Type>>> *>
597 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
598 {
599  if (!value.IsArray()) {
600  if (errors) {
601  errors->reportTypeMismatch<Type>(value.GetType());
602  }
603  return;
604  }
605  pull(reflectable, value.GetArray(), errors);
606 }
607 
611 template <typename Type, Traits::EnableIf<IsArrayOrSet<Type>, Traits::IsReservable<Type>> *>
612 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
613 {
614  if (!value.IsArray()) {
615  if (errors) {
616  errors->reportTypeMismatch<Type>(value.GetType());
617  }
618  return;
619  }
620  auto array = value.GetArray();
621  reflectable.reserve(array.Size());
622  pull(reflectable, array, errors);
623 }
624 
628 template <typename Type, Traits::EnableIf<IsArray<Type>> *>
629 void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors)
630 {
631  // clear previous contents of the array
632  reflectable.clear();
633 
634  // pull all array elements of the specified value
635  std::size_t index = 0;
636  for (const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &item : array) {
637  // set error context for current index
638  if (errors) {
639  errors->currentIndex = index;
640  }
641  ++index;
642  reflectable.emplace_back();
643  pull(reflectable.back(), item, errors);
644  }
645 
646  // clear error context
647  if (errors) {
649  }
650 }
651 
655 template <typename Type, Traits::EnableIf<IsMultiSet<Type>> *>
656 void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors)
657 {
658  // clear previous contents of the array
659  reflectable.clear();
660 
661  // pull all array elements of the specified value
662  std::size_t index = 0;
663  for (const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &item : array) {
664  // set error context for current index
665  if (errors) {
666  errors->currentIndex = index;
667  }
668  ++index;
669  typename Type::value_type itemObj;
670  pull(itemObj, item, errors);
671  reflectable.emplace(move(itemObj));
672  }
673 
674  // clear error context
675  if (errors) {
677  }
678 }
679 
683 template <typename Type, Traits::EnableIf<IsSet<Type>> *>
684 void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstArray array, JsonDeserializationErrors *errors)
685 {
686  // clear previous contents of the array
687  reflectable.clear();
688 
689  // pull all array elements of the specified value
690  std::size_t index = 0;
691  for (const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &item : array) {
692  // set error context for current index
693  if (errors) {
694  errors->currentIndex = index;
695  }
696  ++index;
697  typename Type::value_type itemObj;
698  pull(itemObj, item, errors);
699  if (!reflectable.emplace(move(itemObj)).second) {
700  errors->reportUnexpectedDuplicate(JsonType::Array);
701  }
702  }
703 
704  // clear error context
705  if (errors) {
706  errors->currentIndex = JsonDeserializationError::noIndex;
707  }
708 }
709 
713 template <typename Type, Traits::EnableIf<IsMapOrHash<Type>> *>
714 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
715 {
716  if (!value.IsObject()) {
717  if (errors) {
718  errors->reportTypeMismatch<Type>(value.GetType());
719  }
720  return;
721  }
722  auto obj = value.GetObject();
723  for (auto i = obj.MemberBegin(), end = obj.MemberEnd(); i != end; ++i) {
724  pull(reflectable[i->name.GetString()], i->value, errors);
725  }
726 }
727 
731 template <typename Type, Traits::EnableIf<IsMultiMapOrHash<Type>> *>
732 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
733 {
734  if (!value.IsObject()) {
735  if (errors) {
736  errors->reportTypeMismatch<Type>(value.GetType());
737  }
738  return;
739  }
740  auto obj = value.GetObject();
741  for (auto i = obj.MemberBegin(), end = obj.MemberEnd(); i != end; ++i) {
742  if (i->value.GetType() != RAPIDJSON_NAMESPACE::kArrayType) {
743  auto insertedIterator = reflectable.insert(typename Type::value_type(i->name.GetString(), typename Type::mapped_type()));
744  pull(insertedIterator->second, i->value, errors);
745  continue;
746  }
747  const auto array = i->value.GetArray();
748  for (const auto &value : array) {
749  auto insertedIterator = reflectable.insert(typename Type::value_type(i->name.GetString(), typename Type::mapped_type()));
750  pull(insertedIterator->second, value, errors);
751  }
752  }
753 }
754 
755 namespace Detail {
756 
761 template <class Tuple, std::size_t N> struct TuplePullHelper {
762  static void pull(Tuple &tuple, const RAPIDJSON_NAMESPACE::Value::ConstArray value, JsonDeserializationErrors *errors)
763  {
764  TuplePullHelper<Tuple, N - 1>::pull(tuple, value, errors);
765  JsonReflector::pull<typename std::tuple_element<N - 1, Tuple>::type>(std::get<N - 1>(tuple), value[N - 1], errors);
766  }
767 };
768 
769 template <class Tuple> struct TuplePullHelper<Tuple, 1> {
770  static void pull(Tuple &tuple, const RAPIDJSON_NAMESPACE::Value::ConstArray value, JsonDeserializationErrors *errors)
771  {
772  JsonReflector::pull<typename std::tuple_element<0, Tuple>::type>(std::get<0>(tuple), value[0], errors);
773  }
774 };
775 } // namespace Detail
776 
780 template <typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::tuple>> *>
781 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
782 {
783  if (!value.IsArray()) {
784  if (errors) {
785  errors->reportTypeMismatch<Type>(value.GetType());
786  }
787  return;
788  }
789  const auto array = value.GetArray();
790  if (array.Size() != std::tuple_size<Type>::value) {
791  if (errors) {
792  // FIXME: report expected and actual size
793  errors->reportArraySizeMismatch();
794  }
795  return;
796  }
797  Detail::TuplePullHelper<Type, std::tuple_size<Type>::value>::pull(reflectable, array, errors);
798 }
799 
803 template <typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::pair>> *>
804 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
805 {
806  if (!value.IsArray()) {
807  if (errors) {
808  errors->reportTypeMismatch<Type>(value.GetType());
809  }
810  return;
811  }
812  const auto array = value.GetArray();
813  if (array.Size() != 2) {
814  if (errors) {
815  // FIXME: report expected and actual size
816  errors->reportArraySizeMismatch();
817  }
818  return;
819  }
820  pull(reflectable.first, array[0], errors);
821  pull(reflectable.second, array[1], errors);
822 }
823 
827 template <typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::unique_ptr>> *>
828 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
829 {
830  if (value.IsNull()) {
831  reflectable.reset();
832  return;
833  }
834  reflectable = std::make_unique<typename Type::element_type>();
835  pull(*reflectable, value, errors);
836 }
837 
841 template <typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::shared_ptr>> *>
842 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
843 {
844  if (value.IsNull()) {
845  reflectable.reset();
846  return;
847  }
848  reflectable = std::make_shared<typename Type::element_type>();
849  pull(*reflectable, value, errors);
850 }
851 
853 namespace Detail {
854 template <typename Variant, std::size_t compiletimeIndex = 0>
855 void assignVariantValueByRuntimeIndex(std::size_t runtimeIndex, Variant &variant,
856  const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
857 {
858  if constexpr (compiletimeIndex < std::variant_size_v<Variant>) {
859  if (compiletimeIndex == runtimeIndex) {
860  if constexpr (std::is_same_v<std::variant_alternative_t<compiletimeIndex, Variant>, std::monostate>) {
861  variant = std::monostate{};
862  } else {
863  pull(variant.template emplace<compiletimeIndex>(), value, errors);
864  }
865  } else {
866  assignVariantValueByRuntimeIndex<Variant, compiletimeIndex + 1>(runtimeIndex, variant, value, errors);
867  }
868  } else {
869  if (errors) {
870  errors->emplace_back(JsonDeserializationErrorKind::InvalidVariantIndex, JsonType::Number, JsonType::Number, errors->currentRecord,
871  errors->currentMember, errors->currentIndex);
872  }
873  }
874 }
875 } // namespace Detail
877 
881 template <typename Type, Traits::EnableIf<IsVariant<Type>> *>
882 void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
883 {
884  if (!value.IsObject()) {
885  if (errors) {
886  errors->reportTypeMismatch<Type>(value.GetType());
887  }
888  return;
889  }
890 
891  auto obj = value.GetObject();
892  auto indexIterator = obj.FindMember("index");
893  auto dataIterator = obj.FindMember("data");
894  if (indexIterator == obj.MemberEnd() || dataIterator == obj.MemberEnd()) {
895  if (errors) {
896  errors->emplace_back(JsonDeserializationErrorKind::InvalidVariantObject, JsonType::Object, JsonType::Object, errors->currentRecord,
897  errors->currentMember, errors->currentIndex);
898  }
899  return;
900  }
901  const auto &indexValue = indexIterator->value;
902  if (!indexValue.IsInt()) {
903  if (errors) {
904  errors->emplace_back(JsonDeserializationErrorKind::InvalidVariantIndex, JsonType::Number, jsonType(indexValue.GetType()),
905  errors->currentRecord, errors->currentMember, errors->currentIndex);
906  }
907  return;
908  }
909  const auto index = indexValue.GetInt();
910  if (index < 0) {
911  errors->emplace_back(JsonDeserializationErrorKind::InvalidVariantIndex, JsonType::Number, JsonType::Number, errors->currentRecord,
912  errors->currentMember, errors->currentIndex);
913  return;
914  }
915  Detail::assignVariantValueByRuntimeIndex(static_cast<std::size_t>(index), reflectable, dataIterator->value, errors);
916 }
917 
921 template <typename Type>
922 inline void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ValueIterator &value, JsonDeserializationErrors *errors)
923 {
924  pull<Type>(reflectable, *value, errors);
925  ++value;
926 }
927 
933 template <typename Type>
934 inline void pull(Type &reflectable, const char *name, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value,
936 {
937  // find member
938  const auto member = value.FindMember(name);
939  if (member == value.MemberEnd()) {
940  return; // TODO: handle member missing
941  }
942 
943  // set error context for current member
944  const char *previousMember;
945  if (errors) {
946  previousMember = errors->currentMember;
947  errors->currentMember = name;
948  }
949 
950  // actually pull value for member
951  pull<Type>(reflectable, member->value, errors);
952 
953  // restore previous error context
954  if (errors) {
955  errors->currentMember = previousMember;
956  }
957 }
958 
962 template <typename Type, Traits::DisableIf<IsBuiltInType<Type>> *>
963 void pull(Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
964 {
965  if (!value.IsObject()) {
966  if (errors) {
967  errors->reportTypeMismatch<Type>(value.GetType());
968  }
969  return;
970  }
971  pull(reflectable, value.GetObject(), errors);
972 }
973 
974 // define functions providing high-level JSON serialization
975 
979 template <typename Type, Traits::EnableIfAny<IsJsonSerializable<Type>, IsMapOrHash<Type>, IsMultiMapOrHash<Type>> * = nullptr>
980 RAPIDJSON_NAMESPACE::Document toJsonDocument(const Type &reflectable)
981 {
982  RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kObjectType);
983  push(reflectable, document, document.GetAllocator());
984  return document;
985 }
986 
990 template <typename Type, Traits::EnableIfAny<std::is_integral<Type>, std::is_floating_point<Type>> * = nullptr>
991 RAPIDJSON_NAMESPACE::Document toJsonDocument(Type reflectable)
992 {
993  RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kNumberType);
994  document.Set(reflectable, document.GetAllocator());
995  return document;
996 }
997 
1001 template <typename Type, Traits::EnableIf<std::is_same<Type, std::string>> * = nullptr>
1002 RAPIDJSON_NAMESPACE::Document toJsonDocument(const std::string &reflectable)
1003 {
1004  RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kStringType);
1005  document.SetString(RAPIDJSON_NAMESPACE::StringRef(reflectable.data(), reflectable.size()), document.GetAllocator());
1006  return document;
1007 }
1008 
1012 template <typename Type, Traits::EnableIf<std::is_same<Type, const char *>> * = nullptr>
1013 RAPIDJSON_NAMESPACE::Document toJsonDocument(const char *reflectable)
1014 {
1015  RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kStringType);
1016  document.SetString(RAPIDJSON_NAMESPACE::StringRef(reflectable), document.GetAllocator());
1017  return document;
1018 }
1019 
1023 template <typename Type, Traits::EnableIf<std::is_same<Type, std::string_view>> * = nullptr>
1024 RAPIDJSON_NAMESPACE::Document toJsonDocument(std::string_view reflectable)
1025 {
1026  RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kStringType);
1027  document.SetString(RAPIDJSON_NAMESPACE::StringRef(reflectable.data(), reflectable.size()), document.GetAllocator());
1028  return document;
1029 }
1030 
1034 template <typename Type, Traits::EnableIf<IsArray<Type>> * = nullptr> RAPIDJSON_NAMESPACE::Document toJsonDocument(const Type &reflectable)
1035 {
1036  RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kArrayType);
1037  push(reflectable, document, document.GetAllocator());
1038  return document;
1039 }
1040 
1044 template <typename Type,
1045  Traits::EnableIfAny<IsJsonSerializable<Type>, IsMapOrHash<Type>, IsMultiMapOrHash<Type>, std::is_integral<Type>, std::is_floating_point<Type>,
1046  Traits::IsString<Type>, IsArray<Type>> * = nullptr>
1047 RAPIDJSON_NAMESPACE::StringBuffer toJson(const Type &reflectable)
1048 {
1049  auto document(toJsonDocument(reflectable));
1050  return serializeJsonDocToString(document);
1051 }
1052 
1053 // define functions providing high-level JSON deserialization
1054 
1058 template <typename Type, Traits::EnableIfAny<IsJsonSerializable<Type>, IsMapOrHash<Type>, IsMultiMapOrHash<Type>> * = nullptr>
1059 Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors = nullptr)
1060 {
1061  RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize));
1062  if (!doc.IsObject()) {
1063  if (errors) {
1064  errors->reportTypeMismatch<Type>(doc.GetType());
1065  }
1066  return Type();
1067  }
1068 
1069  Type res;
1070  pull<Type>(res, doc.GetObject(), errors);
1071  return res;
1072 }
1073 
1077 template <typename Type, Traits::EnableIfAny<std::is_integral<Type>, std::is_floating_point<Type>> * = nullptr>
1078 Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors = nullptr)
1079 {
1080  RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize));
1081  if (!doc.Is<Type>()) {
1082  if (errors) {
1083  errors->reportTypeMismatch<Type>(doc.GetType());
1084  }
1085  return Type();
1086  }
1087 
1088  return doc.Get<Type>();
1089 }
1090 
1094 template <typename Type, Traits::EnableIf<std::is_same<Type, std::string>> * = nullptr>
1095 Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors = nullptr)
1096 {
1097  RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize));
1098  if (!doc.IsString()) {
1099  if (errors) {
1100  errors->reportTypeMismatch<Type>(doc.GetType());
1101  }
1102  return Type();
1103  }
1104 
1105  return doc.GetString();
1106 }
1107 
1111 template <typename Type, Traits::EnableIf<IsArray<Type>> * = nullptr>
1112 Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors = nullptr)
1113 {
1114  RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize));
1115  if (!doc.IsArray()) {
1116  if (errors) {
1117  errors->reportTypeMismatch<Type>(doc.GetType());
1118  }
1119  return Type();
1120  }
1121 
1122  Type res;
1123  pull<Type>(res, doc.GetArray(), errors);
1124  return res;
1125 }
1126 
1130 template <typename Type> Type fromJson(const char *json, JsonDeserializationErrors *errors = nullptr)
1131 {
1132  return fromJson<Type>(json, std::strlen(json), errors);
1133 }
1134 
1138 template <typename Type> Type fromJson(const std::string &json, JsonDeserializationErrors *errors = nullptr)
1139 {
1140  return fromJson<Type>(json.data(), json.size(), errors);
1141 }
1142 
1143 } // namespace JsonReflector
1144 } // namespace ReflectiveRapidJSON
1145 
1146 #endif // REFLECTIVE_RAPIDJSON_JSON_REFLECTOR_H
ReflectiveRapidJSON::JsonDeserializationErrors
The JsonDeserializationErrors struct can be passed to fromJson() for error handling.
Definition: errorhandling.h:154
ReflectiveRapidJSON::AdaptedJsonSerializable::qualifiedName
static constexpr const char * qualifiedName
Definition: reflector.h:40
ReflectiveRapidJSON::JsonReflector::fromJson
Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors=nullptr)
Deserializes the specified JSON to.
Definition: reflector.h:1059
ReflectiveRapidJSON::JsonDeserializationErrorKind::InvalidVariantIndex
@ InvalidVariantIndex
ReflectiveRapidJSON::JsonReflector::pull
void pull(Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue< RAPIDJSON_NAMESPACE::UTF8< char >>::ConstObject &value, JsonDeserializationErrors *errors)
Pulls the reflectable which has a custom type from the specified object.
Definition: reflector-boosthana.h:40
ReflectiveRapidJSON::JsonReflector::rapidJsonSize
constexpr RAPIDJSON_NAMESPACE::SizeType rapidJsonSize(std::size_t size)
Casts the specified size to the size type used by RapidJSON ensuring no overflow happens.
Definition: reflector.h:51
ReflectiveRapidJSON::AdaptedJsonSerializable::name
static constexpr const char * name
Definition: reflector.h:39
ReflectiveRapidJSON::JsonReflector::Detail::TuplePullHelper
The TuplePullHelper class helps deserializing tuples from JSON arrays.
Definition: reflector.h:761
ReflectiveRapidJSON::jsonType
constexpr JsonType jsonType()
Definition: errorhandling.h:50
ReflectiveRapidJSON::JsonReflector::toJson
RAPIDJSON_NAMESPACE::StringBuffer toJson(const Type &reflectable)
Serializes the specified reflectable.
Definition: reflector.h:1047
ReflectiveRapidJSON::JsonDeserializationErrors::currentIndex
std::size_t currentIndex
The index in the array which is currently processed.
Definition: errorhandling.h:167
errorhandling.h
Contains helper for error handling when deserializing JSON files.
ReflectiveRapidJSON::JsonReflector::IsCustomType
Traits::Not< IsBuiltInType< Type > > IsCustomType
Definition: reflector.h:87
ReflectiveRapidJSON
Definition: traits.h:13
ReflectiveRapidJSON::JsonDeserializationErrors::currentMember
const char * currentMember
The name of the member (in currentRecord) which is currently being processed.
Definition: errorhandling.h:165
ReflectiveRapidJSON::JsonReflector::Detail::TuplePushHelper::push
static void push(const Tuple &tuple, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
Definition: reflector.h:268
ReflectiveRapidJSON::JsonReflector::Detail::TuplePushHelper< Tuple, 1 >::push
static void push(const Tuple &tuple, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
Definition: reflector.h:276
ReflectiveRapidJSON::JsonReflector::IsJsonSerializable
Traits::Any< Traits::Not< Traits::IsComplete< Type > >, std::is_base_of< JsonSerializable< Type >, Type >, AdaptedJsonSerializable< Type > > IsJsonSerializable
Definition: reflector.h:93
ReflectiveRapidJSON::JsonDeserializationErrors::reportArraySizeMismatch
void reportArraySizeMismatch()
Reports an array size mismatch.
Definition: errorhandling.h:228
ReflectiveRapidJSON::JsonReflector::IsBuiltInType
Traits::Any< std::is_integral< Type >, std::is_floating_point< Type >, std::is_pointer< Type >, std::is_enum< Type >, Traits::IsSpecializationOf< Type, std::tuple >, Traits::IsSpecializationOf< Type, std::pair >, Traits::IsIteratable< Type >, Traits::IsSpecializationOf< Type, std::unique_ptr >, Traits::IsSpecializationOf< Type, std::shared_ptr >, Traits::IsSpecializationOf< Type, std::weak_ptr >, IsVariant< Type > > IsBuiltInType
Definition: reflector.h:86
ReflectiveRapidJSON::JsonDeserializationError::noIndex
static constexpr std::size_t noIndex
Indicates no array was being processed when the error occured.
Definition: errorhandling.h:127
ReflectiveRapidJSON::JsonReflector::parseJsonDocFromString
RAPIDJSON_NAMESPACE::Document parseJsonDocFromString(const char *json, std::size_t jsonSize)
Parses the specified JSON string.
Definition: reflector.h:71
ReflectiveRapidJSON::JsonType::Array
@ Array
ReflectiveRapidJSON::JsonReflector::push
void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
Pushes the specified reflectable to the specified value.
Definition: reflector.h:140
ReflectiveRapidJSON::JsonDeserializationErrorKind::InvalidVariantObject
@ InvalidVariantObject
ReflectiveRapidJSON::JsonReflector::serializeJsonDocToString
RAPIDJSON_NAMESPACE::StringBuffer serializeJsonDocToString(RAPIDJSON_NAMESPACE::Document &document)
Serializes the specified JSON document.
Definition: reflector.h:60
ReflectiveRapidJSON::JsonSerializable
The JsonSerializable class provides the CRTP-base for (de)serializable objects.
Definition: reflector.h:33
ReflectiveRapidJSON::JsonReflector::Detail::TuplePushHelper
The TuplePushHelper class helps serializing tuples to JSON arrays.
Definition: reflector.h:267
ReflectiveRapidJSON::IsVariant
Traits::All< Traits::IsSpecializationOf< Type, std::variant > > IsVariant
Definition: traits.h:67
ReflectiveRapidJSON::JsonReflector::Detail::TuplePullHelper< Tuple, 1 >::pull
static void pull(Tuple &tuple, const RAPIDJSON_NAMESPACE::Value::ConstArray value, JsonDeserializationErrors *errors)
Definition: reflector.h:770
ReflectiveRapidJSON::JsonDeserializationErrors::reportTypeMismatch
void reportTypeMismatch(RAPIDJSON_NAMESPACE::Type presentType)
Reports a type mismatch between.
Definition: errorhandling.h:216
ReflectiveRapidJSON::AdaptedJsonSerializable
The AdaptedJsonSerializable class allows considering 3rd party classes as serializable.
Definition: reflector.h:38
ReflectiveRapidJSON::JsonReflector::toJsonDocument
RAPIDJSON_NAMESPACE::Document toJsonDocument(const Type &reflectable)
Serializes the specified reflectable which has a custom type or can be mapped to and object.
Definition: reflector.h:980
ReflectiveRapidJSON::JsonReflector::Detail::TuplePullHelper::pull
static void pull(Tuple &tuple, const RAPIDJSON_NAMESPACE::Value::ConstArray value, JsonDeserializationErrors *errors)
Definition: reflector.h:762
ReflectiveRapidJSON::JsonType::Number
@ Number
ReflectiveRapidJSON::JsonType::Object
@ Object