8#include "Stroika/Foundation/Containers/Adapters/Adder.h"
13#if qStroika_Foundation_DataExchange_ObjectVariantMapper_Activities
14#include "Stroika/Foundation/Execution/Activity.h"
16#include "Stroika/Foundation/DataExchange/BadFormatException.h"
18#include "Stroika/Foundation/Execution/Throw.h"
32 struct DefaultConstructForRead<Time::Date> {
33 constexpr Time::Date operator() ()
const
39 struct DefaultConstructForRead<Time::DateTime> {
40 constexpr Time::DateTime operator() ()
const
42 return Time::DateTime::kMin;
46 struct DefaultConstructForRead<Time::TimeOfDay> {
47 constexpr Time::TimeOfDay operator() ()
const
53 struct DefaultConstructForRead<IO::Network::CIDR> {
54 IO::Network::CIDR operator() ()
const
56 using namespace IO::Network;
57 return CIDR{InternetAddress{}, 0};
71 const optional<TypeMappingDetails>& overrideTypeMapper)
72 : fSerializedFieldName_{serializedFieldName}
73 , fFieldMetaInfo_{fieldMetaInfo}
74 , fOverrideTypeMapper_{overrideTypeMapper}
76 Require (not serializedFieldName.empty ());
79 inline String ObjectVariantMapper::StructFieldInfo::GetSerializedFieldName ()
const
81 return fSerializedFieldName_;
83 inline StructFieldMetaInfo ObjectVariantMapper::StructFieldInfo::GetStructFieldMetaInfo ()
const
85 return *fFieldMetaInfo_;
87 inline auto ObjectVariantMapper::StructFieldInfo::GetOverrideTypeMapper () const -> optional<TypeMappingDetails>
89 return fOverrideTypeMapper_;
98 : fForType_{forTypeInfo}
99 , fFromObjectMapper_{fromObjectMapper}
100 , fToObjectMapper_{toObjectMapper}
103 template <
typename T>
105 const ToObjectMapperType<T>& toObjectMapper,
const type_index& forTypeInfo)
106 requires (not same_as<T, void>)
107 : TypeMappingDetails{mkGenericFromMapper_ (fromObjectMapper), mkGenericToMapper_ (toObjectMapper), forTypeInfo}
110 inline strong_ordering ObjectVariantMapper::TypeMappingDetails::operator<=> (
const TypeMappingDetails& rhs)
const
112 return Common::StdCompat::compare_three_way{}(fForType_, rhs.fForType_);
114 inline bool ObjectVariantMapper::TypeMappingDetails::operator== (
const TypeMappingDetails& rhs)
const
116 return fForType_ == rhs.fForType_;
118 inline type_index ObjectVariantMapper::TypeMappingDetails::GetForType ()
const
124 return fFromObjectMapper_;
128 return fToObjectMapper_;
130 template <
typename T>
131 inline ObjectVariantMapper::FromObjectMapperType<T> ObjectVariantMapper::TypeMappingDetails::FromObjectMapper (
const FromGenericObjectMapperType& fromObjectMapper)
134 if (Debug::kBuiltWithUndefinedBehaviorSanitizer) {
135 return [fromObjectMapper] (
const ObjectVariantMapper& mapper,
const T* objOfType) -> VariantValue {
136 return fromObjectMapper (mapper, objOfType);
140 return *
reinterpret_cast<const FromObjectMapperType<T>*
> (&fromObjectMapper);
143 template <
typename T>
144 inline ObjectVariantMapper::FromObjectMapperType<T> ObjectVariantMapper::TypeMappingDetails::FromObjectMapper ()
const
146 Require (type_index{
typeid (T)} == fForType_);
147 return FromObjectMapper<T> (fFromObjectMapper_);
149 template <
typename T>
150 inline ObjectVariantMapper::ToObjectMapperType<T> ObjectVariantMapper::TypeMappingDetails::ToObjectMapper (
const ToGenericObjectMapperType& toObjectMapper)
153 if (Debug::kBuiltWithUndefinedBehaviorSanitizer) {
154 return [toObjectMapper] (
const ObjectVariantMapper& mapper,
const VariantValue& d, T* into) ->
void {
155 toObjectMapper (mapper, d, into);
159 return *
reinterpret_cast<const ToObjectMapperType<T>*
> (&toObjectMapper);
162 template <
typename T>
163 inline ObjectVariantMapper::ToObjectMapperType<T> ObjectVariantMapper::TypeMappingDetails::ToObjectMapper ()
const
165 Require (type_index{
typeid (T)} == fForType_);
166 return ToObjectMapper<T> (fToObjectMapper_);
168 template <
typename T>
170 ObjectVariantMapper::TypeMappingDetails::mkGenericFromMapper_ (
const FromObjectMapperType<T>& fromObjectMapper)
173 if (Debug::kBuiltWithUndefinedBehaviorSanitizer) {
174 return [fromObjectMapper] (
const ObjectVariantMapper& mapper,
const void* objOfType) -> VariantValue {
175 return fromObjectMapper (mapper,
reinterpret_cast<const T*
> (objOfType));
182 template <
typename T>
185 if (Debug::kBuiltWithUndefinedBehaviorSanitizer) {
186 return [toObjectMapper] (
const ObjectVariantMapper& mapper,
const VariantValue& d,
void* into) ->
void {
187 toObjectMapper (mapper, d,
reinterpret_cast<T*
> (into));
200 inline ObjectVariantMapper::TypesRegistry::TypesRegistry (
const Traversal::Iterable<TypeMappingDetails>& src)
204 inline optional<ObjectVariantMapper::TypeMappingDetails> ObjectVariantMapper::TypesRegistry::Lookup (type_index t)
const
206 return fSerializers_.Lookup (t);
208 inline void ObjectVariantMapper::TypesRegistry::Add (
const TypeMappingDetails& typeMapDetails)
210 fSerializers_.Add (typeMapDetails);
212 inline void ObjectVariantMapper::TypesRegistry::Add (
const Traversal::Iterable<TypeMappingDetails>& typeMapDetails)
214 fSerializers_ += typeMapDetails;
216 inline void ObjectVariantMapper::TypesRegistry::operator+= (
const TypeMappingDetails& typeMapDetails)
218 Add (typeMapDetails);
220 inline void ObjectVariantMapper::TypesRegistry::operator+= (
const Traversal::Iterable<TypeMappingDetails>& typeMapDetails)
222 Add (typeMapDetails);
224 inline Traversal::Iterable<ObjectVariantMapper::TypeMappingDetails> ObjectVariantMapper::TypesRegistry::GetMappers ()
const
226 return fSerializers_;
234 template <Common::StdCompat::formattable<
wchar_t> T>
235 inline const ObjectVariantMapper::FromObjectMapperType<T> ObjectVariantMapper::kTraceFromObjectMapper =
237 DbgTrace (
"FromObject<{}>(mapper, {}) called",
typeid (T), objOfType);
240 template <Common::StdCompat::formattable<
wchar_t> T>
241 inline const ObjectVariantMapper::ToObjectMapperType<T> ObjectVariantMapper::kTraceToObjectMapper =
243 DbgTrace (
"ToObject<{}>(mapper, {}, {}) called",
typeid (T), d, into);
247 return fTypeMappingRegistry_;
251 fTypeMappingRegistry_ = s;
253 template <
typename T>
254 inline void ObjectVariantMapper::Add (
const FromObjectMapperType<T>& fromObjectMapper,
const ToObjectMapperType<T>& toObjectMapper)
256 Add (TypeMappingDetails{fromObjectMapper, toObjectMapper,
typeid (T)});
274 template <
typename T,
typename... ARGS>
277 if constexpr (same_as<T, TypedBLOB>) {
279 AddCommonType<Memory::BLOB> ();
282 const T* n =
nullptr;
283 AssertDependentTypesAlreadyInRegistry_ (n);
284 auto&& serializer = MakeCommonSerializer<T> (forward<ARGS> (args)...);
285 Assert (serializer.GetForType () == typeid (T));
288 template <
typename CLASS>
289 inline void ObjectVariantMapper::AddClass (
const Traversal::Iterable<StructFieldInfo>& fieldDescriptions,
const ClassMapperOptions<CLASS>& mapperOptions)
291 Add (MakeClassSerializer_<CLASS> (fieldDescriptions, mapperOptions,
this));
293 template <
typename CLASS,
typename BASE_CLASS>
296 TypeMappingDetails baseClassTypeMapper = Lookup_ (
typeid (BASE_CLASS));
297 ClassMapperOptions<CLASS> useOptions = mapperOptions;
298 Require (useOptions.fBeforeFrom ==
nullptr);
299 Require (useOptions.fBeforeTo ==
nullptr);
301 useOptions.fBeforeFrom = baseClassTypeMapper.FromObjectMapper<BASE_CLASS> ();
302 useOptions.fBeforeTo = baseClassTypeMapper.ToObjectMapper<BASE_CLASS> ();
303 Add (MakeClassSerializer_<CLASS> (fieldDescriptions, useOptions,
this));
305 template <
typename T>
308 Require (Lookup_ (
typeid (T)).GetGenericToObjectMapper ());
311 template <
typename T>
316 template <
typename T>
322 if (toObjectMapper !=
nullptr) {
323 toObjectMapper (*
this, v, into);
326 template <
typename T>
330 ToObject<T> (ToObjectMapper<T> (), v, into);
332 template <IDefaultConstructForRead T>
335 T tmp = DefaultConstructForRead<T>{}();
339 template <IDefaultConstructForRead T>
342 return ToObject<T> (ToObjectMapper<T> (), v);
344 template <
typename T>
348 return ToObject<T> (ToObjectMapper<T> (), v);
354 template <
typename T>
358 if (fromObjectMapper ==
nullptr) {
359 return VariantValue{};
362 return fromObjectMapper (*
this, &from);
364 template <
typename T>
367 return FromObjectMapper<T> () (*
this, &from);
369 template <
typename T>
370 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (T*)
374 template <
typename T>
375 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (optional<T>*)
378 (void)Lookup_ (
typeid (T));
381 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
382 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (
const Containers::Bijection<DOMAIN_TYPE, RANGE_TYPE>*)
385 (void)Lookup_ (
typeid (DOMAIN_TYPE));
386 (void)Lookup_ (
typeid (RANGE_TYPE));
389 template <
typename T>
390 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (Containers::Collection<T>*)
393 (void)Lookup_ (
typeid (T));
396 template <
typename T,
typename TRAITS>
397 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (
const Traversal::DiscreteRange<T, TRAITS>*)
400 (void)Lookup_ (
typeid (T));
403 template <
typename T,
typename KEY_TYPE,
typename TRAITS>
404 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (Containers::KeyedCollection<T, KEY_TYPE, TRAITS>*)
407 (void)Lookup_ (
typeid (T));
408 (void)Lookup_ (
typeid (KEY_TYPE));
411 template <
typename KEY_TYPE,
typename VALUE_TYPE>
412 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (
const Mapping<KEY_TYPE, VALUE_TYPE>*)
415 (void)Lookup_ (
typeid (KEY_TYPE));
416 (void)Lookup_ (
typeid (VALUE_TYPE));
419 template <
typename T,
typename TRAITS>
420 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (
const Traversal::Range<T, TRAITS>*)
423 (void)Lookup_ (
typeid (T));
426 template <
typename T>
427 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (
const Sequence<T>*)
430 (void)Lookup_ (
typeid (T));
433 template <
typename T>
434 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (
const Set<T>*)
437 (void)Lookup_ (
typeid (T));
440 template <
typename T,
typename TRAITS>
441 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (
const Execution::Synchronized<T, TRAITS>*)
444 (void)Lookup_ (
typeid (T));
447 template <
typename T>
448 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (
const vector<T>*)
451 (void)Lookup_ (
typeid (T));
454 template <
typename T1,
typename T2>
455 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (
const pair<T1, T2>*)
458 (void)Lookup_ (
typeid (T1));
459 (void)Lookup_ (
typeid (T2));
462 template <
typename T>
463 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (
const Common::CountedValue<T>*)
465#if qStroika_Foundation_Debug_AssertionsChecked
466 (void)Lookup_ (
typeid (T));
469 template <
typename T1,
typename T2>
470 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (
const Common::KeyValuePair<T1, T2>*)
473 (void)Lookup_ (
typeid (T1));
474 (void)Lookup_ (
typeid (T2));
477 template <
typename T1>
478 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (
const tuple<T1>*)
481 (void)Lookup_ (
typeid (T1));
484 template <
typename T1,
typename T2>
485 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (
const tuple<T1, T2>*)
488 (void)Lookup_ (
typeid (T1));
489 (void)Lookup_ (
typeid (T2));
492 template <
typename T1,
typename T2,
typename T3>
493 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (
const tuple<T1, T2, T3>*)
496 (void)Lookup_ (
typeid (T1));
497 (void)Lookup_ (
typeid (T2));
498 (void)Lookup_ (
typeid (T3));
501 template <
typename T,
size_t SZ>
502 inline void ObjectVariantMapper::AssertDependentTypesAlreadyInRegistry_ (
const T (*)[SZ])
505 (void)Lookup_ (
typeid (T));
508 template <Containers::Adapters::IAddableTo ACTUAL_CONTAINER_TYPE>
511 using namespace Characters::Literals;
512 using T =
typename ACTUAL_CONTAINER_TYPE::value_type;
514 const ACTUAL_CONTAINER_TYPE* fromObjOfTypeT) ->
VariantValue {
517 if (not fromObjOfTypeT->empty ()) {
519 for (
const auto& i : *fromObjOfTypeT) {
526 ACTUAL_CONTAINER_TYPE* intoObjOfTypeT) ->
void {
528 Require (intoObjOfTypeT->empty ());
529#if qStroika_Foundation_DataExchange_ObjectVariantMapper_Activities
531 [&] () ->
String {
return "Decoding {:.100} into class {}"_f(d, type_index{
typeid (ACTUAL_CONTAINER_TYPE)}); }};
535 if (not s.
empty ()) {
537 for (
const auto& i : s) {
542 return TypeMappingDetails{fromObjectMapper, toObjectMapper,
typeid (ACTUAL_CONTAINER_TYPE)};
544 template <
typename T,
typename... ARGS>
547 const T* n =
nullptr;
550 return TypeMappingDetails{tmp.GetGenericFromObjectMapper (), tmp.GetGenericToObjectMapper (),
typeid (T)};
552 template <
typename T>
554 const ClassMapperOptions<T>& options)
555 requires (is_class_v<T>)
557 return MakeClassSerializer_<T> (fieldDescriptions, options,
nullptr);
559 template <
typename T>
561 const ClassMapperOptions<T>& options,
563 requires (is_class_v<T>)
565 return MakeCommonSerializer_ForClassObject_and_check_<T> (
typeid (T),
sizeof (T), fieldDescriptions, options, mapperToCheckAgainst);
567 template <
typename T>
570 return MakeClassSerializer_<Math::CommonStatistics<T>> (
574 {
"mean"sv, &Math::CommonStatistics<T>::fMean},
575 {
"median"sv, &Math::CommonStatistics<T>::fMedian},
576 {
"stddev"sv, &Math::CommonStatistics<T>::fStandardDeviation},
578 ClassMapperOptions<Math::CommonStatistics<T>>{},
nullptr);
580 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
581 ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const Containers::Bijection<DOMAIN_TYPE, RANGE_TYPE>*)
583 using namespace Characters;
584 using Containers::Bijection;
585 FromObjectMapperType<Bijection<DOMAIN_TYPE, RANGE_TYPE>> fromObjectMapper =
586 [] (
const ObjectVariantMapper& mapper,
const Bijection<DOMAIN_TYPE, RANGE_TYPE>* fromObjOfTypeT) -> VariantValue {
588 FromObjectMapperType<DOMAIN_TYPE> domainMapper{mapper.FromObjectMapper<DOMAIN_TYPE> ()};
589 FromObjectMapperType<RANGE_TYPE> rangeMapper{mapper.FromObjectMapper<RANGE_TYPE> ()};
590 Sequence<VariantValue> s;
591 for (
const auto& i : *fromObjOfTypeT) {
592 Sequence<VariantValue> encodedPair;
593 encodedPair.Append (mapper.FromObject<DOMAIN_TYPE> (domainMapper, i.first));
594 encodedPair.Append (mapper.FromObject<RANGE_TYPE> (rangeMapper, i.second));
595 s.Append (VariantValue{encodedPair});
597 return VariantValue{s};
599 ToObjectMapperType<Bijection<DOMAIN_TYPE, RANGE_TYPE>> toObjectMapper = [] (
const ObjectVariantMapper& mapper,
const VariantValue& d,
600 Bijection<DOMAIN_TYPE, RANGE_TYPE>* intoObjOfTypeT) ->
void {
602 ToObjectMapperType<DOMAIN_TYPE> domainMapper{mapper.ToObjectMapper<DOMAIN_TYPE> ()};
603 ToObjectMapperType<RANGE_TYPE> rangeMapper{mapper.ToObjectMapper<RANGE_TYPE> ()};
604 Sequence<VariantValue> s = d.As<Sequence<VariantValue>> ();
605 intoObjOfTypeT->clear ();
606 for (
const VariantValue& encodedPair : s) {
607 Sequence<VariantValue> p = encodedPair.As<Sequence<VariantValue>> ();
608 if (p.size () != 2) [[unlikely]] {
609 DbgTrace (
"Bijection ('{}') element with item count ({}) other than 2"_f,
610 type_index{
typeid (Bijection<DOMAIN_TYPE, RANGE_TYPE>)},
static_cast<int> (p.size ()));
611 static const auto kException_ = BadFormatException{
"Mapping element with item count other than 2"sv};
614 intoObjOfTypeT->Add (mapper.ToObject<DOMAIN_TYPE> (domainMapper, p[0]), mapper.ToObject<RANGE_TYPE> (rangeMapper, p[1]));
617 return TypeMappingDetails{fromObjectMapper, toObjectMapper,
typeid (Bijection<DOMAIN_TYPE, RANGE_TYPE>)};
619 template <
typename T>
620 inline ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const Containers::Collection<T>*)
622 return MakeCommonSerializer_WithAdder<Containers::Collection<T>> ();
624 template <
typename T,
typename KEY_TYPE,
typename TRAITS>
625 inline ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const Containers::KeyedCollection<T, KEY_TYPE, TRAITS>*)
627 return MakeCommonSerializer_WithAdder<Containers::KeyedCollection<T, KEY_TYPE, TRAITS>> ();
629 template <
typename KEY_TYPE,
typename VALUE_TYPE>
630 inline ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const Mapping<KEY_TYPE, VALUE_TYPE>*)
635 return MakeCommonSerializer_MappingWithStringishKey<Containers::Mapping<KEY_TYPE, VALUE_TYPE>> ();
637 template <
typename T>
638 inline ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const Containers::MultiSet<T>*)
640 return MakeCommonSerializer_WithAdder<Containers::MultiSet<T>> ();
642 template <
typename T>
643 ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const optional<T>*)
645 FromObjectMapperType<optional<T>> fromObjectMapper = [] (
const ObjectVariantMapper& mapper,
const optional<T>* fromObjOfTypeT) -> VariantValue {
647 if (fromObjOfTypeT->has_value ()) {
648 return mapper.FromObject<T> (**fromObjOfTypeT);
651 return VariantValue{};
654 ToObjectMapperType<optional<T>> toObjectMapper = [] (
const ObjectVariantMapper& mapper,
const VariantValue& d, optional<T>* intoObjOfTypeT) ->
void {
656 if (d.GetType () == VariantValue::eNull) {
657 *intoObjOfTypeT = nullopt;
662 *intoObjOfTypeT = mapper.ToObject<T> (d);
665 return TypeMappingDetails{fromObjectMapper, toObjectMapper,
typeid (optional<T>)};
667 template <
typename T>
668 ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const optional<T>*,
const OptionalSerializerOptions& options)
670 if (not options.fTMapper.has_value ()) {
671 return MakeCommonSerializer_ ((
const optional<T>*)
nullptr);
673 FromObjectMapperType<optional<T>> fromObjectMapper = [options] (
const ObjectVariantMapper& mapper,
const optional<T>* fromObjOfTypeT) -> VariantValue {
675 if (fromObjOfTypeT->has_value ()) {
676 return options.fTMapper->FromObjectMapper<T> () (mapper, &**fromObjOfTypeT);
679 return VariantValue{};
682 ToObjectMapperType<optional<T>> toObjectMapper = [options] (
const ObjectVariantMapper& mapper,
const VariantValue& d,
683 optional<T>* intoObjOfTypeT) ->
void {
685 if (d.GetType () == VariantValue::eNull) {
686 *intoObjOfTypeT = nullopt;
692 options.fTMapper->ToObjectMapper<T> () (mapper, d, &tmp);
693 *intoObjOfTypeT = tmp;
696 return TypeMappingDetails{fromObjectMapper, toObjectMapper,
typeid (optional<T>)};
700 ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const optional<IO::Network::CIDR>*);
701 template <
typename T,
typename TRAITS>
702 ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const Execution::Synchronized<T, TRAITS>*)
704 using Execution::Synchronized;
705 auto fromObjectMapper = [] (
const ObjectVariantMapper& mapper,
const Synchronized<T, TRAITS>* fromObjOfTypeT) -> VariantValue {
707 return mapper.FromObject<T> (**fromObjOfTypeT);
709 auto toObjectMapper = [] (
const ObjectVariantMapper& mapper,
const VariantValue& d, Synchronized<T, TRAITS>* intoObjOfTypeT) ->
void {
711 *intoObjOfTypeT = mapper.ToObject<T> (d);
713 return TypeMappingDetails{
typeid (Synchronized<T, TRAITS>), fromObjectMapper, toObjectMapper};
715 template <
typename T>
716 inline ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const Sequence<T>*)
718 return MakeCommonSerializer_WithAdder<Sequence<T>> ();
720 template <
typename T>
721 inline ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const vector<T>*)
723 return MakeCommonSerializer_WithAdder<vector<T>> ();
725 template <
typename T1,
typename T2>
726 ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const pair<T1, T2>*)
729 return TypeMappingDetails{
730 FromObjectMapperType<pair<T1, T2>>{[] (
const ObjectVariantMapper& mapper,
const pair<T1, T2>* fromObj) -> VariantValue {
731 return VariantValue{Sequence<VariantValue>{mapper.FromObject<T1> (fromObj->first), mapper.FromObject<T2> (fromObj->second)}};
733 ToObjectMapperType<pair<T1, T2>>{[] (
const ObjectVariantMapper& mapper,
const VariantValue& d, pair<T1, T2>* intoObj) ->
void {
734 Sequence<VariantValue> s = d.As<Sequence<VariantValue>> ();
736 static const auto kException_ = BadFormatException{
"Array size out of range for pair"sv};
739 *intoObj = make_pair (mapper.ToObject<T1> (s[0]), mapper.ToObject<T2> (s[1]));
741 typeid (pair<T1, T2>)};
743 template <
typename T>
744 ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const Common::CountedValue<T>*)
747 using CountedValue =
typename Common::CountedValue<T>;
748 using CounterType =
typename CountedValue::CounterType;
749 return TypeMappingDetails{
750 FromObjectMapperType<CountedValue>{[] (
const ObjectVariantMapper& mapper,
const CountedValue* fromObj) -> VariantValue {
751 return VariantValue{Sequence<VariantValue>{mapper.FromObject<T> (fromObj->fValue), mapper.FromObject<CounterType> (fromObj->fCount)}};
753 ToObjectMapperType<CountedValue>{[] (
const ObjectVariantMapper& mapper,
const VariantValue& d, CountedValue* intoObj) ->
void {
754 Sequence<VariantValue> s = d.As<Sequence<VariantValue>> ();
756 static const auto kException_ = BadFormatException{
"Array size out of range for CountedValue"sv};
759 *intoObj = CountedValue{mapper.ToObject<T> (s[0]), mapper.ToObject<CounterType> (s[1])};
761 typeid (CountedValue)};
763 template <
typename T1,
typename T2>
764 ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const Common::KeyValuePair<T1, T2>*)
767 return TypeMappingDetails{
768 FromObjectMapperType<Common::KeyValuePair<T1, T2>>{[] (
const ObjectVariantMapper& mapper,
const Common::KeyValuePair<T1, T2>* fromObj) -> VariantValue {
769 return VariantValue{Sequence<VariantValue>{mapper.FromObject<T1> (fromObj->fKey), mapper.FromObject<T2> (fromObj->fValue)}};
771 ToObjectMapperType<Common::KeyValuePair<T1, T2>>{
772 [] (
const ObjectVariantMapper& mapper,
const VariantValue& d, Common::KeyValuePair<T1, T2>* intoObj) ->
void {
773 Sequence<VariantValue> s = d.As<Sequence<VariantValue>> ();
775 static const auto kException_ = BadFormatException{
"Array size out of range for KeyValuePair"sv};
778 *intoObj = Common::KeyValuePair<T1, T2>{mapper.ToObject<T1> (s[0]), mapper.ToObject<T2> (s[1])};
780 typeid (Common::KeyValuePair<T1, T2>)};
782 template <
typename T1>
783 ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const tuple<T1>*)
786 return TypeMappingDetails{FromObjectMapperType<tuple<T1>>{[] (
const ObjectVariantMapper& mapper,
const tuple<T1>* fromObj) -> VariantValue {
787 return VariantValue{Sequence<VariantValue>{mapper.FromObject<T1> (std::get<0> (*fromObj))}};
789 ToObjectMapperType<tuple<T1>>{[] (
const ObjectVariantMapper& mapper,
const VariantValue& d, tuple<T1>* intoObj) ->
void {
790 Sequence<VariantValue> s = d.As<Sequence<VariantValue>> ();
792 static const auto kException_ = BadFormatException{
"Array size out of range for tuple/1"sv};
795 *intoObj = make_tuple (mapper.ToObject<T1> (s[0]));
799 template <
typename T1,
typename T2>
800 ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const tuple<T1, T2>*)
803 return TypeMappingDetails{
804 FromObjectMapperType<tuple<T1, T2>>{[] (
const ObjectVariantMapper& mapper,
const tuple<T1, T2>* fromObj) -> VariantValue {
806 Sequence<VariantValue>{mapper.FromObject<T1> (std::get<0> (*fromObj)), mapper.FromObject<T2> (std::get<1> (*fromObj))}};
808 ToObjectMapperType<tuple<T1, T2>>{[] (
const ObjectVariantMapper& mapper,
const VariantValue& d, tuple<T1, T2>* intoObj) ->
void {
809 Sequence<VariantValue> s = d.As<Sequence<VariantValue>> ();
811 static const auto kException_ = BadFormatException{
"Array size out of range for tuple/2"sv};
814 *intoObj = make_tuple (mapper.ToObject<T1> (s[0]), mapper.ToObject<T2> (s[1]));
816 typeid (tuple<T1, T2>)};
818 template <
typename T1,
typename T2,
typename T3>
819 ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const tuple<T1, T2, T3>*)
822 return TypeMappingDetails{
823 FromObjectMapperType<tuple<T1, T2, T3>>{[] (
const ObjectVariantMapper& mapper,
const tuple<T1, T2, T3>* fromObj) -> VariantValue {
824 return VariantValue{Sequence<VariantValue>{mapper.FromObject<T1> (std::get<0> (*fromObj)), mapper.FromObject<T2> (std::get<1> (*fromObj)),
825 mapper.FromObject<T3> (std::get<2> (*fromObj))}};
827 ToObjectMapperType<tuple<T1, T2, T3>>{[] (
const ObjectVariantMapper& mapper,
const VariantValue& d, tuple<T1, T2, T3>* intoObj) ->
void {
828 Sequence<VariantValue> s = d.As<Sequence<VariantValue>> ();
830 static const auto kException_ = BadFormatException{
"Array size out of range for tuple/3"sv};
833 *intoObj = make_tuple (mapper.ToObject<T1> (s[0]), mapper.ToObject<T2> (s[1]), mapper.ToObject<T3> (s[2]));
835 typeid (tuple<T1, T2, T3>)};
837 template <
typename T>
838 inline ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const Set<T>*)
840 return MakeCommonSerializer_WithAdder<Set<T>> ();
842 template <
typename T>
843 inline ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const Containers::SortedCollection<T>*)
845 return MakeCommonSerializer_WithAdder<Containers::SortedCollection<T>> ();
847 template <
typename T,
typename KEY_TYPE,
typename TRAITS>
848 inline ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const Containers::SortedKeyedCollection<T, KEY_TYPE, TRAITS>*)
850 return MakeCommonSerializer_WithAdder<Containers::SortedKeyedCollection<T, KEY_TYPE, TRAITS>> ();
852 template <
typename KEY_TYPE,
typename VALUE_TYPE>
853 inline ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const Containers::SortedMapping<KEY_TYPE, VALUE_TYPE>*)
858 return MakeCommonSerializer_MappingWithStringishKey<Containers::SortedMapping<KEY_TYPE, VALUE_TYPE>> ();
860 template <
typename T>
861 inline ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const Containers::SortedMultiSet<T>*)
863 return MakeCommonSerializer_WithAdder<Containers::SortedMultiSet<T>> ();
865 template <
typename T>
866 inline ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const Containers::SortedSet<T>*)
868 return MakeCommonSerializer_WithAdder<Containers::SortedSet<T>> ();
870 template <
typename T,
typename TRAITS>
871 inline ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const Traversal::DiscreteRange<T, TRAITS>*)
873 return MakeCommonSerializer_Range_<Traversal::DiscreteRange<T, TRAITS>> ();
875 template <
typename T,
typename TRAITS,
typename... ARGS>
876 inline ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const Traversal::Range<T, TRAITS>*, ARGS&&... args)
878 return MakeCommonSerializer_Range_<Traversal::Range<T, TRAITS>> (forward<ARGS> (args)...);
880 template <
typename T>
881 inline ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const T*)
882 requires (is_enum_v<T>)
884 return MakeCommonSerializer_NamedEnumerations<T> ();
886 template <
typename T,
size_t SZ>
887 ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_ (
const T (*)[SZ])
889 using namespace Characters::Literals;
891 auto fromObjectMapper = [] (
const ObjectVariantMapper& mapper,
const void* fromObjOfTypeT) -> VariantValue {
893 FromObjectMapperType<T> valueMapper{mapper.FromObjectMapper<T> ()};
894 Sequence<VariantValue> s;
895 const T* actualMember{
reinterpret_cast<const T*
> (fromObjOfTypeT)};
896 for (
auto i = actualMember; i < actualMember + SZ; ++i) {
897 s.Append (mapper.FromObject<T> (valueMapper, *i));
899 return VariantValue{s};
901 auto toObjectMapper = [] (
const ObjectVariantMapper& mapper,
const VariantValue& d,
void* intoObjOfTypeT) ->
void {
903 Sequence<VariantValue> s = d.As<Sequence<VariantValue>> ();
904 T* actualMember{
reinterpret_cast<T*
> (intoObjOfTypeT)};
905 if (s.size () > SZ) [[unlikely]] {
906 DbgTrace (
"Array ('{}') actual size {} out of range"_f, type_index{
typeid (T[SZ])},
static_cast<int> (s.size ()));
907 static const auto kException_ = BadFormatException{
"Array size out of range"sv};
910 ToObjectMapperType<T> valueMapper{mapper.ToObjectMapper<T> ()};
912 for (
const auto& i : s) {
913 actualMember[idx++] = mapper.ToObject<T> (valueMapper, i);
916 actualMember[idx++] = T{};
919 return TypeMappingDetails{fromObjectMapper, toObjectMapper,
typeid (T[SZ])};
921 template <
typename KEY_TYPE,
typename VALUE_TYPE,
typename ACTUAL_CONTAINER_TYPE>
922 ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_WithKeyValuePairAdd_ ()
924 auto fromObjectMapper = [] (
const ObjectVariantMapper& mapper,
const ACTUAL_CONTAINER_TYPE* fromObjOfTypeT) -> VariantValue {
926 FromObjectMapperType<KEY_TYPE> keyMapper{mapper.FromObjectMapper<KEY_TYPE> ()};
927 FromObjectMapperType<VALUE_TYPE> valueMapper{mapper.FromObjectMapper<VALUE_TYPE> ()};
928 Sequence<VariantValue> s;
929 for (
const auto& i : *fromObjOfTypeT) {
930 Sequence<VariantValue> encodedPair;
931 encodedPair.Append (mapper.FromObject<KEY_TYPE> (keyMapper, i.fKey));
932 encodedPair.Append (mapper.FromObject<VALUE_TYPE> (valueMapper, i.fValue));
933 s.Append (VariantValue{encodedPair});
935 return VariantValue{s};
937 auto toObjectMapper = [] (
const ObjectVariantMapper& mapper,
const VariantValue& d, ACTUAL_CONTAINER_TYPE* intoObjOfTypeT) ->
void {
946 ToObjectMapperType<KEY_TYPE> keyMapper{mapper.ToObjectMapper<KEY_TYPE> ()};
947 ToObjectMapperType<VALUE_TYPE> valueMapper{mapper.ToObjectMapper<VALUE_TYPE> ()};
948 Sequence<VariantValue> s = d.As<Sequence<VariantValue>> ();
949 intoObjOfTypeT->clear ();
950 for (
const VariantValue& encodedPair : s) {
951 Sequence<VariantValue> p = encodedPair.As<Sequence<VariantValue>> ();
952 if (p.size () != 2) [[unlikely]] {
953 using namespace Characters;
954 DbgTrace (
"Container with Key/Value pair ('{}') element with item count ({}) other than 2"_f,
955 type_index{
typeid (ACTUAL_CONTAINER_TYPE)},
static_cast<int> (p.size ()));
956 static const auto kException_ = BadFormatException{
"Container with Key/Value pair element with item count other than 2"_k};
959 intoObjOfTypeT->Add (mapper.ToObject<KEY_TYPE> (keyMapper, p[0]), mapper.ToObject<VALUE_TYPE> (valueMapper, p[1]));
962 return TypeMappingDetails{fromObjectMapper, toObjectMapper,
typeid (ACTUAL_CONTAINER_TYPE)};
964 template <
typename ENUM_TYPE>
965 ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_NamedEnumerations (
const Containers::Bijection<ENUM_TYPE, String>& nameMap)
967 using namespace Characters::Literals;
968 static_assert (is_enum_v<ENUM_TYPE>,
"MakeCommonSerializer_NamedEnumerations only works for enum types");
969 using SerializeAsType =
typename underlying_type<ENUM_TYPE>::type;
970 static_assert (
sizeof (SerializeAsType) ==
sizeof (ENUM_TYPE),
"underlyingtype?");
971 FromObjectMapperType<ENUM_TYPE> fromObjectMapper = [nameMap] ([[maybe_unused]]
const ObjectVariantMapper& mapper,
972 const ENUM_TYPE* fromObjOfTypeT) -> VariantValue {
974 Assert (
sizeof (SerializeAsType) ==
sizeof (ENUM_TYPE));
975 Assert (
static_cast<ENUM_TYPE
> (
static_cast<SerializeAsType
> (*fromObjOfTypeT)) == *fromObjOfTypeT);
976 return VariantValue{*nameMap.Lookup (*fromObjOfTypeT)};
978 ToObjectMapperType<ENUM_TYPE> toObjectMapper = [nameMap] ([[maybe_unused]]
const ObjectVariantMapper& mapper,
const VariantValue& d,
979 ENUM_TYPE* intoObjOfTypeT) ->
void {
981 auto optVal = nameMap.InverseLookup (d.As<String> ());
982 if (not optVal.has_value ()) [[unlikely]] {
983 DbgTrace (
"Enumeration ('{}') value '{}' out of range"_f, type_index{
typeid (ENUM_TYPE)}, d);
984 static const auto kException_ = BadFormatException{
"Enumeration value out of range"sv};
987 *intoObjOfTypeT = *optVal;
989 return TypeMappingDetails{fromObjectMapper, toObjectMapper,
typeid (ENUM_TYPE)};
991 template <
typename ENUM_TYPE>
992 inline ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_NamedEnumerations (
const Common::EnumNames<ENUM_TYPE>& nameMap)
994 return MakeCommonSerializer_NamedEnumerations (Containers::Bijection<ENUM_TYPE, String>{nameMap});
996 template <
typename ENUM_TYPE>
997 ObjectVariantMapper::TypeMappingDetails ObjectVariantMapper::MakeCommonSerializer_EnumAsInt ()
1005 static_assert (is_enum_v<ENUM_TYPE>,
"This only works for enum types");
1006 using SerializeAsType =
typename underlying_type<ENUM_TYPE>::type;
1007 static_assert (
sizeof (SerializeAsType) ==
sizeof (ENUM_TYPE),
"underlyingtype?");
1008 FromObjectMapperType<ENUM_TYPE> fromObjectMapper = [] ([[maybe_unused]]
const ObjectVariantMapper& mapper,
1009 const ENUM_TYPE* fromObjOfTypeT) -> VariantValue {
1011 Assert (
static_cast<ENUM_TYPE
> (
static_cast<SerializeAsType
> (*fromObjOfTypeT)) == *fromObjOfTypeT);
1012 return VariantValue{
static_cast<SerializeAsType
> (*fromObjOfTypeT)};
1014 ToObjectMapperType<ENUM_TYPE> toObjectMapper = [] ([[maybe_unused]]
const ObjectVariantMapper& mapper,
const VariantValue& d,
1015 ENUM_TYPE* intoObjOfTypeT) ->
void {
1017 *intoObjOfTypeT =
static_cast<ENUM_TYPE
> (d.As<SerializeAsType> ());
1018 Assert (
static_cast<SerializeAsType
> (*intoObjOfTypeT) == d.As<SerializeAsType> ());
1019 if (not(ENUM_TYPE::eSTART <= *intoObjOfTypeT and *intoObjOfTypeT < ENUM_TYPE::eEND)) [[unlikely]] {
1020 using namespace Characters;
1021 DbgTrace (
"Enumeration ('{}') value {} out of range"_f, type_index{
typeid (ENUM_TYPE)},
static_cast<int> (*intoObjOfTypeT));
1022 static const auto kException_ = BadFormatException{
"Enumeration value out of range"_k};
1026 return TypeMappingDetails{fromObjectMapper, toObjectMapper,
typeid (ENUM_TYPE)};
1028 template <
typename ACTUAL_CONTAINTER_TYPE, IDefaultConstructForRead KEY_TYPE, IDefaultConstructForRead VALUE_TYPE>
1032 const ACTUAL_CONTAINTER_TYPE* fromObjOfTypeT) ->
VariantValue {
1036 using namespace Containers::Concrete;
1037 SortedMapping_stdmap<String, VariantValue>::STDMAP<> m;
1039 m.insert ({mapper.
FromObject<KEY_TYPE> (keyMapper, i.fKey).
template As<String> (),
1040 mapper.
FromObject<VALUE_TYPE> (valueMapper, i.fValue)});
1042 return VariantValue{SortedMapping_stdmap<String, VariantValue>{move (m)}};
1045 ACTUAL_CONTAINTER_TYPE* intoObjOfTypeT) ->
void {
1050 intoObjOfTypeT->
clear ();
1052 intoObjOfTypeT->Add (mapper.
ToObject<KEY_TYPE> (keyMapper, p.fKey), mapper.
ToObject<VALUE_TYPE> (valueMapper, p.fValue));
1055 return TypeMappingDetails{fromObjectMapper, toObjectMapper,
typeid (ACTUAL_CONTAINTER_TYPE)};
1057 template <
typename ACTUAL_CONTAINTER_TYPE, IDefaultConstructForRead KEY_TYPE, IDefaultConstructForRead VALUE_TYPE>
1060 return MakeCommonSerializer_WithKeyValuePairAdd_<KEY_TYPE, VALUE_TYPE, ACTUAL_CONTAINTER_TYPE> ();
1062 template <
typename RANGE_TYPE>
1065 using namespace Characters::Literals;
1066 static const String kLowerBoundLabel_{
"LowerBound"sv};
1067 static const String kUpperBoundLabel_{
"UpperBound"sv};
1068 String lowerBoundLabel = options.fLowerBoundFieldName.value_or (kLowerBoundLabel_);
1069 String upperBoundLabel = options.fUpperBoundFieldName.value_or (kUpperBoundLabel_);
1070 FromObjectMapperType<RANGE_TYPE> fromObjectMapper = [=] (
const ObjectVariantMapper& mapper,
const RANGE_TYPE* fromObjOfTypeT) -> VariantValue {
1072 Mapping<String, VariantValue> m;
1073 if (fromObjOfTypeT->empty ()) {
1074 return VariantValue{};
1077 using value_type =
typename RANGE_TYPE::value_type;
1078 FromObjectMapperType<value_type> valueMapper{mapper.FromObjectMapper<value_type> ()};
1079 m.Add (lowerBoundLabel, mapper.FromObject<value_type> (valueMapper, fromObjOfTypeT->GetLowerBound ()));
1080 m.Add (upperBoundLabel, mapper.FromObject<value_type> (valueMapper, fromObjOfTypeT->GetUpperBound ()));
1081 return VariantValue{m};
1084 ToObjectMapperType<RANGE_TYPE> toObjectMapper = [=] (
const ObjectVariantMapper& mapper,
const VariantValue& d, RANGE_TYPE* intoObjOfTypeT) ->
void {
1086 Mapping<String, VariantValue> m{d.As<Mapping<String, VariantValue>> ()};
1088 *intoObjOfTypeT = RANGE_TYPE{};
1091 if (m.size () != 2) [[unlikely]] {
1092 DbgTrace (
"Range ('{}') element needs LowerBound and UpperBound"_f, type_index{
typeid (RANGE_TYPE)});
1093 static const auto kException_ = BadFormatException{
"Range needs LowerBound and UpperBound"sv};
1096 if (not m.ContainsKey (lowerBoundLabel)) [[unlikely]] {
1097 DbgTrace (
"Range ('{}') element needs LowerBound"_f, type_index{
typeid (RANGE_TYPE)});
1098 static const auto kException_ = BadFormatException{
"Range needs 'LowerBound' element"sv};
1101 if (not m.ContainsKey (upperBoundLabel)) [[unlikely]] {
1102 DbgTrace (
"Range ('{}') element needs UpperBound"_f, type_index{
typeid (RANGE_TYPE)});
1103 static const auto kException_ = BadFormatException{
"Range needs 'UpperBound' element"sv};
1106 using value_type =
typename RANGE_TYPE::value_type;
1107 ToObjectMapperType<value_type> valueMapper{mapper.ToObjectMapper<value_type> ()};
1108 value_type from{mapper.ToObject<value_type> (valueMapper, *m.Lookup (lowerBoundLabel))};
1109 value_type to{mapper.ToObject<value_type> (valueMapper, *m.Lookup (upperBoundLabel))};
1110 *intoObjOfTypeT = CheckedConverter_Range<RANGE_TYPE> (from, to);
1113 return TypeMappingDetails{fromObjectMapper, toObjectMapper,
typeid (RANGE_TYPE)};
1115 template <
typename CLASS>
1116 ObjectVariantMapper::TypeMappingDetails
1117 ObjectVariantMapper::MakeCommonSerializer_ForClassObject_ (
const type_index& forTypeInfo, [[maybe_unused]]
size_t sizeofObj,
1118 const Traversal::Iterable<StructFieldInfo>& fields,
1119 const ClassMapperOptions<CLASS>& options)
1121 using namespace Characters::Literals;
1125 Containers::MultiSet<StructFieldMetaInfo> t;
1126 for (
const auto& i : fields) {
1127 if (i.fFieldMetaInfo_) {
1128 t.Add (*i.fFieldMetaInfo_);
1134 Containers::MultiSet<StructFieldMetaInfo> t;
1135 for (
const auto& i : fields) {
1136 if (i.fFieldMetaInfo_) {
1137 t.Add (*i.fFieldMetaInfo_);
1140 for (
const auto& i : t) {
1141 [[maybe_unused]]
bool alreadyInListOfFields = not(i.fCount == 1);
1146 FromObjectMapperType<CLASS> fromObjectMapper = [fields, options] (
const ObjectVariantMapper& mapper,
const CLASS* fromObjOfTypeT) -> VariantValue {
1147#if Stroika_Foundation_DataExchange_ObjectVariantMapper_USE_NOISY_TRACE_IN_THIS_MODULE_
1148 Debug::TraceContextBumper ctx{
"ObjectVariantMapper::TypeMappingDetails::{}::FromObjectMapper"};
1151#if qStroika_Foundation_DataExchange_ObjectVariantMapper_Activities
1152 auto decodingClassActivity =
1153 Execution::LazyEvalActivity{[&] () -> String {
return "Encoding {:.50}"_f(type_index{
typeid (CLASS)}); }};
1154 Execution::DeclareActivity da{&decodingClassActivity};
1156 Mapping<String, VariantValue> m;
1157 if (options.fBeforeFrom) [[unlikely]] {
1158 m = options.fBeforeFrom (mapper, fromObjOfTypeT).template As<Mapping<String, VariantValue>> ();
1160 for (
const auto& i : fields) {
1161#if Stroika_Foundation_DataExchange_ObjectVariantMapper_USE_NOISY_TRACE_IN_THIS_MODULE_
1162 DbgTrace (
"fieldname = {}, offset={}"_f, i.fSerializedFieldName_, i.fFieldMetaInfo_);
1164 VariantValue vv = [&] () {
1165 const byte* b = i.fFieldMetaInfo_ ? i.fFieldMetaInfo_->GetAddressOfMember (fromObjOfTypeT)
1166 :
reinterpret_cast<const byte*
> (fromObjOfTypeT);
1167 if (i.fOverrideTypeMapper_) [[unlikely]] {
1168 return i.fOverrideTypeMapper_->GetGenericFromObjectMapper () (mapper, b);
1171 Require (i.fFieldMetaInfo_);
1172 return mapper.Lookup_ (i.fFieldMetaInfo_->GetTypeInfo ()).GetGenericFromObjectMapper () (mapper, b);
1175 if (not options.fOmitNullEntriesInFromObject or vv.GetType () != VariantValue::eNull) [[likely]] {
1176 m.Add (i.fSerializedFieldName_, vv);
1179 VariantValue result{m};
1180 if (options.fAfterFrom) [[unlikely]] {
1181 options.fAfterFrom (mapper, fromObjOfTypeT, &result);
1185 ToObjectMapperType<CLASS> toObjectMapper = [fields, options] (
const ObjectVariantMapper& mapper,
const VariantValue& d,
1186 CLASS* intoObjOfTypeT) ->
void {
1187#if Stroika_Foundation_DataExchange_ObjectVariantMapper_USE_NOISY_TRACE_IN_THIS_MODULE_
1188 Debug::TraceContextBumper ctx{
"ObjectVariantMapper::TypeMappingDetails::{}::ToObjectMapper"};
1191#if qStroika_Foundation_DataExchange_ObjectVariantMapper_Activities
1192 auto decodingClassActivity =
1193 Execution::LazyEvalActivity{[&] () -> String {
return "Decoding {:.100} into class {}"_f(d, type_index{
typeid (CLASS)}); }};
1194 Execution::DeclareActivity da{&decodingClassActivity};
1196 if (options.fBeforeTo) {
1197 options.fBeforeTo (mapper, d, intoObjOfTypeT);
1199 Mapping<String, VariantValue> m = d.As<Mapping<String, VariantValue>> ();
1200 for (
const auto& i : fields) {
1201#if qStroika_Foundation_DataExchange_ObjectVariantMapper_Activities
1202 auto decodingFieldActivity =
1203 Execution::LazyEvalActivity{[&] () -> String {
return "Decoding field {}"_f(i.fSerializedFieldName_); }};
1204 [[maybe_unused]] Execution::DeclareActivity daf{&decodingFieldActivity};
1206 optional<VariantValue> o = m.Lookup (i.fSerializedFieldName_);
1207#if Stroika_Foundation_DataExchange_ObjectVariantMapper_USE_NOISY_TRACE_IN_THIS_MODULE_
1208 DbgTrace (
"fieldname = {}, offset={}, present={}"_f, i.fSerializedFieldName_, i.fFieldMetaInfo_, o.has_value ());
1211 byte* b = i.fFieldMetaInfo_ ? i.fFieldMetaInfo_->GetAddressOfMember (intoObjOfTypeT) :
reinterpret_cast<byte*
> (intoObjOfTypeT);
1212 if (i.fOverrideTypeMapper_) {
1213 i.fOverrideTypeMapper_->GetGenericToObjectMapper () (mapper, *o, b);
1216 Require (i.fFieldMetaInfo_);
1217 mapper.Lookup_ (i.fFieldMetaInfo_->GetTypeInfo ()).GetGenericToObjectMapper () (mapper, *o, b);
1221 if (options.fAfterTo) {
1222 options.fAfterTo (mapper, d, intoObjOfTypeT);
1225 return TypeMappingDetails{fromObjectMapper, toObjectMapper, forTypeInfo};
1227 template <
typename CLASS>
1228 inline ObjectVariantMapper::TypeMappingDetails
1229 ObjectVariantMapper::MakeCommonSerializer_ForClassObject_and_check_ (
const type_index& forTypeInfo, [[maybe_unused]]
size_t sizeofObj,
1230 const Traversal::Iterable<StructFieldInfo>& fields,
1237 for (
const auto& i : fields) {
1238 Require (i.fOverrideTypeMapper_ or i.fFieldMetaInfo_);
1239 if (not i.fOverrideTypeMapper_) {
1240 Assert (i.fFieldMetaInfo_);
1241 if (use2Validate !=
nullptr) {
1242 (void)use2Validate->Lookup_ (i.fFieldMetaInfo_->GetTypeInfo ());
1247 return MakeCommonSerializer_ForClassObject_<CLASS> (forTypeInfo, sizeofObj, fields, options);
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
#define RequireNotNull(p)
#define WeakAssert(c)
A WeakAssert() is for things that aren't guaranteed to be true, but are overwhelmingly likely to be t...
String is like std::u32string, except it is much easier to use, often much more space efficient,...
nonvirtual CONTAINER_OF_Key_T As() const
A generalization of a vector: a container whose elements are keyed by the natural numbers.
nonvirtual void Append(ArgByValueType< value_type > item)
ObjectVariantMapper can be used to map C++ types to and from variant-union types, which can be transp...
nonvirtual void AddClass(const Traversal::Iterable< StructFieldInfo > &fieldDescriptions, const ClassMapperOptions< CLASS > &mapperOptions={})
function< VariantValue(const ObjectVariantMapper &mapper, const T *objOfType)> FromObjectMapperType
static TypeMappingDetails MakeCommonSerializer_WithAdder()
nonvirtual void AddCommonType(ARGS &&... args)
nonvirtual void AddSubClass(const Traversal::Iterable< StructFieldInfo > &fieldDescriptions, const ClassMapperOptions< CLASS > &mapperOptions={})
Like @AddClass<> - adding a new class based on parameters - but based on the argument baseClass.
nonvirtual ToObjectMapperType< T > ToObjectMapper() const
static TypeMappingDetails MakeCommonSerializer_MappingWithStringishKey()
nonvirtual void operator+=(const TypeMappingDetails &rhs)
static TypeMappingDetails MakeClassSerializer(const Traversal::Iterable< StructFieldInfo > &fieldDescriptions, const ClassMapperOptions< T > &options={})
nonvirtual VariantValue FromObject(const T &from) const
static TypeMappingDetails MakeCommonSerializer_MappingAsArrayOfKeyValuePairs()
nonvirtual TypesRegistry GetTypeMappingRegistry() const
nonvirtual FromObjectMapperType< T > FromObjectMapper() const
nonvirtual optional< T > ToObjectQuietly(const VariantValue &v) const
nonvirtual T ToObject(const VariantValue &v) const
function< void(const ObjectVariantMapper &mapper, const VariantValue &d, T *into)> ToObjectMapperType
ToObjectMapperType< void > ToGenericObjectMapperType
nonvirtual void Add(const TypeMappingDetails &s)
nonvirtual void SetTypeMappingRegistry(const TypesRegistry &s)
FromObjectMapperType< void > FromGenericObjectMapperType
Simple variant-value (case variant union) object, with (variant) basic types analogous to a value in ...
static const TimeOfDay kMin
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
nonvirtual bool empty() const
Returns true iff size() == 0.
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...
utility for generic code that wishes to add something to a somewhat arbitrary container,...
StructFieldInfo(const String &serializedFieldName, const StructFieldMetaInfo &fieldMetaInfo)
static ToObjectMapperType< T > ToObjectMapper(const ToGenericObjectMapperType &toObjectMapper)
static FromObjectMapperType< T > FromObjectMapper(const FromGenericObjectMapperType &fromObjectMapper)
TypeMappingDetails()=delete