diff --git a/README.md b/README.md index 6ef08a56..5d84c3f2 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ to the files you want to use JSON objects. That's it. Do not forget to set the n :beer: If you are using OS X and [Homebrew](http://brew.sh), just type `brew tap nlohmann/json` and `brew install nlohmann_json` and you're set. If you want the bleeding edge rather than the latest release, use `brew install nlohmann_json --HEAD`. -If you are using the Meson Build System, then you can wrap this repo as a subproject. +If you are using the [Meson Build System](http://mesonbuild.com), then you can wrap this repo as a subproject. :warning: [Version 3.0.0](https://github.com/nlohmann/json/wiki/Road-toward-3.0.0) is currently under development. Branch `develop` is used for the ongoing work and is probably **unstable**. Please use the `master` branch for the last stable version 2.1.1. @@ -839,6 +839,7 @@ I deeply appreciate the help of the following people. - [ftillier](https://github.com/ftillier) fixed a compiler warning. - [tinloaf](https://github.com/tinloaf) made sure all pushed warnings are properly popped. - [Fytch](https://github.com/Fytch) found a bug in the documentation. +- [Jay Sistar](https://github.com/Type1J) implemented a Meson build description Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone. @@ -865,7 +866,6 @@ The library itself contains of a single header file licensed under the MIT licen - [**Github Changelog Generator**](https://github.com/skywinder/github-changelog-generator) to generate the [ChangeLog](https://github.com/nlohmann/json/blob/develop/ChangeLog.md) - [**libFuzzer**](http://llvm.org/docs/LibFuzzer.html) to implement fuzz testing for OSS-Fuzz - [**OSS-Fuzz**](https://github.com/google/oss-fuzz) for continuous fuzz testing of the library -- [**re2c**](http://re2c.org) to generate an automaton for the lexical analysis - [**send_to_wandbox**](https://github.com/nlohmann/json/blob/develop/doc/scripts/send_to_wandbox.py) to send code examples to [Wandbox](http://melpon.org/wandbox) - [**Travis**](https://travis-ci.org) for [continuous integration](https://travis-ci.org/nlohmann/json) on Linux and macOS - [**Valgrind**](http://valgrind.org) to check for correct memory management diff --git a/doc/examples/iterator_wrapper.cpp b/doc/examples/iterator_wrapper.cpp new file mode 100644 index 00000000..208bb705 --- /dev/null +++ b/doc/examples/iterator_wrapper.cpp @@ -0,0 +1,22 @@ +#include "json.hpp" + +using json = nlohmann::json; + +int main() +{ + // create JSON values + json j_object = {{"one", 1}, {"two", 2}}; + json j_array = {1, 2, 4, 8, 16}; + + // example for an object + for (auto& x : json::iterator_wrapper(j_object)) + { + std::cout << "key: " << x.key() << ", value: " << x.value() << '\n'; + } + + // example for an array + for (auto& x : json::iterator_wrapper(j_array)) + { + std::cout << "key: " << x.key() << ", value: " << x.value() << '\n'; + } +} diff --git a/doc/examples/iterator_wrapper.link b/doc/examples/iterator_wrapper.link new file mode 100644 index 00000000..c8f696c3 --- /dev/null +++ b/doc/examples/iterator_wrapper.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/iterator_wrapper.output b/doc/examples/iterator_wrapper.output new file mode 100644 index 00000000..89b09f52 --- /dev/null +++ b/doc/examples/iterator_wrapper.output @@ -0,0 +1,7 @@ +key: one, value: 1 +key: two, value: 2 +key: 0, value: 1 +key: 1, value: 2 +key: 2, value: 4 +key: 3, value: 8 +key: 4, value: 16 diff --git a/src/json.hpp b/src/json.hpp index 36d74ef0..3bfd1234 100644 --- a/src/json.hpp +++ b/src/json.hpp @@ -5204,6 +5204,8 @@ class basic_json reference to the JSON values is returned, so there is no access to the underlying iterator. + @liveexample{The following code shows how the wrapper is used,iterator_wrapper} + @note The name of this function is not yet final and may change in the future. */ @@ -7877,80 +7879,6 @@ class basic_json class iteration_proxy { private: - /// helper class for first "property" - template - class iterator_key_property - { - private: - /// the reference to the proxy - ProxyType& proxy; - - public: - explicit iterator_key_property(ProxyType& proxyRef) noexcept - : proxy(proxyRef) {} - - /// conversion operator (calls key()) - operator typename basic_json::string_t() const - { - return proxy.key(); - } - - /// equal operator (calls key()) - template - bool operator==(const KeyType& key) const - { - return proxy.key() == key; - } - - /// not equal operator (calls key()) - template - bool operator!=(const KeyType& key) const - { - return proxy.key() != key; - } - }; - - /// helper class for second "property" - template - class iterator_value_property - { - private: - /// the reference to the proxy - ProxyType& proxy; - - public: - explicit iterator_value_property(ProxyType& proxyRef) noexcept - : proxy(proxyRef) {} - - /// conversion operator (calls value()) - operator typename IteratorType::reference() const - { - return proxy.value(); - } - - /// equal operator (calls value()) - template - bool operator==(const ValueType& value) const - { - return proxy.value() == value; - } - - /// not equal operator (calls value()) - template - bool operator!=(const ValueType& value) const - { - return proxy.value() != value; - } - - /// assignment operator (calls value()) - template - iterator_value_property& operator=(const ValueType& value) - { - proxy.value() = value; - return *this; - } - }; - /// helper class for iteration class iteration_proxy_internal { @@ -7961,11 +7889,8 @@ class basic_json size_t array_index = 0; public: - iterator_key_property first; - iterator_value_property second; - explicit iteration_proxy_internal(IteratorType it) noexcept - : anchor(it), first(*this), second(*this) + : anchor(it) {} /// dereference operator (needed for range-based for) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 36cc52b5..25e345c2 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -30,7 +30,6 @@ add_executable(${JSON_UNITTEST_TARGET_NAME} "src/unit-element_access2.cpp" "src/unit-inspection.cpp" "src/unit-iterator_wrapper.cpp" - "src/unit-iterator_wrapper_first_second.cpp" "src/unit-iterators1.cpp" "src/unit-iterators2.cpp" "src/unit-json_patch.cpp" diff --git a/test/src/unit-iterator_wrapper_first_second.cpp b/test/src/unit-iterator_wrapper_first_second.cpp deleted file mode 100644 index 6dceef8b..00000000 --- a/test/src/unit-iterator_wrapper_first_second.cpp +++ /dev/null @@ -1,729 +0,0 @@ -/* - __ _____ _____ _____ - __| | __| | | | JSON for Modern C++ (test suite) -| | |__ | | | | | | version 2.1.1 -|_____|_____|_____|_|___| https://github.com/nlohmann/json - -Licensed under the MIT License . -Copyright (c) 2013-2017 Niels Lohmann . - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "catch.hpp" - -#include "json.hpp" -using nlohmann::json; - -TEST_CASE("iterator_wrapper_first_second") -{ - SECTION("object") - { - SECTION("value") - { - json j = {{"A", 1}, {"B", 2}}; - int counter = 1; - - for (auto i : json::iterator_wrapper(j)) - { - switch (counter++) - { - case 1: - { - CHECK(i.first == "A"); - CHECK(i.second == json(1)); - break; - } - - case 2: - { - CHECK(i.first == "B"); - CHECK(i.second == json(2)); - break; - } - - default: - { - break; - } - } - } - - CHECK(counter == 3); - } - - SECTION("reference") - { - json j = {{"A", 1}, {"B", 2}}; - int counter = 1; - - for (auto& i : json::iterator_wrapper(j)) - { - switch (counter++) - { - case 1: - { - CHECK(i.first == "A"); - CHECK(i.second == json(1)); - - // change the value - i.second = json(11); - CHECK(i.second == json(11)); - break; - } - - case 2: - { - CHECK(i.first == "B"); - CHECK(i.second == json(2)); - - // change the value - i.second = json(22); - CHECK(i.second == json(22)); - break; - } - - default: - { - break; - } - } - } - - CHECK(counter == 3); - - // check if values where changed - CHECK(j == json({{"A", 11}, {"B", 22}})); - } - - SECTION("const value") - { - json j = {{"A", 1}, {"B", 2}}; - int counter = 1; - - for (const auto i : json::iterator_wrapper(j)) - { - switch (counter++) - { - case 1: - { - CHECK(i.first == "A"); - CHECK(i.second == json(1)); - break; - } - - case 2: - { - CHECK(i.first == "B"); - CHECK(i.second == json(2)); - break; - } - - default: - { - break; - } - } - } - - CHECK(counter == 3); - } - - SECTION("const reference") - { - json j = {{"A", 1}, {"B", 2}}; - int counter = 1; - - for (const auto& i : json::iterator_wrapper(j)) - { - switch (counter++) - { - case 1: - { - CHECK(i.first == "A"); - CHECK(i.second == json(1)); - break; - } - - case 2: - { - CHECK(i.first == "B"); - CHECK(i.second == json(2)); - break; - } - - default: - { - break; - } - } - } - - CHECK(counter == 3); - } - } - - SECTION("const object") - { - SECTION("value") - { - const json j = {{"A", 1}, {"B", 2}}; - int counter = 1; - - for (auto i : json::iterator_wrapper(j)) - { - switch (counter++) - { - case 1: - { - CHECK(i.first == "A"); - CHECK(i.second == json(1)); - break; - } - - case 2: - { - CHECK(i.first == "B"); - CHECK(i.second == json(2)); - break; - } - - default: - { - break; - } - } - } - - CHECK(counter == 3); - } - - SECTION("reference") - { - const json j = {{"A", 1}, {"B", 2}}; - int counter = 1; - - for (auto& i : json::iterator_wrapper(j)) - { - switch (counter++) - { - case 1: - { - CHECK(i.first == "A"); - CHECK(i.second == json(1)); - break; - } - - case 2: - { - CHECK(i.first == "B"); - CHECK(i.second == json(2)); - break; - } - - default: - { - break; - } - } - } - - CHECK(counter == 3); - } - - SECTION("const value") - { - const json j = {{"A", 1}, {"B", 2}}; - int counter = 1; - - for (const auto i : json::iterator_wrapper(j)) - { - switch (counter++) - { - case 1: - { - CHECK(i.first == "A"); - CHECK(i.second == json(1)); - break; - } - - case 2: - { - CHECK(i.first == "B"); - CHECK(i.second == json(2)); - break; - } - - default: - { - break; - } - } - } - - CHECK(counter == 3); - } - - SECTION("const reference") - { - const json j = {{"A", 1}, {"B", 2}}; - int counter = 1; - - for (const auto& i : json::iterator_wrapper(j)) - { - switch (counter++) - { - case 1: - { - CHECK(i.first == "A"); - CHECK(i.second == json(1)); - break; - } - - case 2: - { - CHECK(i.first == "B"); - CHECK(i.second == json(2)); - break; - } - - default: - { - break; - } - } - } - - CHECK(counter == 3); - } - } - - SECTION("array") - { - SECTION("value") - { - json j = {"A", "B"}; - int counter = 1; - - for (auto i : json::iterator_wrapper(j)) - { - switch (counter++) - { - case 1: - { - CHECK(i.first == "0"); - CHECK(i.second == "A"); - break; - } - - case 2: - { - CHECK(i.first == "1"); - CHECK(i.second == "B"); - break; - } - - default: - { - break; - } - } - } - - CHECK(counter == 3); - } - - SECTION("reference") - { - json j = {"A", "B"}; - int counter = 1; - - for (auto& i : json::iterator_wrapper(j)) - { - switch (counter++) - { - case 1: - { - CHECK(i.first == "0"); - CHECK(i.second == "A"); - - // change the value - i.second = "AA"; - CHECK(i.second == "AA"); - break; - } - - case 2: - { - CHECK(i.first == "1"); - CHECK(i.second == "B"); - - // change the value - i.second = "BB"; - CHECK(i.second == "BB"); - break; - } - - default: - { - break; - } - } - } - - CHECK(counter == 3); - - // check if values where changed - CHECK(j == json({"AA", "BB"})); - } - - SECTION("const value") - { - json j = {"A", "B"}; - int counter = 1; - - for (const auto i : json::iterator_wrapper(j)) - { - switch (counter++) - { - case 1: - { - CHECK(i.first == "0"); - CHECK(i.second == "A"); - break; - } - - case 2: - { - CHECK(i.first == "1"); - CHECK(i.second == "B"); - break; - } - - default: - { - break; - } - } - } - - CHECK(counter == 3); - } - - SECTION("const reference") - { - json j = {"A", "B"}; - int counter = 1; - - for (const auto& i : json::iterator_wrapper(j)) - { - switch (counter++) - { - case 1: - { - CHECK(i.first == "0"); - CHECK(i.second == "A"); - break; - } - - case 2: - { - CHECK(i.first == "1"); - CHECK(i.second == "B"); - break; - } - - default: - { - break; - } - } - } - - CHECK(counter == 3); - } - } - - SECTION("const array") - { - SECTION("value") - { - const json j = {"A", "B"}; - int counter = 1; - - for (auto i : json::iterator_wrapper(j)) - { - switch (counter++) - { - case 1: - { - CHECK(i.first == "0"); - CHECK(i.second == "A"); - break; - } - - case 2: - { - CHECK(i.first == "1"); - CHECK(i.second == "B"); - break; - } - - default: - { - break; - } - } - } - - CHECK(counter == 3); - } - - SECTION("reference") - { - const json j = {"A", "B"}; - int counter = 1; - - for (auto& i : json::iterator_wrapper(j)) - { - switch (counter++) - { - case 1: - { - CHECK(i.first == "0"); - CHECK(i.second == "A"); - break; - } - - case 2: - { - CHECK(i.first == "1"); - CHECK(i.second == "B"); - break; - } - - default: - { - break; - } - } - } - - CHECK(counter == 3); - } - - SECTION("const value") - { - const json j = {"A", "B"}; - int counter = 1; - - for (const auto i : json::iterator_wrapper(j)) - { - switch (counter++) - { - case 1: - { - CHECK(i.first == "0"); - CHECK(i.second == "A"); - break; - } - - case 2: - { - CHECK(i.first == "1"); - CHECK(i.second == "B"); - break; - } - - default: - { - break; - } - } - } - - CHECK(counter == 3); - } - - SECTION("const reference") - { - const json j = {"A", "B"}; - int counter = 1; - - for (const auto& i : json::iterator_wrapper(j)) - { - switch (counter++) - { - case 1: - { - CHECK(i.first == "0"); - CHECK(i.second == "A"); - break; - } - - case 2: - { - CHECK(i.first == "1"); - CHECK(i.second == "B"); - break; - } - - default: - { - break; - } - } - } - - CHECK(counter == 3); - } - } - - SECTION("primitive") - { - SECTION("value") - { - json j = 1; - int counter = 1; - - for (auto i : json::iterator_wrapper(j)) - { - ++counter; - CHECK(i.first == ""); - CHECK(i.second == json(1)); - } - - CHECK(counter == 2); - } - - SECTION("reference") - { - json j = 1; - int counter = 1; - - for (auto& i : json::iterator_wrapper(j)) - { - ++counter; - CHECK(i.first == ""); - CHECK(i.second == json(1)); - - // change value - i.second = json(2); - } - - CHECK(counter == 2); - - // check if value has changed - CHECK(j == json(2)); - } - - SECTION("const value") - { - json j = 1; - int counter = 1; - - for (const auto i : json::iterator_wrapper(j)) - { - ++counter; - CHECK(i.first == ""); - CHECK(i.second == json(1)); - } - - CHECK(counter == 2); - } - - SECTION("const reference") - { - json j = 1; - int counter = 1; - - for (const auto& i : json::iterator_wrapper(j)) - { - ++counter; - CHECK(i.first == ""); - CHECK(i.second == json(1)); - } - - CHECK(counter == 2); - } - } - - SECTION("const primitive") - { - SECTION("value") - { - const json j = 1; - int counter = 1; - - for (auto i : json::iterator_wrapper(j)) - { - ++counter; - CHECK(i.first == ""); - CHECK(i.second == json(1)); - } - - CHECK(counter == 2); - } - - SECTION("reference") - { - const json j = 1; - int counter = 1; - - for (auto& i : json::iterator_wrapper(j)) - { - ++counter; - CHECK(i.first == ""); - CHECK(i.second == json(1)); - } - - CHECK(counter == 2); - } - - SECTION("const value") - { - const json j = 1; - int counter = 1; - - for (const auto i : json::iterator_wrapper(j)) - { - ++counter; - CHECK(i.first == ""); - CHECK(i.second == json(1)); - } - - CHECK(counter == 2); - } - - SECTION("const reference") - { - const json j = 1; - int counter = 1; - - for (const auto& i : json::iterator_wrapper(j)) - { - ++counter; - CHECK(i.first == ""); - CHECK(i.second == json(1)); - } - - CHECK(counter == 2); - } - } -} diff --git a/test/src/unit-unicode.cpp b/test/src/unit-unicode.cpp index 120941ee..17cd9aac 100644 --- a/test/src/unit-unicode.cpp +++ b/test/src/unit-unicode.cpp @@ -34,6 +34,8 @@ using nlohmann::json; #include +void check_utf8string(bool success_expected, int byte1, int byte2, int byte3, int byte4); + // create and check a JSON string with up to four UTF-8 bytes void check_utf8string(bool success_expected, int byte1, int byte2 = -1, int byte3 = -1, int byte4 = -1) {