From e3095f636f3b21e292fb5ac20b1e731c833f6c71 Mon Sep 17 00:00:00 2001 From: Florian Albrechtskirchinger Date: Thu, 28 Jul 2022 22:12:23 +0200 Subject: [PATCH] Add operator<<(json_pointer) (#3601) * Add operator<< for json_pointer * Deprecate json_pointer::operator string_t() * Update documentation * Move operator<<(basic_json) example * Add example * Add mkdocs-redirects * Move operator<< and operator>> doc pages out of basic_json/ * Rename JSON pointer operator_string to operator_string_t * Add unit test --- ...pp => json_pointer__operator_string_t.cpp} | 0 ...=> json_pointer__operator_string_t.output} | 0 ...lize.cpp => operator_ltlt__basic_json.cpp} | 0 ...utput => operator_ltlt__basic_json.output} | 0 docs/examples/operator_ltlt__json_pointer.cpp | 13 +++ .../operator_ltlt__json_pointer.output | 1 + docs/mkdocs/docs/api/basic_json/accept.md | 2 +- docs/mkdocs/docs/api/basic_json/index.md | 4 +- .../docs/api/basic_json/operator_ltlt.md | 62 ------------- docs/mkdocs/docs/api/basic_json/parse.md | 2 +- docs/mkdocs/docs/api/json_pointer/index.md | 2 +- ...perator_string.md => operator_string_t.md} | 13 ++- .../api/{basic_json => }/operator_gtgt.md | 26 +++--- docs/mkdocs/docs/api/operator_ltlt.md | 86 +++++++++++++++++++ .../docs/features/parsing/json_lines.md | 2 +- docs/mkdocs/mkdocs.yml | 12 ++- docs/mkdocs/requirements.txt | 1 + include/nlohmann/detail/json_pointer.hpp | 14 +++ single_include/nlohmann/json.hpp | 14 +++ tests/src/unit-json_pointer.cpp | 12 ++- 20 files changed, 176 insertions(+), 90 deletions(-) rename docs/examples/{json_pointer__operator_string.cpp => json_pointer__operator_string_t.cpp} (100%) rename docs/examples/{json_pointer__operator_string.output => json_pointer__operator_string_t.output} (100%) rename docs/examples/{operator_serialize.cpp => operator_ltlt__basic_json.cpp} (100%) rename docs/examples/{operator_serialize.output => operator_ltlt__basic_json.output} (100%) create mode 100644 docs/examples/operator_ltlt__json_pointer.cpp create mode 100644 docs/examples/operator_ltlt__json_pointer.output delete mode 100644 docs/mkdocs/docs/api/basic_json/operator_ltlt.md rename docs/mkdocs/docs/api/json_pointer/{operator_string.md => operator_string_t.md} (59%) rename docs/mkdocs/docs/api/{basic_json => }/operator_gtgt.md (65%) create mode 100644 docs/mkdocs/docs/api/operator_ltlt.md diff --git a/docs/examples/json_pointer__operator_string.cpp b/docs/examples/json_pointer__operator_string_t.cpp similarity index 100% rename from docs/examples/json_pointer__operator_string.cpp rename to docs/examples/json_pointer__operator_string_t.cpp diff --git a/docs/examples/json_pointer__operator_string.output b/docs/examples/json_pointer__operator_string_t.output similarity index 100% rename from docs/examples/json_pointer__operator_string.output rename to docs/examples/json_pointer__operator_string_t.output diff --git a/docs/examples/operator_serialize.cpp b/docs/examples/operator_ltlt__basic_json.cpp similarity index 100% rename from docs/examples/operator_serialize.cpp rename to docs/examples/operator_ltlt__basic_json.cpp diff --git a/docs/examples/operator_serialize.output b/docs/examples/operator_ltlt__basic_json.output similarity index 100% rename from docs/examples/operator_serialize.output rename to docs/examples/operator_ltlt__basic_json.output diff --git a/docs/examples/operator_ltlt__json_pointer.cpp b/docs/examples/operator_ltlt__json_pointer.cpp new file mode 100644 index 000000000..f4fac886d --- /dev/null +++ b/docs/examples/operator_ltlt__json_pointer.cpp @@ -0,0 +1,13 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create JSON poiner + json::json_pointer ptr("/foo/bar/baz"); + + // write string representation to stream + std::cout << ptr << std::endl; +} diff --git a/docs/examples/operator_ltlt__json_pointer.output b/docs/examples/operator_ltlt__json_pointer.output new file mode 100644 index 000000000..ed359432d --- /dev/null +++ b/docs/examples/operator_ltlt__json_pointer.output @@ -0,0 +1 @@ +/foo/bar/baz diff --git a/docs/mkdocs/docs/api/basic_json/accept.md b/docs/mkdocs/docs/api/basic_json/accept.md index 097cc8c91..1c806e82f 100644 --- a/docs/mkdocs/docs/api/basic_json/accept.md +++ b/docs/mkdocs/docs/api/basic_json/accept.md @@ -96,7 +96,7 @@ Linear in the length of the input. The parser is a predictive LL(1) parser. ## See also - [parse](parse.md) - deserialize from a compatible input -- [operator>>](operator_gtgt.md) - deserialize from stream +- [operator>>](../operator_gtgt.md) - deserialize from stream ## Version history diff --git a/docs/mkdocs/docs/api/basic_json/index.md b/docs/mkdocs/docs/api/basic_json/index.md index 14f6d56c2..35ce63c3e 100644 --- a/docs/mkdocs/docs/api/basic_json/index.md +++ b/docs/mkdocs/docs/api/basic_json/index.md @@ -283,8 +283,8 @@ Access to the JSON value ## Non-member functions -- [**operator<<(std::ostream&)**](operator_ltlt.md) - serialize to stream -- [**operator>>(std::istream&)**](operator_gtgt.md) - deserialize from stream +- [**operator<<(std::ostream&)**](../operator_ltlt.md) - serialize to stream +- [**operator>>(std::istream&)**](../operator_gtgt.md) - deserialize from stream - [**to_string**](to_string.md) - user-defined `to_string` function for JSON values ## Literals diff --git a/docs/mkdocs/docs/api/basic_json/operator_ltlt.md b/docs/mkdocs/docs/api/basic_json/operator_ltlt.md deleted file mode 100644 index 0cba5ea3c..000000000 --- a/docs/mkdocs/docs/api/basic_json/operator_ltlt.md +++ /dev/null @@ -1,62 +0,0 @@ -# operator<<(basic_json) - -```cpp -std::ostream& operator<<(std::ostream& o, const basic_json& j); -``` - -Serialize the given JSON value `j` to the output stream `o`. The JSON value will be serialized using the -[`dump`](dump.md) member function. - -- The indentation of the output can be controlled with the member variable `width` of the output stream `o`. For - instance, using the manipulator `std::setw(4)` on `o` sets the indentation level to `4` and the serialization result - is the same as calling `dump(4)`. -- The indentation character can be controlled with the member variable `fill` of the output stream `o`. For instance, - the manipulator `std::setfill('\\t')` sets indentation to use a tab character rather than the default space character. - -## Parameters - -`o` (in, out) -: stream to serialize to - -`j` (in) -: JSON value to serialize - -## Return value - -the stream `o` - -## Exceptions - -Throws [`type_error.316`](../../home/exceptions.md#jsonexceptiontype_error316) if a string stored inside the JSON value -is not UTF-8 encoded. Note that unlike the [`dump`](dump.md) member functions, no `error_handler` can be set. - -## Complexity - -Linear. - -## Examples - -??? example - - The example below shows the serialization with different parameters to `width` to adjust the indentation level. - - ```cpp - --8<-- "examples/operator_serialize.cpp" - ``` - - Output: - - ```json - --8<-- "examples/operator_serialize.output" - ``` - -## Version history - -- Added in version 1.0.0 -- Support for indentation character added in version 3.0.0. - -!!! warning "Deprecation" - - This function replaces function `#!cpp std::ostream& operator>>(const basic_json& j, std::ostream& o)` which has - been deprecated in version 3.0.0. It will be removed in version 4.0.0. Please replace calls like `#!cpp j >> o;` - with `#!cpp o << j;`. diff --git a/docs/mkdocs/docs/api/basic_json/parse.md b/docs/mkdocs/docs/api/basic_json/parse.md index e0aaf956b..49838ad1d 100644 --- a/docs/mkdocs/docs/api/basic_json/parse.md +++ b/docs/mkdocs/docs/api/basic_json/parse.md @@ -196,7 +196,7 @@ super-linear complexity. ## See also - [accept](accept.md) - check if the input is valid JSON -- [operator>>](operator_gtgt.md) - deserialize from stream +- [operator>>](../operator_gtgt.md) - deserialize from stream ## Version history diff --git a/docs/mkdocs/docs/api/json_pointer/index.md b/docs/mkdocs/docs/api/json_pointer/index.md index dc07d89b3..aee845cde 100644 --- a/docs/mkdocs/docs/api/json_pointer/index.md +++ b/docs/mkdocs/docs/api/json_pointer/index.md @@ -28,7 +28,7 @@ are the base for JSON patches. - [(constructor)](json_pointer.md) - [**to_string**](to_string.md) - return a string representation of the JSON pointer -- [**operator string_t**](operator_string.md) - return a string representation of the JSON pointer +- [**operator string_t**](operator_string_t.md) - return a string representation of the JSON pointer - [**operator/=**](operator_slasheq.md) - append to the end of the JSON pointer - [**operator/**](operator_slash.md) - create JSON Pointer by appending - [**parent_pointer**](parent_pointer.md) - returns the parent of this JSON pointer diff --git a/docs/mkdocs/docs/api/json_pointer/operator_string.md b/docs/mkdocs/docs/api/json_pointer/operator_string_t.md similarity index 59% rename from docs/mkdocs/docs/api/json_pointer/operator_string.md rename to docs/mkdocs/docs/api/json_pointer/operator_string_t.md index f2f99cae7..74105a4f1 100644 --- a/docs/mkdocs/docs/api/json_pointer/operator_string.md +++ b/docs/mkdocs/docs/api/json_pointer/operator_string_t.md @@ -19,6 +19,13 @@ operator string_t() const } ``` +## Notes + +!!! warning "Deprecation" + + This function is deprecated in favor of [`to_string`](to_string.md) and will be removed in a future major version + release. + ## Examples ??? example @@ -26,16 +33,16 @@ operator string_t() const The example shows how JSON Pointers can be implicitly converted to strings. ```cpp - --8<-- "examples/json_pointer__operator_string.cpp" + --8<-- "examples/json_pointer__operator_string_t.cpp" ``` Output: ```json - --8<-- "examples/json_pointer__operator_string.output" + --8<-- "examples/json_pointer__operator_string_t.output" ``` ## Version history - Since version 2.0.0. -- Changed type to `string_t` in version 3.11.0. +- Changed type to `string_t` and deprecated in version 3.11.0. diff --git a/docs/mkdocs/docs/api/basic_json/operator_gtgt.md b/docs/mkdocs/docs/api/operator_gtgt.md similarity index 65% rename from docs/mkdocs/docs/api/basic_json/operator_gtgt.md rename to docs/mkdocs/docs/api/operator_gtgt.md index 97c2f0b4e..98d575add 100644 --- a/docs/mkdocs/docs/api/basic_json/operator_gtgt.md +++ b/docs/mkdocs/docs/api/operator_gtgt.md @@ -1,4 +1,4 @@ -# operator>>(basic_json) +# nlohmann::operator>>(basic_json) ```cpp std::istream& operator>>(std::istream& i, basic_json& j); @@ -20,10 +20,10 @@ the stream `i` ## Exceptions -- Throws [`parse_error.101`](../../home/exceptions.md#jsonexceptionparse_error101) in case of an unexpected token. -- Throws [`parse_error.102`](../../home/exceptions.md#jsonexceptionparse_error102) if to_unicode fails or surrogate +- Throws [`parse_error.101`](../home/exceptions.md#jsonexceptionparse_error101) in case of an unexpected token. +- Throws [`parse_error.102`](../home/exceptions.md#jsonexceptionparse_error102) if to_unicode fails or surrogate error. -- Throws [`parse_error.103`](../../home/exceptions.md#jsonexceptionparse_error103) if to_unicode fails. +- Throws [`parse_error.103`](../home/exceptions.md#jsonexceptionparse_error103) if to_unicode fails. ## Complexity @@ -33,6 +33,12 @@ Linear in the length of the input. The parser is a predictive LL(1) parser. A UTF-8 byte order mark is silently ignored. +!!! warning "Deprecation" + + This function replaces function `#!cpp std::istream& operator<<(basic_json& j, std::istream& i)` which has + been deprecated in version 3.0.0. It will be removed in version 4.0.0. Please replace calls like `#!cpp j << i;` + with `#!cpp i >> j;`. + ## Examples ??? example @@ -51,15 +57,9 @@ A UTF-8 byte order mark is silently ignored. ## See also -- [accept](accept.md) - check if the input is valid JSON -- [parse](parse.md) - deserialize from a compatible input +- [accept](basic_json/accept.md) - check if the input is valid JSON +- [parse](basic_json/parse.md) - deserialize from a compatible input ## Version history -- Added in version 1.0.0 - -!!! warning "Deprecation" - - This function replaces function `#!cpp std::istream& operator<<(basic_json& j, std::istream& i)` which has - been deprecated in version 3.0.0. It will be removed in version 4.0.0. Please replace calls like `#!cpp j << i;` - with `#!cpp i >> j;`. +- Added in version 1.0.0. Deprecated in version 3.0.0. diff --git a/docs/mkdocs/docs/api/operator_ltlt.md b/docs/mkdocs/docs/api/operator_ltlt.md new file mode 100644 index 000000000..ea857718b --- /dev/null +++ b/docs/mkdocs/docs/api/operator_ltlt.md @@ -0,0 +1,86 @@ +# nlohmann::operator<<(basic_json), nlohmann::operator<<(json_pointer) + +```cpp +std::ostream& operator<<(std::ostream& o, const basic_json& j); // (1) + +std::ostream& operator<<(std::ostream& o, const json_pointer& ptr); // (2) +``` + +1. Serialize the given JSON value `j` to the output stream `o`. The JSON value will be serialized using the + [`dump`](basic_json/dump.md) member function. + - The indentation of the output can be controlled with the member variable `width` of the output stream `o`. For + instance, using the manipulator `std::setw(4)` on `o` sets the indentation level to `4` and the serialization + result is the same as calling `dump(4)`. + - The indentation character can be controlled with the member variable `fill` of the output stream `o`. + For instance, the manipulator `std::setfill('\\t')` sets indentation to use a tab character rather than the + default space character. +2. Write a string representation of the given JSON pointer `ptr` to the output stream `o`. The string representation is + obtained using the [`to_string`](json_pointer/to_string.md) member function. + +## Parameters + +`o` (in, out) +: stream to write to + +`j` (in) +: JSON value to serialize + +`ptr` (in) +: JSON pointer to write + +## Return value + +the stream `o` + +## Exceptions + +1. Throws [`type_error.316`](../home/exceptions.md#jsonexceptiontype_error316) if a string stored inside the JSON + value is not UTF-8 encoded. Note that unlike the [`dump`](basic_json/dump.md) member functions, no `error_handler` can be set. +2. None. + +## Complexity + +Linear. + +## Notes + +!!! warning "Deprecation" + + Function `#!cpp std::ostream& operator<<(std::ostream& o, const basic_json& j)` replaces function + `#!cpp std::ostream& operator>>(const basic_json& j, std::ostream& o)` which has been deprecated in version 3.0.0. + It will be removed in version 4.0.0. Please replace calls like `#!cpp j >> o;` with `#!cpp o << j;`. + +## Examples + +??? example "Example: (1) serialize JSON value to stream" + + The example below shows the serialization with different parameters to `width` to adjust the indentation level. + + ```cpp + --8<-- "examples/operator_ltlt__basic_json.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_ltlt__basic_json.output" + ``` + +??? example "Example: (2) write JSON pointer to stream" + + The example below shows how to write a JSON pointer to a stream. + + ```cpp + --8<-- "examples/operator_ltlt__json_pointer.cpp" + ``` + + Output: + + ```json + --8<-- "examples/operator_ltlt__json_pointer.output" + ``` +## Version history + +1. Added in version 1.0.0. Added support for indentation character and deprecated + `#!cpp std::ostream& operator>>(const basic_json& j, std::ostream& o)` in version 3.0.0. +3. Added in version 3.11.0. diff --git a/docs/mkdocs/docs/features/parsing/json_lines.md b/docs/mkdocs/docs/features/parsing/json_lines.md index 69c2163b7..659d31792 100644 --- a/docs/mkdocs/docs/features/parsing/json_lines.md +++ b/docs/mkdocs/docs/features/parsing/json_lines.md @@ -36,7 +36,7 @@ JSON Lines input with more than one value is treated as invalid JSON by the [`pa !!! warning "Note" - Using [`operator>>`](../../api/basic_json/operator_gtgt.md) like + Using [`operator>>`](../../api/operator_gtgt.md) like ```cpp json j; diff --git a/docs/mkdocs/mkdocs.yml b/docs/mkdocs/mkdocs.yml index fe822b0c8..8b7dc4762 100644 --- a/docs/mkdocs/mkdocs.yml +++ b/docs/mkdocs/mkdocs.yml @@ -162,8 +162,6 @@ nav: - 'operator<=': api/basic_json/operator_le.md - 'operator>=': api/basic_json/operator_ge.md - 'operator<=>': api/basic_json/operator_spaceship.md - - 'operator<<': api/basic_json/operator_ltlt.md - - 'operator>>': api/basic_json/operator_gtgt.md - 'operator""_json': api/basic_json/operator_literal_json.md - 'operator""_json_pointer': api/basic_json/operator_literal_json_pointer.md - 'out_of_range': api/basic_json/out_of_range.md @@ -212,7 +210,7 @@ nav: - '(Constructor)': api/json_pointer/json_pointer.md - 'back': api/json_pointer/back.md - 'empty': api/json_pointer/empty.md - - 'operator std::string': api/json_pointer/operator_string.md + - 'operator string_t': api/json_pointer/operator_string_t.md - 'operator/': api/json_pointer/operator_slash.md - 'operator/=': api/json_pointer/operator_slasheq.md - 'parent_pointer': api/json_pointer/parent_pointer.md @@ -235,6 +233,9 @@ nav: - 'start_array': api/json_sax/start_array.md - 'start_object': api/json_sax/start_object.md - 'string': api/json_sax/string.md + - 'operator<<(basic_json)': api/operator_ltlt.md + - 'operator<<(json_pointer)': api/operator_ltlt.md + - 'operator>>(basic_json)': api/operator_gtgt.md - 'ordered_json': api/ordered_json.md - 'ordered_map': api/ordered_map.md - macros: @@ -324,6 +325,11 @@ plugins: - minify: minify_html: true - git-revision-date-localized + - redirects: + redirect_maps: + 'api/basic_json/operator_gtgt.md': api/operator_gtgt.md + 'api/basic_json/operator_ltlt.md': api/operator_ltlt.md + 'api/json_pointer/operator_string.md': api/json_pointer/operator_string_t.md extra_css: - css/custom.css diff --git a/docs/mkdocs/requirements.txt b/docs/mkdocs/requirements.txt index aa9fcaf0e..51fceb5d3 100644 --- a/docs/mkdocs/requirements.txt +++ b/docs/mkdocs/requirements.txt @@ -25,6 +25,7 @@ mkdocs-git-revision-date-localized-plugin==1.0.1 mkdocs-material==8.2.10 mkdocs-material-extensions==1.0.3 mkdocs-minify-plugin==0.5.0 +mkdocs-redirects==1.0.4 mkdocs-simple-hooks==0.1.5 nltk==3.7 packaging==21.3 diff --git a/include/nlohmann/detail/json_pointer.hpp b/include/nlohmann/detail/json_pointer.hpp index 35e1ddbc5..79776bcc6 100644 --- a/include/nlohmann/detail/json_pointer.hpp +++ b/include/nlohmann/detail/json_pointer.hpp @@ -12,6 +12,9 @@ #include // isdigit #include // errno, ERANGE #include // strtoull +#ifndef JSON_NO_IO + #include // ostream +#endif // JSON_NO_IO #include // max #include // accumulate #include // string @@ -75,11 +78,22 @@ class json_pointer /// @brief return a string representation of the JSON pointer /// @sa https://json.nlohmann.me/api/json_pointer/operator_string/ + JSON_HEDLEY_DEPRECATED_FOR(3.11.0, to_string()) operator string_t() const { return to_string(); } +#ifndef JSON_NO_IO + /// @brief write string representation of the JSON pointer to stream + /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/ + friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr) + { + o << ptr.to_string(); + return o; + } +#endif + /// @brief append another JSON pointer at the end of this JSON pointer /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/ json_pointer& operator/=(const json_pointer& ptr) diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 78b41822e..3341f0286 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -13458,6 +13458,9 @@ class json_reverse_iterator : public std::reverse_iterator #include // isdigit #include // errno, ERANGE #include // strtoull +#ifndef JSON_NO_IO + #include // ostream +#endif // JSON_NO_IO #include // max #include // accumulate #include // string @@ -13526,11 +13529,22 @@ class json_pointer /// @brief return a string representation of the JSON pointer /// @sa https://json.nlohmann.me/api/json_pointer/operator_string/ + JSON_HEDLEY_DEPRECATED_FOR(3.11.0, to_string()) operator string_t() const { return to_string(); } +#ifndef JSON_NO_IO + /// @brief write string representation of the JSON pointer to stream + /// @sa https://json.nlohmann.me/api/basic_json/operator_ltlt/ + friend std::ostream& operator<<(std::ostream& o, const json_pointer& ptr) + { + o << ptr.to_string(); + return o; + } +#endif + /// @brief append another JSON pointer at the end of this JSON pointer /// @sa https://json.nlohmann.me/api/json_pointer/operator_slasheq/ json_pointer& operator/=(const json_pointer& ptr) diff --git a/tests/src/unit-json_pointer.cpp b/tests/src/unit-json_pointer.cpp index 50a1f1ce9..977af9f6e 100644 --- a/tests/src/unit-json_pointer.cpp +++ b/tests/src/unit-json_pointer.cpp @@ -12,6 +12,8 @@ #include using nlohmann::json; +#include + TEST_CASE("JSON pointers") { SECTION("errors") @@ -475,12 +477,16 @@ TEST_CASE("JSON pointers") SECTION("string representation") { - for (const auto* ptr : + for (const auto* ptr_str : {"", "/foo", "/foo/0", "/", "/a~1b", "/c%d", "/e^f", "/g|h", "/i\\j", "/k\"l", "/ ", "/m~0n" }) { - CHECK(json::json_pointer(ptr).to_string() == ptr); - CHECK(std::string(json::json_pointer(ptr)) == ptr); + json::json_pointer ptr(ptr_str); + std::stringstream ss; + ss << ptr; + CHECK(ptr.to_string() == ptr_str); + CHECK(std::string(ptr) == ptr_str); + CHECK(ss.str() == ptr_str); } }