Allow serializing enums

Note that deserializing is not so simple because
we would need to check whether the integer actually
is an item of the expected enumeration type.
This commit is contained in:
Martchus 2017-10-29 21:31:23 +01:00
parent e1dca1d1a2
commit ae3d8030b6
3 changed files with 44 additions and 9 deletions

View File

@ -23,7 +23,7 @@ namespace Reflector {
// define functions to "push" values to a RapidJSON array or object
template <typename Type,
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>, std::is_enum<Type>,
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
{
@ -35,7 +35,7 @@ void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Object &value, RA
// define functions to "pull" values from a RapidJSON array or object
template <typename Type,
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>, std::is_enum<Type>,
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
void pull(
Type &reflectable, RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ValueIterator &value, JsonDeserializationErrors *errors)
@ -46,7 +46,7 @@ void pull(
}
template <typename Type,
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>, std::is_enum<Type>,
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
void pull(Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value,
JsonDeserializationErrors *errors)

View File

@ -55,7 +55,7 @@ namespace Reflector {
* \brief Pushes the \a reflectable which has a custom type to the specified array.
*/
template <typename Type,
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>, std::is_enum<Type>,
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
@ -64,7 +64,7 @@ void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAP
* \remarks The definition of this function must be provided by the code generator or Boost.Hana.
*/
template <typename Type,
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>, std::is_enum<Type>,
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator);
@ -77,6 +77,15 @@ inline void push(Type reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAP
value.PushBack(reflectable, allocator);
}
/*!
* \brief Pushes the specified enumeration item to the specified array.
*/
template <typename Type, Traits::EnableIfAny<std::is_enum<Type>>...>
inline void push(Type reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
{
value.PushBack(static_cast<typename std::underlying_type<Type>::type>(reflectable), allocator);
}
/*!
* \brief Pushes the specified C-string to the specified array.
*/
@ -147,6 +156,16 @@ inline void push(
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), reflectable, allocator);
}
/*!
* \brief Pushes the specified enumeration item as member to the specified object.
*/
template <typename Type, Traits::EnableIfAny<std::is_enum<Type>>...>
inline void push(
Type reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
{
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), static_cast<typename std::underlying_type<Type>::type>(reflectable), allocator);
}
/*!
* \brief Pushes the specified C-string as member to the specified object.
*/
@ -215,7 +234,7 @@ void push(
* \brief Pushes the \a reflectable which has a custom type to the specified array.
*/
template <typename Type,
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>, std::is_enum<Type>,
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
{
@ -231,7 +250,7 @@ void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAP
* \brief Pulls the \a reflectable which has a custom type from the specified value.
*/
template <typename Type,
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>, std::is_enum<Type>,
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
void pull(
Type &reflectable, RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ValueIterator &value, JsonDeserializationErrors *errors);
@ -241,7 +260,7 @@ void pull(
* \remarks The definition of this function must be provided by the code generator or Boost.Hana.
*/
template <typename Type,
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>,
Traits::DisableIfAny<std::is_integral<Type>, std::is_floating_point<Type>, std::is_pointer<Type>, std::is_enum<Type>,
Traits::All<Traits::IsIteratable<Type>, Traits::Not<Traits::IsSpecializationOf<Type, std::basic_string>>>>...>
void pull(Type &reflectable, const RAPIDJSON_NAMESPACE::GenericValue<RAPIDJSON_NAMESPACE::UTF8<char>>::ConstObject &value,
JsonDeserializationErrors *errors);

View File

@ -48,6 +48,18 @@ struct NestingArray : public JsonSerializable<NestingArray> {
vector<TestObject> testObjects;
};
enum SomeEnum {
SomeEnumItem1,
SomeEnumItem2,
SomeEnumItem3,
};
enum class SomeEnumClass {
Item1,
Item2,
Item3,
};
// pretend serialization code for structs has been generated
namespace ReflectiveRapidJSON {
namespace Reflector {
@ -188,6 +200,10 @@ void JsonReflectorTests::testSerializePrimitives()
// number
Reflector::push<int>(25, array, alloc);
Reflector::push<double>(12.5, array, alloc);
// enum
Reflector::push<SomeEnum>(SomeEnumItem2, array, alloc);
Reflector::push<SomeEnumClass>(SomeEnumClass::Item2, array, alloc);
Reflector::push<SomeEnumClass>(SomeEnumClass::Item3, array, alloc);
// array
Reflector::push<vector<const char *>>({ "foo1", "bar1" }, array, alloc);
Reflector::push<list<const char *>>({ "foo2", "bar2" }, array, alloc);
@ -200,7 +216,7 @@ void JsonReflectorTests::testSerializePrimitives()
Writer<StringBuffer> jsonWriter(strbuf);
doc.Accept(jsonWriter);
CPPUNIT_ASSERT_EQUAL(
"[\"foo\",\"bar\",25,12.5,[\"foo1\",\"bar1\"],[\"foo2\",\"bar2\"],[\"foo3\",\"bar3\"],true,false]"s, string(strbuf.GetString()));
"[\"foo\",\"bar\",25,12.5,1,1,2,[\"foo1\",\"bar1\"],[\"foo2\",\"bar2\"],[\"foo3\",\"bar3\"],true,false]"s, string(strbuf.GetString()));
}
/*!