From f00898331e548e864b6d37f70c5470a841fe6cca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20DELRIEU?= Date: Sun, 8 Jan 2017 14:06:25 +0100 Subject: [PATCH] replace constructor by from/to_json: number_integer_t --- src/json.hpp | 129 +++++++++++----------------------------------- src/json.hpp.re2c | 129 +++++++++++----------------------------------- 2 files changed, 62 insertions(+), 196 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index f3464894..9f8f3145 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -260,6 +260,18 @@ struct external_constructor } }; +template <> +struct external_constructor +{ + template + static void construct(Json &j, typename Json::number_integer_t val) noexcept + { + j.m_type = value_t::number_integer; + j.m_value = val; + 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 @@ -387,6 +399,7 @@ struct is_compatible_integer_type_impl : std::false_type {}; template struct is_compatible_integer_type_impl { + // is there an assert somewhere on overflows? using RealLimits = std::numeric_limits; using CompatibleLimits = std::numeric_limits; @@ -402,7 +415,7 @@ struct is_compatible_integer_type { static constexpr auto value = is_compatible_integer_type_impl < - std::is_arithmetic::value and + std::is_integral::value and not std::is_same::value, RealIntegerType, CompatibleNumberIntegerType > ::value; }; @@ -422,8 +435,7 @@ struct is_compatible_basic_json_type is_unscoped_enum::value or std::is_same::value or is_compatible_array_type::value or - is_compatible_object_type::value or - is_compatible_integer_type::value; + is_compatible_object_type::value; }; template @@ -547,6 +559,16 @@ void to_json(Json &j, CompatibleNumberUnsignedType val) noexcept external_constructor::construct(j, val); } +template < + typename Json, typename CompatibleNumberIntegerType, + enable_if_t::value, + int> = 0> +void to_json(Json &j, CompatibleNumberIntegerType val) noexcept +{ + external_constructor::construct(j, val); +} + template void from_json(Json const& j, typename Json::boolean_t& b) { @@ -575,6 +597,12 @@ void from_json(Json const& j, typename Json::number_unsigned_t& val) get_arithmetic_value(j, val); } +template +void from_json(Json const& j, typename Json::number_integer_t& val) +{ + get_arithmetic_value(j, val); +} + // overload for arithmetic types, not chosen for basic_json template arguments (BooleanType, etc..) // // note: Is it really necessary to provide explicit overloads for boolean_t etc.. @@ -1820,64 +1848,6 @@ class basic_json JSONSerializer>::to_json(*this, std::forward(val)); } - /*! - @brief create an integer number (explicit) - - Create an integer number JSON value with a given content. - - @tparam T A helper type to remove this function via SFINAE in case @ref - number_integer_t is the same as `int`. In this case, this constructor - would have the same signature as @ref basic_json(const int value). Note - the helper type @a T is not visible in this constructor's interface. - - @param[in] val an integer to create a JSON number from - - @complexity Constant. - - @liveexample{The example below shows the construction of an integer - number value.,basic_json__number_integer_t} - - @sa @ref basic_json(const int) -- create a number value (integer) - @sa @ref basic_json(const CompatibleNumberIntegerType) -- create a number - value (integer) from a compatible number type - - @since version 1.0.0 - */ - template::value) and - std::is_same::value, int>::type = 0> - basic_json(const number_integer_t val) noexcept - : m_type(value_t::number_integer), m_value(val) - { - assert_invariant(); - } - - /*! - @brief create an integer number from an enum type (explicit) - - Create an integer number JSON value with a given content. - - @param[in] val an integer to create a JSON number from - - @note This constructor allows to pass enums directly to a constructor. As - C++ has no way of specifying the type of an anonymous enum explicitly, we - can only rely on the fact that such values implicitly convert to int. As - int may already be the same type of number_integer_t, we may need to - switch off the constructor @ref basic_json(const number_integer_t). - - @complexity Constant. - - @liveexample{The example below shows the construction of an integer - number value from an anonymous enum.,basic_json__const_int} - - @sa @ref basic_json(const number_integer_t) -- create a number value - (integer) - @sa @ref basic_json(const CompatibleNumberIntegerType) -- create a number - value (integer) from a compatible number type - - @since version 1.0.0 - */ - // Constructor for unscoped enums (not enum classes) template ::value, int> = 0> basic_json(T val) noexcept @@ -1887,43 +1857,6 @@ class basic_json assert_invariant(); } - /*! - @brief create an integer number (implicit) - - Create an integer number JSON value with a given content. This constructor - allows any type @a CompatibleNumberIntegerType that can be used to - construct values of type @ref number_integer_t. - - @tparam CompatibleNumberIntegerType An integer type which is compatible to - @ref number_integer_t. Examples include the types `int`, `int32_t`, - `long`, and `short`. - - @param[in] val an integer to create a JSON number from - - @complexity Constant. - - @liveexample{The example below shows the construction of several integer - number values from compatible - types.,basic_json__CompatibleIntegerNumberType} - - @sa @ref basic_json(const number_integer_t) -- create a number value - (integer) - @sa @ref basic_json(const int) -- create a number value (integer) - - @since version 1.0.0 - */ - template < - typename CompatibleNumberIntegerType, - enable_if_t::value, - int> = 0 > - basic_json(const CompatibleNumberIntegerType val) noexcept - : m_type(value_t::number_integer), - m_value(static_cast(val)) - { - assert_invariant(); - } - /*! @brief create a container (array or object) from an initializer list diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index a7841f6f..909ce90d 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -260,6 +260,18 @@ struct external_constructor } }; +template <> +struct external_constructor +{ + template + static void construct(Json &j, typename Json::number_integer_t val) noexcept + { + j.m_type = value_t::number_integer; + j.m_value = val; + 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 @@ -387,6 +399,7 @@ struct is_compatible_integer_type_impl : std::false_type {}; template struct is_compatible_integer_type_impl { + // is there an assert somewhere on overflows? using RealLimits = std::numeric_limits; using CompatibleLimits = std::numeric_limits; @@ -402,7 +415,7 @@ struct is_compatible_integer_type { static constexpr auto value = is_compatible_integer_type_impl < - std::is_arithmetic::value and + std::is_integral::value and not std::is_same::value, RealIntegerType, CompatibleNumberIntegerType > ::value; }; @@ -422,8 +435,7 @@ struct is_compatible_basic_json_type is_unscoped_enum::value or std::is_same::value or is_compatible_array_type::value or - is_compatible_object_type::value or - is_compatible_integer_type::value; + is_compatible_object_type::value; }; template @@ -547,6 +559,16 @@ void to_json(Json &j, CompatibleNumberUnsignedType val) noexcept external_constructor::construct(j, val); } +template < + typename Json, typename CompatibleNumberIntegerType, + enable_if_t::value, + int> = 0> +void to_json(Json &j, CompatibleNumberIntegerType val) noexcept +{ + external_constructor::construct(j, val); +} + template void from_json(Json const& j, typename Json::boolean_t& b) { @@ -575,6 +597,12 @@ void from_json(Json const& j, typename Json::number_unsigned_t& val) get_arithmetic_value(j, val); } +template +void from_json(Json const& j, typename Json::number_integer_t& val) +{ + get_arithmetic_value(j, val); +} + // overload for arithmetic types, not chosen for basic_json template arguments (BooleanType, etc..) // // note: Is it really necessary to provide explicit overloads for boolean_t etc.. @@ -1821,64 +1849,6 @@ class basic_json JSONSerializer>::to_json(*this, std::forward(val)); } - /*! - @brief create an integer number (explicit) - - Create an integer number JSON value with a given content. - - @tparam T A helper type to remove this function via SFINAE in case @ref - number_integer_t is the same as `int`. In this case, this constructor - would have the same signature as @ref basic_json(const int value). Note - the helper type @a T is not visible in this constructor's interface. - - @param[in] val an integer to create a JSON number from - - @complexity Constant. - - @liveexample{The example below shows the construction of an integer - number value.,basic_json__number_integer_t} - - @sa @ref basic_json(const int) -- create a number value (integer) - @sa @ref basic_json(const CompatibleNumberIntegerType) -- create a number - value (integer) from a compatible number type - - @since version 1.0.0 - */ - template::value) and - std::is_same::value, int>::type = 0> - basic_json(const number_integer_t val) noexcept - : m_type(value_t::number_integer), m_value(val) - { - assert_invariant(); - } - - /*! - @brief create an integer number from an enum type (explicit) - - Create an integer number JSON value with a given content. - - @param[in] val an integer to create a JSON number from - - @note This constructor allows to pass enums directly to a constructor. As - C++ has no way of specifying the type of an anonymous enum explicitly, we - can only rely on the fact that such values implicitly convert to int. As - int may already be the same type of number_integer_t, we may need to - switch off the constructor @ref basic_json(const number_integer_t). - - @complexity Constant. - - @liveexample{The example below shows the construction of an integer - number value from an anonymous enum.,basic_json__const_int} - - @sa @ref basic_json(const number_integer_t) -- create a number value - (integer) - @sa @ref basic_json(const CompatibleNumberIntegerType) -- create a number - value (integer) from a compatible number type - - @since version 1.0.0 - */ - // Constructor for unscoped enums (not enum classes) template ::value, int> = 0> basic_json(T val) noexcept @@ -1888,43 +1858,6 @@ class basic_json assert_invariant(); } - /*! - @brief create an integer number (implicit) - - Create an integer number JSON value with a given content. This constructor - allows any type @a CompatibleNumberIntegerType that can be used to - construct values of type @ref number_integer_t. - - @tparam CompatibleNumberIntegerType An integer type which is compatible to - @ref number_integer_t. Examples include the types `int`, `int32_t`, - `long`, and `short`. - - @param[in] val an integer to create a JSON number from - - @complexity Constant. - - @liveexample{The example below shows the construction of several integer - number values from compatible - types.,basic_json__CompatibleIntegerNumberType} - - @sa @ref basic_json(const number_integer_t) -- create a number value - (integer) - @sa @ref basic_json(const int) -- create a number value (integer) - - @since version 1.0.0 - */ - template < - typename CompatibleNumberIntegerType, - enable_if_t::value, - int> = 0 > - basic_json(const CompatibleNumberIntegerType val) noexcept - : m_type(value_t::number_integer), - m_value(static_cast(val)) - { - assert_invariant(); - } - /*! @brief create a container (array or object) from an initializer list