diff --git a/include/json5/json5_reflect.hpp b/include/json5/json5_reflect.hpp index cc6888b..6fece12 100644 --- a/include/json5/json5_reflect.hpp +++ b/include/json5/json5_reflect.hpp @@ -37,6 +37,12 @@ template error from_file( std::string_view fileName, T &out ); namespace detail { +template struct is_optional : public std::false_type { }; + +template struct is_optional> : public std::true_type { }; + +template constexpr static bool is_optional_v = is_optional::value; + // Pre-declare so compiler knows it exists before it is attempted to be used template error read(const json5::value& in, T& out); @@ -153,7 +159,12 @@ inline json5::value write_enum( writer &w, T in ) template inline void write_tuple_value(writer& w, std::string_view name, const Type& in) { - if constexpr ( std::is_enum_v ) + if constexpr (is_optional_v) + { + if (in) + write_tuple_value(w, name, *in); + } + else if constexpr (std::is_enum_v) { if constexpr ( enum_table() ) w[name] = write_enum( w, in ); @@ -360,7 +371,20 @@ inline error read_enum( const json5::value &in, T &out ) template inline error read_tuple_value( const json5::object_view::iterator iter, Type &out ) { - if constexpr ( std::is_enum_v ) + if constexpr (is_optional_v) + { + if ((*iter).second.is_null()) + { + out = std::nullopt; + } + else + { + out = typename Type::value_type(); + if (auto err = read_tuple_value(iter, *out)) + return err; + } + } + else if constexpr (std::is_enum_v) { if constexpr ( enum_table() ) {