From 51edad39623fa6e565897cdb23b7cbc09a342764 Mon Sep 17 00:00:00 2001 From: Niels Date: Mon, 15 Jun 2015 19:45:25 +0200 Subject: [PATCH] fixed #89 without breaking #71 --- src/json.hpp | 41 ++++++++++++++++++++++++++++++++++------- src/json.hpp.re2c | 41 ++++++++++++++++++++++++++++++++++------- test/unit.cpp | 9 +++++++++ 3 files changed, 77 insertions(+), 14 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index f2a86d15..63f48140 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -425,14 +425,40 @@ class basic_json : m_type(value_t::boolean), m_value(value) {} - /// create an integer number (explicit) - basic_json(const number_integer_t& value) + /*! + @brief create an integer number (explicit) + + @tparam T helper type to compare number_integer_t and int + @param value an integer to create a JSON number from + + This constructor takes care about explicitly passed values of type + number_integer_t. However, this constructor would have the same signature + as the existing one for const int values, so we need to switch this one off + in case number_integer_t is the same as int. + */ + template::value) + and std::is_same::value + , int>::type = 0> + basic_json(const number_integer_t value) : m_type(value_t::number_integer), m_value(value) {} - /// create an int number to support enum type (implicit) - basic_json(const int int_enum) - : basic_json(static_cast(int_enum)) + /*! + @brief create an int number to support enum type (implicit) + + @param value an integer to create a JSON number from + + 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 + that constructor, which is done above. + */ + basic_json(const int value) + : m_type(value_t::number_integer), + m_value(static_cast(value)) {} /// create an integer number (implicit) @@ -442,11 +468,12 @@ class basic_json std::numeric_limits::is_integer, T>::type = 0> basic_json(const T value) noexcept - : basic_json(number_integer_t(value)) + : m_type(value_t::number_integer), + m_value(static_cast(value)) {} /// create a floating-point number (explicit) - basic_json(const number_float_t& value) + basic_json(const number_float_t value) : m_type(value_t::number_float), m_value(value) { // replace infinity and NAN by null diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 2131f47d..dbe03a27 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -425,14 +425,40 @@ class basic_json : m_type(value_t::boolean), m_value(value) {} - /// create an integer number (explicit) - basic_json(const number_integer_t& value) + /*! + @brief create an integer number (explicit) + + @tparam T helper type to compare number_integer_t and int + @param value an integer to create a JSON number from + + This constructor takes care about explicitly passed values of type + number_integer_t. However, this constructor would have the same signature + as the existing one for const int values, so we need to switch this one off + in case number_integer_t is the same as int. + */ + template::value) + and std::is_same::value + , int>::type = 0> + basic_json(const number_integer_t value) : m_type(value_t::number_integer), m_value(value) {} - /// create an int number to support enum type (implicit) - basic_json(const int int_enum) - : basic_json(static_cast(int_enum)) + /*! + @brief create an int number to support enum type (implicit) + + @param value an integer to create a JSON number from + + 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 + that constructor, which is done above. + */ + basic_json(const int value) + : m_type(value_t::number_integer), + m_value(static_cast(value)) {} /// create an integer number (implicit) @@ -442,11 +468,12 @@ class basic_json std::numeric_limits::is_integer, T>::type = 0> basic_json(const T value) noexcept - : basic_json(number_integer_t(value)) + : m_type(value_t::number_integer), + m_value(static_cast(value)) {} /// create a floating-point number (explicit) - basic_json(const number_float_t& value) + basic_json(const number_float_t value) : m_type(value_t::number_float), m_value(value) { // replace infinity and NAN by null diff --git a/test/unit.cpp b/test/unit.cpp index 1dab03d9..cedcb9ba 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -8892,4 +8892,13 @@ TEST_CASE("regression tests") float foo = j["Foo"]; CHECK(foo == Approx(42.42)); } + + SECTION("issue #89 - nonstandard integer type") + { + // create JSON class with nonstandard integer number type + nlohmann::basic_json j; + j["int_1"] = 1; + // we need to cast to int to compile with Catch - the value is int32_t + CHECK(static_cast(j["int_1"]) == 1); + } }