diff --git a/doc/examples/contains.cpp b/doc/examples/contains.cpp new file mode 100644 index 00000000..df8201c3 --- /dev/null +++ b/doc/examples/contains.cpp @@ -0,0 +1,17 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create some JSON values + json j_object = R"( {"key": "value"} )"_json; + json j_array = R"( [1, 2, 3] )"_json; + + // call contains + std::cout << std::boolalpha << + "j_object contains 'key': " << j_object.contains("key") << '\n' << + "j_object contains 'another': " << j_object.contains("another") << '\n' << + "j_array contains 'key': " << j_array.contains("key") << std::endl; +} diff --git a/doc/examples/contains.link b/doc/examples/contains.link new file mode 100644 index 00000000..c66676a6 --- /dev/null +++ b/doc/examples/contains.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/contains.output b/doc/examples/contains.output new file mode 100644 index 00000000..14ad177b --- /dev/null +++ b/doc/examples/contains.output @@ -0,0 +1,3 @@ +j_object contains 'key': true +j_object contains 'another': false +j_array contains 'key': false diff --git a/doc/examples/json_pointer__empty.cpp b/doc/examples/json_pointer__empty.cpp new file mode 100644 index 00000000..5daaadc6 --- /dev/null +++ b/doc/examples/json_pointer__empty.cpp @@ -0,0 +1,20 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON Pointers + json::json_pointer ptr0; + json::json_pointer ptr1(""); + json::json_pointer ptr2("/foo"); + json::json_pointer ptr3("/foo/0"); + + // call empty() + std::cout << std::boolalpha + << ptr0 << ": " << ptr0.empty() << '\n' + << ptr1 << ": " << ptr1.empty() << '\n' + << ptr2 << ": " << ptr2.empty() << '\n' + << ptr3 << ": " << ptr3.empty() << std::endl; +} diff --git a/doc/examples/json_pointer__empty.link b/doc/examples/json_pointer__empty.link new file mode 100644 index 00000000..e3759120 --- /dev/null +++ b/doc/examples/json_pointer__empty.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/json_pointer__empty.output b/doc/examples/json_pointer__empty.output new file mode 100644 index 00000000..a7ee49c1 --- /dev/null +++ b/doc/examples/json_pointer__empty.output @@ -0,0 +1,4 @@ +"": true +"": true +"/foo": false +"/foo/0": false diff --git a/doc/examples/json_pointer__parent_pointer.cpp b/doc/examples/json_pointer__parent_pointer.cpp new file mode 100644 index 00000000..6021463a --- /dev/null +++ b/doc/examples/json_pointer__parent_pointer.cpp @@ -0,0 +1,18 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // different JSON Pointers + json::json_pointer ptr1(""); + json::json_pointer ptr2("/foo"); + json::json_pointer ptr3("/foo/0"); + + // call parent_pointer() + std::cout << std::boolalpha + << "parent of " << ptr1 << " is " << ptr1.parent_pointer() << '\n' + << "parent of " << ptr2 << " is " << ptr2.parent_pointer() << '\n' + << "parent of " << ptr3 << " is " << ptr3.parent_pointer() << std::endl; +} diff --git a/doc/examples/json_pointer__parent_pointer.link b/doc/examples/json_pointer__parent_pointer.link new file mode 100644 index 00000000..4aa6327e --- /dev/null +++ b/doc/examples/json_pointer__parent_pointer.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/json_pointer__parent_pointer.output b/doc/examples/json_pointer__parent_pointer.output new file mode 100644 index 00000000..4cc6f3f1 --- /dev/null +++ b/doc/examples/json_pointer__parent_pointer.output @@ -0,0 +1,3 @@ +parent of "" is "" +parent of "/foo" is "" +parent of "/foo/0" is "/foo" diff --git a/doc/examples/json_pointer__push_back.cpp b/doc/examples/json_pointer__push_back.cpp new file mode 100644 index 00000000..d6536b3f --- /dev/null +++ b/doc/examples/json_pointer__push_back.cpp @@ -0,0 +1,21 @@ +#include +#include + +using json = nlohmann::json; + +int main() +{ + // create empty JSON Pointer + json::json_pointer ptr; + std::cout << ptr << '\n'; + + // call push_back() + ptr.push_back("foo"); + std::cout << ptr << '\n'; + + ptr.push_back("0"); + std::cout << ptr << '\n'; + + ptr.push_back("bar"); + std::cout << ptr << '\n'; +} diff --git a/doc/examples/json_pointer__push_back.link b/doc/examples/json_pointer__push_back.link new file mode 100644 index 00000000..d0cadd7c --- /dev/null +++ b/doc/examples/json_pointer__push_back.link @@ -0,0 +1 @@ +online \ No newline at end of file diff --git a/doc/examples/json_pointer__push_back.output b/doc/examples/json_pointer__push_back.output new file mode 100644 index 00000000..92c019cd --- /dev/null +++ b/doc/examples/json_pointer__push_back.output @@ -0,0 +1,4 @@ +"" +"/foo" +"/foo/0" +"/foo/0/bar" diff --git a/doc/index.md b/doc/index.md index 1266a273..ea6dc6ae 100644 --- a/doc/index.md +++ b/doc/index.md @@ -57,6 +57,7 @@ These pages contain the API documentation of JSON for Modern C++, a C++11 header - @link nlohmann::basic_json::number_integer_t signed integers @endlink - @link nlohmann::basic_json::number_unsigned_t unsigned integers @endlink - @link nlohmann::basic_json::number_float_t floating-point @endlink +- @link nlohmann::json_pointer JSON Pointer @endlink # Container function overview diff --git a/include/nlohmann/detail/exceptions.hpp b/include/nlohmann/detail/exceptions.hpp index 5a73dedb..519a5975 100644 --- a/include/nlohmann/detail/exceptions.hpp +++ b/include/nlohmann/detail/exceptions.hpp @@ -223,7 +223,7 @@ name / id | example message | description ----------------------------- | --------------- | ------------------------- json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead. json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types. -json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t&. +json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t &. json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types. json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types. json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types. diff --git a/include/nlohmann/detail/input/input_adapters.hpp b/include/nlohmann/detail/input/input_adapters.hpp index 0374731f..8730748c 100644 --- a/include/nlohmann/detail/input/input_adapters.hpp +++ b/include/nlohmann/detail/input/input_adapters.hpp @@ -61,9 +61,9 @@ class file_input_adapter : public input_adapter_protocol // make class move-only file_input_adapter(const file_input_adapter&) = delete; - file_input_adapter(file_input_adapter&&) noexcept = default; + file_input_adapter(file_input_adapter&&) = default; file_input_adapter& operator=(const file_input_adapter&) = delete; - file_input_adapter& operator=(file_input_adapter&&) noexcept = default; + file_input_adapter& operator=(file_input_adapter&&) = default; ~file_input_adapter() override = default; std::char_traits::int_type get_character() noexcept override diff --git a/include/nlohmann/detail/json_pointer.hpp b/include/nlohmann/detail/json_pointer.hpp index a2db2357..3d44e267 100644 --- a/include/nlohmann/detail/json_pointer.hpp +++ b/include/nlohmann/detail/json_pointer.hpp @@ -82,7 +82,9 @@ class json_pointer */ json_pointer& operator/=(const json_pointer& ptr) { - reference_tokens.insert(reference_tokens.end(), ptr.reference_tokens.begin(), ptr.reference_tokens.end()); + reference_tokens.insert(reference_tokens.end(), + ptr.reference_tokens.begin(), + ptr.reference_tokens.end()); return *this; } @@ -102,7 +104,8 @@ class json_pointer /*! @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer */ - friend json_pointer operator/(const json_pointer& left_ptr, const json_pointer& right_ptr) + friend json_pointer operator/(const json_pointer& left_ptr, + const json_pointer& right_ptr) { return json_pointer(left_ptr) /= right_ptr; } @@ -124,7 +127,17 @@ class json_pointer } /*! - @brief create a new JSON pointer that is the parent of this JSON pointer + @brief returns the parent of this JSON pointer + + @return parent of this JSON pointer; in case this JSON pointer is the root, + the root itself is returned + + @complexity Constant. + + @liveexample{The example shows the result of `parent_pointer` for different + JSON Pointers.,json_pointer__parent_pointer} + + @since version 3.6.0 */ json_pointer parent_pointer() const { @@ -138,27 +151,6 @@ class json_pointer return res; } - /*! - @param[in] s reference token to be converted into an array index - - @return integer representation of @a s - - @throw out_of_range.404 if string @a s could not be converted to an integer - */ - static int array_index(const std::string& s) - { - std::size_t processed_chars = 0; - const int res = std::stoi(s, &processed_chars); - - // check if the string was completely read - if (JSON_UNLIKELY(processed_chars != s.size())) - { - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'")); - } - - return res; - } - /*! @brief remove and return last reference token @throw out_of_range.405 if JSON pointer has no parent @@ -177,6 +169,15 @@ class json_pointer /*! @brief append an unescaped token at the end of the reference pointer + + @param[in] token token to add + + @complexity Amortized constant. + + @liveexample{The example shows the result of `push_back` for different + JSON Pointers.,json_pointer__push_back} + + @since version 0.6.0 */ void push_back(const std::string& token) { @@ -189,13 +190,47 @@ class json_pointer reference_tokens.push_back(std::move(token)); } - /// return whether pointer points to the root document + /*! + @brief return whether pointer points to the root document + + @return true iff the JSON pointer points to the root document + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this function never throws exceptions. + + @liveexample{The example shows the result of `empty` for different JSON + Pointers.,json_pointer__empty} + + @since version 3.6.0 + */ bool empty() const noexcept { return reference_tokens.empty(); } private: + /*! + @param[in] s reference token to be converted into an array index + + @return integer representation of @a s + + @throw out_of_range.404 if string @a s could not be converted to an integer + */ + static int array_index(const std::string& s) + { + std::size_t processed_chars = 0; + const int res = std::stoi(s, &processed_chars); + + // check if the string was completely read + if (JSON_UNLIKELY(processed_chars != s.size())) + { + JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'")); + } + + return res; + } + json_pointer top() const { if (JSON_UNLIKELY(empty())) diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 769126e5..6bc13727 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -3901,6 +3901,8 @@ class basic_json @liveexample{The example shows how `find()` is used.,find__key_type} + @sa @ref contains(KeyT&&) const -- checks whether a key exists + @since version 1.0.0 */ template @@ -3979,6 +3981,10 @@ class basic_json @complexity Logarithmic in the size of the JSON object. + @liveexample{The following code shows an example for `contains()`.,contains} + + @sa @ref find(KeyT&&) -- returns an iterator to an object element + @since version 3.6.0 */ template diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 338d2b0d..f5b3aa7c 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -323,7 +323,7 @@ name / id | example message | description ----------------------------- | --------------- | ------------------------- json.exception.type_error.301 | cannot create object from initializer list | To create an object from an initializer list, the initializer list must consist only of a list of pairs whose first element is a string. When this constraint is violated, an array is created instead. json.exception.type_error.302 | type must be object, but is array | During implicit or explicit value conversion, the JSON type must be compatible to the target type. For instance, a JSON string can only be converted into string types, but not into numbers or boolean types. -json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t&. +json.exception.type_error.303 | incompatible ReferenceType for get_ref, actual type is object | To retrieve a reference to a value stored in a @ref basic_json object with @ref get_ref, the type of the reference must match the value type. For instance, for a JSON array, the @a ReferenceType must be @ref array_t &. json.exception.type_error.304 | cannot use at() with string | The @ref at() member functions can only be executed for certain JSON types. json.exception.type_error.305 | cannot use operator[] with string | The @ref operator[] member functions can only be executed for certain JSON types. json.exception.type_error.306 | cannot use value() with string | The @ref value() member functions can only be executed for certain JSON types. @@ -2296,9 +2296,9 @@ class file_input_adapter : public input_adapter_protocol // make class move-only file_input_adapter(const file_input_adapter&) = delete; - file_input_adapter(file_input_adapter&&) noexcept = default; + file_input_adapter(file_input_adapter&&) = default; file_input_adapter& operator=(const file_input_adapter&) = delete; - file_input_adapter& operator=(file_input_adapter&&) noexcept = default; + file_input_adapter& operator=(file_input_adapter&&) = default; ~file_input_adapter() override = default; std::char_traits::int_type get_character() noexcept override @@ -8529,7 +8529,9 @@ class json_pointer */ json_pointer& operator/=(const json_pointer& ptr) { - reference_tokens.insert(reference_tokens.end(), ptr.reference_tokens.begin(), ptr.reference_tokens.end()); + reference_tokens.insert(reference_tokens.end(), + ptr.reference_tokens.begin(), + ptr.reference_tokens.end()); return *this; } @@ -8549,7 +8551,8 @@ class json_pointer /*! @brief create a new JSON pointer by appending the right JSON pointer at the end of the left JSON pointer */ - friend json_pointer operator/(const json_pointer& left_ptr, const json_pointer& right_ptr) + friend json_pointer operator/(const json_pointer& left_ptr, + const json_pointer& right_ptr) { return json_pointer(left_ptr) /= right_ptr; } @@ -8571,7 +8574,17 @@ class json_pointer } /*! - @brief create a new JSON pointer that is the parent of this JSON pointer + @brief returns the parent of this JSON pointer + + @return parent of this JSON pointer; in case this JSON pointer is the root, + the root itself is returned + + @complexity Constant. + + @liveexample{The example shows the result of `parent_pointer` for different + JSON Pointers.,json_pointer__parent_pointer} + + @since version 3.6.0 */ json_pointer parent_pointer() const { @@ -8585,27 +8598,6 @@ class json_pointer return res; } - /*! - @param[in] s reference token to be converted into an array index - - @return integer representation of @a s - - @throw out_of_range.404 if string @a s could not be converted to an integer - */ - static int array_index(const std::string& s) - { - std::size_t processed_chars = 0; - const int res = std::stoi(s, &processed_chars); - - // check if the string was completely read - if (JSON_UNLIKELY(processed_chars != s.size())) - { - JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'")); - } - - return res; - } - /*! @brief remove and return last reference token @throw out_of_range.405 if JSON pointer has no parent @@ -8624,6 +8616,15 @@ class json_pointer /*! @brief append an unescaped token at the end of the reference pointer + + @param[in] token token to add + + @complexity Amortized constant. + + @liveexample{The example shows the result of `push_back` for different + JSON Pointers.,json_pointer__push_back} + + @since version 0.6.0 */ void push_back(const std::string& token) { @@ -8636,13 +8637,47 @@ class json_pointer reference_tokens.push_back(std::move(token)); } - /// return whether pointer points to the root document + /*! + @brief return whether pointer points to the root document + + @return true iff the JSON pointer points to the root document + + @complexity Constant. + + @exceptionsafety No-throw guarantee: this function never throws exceptions. + + @liveexample{The example shows the result of `empty` for different JSON + Pointers.,json_pointer__empty} + + @since version 3.6.0 + */ bool empty() const noexcept { return reference_tokens.empty(); } private: + /*! + @param[in] s reference token to be converted into an array index + + @return integer representation of @a s + + @throw out_of_range.404 if string @a s could not be converted to an integer + */ + static int array_index(const std::string& s) + { + std::size_t processed_chars = 0; + const int res = std::stoi(s, &processed_chars); + + // check if the string was completely read + if (JSON_UNLIKELY(processed_chars != s.size())) + { + JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'")); + } + + return res; + } + json_pointer top() const { if (JSON_UNLIKELY(empty())) @@ -16543,6 +16578,8 @@ class basic_json @liveexample{The example shows how `find()` is used.,find__key_type} + @sa @ref contains(KeyT&&) const -- checks whether a key exists + @since version 1.0.0 */ template @@ -16621,6 +16658,10 @@ class basic_json @complexity Logarithmic in the size of the JSON object. + @liveexample{The following code shows an example for `contains()`.,contains} + + @sa @ref find(KeyT&&) -- returns an iterator to an object element + @since version 3.6.0 */ template