Add experimental support for multimap
Makes sense for binary (de)serialization, not sure about JSON (de)serialization
This commit is contained in:
parent
f77229471a
commit
d64174c000
|
@ -82,7 +82,9 @@ The following table shows the mapping of supported C++ types to supported JSON t
|
|||
* custom types must provide a default constructor.
|
||||
* constant member variables are skipped.
|
||||
* It is possible to treat custom types as set/map using the macro `REFLECTIVE_RAPIDJSON_TREAT_AS_MAP_OR_HASH`,
|
||||
`REFLECTIVE_RAPIDJSON_TREAT_AS_SET` or `REFLECTIVE_RAPIDJSON_TREAT_AS_MULTI_SET`.
|
||||
`REFLECTIVE_RAPIDJSON_TREAT_AS_MULTI_MAP_OR_HASH`, `REFLECTIVE_RAPIDJSON_TREAT_AS_SET` or
|
||||
`REFLECTIVE_RAPIDJSON_TREAT_AS_MULTI_SET`.
|
||||
* The key type of the `std::map`, `std::unordered_map` must be `std::string`.
|
||||
* For custom (de)serialization, see the section below.
|
||||
* The binary (de)serializer supports approximately the same C++ types but obviously maps them to a platform
|
||||
independent binary representation rather than a JSON type.
|
||||
|
|
|
@ -58,10 +58,10 @@ public:
|
|||
template <typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::unique_ptr>> * = nullptr> void read(Type &pair);
|
||||
template <typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::shared_ptr>> * = nullptr> void read(Type &pair);
|
||||
template <typename Type, Traits::EnableIf<IsArray<Type>, Traits::IsResizable<Type>> * = nullptr> void read(Type &iteratable);
|
||||
template <typename Type, Traits::EnableIf<IsMapOrHash<Type>> * = nullptr> void read(Type &iteratable);
|
||||
template <typename Type, Traits::EnableIfAny<IsMapOrHash<Type>, IsMultiMapOrHash<Type>> * = nullptr> void read(Type &iteratable);
|
||||
template <typename Type,
|
||||
Traits::EnableIf<IsIteratableExceptString<Type>, Traits::None<IsMapOrHash<Type>, Traits::All<IsArray<Type>, Traits::IsResizable<Type>>>>
|
||||
* = nullptr>
|
||||
Traits::EnableIf<IsIteratableExceptString<Type>,
|
||||
Traits::None<IsMapOrHash<Type>, IsMultiMapOrHash<Type>, Traits::All<IsArray<Type>, Traits::IsResizable<Type>>>> * = nullptr>
|
||||
void read(Type &iteratable);
|
||||
template <typename Type, Traits::EnableIf<std::is_enum<Type>> * = nullptr> void read(Type &customType);
|
||||
template <typename Type, Traits::EnableIf<IsCustomType<Type>> * = nullptr> void read(Type &customType);
|
||||
|
@ -138,7 +138,7 @@ template <typename Type, Traits::EnableIf<IsArray<Type>, Traits::IsResizable<Typ
|
|||
}
|
||||
}
|
||||
|
||||
template <typename Type, Traits::EnableIf<IsMapOrHash<Type>> *> void BinaryDeserializer::read(Type &iteratable)
|
||||
template <typename Type, Traits::EnableIfAny<IsMapOrHash<Type>, IsMultiMapOrHash<Type>> *> void BinaryDeserializer::read(Type &iteratable)
|
||||
{
|
||||
const auto size = readVariableLengthUIntBE();
|
||||
for (size_t i = 0; i != size; ++i) {
|
||||
|
@ -149,7 +149,8 @@ template <typename Type, Traits::EnableIf<IsMapOrHash<Type>> *> void BinaryDeser
|
|||
}
|
||||
|
||||
template <typename Type,
|
||||
Traits::EnableIf<IsIteratableExceptString<Type>, Traits::None<IsMapOrHash<Type>, Traits::All<IsArray<Type>, Traits::IsResizable<Type>>>> *>
|
||||
Traits::EnableIf<IsIteratableExceptString<Type>,
|
||||
Traits::None<IsMapOrHash<Type>, IsMultiMapOrHash<Type>, Traits::All<IsArray<Type>, Traits::IsResizable<Type>>>> *>
|
||||
void BinaryDeserializer::read(Type &iteratable)
|
||||
{
|
||||
const auto size = readVariableLengthUIntBE();
|
||||
|
|
|
@ -211,9 +211,10 @@ void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_
|
|||
}
|
||||
|
||||
/*!
|
||||
* \brief Pushes the specified map (std::map, std::unordered_map) to the specified value.
|
||||
* \brief Pushes the specified map (std::map, std::unordered_map) or multimap (std::multimap, std::unordered_multimap) to the
|
||||
* specified value.
|
||||
*/
|
||||
template <typename Type, Traits::EnableIf<IsMapOrHash<Type>> * = nullptr>
|
||||
template <typename Type, Traits::EnableIfAny<IsMapOrHash<Type>, IsMultiMapOrHash<Type>> * = nullptr>
|
||||
void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
|
||||
{
|
||||
value.SetObject();
|
||||
|
@ -371,6 +372,12 @@ void pull(Type &reflectable, rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<c
|
|||
template <typename Type, Traits::EnableIf<IsMapOrHash<Type>> * = nullptr>
|
||||
void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
|
||||
|
||||
/*!
|
||||
* \brief Pulls the specified \a reflectable which is a multimap from the specified value which is checked to contain an object.
|
||||
*/
|
||||
template <typename Type, Traits::EnableIf<IsMultiMapOrHash<Type>> * = nullptr>
|
||||
void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors);
|
||||
|
||||
/*!
|
||||
* \brief Pulls the specified \a reflectable which is a tuple from the specified value which is checked to contain an array.
|
||||
*/
|
||||
|
@ -628,6 +635,25 @@ void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Pulls the specified \a reflectable which is a multimap from the specified value which is checked to contain an object.
|
||||
*/
|
||||
template <typename Type, Traits::EnableIf<IsMultiMapOrHash<Type>> *>
|
||||
void pull(Type &reflectable, const rapidjson::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>> &value, JsonDeserializationErrors *errors)
|
||||
{
|
||||
if (!value.IsObject()) {
|
||||
if (errors) {
|
||||
errors->reportTypeMismatch<Type>(value.GetType());
|
||||
}
|
||||
return;
|
||||
}
|
||||
auto obj = value.GetObject();
|
||||
for (auto i = obj.MemberBegin(), end = obj.MemberEnd(); i != end; ++i) {
|
||||
auto insertedIterator = reflectable.insert(typename Type::value_type(i->name.GetString(), typename Type::mapped_type()));
|
||||
pull(insertedIterator->second, i->value, errors);
|
||||
}
|
||||
}
|
||||
|
||||
namespace Detail {
|
||||
|
||||
/*!
|
||||
|
@ -762,7 +788,7 @@ void pull(Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_N
|
|||
/*!
|
||||
* \brief Serializes the specified \a reflectable which has a custom type or can be mapped to and object.
|
||||
*/
|
||||
template <typename Type, Traits::EnableIfAny<IsJsonSerializable<Type>, IsMapOrHash<Type>> * = nullptr>
|
||||
template <typename Type, Traits::EnableIfAny<IsJsonSerializable<Type>, IsMapOrHash<Type>, IsMultiMapOrHash<Type>> * = nullptr>
|
||||
RAPIDJSON_NAMESPACE::StringBuffer toJson(const Type &reflectable)
|
||||
{
|
||||
RAPIDJSON_NAMESPACE::Document document(RAPIDJSON_NAMESPACE::kObjectType);
|
||||
|
@ -819,7 +845,7 @@ template <typename Type, Traits::EnableIf<IsArray<Type>> * = nullptr> RAPIDJSON_
|
|||
/*!
|
||||
* \brief Deserializes the specified JSON to \tparam Type which is a custom type or can be mapped to an object.
|
||||
*/
|
||||
template <typename Type, Traits::EnableIfAny<IsJsonSerializable<Type>, IsMapOrHash<Type>> * = nullptr>
|
||||
template <typename Type, Traits::EnableIfAny<IsJsonSerializable<Type>, IsMapOrHash<Type>, IsMultiMapOrHash<Type>> * = nullptr>
|
||||
Type fromJson(const char *json, std::size_t jsonSize, JsonDeserializationErrors *errors = nullptr)
|
||||
{
|
||||
RAPIDJSON_NAMESPACE::Document doc(parseJsonDocFromString(json, jsonSize));
|
||||
|
|
|
@ -12,6 +12,7 @@ struct Foo {
|
|||
struct Bar {
|
||||
};
|
||||
REFLECTIVE_RAPIDJSON_TREAT_AS_MAP_OR_HASH(Foo);
|
||||
REFLECTIVE_RAPIDJSON_TREAT_AS_MULTI_MAP_OR_HASH(Foo);
|
||||
REFLECTIVE_RAPIDJSON_TREAT_AS_SET(Bar);
|
||||
REFLECTIVE_RAPIDJSON_TREAT_AS_MULTI_SET(Foo);
|
||||
|
||||
|
@ -37,6 +38,10 @@ static_assert(IsMapOrHash<map<string, int>>::value, "map mapped to object");
|
|||
static_assert(IsMapOrHash<unordered_map<string, int>>::value, "hash mapped to object");
|
||||
static_assert(!IsMapOrHash<vector<int>>::value, "vector not mapped to object");
|
||||
static_assert(IsMapOrHash<Foo>::value, "Foo mapped to object via TreatAsMapOrHash");
|
||||
static_assert(IsMultiMapOrHash<multimap<string, int>>::value, "multimap mapped to object");
|
||||
static_assert(IsMultiMapOrHash<unordered_multimap<string, int>>::value, "unordered multimap mapped to object");
|
||||
static_assert(!IsMultiMapOrHash<vector<int>>::value, "vector not mapped to object");
|
||||
static_assert(IsMultiMapOrHash<Foo>::value, "Foo mapped to object via TreatAsMultiMapOrHash");
|
||||
static_assert(IsIteratableExceptString<std::vector<int>>::value, "vector is iteratable");
|
||||
static_assert(!IsIteratableExceptString<std::string>::value, "string not iteratable");
|
||||
static_assert(!IsIteratableExceptString<std::wstring>::value, "wstring not iteratable");
|
||||
|
|
|
@ -15,6 +15,9 @@ namespace ReflectiveRapidJSON {
|
|||
/// \brief \brief The TreatAsMapOrHash class allows treating custom classes as std::map or std::unordered_map.
|
||||
template <typename T> struct TreatAsMapOrHash : public Traits::Bool<false> {
|
||||
};
|
||||
/// \brief \brief The TreatAsMultiMapOrHash class allows treating custom classes as std::multimap or std::unordered_multimap.
|
||||
template <typename T> struct TreatAsMultiMapOrHash : public Traits::Bool<false> {
|
||||
};
|
||||
/// \brief \brief The TreatAsSet class allows treating custom classes as std::set or std::unordered_set.
|
||||
template <typename T> struct TreatAsSet : public Traits::Bool<false> {
|
||||
};
|
||||
|
@ -25,6 +28,9 @@ template <typename T> struct TreatAsMultiSet : public Traits::Bool<false> {
|
|||
#define REFLECTIVE_RAPIDJSON_TREAT_AS_MAP_OR_HASH(T) \
|
||||
template <> struct TreatAsMapOrHash<T> : public Traits::Bool<true> { \
|
||||
}
|
||||
#define REFLECTIVE_RAPIDJSON_TREAT_AS_MULTI_MAP_OR_HASH(T) \
|
||||
template <> struct TreatAsMultiMapOrHash<T> : public Traits::Bool<true> { \
|
||||
}
|
||||
#define REFLECTIVE_RAPIDJSON_TREAT_AS_SET(T) \
|
||||
template <> struct TreatAsSet<T> : public Traits::Bool<true> { \
|
||||
}
|
||||
|
@ -37,6 +43,9 @@ template <typename Type>
|
|||
using IsMapOrHash
|
||||
= Traits::Any<Traits::IsSpecializationOf<Type, std::map>, Traits::IsSpecializationOf<Type, std::unordered_map>, TreatAsMapOrHash<Type>>;
|
||||
template <typename Type>
|
||||
using IsMultiMapOrHash = Traits::Any<Traits::IsSpecializationOf<Type, std::multimap>, Traits::IsSpecializationOf<Type, std::unordered_multimap>,
|
||||
TreatAsMultiMapOrHash<Type>>;
|
||||
template <typename Type>
|
||||
using IsSet = Traits::Any<Traits::IsSpecializationOf<Type, std::set>, Traits::IsSpecializationOf<Type, std::unordered_set>, TreatAsSet<Type>>;
|
||||
template <typename Type>
|
||||
using IsMultiSet
|
||||
|
|
Loading…
Reference in New Issue