2017-03-07 09:32:29 +00:00
|
|
|
#pragma once
|
|
|
|
|
2017-03-25 23:58:11 +00:00
|
|
|
#include <macro_map.h>
|
2017-03-25 20:32:44 +00:00
|
|
|
#include <optional.h>
|
2017-02-23 08:47:07 +00:00
|
|
|
#include <rapidjson/document.h>
|
|
|
|
#include <rapidjson/prettywriter.h>
|
2017-03-25 20:32:44 +00:00
|
|
|
|
2017-06-14 04:00:51 +00:00
|
|
|
#include <memory>
|
2017-03-14 08:33:39 +00:00
|
|
|
#include <string>
|
2017-06-14 04:00:51 +00:00
|
|
|
#include <vector>
|
2017-02-23 08:47:07 +00:00
|
|
|
|
2017-03-14 08:33:39 +00:00
|
|
|
using std::experimental::nullopt;
|
2017-09-22 01:14:57 +00:00
|
|
|
using std::experimental::optional;
|
2017-03-01 08:36:11 +00:00
|
|
|
|
2017-03-07 09:32:29 +00:00
|
|
|
using Reader = rapidjson::GenericValue<rapidjson::UTF8<>>;
|
2017-03-27 04:04:48 +00:00
|
|
|
using Writer = rapidjson::Writer<rapidjson::StringBuffer>;
|
2017-05-12 06:08:15 +00:00
|
|
|
struct IndexFile;
|
2017-02-23 08:47:07 +00:00
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
#define REFLECT_MEMBER_START() \
|
|
|
|
if (!ReflectMemberStart(visitor, value)) \
|
|
|
|
return
|
|
|
|
#define REFLECT_MEMBER_START1(value) \
|
|
|
|
if (!ReflectMemberStart(visitor, value)) \
|
|
|
|
return
|
|
|
|
#define REFLECT_MEMBER_END() ReflectMemberEnd(visitor, value);
|
|
|
|
#define REFLECT_MEMBER_END1(value) ReflectMemberEnd(visitor, value);
|
|
|
|
#define REFLECT_MEMBER(name) ReflectMember(visitor, #name, value.name)
|
|
|
|
#define REFLECT_MEMBER2(name, value) ReflectMember(visitor, name, value)
|
|
|
|
|
|
|
|
#define MAKE_REFLECT_TYPE_PROXY(type, as_type) \
|
|
|
|
template <typename TVisitor> \
|
2017-03-25 22:13:19 +00:00
|
|
|
void Reflect(TVisitor& visitor, type& value) { \
|
2017-09-22 01:14:57 +00:00
|
|
|
auto value0 = static_cast<as_type>(value); \
|
|
|
|
Reflect(visitor, value0); \
|
|
|
|
value = static_cast<type>(value0); \
|
2017-03-25 22:13:19 +00:00
|
|
|
}
|
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
#define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name);
|
2017-03-25 23:58:11 +00:00
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
#define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \
|
|
|
|
template <typename TVisitor> \
|
2017-03-25 23:58:11 +00:00
|
|
|
void Reflect(TVisitor& visitor, type& value) { \
|
2017-09-22 01:14:57 +00:00
|
|
|
REFLECT_MEMBER_START(); \
|
|
|
|
REFLECT_MEMBER_END(); \
|
2017-03-25 23:58:11 +00:00
|
|
|
}
|
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
#define MAKE_REFLECT_STRUCT(type, ...) \
|
|
|
|
template <typename TVisitor> \
|
|
|
|
void Reflect(TVisitor& visitor, type& value) { \
|
|
|
|
REFLECT_MEMBER_START(); \
|
2017-03-25 23:58:11 +00:00
|
|
|
MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \
|
2017-09-22 01:14:57 +00:00
|
|
|
REFLECT_MEMBER_END(); \
|
2017-03-25 23:58:11 +00:00
|
|
|
}
|
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
#define _MAPPABLE_REFLECT_ARRAY(name) Reflect(visitor, value.name);
|
2017-05-20 19:31:07 +00:00
|
|
|
|
|
|
|
// Reflects the struct so it is serialized as an array instead of an object.
|
|
|
|
// This currently only supports writers.
|
|
|
|
#define MAKE_REFLECT_STRUCT_WRITER_AS_ARRAY(type, ...) \
|
2017-09-22 01:14:57 +00:00
|
|
|
inline void Reflect(Writer& visitor, type& value) { \
|
|
|
|
visitor.StartArray(); \
|
|
|
|
MACRO_MAP(_MAPPABLE_REFLECT_ARRAY, __VA_ARGS__) \
|
|
|
|
visitor.EndArray(); \
|
2017-05-20 19:31:07 +00:00
|
|
|
}
|
2017-03-25 23:58:11 +00:00
|
|
|
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename T>
|
2017-03-26 00:22:06 +00:00
|
|
|
struct NonElidedVector : public std::vector<T> {};
|
|
|
|
|
2017-03-07 09:32:29 +00:00
|
|
|
// API:
|
|
|
|
/*
|
|
|
|
template<typename TVisitor, typename T>
|
|
|
|
void Reflect(TVisitor& visitor, T& value) {
|
|
|
|
static_assert(false, "Missing implementation");
|
|
|
|
}
|
|
|
|
template<typename TVisitor>
|
|
|
|
void DefaultReflectMemberStart(TVisitor& visitor) {
|
|
|
|
static_assert(false, "Missing implementation");
|
|
|
|
}
|
|
|
|
template<typename TVisitor, typename T>
|
|
|
|
bool ReflectMemberStart(TVisitor& visitor, T& value) {
|
|
|
|
static_assert(false, "Missing implementation");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
template<typename TVisitor, typename T>
|
|
|
|
void ReflectMemberEnd(TVisitor& visitor, T& value) {
|
|
|
|
static_assert(false, "Missing implementation");
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
2017-05-19 07:02:01 +00:00
|
|
|
// int16_t
|
|
|
|
void Reflect(Reader& visitor, int16_t& value);
|
|
|
|
void Reflect(Writer& visitor, int16_t& value);
|
|
|
|
// int32_t
|
|
|
|
void Reflect(Reader& visitor, int32_t& value);
|
|
|
|
void Reflect(Writer& visitor, int32_t& value);
|
2017-04-20 04:57:44 +00:00
|
|
|
// int64_t
|
|
|
|
void Reflect(Reader& visitor, int64_t& value);
|
|
|
|
void Reflect(Writer& visitor, int64_t& value);
|
2017-05-19 07:02:01 +00:00
|
|
|
// uint64_t
|
|
|
|
void Reflect(Reader& visitor, uint64_t& value);
|
|
|
|
void Reflect(Writer& visitor, uint64_t& value);
|
2017-03-07 18:01:23 +00:00
|
|
|
// bool
|
|
|
|
void Reflect(Reader& visitor, bool& value);
|
|
|
|
void Reflect(Writer& visitor, bool& value);
|
|
|
|
// std::string
|
|
|
|
void Reflect(Reader& visitor, std::string& value);
|
|
|
|
void Reflect(Writer& visitor, std::string& value);
|
|
|
|
|
2017-03-07 09:32:29 +00:00
|
|
|
// Writer:
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename T>
|
2017-03-07 09:32:29 +00:00
|
|
|
void Reflect(Writer& visitor, std::vector<T>& values) {
|
|
|
|
visitor.StartArray();
|
|
|
|
for (auto& value : values)
|
|
|
|
Reflect(visitor, value);
|
|
|
|
visitor.EndArray();
|
|
|
|
}
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename T>
|
2017-03-07 09:32:29 +00:00
|
|
|
void Reflect(Writer& visitor, optional<T> value) {
|
|
|
|
if (value)
|
|
|
|
Reflect(visitor, value.value());
|
|
|
|
}
|
|
|
|
inline void DefaultReflectMemberStart(Writer& visitor) {
|
|
|
|
visitor.StartObject();
|
|
|
|
}
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename T>
|
2017-03-07 09:32:29 +00:00
|
|
|
bool ReflectMemberStart(Writer& visitor, T& value) {
|
|
|
|
visitor.StartObject();
|
|
|
|
return true;
|
|
|
|
}
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename T>
|
2017-03-07 09:32:29 +00:00
|
|
|
void ReflectMemberEnd(Writer& visitor, T& value) {
|
|
|
|
visitor.EndObject();
|
|
|
|
}
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename T>
|
2017-03-07 09:32:29 +00:00
|
|
|
void ReflectMember(Writer& visitor, const char* name, T& value) {
|
|
|
|
visitor.Key(name);
|
|
|
|
Reflect(visitor, value);
|
|
|
|
}
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename T>
|
2017-03-07 09:32:29 +00:00
|
|
|
void ReflectMember(Writer& visitor, const char* name, std::vector<T>& values) {
|
|
|
|
if (values.empty())
|
|
|
|
return;
|
|
|
|
visitor.Key(name);
|
|
|
|
visitor.StartArray();
|
|
|
|
for (auto& value : values)
|
|
|
|
Reflect(visitor, value);
|
|
|
|
visitor.EndArray();
|
|
|
|
}
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename T>
|
|
|
|
void ReflectMember(Writer& visitor,
|
|
|
|
const char* name,
|
|
|
|
NonElidedVector<T>& values) {
|
2017-03-26 00:22:06 +00:00
|
|
|
visitor.Key(name);
|
|
|
|
visitor.StartArray();
|
|
|
|
for (auto& value : values)
|
|
|
|
Reflect(visitor, value);
|
|
|
|
visitor.EndArray();
|
|
|
|
}
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename T>
|
2017-03-07 09:32:29 +00:00
|
|
|
void ReflectMember(Writer& visitor, const char* name, optional<T>& value) {
|
|
|
|
if (!value)
|
|
|
|
return;
|
|
|
|
visitor.Key(name);
|
|
|
|
Reflect(visitor, value);
|
2017-03-01 08:36:11 +00:00
|
|
|
}
|
2017-03-08 08:09:15 +00:00
|
|
|
void ReflectMember(Writer& visitor, const char* name, std::string& value);
|
2017-03-01 08:36:11 +00:00
|
|
|
|
2017-03-07 09:32:29 +00:00
|
|
|
// Reader:
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename T>
|
2017-03-07 09:32:29 +00:00
|
|
|
void Reflect(Reader& visitor, std::vector<T>& values) {
|
2017-11-18 17:27:37 +00:00
|
|
|
if (!visitor.IsArray())
|
|
|
|
return;
|
2017-03-07 09:32:29 +00:00
|
|
|
for (auto& entry : visitor.GetArray()) {
|
|
|
|
T entry_value;
|
|
|
|
Reflect(entry, entry_value);
|
|
|
|
values.push_back(entry_value);
|
|
|
|
}
|
|
|
|
}
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename T>
|
2017-03-08 09:00:39 +00:00
|
|
|
void Reflect(Reader& visitor, optional<T>& value) {
|
2017-11-18 17:27:37 +00:00
|
|
|
if (visitor.IsNull())
|
|
|
|
return;
|
2017-03-07 09:32:29 +00:00
|
|
|
T real_value;
|
|
|
|
Reflect(visitor, real_value);
|
|
|
|
value = real_value;
|
|
|
|
}
|
|
|
|
inline void DefaultReflectMemberStart(Reader& visitor) {}
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename T>
|
2017-03-07 09:32:29 +00:00
|
|
|
bool ReflectMemberStart(Reader& visitor, T& value) {
|
|
|
|
return true;
|
|
|
|
}
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename T>
|
2017-03-07 09:32:29 +00:00
|
|
|
void ReflectMemberEnd(Reader& visitor, T& value) {}
|
2017-09-22 01:14:57 +00:00
|
|
|
template <typename T>
|
2017-03-07 09:32:29 +00:00
|
|
|
void ReflectMember(Reader& visitor, const char* name, T& value) {
|
|
|
|
auto it = visitor.FindMember(name);
|
|
|
|
if (it != visitor.MemberEnd()) {
|
|
|
|
Reader& child_visitor = it->value;
|
|
|
|
Reflect(child_visitor, value);
|
2017-03-01 08:36:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-12 06:08:15 +00:00
|
|
|
std::string Serialize(IndexFile& file);
|
2017-09-22 01:14:57 +00:00
|
|
|
std::unique_ptr<IndexFile> Deserialize(std::string path,
|
|
|
|
std::string serialized,
|
|
|
|
optional<int> expected_version);
|
2017-04-20 06:02:24 +00:00
|
|
|
|
2017-07-30 04:46:21 +00:00
|
|
|
void SetTestOutputMode();
|