Allow to teat custom types as std::map/std::set

This commit is contained in:
Martchus 2018-10-29 23:21:07 +01:00
parent 98b25c813e
commit f77229471a
3 changed files with 55 additions and 6 deletions

View File

@ -81,6 +81,8 @@ The following table shows the mapping of supported C++ types to supported JSON t
is currently not supported.
* 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`.
* 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.

View File

@ -6,6 +6,15 @@
using namespace std;
using namespace ReflectiveRapidJSON;
// treat some types differently to test Treat... traits
struct Foo {
};
struct Bar {
};
REFLECTIVE_RAPIDJSON_TREAT_AS_MAP_OR_HASH(Foo);
REFLECTIVE_RAPIDJSON_TREAT_AS_SET(Bar);
REFLECTIVE_RAPIDJSON_TREAT_AS_MULTI_SET(Foo);
// test traits
static_assert(IsArray<vector<int>>::value, "vector mapped to array");
static_assert(IsArray<list<int>>::value, "list mapped to array");
@ -13,9 +22,22 @@ static_assert(!IsArray<set<int>>::value, "set not considered an array");
static_assert(!IsArray<multiset<int>>::value, "multiset not considered an array");
static_assert(IsArrayOrSet<set<int>>::value, "set is array or set");
static_assert(IsArrayOrSet<multiset<int>>::value, "multiset is array or set");
static_assert(IsSet<unordered_set<int>>::value, "set");
static_assert(IsArrayOrSet<Foo>::value, "Foo is array or set via TreatAsMultiSet");
static_assert(IsArrayOrSet<Bar>::value, "Foo is array or set via TreatAsSet");
static_assert(!IsArrayOrSet<string>::value, "string not mapped to array or set though it is iteratable");
static_assert(IsSet<set<int>>::value, "set mapped to set");
static_assert(IsSet<unordered_set<int>>::value, "unordered_set mapped to set");
static_assert(IsSet<Bar>::value, "Bar mapped to set via TreatAsSet");
static_assert(!IsSet<string>::value, "string not mapped to set");
static_assert(IsMultiSet<unordered_multiset<int>>::value, "multiset");
static_assert(IsMultiSet<Foo>::value, "Foo mapped to multiset via TreatAsMultiSet");
static_assert(!IsMultiSet<string>::value, "string not mapped to multiset");
static_assert(!IsArray<string>::value, "string not mapped to array though it is iteratable");
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(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");
static_assert(!IsIteratableExceptString<const std::string>::value, "string not iteratable");

View File

@ -11,15 +11,40 @@
namespace ReflectiveRapidJSON {
// define structs and macros to allow treating custom data types as std::map, std::set, ...
/// \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 TreatAsSet class allows treating custom classes as std::set or std::unordered_set.
template <typename T> struct TreatAsSet : public Traits::Bool<false> {
};
/// \brief \brief The TreatAsMultiSet class allows treating custom classes as std::multiset or std::unordered_multiset.
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_SET(T) \
template <> struct TreatAsSet<T> : public Traits::Bool<true> { \
}
#define REFLECTIVE_RAPIDJSON_TREAT_AS_MULTI_SET(T) \
template <> struct TreatAsMultiSet<T> : public Traits::Bool<true> { \
}
// define traits to check for arrays, sets and maps
template <typename Type>
using IsMapOrHash = Traits::Any<Traits::IsSpecializationOf<Type, std::map>, Traits::IsSpecializationOf<Type, std::unordered_map>>;
template <typename Type> using IsSet = Traits::Any<Traits::IsSpecializationOf<Type, std::set>, Traits::IsSpecializationOf<Type, std::unordered_set>>;
using IsMapOrHash
= Traits::Any<Traits::IsSpecializationOf<Type, std::map>, Traits::IsSpecializationOf<Type, std::unordered_map>, TreatAsMapOrHash<Type>>;
template <typename Type>
using IsMultiSet = Traits::Any<Traits::IsSpecializationOf<Type, std::multiset>, Traits::IsSpecializationOf<Type, std::unordered_multiset>>;
using IsSet = Traits::Any<Traits::IsSpecializationOf<Type, std::set>, Traits::IsSpecializationOf<Type, std::unordered_set>, TreatAsSet<Type>>;
template <typename Type>
using IsArrayOrSet
= Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>, Traits::Not<IsMapOrHash<Type>>>;
using IsMultiSet
= Traits::Any<Traits::IsSpecializationOf<Type, std::multiset>, Traits::IsSpecializationOf<Type, std::unordered_multiset>, TreatAsMultiSet<Type>>;
template <typename Type>
using IsArrayOrSet = Traits::Any<Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>,
Traits::Not<IsMapOrHash<Type>>, Traits::Not<IsMultiMapOrHash<Type>>>,
TreatAsSet<Type>, TreatAsMultiSet<Type>>;
template <typename Type>
using IsArray = Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>,
Traits::Not<IsMapOrHash<Type>>, Traits::Not<IsSet<Type>>, Traits::Not<IsMultiSet<Type>>>;