diff --git a/src/json.hpp b/src/json.hpp index e9a6c80b..2524a694 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -187,7 +187,7 @@ struct conjunction template struct negation : std::integral_constant < bool, !B::value > {}; -template std::string type_name(const Json& j) +template std::string type_name(const BasicJsonType& j) { switch (j.m_type) { @@ -220,8 +220,8 @@ template struct external_constructor; template <> struct external_constructor { - template - static void construct(Json& j, typename Json::boolean_t b) noexcept + template + static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept { j.m_type = value_t::boolean; j.m_value = b; @@ -232,8 +232,8 @@ struct external_constructor template <> struct external_constructor { - template - static void construct(Json& j, const typename Json::string_t& s) + template + static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s) { j.m_type = value_t::string; j.m_value = s; @@ -244,12 +244,12 @@ struct external_constructor template <> struct external_constructor { - template - static void construct(Json& j, typename Json::number_float_t val) noexcept + template + static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept { // replace infinity and NAN by null if (not std::isfinite(val)) - j = Json{}; + j = BasicJsonType{}; else { j.m_type = value_t::number_float; @@ -262,8 +262,8 @@ struct external_constructor template <> struct external_constructor { - template - static void construct(Json& j, typename Json::number_unsigned_t val) noexcept + template + static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept { j.m_type = value_t::number_unsigned; j.m_value = val; @@ -274,8 +274,8 @@ struct external_constructor template <> struct external_constructor { - template - static void construct(Json& j, typename Json::number_integer_t val) noexcept + template + static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept { j.m_type = value_t::number_integer; j.m_value = val; @@ -286,25 +286,25 @@ struct external_constructor template <> struct external_constructor { - template - static void construct(Json& j, const typename Json::array_t& arr) + template + static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr) { j.m_type = value_t::array; j.m_value = arr; j.assert_invariant(); } - template ::value, + typename BasicJsonType::array_t>::value, int> = 0> - static void construct(Json& j, const CompatibleArrayType& arr) + static void construct(BasicJsonType& j, const CompatibleArrayType& arr) { using std::begin; using std::end; j.m_type = value_t::array; j.m_value.array = - j.template create(begin(arr), end(arr)); + j.template create(begin(arr), end(arr)); j.assert_invariant(); } }; @@ -312,26 +312,26 @@ struct external_constructor template <> struct external_constructor { - template - static void construct(Json& j, const typename Json::object_t& obj) + template + static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj) { j.m_type = value_t::object; j.m_value = obj; j.assert_invariant(); } - template ::value, + typename BasicJsonType::object_t>::value, int> = 0> - static void construct(Json& j, const CompatibleObjectType& obj) + static void construct(BasicJsonType& j, const CompatibleObjectType& obj) { using std::begin; using std::end; j.m_type = value_t::object; j.m_value.object = - j.template create(begin(obj), end(obj)); + j.template create(begin(obj), end(obj)); j.assert_invariant(); } }; @@ -377,27 +377,27 @@ struct is_compatible_object_type_impl typename CompatibleObjectType::mapped_type>::value; }; -template +template struct is_compatible_object_type { static auto constexpr value = is_compatible_object_type_impl < conjunction>, has_mapped_type, has_key_type>::value, - typename Json::object_t, CompatibleObjectType >::value; + typename BasicJsonType::object_t, CompatibleObjectType >::value; }; -template +template struct is_basic_json_nested_type { - static auto constexpr value = std::is_same::value or - std::is_same::value or - std::is_same::value or - std::is_same::value or - std::is_same::value; + static auto constexpr value = std::is_same::value or + std::is_same::value or + std::is_same::value or + std::is_same::value or + std::is_same::value; }; -template +template struct is_compatible_array_type { // TODO concept Container? @@ -405,10 +405,10 @@ struct is_compatible_array_type static auto constexpr value = conjunction>, negation>, - negation>, + negation>, - negation>, + negation>, has_value_type, has_iterator>::value; }; @@ -441,76 +441,76 @@ struct is_compatible_integer_type }; // This trait checks if JSONSerializer::from_json(json const&, udt&) exists -template +template struct has_from_json { private: // also check the return type of from_json template ::from_json( - std::declval(), std::declval()))>::value>> + std::declval(), std::declval()))>::value>> static int detect(U&&); static void detect(...); public: static constexpr bool value = std::is_integral>()))>::value; + detect(std::declval>()))>::value; }; // This trait checks if JSONSerializer::from_json(json const&) exists // this overload is used for non-default-constructible user-defined-types -template +template struct has_non_default_from_json { private: template < typename U, typename = enable_if_t::from_json(std::declval()))>::value >> + T, decltype(uncvref_t::from_json(std::declval()))>::value >> static int detect(U&&); static void detect(...); public: static constexpr bool value = std::is_integral>()))>::value; + std::declval>()))>::value; }; -// This trait checks if Json::json_serializer::to_json exists -template +// This trait checks if BasicJsonType::json_serializer::to_json exists +template struct has_to_json { private: template ::to_json( - std::declval(), std::declval()))> + std::declval(), std::declval()))> static int detect(U&&); static void detect(...); public: static constexpr bool value = std::is_integral>()))>::value; + std::declval>()))>::value; }; // overloads for basic_json template parameters -template ::value and not std::is_same::value, + typename BasicJsonType::boolean_t>::value, int> = 0> -void get_arithmetic_value(const Json& j, ArithmeticType& val) +void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val) { switch (static_cast(j)) { case value_t::number_unsigned: val = static_cast( - *j.template get_ptr()); + *j.template get_ptr()); break; case value_t::number_integer: val = static_cast( - *j.template get_ptr()); + *j.template get_ptr()); break; case value_t::number_float: val = static_cast( - *j.template get_ptr()); + *j.template get_ptr()); break; default: JSON_THROW( @@ -518,136 +518,136 @@ void get_arithmetic_value(const Json& j, ArithmeticType& val) } } -template -void to_json(Json& j, typename Json::boolean_t b) noexcept +template +void to_json(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept { external_constructor::construct(j, b); } -template ::value, int> = 0> -void to_json(Json& j, const CompatibleString& s) +void to_json(BasicJsonType& j, const CompatibleString& s) { external_constructor::construct(j, s); } -template ::value, int> = 0> -void to_json(Json& j, FloatType val) noexcept +void to_json(BasicJsonType& j, FloatType val) noexcept { - external_constructor::construct(j, static_cast(val)); + external_constructor::construct(j, static_cast(val)); } template < - typename Json, typename CompatibleNumberUnsignedType, - enable_if_t::value, int> = 0 > -void to_json(Json& j, CompatibleNumberUnsignedType val) noexcept +void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept { - external_constructor::construct(j, static_cast(val)); + external_constructor::construct(j, static_cast(val)); } template < - typename Json, typename CompatibleNumberIntegerType, - enable_if_t::value, int> = 0 > -void to_json(Json& j, CompatibleNumberIntegerType val) noexcept +void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept { - external_constructor::construct(j, static_cast(val)); + external_constructor::construct(j, static_cast(val)); } -template ::value, int> = 0> -void to_json(Json& j, UnscopedEnumType e) noexcept +void to_json(BasicJsonType& j, UnscopedEnumType e) noexcept { external_constructor::construct(j, e); } template < - typename Json, typename CompatibleArrayType, + typename BasicJsonType, typename CompatibleArrayType, enable_if_t < - is_compatible_array_type::value or - std::is_same::value, + is_compatible_array_type::value or + std::is_same::value, int > = 0 > -void to_json(Json& j, const CompatibleArrayType& arr) +void to_json(BasicJsonType& j, const CompatibleArrayType& arr) { external_constructor::construct(j, arr); } template < - typename Json, typename CompatibleObjectType, - enable_if_t::value, + typename BasicJsonType, typename CompatibleObjectType, + enable_if_t::value, int> = 0 > -void to_json(Json& j, const CompatibleObjectType& arr) +void to_json(BasicJsonType& j, const CompatibleObjectType& arr) { external_constructor::construct(j, arr); } -template -void from_json(const Json& j, typename Json::boolean_t& b) +template +void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b) { if (!j.is_boolean()) { JSON_THROW(std::domain_error("type must be boolean, but is " + type_name(j))); } - b = *j.template get_ptr(); + b = *j.template get_ptr(); } -template -void from_json(const Json& j, typename Json::string_t& s) +template +void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s) { if (!j.is_string()) { JSON_THROW(std::domain_error("type must be string, but is " + type_name(j))); } - s = *j.template get_ptr(); + s = *j.template get_ptr(); } -template -void from_json(const Json& j, typename Json::number_float_t& val) +template +void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val) { get_arithmetic_value(j, val); } -template -void from_json(const Json& j, typename Json::number_unsigned_t& val) +template +void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val) { get_arithmetic_value(j, val); } -template -void from_json(const Json& j, typename Json::number_integer_t& val) +template +void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val) { get_arithmetic_value(j, val); } -template ::value, int> = 0> -void from_json(const Json& j, UnscopedEnumType& e) +void from_json(const BasicJsonType& j, UnscopedEnumType& e) { typename std::underlying_type::type val = e; get_arithmetic_value(j, val); e = static_cast(val); } -template -void from_json(const Json& j, typename Json::array_t& arr) +template +void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr) { if (!j.is_array()) { JSON_THROW(std::domain_error("type must be array, but is " + type_name(j))); } - arr = *j.template get_ptr(); + arr = *j.template get_ptr(); } // forward_list doesn't have an insert method, TODO find a way to avoid including forward_list -template -void from_json(const Json& j, std::forward_list& l) +template +void from_json(const BasicJsonType& j, std::forward_list& l) { // do not perform the check when user wants to retrieve jsons // (except when it's null.. ?) @@ -655,7 +655,7 @@ void from_json(const Json& j, std::forward_list& l) { JSON_THROW(std::domain_error("type must be array, but is " + type_name(j))); } - if (not std::is_same::value) + if (not std::is_same::value) { if (!j.is_array()) { @@ -668,23 +668,23 @@ void from_json(const Json& j, std::forward_list& l) } } -template -void from_json_array_impl(const Json& j, CompatibleArrayType& arr, priority_tag<0>) +template +void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0>) { using std::begin; using std::end; std::transform( - j.begin(), j.end(), std::inserter(arr, end(arr)), [](const Json & i) + j.begin(), j.end(), std::inserter(arr, end(arr)), [](const BasicJsonType & i) { - // get() returns *this, this won't call a from_json method when - // value_type is Json + // get() returns *this, this won't call a from_json method when + // value_type is BasicJsonType return i.template get(); }); } -template -auto from_json_array_impl(const Json& j, CompatibleArrayType& arr, priority_tag<1>) +template +auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1>) -> decltype( arr.reserve(std::declval()), void()) @@ -694,28 +694,28 @@ auto from_json_array_impl(const Json& j, CompatibleArrayType& arr, priority_tag arr.reserve(j.size()); std::transform( - j.begin(), j.end(), std::inserter(arr, end(arr)), [](const Json & i) + j.begin(), j.end(), std::inserter(arr, end(arr)), [](const BasicJsonType & i) { - // get() returns *this, this won't call a from_json method when - // value_type is Json + // get() returns *this, this won't call a from_json method when + // value_type is BasicJsonType return i.template get(); }); } template < - typename Json, typename CompatibleArrayType, - enable_if_t::value and - not std::is_same::value and + not std::is_same::value, int> = 0 > -void from_json(const Json& j, CompatibleArrayType& arr) +void from_json(const BasicJsonType& j, CompatibleArrayType& arr) { if (j.is_null()) { JSON_THROW(std::domain_error("type must be array, but is " + type_name(j))); } - // when T == Json, do not check if value_t is correct - if (not std::is_same::value) + // when T == BasicJsonType, do not check if value_t is correct + if (not std::is_same::value) { if (!j.is_array()) { @@ -727,17 +727,17 @@ void from_json(const Json& j, CompatibleArrayType& arr) template < - typename Json, typename CompatibleObjectType, - enable_if_t::value, + typename BasicJsonType, typename CompatibleObjectType, + enable_if_t::value, int> = 0 > -void from_json(const Json& j, CompatibleObjectType& obj) +void from_json(const BasicJsonType& j, CompatibleObjectType& obj) { if (!j.is_object()) { JSON_THROW(std::domain_error("type must be object, but is " + type_name(j))); } - auto inner_object = j.template get_ptr(); + auto inner_object = j.template get_ptr(); using std::begin; using std::end; // we could avoid the assignment, but this might require a for loop, which @@ -750,36 +750,36 @@ void from_json(const Json& j, CompatibleObjectType& obj) // note: Is it really necessary to provide explicit overloads for boolean_t etc.. // in case of a custom BooleanType which is not an arithmetic type? template < - typename Json, typename ArithmeticType, + typename BasicJsonType, typename ArithmeticType, enable_if_t < std::is_arithmetic::value and not std::is_same::value and + typename BasicJsonType::number_unsigned_t>::value and not std::is_same::value and + typename BasicJsonType::number_integer_t>::value and not std::is_same::value and - not std::is_same::value, + typename BasicJsonType::number_float_t>::value and + not std::is_same::value, int > = 0 > -void from_json(const Json& j, ArithmeticType& val) +void from_json(const BasicJsonType& j, ArithmeticType& val) { switch (static_cast(j)) { case value_t::number_unsigned: val = static_cast( - *j.template get_ptr()); + *j.template get_ptr()); break; case value_t::number_integer: val = static_cast( - *j.template get_ptr()); + *j.template get_ptr()); break; case value_t::number_float: val = static_cast( - *j.template get_ptr()); + *j.template get_ptr()); break; case value_t::boolean: val = static_cast( - *j.template get_ptr()); + *j.template get_ptr()); break; default: JSON_THROW( @@ -789,8 +789,8 @@ void from_json(const Json& j, ArithmeticType& val) struct to_json_fn { - template - auto call(Json& j, T&& val, priority_tag<1>) const + template + auto call(BasicJsonType& j, T&& val, priority_tag<1>) const noexcept(noexcept(to_json(j, std::forward(val)))) -> decltype(to_json(j, std::forward(val)), void()) @@ -798,15 +798,15 @@ struct to_json_fn return to_json(j, std::forward(val)); } - template - void call(Json&, T&&, priority_tag<0>) const noexcept + template + void call(BasicJsonType&, T&&, priority_tag<0>) const noexcept { - static_assert(sizeof(Json) == 0, "to_json method in T's namespace can not be called"); + static_assert(sizeof(BasicJsonType) == 0, "to_json method in T's namespace can not be called"); } public: - template - void operator()(Json& j, T&& val) const + template + void operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(std::declval().call(j, std::forward(val), priority_tag<1> {}))) { return call(j, std::forward(val), priority_tag<1> {}); @@ -816,23 +816,23 @@ struct to_json_fn struct from_json_fn { private: - template - auto call(const Json& j, T& val, priority_tag<1>) const + template + auto call(const BasicJsonType& j, T& val, priority_tag<1>) const noexcept(noexcept(from_json(j, val))) -> decltype(from_json(j, val), void()) { return from_json(j, val); } - template - void call(const Json&, T&, priority_tag<0>) const noexcept + template + void call(const BasicJsonType&, T&, priority_tag<0>) const noexcept { - static_assert(sizeof(Json) == 0, "from_json method in T's namespace can not be called"); + static_assert(sizeof(BasicJsonType) == 0, "from_json method in T's namespace can not be called"); } public: - template - void operator()(const Json& j, T& val) const + template + void operator()(const BasicJsonType& j, T& val) const noexcept(noexcept(std::declval().call(j, val, priority_tag<1> {}))) { return call(j, val, priority_tag<1> {}); @@ -881,14 +881,14 @@ constexpr const auto& from_json = detail::static_const::va template struct adl_serializer { - template - static void from_json(Json&& j, T& val) noexcept(noexcept(::nlohmann::from_json(std::forward(j), val))) + template + static void from_json(BasicJsonType&& j, T& val) noexcept(noexcept(::nlohmann::from_json(std::forward(j), val))) { - ::nlohmann::from_json(std::forward(j), val); + ::nlohmann::from_json(std::forward(j), val); } - template - static void to_json(Json& j, T&& val) noexcept( + template + static void to_json(BasicJsonType& j, T&& val) noexcept( noexcept(::nlohmann::to_json(j, std::forward(val)))) { ::nlohmann::to_json(j, std::forward(val)); @@ -989,7 +989,7 @@ class basic_json { private: template <::nlohmann::value_t> friend struct detail::external_constructor; - template friend std::string detail::type_name(const Json&); + template friend std::string detail::type_name(const BasicJsonType&); /// workaround type for MSVC using basic_json_t = basic_json= ':') goto basic_json_parser_32; + yych = *++m_cursor; + if (yych <= '/') + { + goto basic_json_parser_32; + } + if (yych >= ':') + { + goto basic_json_parser_32; + } basic_json_parser_52: - ++m_cursor; - if (m_limit <= m_cursor) fill_line_buffer(1); // LCOV_EXCL_LINE - yych = *m_cursor; - if (yych <= '/') goto basic_json_parser_14; - if (yych <= '9') goto basic_json_parser_52; - goto basic_json_parser_14; + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= '/') + { + goto basic_json_parser_14; + } + if (yych <= '9') + { + goto basic_json_parser_52; + } + goto basic_json_parser_14; basic_json_parser_54: - yych = *++m_cursor; - if (yych == 's') goto basic_json_parser_58; - goto basic_json_parser_32; + yych = *++m_cursor; + if (yych == 's') + { + goto basic_json_parser_58; + } + goto basic_json_parser_32; basic_json_parser_55: - yych = *++m_cursor; - if (yych == 'l') goto basic_json_parser_59; - goto basic_json_parser_32; + yych = *++m_cursor; + if (yych == 'l') + { + goto basic_json_parser_59; + } + goto basic_json_parser_32; basic_json_parser_56: - yych = *++m_cursor; - if (yych == 'e') goto basic_json_parser_61; - goto basic_json_parser_32; + yych = *++m_cursor; + if (yych == 'e') + { + goto basic_json_parser_61; + } + goto basic_json_parser_32; basic_json_parser_57: - ++m_cursor; - if (m_limit <= m_cursor) fill_line_buffer(1); // LCOV_EXCL_LINE - yych = *m_cursor; - if (yych <= '@') { - if (yych <= '/') goto basic_json_parser_32; - if (yych <= '9') goto basic_json_parser_63; - goto basic_json_parser_32; - } else { - if (yych <= 'F') goto basic_json_parser_63; - if (yych <= '`') goto basic_json_parser_32; - if (yych <= 'f') goto basic_json_parser_63; - goto basic_json_parser_32; - } + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= '@') + { + if (yych <= '/') + { + goto basic_json_parser_32; + } + if (yych <= '9') + { + goto basic_json_parser_63; + } + goto basic_json_parser_32; + } + else + { + if (yych <= 'F') + { + goto basic_json_parser_63; + } + if (yych <= '`') + { + goto basic_json_parser_32; + } + if (yych <= 'f') + { + goto basic_json_parser_63; + } + goto basic_json_parser_32; + } basic_json_parser_58: - yych = *++m_cursor; - if (yych == 'e') goto basic_json_parser_64; - goto basic_json_parser_32; + yych = *++m_cursor; + if (yych == 'e') + { + goto basic_json_parser_64; + } + goto basic_json_parser_32; basic_json_parser_59: - ++m_cursor; - { last_token_type = token_type::literal_null; break; } + ++m_cursor; + { + last_token_type = token_type::literal_null; + break; + } basic_json_parser_61: - ++m_cursor; - { last_token_type = token_type::literal_true; break; } + ++m_cursor; + { + last_token_type = token_type::literal_true; + break; + } basic_json_parser_63: - ++m_cursor; - if (m_limit <= m_cursor) fill_line_buffer(1); // LCOV_EXCL_LINE - yych = *m_cursor; - if (yych <= '@') { - if (yych <= '/') goto basic_json_parser_32; - if (yych <= '9') goto basic_json_parser_66; - goto basic_json_parser_32; - } else { - if (yych <= 'F') goto basic_json_parser_66; - if (yych <= '`') goto basic_json_parser_32; - if (yych <= 'f') goto basic_json_parser_66; - goto basic_json_parser_32; - } + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= '@') + { + if (yych <= '/') + { + goto basic_json_parser_32; + } + if (yych <= '9') + { + goto basic_json_parser_66; + } + goto basic_json_parser_32; + } + else + { + if (yych <= 'F') + { + goto basic_json_parser_66; + } + if (yych <= '`') + { + goto basic_json_parser_32; + } + if (yych <= 'f') + { + goto basic_json_parser_66; + } + goto basic_json_parser_32; + } basic_json_parser_64: - ++m_cursor; - { last_token_type = token_type::literal_false; break; } + ++m_cursor; + { + last_token_type = token_type::literal_false; + break; + } basic_json_parser_66: - ++m_cursor; - if (m_limit <= m_cursor) fill_line_buffer(1); // LCOV_EXCL_LINE - yych = *m_cursor; - if (yych <= '@') { - if (yych <= '/') goto basic_json_parser_32; - if (yych <= '9') goto basic_json_parser_30; - goto basic_json_parser_32; - } else { - if (yych <= 'F') goto basic_json_parser_30; - if (yych <= '`') goto basic_json_parser_32; - if (yych <= 'f') goto basic_json_parser_30; - goto basic_json_parser_32; - } - } + ++m_cursor; + if (m_limit <= m_cursor) + { + fill_line_buffer(1); // LCOV_EXCL_LINE + } + yych = *m_cursor; + if (yych <= '@') + { + if (yych <= '/') + { + goto basic_json_parser_32; + } + if (yych <= '9') + { + goto basic_json_parser_30; + } + goto basic_json_parser_32; + } + else + { + if (yych <= 'F') + { + goto basic_json_parser_30; + } + if (yych <= '`') + { + goto basic_json_parser_32; + } + if (yych <= 'f') + { + goto basic_json_parser_30; + } + goto basic_json_parser_32; + } + } } diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index cb4f3ad1..94b72eb2 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -187,7 +187,7 @@ struct conjunction template struct negation : std::integral_constant < bool, !B::value > {}; -template std::string type_name(const Json& j) +template std::string type_name(const BasicJsonType& j) { switch (j.m_type) { @@ -220,8 +220,8 @@ template struct external_constructor; template <> struct external_constructor { - template - static void construct(Json& j, typename Json::boolean_t b) noexcept + template + static void construct(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept { j.m_type = value_t::boolean; j.m_value = b; @@ -232,8 +232,8 @@ struct external_constructor template <> struct external_constructor { - template - static void construct(Json& j, const typename Json::string_t& s) + template + static void construct(BasicJsonType& j, const typename BasicJsonType::string_t& s) { j.m_type = value_t::string; j.m_value = s; @@ -244,12 +244,12 @@ struct external_constructor template <> struct external_constructor { - template - static void construct(Json& j, typename Json::number_float_t val) noexcept + template + static void construct(BasicJsonType& j, typename BasicJsonType::number_float_t val) noexcept { // replace infinity and NAN by null if (not std::isfinite(val)) - j = Json{}; + j = BasicJsonType{}; else { j.m_type = value_t::number_float; @@ -262,8 +262,8 @@ struct external_constructor template <> struct external_constructor { - template - static void construct(Json& j, typename Json::number_unsigned_t val) noexcept + template + static void construct(BasicJsonType& j, typename BasicJsonType::number_unsigned_t val) noexcept { j.m_type = value_t::number_unsigned; j.m_value = val; @@ -274,8 +274,8 @@ struct external_constructor template <> struct external_constructor { - template - static void construct(Json& j, typename Json::number_integer_t val) noexcept + template + static void construct(BasicJsonType& j, typename BasicJsonType::number_integer_t val) noexcept { j.m_type = value_t::number_integer; j.m_value = val; @@ -286,25 +286,25 @@ struct external_constructor template <> struct external_constructor { - template - static void construct(Json& j, const typename Json::array_t& arr) + template + static void construct(BasicJsonType& j, const typename BasicJsonType::array_t& arr) { j.m_type = value_t::array; j.m_value = arr; j.assert_invariant(); } - template ::value, + typename BasicJsonType::array_t>::value, int> = 0> - static void construct(Json& j, const CompatibleArrayType& arr) + static void construct(BasicJsonType& j, const CompatibleArrayType& arr) { using std::begin; using std::end; j.m_type = value_t::array; j.m_value.array = - j.template create(begin(arr), end(arr)); + j.template create(begin(arr), end(arr)); j.assert_invariant(); } }; @@ -312,26 +312,26 @@ struct external_constructor template <> struct external_constructor { - template - static void construct(Json& j, const typename Json::object_t& obj) + template + static void construct(BasicJsonType& j, const typename BasicJsonType::object_t& obj) { j.m_type = value_t::object; j.m_value = obj; j.assert_invariant(); } - template ::value, + typename BasicJsonType::object_t>::value, int> = 0> - static void construct(Json& j, const CompatibleObjectType& obj) + static void construct(BasicJsonType& j, const CompatibleObjectType& obj) { using std::begin; using std::end; j.m_type = value_t::object; j.m_value.object = - j.template create(begin(obj), end(obj)); + j.template create(begin(obj), end(obj)); j.assert_invariant(); } }; @@ -377,27 +377,27 @@ struct is_compatible_object_type_impl typename CompatibleObjectType::mapped_type>::value; }; -template +template struct is_compatible_object_type { static auto constexpr value = is_compatible_object_type_impl < conjunction>, has_mapped_type, has_key_type>::value, - typename Json::object_t, CompatibleObjectType >::value; + typename BasicJsonType::object_t, CompatibleObjectType >::value; }; -template +template struct is_basic_json_nested_type { - static auto constexpr value = std::is_same::value or - std::is_same::value or - std::is_same::value or - std::is_same::value or - std::is_same::value; + static auto constexpr value = std::is_same::value or + std::is_same::value or + std::is_same::value or + std::is_same::value or + std::is_same::value; }; -template +template struct is_compatible_array_type { // TODO concept Container? @@ -405,10 +405,10 @@ struct is_compatible_array_type static auto constexpr value = conjunction>, negation>, - negation>, + negation>, - negation>, + negation>, has_value_type, has_iterator>::value; }; @@ -441,76 +441,76 @@ struct is_compatible_integer_type }; // This trait checks if JSONSerializer::from_json(json const&, udt&) exists -template +template struct has_from_json { private: // also check the return type of from_json template ::from_json( - std::declval(), std::declval()))>::value>> + std::declval(), std::declval()))>::value>> static int detect(U&&); static void detect(...); public: static constexpr bool value = std::is_integral>()))>::value; + detect(std::declval>()))>::value; }; // This trait checks if JSONSerializer::from_json(json const&) exists // this overload is used for non-default-constructible user-defined-types -template +template struct has_non_default_from_json { private: template < typename U, typename = enable_if_t::from_json(std::declval()))>::value >> + T, decltype(uncvref_t::from_json(std::declval()))>::value >> static int detect(U&&); static void detect(...); public: static constexpr bool value = std::is_integral>()))>::value; + std::declval>()))>::value; }; -// This trait checks if Json::json_serializer::to_json exists -template +// This trait checks if BasicJsonType::json_serializer::to_json exists +template struct has_to_json { private: template ::to_json( - std::declval(), std::declval()))> + std::declval(), std::declval()))> static int detect(U&&); static void detect(...); public: static constexpr bool value = std::is_integral>()))>::value; + std::declval>()))>::value; }; // overloads for basic_json template parameters -template ::value and not std::is_same::value, + typename BasicJsonType::boolean_t>::value, int> = 0> -void get_arithmetic_value(const Json& j, ArithmeticType& val) +void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val) { switch (static_cast(j)) { case value_t::number_unsigned: val = static_cast( - *j.template get_ptr()); + *j.template get_ptr()); break; case value_t::number_integer: val = static_cast( - *j.template get_ptr()); + *j.template get_ptr()); break; case value_t::number_float: val = static_cast( - *j.template get_ptr()); + *j.template get_ptr()); break; default: JSON_THROW( @@ -518,136 +518,136 @@ void get_arithmetic_value(const Json& j, ArithmeticType& val) } } -template -void to_json(Json& j, typename Json::boolean_t b) noexcept +template +void to_json(BasicJsonType& j, typename BasicJsonType::boolean_t b) noexcept { external_constructor::construct(j, b); } -template ::value, int> = 0> -void to_json(Json& j, const CompatibleString& s) +void to_json(BasicJsonType& j, const CompatibleString& s) { external_constructor::construct(j, s); } -template ::value, int> = 0> -void to_json(Json& j, FloatType val) noexcept +void to_json(BasicJsonType& j, FloatType val) noexcept { - external_constructor::construct(j, static_cast(val)); + external_constructor::construct(j, static_cast(val)); } template < - typename Json, typename CompatibleNumberUnsignedType, - enable_if_t::value, int> = 0 > -void to_json(Json& j, CompatibleNumberUnsignedType val) noexcept +void to_json(BasicJsonType& j, CompatibleNumberUnsignedType val) noexcept { - external_constructor::construct(j, static_cast(val)); + external_constructor::construct(j, static_cast(val)); } template < - typename Json, typename CompatibleNumberIntegerType, - enable_if_t::value, int> = 0 > -void to_json(Json& j, CompatibleNumberIntegerType val) noexcept +void to_json(BasicJsonType& j, CompatibleNumberIntegerType val) noexcept { - external_constructor::construct(j, static_cast(val)); + external_constructor::construct(j, static_cast(val)); } -template ::value, int> = 0> -void to_json(Json& j, UnscopedEnumType e) noexcept +void to_json(BasicJsonType& j, UnscopedEnumType e) noexcept { external_constructor::construct(j, e); } template < - typename Json, typename CompatibleArrayType, + typename BasicJsonType, typename CompatibleArrayType, enable_if_t < - is_compatible_array_type::value or - std::is_same::value, + is_compatible_array_type::value or + std::is_same::value, int > = 0 > -void to_json(Json& j, const CompatibleArrayType& arr) +void to_json(BasicJsonType& j, const CompatibleArrayType& arr) { external_constructor::construct(j, arr); } template < - typename Json, typename CompatibleObjectType, - enable_if_t::value, + typename BasicJsonType, typename CompatibleObjectType, + enable_if_t::value, int> = 0 > -void to_json(Json& j, const CompatibleObjectType& arr) +void to_json(BasicJsonType& j, const CompatibleObjectType& arr) { external_constructor::construct(j, arr); } -template -void from_json(const Json& j, typename Json::boolean_t& b) +template +void from_json(const BasicJsonType& j, typename BasicJsonType::boolean_t& b) { if (!j.is_boolean()) { JSON_THROW(std::domain_error("type must be boolean, but is " + type_name(j))); } - b = *j.template get_ptr(); + b = *j.template get_ptr(); } -template -void from_json(const Json& j, typename Json::string_t& s) +template +void from_json(const BasicJsonType& j, typename BasicJsonType::string_t& s) { if (!j.is_string()) { JSON_THROW(std::domain_error("type must be string, but is " + type_name(j))); } - s = *j.template get_ptr(); + s = *j.template get_ptr(); } -template -void from_json(const Json& j, typename Json::number_float_t& val) +template +void from_json(const BasicJsonType& j, typename BasicJsonType::number_float_t& val) { get_arithmetic_value(j, val); } -template -void from_json(const Json& j, typename Json::number_unsigned_t& val) +template +void from_json(const BasicJsonType& j, typename BasicJsonType::number_unsigned_t& val) { get_arithmetic_value(j, val); } -template -void from_json(const Json& j, typename Json::number_integer_t& val) +template +void from_json(const BasicJsonType& j, typename BasicJsonType::number_integer_t& val) { get_arithmetic_value(j, val); } -template ::value, int> = 0> -void from_json(const Json& j, UnscopedEnumType& e) +void from_json(const BasicJsonType& j, UnscopedEnumType& e) { typename std::underlying_type::type val = e; get_arithmetic_value(j, val); e = static_cast(val); } -template -void from_json(const Json& j, typename Json::array_t& arr) +template +void from_json(const BasicJsonType& j, typename BasicJsonType::array_t& arr) { if (!j.is_array()) { JSON_THROW(std::domain_error("type must be array, but is " + type_name(j))); } - arr = *j.template get_ptr(); + arr = *j.template get_ptr(); } // forward_list doesn't have an insert method, TODO find a way to avoid including forward_list -template -void from_json(const Json& j, std::forward_list& l) +template +void from_json(const BasicJsonType& j, std::forward_list& l) { // do not perform the check when user wants to retrieve jsons // (except when it's null.. ?) @@ -655,7 +655,7 @@ void from_json(const Json& j, std::forward_list& l) { JSON_THROW(std::domain_error("type must be array, but is " + type_name(j))); } - if (not std::is_same::value) + if (not std::is_same::value) { if (!j.is_array()) { @@ -668,23 +668,23 @@ void from_json(const Json& j, std::forward_list& l) } } -template -void from_json_array_impl(const Json& j, CompatibleArrayType& arr, priority_tag<0>) +template +void from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<0>) { using std::begin; using std::end; std::transform( - j.begin(), j.end(), std::inserter(arr, end(arr)), [](const Json & i) + j.begin(), j.end(), std::inserter(arr, end(arr)), [](const BasicJsonType & i) { - // get() returns *this, this won't call a from_json method when - // value_type is Json + // get() returns *this, this won't call a from_json method when + // value_type is BasicJsonType return i.template get(); }); } -template -auto from_json_array_impl(const Json& j, CompatibleArrayType& arr, priority_tag<1>) +template +auto from_json_array_impl(const BasicJsonType& j, CompatibleArrayType& arr, priority_tag<1>) -> decltype( arr.reserve(std::declval()), void()) @@ -694,28 +694,28 @@ auto from_json_array_impl(const Json& j, CompatibleArrayType& arr, priority_tag arr.reserve(j.size()); std::transform( - j.begin(), j.end(), std::inserter(arr, end(arr)), [](const Json & i) + j.begin(), j.end(), std::inserter(arr, end(arr)), [](const BasicJsonType & i) { - // get() returns *this, this won't call a from_json method when - // value_type is Json + // get() returns *this, this won't call a from_json method when + // value_type is BasicJsonType return i.template get(); }); } template < - typename Json, typename CompatibleArrayType, - enable_if_t::value and - not std::is_same::value and + not std::is_same::value, int> = 0 > -void from_json(const Json& j, CompatibleArrayType& arr) +void from_json(const BasicJsonType& j, CompatibleArrayType& arr) { if (j.is_null()) { JSON_THROW(std::domain_error("type must be array, but is " + type_name(j))); } - // when T == Json, do not check if value_t is correct - if (not std::is_same::value) + // when T == BasicJsonType, do not check if value_t is correct + if (not std::is_same::value) { if (!j.is_array()) { @@ -727,17 +727,17 @@ void from_json(const Json& j, CompatibleArrayType& arr) template < - typename Json, typename CompatibleObjectType, - enable_if_t::value, + typename BasicJsonType, typename CompatibleObjectType, + enable_if_t::value, int> = 0 > -void from_json(const Json& j, CompatibleObjectType& obj) +void from_json(const BasicJsonType& j, CompatibleObjectType& obj) { if (!j.is_object()) { JSON_THROW(std::domain_error("type must be object, but is " + type_name(j))); } - auto inner_object = j.template get_ptr(); + auto inner_object = j.template get_ptr(); using std::begin; using std::end; // we could avoid the assignment, but this might require a for loop, which @@ -750,36 +750,36 @@ void from_json(const Json& j, CompatibleObjectType& obj) // note: Is it really necessary to provide explicit overloads for boolean_t etc.. // in case of a custom BooleanType which is not an arithmetic type? template < - typename Json, typename ArithmeticType, + typename BasicJsonType, typename ArithmeticType, enable_if_t < std::is_arithmetic::value and not std::is_same::value and + typename BasicJsonType::number_unsigned_t>::value and not std::is_same::value and + typename BasicJsonType::number_integer_t>::value and not std::is_same::value and - not std::is_same::value, + typename BasicJsonType::number_float_t>::value and + not std::is_same::value, int > = 0 > -void from_json(const Json& j, ArithmeticType& val) +void from_json(const BasicJsonType& j, ArithmeticType& val) { switch (static_cast(j)) { case value_t::number_unsigned: val = static_cast( - *j.template get_ptr()); + *j.template get_ptr()); break; case value_t::number_integer: val = static_cast( - *j.template get_ptr()); + *j.template get_ptr()); break; case value_t::number_float: val = static_cast( - *j.template get_ptr()); + *j.template get_ptr()); break; case value_t::boolean: val = static_cast( - *j.template get_ptr()); + *j.template get_ptr()); break; default: JSON_THROW( @@ -789,8 +789,8 @@ void from_json(const Json& j, ArithmeticType& val) struct to_json_fn { - template - auto call(Json& j, T&& val, priority_tag<1>) const + template + auto call(BasicJsonType& j, T&& val, priority_tag<1>) const noexcept(noexcept(to_json(j, std::forward(val)))) -> decltype(to_json(j, std::forward(val)), void()) @@ -798,15 +798,15 @@ struct to_json_fn return to_json(j, std::forward(val)); } - template - void call(Json&, T&&, priority_tag<0>) const noexcept + template + void call(BasicJsonType&, T&&, priority_tag<0>) const noexcept { - static_assert(sizeof(Json) == 0, "to_json method in T's namespace can not be called"); + static_assert(sizeof(BasicJsonType) == 0, "to_json method in T's namespace can not be called"); } public: - template - void operator()(Json& j, T&& val) const + template + void operator()(BasicJsonType& j, T&& val) const noexcept(noexcept(std::declval().call(j, std::forward(val), priority_tag<1> {}))) { return call(j, std::forward(val), priority_tag<1> {}); @@ -816,23 +816,23 @@ struct to_json_fn struct from_json_fn { private: - template - auto call(const Json& j, T& val, priority_tag<1>) const + template + auto call(const BasicJsonType& j, T& val, priority_tag<1>) const noexcept(noexcept(from_json(j, val))) -> decltype(from_json(j, val), void()) { return from_json(j, val); } - template - void call(const Json&, T&, priority_tag<0>) const noexcept + template + void call(const BasicJsonType&, T&, priority_tag<0>) const noexcept { - static_assert(sizeof(Json) == 0, "from_json method in T's namespace can not be called"); + static_assert(sizeof(BasicJsonType) == 0, "from_json method in T's namespace can not be called"); } public: - template - void operator()(const Json& j, T& val) const + template + void operator()(const BasicJsonType& j, T& val) const noexcept(noexcept(std::declval().call(j, val, priority_tag<1> {}))) { return call(j, val, priority_tag<1> {}); @@ -881,14 +881,14 @@ constexpr const auto& from_json = detail::static_const::va template struct adl_serializer { - template - static void from_json(Json&& j, T& val) noexcept(noexcept(::nlohmann::from_json(std::forward(j), val))) + template + static void from_json(BasicJsonType&& j, T& val) noexcept(noexcept(::nlohmann::from_json(std::forward(j), val))) { - ::nlohmann::from_json(std::forward(j), val); + ::nlohmann::from_json(std::forward(j), val); } - template - static void to_json(Json& j, T&& val) noexcept( + template + static void to_json(BasicJsonType& j, T&& val) noexcept( noexcept(::nlohmann::to_json(j, std::forward(val)))) { ::nlohmann::to_json(j, std::forward(val)); @@ -989,7 +989,7 @@ class basic_json { private: template <::nlohmann::value_t> friend struct detail::external_constructor; - template friend std::string detail::type_name(const Json&); + template friend std::string detail::type_name(const BasicJsonType&); /// workaround type for MSVC using basic_json_t = basic_json -void to_json(Json& j, age a) +template +void to_json(BasicJsonType& j, age a) { j = a.m_val; } -template -void to_json(Json& j, const name& n) +template +void to_json(BasicJsonType& j, const name& n) { j = n.m_val; } -template -void to_json(Json& j, country c) +template +void to_json(BasicJsonType& j, country c) { switch (c) { @@ -113,10 +113,10 @@ void to_json(Json& j, country c) } } -template -void to_json(Json& j, const person& p) +template +void to_json(BasicJsonType& j, const person& p) { - j = Json{{"age", p.m_age}, {"name", p.m_name}, {"country", p.m_country}}; + j = BasicJsonType{{"age", p.m_age}, {"name", p.m_name}, {"country", p.m_country}}; } void to_json(nlohmann::json& j, const address& a) @@ -171,20 +171,20 @@ bool operator==(const contact_book& lhs, const contact_book& rhs) // from_json methods namespace udt { -template -void from_json(const Json& j, age& a) +template +void from_json(const BasicJsonType& j, age& a) { a.m_val = j.template get(); } -template -void from_json(const Json& j, name& n) +template +void from_json(const BasicJsonType& j, name& n) { n.m_val = j.template get(); } -template -void from_json(const Json& j, country& c) +template +void from_json(const BasicJsonType& j, country& c) { const auto str = j.template get(); static const std::map m = @@ -199,8 +199,8 @@ void from_json(const Json& j, country& c) c = it->second; } -template -void from_json(const Json& j, person& p) +template +void from_json(const BasicJsonType& j, person& p) { p.m_age = j["age"].template get(); p.m_name = j["name"].template get(); @@ -493,20 +493,20 @@ struct pod_serializer { // use adl for non-pods, or scalar types template < - typename Json, typename U = T, + typename BasicJsonType, typename U = T, typename std::enable_if < not(std::is_pod::value and std::is_class::value), int >::type = 0 > - static void from_json(const Json& j, U& t) + static void from_json(const BasicJsonType& j, U& t) { using nlohmann::from_json; from_json(j, t); } // special behaviour for pods - template ::value and std::is_class::value, int>::type = 0> - static void from_json(const Json& j, U& t) + static void from_json(const BasicJsonType& j, U& t) { std::uint64_t value; // TODO The following block is no longer relevant in this serializer, make another one that shows the issue @@ -529,19 +529,19 @@ struct pod_serializer } template < - typename Json, typename U = T, + typename BasicJsonType, typename U = T, typename std::enable_if < not(std::is_pod::value and std::is_class::value), int >::type = 0 > - static void to_json(Json& j, const T& t) + static void to_json(BasicJsonType& j, const T& t) { using nlohmann::to_json; to_json(j, t); } - template ::value and std::is_class::value, int>::type = 0> - static void to_json(Json& j, const T& t) noexcept + static void to_json(BasicJsonType& j, const T& t) noexcept { auto bytes = static_cast< const unsigned char*>(static_cast(&t)); std::uint64_t value = bytes[0]; @@ -565,14 +565,14 @@ struct non_pod std::string s; }; -template -void to_json(Json& j, const non_pod& np) +template +void to_json(BasicJsonType& j, const non_pod& np) { j = np.s; } -template -void from_json(const Json& j, non_pod& np) +template +void from_json(const BasicJsonType& j, non_pod& np) { np.s = j.template get(); }