From bd2783f45ca91adee7b368f94651fee673844ecb Mon Sep 17 00:00:00 2001 From: dariomt Date: Fri, 16 Oct 2015 15:23:57 +0200 Subject: [PATCH 1/8] Added get_ref() Same as get_ptr() but for references. If the type is incompatible it throws (get_ptr() returns null). Implemented in terms of get_ptr(). --- doc/examples/get_ref.cpp | 26 ++++++ src/json.hpp | 63 ++++++++++++- test/unit.cpp | 186 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 273 insertions(+), 2 deletions(-) create mode 100644 doc/examples/get_ref.cpp diff --git a/doc/examples/get_ref.cpp b/doc/examples/get_ref.cpp new file mode 100644 index 000000000..a8a868532 --- /dev/null +++ b/doc/examples/get_ref.cpp @@ -0,0 +1,26 @@ +#include + +using namespace nlohmann; + +int main() +{ + // create a JSON number + json value = 17; + + // explicitly getting references + auto r1 = value.get_ref(); + auto r2 = value.get_ref(); + + // print the values + std::cout << r1 << ' ' << r2 << '\n'; + + // incompatible type throws exception + try + { + auto r3 = value.get_ref(); + } + catch(std::domain_error& ex) + { + std::cout << ex.what() << '\n'; + } +} diff --git a/src/json.hpp b/src/json.hpp index 68c78b539..d45ab015a 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -2251,6 +2251,19 @@ class basic_json return is_number_float() ? &m_value.number_float : nullptr; } + /// helper function to implement get_ref without code duplication + /// for const and non-const overloads + /// ThisType will be deduced as 'basic_jason' or 'const basic_json' + template + static ReferenceType get_ref_impl(ThisType& obj) + { + using PointerType = std::add_pointer::type; + // delegate the call to get_ptr<>() + auto ptr = obj.get_ptr(); + if (ptr) return *ptr; + throw std::domain_error("incompatible ReferenceType for get_ref, actual type is " + obj.type_name()); + } + public: /// @name value access @@ -2387,10 +2400,56 @@ class basic_json std::is_pointer::value and std::is_const< typename std::remove_pointer::type >::value , int>::type = 0> - const PointerType get_ptr() const noexcept + PointerType get_ptr() const noexcept { // delegate the call to get_impl_ptr<>() const - return get_impl_ptr(static_cast(nullptr)); + return get_impl_ptr(static_cast(nullptr)); + } + + /*! + @brief get a reference value (implicit) + + Implict reference access to the internally stored JSON value. No copies are + made. + + @warning Writing data to the referee of the result yields an undefined + state. + + @tparam ReferenceType reference type; must be a reference to @ref array_t, @ref + object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or @ref + number_float_t. + + @return reference to the internally stored JSON value if the requested reference + type @a ReferenceType fits to the JSON value; throws std::domain_error otherwise + + @throw std::domain_error in case passed type @a ReferenceType is incompatible + with the stored JSON value + + @complexity Constant. + */ + template::value + , int>::type = 0> + ReferenceType get_ref() + { + // delegate call to get_ref_impl + return get_ref_impl(*this); + } + + /*! + @brief get a reference value (implicit) + @copydoc get_ref() + */ + template::value + and std::is_const< typename std::remove_reference::type >::value + , int>::type = 0> + ReferenceType get_ref() const + { + // delegate call to get_ref_impl + return get_ref_impl(*this); } /*! diff --git a/test/unit.cpp b/test/unit.cpp index d12bc38ed..47a7a7512 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -2494,6 +2494,22 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() == nullptr); } + SECTION("pointer access to const object_t") + { + using test_type = json::object_t; + const json value = {{"one", 1}, {"two", 2}}; + + // this should not compile + // test_type* p1 = value.get_ptr(); + + // check if pointers are returned correctly + const test_type* p2 = value.get_ptr(); + CHECK(*p2 == value.get()); + + const test_type* const p3 = value.get_ptr(); + CHECK(p2 == p3); + } + SECTION("pointer access to array_t") { using test_type = json::array_t; @@ -2630,6 +2646,176 @@ TEST_CASE("pointer access") } } +TEST_CASE("reference access") +{ + // create a JSON value with different types + json json_types = + { + {"boolean", true}, + { + "number", { + {"integer", 42}, + {"floating-point", 17.23} + } + }, + {"string", "Hello, world!"}, + {"array", {1, 2, 3, 4, 5}}, + {"null", nullptr} + }; + + SECTION("reference access to object_t") + { + using test_type = json::object_t; + json value = {{"one", 1}, {"two", 2}}; + + // check if references are returned correctly + test_type& p1 = value.get_ref(); + CHECK(&p1 == value.get_ptr()); + CHECK(p1 == value.get()); + + const test_type& p2 = value.get_ref(); + CHECK(&p2 == value.get_ptr()); + CHECK(p2 == value.get()); + + // check if mismatching references throw correctly + CHECK_NOTHROW(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + } + + SECTION("const reference access to const object_t") + { + using test_type = json::object_t; + const json value = {{"one", 1}, {"two", 2}}; + + // this should not compile + // test_type& p1 = value.get_ref(); + + // check if references are returned correctly + const test_type& p2 = value.get_ref(); + CHECK(&p2 == value.get_ptr()); + CHECK(p2 == value.get()); + } + + SECTION("reference access to array_t") + { + using test_type = json::array_t; + json value = {1, 2, 3, 4}; + + // check if references are returned correctly + test_type& p1 = value.get_ref(); + CHECK(&p1 == value.get_ptr()); + CHECK(p1 == value.get()); + + const test_type& p2 = value.get_ref(); + CHECK(&p2 == value.get_ptr()); + CHECK(p2 == value.get()); + + // check if mismatching references throw correctly + CHECK_THROWS(value.get_ref()); + CHECK_NOTHROW(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + } + + SECTION("reference access to string_t") + { + using test_type = json::string_t; + json value = "hello"; + + // check if references are returned correctly + test_type& p1 = value.get_ref(); + CHECK(&p1 == value.get_ptr()); + CHECK(p1 == value.get()); + + const test_type& p2 = value.get_ref(); + CHECK(&p2 == value.get_ptr()); + CHECK(p2 == value.get()); + + // check if mismatching references throw correctly + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_NOTHROW(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + } + + SECTION("reference access to boolean_t") + { + using test_type = json::boolean_t; + json value = false; + + // check if references are returned correctly + test_type& p1 = value.get_ref(); + CHECK(&p1 == value.get_ptr()); + CHECK(p1 == value.get()); + + const test_type& p2 = value.get_ref(); + CHECK(&p2 == value.get_ptr()); + CHECK(p2 == value.get()); + + // check if mismatching references throw correctly + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_NOTHROW(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + } + + SECTION("reference access to number_integer_t") + { + using test_type = json::number_integer_t; + json value = 23; + + // check if references are returned correctly + test_type& p1 = value.get_ref(); + CHECK(&p1 == value.get_ptr()); + CHECK(p1 == value.get()); + + const test_type& p2 = value.get_ref(); + CHECK(&p2 == value.get_ptr()); + CHECK(p2 == value.get()); + + // check if mismatching references throw correctly + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_NOTHROW(value.get_ref()); + CHECK_THROWS(value.get_ref()); + } + + SECTION("reference access to number_float_t") + { + using test_type = json::number_float_t; + json value = 42.23; + + // check if references are returned correctly + test_type& p1 = value.get_ref(); + CHECK(&p1 == value.get_ptr()); + CHECK(p1 == value.get()); + + const test_type& p2 = value.get_ref(); + CHECK(&p2 == value.get_ptr()); + CHECK(p2 == value.get()); + + // check if mismatching references throw correctly + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_THROWS(value.get_ref()); + CHECK_NOTHROW(value.get_ref()); + } +} + TEST_CASE("element access") { SECTION("array") From 5198e1f2e46a5aeab7c836ad43bc450c53fcd084 Mon Sep 17 00:00:00 2001 From: dariomt Date: Fri, 16 Oct 2015 15:45:47 +0200 Subject: [PATCH 2/8] removed const in get_ptr() by accident --- src/json.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index d45ab015a..30e6b2fe3 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -2400,10 +2400,10 @@ class basic_json std::is_pointer::value and std::is_const< typename std::remove_pointer::type >::value , int>::type = 0> - PointerType get_ptr() const noexcept + const PointerType get_ptr() const noexcept { // delegate the call to get_impl_ptr<>() const - return get_impl_ptr(static_cast(nullptr)); + return get_impl_ptr(static_cast(nullptr)); } /*! From 4d079d135e7e21df3b3bd1126aa69011bde5be18 Mon Sep 17 00:00:00 2001 From: dariomt Date: Mon, 18 Jan 2016 11:32:24 +0100 Subject: [PATCH 3/8] replicate code changes into re2c file --- src/json.hpp.re2c | 59 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index a733f0979..474cb7500 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -2416,6 +2416,19 @@ class basic_json return is_number_float() ? &m_value.number_float : nullptr; } + /// helper function to implement get_ref without code duplication + /// for const and non-const overloads + /// ThisType will be deduced as 'basic_jason' or 'const basic_json' + template + static ReferenceType get_ref_impl(ThisType& obj) + { + using PointerType = std::add_pointer::type; + // delegate the call to get_ptr<>() + auto ptr = obj.get_ptr(); + if (ptr) return *ptr; + throw std::domain_error("incompatible ReferenceType for get_ref, actual type is " + obj.type_name()); + } + public: /// @name value access @@ -2563,6 +2576,52 @@ class basic_json return get_impl_ptr(static_cast(nullptr)); } + /*! + @brief get a reference value (implicit) + + Implict reference access to the internally stored JSON value. No copies are + made. + + @warning Writing data to the referee of the result yields an undefined + state. + + @tparam ReferenceType reference type; must be a reference to @ref array_t, @ref + object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or @ref + number_float_t. + + @return reference to the internally stored JSON value if the requested reference + type @a ReferenceType fits to the JSON value; throws std::domain_error otherwise + + @throw std::domain_error in case passed type @a ReferenceType is incompatible + with the stored JSON value + + @complexity Constant. + */ + template::value + , int>::type = 0> + ReferenceType get_ref() + { + // delegate call to get_ref_impl + return get_ref_impl(*this); + } + + /*! + @brief get a reference value (implicit) + @copydoc get_ref() + */ + template::value + and std::is_const< typename std::remove_reference::type >::value + , int>::type = 0> + ReferenceType get_ref() const + { + // delegate call to get_ref_impl + return get_ref_impl(*this); + } + /*! @brief get a value (implicit) From e2f0e8b945abe86906455139274fc37f1b9afdb4 Mon Sep 17 00:00:00 2001 From: dariomt Date: Tue, 19 Jan 2016 14:56:07 +0100 Subject: [PATCH 4/8] added missing typename (required by clang/gcc) --- src/json.hpp | 2 +- src/json.hpp.re2c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index db3d13aa6..920dd4d68 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -2422,7 +2422,7 @@ class basic_json template static ReferenceType get_ref_impl(ThisType& obj) { - using PointerType = std::add_pointer::type; + using PointerType = typename std::add_pointer::type; // delegate the call to get_ptr<>() auto ptr = obj.get_ptr(); if (ptr) return *ptr; diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 474cb7500..13f749930 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -2422,7 +2422,7 @@ class basic_json template static ReferenceType get_ref_impl(ThisType& obj) { - using PointerType = std::add_pointer::type; + using PointerType = typename std::add_pointer::type; // delegate the call to get_ptr<>() auto ptr = obj.get_ptr(); if (ptr) return *ptr; From db3c7fdb967ed42a0d39aff43ef0d9cdc145f2b0 Mon Sep 17 00:00:00 2001 From: dariomt Date: Tue, 19 Jan 2016 16:20:27 +0100 Subject: [PATCH 5/8] added missing template keyword (required by clang) --- src/json.hpp | 2 +- src/json.hpp.re2c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/json.hpp b/src/json.hpp index 920dd4d68..81c02857f 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -2424,7 +2424,7 @@ class basic_json { using PointerType = typename std::add_pointer::type; // delegate the call to get_ptr<>() - auto ptr = obj.get_ptr(); + auto ptr = obj.template get_ptr(); if (ptr) return *ptr; throw std::domain_error("incompatible ReferenceType for get_ref, actual type is " + obj.type_name()); } diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 13f749930..0838b234d 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -2424,7 +2424,7 @@ class basic_json { using PointerType = typename std::add_pointer::type; // delegate the call to get_ptr<>() - auto ptr = obj.get_ptr(); + auto ptr = obj.template get_ptr(); if (ptr) return *ptr; throw std::domain_error("incompatible ReferenceType for get_ref, actual type is " + obj.type_name()); } From a04bd4f851d57c0483455a728e6286e2b5261f6e Mon Sep 17 00:00:00 2001 From: Niels Date: Wed, 20 Jan 2016 21:14:58 +0100 Subject: [PATCH 6/8] cleanup after #184 --- README.md | 2 +- doc/examples/get_ref.cpp | 4 +-- doc/examples/get_ref.link | 1 + doc/examples/get_ref.output | 2 ++ src/json.hpp | 61 +++++++++++++++++++++++++------------ src/json.hpp.re2c | 61 +++++++++++++++++++++++++------------ test/unit.cpp | 30 +++++++++--------- 7 files changed, 103 insertions(+), 58 deletions(-) create mode 100644 doc/examples/get_ref.link create mode 100644 doc/examples/get_ref.output diff --git a/README.md b/README.md index 95e920f1b..68d4a1fb8 100644 --- a/README.md +++ b/README.md @@ -382,7 +382,7 @@ I deeply appreciate the help of the following people. - [Colin Hirsch](https://github.com/ColinH) took care of a small namespace issue. - [Huu Nguyen](https://github.com/whoshuu) correct a variable name in the documentation. - [Silverweed](https://github.com/silverweed) overloaded `parse()` to accept an rvalue reference. -- [dariomt](https://github.com/dariomt) fixed a subtlety in MSVC type support. +- [dariomt](https://github.com/dariomt) fixed a subtlety in MSVC type support and implemented the `get_ref()` function to get a reference to stored values. - [ZahlGraf](https://github.com/ZahlGraf) added a workaround that allows compilation using Android NDK. - [whackashoe](https://github.com/whackashoe) replaced a function that was marked as unsafe by Visual Studio. - [406345](https://github.com/406345) fixed two small warnings. diff --git a/doc/examples/get_ref.cpp b/doc/examples/get_ref.cpp index a8a868532..c73cff3e4 100644 --- a/doc/examples/get_ref.cpp +++ b/doc/examples/get_ref.cpp @@ -13,13 +13,13 @@ int main() // print the values std::cout << r1 << ' ' << r2 << '\n'; - + // incompatible type throws exception try { auto r3 = value.get_ref(); } - catch(std::domain_error& ex) + catch (std::domain_error& ex) { std::cout << ex.what() << '\n'; } diff --git a/doc/examples/get_ref.link b/doc/examples/get_ref.link new file mode 100644 index 000000000..4c8fd69af --- /dev/null +++ b/doc/examples/get_ref.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/get_ref.output b/doc/examples/get_ref.output new file mode 100644 index 000000000..50bc0df69 --- /dev/null +++ b/doc/examples/get_ref.output @@ -0,0 +1,2 @@ +17 17 +incompatible ReferenceType for get_ref, actual type is number diff --git a/src/json.hpp b/src/json.hpp index 81c02857f..343d23565 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -2416,17 +2416,33 @@ class basic_json return is_number_float() ? &m_value.number_float : nullptr; } - /// helper function to implement get_ref without code duplication - /// for const and non-const overloads - /// ThisType will be deduced as 'basic_jason' or 'const basic_json' - template + /*! + @brief helper function to implement get_ref() + + This funcion helps to implement get_ref() without code duplication for + const and non-const overloads + + @tparam ThisType will be deduced as `basic_json` or `const basic_json` + + @throw std::domain_error if ReferenceType does not match underlying value + type of the current JSON + */ + template static ReferenceType get_ref_impl(ThisType& obj) { - using PointerType = typename std::add_pointer::type; // delegate the call to get_ptr<>() + using PointerType = typename std::add_pointer::type; auto ptr = obj.template get_ptr(); - if (ptr) return *ptr; - throw std::domain_error("incompatible ReferenceType for get_ref, actual type is " + obj.type_name()); + + if (ptr != nullptr) + { + return *ptr; + } + else + { + throw std::domain_error("incompatible ReferenceType for get_ref, actual type is " + + obj.type_name()); + } } public: @@ -2576,7 +2592,7 @@ class basic_json return get_impl_ptr(static_cast(nullptr)); } - /*! + /*! @brief get a reference value (implicit) Implict reference access to the internally stored JSON value. No copies are @@ -2585,17 +2601,22 @@ class basic_json @warning Writing data to the referee of the result yields an undefined state. - @tparam ReferenceType reference type; must be a reference to @ref array_t, @ref - object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or @ref - number_float_t. + @tparam ReferenceType reference type; must be a reference to @ref array_t, + @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or + @ref number_float_t. - @return reference to the internally stored JSON value if the requested reference - type @a ReferenceType fits to the JSON value; throws std::domain_error otherwise + @return reference to the internally stored JSON value if the requested + reference type @a ReferenceType fits to the JSON value; throws + std::domain_error otherwise - @throw std::domain_error in case passed type @a ReferenceType is incompatible - with the stored JSON value + @throw std::domain_error in case passed type @a ReferenceType is + incompatible with the stored JSON value @complexity Constant. + + @liveexample{The example shows several calls to `get_ref()`.,get_ref} + + @since version 1.0.1 */ template::type = 0> ReferenceType get_ref() { - // delegate call to get_ref_impl - return get_ref_impl(*this); + // delegate call to get_ref_impl + return get_ref_impl(*this); } /*! @@ -2614,12 +2635,12 @@ class basic_json template::value - and std::is_const< typename std::remove_reference::type >::value + and std::is_const::type>::value , int>::type = 0> ReferenceType get_ref() const { - // delegate call to get_ref_impl - return get_ref_impl(*this); + // delegate call to get_ref_impl + return get_ref_impl(*this); } /*! diff --git a/src/json.hpp.re2c b/src/json.hpp.re2c index 0838b234d..d384f313a 100644 --- a/src/json.hpp.re2c +++ b/src/json.hpp.re2c @@ -2416,17 +2416,33 @@ class basic_json return is_number_float() ? &m_value.number_float : nullptr; } - /// helper function to implement get_ref without code duplication - /// for const and non-const overloads - /// ThisType will be deduced as 'basic_jason' or 'const basic_json' - template + /*! + @brief helper function to implement get_ref() + + This funcion helps to implement get_ref() without code duplication for + const and non-const overloads + + @tparam ThisType will be deduced as `basic_json` or `const basic_json` + + @throw std::domain_error if ReferenceType does not match underlying value + type of the current JSON + */ + template static ReferenceType get_ref_impl(ThisType& obj) { - using PointerType = typename std::add_pointer::type; // delegate the call to get_ptr<>() + using PointerType = typename std::add_pointer::type; auto ptr = obj.template get_ptr(); - if (ptr) return *ptr; - throw std::domain_error("incompatible ReferenceType for get_ref, actual type is " + obj.type_name()); + + if (ptr != nullptr) + { + return *ptr; + } + else + { + throw std::domain_error("incompatible ReferenceType for get_ref, actual type is " + + obj.type_name()); + } } public: @@ -2576,7 +2592,7 @@ class basic_json return get_impl_ptr(static_cast(nullptr)); } - /*! + /*! @brief get a reference value (implicit) Implict reference access to the internally stored JSON value. No copies are @@ -2585,17 +2601,22 @@ class basic_json @warning Writing data to the referee of the result yields an undefined state. - @tparam ReferenceType reference type; must be a reference to @ref array_t, @ref - object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or @ref - number_float_t. + @tparam ReferenceType reference type; must be a reference to @ref array_t, + @ref object_t, @ref string_t, @ref boolean_t, @ref number_integer_t, or + @ref number_float_t. - @return reference to the internally stored JSON value if the requested reference - type @a ReferenceType fits to the JSON value; throws std::domain_error otherwise + @return reference to the internally stored JSON value if the requested + reference type @a ReferenceType fits to the JSON value; throws + std::domain_error otherwise - @throw std::domain_error in case passed type @a ReferenceType is incompatible - with the stored JSON value + @throw std::domain_error in case passed type @a ReferenceType is + incompatible with the stored JSON value @complexity Constant. + + @liveexample{The example shows several calls to `get_ref()`.,get_ref} + + @since version 1.0.1 */ template::type = 0> ReferenceType get_ref() { - // delegate call to get_ref_impl - return get_ref_impl(*this); + // delegate call to get_ref_impl + return get_ref_impl(*this); } /*! @@ -2614,12 +2635,12 @@ class basic_json template::value - and std::is_const< typename std::remove_reference::type >::value + and std::is_const::type>::value , int>::type = 0> ReferenceType get_ref() const { - // delegate call to get_ref_impl - return get_ref_impl(*this); + // delegate call to get_ref_impl + return get_ref_impl(*this); } /*! diff --git a/test/unit.cpp b/test/unit.cpp index 81b341f69..8b3bc19b2 100644 --- a/test/unit.cpp +++ b/test/unit.cpp @@ -2604,13 +2604,13 @@ TEST_CASE("pointer access") CHECK(value.get_ptr() == nullptr); } - SECTION("pointer access to const object_t") + SECTION("pointer access to const object_t") { using test_type = json::object_t; const json value = {{"one", 1}, {"two", 2}}; - // this should not compile - // test_type* p1 = value.get_ptr(); + // this should not compile + // test_type* p1 = value.get_ptr(); // check if pointers are returned correctly const test_type* p2 = value.get_ptr(); @@ -2781,14 +2781,14 @@ TEST_CASE("reference access") // check if references are returned correctly test_type& p1 = value.get_ref(); CHECK(&p1 == value.get_ptr()); - CHECK(p1 == value.get()); + CHECK(p1 == value.get()); const test_type& p2 = value.get_ref(); CHECK(&p2 == value.get_ptr()); CHECK(p2 == value.get()); // check if mismatching references throw correctly - CHECK_NOTHROW(value.get_ref()); + CHECK_NOTHROW(value.get_ref()); CHECK_THROWS(value.get_ref()); CHECK_THROWS(value.get_ref()); CHECK_THROWS(value.get_ref()); @@ -2796,13 +2796,13 @@ TEST_CASE("reference access") CHECK_THROWS(value.get_ref()); } - SECTION("const reference access to const object_t") + SECTION("const reference access to const object_t") { using test_type = json::object_t; const json value = {{"one", 1}, {"two", 2}}; - // this should not compile - // test_type& p1 = value.get_ref(); + // this should not compile + // test_type& p1 = value.get_ref(); // check if references are returned correctly const test_type& p2 = value.get_ref(); @@ -2818,7 +2818,7 @@ TEST_CASE("reference access") // check if references are returned correctly test_type& p1 = value.get_ref(); CHECK(&p1 == value.get_ptr()); - CHECK(p1 == value.get()); + CHECK(p1 == value.get()); const test_type& p2 = value.get_ref(); CHECK(&p2 == value.get_ptr()); @@ -2841,7 +2841,7 @@ TEST_CASE("reference access") // check if references are returned correctly test_type& p1 = value.get_ref(); CHECK(&p1 == value.get_ptr()); - CHECK(p1 == value.get()); + CHECK(p1 == value.get()); const test_type& p2 = value.get_ref(); CHECK(&p2 == value.get_ptr()); @@ -2864,7 +2864,7 @@ TEST_CASE("reference access") // check if references are returned correctly test_type& p1 = value.get_ref(); CHECK(&p1 == value.get_ptr()); - CHECK(p1 == value.get()); + CHECK(p1 == value.get()); const test_type& p2 = value.get_ref(); CHECK(&p2 == value.get_ptr()); @@ -2884,10 +2884,10 @@ TEST_CASE("reference access") using test_type = json::number_integer_t; json value = 23; - // check if references are returned correctly + // check if references are returned correctly test_type& p1 = value.get_ref(); CHECK(&p1 == value.get_ptr()); - CHECK(p1 == value.get()); + CHECK(p1 == value.get()); const test_type& p2 = value.get_ref(); CHECK(&p2 == value.get_ptr()); @@ -2907,10 +2907,10 @@ TEST_CASE("reference access") using test_type = json::number_float_t; json value = 42.23; - // check if references are returned correctly + // check if references are returned correctly test_type& p1 = value.get_ref(); CHECK(&p1 == value.get_ptr()); - CHECK(p1 == value.get()); + CHECK(p1 == value.get()); const test_type& p2 = value.get_ref(); CHECK(&p2 == value.get_ptr()); From 5c4624c351a473b04b1d3b9900f1a88fb4e0a306 Mon Sep 17 00:00:00 2001 From: Niels Date: Wed, 20 Jan 2016 21:15:10 +0100 Subject: [PATCH 7/8] wishlist --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 81fac6d94..b258f4642 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -67,3 +67,4 @@ The following areas really need contribution: - Extending the **continuous integration** beyond Linux running some versions of GCC and Clang on [Travis](https://travis-ci.org/nlohmann/json) and Microsoft Visual Studio on [AppVeyor](https://ci.appveyor.com/project/nlohmann/json). We have found a lot of bugs just because several compilers behave in a slightly different manner. - Improving the efficiency of the **JSON parser**. The current parser is implemented as a naive recursive descent parser with hand coded string handling. More sophisticated approaches like LALR parsers would be really appreciated. That said, parser generators like Bison or ANTLR do not play nice with single-header files -- I really would like to keep the parser inside the `json.hpp` header, and I am not aware of approaches similar to [`re2c`](http://re2c.org) for parsing. - Extending and updating existing **benchmarks** to include (the most recent version of) this library. Though efficiency is not everything, speed and memory consumption are very important characteristics for C++ developers, so having proper comparisons would be interesting. +- Check the code with [Coverity](https://scan.coverity.com). From f854410542d35909291fc901ca0def459fdb3990 Mon Sep 17 00:00:00 2001 From: Niels Date: Wed, 20 Jan 2016 21:20:41 +0100 Subject: [PATCH 8/8] added a note wrt. Valgrind (#175) --- CONTRIBUTING.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b258f4642..3e6258d43 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -52,6 +52,10 @@ There are currently two files which need to be edited: Please understand that I cannot accept pull requests changing only file `src/json.hpp`. +## Note + +- If you open a pull request, the code will be automatically tested with [Valgrind](http://valgrind.org)'s Memcheck tool to detect memory leaks. Please be aware that the execution with Valgrind _may_ in rare cases yield different behavior than running the code directly. This can result in failing unit tests which run successfully without Valgrind. + ## Please don't - Only make changes to file `src/json.hpp` -- please read the paragraph above and understand why `src/json.hpp.re2c` exists.