48#if __has_include( <nfx/containers/PerfectHashMap.h>)
50# include <nfx/containers/PerfectHashMap.h>
52namespace nfx::serialization::json
57 template <
typename TKey,
typename TValue,
typename HashType, HashType Seed,
typename Hasher,
typename KeyEqual>
58 struct SerializationTraits<nfx::containers::PerfectHashMap<TKey, TValue, HashType, Seed, Hasher, KeyEqual>>
67 const Document& doc, nfx::containers::PerfectHashMap<TKey, TValue, HashType, Seed, Hasher, KeyEqual>& obj )
69 if( !doc.is<Array>(
"" ) )
71 throw std::runtime_error{
"Cannot deserialize non-array JSON value into PerfectHashMap" };
75 std::vector<std::pair<TKey, TValue>> items;
78 auto arrayOpt = doc.get<Array>(
"" );
79 if( arrayOpt.has_value() )
81 for(
const auto& pairDoc : arrayOpt.value() )
85 bool keyFound =
false;
87 if( pairDoc.contains(
"key" ) )
90 if constexpr( std::is_same_v<TKey, std::string> )
92 auto keyOpt = pairDoc.get<std::string>(
"key" );
99 else if constexpr( std::is_integral_v<TKey> && !std::is_same_v<TKey, bool> )
101 auto keyOpt = pairDoc.get<int64_t>(
"key" );
104 key =
static_cast<TKey
>( *keyOpt );
108 else if constexpr( std::is_floating_point_v<TKey> )
110 auto keyOpt = pairDoc.get<
double>(
"key" );
113 key =
static_cast<TKey
>( *keyOpt );
117 else if constexpr( std::is_same_v<TKey, bool> )
119 auto keyOpt = pairDoc.get<
bool>(
"key" );
130 bool valueFound =
false;
132 if( pairDoc.contains(
"value" ) )
135 if constexpr( std::is_same_v<TValue, std::string> )
137 auto valOpt = pairDoc.get<std::string>(
"value" );
144 else if constexpr( std::is_integral_v<TValue> && !std::is_same_v<TValue, bool> )
146 auto valOpt = pairDoc.get<int64_t>(
"value" );
149 value =
static_cast<TValue
>( *valOpt );
153 else if constexpr( std::is_floating_point_v<TValue> )
155 auto valOpt = pairDoc.get<
double>(
"value" );
158 value =
static_cast<TValue
>( *valOpt );
162 else if constexpr( std::is_same_v<TValue, bool> )
164 auto valOpt = pairDoc.get<
bool>(
"value" );
173 if( keyFound && valueFound )
175 items.emplace_back( std::move( key ), std::move( value ) );
180 obj = nfx::containers::PerfectHashMap<TKey, TValue, HashType, Seed, Hasher, KeyEqual>( std::move( items ) );
189 static void serialize(
190 const nfx::containers::PerfectHashMap<TKey, TValue, HashType, Seed, Hasher, KeyEqual>& obj,
191 nfx::json::Builder& builder )
193 builder.writeStartArray();
195 for(
auto it = obj.begin(); it != obj.end(); ++it )
197 const auto& pair = *it;
199 builder.writeStartObject();
202 builder.writeKey(
"key" );
203 Serializer<TKey>{}.serializeValue( pair.first, builder );
206 builder.writeKey(
"value" );
207 Serializer<TValue>{}.serializeValue( pair.second, builder );
209 builder.writeEndObject();
212 builder.writeEndArray();
223#if __has_include( <nfx/containers/FastHashMap.h>)
225# include <nfx/containers/FastHashMap.h>
227namespace nfx::serialization::json
232 template <
typename TKey,
typename TValue,
typename HashType, HashType Seed,
typename Hasher,
typename KeyEqual>
233 struct SerializationTraits<nfx::containers::FastHashMap<TKey, TValue, HashType, Seed, Hasher, KeyEqual>>
242 const Document& doc, nfx::containers::FastHashMap<TKey, TValue, HashType, Seed, Hasher, KeyEqual>& obj )
248 if( doc.is<Object>(
"" ) )
251 auto objectOpt = doc.get<Object>(
"" );
252 if( objectOpt.has_value() )
254 for(
const auto& [keyStr, valueDoc] : objectOpt.value() )
258 if constexpr( std::is_same_v<TKey, std::string> )
265 keyDoc.set(
"", keyStr );
266 Serializer<TKey> keySerializer;
267 keySerializer.deserializeValue( keyDoc, key );
272 Serializer<TValue> valueSerializer;
273 valueSerializer.deserializeValue( valueDoc, value );
274 obj.insertOrAssign( std::move( key ), std::move( value ) );
279 else if( doc.is<Array>(
"" ) )
282 auto arrayOpt = doc.get<Array>(
"" );
283 if( arrayOpt.has_value() )
285 for(
const auto& pairDoc : arrayOpt.value() )
289 bool keyFound =
false;
291 if( pairDoc.contains(
"key" ) )
294 if constexpr( std::is_same_v<TKey, std::string> )
296 auto keyOpt = pairDoc.get<std::string>(
"key" );
303 else if constexpr( std::is_integral_v<TKey> && !std::is_same_v<TKey, bool> )
305 auto keyOpt = pairDoc.get<int64_t>(
"key" );
308 key =
static_cast<TKey
>( *keyOpt );
312 else if constexpr( std::is_floating_point_v<TKey> )
314 auto keyOpt = pairDoc.get<
double>(
"key" );
317 key =
static_cast<TKey
>( *keyOpt );
321 else if constexpr( std::is_same_v<TKey, bool> )
323 auto keyOpt = pairDoc.get<
bool>(
"key" );
334 bool valueFound =
false;
336 if( pairDoc.contains(
"value" ) )
339 if constexpr( std::is_same_v<TValue, std::string> )
341 auto valOpt = pairDoc.get<std::string>(
"value" );
348 else if constexpr( std::is_integral_v<TValue> && !std::is_same_v<TValue, bool> )
350 auto valOpt = pairDoc.get<int64_t>(
"value" );
353 value =
static_cast<TValue
>( *valOpt );
357 else if constexpr( std::is_floating_point_v<TValue> )
359 auto valOpt = pairDoc.get<
double>(
"value" );
362 value =
static_cast<TValue
>( *valOpt );
366 else if constexpr( std::is_same_v<TValue, bool> )
368 auto valOpt = pairDoc.get<
bool>(
"value" );
377 if( keyFound && valueFound )
379 obj.insertOrAssign( std::move( key ), std::move( value ) );
386 throw std::runtime_error{
"Cannot deserialize JSON value into FastHashMap: must be object or array" };
396 static void serialize(
397 const nfx::containers::FastHashMap<TKey, TValue, HashType, Seed, Hasher, KeyEqual>& obj,
398 nfx::json::Builder& builder )
400 builder.writeStartArray();
402 for(
auto it = obj.begin(); it != obj.end(); ++it )
404 const auto& pair = *it;
406 builder.writeStartObject();
409 builder.writeKey(
"key" );
410 Serializer<TKey>{}.serializeValue( pair.first, builder );
413 builder.writeKey(
"value" );
414 Serializer<TValue>{}.serializeValue( pair.second, builder );
416 builder.writeEndObject();
419 builder.writeEndArray();
430#if __has_include( <nfx/containers/FastHashSet.h>)
432# include <nfx/containers/FastHashSet.h>
434namespace nfx::serialization::json
439 template <
typename TKey,
typename HashType, HashType Seed,
typename Hasher,
typename KeyEqual>
440 struct SerializationTraits<nfx::containers::FastHashSet<TKey, HashType, Seed, Hasher, KeyEqual>>
448 const Document& doc, nfx::containers::FastHashSet<TKey, HashType, Seed, Hasher, KeyEqual>& obj )
450 if( !doc.is<Array>(
"" ) )
452 throw std::runtime_error{
"Cannot deserialize non-array JSON value into FastHashSet" };
459 auto arrayOpt = doc.get<Array>(
"" );
460 if( arrayOpt.has_value() )
462 for(
const auto& itemDoc : arrayOpt.value() )
465 Serializer<TKey>{}.deserializeValue( itemDoc, item );
466 obj.insert( std::move( item ) );
477 static void serialize(
478 const nfx::containers::FastHashSet<TKey, HashType, Seed, Hasher, KeyEqual>& obj,
479 nfx::json::Builder& builder )
481 builder.writeStartArray();
483 for(
auto it = obj.begin(); it != obj.end(); ++it )
485 Serializer<TKey>{}.serializeValue( *it, builder );
488 builder.writeEndArray();
499#if __has_include( <nfx/containers/StackVector.h>)
501# include <nfx/containers/StackVector.h>
503namespace nfx::serialization::json
508 template <
typename T, std::
size_t N>
516 static void fromDocument(
const Document& doc, nfx::containers::StackVector<T, N>& obj )
518 if( !doc.is<Array>(
"" ) )
520 throw std::runtime_error{
"Cannot deserialize non-array JSON value into StackVector" };
527 auto arrayOpt = doc.get<Array>(
"" );
528 if( arrayOpt.has_value() )
530 for(
const auto& elementDoc : arrayOpt.value() )
534 Serializer<T> elementSerializer;
535 elementSerializer.deserializeValue( elementDoc, element );
537 obj.push_back( std::move( element ) );
548 static void serialize(
const nfx::containers::StackVector<T, N>& obj, nfx::json::Builder& builder )
550 builder.writeStartArray();
552 for(
const auto& element : obj )
554 Serializer<T>{}.serializeValue( element, builder );
557 builder.writeEndArray();
568#if __has_include( <nfx/containers/OrderedHashMap.h>)
570# include <nfx/containers/OrderedHashMap.h>
572namespace nfx::serialization::json
577 template <
typename TKey,
typename TValue,
typename HashType, HashType Seed,
typename Hasher,
typename KeyEqual>
578 struct SerializationTraits<nfx::containers::OrderedHashMap<TKey, TValue, HashType, Seed, Hasher, KeyEqual>>
587 const Document& doc, nfx::containers::OrderedHashMap<TKey, TValue, HashType, Seed, Hasher, KeyEqual>& obj )
589 if( !doc.is<Array>(
"" ) )
591 throw std::runtime_error{
"Cannot deserialize non-array JSON value into OrderedHashMap" };
597 auto arrayOpt = doc.get<Array>(
"" );
598 if( arrayOpt.has_value() )
600 for(
const auto& pairDoc : arrayOpt.value() )
604 bool keyFound =
false;
606 if( pairDoc.contains(
"key" ) )
609 if constexpr( std::is_same_v<TKey, std::string> )
611 auto keyOpt = pairDoc.get<std::string>(
"key" );
618 else if constexpr( std::is_integral_v<TKey> && !std::is_same_v<TKey, bool> )
620 auto keyOpt = pairDoc.get<int64_t>(
"key" );
623 key =
static_cast<TKey
>( *keyOpt );
627 else if constexpr( std::is_floating_point_v<TKey> )
629 auto keyOpt = pairDoc.get<
double>(
"key" );
632 key =
static_cast<TKey
>( *keyOpt );
636 else if constexpr( std::is_same_v<TKey, bool> )
638 auto keyOpt = pairDoc.get<
bool>(
"key" );
649 bool valueFound =
false;
651 if( pairDoc.contains(
"value" ) )
654 if constexpr( std::is_same_v<TValue, std::string> )
656 auto valOpt = pairDoc.get<std::string>(
"value" );
663 else if constexpr( std::is_integral_v<TValue> && !std::is_same_v<TValue, bool> )
665 auto valOpt = pairDoc.get<int64_t>(
"value" );
668 value =
static_cast<TValue
>( *valOpt );
672 else if constexpr( std::is_floating_point_v<TValue> )
674 auto valOpt = pairDoc.get<
double>(
"value" );
677 value =
static_cast<TValue
>( *valOpt );
681 else if constexpr( std::is_same_v<TValue, bool> )
683 auto valOpt = pairDoc.get<
bool>(
"value" );
692 if( keyFound && valueFound )
694 obj.insertOrAssign( std::move( key ), std::move( value ) );
706 static void serialize(
707 const nfx::containers::OrderedHashMap<TKey, TValue, HashType, Seed, Hasher, KeyEqual>& obj,
710 builder.writeStartArray();
712 for(
const auto& [key, value] : obj )
714 builder.writeStartObject();
715 builder.write(
"key", key );
716 builder.write(
"value", value );
717 builder.writeEndObject();
720 builder.writeEndArray();
731#if __has_include( <nfx/containers/OrderedHashSet.h>)
733# include <nfx/containers/OrderedHashSet.h>
735namespace nfx::serialization::json
740 template <
typename TKey,
typename HashType, HashType Seed,
typename Hasher,
typename KeyEqual>
741 struct SerializationTraits<nfx::containers::OrderedHashSet<TKey, HashType, Seed, Hasher, KeyEqual>>
750 const Document& doc, nfx::containers::OrderedHashSet<TKey, HashType, Seed, Hasher, KeyEqual>& obj )
752 if( !doc.is<Array>(
"" ) )
754 throw std::runtime_error{
"Cannot deserialize non-array JSON value into OrderedHashSet" };
760 auto arrayOpt = doc.get<Array>(
"" );
761 if( arrayOpt.has_value() )
763 for(
const auto& elementDoc : arrayOpt.value() )
767 bool elementFound =
false;
770 if constexpr( std::is_same_v<TKey, std::string> )
772 auto elemOpt = elementDoc.get<std::string>(
"" );
779 else if constexpr( std::is_integral_v<TKey> && !std::is_same_v<TKey, bool> )
781 auto elemOpt = elementDoc.get<int64_t>(
"" );
784 element =
static_cast<TKey
>( *elemOpt );
788 else if constexpr( std::is_floating_point_v<TKey> )
790 auto elemOpt = elementDoc.get<
double>(
"" );
793 element =
static_cast<TKey
>( *elemOpt );
797 else if constexpr( std::is_same_v<TKey, bool> )
799 auto elemOpt = elementDoc.get<
bool>(
"" );
809 obj.insert( std::move( element ) );
821 static void serialize(
822 const nfx::containers::OrderedHashSet<TKey, HashType, Seed, Hasher, KeyEqual>& obj, Builder& builder )
824 builder.writeStartArray();
826 for(
const auto& element : obj )
828 builder.write( element );
831 builder.writeEndArray();
842#if __has_include( <nfx/containers/StackHashMap.h>)
844# include <nfx/containers/StackHashMap.h>
846namespace nfx::serialization::json
851 template <
typename TKey,
typename TValue, std::
size_t N,
typename KeyEqual>
860 static void fromDocument(
const Document& doc, nfx::containers::StackHashMap<TKey, TValue, N, KeyEqual>& obj )
862 if( !doc.is<Array>(
"" ) )
864 throw std::runtime_error{
"Cannot deserialize non-array JSON value into StackHashMap" };
871 auto arrayOpt = doc.get<Array>(
"" );
872 if( arrayOpt.has_value() )
874 for(
const auto& pairDoc : arrayOpt.value() )
877 auto keyDoc = pairDoc.get<Document>(
"key" );
880 throw std::runtime_error{
"Missing 'key' field in StackHashMap array element" };
883 Serializer<TKey>{}.deserializeValue( *keyDoc, key );
886 auto valueDoc = pairDoc.get<Document>(
"value" );
889 throw std::runtime_error{
"Missing 'value' field in StackHashMap array element" };
892 Serializer<TValue>{}.deserializeValue( *valueDoc, value );
894 obj.insertOrAssign( std::move( key ), std::move( value ) );
905 static void serialize(
906 const nfx::containers::StackHashMap<TKey, TValue, N, KeyEqual>& obj, nfx::json::Builder& builder )
908 builder.writeStartArray();
910 obj.forEach( [&builder](
const TKey& key,
const TValue& value ) {
911 builder.writeStartObject();
914 builder.writeKey(
"key" );
915 Serializer<TKey>{}.serializeValue( key, builder );
918 builder.writeKey(
"value" );
919 Serializer<TValue>{}.serializeValue( value, builder );
921 builder.writeEndObject();
924 builder.writeEndArray();
935#if __has_include( <nfx/containers/StackHashSet.h>)
937# include <nfx/containers/StackHashSet.h>
939namespace nfx::serialization::json
944 template <
typename TKey, std::
size_t N,
typename KeyEqual>
952 static void fromDocument(
const Document& doc, nfx::containers::StackHashSet<TKey, N, KeyEqual>& obj )
954 if( !doc.is<Array>(
"" ) )
956 throw std::runtime_error{
"Cannot deserialize non-array JSON value into StackHashSet" };
963 auto arrayOpt = doc.get<Array>(
"" );
964 if( arrayOpt.has_value() )
966 for(
const auto& itemDoc : arrayOpt.value() )
969 Serializer<TKey>{}.deserializeValue( itemDoc, item );
970 obj.insert( std::move( item ) );
981 static void serialize(
982 const nfx::containers::StackHashSet<TKey, N, KeyEqual>& obj, nfx::json::Builder& builder )
984 builder.writeStartArray();
986 obj.forEach( [&builder](
const TKey& element ) { Serializer<TKey>{}.serializeValue( element, builder ); } );
988 builder.writeEndArray();
Templated JSON serializer with compile-time type mapping.
Serialization traits template (forward declaration).
static void fromDocument(const Document &doc, T &obj)
Convert Document to object (deserialization).