diff --git a/src/json.hpp b/src/json.hpp index 00556604..becbcbd2 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -217,6 +217,18 @@ struct external_constructor j.assert_invariant(); } }; + +template <> +struct external_constructor +{ + template + static void construct(Json &j, const typename Json::string_t& s) + { + j.m_type = value_t::string; + j.m_value = s; + j.assert_invariant(); + } +}; // very useful construct against boilerplate (more boilerplate needed than in // C++17: http://en.cppreference.com/w/cpp/types/void_t) template struct make_void @@ -328,12 +340,14 @@ struct is_compatible_array_type { // the check for CompatibleArrayType = void is done in // `is_compatible_object_type`, but we need the conjunction here as well - static auto constexpr value = is_compatible_array_type_impl < - conjunction>, - has_value_type, - has_iterator>::value, - BasicJson, CompatibleArrayType >::value; + static auto constexpr value = is_compatible_array_type_impl< + conjunction>, + negation>, + has_value_type, + has_iterator>::value, + BasicJson, CompatibleArrayType>::value; }; template @@ -376,7 +390,6 @@ struct is_compatible_basic_json_type static auto constexpr value = is_unscoped_enum::value or std::is_same::value or - std::is_constructible::value or is_compatible_array_type::value or is_compatible_object_type::value or is_compatible_float_type::value or @@ -457,6 +470,15 @@ void to_json(Json &j, typename Json::boolean_t b) noexcept external_constructor::construct(j, b); } +template ::value, + int> = 0> +void to_json(Json &j, const CompatibleString &s) +{ + external_constructor::construct(j, s); +} + template void from_json(Json const& j, typename Json::boolean_t& b) { @@ -465,6 +487,14 @@ void from_json(Json const& j, typename Json::boolean_t& b) b = *const_cast(j).template get_ptr(); } +template +void from_json(Json const& j, typename Json::string_t& s) +{ + if (!j.is_string()) + throw std::domain_error("type must be string, but is " + type_name(j)); + s = *const_cast(j).template get_ptr(); +} + struct to_json_fn { // is it really useful to mark those as constexpr? @@ -1680,90 +1710,6 @@ class basic_json JSONSerializer>::to_json(*this, std::forward(val)); } - /*! - @brief create a string (explicit) - - Create an string JSON value with a given content. - - @param[in] val a value for the string - - @complexity Linear in the size of the passed @a val. - - @throw std::bad_alloc if allocation for string value fails - - @liveexample{The following code shows the constructor with an @ref - string_t parameter.,basic_json__string_t} - - @sa @ref basic_json(const typename string_t::value_type*) -- create a - string value from a character pointer - @sa @ref basic_json(const CompatibleStringType&) -- create a string value - from a compatible string container - - @since version 1.0.0 - */ - basic_json(const string_t& val) - : m_type(value_t::string), m_value(val) - { - assert_invariant(); - } - - /*! - @brief create a string (explicit) - - Create a string JSON value with a given content. - - @param[in] val a literal value for the string - - @complexity Linear in the size of the passed @a val. - - @throw std::bad_alloc if allocation for string value fails - - @liveexample{The following code shows the constructor with string literal - parameter.,basic_json__string_t_value_type} - - @sa @ref basic_json(const string_t&) -- create a string value - @sa @ref basic_json(const CompatibleStringType&) -- create a string value - from a compatible string container - - @since version 1.0.0 - */ - basic_json(const typename string_t::value_type* val) - : basic_json(string_t(val)) - { - assert_invariant(); - } - - /*! - @brief create a string (implicit) - - Create a string JSON value with a given content. - - @param[in] val a value for the string - - @tparam CompatibleStringType an string type which is compatible to @ref - string_t, for instance `std::string`. - - @complexity Linear in the size of the passed @a val. - - @throw std::bad_alloc if allocation for string value fails - - @liveexample{The following code shows the construction of a string value - from a compatible type.,basic_json__CompatibleStringType} - - @sa @ref basic_json(const string_t&) -- create a string value - @sa @ref basic_json(const typename string_t::value_type*) -- create a - string value from a character pointer - - @since version 1.0.0 - */ - template::value, int>::type = 0> - basic_json(const CompatibleStringType& val) - : basic_json(string_t(val)) - { - assert_invariant(); - } - /*! @brief create an integer number (explicit) @@ -11505,9 +11451,21 @@ basic_json_parser_66: } private: + friend bool operator==(json_pointer const &lhs, + json_pointer const &rhs) noexcept + { + return lhs.reference_tokens == rhs.reference_tokens; + } + + friend bool operator!=(json_pointer const &lhs, + json_pointer const &rhs) noexcept + { + return !(lhs == rhs); + } + /// the reference tokens std::vector reference_tokens {}; - }; + }; ////////////////////////// // JSON Pointer support // diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 067ad1a6..0122e8b5 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -217,6 +217,18 @@ struct external_constructor j.assert_invariant(); } }; + +template <> +struct external_constructor +{ + template + static void construct(Json &j, const typename Json::string_t& s) + { + j.m_type = value_t::string; + j.m_value = s; + j.assert_invariant(); + } +}; // very useful construct against boilerplate (more boilerplate needed than in // C++17: http://en.cppreference.com/w/cpp/types/void_t) template struct make_void @@ -328,12 +340,14 @@ struct is_compatible_array_type { // the check for CompatibleArrayType = void is done in // `is_compatible_object_type`, but we need the conjunction here as well - static auto constexpr value = is_compatible_array_type_impl < - conjunction>, - has_value_type, - has_iterator>::value, - BasicJson, CompatibleArrayType >::value; + static auto constexpr value = is_compatible_array_type_impl< + conjunction>, + negation>, + has_value_type, + has_iterator>::value, + BasicJson, CompatibleArrayType>::value; }; template @@ -376,7 +390,6 @@ struct is_compatible_basic_json_type static auto constexpr value = is_unscoped_enum::value or std::is_same::value or - std::is_constructible::value or is_compatible_array_type::value or is_compatible_object_type::value or is_compatible_float_type::value or @@ -457,6 +470,15 @@ void to_json(Json &j, typename Json::boolean_t b) noexcept external_constructor::construct(j, b); } +template ::value, + int> = 0> +void to_json(Json &j, const CompatibleString &s) +{ + external_constructor::construct(j, s); +} + template void from_json(Json const& j, typename Json::boolean_t& b) { @@ -465,6 +487,14 @@ void from_json(Json const& j, typename Json::boolean_t& b) b = *const_cast(j).template get_ptr(); } +template +void from_json(Json const& j, typename Json::string_t& s) +{ + if (!j.is_string()) + throw std::domain_error("type must be string, but is " + type_name(j)); + s = *const_cast(j).template get_ptr(); +} + struct to_json_fn { // is it really useful to mark those as constexpr? @@ -1681,90 +1711,6 @@ class basic_json JSONSerializer>::to_json(*this, std::forward(val)); } - /*! - @brief create a string (explicit) - - Create an string JSON value with a given content. - - @param[in] val a value for the string - - @complexity Linear in the size of the passed @a val. - - @throw std::bad_alloc if allocation for string value fails - - @liveexample{The following code shows the constructor with an @ref - string_t parameter.,basic_json__string_t} - - @sa @ref basic_json(const typename string_t::value_type*) -- create a - string value from a character pointer - @sa @ref basic_json(const CompatibleStringType&) -- create a string value - from a compatible string container - - @since version 1.0.0 - */ - basic_json(const string_t& val) - : m_type(value_t::string), m_value(val) - { - assert_invariant(); - } - - /*! - @brief create a string (explicit) - - Create a string JSON value with a given content. - - @param[in] val a literal value for the string - - @complexity Linear in the size of the passed @a val. - - @throw std::bad_alloc if allocation for string value fails - - @liveexample{The following code shows the constructor with string literal - parameter.,basic_json__string_t_value_type} - - @sa @ref basic_json(const string_t&) -- create a string value - @sa @ref basic_json(const CompatibleStringType&) -- create a string value - from a compatible string container - - @since version 1.0.0 - */ - basic_json(const typename string_t::value_type* val) - : basic_json(string_t(val)) - { - assert_invariant(); - } - - /*! - @brief create a string (implicit) - - Create a string JSON value with a given content. - - @param[in] val a value for the string - - @tparam CompatibleStringType an string type which is compatible to @ref - string_t, for instance `std::string`. - - @complexity Linear in the size of the passed @a val. - - @throw std::bad_alloc if allocation for string value fails - - @liveexample{The following code shows the construction of a string value - from a compatible type.,basic_json__CompatibleStringType} - - @sa @ref basic_json(const string_t&) -- create a string value - @sa @ref basic_json(const typename string_t::value_type*) -- create a - string value from a character pointer - - @since version 1.0.0 - */ - template::value, int>::type = 0> - basic_json(const CompatibleStringType& val) - : basic_json(string_t(val)) - { - assert_invariant(); - } - /*! @brief create an integer number (explicit) @@ -11131,9 +11077,21 @@ class basic_json } private: + friend bool operator==(json_pointer const &lhs, + json_pointer const &rhs) noexcept + { + return lhs.reference_tokens == rhs.reference_tokens; + } + + friend bool operator!=(json_pointer const &lhs, + json_pointer const &rhs) noexcept + { + return !(lhs == rhs); + } + /// the reference tokens std::vector reference_tokens {}; - }; + }; ////////////////////////// // JSON Pointer support //