diff --git a/src/serializer.h b/src/serializer.h index fffbffa7..87742e09 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -136,39 +136,42 @@ void ReflectMemberEnd(TVisitor& visitor, T& value) { } */ -// uint8_t +//// Elementary types + void Reflect(Reader& visitor, uint8_t& value); void Reflect(Writer& visitor, uint8_t& value); -// 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); -// int64_t + void Reflect(Reader& visitor, int64_t& value); void Reflect(Writer& visitor, int64_t& value); -// uint64_t + void Reflect(Reader& visitor, uint64_t& value); void Reflect(Writer& visitor, uint64_t& value); -// double + void Reflect(Reader& visitor, double& value); void Reflect(Writer& visitor, double& value); -// 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); +// std::monostate is used to represent JSON null void Reflect(Reader& visitor, std::monostate&); void Reflect(Writer& visitor, std::monostate&); void Reflect(Reader& visitor, SerializeFormat& value); void Reflect(Writer& visitor, SerializeFormat& value); -// std::optional +//// Type constructors + +// Usually used for null | object template void Reflect(Reader& visitor, optional& value) { if (visitor.IsNull()) { @@ -189,6 +192,7 @@ void Reflect(Writer& visitor, optional& value) { visitor.Null(); } +// Backport C++17 std::disjunction namespace { template struct disjunction @@ -197,8 +201,11 @@ template struct disjunction : B0 {}; } +// Helper struct to reflect std::variant template struct ReflectVariant { + // If T appears in Ts..., we should set the value of std::variant to + // what we get from Reader. template typename std::enable_if...>::value, void>::type @@ -207,12 +214,15 @@ struct ReflectVariant { Reflect(visitor, a); value = a; } + // This SFINAE overload is used to prevent compile error. value = a; is not + // allowed if T does not appear in Ts... template typename std::enable_if...>::value, void>::type ReflectTag(Reader&, std::variant&) {} void operator()(Reader& visitor, std::variant& value) { + // Based on tag dispatch, call different ReflectTag helper. if (visitor.IsNull()) ReflectTag(visitor, value); // It is possible that IsInt64() && IsInt(). We don't call ReflectTag if @@ -227,6 +237,7 @@ struct ReflectVariant { assert(0); } + // Check which type the variant contains and call corresponding Reflect. void operator()(Writer& visitor, std::variant& value) { if (value.index() == N - 1) Reflect(visitor, std::get(value)); @@ -235,6 +246,7 @@ struct ReflectVariant { } }; +// Writer feflection on std::variant recurses. This is induction basis. template struct ReflectVariant<0, Ts...> { void operator()(Writer& visitor, std::variant& value) {}