Allow serializing tuples

This commit is contained in:
Martchus 2017-10-29 22:10:50 +01:00
parent 5e95127185
commit d849144504
2 changed files with 49 additions and 2 deletions

View File

@ -16,6 +16,7 @@
#include <rapidjson/writer.h>
#include <string>
#include <tuple>
#include "./errorhandling.h"
@ -133,6 +134,36 @@ void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAP
value.PushBack(array, allocator);
}
namespace Detail {
template <class Tuple, std::size_t N> struct TupleHelper {
static void push(const Tuple &tuple, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
{
TupleHelper<Tuple, N - 1>::push(tuple, value, allocator);
Reflector::push(std::get<N - 1>(tuple), value, allocator);
}
};
template <class Tuple> struct TupleHelper<Tuple, 1> {
static void push(const Tuple &tuple, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
{
Reflector::push(std::get<0>(tuple), value, allocator);
}
};
} // namespace Detail
/*!
* \brief Pushes the specified tuple to the specified array.
*/
template <typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::tuple>>...>
void push(const Type &reflectable, RAPIDJSON_NAMESPACE::Value::Array &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
{
RAPIDJSON_NAMESPACE::Value arrayValue(RAPIDJSON_NAMESPACE::kArrayType);
RAPIDJSON_NAMESPACE::Value::Array array(arrayValue.GetArray());
array.Reserve(std::tuple_size<Type>::value, allocator);
Detail::TupleHelper<Type, std::tuple_size<Type>::value>::push(reflectable, array, allocator);
value.PushBack(array, allocator);
}
/*!
* \brief Pushes the specified \a reflectable which has a custom type as member to the specified object.
*/
@ -232,6 +263,20 @@ void push(
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), array, allocator);
}
/*!
* \brief Pushes the specified tuple as member to the specified object.
*/
template <typename Type, Traits::EnableIf<Traits::IsSpecializationOf<Type, std::tuple>>...>
void push(
const Type &reflectable, const char *name, RAPIDJSON_NAMESPACE::Value::Object &value, RAPIDJSON_NAMESPACE::Document::AllocatorType &allocator)
{
RAPIDJSON_NAMESPACE::Value arrayValue(RAPIDJSON_NAMESPACE::kArrayType);
RAPIDJSON_NAMESPACE::Value::Array array(arrayValue.GetArray());
array.Reserve(std::tuple_size<Type>::value, allocator);
Detail::TupleHelper<Type, std::tuple_size<Type>::value>::push(reflectable, array, allocator);
value.AddMember(RAPIDJSON_NAMESPACE::StringRef(name), array, allocator);
}
/*!
* \brief Pushes the \a reflectable which has a custom type to the specified array.
*/

View File

@ -16,6 +16,7 @@ using TestUtilities::operator<<; // must be visible prior to the call site
#include <iostream>
#include <string>
#include <tuple>
#include <vector>
using namespace std;
@ -208,6 +209,7 @@ void JsonReflectorTests::testSerializePrimitives()
Reflector::push<vector<const char *>>({ "foo1", "bar1" }, array, alloc);
Reflector::push<list<const char *>>({ "foo2", "bar2" }, array, alloc);
Reflector::push<initializer_list<const char *>>({ "foo3", "bar3" }, array, alloc);
Reflector::push<tuple<int, double>>(make_tuple(2, 413.0), array, alloc);
// boolean
Reflector::push<bool>(true, array, alloc);
Reflector::push<bool>(false, array, alloc);
@ -215,8 +217,8 @@ void JsonReflectorTests::testSerializePrimitives()
StringBuffer strbuf;
Writer<StringBuffer> jsonWriter(strbuf);
doc.Accept(jsonWriter);
CPPUNIT_ASSERT_EQUAL(
"[\"foo\",\"bar\",25,12.5,1,1,2,[\"foo1\",\"bar1\"],[\"foo2\",\"bar2\"],[\"foo3\",\"bar3\"],true,false]"s, string(strbuf.GetString()));
CPPUNIT_ASSERT_EQUAL("[\"foo\",\"bar\",25,12.5,1,1,2,[\"foo1\",\"bar1\"],[\"foo2\",\"bar2\"],[\"foo3\",\"bar3\"],[2,413.0],true,false]"s,
string(strbuf.GetString()));
}
/*!