serializer: make visitor/vis value/v consistent

This commit is contained in:
Fangrui Song 2018-11-23 11:53:21 -08:00
parent 58e996366d
commit 3bcb5f23a4
3 changed files with 221 additions and 225 deletions

View File

@ -27,16 +27,16 @@ struct Hover {
std::optional<lsRange> range;
};
void Reflect(Writer &visitor, MarkedString &value) {
void Reflect(Writer &vis, MarkedString &v) {
// If there is a language, emit a `{language:string, value:string}` object. If
// not, emit a string.
if (value.language) {
if (v.language) {
REFLECT_MEMBER_START();
REFLECT_MEMBER(language);
REFLECT_MEMBER(value);
REFLECT_MEMBER_END();
} else {
Reflect(visitor, value.value);
Reflect(vis, v.value);
}
}
MAKE_REFLECT_STRUCT(Hover, contents, range);

View File

@ -41,96 +41,94 @@ Writer::~Writer() {}
BinaryWriter::~BinaryWriter() {}
JsonWriter::~JsonWriter() {}
void Reflect(Reader &visitor, uint8_t &value) { value = visitor.GetUInt8(); }
void Reflect(Writer &visitor, uint8_t &value) { visitor.UInt8(value); }
void Reflect(Reader &vis, uint8_t &v) { v = vis.GetUInt8(); }
void Reflect(Writer &vis, uint8_t &v) { vis.UInt8(v); }
void Reflect(Reader &visitor, short &value) {
if (!visitor.IsInt())
void Reflect(Reader &vis, short &v) {
if (!vis.IsInt())
throw std::invalid_argument("short");
value = (short)visitor.GetInt();
v = (short)vis.GetInt();
}
void Reflect(Writer &visitor, short &value) { visitor.Int(value); }
void Reflect(Writer &vis, short &v) { vis.Int(v); }
void Reflect(Reader &visitor, unsigned short &value) {
if (!visitor.IsInt())
void Reflect(Reader &vis, unsigned short &v) {
if (!vis.IsInt())
throw std::invalid_argument("unsigned short");
value = (unsigned short)visitor.GetInt();
v = (unsigned short)vis.GetInt();
}
void Reflect(Writer &visitor, unsigned short &value) { visitor.Int(value); }
void Reflect(Writer &vis, unsigned short &v) { vis.Int(v); }
void Reflect(Reader &visitor, int &value) {
if (!visitor.IsInt())
void Reflect(Reader &vis, int &v) {
if (!vis.IsInt())
throw std::invalid_argument("int");
value = visitor.GetInt();
v = vis.GetInt();
}
void Reflect(Writer &visitor, int &value) { visitor.Int(value); }
void Reflect(Writer &vis, int &v) { vis.Int(v); }
void Reflect(Reader &visitor, unsigned &value) {
if (!visitor.IsUInt64())
void Reflect(Reader &vis, unsigned &v) {
if (!vis.IsUInt64())
throw std::invalid_argument("unsigned");
value = visitor.GetUInt32();
v = vis.GetUInt32();
}
void Reflect(Writer &visitor, unsigned &value) { visitor.UInt32(value); }
void Reflect(Writer &vis, unsigned &v) { vis.UInt32(v); }
void Reflect(Reader &visitor, long &value) {
if (!visitor.IsInt64())
void Reflect(Reader &vis, long &v) {
if (!vis.IsInt64())
throw std::invalid_argument("long");
value = long(visitor.GetInt64());
v = long(vis.GetInt64());
}
void Reflect(Writer &visitor, long &value) { visitor.Int64(value); }
void Reflect(Writer &vis, long &v) { vis.Int64(v); }
void Reflect(Reader &visitor, unsigned long &value) {
if (!visitor.IsUInt64())
void Reflect(Reader &vis, unsigned long &v) {
if (!vis.IsUInt64())
throw std::invalid_argument("unsigned long");
value = (unsigned long)visitor.GetUInt64();
v = (unsigned long)vis.GetUInt64();
}
void Reflect(Writer &visitor, unsigned long &value) { visitor.UInt64(value); }
void Reflect(Writer &vis, unsigned long &v) { vis.UInt64(v); }
void Reflect(Reader &visitor, long long &value) {
if (!visitor.IsInt64())
void Reflect(Reader &vis, long long &v) {
if (!vis.IsInt64())
throw std::invalid_argument("long long");
value = visitor.GetInt64();
v = vis.GetInt64();
}
void Reflect(Writer &visitor, long long &value) { visitor.Int64(value); }
void Reflect(Writer &vis, long long &v) { vis.Int64(v); }
void Reflect(Reader &visitor, unsigned long long &value) {
if (!visitor.IsUInt64())
void Reflect(Reader &vis, unsigned long long &v) {
if (!vis.IsUInt64())
throw std::invalid_argument("unsigned long long");
value = visitor.GetUInt64();
}
void Reflect(Writer &visitor, unsigned long long &value) {
visitor.UInt64(value);
v = vis.GetUInt64();
}
void Reflect(Writer &vis, unsigned long long &v) { vis.UInt64(v); }
void Reflect(Reader &visitor, double &value) {
if (!visitor.IsDouble())
void Reflect(Reader &vis, double &v) {
if (!vis.IsDouble())
throw std::invalid_argument("double");
value = visitor.GetDouble();
v = vis.GetDouble();
}
void Reflect(Writer &visitor, double &value) { visitor.Double(value); }
void Reflect(Writer &vis, double &v) { vis.Double(v); }
void Reflect(Reader &visitor, bool &value) {
if (!visitor.IsBool())
void Reflect(Reader &vis, bool &v) {
if (!vis.IsBool())
throw std::invalid_argument("bool");
value = visitor.GetBool();
v = vis.GetBool();
}
void Reflect(Writer &visitor, bool &value) { visitor.Bool(value); }
void Reflect(Writer &vis, bool &v) { vis.Bool(v); }
void Reflect(Reader &visitor, std::string &value) {
if (!visitor.IsString())
void Reflect(Reader &vis, std::string &v) {
if (!vis.IsString())
throw std::invalid_argument("std::string");
value = visitor.GetString();
v = vis.GetString();
}
void Reflect(Writer &visitor, std::string &value) {
visitor.String(value.c_str(), (rapidjson::SizeType)value.size());
void Reflect(Writer &vis, std::string &v) {
vis.String(v.c_str(), (rapidjson::SizeType)v.size());
}
void Reflect(Reader &, std::string_view &) { assert(0); }
void Reflect(Writer &visitor, std::string_view &data) {
void Reflect(Writer &vis, std::string_view &data) {
if (data.empty())
visitor.String("");
vis.String("");
else
visitor.String(&data[0], (rapidjson::SizeType)data.size());
vis.String(&data[0], (rapidjson::SizeType)data.size());
}
void Reflect(Reader &vis, const char *&v) {
@ -139,17 +137,17 @@ void Reflect(Reader &vis, const char *&v) {
}
void Reflect(Writer &vis, const char *&v) { vis.String(v); }
void Reflect(Reader &visitor, JsonNull &value) {
assert(visitor.Format() == SerializeFormat::Json);
visitor.GetNull();
void Reflect(Reader &vis, JsonNull &v) {
assert(vis.Format() == SerializeFormat::Json);
vis.GetNull();
}
void Reflect(Writer &visitor, JsonNull &value) { visitor.Null(); }
void Reflect(Writer &vis, JsonNull &v) { vis.Null(); }
// std::unordered_map
template <typename V>
void Reflect(Reader &visitor, std::unordered_map<Usr, V> &map) {
visitor.IterArray([&](Reader &entry) {
void Reflect(Reader &vis, std::unordered_map<Usr, V> &map) {
vis.IterArray([&](Reader &entry) {
V val;
Reflect(entry, val);
auto usr = val.usr;
@ -157,14 +155,14 @@ void Reflect(Reader &visitor, std::unordered_map<Usr, V> &map) {
});
}
template <typename V>
void Reflect(Writer &visitor, std::unordered_map<Usr, V> &map) {
void Reflect(Writer &vis, std::unordered_map<Usr, V> &map) {
std::vector<std::pair<uint64_t, V>> xs(map.begin(), map.end());
std::sort(xs.begin(), xs.end(),
[](const auto &a, const auto &b) { return a.first < b.first; });
visitor.StartArray(xs.size());
vis.StartArray(xs.size());
for (auto &it : xs)
Reflect(visitor, it.second);
visitor.EndArray();
Reflect(vis, it.second);
vis.EndArray();
}
// Used by IndexFile::dependencies.
@ -202,18 +200,18 @@ void Reflect(Writer &vis, DenseMap<CachedHashStringRef, int64_t> &v) {
}
// TODO: Move this to indexer.cc
void Reflect(Reader &visitor, IndexInclude &value) {
void Reflect(Reader &vis, IndexInclude &v) {
REFLECT_MEMBER_START();
REFLECT_MEMBER(line);
REFLECT_MEMBER(resolved_path);
REFLECT_MEMBER_END();
}
void Reflect(Writer &visitor, IndexInclude &value) {
void Reflect(Writer &vis, IndexInclude &v) {
REFLECT_MEMBER_START();
REFLECT_MEMBER(line);
if (gTestOutputMode) {
std::string basename = llvm::sys::path::filename(value.resolved_path);
if (value.resolved_path[0] != '&')
std::string basename = llvm::sys::path::filename(v.resolved_path);
if (v.resolved_path[0] != '&')
basename = "&" + basename;
REFLECT_MEMBER2("resolved_path", basename);
} else {
@ -222,114 +220,112 @@ void Reflect(Writer &visitor, IndexInclude &value) {
REFLECT_MEMBER_END();
}
template <typename Def>
void ReflectHoverAndComments(Reader &visitor, Def &def) {
ReflectMember(visitor, "hover", def.hover);
ReflectMember(visitor, "comments", def.comments);
template <typename Def> void ReflectHoverAndComments(Reader &vis, Def &def) {
ReflectMember(vis, "hover", def.hover);
ReflectMember(vis, "comments", def.comments);
}
template <typename Def>
void ReflectHoverAndComments(Writer &visitor, Def &def) {
template <typename Def> void ReflectHoverAndComments(Writer &vis, Def &def) {
// Don't emit empty hover and comments in JSON test mode.
if (!gTestOutputMode || def.hover[0])
ReflectMember(visitor, "hover", def.hover);
ReflectMember(vis, "hover", def.hover);
if (!gTestOutputMode || def.comments[0])
ReflectMember(visitor, "comments", def.comments);
ReflectMember(vis, "comments", def.comments);
}
template <typename Def> void ReflectShortName(Reader &visitor, Def &def) {
template <typename Def> void ReflectShortName(Reader &vis, Def &def) {
if (gTestOutputMode) {
std::string short_name;
ReflectMember(visitor, "short_name", short_name);
ReflectMember(vis, "short_name", short_name);
def.short_name_offset =
std::string_view(def.detailed_name).find(short_name);
assert(def.short_name_offset != std::string::npos);
def.short_name_size = short_name.size();
} else {
ReflectMember(visitor, "short_name_offset", def.short_name_offset);
ReflectMember(visitor, "short_name_size", def.short_name_size);
ReflectMember(vis, "short_name_offset", def.short_name_offset);
ReflectMember(vis, "short_name_size", def.short_name_size);
}
}
template <typename Def> void ReflectShortName(Writer &visitor, Def &def) {
template <typename Def> void ReflectShortName(Writer &vis, Def &def) {
if (gTestOutputMode) {
std::string_view short_name(def.detailed_name + def.short_name_offset,
def.short_name_size);
ReflectMember(visitor, "short_name", short_name);
ReflectMember(vis, "short_name", short_name);
} else {
ReflectMember(visitor, "short_name_offset", def.short_name_offset);
ReflectMember(visitor, "short_name_size", def.short_name_size);
ReflectMember(vis, "short_name_offset", def.short_name_offset);
ReflectMember(vis, "short_name_size", def.short_name_size);
}
}
template <typename TVisitor> void Reflect(TVisitor &visitor, IndexFunc &value) {
template <typename TVisitor> void Reflect(TVisitor &vis, IndexFunc &v) {
REFLECT_MEMBER_START();
REFLECT_MEMBER2("usr", value.usr);
REFLECT_MEMBER2("detailed_name", value.def.detailed_name);
REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset);
ReflectShortName(visitor, value.def);
REFLECT_MEMBER2("spell", value.def.spell);
ReflectHoverAndComments(visitor, value.def);
REFLECT_MEMBER2("bases", value.def.bases);
REFLECT_MEMBER2("vars", value.def.vars);
REFLECT_MEMBER2("callees", value.def.callees);
REFLECT_MEMBER2("kind", value.def.kind);
REFLECT_MEMBER2("parent_kind", value.def.parent_kind);
REFLECT_MEMBER2("storage", value.def.storage);
REFLECT_MEMBER2("usr", v.usr);
REFLECT_MEMBER2("detailed_name", v.def.detailed_name);
REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset);
ReflectShortName(vis, v.def);
REFLECT_MEMBER2("spell", v.def.spell);
ReflectHoverAndComments(vis, v.def);
REFLECT_MEMBER2("bases", v.def.bases);
REFLECT_MEMBER2("vars", v.def.vars);
REFLECT_MEMBER2("callees", v.def.callees);
REFLECT_MEMBER2("kind", v.def.kind);
REFLECT_MEMBER2("parent_kind", v.def.parent_kind);
REFLECT_MEMBER2("storage", v.def.storage);
REFLECT_MEMBER2("declarations", value.declarations);
REFLECT_MEMBER2("derived", value.derived);
REFLECT_MEMBER2("uses", value.uses);
REFLECT_MEMBER2("declarations", v.declarations);
REFLECT_MEMBER2("derived", v.derived);
REFLECT_MEMBER2("uses", v.uses);
REFLECT_MEMBER_END();
}
template <typename TVisitor> void Reflect(TVisitor &visitor, IndexType &value) {
template <typename TVisitor> void Reflect(TVisitor &vis, IndexType &v) {
REFLECT_MEMBER_START();
REFLECT_MEMBER2("usr", value.usr);
REFLECT_MEMBER2("detailed_name", value.def.detailed_name);
REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset);
ReflectShortName(visitor, value.def);
ReflectHoverAndComments(visitor, value.def);
REFLECT_MEMBER2("spell", value.def.spell);
REFLECT_MEMBER2("bases", value.def.bases);
REFLECT_MEMBER2("funcs", value.def.funcs);
REFLECT_MEMBER2("types", value.def.types);
REFLECT_MEMBER2("vars", value.def.vars);
REFLECT_MEMBER2("alias_of", value.def.alias_of);
REFLECT_MEMBER2("kind", value.def.kind);
REFLECT_MEMBER2("parent_kind", value.def.parent_kind);
REFLECT_MEMBER2("usr", v.usr);
REFLECT_MEMBER2("detailed_name", v.def.detailed_name);
REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset);
ReflectShortName(vis, v.def);
ReflectHoverAndComments(vis, v.def);
REFLECT_MEMBER2("spell", v.def.spell);
REFLECT_MEMBER2("bases", v.def.bases);
REFLECT_MEMBER2("funcs", v.def.funcs);
REFLECT_MEMBER2("types", v.def.types);
REFLECT_MEMBER2("vars", v.def.vars);
REFLECT_MEMBER2("alias_of", v.def.alias_of);
REFLECT_MEMBER2("kind", v.def.kind);
REFLECT_MEMBER2("parent_kind", v.def.parent_kind);
REFLECT_MEMBER2("declarations", value.declarations);
REFLECT_MEMBER2("derived", value.derived);
REFLECT_MEMBER2("instances", value.instances);
REFLECT_MEMBER2("uses", value.uses);
REFLECT_MEMBER2("declarations", v.declarations);
REFLECT_MEMBER2("derived", v.derived);
REFLECT_MEMBER2("instances", v.instances);
REFLECT_MEMBER2("uses", v.uses);
REFLECT_MEMBER_END();
}
template <typename TVisitor> void Reflect(TVisitor &visitor, IndexVar &value) {
template <typename TVisitor> void Reflect(TVisitor &vis, IndexVar &v) {
REFLECT_MEMBER_START();
REFLECT_MEMBER2("usr", value.usr);
REFLECT_MEMBER2("detailed_name", value.def.detailed_name);
REFLECT_MEMBER2("qual_name_offset", value.def.qual_name_offset);
ReflectShortName(visitor, value.def);
ReflectHoverAndComments(visitor, value.def);
REFLECT_MEMBER2("spell", value.def.spell);
REFLECT_MEMBER2("type", value.def.type);
REFLECT_MEMBER2("kind", value.def.kind);
REFLECT_MEMBER2("parent_kind", value.def.parent_kind);
REFLECT_MEMBER2("storage", value.def.storage);
REFLECT_MEMBER2("usr", v.usr);
REFLECT_MEMBER2("detailed_name", v.def.detailed_name);
REFLECT_MEMBER2("qual_name_offset", v.def.qual_name_offset);
ReflectShortName(vis, v.def);
ReflectHoverAndComments(vis, v.def);
REFLECT_MEMBER2("spell", v.def.spell);
REFLECT_MEMBER2("type", v.def.type);
REFLECT_MEMBER2("kind", v.def.kind);
REFLECT_MEMBER2("parent_kind", v.def.parent_kind);
REFLECT_MEMBER2("storage", v.def.storage);
REFLECT_MEMBER2("declarations", value.declarations);
REFLECT_MEMBER2("uses", value.uses);
REFLECT_MEMBER2("declarations", v.declarations);
REFLECT_MEMBER2("uses", v.uses);
REFLECT_MEMBER_END();
}
// IndexFile
bool ReflectMemberStart(Writer &visitor, IndexFile &value) {
visitor.StartObject();
bool ReflectMemberStart(Writer &vis, IndexFile &v) {
vis.StartObject();
return true;
}
template <typename TVisitor> void Reflect(TVisitor &visitor, IndexFile &value) {
template <typename TVisitor> void Reflect(TVisitor &vis, IndexFile &v) {
REFLECT_MEMBER_START();
if (!gTestOutputMode) {
REFLECT_MEMBER(mtime);
@ -352,13 +348,13 @@ void Reflect(Reader &vis, SerializeFormat &v) {
: SerializeFormat::Binary;
}
void Reflect(Writer &visitor, SerializeFormat &value) {
switch (value) {
void Reflect(Writer &vis, SerializeFormat &v) {
switch (v) {
case SerializeFormat::Binary:
visitor.String("binary");
vis.String("binary");
break;
case SerializeFormat::Json:
visitor.String("json");
vis.String("json");
break;
}
}

View File

@ -94,34 +94,34 @@ public:
struct IndexFile;
#define REFLECT_MEMBER_START() ReflectMemberStart(visitor)
#define REFLECT_MEMBER_END() ReflectMemberEnd(visitor);
#define REFLECT_MEMBER(name) ReflectMember(visitor, #name, value.name)
#define REFLECT_MEMBER2(name, value) ReflectMember(visitor, name, value)
#define REFLECT_MEMBER_START() ReflectMemberStart(vis)
#define REFLECT_MEMBER_END() ReflectMemberEnd(vis);
#define REFLECT_MEMBER(name) ReflectMember(vis, #name, v.name)
#define REFLECT_MEMBER2(name, v) ReflectMember(vis, name, v)
#define MAKE_REFLECT_TYPE_PROXY(type_name) \
MAKE_REFLECT_TYPE_PROXY2(type_name, std::underlying_type_t<type_name>)
#define MAKE_REFLECT_TYPE_PROXY2(type, as_type) \
LLVM_ATTRIBUTE_UNUSED inline void Reflect(Reader &visitor, type &value) { \
LLVM_ATTRIBUTE_UNUSED inline void Reflect(Reader &vis, type &v) { \
as_type value0; \
::ccls::Reflect(visitor, value0); \
value = static_cast<type>(value0); \
::ccls::Reflect(vis, value0); \
v = static_cast<type>(value0); \
} \
LLVM_ATTRIBUTE_UNUSED inline void Reflect(Writer &visitor, type &value) { \
auto value0 = static_cast<as_type>(value); \
::ccls::Reflect(visitor, value0); \
LLVM_ATTRIBUTE_UNUSED inline void Reflect(Writer &vis, type &v) { \
auto value0 = static_cast<as_type>(v); \
::ccls::Reflect(vis, value0); \
}
#define _MAPPABLE_REFLECT_MEMBER(name) REFLECT_MEMBER(name);
#define MAKE_REFLECT_EMPTY_STRUCT(type, ...) \
template <typename TVisitor> void Reflect(TVisitor &visitor, type &value) { \
template <typename TVisitor> void Reflect(TVisitor &vis, type &v) { \
REFLECT_MEMBER_START(); \
REFLECT_MEMBER_END(); \
}
#define MAKE_REFLECT_STRUCT(type, ...) \
template <typename TVisitor> void Reflect(TVisitor &visitor, type &value) { \
template <typename TVisitor> void Reflect(TVisitor &vis, type &v) { \
REFLECT_MEMBER_START(); \
MACRO_MAP(_MAPPABLE_REFLECT_MEMBER, __VA_ARGS__) \
REFLECT_MEMBER_END(); \
@ -133,66 +133,66 @@ struct IndexFile;
#define NUM_VA_ARGS(...) NUM_VA_ARGS_IMPL(__VA_ARGS__,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
// clang-format on
#define _MAPPABLE_REFLECT_ARRAY(name) Reflect(visitor, value.name);
#define _MAPPABLE_REFLECT_ARRAY(name) Reflect(vis, v.name);
// 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, ...) \
inline void Reflect(Writer &visitor, type &value) { \
visitor.StartArray(NUM_VA_ARGS(__VA_ARGS__)); \
inline void Reflect(Writer &vis, type &v) { \
vis.StartArray(NUM_VA_ARGS(__VA_ARGS__)); \
MACRO_MAP(_MAPPABLE_REFLECT_ARRAY, __VA_ARGS__) \
visitor.EndArray(); \
vis.EndArray(); \
}
//// Elementary types
void Reflect(Reader &visitor, uint8_t &value);
void Reflect(Writer &visitor, uint8_t &value);
void Reflect(Reader &vis, uint8_t &v);
void Reflect(Writer &vis, uint8_t &v);
void Reflect(Reader &visitor, short &value);
void Reflect(Writer &visitor, short &value);
void Reflect(Reader &vis, short &v);
void Reflect(Writer &vis, short &v);
void Reflect(Reader &visitor, unsigned short &value);
void Reflect(Writer &visitor, unsigned short &value);
void Reflect(Reader &vis, unsigned short &v);
void Reflect(Writer &vis, unsigned short &v);
void Reflect(Reader &visitor, int &value);
void Reflect(Writer &visitor, int &value);
void Reflect(Reader &vis, int &v);
void Reflect(Writer &vis, int &v);
void Reflect(Reader &visitor, unsigned &value);
void Reflect(Writer &visitor, unsigned &value);
void Reflect(Reader &vis, unsigned &v);
void Reflect(Writer &vis, unsigned &v);
void Reflect(Reader &visitor, long &value);
void Reflect(Writer &visitor, long &value);
void Reflect(Reader &vis, long &v);
void Reflect(Writer &vis, long &v);
void Reflect(Reader &visitor, unsigned long &value);
void Reflect(Writer &visitor, unsigned long &value);
void Reflect(Reader &vis, unsigned long &v);
void Reflect(Writer &vis, unsigned long &v);
void Reflect(Reader &visitor, long long &value);
void Reflect(Writer &visitor, long long &value);
void Reflect(Reader &vis, long long &v);
void Reflect(Writer &vis, long long &v);
void Reflect(Reader &visitor, unsigned long long &value);
void Reflect(Writer &visitor, unsigned long long &value);
void Reflect(Reader &vis, unsigned long long &v);
void Reflect(Writer &vis, unsigned long long &v);
void Reflect(Reader &visitor, double &value);
void Reflect(Writer &visitor, double &value);
void Reflect(Reader &vis, double &v);
void Reflect(Writer &vis, double &v);
void Reflect(Reader &visitor, bool &value);
void Reflect(Writer &visitor, bool &value);
void Reflect(Reader &vis, bool &v);
void Reflect(Writer &vis, bool &v);
void Reflect(Reader &visitor, std::string &value);
void Reflect(Writer &visitor, std::string &value);
void Reflect(Reader &vis, std::string &v);
void Reflect(Writer &vis, std::string &v);
void Reflect(Reader &visitor, std::string_view &view);
void Reflect(Writer &visitor, std::string_view &view);
void Reflect(Reader &vis, std::string_view &v);
void Reflect(Writer &vis, std::string_view &v);
void Reflect(Reader &vis, const char *&v);
void Reflect(Writer &vis, const char *&v);
void Reflect(Reader &visitor, JsonNull &value);
void Reflect(Writer &visitor, JsonNull &value);
void Reflect(Reader &vis, JsonNull &v);
void Reflect(Writer &vis, JsonNull &v);
void Reflect(Reader &visitor, SerializeFormat &value);
void Reflect(Writer &visitor, SerializeFormat &value);
void Reflect(Reader &vis, SerializeFormat &v);
void Reflect(Writer &vis, SerializeFormat &v);
//// Type constructors
@ -200,60 +200,60 @@ void Reflect(Writer &visitor, SerializeFormat &value);
// properties (in `key: value` context). Reflect std::optional<T> is used for a
// different purpose, whether an object is nullable (possibly in `value`
// context).
template <typename T> void Reflect(Reader &visitor, std::optional<T> &value) {
if (visitor.IsNull()) {
visitor.GetNull();
template <typename T> void Reflect(Reader &vis, std::optional<T> &v) {
if (vis.IsNull()) {
vis.GetNull();
return;
}
T real_value;
Reflect(visitor, real_value);
value = std::move(real_value);
T val;
Reflect(vis, val);
v = std::move(val);
}
template <typename T> void Reflect(Writer &visitor, std::optional<T> &value) {
if (value) {
if (visitor.Format() != SerializeFormat::Json)
visitor.UInt8(1);
Reflect(visitor, *value);
template <typename T> void Reflect(Writer &vis, std::optional<T> &v) {
if (v) {
if (vis.Format() != SerializeFormat::Json)
vis.UInt8(1);
Reflect(vis, *v);
} else
visitor.Null();
vis.Null();
}
// The same as std::optional
template <typename T> void Reflect(Reader &visitor, Maybe<T> &value) {
if (visitor.IsNull()) {
visitor.GetNull();
template <typename T> void Reflect(Reader &vis, Maybe<T> &v) {
if (vis.IsNull()) {
vis.GetNull();
return;
}
T real_value;
Reflect(visitor, real_value);
value = std::move(real_value);
T val;
Reflect(vis, val);
v = std::move(val);
}
template <typename T> void Reflect(Writer &visitor, Maybe<T> &value) {
if (value) {
if (visitor.Format() != SerializeFormat::Json)
visitor.UInt8(1);
Reflect(visitor, *value);
template <typename T> void Reflect(Writer &vis, Maybe<T> &v) {
if (v) {
if (vis.Format() != SerializeFormat::Json)
vis.UInt8(1);
Reflect(vis, *v);
} else
visitor.Null();
vis.Null();
}
template <typename T>
void ReflectMember(Writer &visitor, const char *name, std::optional<T> &value) {
void ReflectMember(Writer &vis, const char *name, std::optional<T> &v) {
// For TypeScript std::optional property key?: value in the spec,
// We omit both key and value if value is std::nullopt (null) for JsonWriter
// to reduce output. But keep it for other serialization formats.
if (value || visitor.Format() != SerializeFormat::Json) {
visitor.Key(name);
Reflect(visitor, value);
if (v || vis.Format() != SerializeFormat::Json) {
vis.Key(name);
Reflect(vis, v);
}
}
// The same as std::optional
template <typename T>
void ReflectMember(Writer &visitor, const char *name, Maybe<T> &value) {
if (value.Valid() || visitor.Format() != SerializeFormat::Json) {
visitor.Key(name);
Reflect(visitor, value);
void ReflectMember(Writer &vis, const char *name, Maybe<T> &v) {
if (v.Valid() || vis.Format() != SerializeFormat::Json) {
vis.Key(name);
Reflect(vis, v);
}
}
@ -271,18 +271,18 @@ void Reflect(Writer &vis, std::pair<L, R> &v) {
}
// std::vector
template <typename T> void Reflect(Reader &visitor, std::vector<T> &values) {
visitor.IterArray([&](Reader &entry) {
template <typename T> void Reflect(Reader &vis, std::vector<T> &vs) {
vis.IterArray([&](Reader &entry) {
T entry_value;
Reflect(entry, entry_value);
values.push_back(std::move(entry_value));
vs.push_back(std::move(entry_value));
});
}
template <typename T> void Reflect(Writer &visitor, std::vector<T> &values) {
visitor.StartArray(values.size());
for (auto &value : values)
Reflect(visitor, value);
visitor.EndArray();
template <typename T> void Reflect(Writer &vis, std::vector<T> &vs) {
vis.StartArray(vs.size());
for (auto &v : vs)
Reflect(vis, v);
vis.EndArray();
}
// ReflectMember