diff --git a/.gitignore b/.gitignore index 24927354e..a63b660f6 100644 --- a/.gitignore +++ b/.gitignore @@ -9,9 +9,10 @@ /.idea /cmake-build-* - +# Visual Studio Code /.vs/ /.vscode/ +/out/ # clangd cache /.cache/ diff --git a/README.md b/README.md index 5d7bd9109..34d737e96 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ [![Documentation](https://img.shields.io/badge/docs-mkdocs-blue.svg)](https://json.nlohmann.me) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT) [![GitHub Releases](https://img.shields.io/github/release/nlohmann/json.svg)](https://github.com/nlohmann/json/releases) +[![Packaging status](https://repology.org/badge/tiny-repos/nlohmann-json.svg)](https://repology.org/project/nlohmann-json/versions) [![GitHub Downloads](https://img.shields.io/github/downloads/nlohmann/json/total)](https://github.com/nlohmann/json/releases) [![GitHub Issues](https://img.shields.io/github/issues/nlohmann/json.svg)](https://github.com/nlohmann/json/issues) [![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/nlohmann/json.svg)](https://isitmaintained.com/project/nlohmann/json "Average time to resolve an issue") @@ -24,6 +25,8 @@ - [Sponsors](#sponsors) - [Support](#support) ([documentation](https://json.nlohmann.me), [FAQ](https://json.nlohmann.me/home/faq/), [discussions](https://github.com/nlohmann/json/discussions), [API](https://json.nlohmann.me/api/basic_json/), [bug issues](https://github.com/nlohmann/json/issues)) - [Examples](#examples) + - [Read JSON from a file](#read-json-from-a-file) + - [Creating `json` objects from JSON literals](#creating-json-objects-from-json-literals) - [JSON as first-class data type](#json-as-first-class-data-type) - [Serialization / Deserialization](#serialization--deserialization) - [STL-like access](#stl-like-access) @@ -98,7 +101,66 @@ There is also a [**docset**](https://github.com/Kapeli/Dash-User-Contributions/t ## Examples -Beside the examples below, you may want to check the [documentation](https://json.nlohmann.me/) where each function contains a separate code example (e.g., check out [`emplace()`](https://json.nlohmann.me/api/basic_json/emplace/)). All [example files](https://github.com/nlohmann/json/tree/develop/docs/examples) can be compiled and executed on their own (e.g., file [emplace.cpp](https://github.com/nlohmann/json/blob/develop/docs/examples/emplace.cpp)). +Here are some examples to give you an idea how to use the class. + +Beside the examples below, you may want to: + +→ Check the [documentation](https://json.nlohmann.me/)\ +→ Browse the [standalone example files](https://github.com/nlohmann/json/tree/develop/docs/examples) + +Every API function (documented in the [API Documentation](https://json.nlohmann.me/api/basic_json/)) has a corresponding standalone example file. For example, the [`emplace()`](https://json.nlohmann.me/api/basic_json/emplace/) function has a matching [emplace.cpp](https://github.com/nlohmann/json/blob/develop/docs/examples/emplace.cpp) example file. + +### Read JSON from a file + +The `json` class provides an API for manipulating a JSON value. To create a `json` object by reading a JSON file: + +```cpp +#include +#include +using json = nlohmann::json; + +// ... + +std::ifstream f("example.json"); +json data = json::parse(f); +``` + +### Creating `json` objects from JSON literals + +Assume you want to create hard-code this literal JSON value in a file, as a `json` object: + +```json +{ + "pi": 3.141, + "happy": true +} +``` + +There are various options: + +```cpp +// Using (raw) string literals and json::parse +json ex1 = json::parse(R"( + { + "pi": 3.141, + "happy": true + } +)"); + +// Using user-defined (raw) string literals +json ex2 = R"( + { + "pi": 3.141, + "happy": true + } +)"_json; + +// Using initializer lists +json ex3 = { + {"happy", true}, + {"pi", 3.141}, +}; +``` ### JSON as first-class data type diff --git a/cmake/ci.cmake b/cmake/ci.cmake index 4fcff86aa..e959edb56 100644 --- a/cmake/ci.cmake +++ b/cmake/ci.cmake @@ -595,7 +595,7 @@ add_custom_target(ci_test_amalgamation add_custom_target(ci_test_single_header COMMAND CXX=${GCC_TOOL} CXXFLAGS="${GCC_CXXFLAGS}" ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=Debug -GNinja - -DJSON_BuildTests=ON -DJSON_MultipleHeader=OFF -DJSON_FastTests=ON + -DJSON_BuildTests=ON -DJSON_MultipleHeaders=OFF -DJSON_FastTests=ON -S${PROJECT_SOURCE_DIR} -B${PROJECT_BINARY_DIR}/build_single_header COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR}/build_single_header COMMAND cd ${PROJECT_BINARY_DIR}/build_single_header && ${CMAKE_CTEST_COMMAND} --parallel ${N} --output-on-failure diff --git a/cmake/test.cmake b/cmake/test.cmake index b8b1250fb..bb840c6c0 100644 --- a/cmake/test.cmake +++ b/cmake/test.cmake @@ -50,9 +50,10 @@ endforeach() # [COMPILE_FEATURES ...] # [COMPILE_OPTIONS ...] # [LINK_LIBRARIES ...] -# [LINK_OPTIONS ...]) +# [LINK_OPTIONS ...] +# [TEST_PROPERTIES ...]) # -# Supply test- and standard-specific build settings. +# Supply test- and standard-specific build settings and/or test properties. # Specify multiple tests using a list e.g., "test-foo;test-bar". # # Must be called BEFORE the test is created. @@ -60,7 +61,7 @@ endforeach() function(json_test_set_test_options tests) cmake_parse_arguments(args "" "" - "CXX_STANDARDS;COMPILE_DEFINITIONS;COMPILE_FEATURES;COMPILE_OPTIONS;LINK_LIBRARIES;LINK_OPTIONS" + "CXX_STANDARDS;COMPILE_DEFINITIONS;COMPILE_FEATURES;COMPILE_OPTIONS;LINK_LIBRARIES;LINK_OPTIONS;TEST_PROPERTIES" ${ARGN}) if(NOT args_CXX_STANDARDS) @@ -91,10 +92,23 @@ function(json_test_set_test_options tests) target_compile_options(${test_interface} INTERFACE ${args_COMPILE_OPTIONS}) target_link_libraries (${test_interface} INTERFACE ${args_LINK_LIBRARIES}) target_link_options(${test_interface} INTERFACE ${args_LINK_OPTIONS}) + #set_target_properties(${test_interface} PROPERTIES JSON_TEST_PROPERTIES "${args_TEST_PROPERTIES}") + set_property(DIRECTORY PROPERTY + ${test_interface}_TEST_PROPERTIES "${args_TEST_PROPERTIES}" + ) endforeach() endforeach() endfunction() +# for internal use by _json_test_add_test() +function(_json_test_apply_test_properties test_target properties_target) + #get_target_property(test_properties ${properties_target} JSON_TEST_PROPERTIES) + get_property(test_properties DIRECTORY PROPERTY ${properties_target}_TEST_PROPERTIES) + if(test_properties) + set_tests_properties(${test_target} PROPERTIES ${test_properties}) + endif() +endfunction() + # for internal use by json_test_add_test_for() function(_json_test_add_test test_name file main cxx_standard) set(test_target ${test_name}_cpp${cxx_standard}) @@ -142,6 +156,23 @@ function(_json_test_add_test test_name file main cxx_standard) endif() set_tests_properties(${test_target} PROPERTIES LABELS "all" FIXTURES_REQUIRED TEST_DATA) + # apply standard-specific test properties + if(TARGET _json_test_interface__cpp_${cxx_standard}) + _json_test_apply_test_properties(${test_target} _json_test_interface__cpp_${cxx_standard}) + endif() + + # apply test-specific test properties + if(TARGET _json_test_interface_${test_name}) + _json_test_apply_test_properties(${test_target} _json_test_interface_${test_name}) + endif() + + # apply test- and standard-specific test properties + if(TARGET _json_test_interface_${test_name}_cpp_${cxx_standard}) + _json_test_apply_test_properties(${test_target} + _json_test_interface_${test_name}_cpp_${cxx_standard} + ) + endif() + if(JSON_Valgrind) add_test(NAME ${test_target}_valgrind COMMAND ${memcheck_command} $ ${DOCTEST_TEST_FILTER} diff --git a/include/nlohmann/detail/meta/type_traits.hpp b/include/nlohmann/detail/meta/type_traits.hpp index 0de66bca5..11bf3c12a 100644 --- a/include/nlohmann/detail/meta/type_traits.hpp +++ b/include/nlohmann/detail/meta/type_traits.hpp @@ -512,16 +512,23 @@ decltype(std::declval()(std::declval(), std::declval())), decltype(std::declval()(std::declval(), std::declval())) >> : std::true_type {}; -// checks if BasicJsonType::object_t::key_type and KeyType are comparable using Compare functor -template -using is_key_type_comparable = typename is_comparable < - typename BasicJsonType::object_comparator_t, - const key_type_t&, - KeyType >::type; - template using detect_is_transparent = typename T::is_transparent; +// type trait to check if KeyType can be used as object key (without a BasicJsonType) +// see is_usable_as_basic_json_key_type below +template> +using is_usable_as_key_type = typename std::conditional < + is_comparable::value + && !(ExcludeObjectKeyType && std::is_same::value) + && (!RequireTransparentComparator + || is_detected ::value) + && !is_json_pointer::value, + std::true_type, + std::false_type >::type; + // type trait to check if KeyType can be used as object key // true if: // - KeyType is comparable with BasicJsonType::object_t::key_type @@ -530,17 +537,13 @@ using detect_is_transparent = typename T::is_transparent; // - KeyType is not a JSON iterator or json_pointer template> -using is_usable_as_key_type = typename std::conditional < - is_key_type_comparable::value - && !(ExcludeObjectKeyType && std::is_same::value) - && (!RequireTransparentComparator || is_detected < - detect_is_transparent, - typename BasicJsonType::object_comparator_t >::value) - && !is_json_iterator_of::value - && !is_json_pointer::value, - std::true_type, - std::false_type >::type; +using is_usable_as_basic_json_key_type = typename std::conditional < + is_usable_as_key_type::value + && !is_json_iterator_of::value, + std::true_type, + std::false_type >::type; template using detect_erase_with_key_type = decltype(std::declval().erase(std::declval())); diff --git a/include/nlohmann/detail/output/output_adapters.hpp b/include/nlohmann/detail/output/output_adapters.hpp index 78a9f3860..134bd9aab 100644 --- a/include/nlohmann/detail/output/output_adapters.hpp +++ b/include/nlohmann/detail/output/output_adapters.hpp @@ -61,7 +61,7 @@ class output_vector_adapter : public output_adapter_protocol JSON_HEDLEY_NON_NULL(2) void write_characters(const CharType* s, std::size_t length) override { - std::copy(s, s + length, std::back_inserter(v)); + v.insert(v.end(), s, s + length); } private: diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 32e33a26e..faa943618 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -2001,7 +2001,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief access specified object element with bounds checking /// @sa https://json.nlohmann.me/api/basic_json/at/ template::value, int> = 0> + detail::is_usable_as_basic_json_key_type::value, int> = 0> reference at(KeyType && key) { // at only works for objects @@ -2039,7 +2039,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief access specified object element with bounds checking /// @sa https://json.nlohmann.me/api/basic_json/at/ template::value, int> = 0> + detail::is_usable_as_basic_json_key_type::value, int> = 0> const_reference at(KeyType && key) const { // at only works for objects @@ -2169,7 +2169,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief access specified object element /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ template::value, int > = 0 > + detail::is_usable_as_basic_json_key_type::value, int > = 0 > reference operator[](KeyType && key) { // implicitly convert null value to an empty object @@ -2193,7 +2193,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief access specified object element /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ template::value, int > = 0 > + detail::is_usable_as_basic_json_key_type::value, int > = 0 > const_reference operator[](KeyType && key) const { // const operator[] only works for objects @@ -2262,7 +2262,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec template < class KeyType, class ValueType, detail::enable_if_t < detail::is_getable::value && !std::is_same::value - && detail::is_usable_as_key_type::value, int > = 0 > + && detail::is_usable_as_basic_json_key_type::value, int > = 0 > typename std::decay::type value(KeyType && key, ValueType && default_value) const { // value only works for objects @@ -2561,7 +2561,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief remove element from a JSON object given a key /// @sa https://json.nlohmann.me/api/basic_json/erase/ template::value, int> = 0> + detail::is_usable_as_basic_json_key_type::value, int> = 0> size_type erase(KeyType && key) { return erase_internal(std::forward(key)); @@ -2628,7 +2628,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief find an element in a JSON object /// @sa https://json.nlohmann.me/api/basic_json/find/ template::value, int> = 0> + detail::is_usable_as_basic_json_key_type::value, int> = 0> iterator find(KeyType && key) { auto result = end(); @@ -2644,7 +2644,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief find an element in a JSON object /// @sa https://json.nlohmann.me/api/basic_json/find/ template::value, int> = 0> + detail::is_usable_as_basic_json_key_type::value, int> = 0> const_iterator find(KeyType && key) const { auto result = cend(); @@ -2668,7 +2668,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief returns the number of occurrences of a key in a JSON object /// @sa https://json.nlohmann.me/api/basic_json/count/ template::value, int> = 0> + detail::is_usable_as_basic_json_key_type::value, int> = 0> size_type count(KeyType && key) const { // return 0 for all nonobject types @@ -2685,7 +2685,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief check the existence of an element in a JSON object /// @sa https://json.nlohmann.me/api/basic_json/contains/ template::value, int> = 0> + detail::is_usable_as_basic_json_key_type::value, int> = 0> bool contains(KeyType && key) const { return is_object() && m_value.object->find(std::forward(key)) != m_value.object->end(); diff --git a/include/nlohmann/ordered_map.hpp b/include/nlohmann/ordered_map.hpp index 1f063a489..76c1d5077 100644 --- a/include/nlohmann/ordered_map.hpp +++ b/include/nlohmann/ordered_map.hpp @@ -18,6 +18,7 @@ #include // vector #include +#include namespace nlohmann { @@ -60,21 +61,50 @@ template , return {it, false}; } } - Container::emplace_back(key, t); - return {--this->end(), true}; + Container::emplace_back(key, std::forward(t)); + return {std::prev(this->end()), true}; } - T& operator[](const Key& key) + template::value, int> = 0> + std::pair emplace(KeyType && key, T && t) + { + for (auto it = this->begin(); it != this->end(); ++it) + { + if (m_compare(it->first, key)) + { + return {it, false}; + } + } + Container::emplace_back(std::forward(key), std::forward(t)); + return {std::prev(this->end()), true}; + } + + T& operator[](const key_type& key) { return emplace(key, T{}).first->second; } - const T& operator[](const Key& key) const + template::value, int> = 0> + T & operator[](KeyType && key) + { + return emplace(std::forward(key), T{}).first->second; + } + + const T& operator[](const key_type& key) const { return at(key); } - T& at(const Key& key) + template::value, int> = 0> + const T & operator[](KeyType && key) const + { + return at(std::forward(key)); + } + + T& at(const key_type& key) { for (auto it = this->begin(); it != this->end(); ++it) { @@ -87,7 +117,9 @@ template , JSON_THROW(std::out_of_range("key not found")); } - const T& at(const Key& key) const + template::value, int> = 0> + T & at(KeyType && key) { for (auto it = this->begin(); it != this->end(); ++it) { @@ -100,7 +132,56 @@ template , JSON_THROW(std::out_of_range("key not found")); } - size_type erase(const Key& key) + const T& at(const key_type& key) const + { + for (auto it = this->begin(); it != this->end(); ++it) + { + if (m_compare(it->first, key)) + { + return it->second; + } + } + + JSON_THROW(std::out_of_range("key not found")); + } + + template::value, int> = 0> + const T & at(KeyType && key) const + { + for (auto it = this->begin(); it != this->end(); ++it) + { + if (m_compare(it->first, key)) + { + return it->second; + } + } + + JSON_THROW(std::out_of_range("key not found")); + } + + size_type erase(const key_type& key) + { + for (auto it = this->begin(); it != this->end(); ++it) + { + if (m_compare(it->first, key)) + { + // Since we cannot move const Keys, re-construct them in place + for (auto next = it; ++next != this->end(); ++it) + { + it->~value_type(); // Destroy but keep allocation + new (&*it) value_type{std::move(*next)}; + } + Container::pop_back(); + return 1; + } + } + return 0; + } + + template::value, int> = 0> + size_type erase(KeyType && key) { for (auto it = this->begin(); it != this->end(); ++it) { @@ -126,6 +207,11 @@ template , iterator erase(iterator first, iterator last) { + if (first == last) + { + return first; + } + const auto elements_affected = std::distance(first, last); const auto offset = std::distance(Container::begin(), first); @@ -172,7 +258,7 @@ template , return Container::begin() + offset; } - size_type count(const Key& key) const + size_type count(const key_type& key) const { for (auto it = this->begin(); it != this->end(); ++it) { @@ -184,7 +270,21 @@ template , return 0; } - iterator find(const Key& key) + template::value, int> = 0> + size_type count(KeyType && key) const + { + for (auto it = this->begin(); it != this->end(); ++it) + { + if (m_compare(it->first, key)) + { + return 1; + } + } + return 0; + } + + iterator find(const key_type& key) { for (auto it = this->begin(); it != this->end(); ++it) { @@ -196,7 +296,21 @@ template , return Container::end(); } - const_iterator find(const Key& key) const + template::value, int> = 0> + iterator find(KeyType && key) + { + for (auto it = this->begin(); it != this->end(); ++it) + { + if (m_compare(it->first, key)) + { + return it; + } + } + return Container::end(); + } + + const_iterator find(const key_type& key) const { for (auto it = this->begin(); it != this->end(); ++it) { diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 8e8d0f3d3..cc5562d06 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -3800,16 +3800,23 @@ decltype(std::declval()(std::declval(), std::declval())), decltype(std::declval()(std::declval(), std::declval())) >> : std::true_type {}; -// checks if BasicJsonType::object_t::key_type and KeyType are comparable using Compare functor -template -using is_key_type_comparable = typename is_comparable < - typename BasicJsonType::object_comparator_t, - const key_type_t&, - KeyType >::type; - template using detect_is_transparent = typename T::is_transparent; +// type trait to check if KeyType can be used as object key (without a BasicJsonType) +// see is_usable_as_basic_json_key_type below +template> +using is_usable_as_key_type = typename std::conditional < + is_comparable::value + && !(ExcludeObjectKeyType && std::is_same::value) + && (!RequireTransparentComparator + || is_detected ::value) + && !is_json_pointer::value, + std::true_type, + std::false_type >::type; + // type trait to check if KeyType can be used as object key // true if: // - KeyType is comparable with BasicJsonType::object_t::key_type @@ -3818,17 +3825,13 @@ using detect_is_transparent = typename T::is_transparent; // - KeyType is not a JSON iterator or json_pointer template> -using is_usable_as_key_type = typename std::conditional < - is_key_type_comparable::value - && !(ExcludeObjectKeyType && std::is_same::value) - && (!RequireTransparentComparator || is_detected < - detect_is_transparent, - typename BasicJsonType::object_comparator_t >::value) - && !is_json_iterator_of::value - && !is_json_pointer::value, - std::true_type, - std::false_type >::type; +using is_usable_as_basic_json_key_type = typename std::conditional < + is_usable_as_key_type::value + && !is_json_iterator_of::value, + std::true_type, + std::false_type >::type; template using detect_erase_with_key_type = decltype(std::declval().erase(std::declval())); @@ -14508,7 +14511,7 @@ class output_vector_adapter : public output_adapter_protocol JSON_HEDLEY_NON_NULL(2) void write_characters(const CharType* s, std::size_t length) override { - std::copy(s, s + length, std::back_inserter(v)); + v.insert(v.end(), s, s + length); } private: @@ -18552,6 +18555,8 @@ class serializer // #include +// #include + namespace nlohmann { @@ -18594,21 +18599,50 @@ template , return {it, false}; } } - Container::emplace_back(key, t); - return {--this->end(), true}; + Container::emplace_back(key, std::forward(t)); + return {std::prev(this->end()), true}; } - T& operator[](const Key& key) + template::value, int> = 0> + std::pair emplace(KeyType && key, T && t) + { + for (auto it = this->begin(); it != this->end(); ++it) + { + if (m_compare(it->first, key)) + { + return {it, false}; + } + } + Container::emplace_back(std::forward(key), std::forward(t)); + return {std::prev(this->end()), true}; + } + + T& operator[](const key_type& key) { return emplace(key, T{}).first->second; } - const T& operator[](const Key& key) const + template::value, int> = 0> + T & operator[](KeyType && key) + { + return emplace(std::forward(key), T{}).first->second; + } + + const T& operator[](const key_type& key) const { return at(key); } - T& at(const Key& key) + template::value, int> = 0> + const T & operator[](KeyType && key) const + { + return at(std::forward(key)); + } + + T& at(const key_type& key) { for (auto it = this->begin(); it != this->end(); ++it) { @@ -18621,7 +18655,9 @@ template , JSON_THROW(std::out_of_range("key not found")); } - const T& at(const Key& key) const + template::value, int> = 0> + T & at(KeyType && key) { for (auto it = this->begin(); it != this->end(); ++it) { @@ -18634,7 +18670,56 @@ template , JSON_THROW(std::out_of_range("key not found")); } - size_type erase(const Key& key) + const T& at(const key_type& key) const + { + for (auto it = this->begin(); it != this->end(); ++it) + { + if (m_compare(it->first, key)) + { + return it->second; + } + } + + JSON_THROW(std::out_of_range("key not found")); + } + + template::value, int> = 0> + const T & at(KeyType && key) const + { + for (auto it = this->begin(); it != this->end(); ++it) + { + if (m_compare(it->first, key)) + { + return it->second; + } + } + + JSON_THROW(std::out_of_range("key not found")); + } + + size_type erase(const key_type& key) + { + for (auto it = this->begin(); it != this->end(); ++it) + { + if (m_compare(it->first, key)) + { + // Since we cannot move const Keys, re-construct them in place + for (auto next = it; ++next != this->end(); ++it) + { + it->~value_type(); // Destroy but keep allocation + new (&*it) value_type{std::move(*next)}; + } + Container::pop_back(); + return 1; + } + } + return 0; + } + + template::value, int> = 0> + size_type erase(KeyType && key) { for (auto it = this->begin(); it != this->end(); ++it) { @@ -18660,6 +18745,11 @@ template , iterator erase(iterator first, iterator last) { + if (first == last) + { + return first; + } + const auto elements_affected = std::distance(first, last); const auto offset = std::distance(Container::begin(), first); @@ -18706,7 +18796,7 @@ template , return Container::begin() + offset; } - size_type count(const Key& key) const + size_type count(const key_type& key) const { for (auto it = this->begin(); it != this->end(); ++it) { @@ -18718,7 +18808,21 @@ template , return 0; } - iterator find(const Key& key) + template::value, int> = 0> + size_type count(KeyType && key) const + { + for (auto it = this->begin(); it != this->end(); ++it) + { + if (m_compare(it->first, key)) + { + return 1; + } + } + return 0; + } + + iterator find(const key_type& key) { for (auto it = this->begin(); it != this->end(); ++it) { @@ -18730,7 +18834,21 @@ template , return Container::end(); } - const_iterator find(const Key& key) const + template::value, int> = 0> + iterator find(KeyType && key) + { + for (auto it = this->begin(); it != this->end(); ++it) + { + if (m_compare(it->first, key)) + { + return it; + } + } + return Container::end(); + } + + const_iterator find(const key_type& key) const { for (auto it = this->begin(); it != this->end(); ++it) { @@ -20708,7 +20826,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief access specified object element with bounds checking /// @sa https://json.nlohmann.me/api/basic_json/at/ template::value, int> = 0> + detail::is_usable_as_basic_json_key_type::value, int> = 0> reference at(KeyType && key) { // at only works for objects @@ -20746,7 +20864,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief access specified object element with bounds checking /// @sa https://json.nlohmann.me/api/basic_json/at/ template::value, int> = 0> + detail::is_usable_as_basic_json_key_type::value, int> = 0> const_reference at(KeyType && key) const { // at only works for objects @@ -20876,7 +20994,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief access specified object element /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ template::value, int > = 0 > + detail::is_usable_as_basic_json_key_type::value, int > = 0 > reference operator[](KeyType && key) { // implicitly convert null value to an empty object @@ -20900,7 +21018,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief access specified object element /// @sa https://json.nlohmann.me/api/basic_json/operator%5B%5D/ template::value, int > = 0 > + detail::is_usable_as_basic_json_key_type::value, int > = 0 > const_reference operator[](KeyType && key) const { // const operator[] only works for objects @@ -20969,7 +21087,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec template < class KeyType, class ValueType, detail::enable_if_t < detail::is_getable::value && !std::is_same::value - && detail::is_usable_as_key_type::value, int > = 0 > + && detail::is_usable_as_basic_json_key_type::value, int > = 0 > typename std::decay::type value(KeyType && key, ValueType && default_value) const { // value only works for objects @@ -21268,7 +21386,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief remove element from a JSON object given a key /// @sa https://json.nlohmann.me/api/basic_json/erase/ template::value, int> = 0> + detail::is_usable_as_basic_json_key_type::value, int> = 0> size_type erase(KeyType && key) { return erase_internal(std::forward(key)); @@ -21335,7 +21453,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief find an element in a JSON object /// @sa https://json.nlohmann.me/api/basic_json/find/ template::value, int> = 0> + detail::is_usable_as_basic_json_key_type::value, int> = 0> iterator find(KeyType && key) { auto result = end(); @@ -21351,7 +21469,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief find an element in a JSON object /// @sa https://json.nlohmann.me/api/basic_json/find/ template::value, int> = 0> + detail::is_usable_as_basic_json_key_type::value, int> = 0> const_iterator find(KeyType && key) const { auto result = cend(); @@ -21375,7 +21493,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief returns the number of occurrences of a key in a JSON object /// @sa https://json.nlohmann.me/api/basic_json/count/ template::value, int> = 0> + detail::is_usable_as_basic_json_key_type::value, int> = 0> size_type count(KeyType && key) const { // return 0 for all nonobject types @@ -21392,7 +21510,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @brief check the existence of an element in a JSON object /// @sa https://json.nlohmann.me/api/basic_json/contains/ template::value, int> = 0> + detail::is_usable_as_basic_json_key_type::value, int> = 0> bool contains(KeyType && key) const { return is_object() && m_value.object->find(std::forward(key)) != m_value.object->end(); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8f9240f1a..a664f4baf 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -80,12 +80,17 @@ endif() # disable exceptions for test-disabled_exceptions json_test_set_test_options(test-disabled_exceptions COMPILE_DEFINITIONS JSON_NOEXCEPTION) if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU") -json_test_set_test_options(test-disabled_exceptions COMPILE_OPTIONS -fno-exceptions) + json_test_set_test_options(test-disabled_exceptions COMPILE_OPTIONS -fno-exceptions) elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") # disabled due to https://github.com/nlohmann/json/discussions/2824 #json_test_set_test_options(test-disabled_exceptions COMPILE_DEFINITIONS _HAS_EXCEPTIONS=0 COMPILE_OPTIONS /EH) endif() +# set timeouts for Unicode tests +json_test_set_test_options("test-unicode2;test-unicode3;test-unicode4;test-unicode5" + TEST_PROPERTIES "TIMEOUT_AFTER_MATCH;1500$UTF-8 strings checked" +) + ############################################################################# # add unit tests ############################################################################# diff --git a/tests/benchmarks/src/benchmarks.cpp b/tests/benchmarks/src/benchmarks.cpp index 0b3084bc3..4cc987dc0 100644 --- a/tests/benchmarks/src/benchmarks.cpp +++ b/tests/benchmarks/src/benchmarks.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include using json = nlohmann::json; @@ -115,4 +117,63 @@ BENCHMARK_CAPTURE(Dump, small_signed_ints / -, TEST_DATA_DIRECTORY "/regression/ BENCHMARK_CAPTURE(Dump, small_signed_ints / 4, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json", 4); +////////////////////////////////////////////////////////////////////////////// +// serialize CBOR +////////////////////////////////////////////////////////////////////////////// +static void ToCbor(benchmark::State& state, const char* filename) +{ + std::ifstream f(filename); + std::string str((std::istreambuf_iterator(f)), std::istreambuf_iterator()); + json j = json::parse(str); + + while (state.KeepRunning()) + { + json::to_cbor(j); + } + + state.SetBytesProcessed(state.iterations() * json::to_cbor(j).size()); +} +BENCHMARK_CAPTURE(ToCbor, jeopardy, TEST_DATA_DIRECTORY "/jeopardy/jeopardy.json"); +BENCHMARK_CAPTURE(ToCbor, canada, TEST_DATA_DIRECTORY "/nativejson-benchmark/canada.json"); +BENCHMARK_CAPTURE(ToCbor, citm_catalog, TEST_DATA_DIRECTORY "/nativejson-benchmark/citm_catalog.json"); +BENCHMARK_CAPTURE(ToCbor, twitter, TEST_DATA_DIRECTORY "/nativejson-benchmark/twitter.json"); +BENCHMARK_CAPTURE(ToCbor, floats, TEST_DATA_DIRECTORY "/regression/floats.json"); +BENCHMARK_CAPTURE(ToCbor, signed_ints, TEST_DATA_DIRECTORY "/regression/signed_ints.json"); +BENCHMARK_CAPTURE(ToCbor, unsigned_ints, TEST_DATA_DIRECTORY "/regression/unsigned_ints.json"); +BENCHMARK_CAPTURE(ToCbor, small_signed_ints, TEST_DATA_DIRECTORY "/regression/small_signed_ints.json"); + +////////////////////////////////////////////////////////////////////////////// +// serialize binary CBOR +////////////////////////////////////////////////////////////////////////////// +static void BinaryToCbor(benchmark::State& state) +{ + std::vector data(256); + std::iota(data.begin(), data.end(), 0); + + auto it = data.begin(); + std::vector in; + in.reserve(state.range(0)); + for (int i = 0; i < state.range(0); ++i) + { + if (it == data.end()) + { + it = data.begin(); + } + + in.push_back(*it); + ++it; + } + + json::binary_t bin{in}; + json j{{"type", "binary"}, {"data", bin}}; + + while (state.KeepRunning()) + { + json::to_cbor(j); + } + + state.SetBytesProcessed(state.iterations() * json::to_cbor(j).size()); +} +BENCHMARK(BinaryToCbor)->RangeMultiplier(2)->Range(8, 8 << 12); + BENCHMARK_MAIN(); diff --git a/tests/src/unit-element_access2.cpp b/tests/src/unit-element_access2.cpp index 48a1b88a7..d164cf99f 100644 --- a/tests/src/unit-element_access2.cpp +++ b/tests/src/unit-element_access2.cpp @@ -10,67 +10,66 @@ #include "doctest_compatibility.h" #include -using nlohmann::json; -TEST_CASE("element access 2") +TEST_CASE_TEMPLATE("element access 2", Json, nlohmann::json, nlohmann::ordered_json) { SECTION("object") { - json j = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", json::object()}, {"array", {1, 2, 3}}}; - const json j_const = j; + Json j = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", Json::object()}, {"array", {1, 2, 3}}}; + const Json j_const = j; SECTION("access specified element with bounds checking") { SECTION("access within bounds") { - CHECK(j.at("integer") == json(1)); - CHECK(j.at("unsigned") == json(1u)); - CHECK(j.at("boolean") == json(true)); - CHECK(j.at("null") == json(nullptr)); - CHECK(j.at("string") == json("hello world")); - CHECK(j.at("floating") == json(42.23)); - CHECK(j.at("object") == json::object()); - CHECK(j.at("array") == json({1, 2, 3})); + CHECK(j.at("integer") == Json(1)); + CHECK(j.at("unsigned") == Json(1u)); + CHECK(j.at("boolean") == Json(true)); + CHECK(j.at("null") == Json(nullptr)); + CHECK(j.at("string") == Json("hello world")); + CHECK(j.at("floating") == Json(42.23)); + CHECK(j.at("object") == Json::object()); + CHECK(j.at("array") == Json({1, 2, 3})); - CHECK(j_const.at("integer") == json(1)); - CHECK(j_const.at("unsigned") == json(1u)); - CHECK(j_const.at("boolean") == json(true)); - CHECK(j_const.at("null") == json(nullptr)); - CHECK(j_const.at("string") == json("hello world")); - CHECK(j_const.at("floating") == json(42.23)); - CHECK(j_const.at("object") == json::object()); - CHECK(j_const.at("array") == json({1, 2, 3})); + CHECK(j_const.at("integer") == Json(1)); + CHECK(j_const.at("unsigned") == Json(1u)); + CHECK(j_const.at("boolean") == Json(true)); + CHECK(j_const.at("null") == Json(nullptr)); + CHECK(j_const.at("string") == Json("hello world")); + CHECK(j_const.at("floating") == Json(42.23)); + CHECK(j_const.at("object") == Json::object()); + CHECK(j_const.at("array") == Json({1, 2, 3})); #ifdef JSON_HAS_CPP_17 - CHECK(j.at(std::string_view("integer")) == json(1)); - CHECK(j.at(std::string_view("unsigned")) == json(1u)); - CHECK(j.at(std::string_view("boolean")) == json(true)); - CHECK(j.at(std::string_view("null")) == json(nullptr)); - CHECK(j.at(std::string_view("string")) == json("hello world")); - CHECK(j.at(std::string_view("floating")) == json(42.23)); - CHECK(j.at(std::string_view("object")) == json::object()); - CHECK(j.at(std::string_view("array")) == json({1, 2, 3})); + CHECK(j.at(std::string_view("integer")) == Json(1)); + CHECK(j.at(std::string_view("unsigned")) == Json(1u)); + CHECK(j.at(std::string_view("boolean")) == Json(true)); + CHECK(j.at(std::string_view("null")) == Json(nullptr)); + CHECK(j.at(std::string_view("string")) == Json("hello world")); + CHECK(j.at(std::string_view("floating")) == Json(42.23)); + CHECK(j.at(std::string_view("object")) == Json::object()); + CHECK(j.at(std::string_view("array")) == Json({1, 2, 3})); - CHECK(j_const.at(std::string_view("integer")) == json(1)); - CHECK(j_const.at(std::string_view("unsigned")) == json(1u)); - CHECK(j_const.at(std::string_view("boolean")) == json(true)); - CHECK(j_const.at(std::string_view("null")) == json(nullptr)); - CHECK(j_const.at(std::string_view("string")) == json("hello world")); - CHECK(j_const.at(std::string_view("floating")) == json(42.23)); - CHECK(j_const.at(std::string_view("object")) == json::object()); - CHECK(j_const.at(std::string_view("array")) == json({1, 2, 3})); + CHECK(j_const.at(std::string_view("integer")) == Json(1)); + CHECK(j_const.at(std::string_view("unsigned")) == Json(1u)); + CHECK(j_const.at(std::string_view("boolean")) == Json(true)); + CHECK(j_const.at(std::string_view("null")) == Json(nullptr)); + CHECK(j_const.at(std::string_view("string")) == Json("hello world")); + CHECK(j_const.at(std::string_view("floating")) == Json(42.23)); + CHECK(j_const.at(std::string_view("object")) == Json::object()); + CHECK(j_const.at(std::string_view("array")) == Json({1, 2, 3})); #endif } SECTION("access outside bounds") { - CHECK_THROWS_WITH_AS(j.at("foo"), "[json.exception.out_of_range.403] key 'foo' not found", json::out_of_range&); - CHECK_THROWS_WITH_AS(j_const.at("foo"), "[json.exception.out_of_range.403] key 'foo' not found", json::out_of_range&); + CHECK_THROWS_WITH_AS(j.at("foo"), "[json.exception.out_of_range.403] key 'foo' not found", typename Json::out_of_range&); + CHECK_THROWS_WITH_AS(j_const.at("foo"), "[json.exception.out_of_range.403] key 'foo' not found", typename Json::out_of_range&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j.at(std::string_view("foo")), "[json.exception.out_of_range.403] key 'foo' not found", json::out_of_range&); - CHECK_THROWS_WITH_AS(j_const.at(std::string_view("foo")), "[json.exception.out_of_range.403] key 'foo' not found", json::out_of_range&); + CHECK_THROWS_WITH_AS(j.at(std::string_view("foo")), "[json.exception.out_of_range.403] key 'foo' not found", typename Json::out_of_range&); + CHECK_THROWS_WITH_AS(j_const.at(std::string_view("foo")), "[json.exception.out_of_range.403] key 'foo' not found", typename Json::out_of_range&); #endif } @@ -78,92 +77,92 @@ TEST_CASE("element access 2") { SECTION("null") { - json j_nonobject(json::value_t::null); - const json j_nonobject_const(j_nonobject); - CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with null", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with null", json::type_error&); + Json j_nonobject(Json::value_t::null); + const Json j_nonobject_const(j_nonobject); + CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with null", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with null", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view(std::string_view("foo"))), "[json.exception.type_error.304] cannot use at() with null", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view(std::string_view("foo"))), "[json.exception.type_error.304] cannot use at() with null", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view(std::string_view("foo"))), "[json.exception.type_error.304] cannot use at() with null", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view(std::string_view("foo"))), "[json.exception.type_error.304] cannot use at() with null", typename Json::type_error&); #endif } SECTION("boolean") { - json j_nonobject(json::value_t::boolean); - const json j_nonobject_const(j_nonobject); - CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with boolean", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with boolean", json::type_error&); + Json j_nonobject(Json::value_t::boolean); + const Json j_nonobject_const(j_nonobject); + CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with boolean", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with boolean", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with boolean", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with boolean", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with boolean", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with boolean", typename Json::type_error&); #endif } SECTION("string") { - json j_nonobject(json::value_t::string); - const json j_nonobject_const(j_nonobject); - CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with string", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with string", json::type_error&); + Json j_nonobject(Json::value_t::string); + const Json j_nonobject_const(j_nonobject); + CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with string", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with string", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with string", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with string", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with string", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with string", typename Json::type_error&); #endif } SECTION("array") { - json j_nonobject(json::value_t::array); - const json j_nonobject_const(j_nonobject); - CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with array", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with array", json::type_error&); + Json j_nonobject(Json::value_t::array); + const Json j_nonobject_const(j_nonobject); + CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with array", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with array", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with array", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with array", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with array", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with array", typename Json::type_error&); #endif } SECTION("number (integer)") { - json j_nonobject(json::value_t::number_integer); - const json j_nonobject_const(j_nonobject); - CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number", json::type_error&); + Json j_nonobject(Json::value_t::number_integer); + const Json j_nonobject_const(j_nonobject); + CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); #endif } SECTION("number (unsigned)") { - json j_nonobject(json::value_t::number_unsigned); - const json j_nonobject_const(j_nonobject); - CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number", json::type_error&); + Json j_nonobject(Json::value_t::number_unsigned); + const Json j_nonobject_const(j_nonobject); + CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); #endif } SECTION("number (floating-point)") { - json j_nonobject(json::value_t::number_float); - const json j_nonobject_const(j_nonobject); - CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number", json::type_error&); + Json j_nonobject(Json::value_t::number_float); + const Json j_nonobject_const(j_nonobject); + CHECK_THROWS_WITH_AS(j_nonobject.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.at("foo"), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.at(std::string_view("foo")), "[json.exception.type_error.304] cannot use at() with number", typename Json::type_error&); #endif } } @@ -179,14 +178,14 @@ TEST_CASE("element access 2") CHECK(j.value("integer", 1.0) == Approx(1)); CHECK(j.value("unsigned", 2) == 1u); CHECK(j.value("unsigned", 1.0) == Approx(1u)); - CHECK(j.value("null", json(1)) == json()); + CHECK(j.value("null", Json(1)) == Json()); CHECK(j.value("boolean", false) == true); CHECK(j.value("string", "bar") == "hello world"); CHECK(j.value("string", std::string("bar")) == "hello world"); CHECK(j.value("floating", 12.34) == Approx(42.23)); CHECK(j.value("floating", 12) == 42); - CHECK(j.value("object", json({{"foo", "bar"}})) == json::object()); - CHECK(j.value("array", json({10, 100})) == json({1, 2, 3})); + CHECK(j.value("object", Json({{"foo", "bar"}})) == Json::object()); + CHECK(j.value("array", Json({10, 100})) == Json({1, 2, 3})); CHECK(j_const.value("integer", 2) == 1); CHECK(j_const.value("integer", 1.0) == Approx(1)); @@ -197,22 +196,22 @@ TEST_CASE("element access 2") CHECK(j_const.value("string", std::string("bar")) == "hello world"); CHECK(j_const.value("floating", 12.34) == Approx(42.23)); CHECK(j_const.value("floating", 12) == 42); - CHECK(j_const.value("object", json({{"foo", "bar"}})) == json::object()); - CHECK(j_const.value("array", json({10, 100})) == json({1, 2, 3})); + CHECK(j_const.value("object", Json({{"foo", "bar"}})) == Json::object()); + CHECK(j_const.value("array", Json({10, 100})) == Json({1, 2, 3})); #ifdef JSON_HAS_CPP_17 CHECK(j.value(std::string_view("integer"), 2) == 1); CHECK(j.value(std::string_view("integer"), 1.0) == Approx(1)); CHECK(j.value(std::string_view("unsigned"), 2) == 1u); CHECK(j.value(std::string_view("unsigned"), 1.0) == Approx(1u)); - CHECK(j.value(std::string_view("null"), json(1)) == json()); + CHECK(j.value(std::string_view("null"), Json(1)) == Json()); CHECK(j.value(std::string_view("boolean"), false) == true); CHECK(j.value(std::string_view("string"), "bar") == "hello world"); CHECK(j.value(std::string_view("string"), std::string("bar")) == "hello world"); CHECK(j.value(std::string_view("floating"), 12.34) == Approx(42.23)); CHECK(j.value(std::string_view("floating"), 12) == 42); - CHECK(j.value(std::string_view("object"), json({{"foo", "bar"}})) == json::object()); - CHECK(j.value(std::string_view("array"), json({10, 100})) == json({1, 2, 3})); + CHECK(j.value(std::string_view("object"), Json({{"foo", "bar"}})) == Json::object()); + CHECK(j.value(std::string_view("array"), Json({10, 100})) == Json({1, 2, 3})); CHECK(j_const.value(std::string_view("integer"), 2) == 1); CHECK(j_const.value(std::string_view("integer"), 1.0) == Approx(1)); @@ -223,8 +222,8 @@ TEST_CASE("element access 2") CHECK(j_const.value(std::string_view("string"), std::string("bar")) == "hello world"); CHECK(j_const.value(std::string_view("floating"), 12.34) == Approx(42.23)); CHECK(j_const.value(std::string_view("floating"), 12) == 42); - CHECK(j_const.value(std::string_view("object"), json({{"foo", "bar"}})) == json::object()); - CHECK(j_const.value(std::string_view("array"), json({10, 100})) == json({1, 2, 3})); + CHECK(j_const.value(std::string_view("object"), Json({{"foo", "bar"}})) == Json::object()); + CHECK(j_const.value(std::string_view("array"), Json({10, 100})) == Json({1, 2, 3})); #endif } @@ -235,16 +234,16 @@ TEST_CASE("element access 2") CHECK(j.value("_", false) == false); CHECK(j.value("_", "bar") == "bar"); CHECK(j.value("_", 12.34) == Approx(12.34)); - CHECK(j.value("_", json({{"foo", "bar"}})) == json({{"foo", "bar"}})); - CHECK(j.value("_", json({10, 100})) == json({10, 100})); + CHECK(j.value("_", Json({{"foo", "bar"}})) == Json({{"foo", "bar"}})); + CHECK(j.value("_", Json({10, 100})) == Json({10, 100})); CHECK(j_const.value("_", 2) == 2); CHECK(j_const.value("_", 2u) == 2u); CHECK(j_const.value("_", false) == false); CHECK(j_const.value("_", "bar") == "bar"); CHECK(j_const.value("_", 12.34) == Approx(12.34)); - CHECK(j_const.value("_", json({{"foo", "bar"}})) == json({{"foo", "bar"}})); - CHECK(j_const.value("_", json({10, 100})) == json({10, 100})); + CHECK(j_const.value("_", Json({{"foo", "bar"}})) == Json({{"foo", "bar"}})); + CHECK(j_const.value("_", Json({10, 100})) == Json({10, 100})); #ifdef JSON_HAS_CPP_17 CHECK(j.value(std::string_view("_"), 2) == 2); @@ -252,16 +251,16 @@ TEST_CASE("element access 2") CHECK(j.value(std::string_view("_"), false) == false); CHECK(j.value(std::string_view("_"), "bar") == "bar"); CHECK(j.value(std::string_view("_"), 12.34) == Approx(12.34)); - CHECK(j.value(std::string_view("_"), json({{"foo", "bar"}})) == json({{"foo", "bar"}})); - CHECK(j.value(std::string_view("_"), json({10, 100})) == json({10, 100})); + CHECK(j.value(std::string_view("_"), Json({{"foo", "bar"}})) == Json({{"foo", "bar"}})); + CHECK(j.value(std::string_view("_"), Json({10, 100})) == Json({10, 100})); CHECK(j_const.value(std::string_view("_"), 2) == 2); CHECK(j_const.value(std::string_view("_"), 2u) == 2u); CHECK(j_const.value(std::string_view("_"), false) == false); CHECK(j_const.value(std::string_view("_"), "bar") == "bar"); CHECK(j_const.value(std::string_view("_"), 12.34) == Approx(12.34)); - CHECK(j_const.value(std::string_view("_"), json({{"foo", "bar"}})) == json({{"foo", "bar"}})); - CHECK(j_const.value(std::string_view("_"), json({10, 100})) == json({10, 100})); + CHECK(j_const.value(std::string_view("_"), Json({{"foo", "bar"}})) == Json({{"foo", "bar"}})); + CHECK(j_const.value(std::string_view("_"), Json({10, 100})) == Json({10, 100})); #endif } @@ -269,92 +268,92 @@ TEST_CASE("element access 2") { SECTION("null") { - json j_nonobject(json::value_t::null); - const json j_nonobject_const(json::value_t::null); - CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with null", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with null", json::type_error&); + Json j_nonobject(Json::value_t::null); + const Json j_nonobject_const(Json::value_t::null); + CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with null", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with null", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); #endif } SECTION("boolean") { - json j_nonobject(json::value_t::boolean); - const json j_nonobject_const(json::value_t::boolean); - CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with boolean", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with boolean", json::type_error&); + Json j_nonobject(Json::value_t::boolean); + const Json j_nonobject_const(Json::value_t::boolean); + CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with boolean", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with boolean", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&); #endif } SECTION("string") { - json j_nonobject(json::value_t::string); - const json j_nonobject_const(json::value_t::string); - CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with string", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with string", json::type_error&); + Json j_nonobject(Json::value_t::string); + const Json j_nonobject_const(Json::value_t::string); + CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with string", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with string", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&); #endif } SECTION("array") { - json j_nonobject(json::value_t::array); - const json j_nonobject_const(json::value_t::array); - CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with array", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with array", json::type_error&); + Json j_nonobject(Json::value_t::array); + const Json j_nonobject_const(Json::value_t::array); + CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with array", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with array", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&); #endif } SECTION("number (integer)") { - json j_nonobject(json::value_t::number_integer); - const json j_nonobject_const(json::value_t::number_integer); - CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); + Json j_nonobject(Json::value_t::number_integer); + const Json j_nonobject_const(Json::value_t::number_integer); + CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); #endif } SECTION("number (unsigned)") { - json j_nonobject(json::value_t::number_unsigned); - const json j_nonobject_const(json::value_t::number_unsigned); - CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); + Json j_nonobject(Json::value_t::number_unsigned); + const Json j_nonobject_const(Json::value_t::number_unsigned); + CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); #endif } SECTION("number (floating-point)") { - json j_nonobject(json::value_t::number_float); - const json j_nonobject_const(json::value_t::number_float); - CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); + Json j_nonobject(Json::value_t::number_float); + const Json j_nonobject_const(Json::value_t::number_float); + CHECK_THROWS_WITH_AS(j_nonobject.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value("foo", 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value(std::string_view("foo"), 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); #endif } } @@ -368,14 +367,14 @@ TEST_CASE("element access 2") CHECK(j.value("/integer"_json_pointer, 1.0) == Approx(1)); CHECK(j.value("/unsigned"_json_pointer, 2) == 1u); CHECK(j.value("/unsigned"_json_pointer, 1.0) == Approx(1u)); - CHECK(j.value("/null"_json_pointer, json(1)) == json()); + CHECK(j.value("/null"_json_pointer, Json(1)) == Json()); CHECK(j.value("/boolean"_json_pointer, false) == true); CHECK(j.value("/string"_json_pointer, "bar") == "hello world"); CHECK(j.value("/string"_json_pointer, std::string("bar")) == "hello world"); CHECK(j.value("/floating"_json_pointer, 12.34) == Approx(42.23)); CHECK(j.value("/floating"_json_pointer, 12) == 42); - CHECK(j.value("/object"_json_pointer, json({{"foo", "bar"}})) == json::object()); - CHECK(j.value("/array"_json_pointer, json({10, 100})) == json({1, 2, 3})); + CHECK(j.value("/object"_json_pointer, Json({{"foo", "bar"}})) == Json::object()); + CHECK(j.value("/array"_json_pointer, Json({10, 100})) == Json({1, 2, 3})); CHECK(j_const.value("/integer"_json_pointer, 2) == 1); CHECK(j_const.value("/integer"_json_pointer, 1.0) == Approx(1)); @@ -386,66 +385,66 @@ TEST_CASE("element access 2") CHECK(j_const.value("/string"_json_pointer, std::string("bar")) == "hello world"); CHECK(j_const.value("/floating"_json_pointer, 12.34) == Approx(42.23)); CHECK(j_const.value("/floating"_json_pointer, 12) == 42); - CHECK(j_const.value("/object"_json_pointer, json({{"foo", "bar"}})) == json::object()); - CHECK(j_const.value("/array"_json_pointer, json({10, 100})) == json({1, 2, 3})); + CHECK(j_const.value("/object"_json_pointer, Json({{"foo", "bar"}})) == Json::object()); + CHECK(j_const.value("/array"_json_pointer, Json({10, 100})) == Json({1, 2, 3})); } SECTION("access on non-object type") { SECTION("null") { - json j_nonobject(json::value_t::null); - const json j_nonobject_const(json::value_t::null); - CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with null", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with null", json::type_error&); + Json j_nonobject(Json::value_t::null); + const Json j_nonobject_const(Json::value_t::null); + CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with null", typename Json::type_error&); } SECTION("boolean") { - json j_nonobject(json::value_t::boolean); - const json j_nonobject_const(json::value_t::boolean); - CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with boolean", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with boolean", json::type_error&); + Json j_nonobject(Json::value_t::boolean); + const Json j_nonobject_const(Json::value_t::boolean); + CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with boolean", typename Json::type_error&); } SECTION("string") { - json j_nonobject(json::value_t::string); - const json j_nonobject_const(json::value_t::string); - CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with string", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with string", json::type_error&); + Json j_nonobject(Json::value_t::string); + const Json j_nonobject_const(Json::value_t::string); + CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with string", typename Json::type_error&); } SECTION("array") { - json j_nonobject(json::value_t::array); - const json j_nonobject_const(json::value_t::array); - CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with array", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with array", json::type_error&); + Json j_nonobject(Json::value_t::array); + const Json j_nonobject_const(Json::value_t::array); + CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with array", typename Json::type_error&); } SECTION("number (integer)") { - json j_nonobject(json::value_t::number_integer); - const json j_nonobject_const(json::value_t::number_integer); - CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); + Json j_nonobject(Json::value_t::number_integer); + const Json j_nonobject_const(Json::value_t::number_integer); + CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); } SECTION("number (unsigned)") { - json j_nonobject(json::value_t::number_unsigned); - const json j_nonobject_const(json::value_t::number_unsigned); - CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); + Json j_nonobject(Json::value_t::number_unsigned); + const Json j_nonobject_const(Json::value_t::number_unsigned); + CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); } SECTION("number (floating-point)") { - json j_nonobject(json::value_t::number_float); - const json j_nonobject_const(json::value_t::number_float); - CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", json::type_error&); + Json j_nonobject(Json::value_t::number_float); + const Json j_nonobject_const(Json::value_t::number_float); + CHECK_THROWS_WITH_AS(j_nonobject.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject_const.value("/foo"_json_pointer, 1), "[json.exception.type_error.306] cannot use value() with number", typename Json::type_error&); } } } @@ -454,7 +453,7 @@ TEST_CASE("element access 2") SECTION("non-const operator[]") { { - json j_null; + Json j_null; CHECK(j_null.is_null()); j_null["key"] = 1; CHECK(j_null.is_object()); @@ -465,7 +464,7 @@ TEST_CASE("element access 2") #ifdef JSON_HAS_CPP_17 { std::string_view key = "key"; - json j_null; + Json j_null; CHECK(j_null.is_null()); j_null[key] = 1; CHECK(j_null.is_object()); @@ -478,110 +477,122 @@ TEST_CASE("element access 2") SECTION("front and back") { - // "array" is the smallest key - CHECK(j.front() == json({1, 2, 3})); - CHECK(j_const.front() == json({1, 2, 3})); - // "unsigned" is the largest key - CHECK(j.back() == json(1u)); - CHECK(j_const.back() == json(1u)); + if (std::is_same::value) + { + // "integer" is the first key + CHECK(j.front() == Json(1)); + CHECK(j_const.front() == Json(1)); + // "array" is last key + CHECK(j.back() == Json({1, 2, 3})); + CHECK(j_const.back() == Json({1, 2, 3})); + } + else + { + // "array" is the smallest key + CHECK(j.front() == Json({1, 2, 3})); + CHECK(j_const.front() == Json({1, 2, 3})); + // "unsigned" is the largest key + CHECK(j.back() == Json(1u)); + CHECK(j_const.back() == Json(1u)); + } } SECTION("access specified element") { SECTION("access within bounds") { - CHECK(j["integer"] == json(1)); - CHECK(j[json::object_t::key_type("integer")] == j["integer"]); + CHECK(j["integer"] == Json(1)); + CHECK(j[typename Json::object_t::key_type("integer")] == j["integer"]); - CHECK(j["unsigned"] == json(1u)); - CHECK(j[json::object_t::key_type("unsigned")] == j["unsigned"]); + CHECK(j["unsigned"] == Json(1u)); + CHECK(j[typename Json::object_t::key_type("unsigned")] == j["unsigned"]); - CHECK(j["boolean"] == json(true)); - CHECK(j[json::object_t::key_type("boolean")] == j["boolean"]); + CHECK(j["boolean"] == Json(true)); + CHECK(j[typename Json::object_t::key_type("boolean")] == j["boolean"]); - CHECK(j["null"] == json(nullptr)); - CHECK(j[json::object_t::key_type("null")] == j["null"]); + CHECK(j["null"] == Json(nullptr)); + CHECK(j[typename Json::object_t::key_type("null")] == j["null"]); - CHECK(j["string"] == json("hello world")); - CHECK(j[json::object_t::key_type("string")] == j["string"]); + CHECK(j["string"] == Json("hello world")); + CHECK(j[typename Json::object_t::key_type("string")] == j["string"]); - CHECK(j["floating"] == json(42.23)); - CHECK(j[json::object_t::key_type("floating")] == j["floating"]); + CHECK(j["floating"] == Json(42.23)); + CHECK(j[typename Json::object_t::key_type("floating")] == j["floating"]); - CHECK(j["object"] == json::object()); - CHECK(j[json::object_t::key_type("object")] == j["object"]); + CHECK(j["object"] == Json::object()); + CHECK(j[typename Json::object_t::key_type("object")] == j["object"]); - CHECK(j["array"] == json({1, 2, 3})); - CHECK(j[json::object_t::key_type("array")] == j["array"]); + CHECK(j["array"] == Json({1, 2, 3})); + CHECK(j[typename Json::object_t::key_type("array")] == j["array"]); - CHECK(j_const["integer"] == json(1)); - CHECK(j_const[json::object_t::key_type("integer")] == j["integer"]); + CHECK(j_const["integer"] == Json(1)); + CHECK(j_const[typename Json::object_t::key_type("integer")] == j["integer"]); - CHECK(j_const["boolean"] == json(true)); - CHECK(j_const[json::object_t::key_type("boolean")] == j["boolean"]); + CHECK(j_const["boolean"] == Json(true)); + CHECK(j_const[typename Json::object_t::key_type("boolean")] == j["boolean"]); - CHECK(j_const["null"] == json(nullptr)); - CHECK(j_const[json::object_t::key_type("null")] == j["null"]); + CHECK(j_const["null"] == Json(nullptr)); + CHECK(j_const[typename Json::object_t::key_type("null")] == j["null"]); - CHECK(j_const["string"] == json("hello world")); - CHECK(j_const[json::object_t::key_type("string")] == j["string"]); + CHECK(j_const["string"] == Json("hello world")); + CHECK(j_const[typename Json::object_t::key_type("string")] == j["string"]); - CHECK(j_const["floating"] == json(42.23)); - CHECK(j_const[json::object_t::key_type("floating")] == j["floating"]); + CHECK(j_const["floating"] == Json(42.23)); + CHECK(j_const[typename Json::object_t::key_type("floating")] == j["floating"]); - CHECK(j_const["object"] == json::object()); - CHECK(j_const[json::object_t::key_type("object")] == j["object"]); + CHECK(j_const["object"] == Json::object()); + CHECK(j_const[typename Json::object_t::key_type("object")] == j["object"]); - CHECK(j_const["array"] == json({1, 2, 3})); - CHECK(j_const[json::object_t::key_type("array")] == j["array"]); + CHECK(j_const["array"] == Json({1, 2, 3})); + CHECK(j_const[typename Json::object_t::key_type("array")] == j["array"]); } #ifdef JSON_HAS_CPP_17 SECTION("access within bounds (string_view)") { - CHECK(j["integer"] == json(1)); + CHECK(j["integer"] == Json(1)); CHECK(j[std::string_view("integer")] == j["integer"]); - CHECK(j["unsigned"] == json(1u)); + CHECK(j["unsigned"] == Json(1u)); CHECK(j[std::string_view("unsigned")] == j["unsigned"]); - CHECK(j["boolean"] == json(true)); + CHECK(j["boolean"] == Json(true)); CHECK(j[std::string_view("boolean")] == j["boolean"]); - CHECK(j["null"] == json(nullptr)); + CHECK(j["null"] == Json(nullptr)); CHECK(j[std::string_view("null")] == j["null"]); - CHECK(j["string"] == json("hello world")); + CHECK(j["string"] == Json("hello world")); CHECK(j[std::string_view("string")] == j["string"]); - CHECK(j["floating"] == json(42.23)); + CHECK(j["floating"] == Json(42.23)); CHECK(j[std::string_view("floating")] == j["floating"]); - CHECK(j["object"] == json::object()); + CHECK(j["object"] == Json::object()); CHECK(j[std::string_view("object")] == j["object"]); - CHECK(j["array"] == json({1, 2, 3})); + CHECK(j["array"] == Json({1, 2, 3})); CHECK(j[std::string_view("array")] == j["array"]); - CHECK(j_const["integer"] == json(1)); + CHECK(j_const["integer"] == Json(1)); CHECK(j_const[std::string_view("integer")] == j["integer"]); - CHECK(j_const["boolean"] == json(true)); + CHECK(j_const["boolean"] == Json(true)); CHECK(j_const[std::string_view("boolean")] == j["boolean"]); - CHECK(j_const["null"] == json(nullptr)); + CHECK(j_const["null"] == Json(nullptr)); CHECK(j_const[std::string_view("null")] == j["null"]); - CHECK(j_const["string"] == json("hello world")); + CHECK(j_const["string"] == Json("hello world")); CHECK(j_const[std::string_view("string")] == j["string"]); - CHECK(j_const["floating"] == json(42.23)); + CHECK(j_const["floating"] == Json(42.23)); CHECK(j_const[std::string_view("floating")] == j["floating"]); - CHECK(j_const["object"] == json::object()); + CHECK(j_const["object"] == Json::object()); CHECK(j_const[std::string_view("object")] == j["object"]); - CHECK(j_const["array"] == json({1, 2, 3})); + CHECK(j_const["array"] == Json({1, 2, 3})); CHECK(j_const[std::string_view("array")] == j["array"]); } #endif @@ -590,131 +601,131 @@ TEST_CASE("element access 2") { SECTION("null") { - json j_nonobject(json::value_t::null); - json j_nonobject2(json::value_t::null); - const json j_const_nonobject(j_nonobject); + Json j_nonobject(Json::value_t::null); + Json j_nonobject2(Json::value_t::null); + const Json j_const_nonobject(j_nonobject); CHECK_NOTHROW(j_nonobject["foo"]); - CHECK_NOTHROW(j_nonobject2[json::object_t::key_type("foo")]); - CHECK_THROWS_WITH_AS(j_const_nonobject["foo"], "[json.exception.type_error.305] cannot use operator[] with a string argument with null", json::type_error&); - CHECK_THROWS_WITH_AS(j_const_nonobject[json::object_t::key_type("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with null", json::type_error&); + CHECK_NOTHROW(j_nonobject2[typename Json::object_t::key_type("foo")]); + CHECK_THROWS_WITH_AS(j_const_nonobject["foo"], "[json.exception.type_error.305] cannot use operator[] with a string argument with null", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with null", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 CHECK_NOTHROW(j_nonobject2[std::string_view("foo")]); - CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with null", json::type_error&); + CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with null", typename Json::type_error&); #endif } SECTION("boolean") { - json j_nonobject(json::value_t::boolean); - const json j_const_nonobject(j_nonobject); + Json j_nonobject(Json::value_t::boolean); + const Json j_const_nonobject(j_nonobject); CHECK_THROWS_WITH_AS(j_nonobject["foo"], - "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject[json::object_t::key_type("foo")], - "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", json::type_error&); + "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")], + "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&); CHECK_THROWS_WITH_AS(j_const_nonobject["foo"], - "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", json::type_error&); - CHECK_THROWS_WITH_AS(j_const_nonobject[json::object_t::key_type("foo")], - "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", json::type_error&); + "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")], + "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", json::type_error&); - CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with boolean", typename Json::type_error&); #endif } SECTION("string") { - json j_nonobject(json::value_t::string); - const json j_const_nonobject(j_nonobject); + Json j_nonobject(Json::value_t::string); + const Json j_const_nonobject(j_nonobject); CHECK_THROWS_WITH_AS(j_nonobject["foo"], - "[json.exception.type_error.305] cannot use operator[] with a string argument with string", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject[json::object_t::key_type("foo")], - "[json.exception.type_error.305] cannot use operator[] with a string argument with string", json::type_error&); + "[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")], + "[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&); CHECK_THROWS_WITH_AS(j_const_nonobject["foo"], - "[json.exception.type_error.305] cannot use operator[] with a string argument with string", json::type_error&); - CHECK_THROWS_WITH_AS(j_const_nonobject[json::object_t::key_type("foo")], - "[json.exception.type_error.305] cannot use operator[] with a string argument with string", json::type_error&); + "[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")], + "[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with string", json::type_error&); - CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with string", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with string", typename Json::type_error&); #endif } SECTION("array") { - json j_nonobject(json::value_t::array); - const json j_const_nonobject(j_nonobject); + Json j_nonobject(Json::value_t::array); + const Json j_const_nonobject(j_nonobject); CHECK_THROWS_WITH_AS(j_nonobject["foo"], - "[json.exception.type_error.305] cannot use operator[] with a string argument with array", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject[json::object_t::key_type("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with array", json::type_error&); + "[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&); CHECK_THROWS_WITH_AS(j_const_nonobject["foo"], - "[json.exception.type_error.305] cannot use operator[] with a string argument with array", json::type_error&); - CHECK_THROWS_WITH_AS(j_const_nonobject[json::object_t::key_type("foo")], - "[json.exception.type_error.305] cannot use operator[] with a string argument with array", json::type_error&); + "[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")], + "[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with array", json::type_error&); - CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with array", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with array", typename Json::type_error&); #endif } SECTION("number (integer)") { - json j_nonobject(json::value_t::number_integer); - const json j_const_nonobject(j_nonobject); + Json j_nonobject(Json::value_t::number_integer); + const Json j_const_nonobject(j_nonobject); CHECK_THROWS_WITH_AS(j_nonobject["foo"], - "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject[json::object_t::key_type("foo")], - "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); + "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")], + "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); CHECK_THROWS_WITH_AS(j_const_nonobject["foo"], - "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_const_nonobject[json::object_t::key_type("foo")], - "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); + "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")], + "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); #endif } SECTION("number (unsigned)") { - json j_nonobject(json::value_t::number_unsigned); - const json j_const_nonobject(j_nonobject); + Json j_nonobject(Json::value_t::number_unsigned); + const Json j_const_nonobject(j_nonobject); CHECK_THROWS_WITH_AS(j_nonobject["foo"], - "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject[json::object_t::key_type("foo")], - "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); + "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")], + "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); CHECK_THROWS_WITH_AS(j_const_nonobject["foo"], - "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_const_nonobject[json::object_t::key_type("foo")], - "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); + "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")], + "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); #endif } SECTION("number (floating-point)") { - json j_nonobject(json::value_t::number_float); - const json j_const_nonobject(j_nonobject); + Json j_nonobject(Json::value_t::number_float); + const Json j_const_nonobject(j_nonobject); CHECK_THROWS_WITH_AS(j_nonobject["foo"], - "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_nonobject[json::object_t::key_type("foo")], - "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); + "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject[typename Json::object_t::key_type("foo")], + "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); CHECK_THROWS_WITH_AS(j_const_nonobject["foo"], - "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_const_nonobject[json::object_t::key_type("foo")], - "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); + "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_const_nonobject[typename Json::object_t::key_type("foo")], + "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); - CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); + CHECK_THROWS_WITH_AS(j_const_nonobject[std::string_view("foo")], "[json.exception.type_error.305] cannot use operator[] with a string argument with number", typename Json::type_error&); #endif } } @@ -815,31 +826,31 @@ TEST_CASE("element access 2") SECTION("erase(begin())") { { - json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; - json::iterator it2 = jobject.erase(jobject.begin()); - CHECK(jobject == json({{"b", 1}, {"c", 17u}})); - CHECK(*it2 == json(1)); + Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; + typename Json::iterator it2 = jobject.erase(jobject.begin()); + CHECK(jobject == Json({{"b", 1}, {"c", 17u}})); + CHECK(*it2 == Json(1)); } { - json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; - json::const_iterator it2 = jobject.erase(jobject.cbegin()); - CHECK(jobject == json({{"b", 1}, {"c", 17u}})); - CHECK(*it2 == json(1)); + Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; + typename Json::const_iterator it2 = jobject.erase(jobject.cbegin()); + CHECK(jobject == Json({{"b", 1}, {"c", 17u}})); + CHECK(*it2 == Json(1)); } } SECTION("erase(begin(), end())") { { - json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; - json::iterator it2 = jobject.erase(jobject.begin(), jobject.end()); - CHECK(jobject == json::object()); + Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; + typename Json::iterator it2 = jobject.erase(jobject.begin(), jobject.end()); + CHECK(jobject == Json::object()); CHECK(it2 == jobject.end()); } { - json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; - json::const_iterator it2 = jobject.erase(jobject.cbegin(), jobject.cend()); - CHECK(jobject == json::object()); + Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; + typename Json::const_iterator it2 = jobject.erase(jobject.cbegin(), jobject.cend()); + CHECK(jobject == Json::object()); CHECK(it2 == jobject.cend()); } } @@ -847,78 +858,78 @@ TEST_CASE("element access 2") SECTION("erase(begin(), begin())") { { - json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; - json::iterator it2 = jobject.erase(jobject.begin(), jobject.begin()); - CHECK(jobject == json({{"a", "a"}, {"b", 1}, {"c", 17u}})); - CHECK(*it2 == json("a")); + Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; + typename Json::iterator it2 = jobject.erase(jobject.begin(), jobject.begin()); + CHECK(jobject == Json({{"a", "a"}, {"b", 1}, {"c", 17u}})); + CHECK(*it2 == Json("a")); } { - json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; - json::const_iterator it2 = jobject.erase(jobject.cbegin(), jobject.cbegin()); - CHECK(jobject == json({{"a", "a"}, {"b", 1}, {"c", 17u}})); - CHECK(*it2 == json("a")); + Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; + typename Json::const_iterator it2 = jobject.erase(jobject.cbegin(), jobject.cbegin()); + CHECK(jobject == Json({{"a", "a"}, {"b", 1}, {"c", 17u}})); + CHECK(*it2 == Json("a")); } } SECTION("erase at offset") { { - json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; - json::iterator it = jobject.find("b"); - json::iterator it2 = jobject.erase(it); - CHECK(jobject == json({{"a", "a"}, {"c", 17u}})); - CHECK(*it2 == json(17)); + Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; + typename Json::iterator it = jobject.find("b"); + typename Json::iterator it2 = jobject.erase(it); + CHECK(jobject == Json({{"a", "a"}, {"c", 17u}})); + CHECK(*it2 == Json(17)); } { - json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; - json::const_iterator it = jobject.find("b"); - json::const_iterator it2 = jobject.erase(it); - CHECK(jobject == json({{"a", "a"}, {"c", 17u}})); - CHECK(*it2 == json(17)); + Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}}; + typename Json::const_iterator it = jobject.find("b"); + typename Json::const_iterator it2 = jobject.erase(it); + CHECK(jobject == Json({{"a", "a"}, {"c", 17u}})); + CHECK(*it2 == Json(17)); } } SECTION("erase subrange") { { - json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; - json::iterator it2 = jobject.erase(jobject.find("b"), jobject.find("e")); - CHECK(jobject == json({{"a", "a"}, {"e", true}})); - CHECK(*it2 == json(true)); + Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; + typename Json::iterator it2 = jobject.erase(jobject.find("b"), jobject.find("e")); + CHECK(jobject == Json({{"a", "a"}, {"e", true}})); + CHECK(*it2 == Json(true)); } { - json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; - json::const_iterator it2 = jobject.erase(jobject.find("b"), jobject.find("e")); - CHECK(jobject == json({{"a", "a"}, {"e", true}})); - CHECK(*it2 == json(true)); + Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; + typename Json::const_iterator it2 = jobject.erase(jobject.find("b"), jobject.find("e")); + CHECK(jobject == Json({{"a", "a"}, {"e", true}})); + CHECK(*it2 == Json(true)); } } SECTION("different objects") { { - json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; - json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}}; + Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; + Json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}}; CHECK_THROWS_WITH_AS(jobject.erase(jobject2.begin()), - "[json.exception.invalid_iterator.202] iterator does not fit current value", json::invalid_iterator&); + "[json.exception.invalid_iterator.202] iterator does not fit current value", typename Json::invalid_iterator&); CHECK_THROWS_WITH_AS(jobject.erase(jobject.begin(), jobject2.end()), - "[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&); + "[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&); CHECK_THROWS_WITH_AS(jobject.erase(jobject2.begin(), jobject.end()), - "[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&); + "[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&); CHECK_THROWS_WITH_AS(jobject.erase(jobject2.begin(), jobject2.end()), - "[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&); + "[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&); } { - json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; - json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}}; + Json jobject = {{"a", "a"}, {"b", 1}, {"c", 17u}, {"d", false}, {"e", true}}; + Json jobject2 = {{"a", "a"}, {"b", 1}, {"c", 17u}}; CHECK_THROWS_WITH_AS(jobject.erase(jobject2.cbegin()), - "[json.exception.invalid_iterator.202] iterator does not fit current value", json::invalid_iterator&); + "[json.exception.invalid_iterator.202] iterator does not fit current value", typename Json::invalid_iterator&); CHECK_THROWS_WITH_AS(jobject.erase(jobject.cbegin(), jobject2.cend()), - "[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&); + "[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&); CHECK_THROWS_WITH_AS(jobject.erase(jobject2.cbegin(), jobject.cend()), - "[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&); + "[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&); CHECK_THROWS_WITH_AS(jobject.erase(jobject2.cbegin(), jobject2.cend()), - "[json.exception.invalid_iterator.203] iterators do not fit current value", json::invalid_iterator&); + "[json.exception.invalid_iterator.203] iterators do not fit current value", typename Json::invalid_iterator&); } } } @@ -927,61 +938,61 @@ TEST_CASE("element access 2") { SECTION("null") { - json j_nonobject(json::value_t::null); - CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with null", json::type_error&); + Json j_nonobject(Json::value_t::null); + CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with null", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with null", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with null", typename Json::type_error&); #endif } SECTION("boolean") { - json j_nonobject(json::value_t::boolean); - CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with boolean", json::type_error&); + Json j_nonobject(Json::value_t::boolean); + CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with boolean", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with boolean", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with boolean", typename Json::type_error&); #endif } SECTION("string") { - json j_nonobject(json::value_t::string); - CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with string", json::type_error&); + Json j_nonobject(Json::value_t::string); + CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with string", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with string", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with string", typename Json::type_error&); #endif } SECTION("array") { - json j_nonobject(json::value_t::array); - CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with array", json::type_error&); + Json j_nonobject(Json::value_t::array); + CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with array", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with array", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with array", typename Json::type_error&); #endif } SECTION("number (integer)") { - json j_nonobject(json::value_t::number_integer); - CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with number", json::type_error&); + Json j_nonobject(Json::value_t::number_integer); + CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with number", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with number", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with number", typename Json::type_error&); #endif } SECTION("number (floating-point)") { - json j_nonobject(json::value_t::number_float); - CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with number", json::type_error&); + Json j_nonobject(Json::value_t::number_float); + CHECK_THROWS_WITH_AS(j_nonobject.erase("foo"), "[json.exception.type_error.307] cannot use erase() with number", typename Json::type_error&); #ifdef JSON_HAS_CPP_17 - CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with number", json::type_error&); + CHECK_THROWS_WITH_AS(j_nonobject.erase(std::string_view("foo")), "[json.exception.type_error.307] cannot use erase() with number", typename Json::type_error&); #endif } } @@ -1028,8 +1039,8 @@ TEST_CASE("element access 2") { SECTION("null") { - json j_nonarray(json::value_t::null); - const json j_nonarray_const(j_nonarray); + Json j_nonarray(Json::value_t::null); + const Json j_nonarray_const(j_nonarray); CHECK(j_nonarray.find("foo") == j_nonarray.end()); CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end()); @@ -1042,8 +1053,8 @@ TEST_CASE("element access 2") SECTION("string") { - json j_nonarray(json::value_t::string); - const json j_nonarray_const(j_nonarray); + Json j_nonarray(Json::value_t::string); + const Json j_nonarray_const(j_nonarray); CHECK(j_nonarray.find("foo") == j_nonarray.end()); CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end()); @@ -1056,8 +1067,8 @@ TEST_CASE("element access 2") SECTION("object") { - json j_nonarray(json::value_t::object); - const json j_nonarray_const(j_nonarray); + Json j_nonarray(Json::value_t::object); + const Json j_nonarray_const(j_nonarray); CHECK(j_nonarray.find("foo") == j_nonarray.end()); CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end()); @@ -1070,8 +1081,8 @@ TEST_CASE("element access 2") SECTION("array") { - json j_nonarray(json::value_t::array); - const json j_nonarray_const(j_nonarray); + Json j_nonarray(Json::value_t::array); + const Json j_nonarray_const(j_nonarray); CHECK(j_nonarray.find("foo") == j_nonarray.end()); CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end()); @@ -1084,8 +1095,8 @@ TEST_CASE("element access 2") SECTION("boolean") { - json j_nonarray(json::value_t::boolean); - const json j_nonarray_const(j_nonarray); + Json j_nonarray(Json::value_t::boolean); + const Json j_nonarray_const(j_nonarray); CHECK(j_nonarray.find("foo") == j_nonarray.end()); CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end()); @@ -1098,8 +1109,8 @@ TEST_CASE("element access 2") SECTION("number (integer)") { - json j_nonarray(json::value_t::number_integer); - const json j_nonarray_const(j_nonarray); + Json j_nonarray(Json::value_t::number_integer); + const Json j_nonarray_const(j_nonarray); CHECK(j_nonarray.find("foo") == j_nonarray.end()); CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end()); @@ -1112,8 +1123,8 @@ TEST_CASE("element access 2") SECTION("number (unsigned)") { - json j_nonarray(json::value_t::number_unsigned); - const json j_nonarray_const(j_nonarray); + Json j_nonarray(Json::value_t::number_unsigned); + const Json j_nonarray_const(j_nonarray); CHECK(j_nonarray.find("foo") == j_nonarray.end()); CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end()); @@ -1126,8 +1137,8 @@ TEST_CASE("element access 2") SECTION("number (floating-point)") { - json j_nonarray(json::value_t::number_float); - const json j_nonarray_const(j_nonarray); + Json j_nonarray(Json::value_t::number_float); + const Json j_nonarray_const(j_nonarray); CHECK(j_nonarray.find("foo") == j_nonarray.end()); CHECK(j_nonarray_const.find("foo") == j_nonarray_const.end()); @@ -1177,8 +1188,8 @@ TEST_CASE("element access 2") { SECTION("null") { - json j_nonobject(json::value_t::null); - const json j_nonobject_const(json::value_t::null); + Json j_nonobject(Json::value_t::null); + const Json j_nonobject_const(Json::value_t::null); CHECK(j_nonobject.count("foo") == 0); CHECK(j_nonobject_const.count("foo") == 0); @@ -1191,8 +1202,8 @@ TEST_CASE("element access 2") SECTION("string") { - json j_nonobject(json::value_t::string); - const json j_nonobject_const(json::value_t::string); + Json j_nonobject(Json::value_t::string); + const Json j_nonobject_const(Json::value_t::string); CHECK(j_nonobject.count("foo") == 0); CHECK(j_nonobject_const.count("foo") == 0); @@ -1205,8 +1216,8 @@ TEST_CASE("element access 2") SECTION("object") { - json j_nonobject(json::value_t::object); - const json j_nonobject_const(json::value_t::object); + Json j_nonobject(Json::value_t::object); + const Json j_nonobject_const(Json::value_t::object); CHECK(j_nonobject.count("foo") == 0); CHECK(j_nonobject_const.count("foo") == 0); @@ -1219,8 +1230,8 @@ TEST_CASE("element access 2") SECTION("array") { - json j_nonobject(json::value_t::array); - const json j_nonobject_const(json::value_t::array); + Json j_nonobject(Json::value_t::array); + const Json j_nonobject_const(Json::value_t::array); CHECK(j_nonobject.count("foo") == 0); CHECK(j_nonobject_const.count("foo") == 0); @@ -1233,8 +1244,8 @@ TEST_CASE("element access 2") SECTION("boolean") { - json j_nonobject(json::value_t::boolean); - const json j_nonobject_const(json::value_t::boolean); + Json j_nonobject(Json::value_t::boolean); + const Json j_nonobject_const(Json::value_t::boolean); CHECK(j_nonobject.count("foo") == 0); CHECK(j_nonobject_const.count("foo") == 0); @@ -1247,8 +1258,8 @@ TEST_CASE("element access 2") SECTION("number (integer)") { - json j_nonobject(json::value_t::number_integer); - const json j_nonobject_const(json::value_t::number_integer); + Json j_nonobject(Json::value_t::number_integer); + const Json j_nonobject_const(Json::value_t::number_integer); CHECK(j_nonobject.count("foo") == 0); CHECK(j_nonobject_const.count("foo") == 0); @@ -1261,8 +1272,8 @@ TEST_CASE("element access 2") SECTION("number (unsigned)") { - json j_nonobject(json::value_t::number_unsigned); - const json j_nonobject_const(json::value_t::number_unsigned); + Json j_nonobject(Json::value_t::number_unsigned); + const Json j_nonobject_const(Json::value_t::number_unsigned); CHECK(j_nonobject.count("foo") == 0); CHECK(j_nonobject_const.count("foo") == 0); @@ -1275,8 +1286,8 @@ TEST_CASE("element access 2") SECTION("number (floating-point)") { - json j_nonobject(json::value_t::number_float); - const json j_nonobject_const(json::value_t::number_float); + Json j_nonobject(Json::value_t::number_float); + const Json j_nonobject_const(Json::value_t::number_float); CHECK(j_nonobject.count("foo") == 0); CHECK(j_nonobject_const.count("foo") == 0); @@ -1327,8 +1338,8 @@ TEST_CASE("element access 2") { SECTION("null") { - json j_nonobject(json::value_t::null); - const json j_nonobject_const(json::value_t::null); + Json j_nonobject(Json::value_t::null); + const Json j_nonobject_const(Json::value_t::null); CHECK(j_nonobject.contains("foo") == false); CHECK(j_nonobject_const.contains("foo") == false); @@ -1341,8 +1352,8 @@ TEST_CASE("element access 2") SECTION("string") { - json j_nonobject(json::value_t::string); - const json j_nonobject_const(json::value_t::string); + Json j_nonobject(Json::value_t::string); + const Json j_nonobject_const(Json::value_t::string); CHECK(j_nonobject.contains("foo") == false); CHECK(j_nonobject_const.contains("foo") == false); @@ -1355,8 +1366,8 @@ TEST_CASE("element access 2") SECTION("object") { - json j_nonobject(json::value_t::object); - const json j_nonobject_const(json::value_t::object); + Json j_nonobject(Json::value_t::object); + const Json j_nonobject_const(Json::value_t::object); CHECK(j_nonobject.contains("foo") == false); CHECK(j_nonobject_const.contains("foo") == false); @@ -1369,8 +1380,8 @@ TEST_CASE("element access 2") SECTION("array") { - json j_nonobject(json::value_t::array); - const json j_nonobject_const(json::value_t::array); + Json j_nonobject(Json::value_t::array); + const Json j_nonobject_const(Json::value_t::array); CHECK(j_nonobject.contains("foo") == false); CHECK(j_nonobject_const.contains("foo") == false); @@ -1383,8 +1394,8 @@ TEST_CASE("element access 2") SECTION("boolean") { - json j_nonobject(json::value_t::boolean); - const json j_nonobject_const(json::value_t::boolean); + Json j_nonobject(Json::value_t::boolean); + const Json j_nonobject_const(Json::value_t::boolean); CHECK(j_nonobject.contains("foo") == false); CHECK(j_nonobject_const.contains("foo") == false); @@ -1397,8 +1408,8 @@ TEST_CASE("element access 2") SECTION("number (integer)") { - json j_nonobject(json::value_t::number_integer); - const json j_nonobject_const(json::value_t::number_integer); + Json j_nonobject(Json::value_t::number_integer); + const Json j_nonobject_const(Json::value_t::number_integer); CHECK(j_nonobject.contains("foo") == false); CHECK(j_nonobject_const.contains("foo") == false); @@ -1411,8 +1422,8 @@ TEST_CASE("element access 2") SECTION("number (unsigned)") { - json j_nonobject(json::value_t::number_unsigned); - const json j_nonobject_const(json::value_t::number_unsigned); + Json j_nonobject(Json::value_t::number_unsigned); + const Json j_nonobject_const(Json::value_t::number_unsigned); CHECK(j_nonobject.contains("foo") == false); CHECK(j_nonobject_const.contains("foo") == false); @@ -1425,8 +1436,8 @@ TEST_CASE("element access 2") SECTION("number (floating-point)") { - json j_nonobject(json::value_t::number_float); - const json j_nonobject_const(json::value_t::number_float); + Json j_nonobject(Json::value_t::number_float); + const Json j_nonobject_const(Json::value_t::number_float); CHECK(j_nonobject.contains("foo") == false); CHECK(j_nonobject_const.contains("foo") == false); #ifdef JSON_HAS_CPP_17 @@ -1440,12 +1451,12 @@ TEST_CASE("element access 2") } #if !defined(JSON_NOEXCEPTION) -TEST_CASE("element access 2 (throwing tests)") +TEST_CASE_TEMPLATE("element access 2 (throwing tests)", Json, nlohmann::json, nlohmann::ordered_json) { SECTION("object") { - json j = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", json::object()}, {"array", {1, 2, 3}}}; - const json j_const = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", json::object()}, {"array", {1, 2, 3}}}; + Json j = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", Json::object()}, {"array", {1, 2, 3}}}; + const Json j_const = {{"integer", 1}, {"unsigned", 1u}, {"floating", 42.23}, {"null", nullptr}, {"string", "hello world"}, {"boolean", true}, {"object", Json::object()}, {"array", {1, 2, 3}}}; SECTION("access specified element with default value") { @@ -1458,16 +1469,16 @@ TEST_CASE("element access 2 (throwing tests)") CHECK(j.value("/not/existing"_json_pointer, false) == false); CHECK(j.value("/not/existing"_json_pointer, "bar") == "bar"); CHECK(j.value("/not/existing"_json_pointer, 12.34) == Approx(12.34)); - CHECK(j.value("/not/existing"_json_pointer, json({{"foo", "bar"}})) == json({{"foo", "bar"}})); - CHECK(j.value("/not/existing"_json_pointer, json({10, 100})) == json({10, 100})); + CHECK(j.value("/not/existing"_json_pointer, Json({{"foo", "bar"}})) == Json({{"foo", "bar"}})); + CHECK(j.value("/not/existing"_json_pointer, Json({10, 100})) == Json({10, 100})); CHECK(j_const.value("/not/existing"_json_pointer, 2) == 2); CHECK(j_const.value("/not/existing"_json_pointer, 2u) == 2u); CHECK(j_const.value("/not/existing"_json_pointer, false) == false); CHECK(j_const.value("/not/existing"_json_pointer, "bar") == "bar"); CHECK(j_const.value("/not/existing"_json_pointer, 12.34) == Approx(12.34)); - CHECK(j_const.value("/not/existing"_json_pointer, json({{"foo", "bar"}})) == json({{"foo", "bar"}})); - CHECK(j_const.value("/not/existing"_json_pointer, json({10, 100})) == json({10, 100})); + CHECK(j_const.value("/not/existing"_json_pointer, Json({{"foo", "bar"}})) == Json({{"foo", "bar"}})); + CHECK(j_const.value("/not/existing"_json_pointer, Json({10, 100})) == Json({10, 100})); } } } diff --git a/tests/src/unit-items.cpp b/tests/src/unit-items.cpp index fa65b398a..a7b1385d0 100644 --- a/tests/src/unit-items.cpp +++ b/tests/src/unit-items.cpp @@ -13,7 +13,9 @@ using nlohmann::json; // This test suite uses range for loops where values are copied. This is inefficient in usual code, but required to achieve 100% coverage. DOCTEST_GCC_SUPPRESS_WARNING_PUSH -DOCTEST_GCC_SUPPRESS_WARNING("-Wrange-loop-construct") +#if DOCTEST_GCC >= DOCTEST_COMPILER(11, 0, 0) + DOCTEST_GCC_SUPPRESS_WARNING("-Wrange-loop-construct") +#endif DOCTEST_CLANG_SUPPRESS_WARNING_PUSH DOCTEST_CLANG_SUPPRESS_WARNING("-Wrange-loop-construct") diff --git a/tests/src/unit-iterators2.cpp b/tests/src/unit-iterators2.cpp index 9692a2b88..16ce67927 100644 --- a/tests/src/unit-iterators2.cpp +++ b/tests/src/unit-iterators2.cpp @@ -895,7 +895,7 @@ TEST_CASE("iterators 2") } // libstdc++ algorithms don't work with Clang 15 (04/2022) -#if !defined(__clang__) || (defined(__clang__) && defined(__GLIBCXX__)) +#if !DOCTEST_CLANG || (DOCTEST_CLANG && defined(__GLIBCXX__)) SECTION("algorithms") { SECTION("copy") @@ -934,7 +934,7 @@ TEST_CASE("iterators 2") // libstdc++ views don't work with Clang 15 (04/2022) // libc++ hides limited ranges implementation behind guard macro -#if !(defined(__clang__) && (defined(__GLIBCXX__) || defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES))) +#if !(DOCTEST_CLANG && (defined(__GLIBCXX__) || defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES))) SECTION("views") { SECTION("reverse") diff --git a/tests/src/unit-regression1.cpp b/tests/src/unit-regression1.cpp index 641231d35..1e2a5ff1c 100644 --- a/tests/src/unit-regression1.cpp +++ b/tests/src/unit-regression1.cpp @@ -1499,7 +1499,7 @@ TEST_CASE("regression tests, exceptions dependent") ///////////////////////////////////////////////////////////////////// // the code below fails with Clang on Windows, so we need to exclude it there -#if defined(__clang__) && (defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)) +#if DOCTEST_CLANG && (defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)) #else template class array {}; template class object {}; diff --git a/tests/src/unit-regression2.cpp b/tests/src/unit-regression2.cpp index 8b7575ef5..63df1a63b 100644 --- a/tests/src/unit-regression2.cpp +++ b/tests/src/unit-regression2.cpp @@ -782,7 +782,7 @@ TEST_CASE("regression tests 2") const auto j_path = j.get(); CHECK(j_path == text_path); -#if defined(__clang__) || ((defined(__GNUC__) && !defined(__INTEL_COMPILER)) && (__GNUC__ > 8 || (__GNUC__ == 8 && __GNUC_MINOR__ >= 4))) +#if DOCTEST_CLANG || DOCTEST_GCC >= DOCTEST_COMPILER(8, 4, 0) // only known to work on Clang and GCC >=8.4 CHECK_THROWS_WITH_AS(nlohmann::detail::std_fs::path(json(1)), "[json.exception.type_error.302] type must be string, but is number", json::type_error); #endif