diff --git a/.clang-tidy b/.clang-tidy index 29b3e9302..7132199dd 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,9 +1,15 @@ -# TODO: The first three checks are only removed to get the CI going. They have to be addressed at some point. -# TODO: portability-avoid-pragma-once: should be fixed eventually +# bugprone-use-after-move (hicpp-invalid-access-moved is its alias) still flags +# the basic_json move constructor, which forwards the whole object to its base +# class (#5724), and two forwards in the error-message construction of +# at(KeyType&&) (json.hpp, both overloads: find(std::forward(key)) +# followed by string_t(std::forward(key)) in the throw), which #5689 +# rewrites. Re-enable both checks once those changes have landed. +# portability-avoid-pragma-once: kept disabled on purpose. #pragma once is accepted +# by every supported compiler, and tools/amalgamate/amalgamate.py strips it from +# single_include, so there is nothing left to fix here. Checks: '*, - -portability-template-virtual-member-function, -bugprone-use-after-move, -hicpp-invalid-access-moved, @@ -37,7 +43,6 @@ Checks: '*, -google-readability-function-size, -google-runtime-float, -google-runtime-int, - -google-runtime-references, -hicpp-avoid-goto, -hicpp-explicit-conversions, -hicpp-function-size, @@ -71,6 +76,7 @@ Checks: '*, -readability-magic-numbers, -readability-redundant-access-specifiers, -readability-redundant-parentheses, + -readability-redundant-typename, -readability-simplify-boolean-expr, -readability-uppercase-literal-suffix, -readability-use-concise-preprocessor-directives' @@ -81,5 +87,4 @@ CheckOptions: WarningsAsErrors: '*' -#HeaderFilterRegex: '.*nlohmann.*' HeaderFilterRegex: '.*hpp$' diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 485fb3b6d..4612dcaa6 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -85,7 +85,7 @@ jobs: ci_static_analysis_clang: runs-on: ubuntu-latest - container: silkeh/clang:dev + container: silkeh/clang:22 strategy: matrix: target: [ci_test_clang, ci_clang_tidy, ci_test_clang_sanitizer, ci_clang_analyze, ci_single_binaries] diff --git a/cmake/ci.cmake b/cmake/ci.cmake index c0ed77f6c..353975b8e 100644 --- a/cmake/ci.cmake +++ b/cmake/ci.cmake @@ -8,24 +8,24 @@ set(N 10) include(FindPython3) find_package(Python3 COMPONENTS Interpreter) -find_program(CLANG_TOOL NAMES clang++-HEAD clang++ clang++-20 clang++-19 clang++-18 clang++-17 clang++-16 clang++-15 clang++-14 clang++-13 clang++-12 clang++-11 clang++) +find_program(CLANG_TOOL NAMES clang++-HEAD clang++ clang++-22 clang++-21 clang++-20 clang++-19 clang++-18 clang++-17 clang++-16 clang++-15 clang++-14 clang++-13 clang++-12 clang++-11 clang++) execute_process(COMMAND ${CLANG_TOOL} --version OUTPUT_VARIABLE CLANG_TOOL_VERSION ERROR_VARIABLE CLANG_TOOL_VERSION) string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TOOL_VERSION "${CLANG_TOOL_VERSION}") message(STATUS "🔖 Clang ${CLANG_TOOL_VERSION} (${CLANG_TOOL})") -find_program(CLANG_TIDY_TOOL NAMES clang-tidy-20 clang-tidy-19 clang-tidy-18 clang-tidy-17 clang-tidy-16 clang-tidy-15 clang-tidy-14 clang-tidy-13 clang-tidy-12 clang-tidy-11 clang-tidy) +find_program(CLANG_TIDY_TOOL NAMES clang-tidy-22 clang-tidy-21 clang-tidy-20 clang-tidy-19 clang-tidy-18 clang-tidy-17 clang-tidy-16 clang-tidy-15 clang-tidy-14 clang-tidy-13 clang-tidy-12 clang-tidy-11 clang-tidy) execute_process(COMMAND ${CLANG_TIDY_TOOL} --version OUTPUT_VARIABLE CLANG_TIDY_TOOL_VERSION ERROR_VARIABLE CLANG_TIDY_TOOL_VERSION) string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" CLANG_TIDY_TOOL_VERSION "${CLANG_TIDY_TOOL_VERSION}") message(STATUS "🔖 Clang-Tidy ${CLANG_TIDY_TOOL_VERSION} (${CLANG_TIDY_TOOL})") message(STATUS "🔖 CMake ${CMAKE_VERSION} (${CMAKE_COMMAND})") -find_program(GCC_TOOL NAMES g++-latest g++-HEAD g++ g++-15 g++-14 g++-13 g++-12 g++-11 g++-10) +find_program(GCC_TOOL NAMES g++-latest g++-HEAD g++ g++-16 g++-15 g++-14 g++-13 g++-12 g++-11 g++-10) execute_process(COMMAND ${GCC_TOOL} --version OUTPUT_VARIABLE GCC_TOOL_VERSION ERROR_VARIABLE GCC_TOOL_VERSION) string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" GCC_TOOL_VERSION "${GCC_TOOL_VERSION}") message(STATUS "🔖 GCC ${GCC_TOOL_VERSION} (${GCC_TOOL})") -find_program(GCOV_TOOL NAMES gcov-HEAD gcov gcov-15 gcov-14 gcov-13 gcov-12 gcov-11 gcov-10) +find_program(GCOV_TOOL NAMES gcov-HEAD gcov gcov-16 gcov-15 gcov-14 gcov-13 gcov-12 gcov-11 gcov-10) execute_process(COMMAND ${GCOV_TOOL} --version OUTPUT_VARIABLE GCOV_TOOL_VERSION ERROR_VARIABLE GCOV_TOOL_VERSION) string(REGEX MATCH "[0-9]+(\\.[0-9]+)+" GCOV_TOOL_VERSION "${GCOV_TOOL_VERSION}") message(STATUS "🔖 GCOV ${GCOV_TOOL_VERSION} (${GCOV_TOOL})") diff --git a/cmake/clang_flags.cmake b/cmake/clang_flags.cmake index 0619545ec..ef320fadb 100644 --- a/cmake/clang_flags.cmake +++ b/cmake/clang_flags.cmake @@ -2,7 +2,6 @@ # -Wno-c++98-compat The library targets C++11. # -Wno-c++98-compat-pedantic The library targets C++11. # -Wno-deprecated-declarations The library contains annotations for deprecated functions. -# -Wno-extra-semi-stmt The library uses assert which triggers this warning. # -Wno-padded We do not care about padding warnings. # -Wno-covered-switch-default All switches list all cases and a default case. # -Wno-c2y-extensions Clang 22.1 diagnoses __COUNTER__ as a C2y extension, also in @@ -20,7 +19,6 @@ set(CLANG_CXXFLAGS -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-deprecated-declarations - -Wno-extra-semi-stmt -Wno-padded -Wno-covered-switch-default -Wno-c2y-extensions diff --git a/cmake/gcc_flags.cmake b/cmake/gcc_flags.cmake index 34c168cee..0a3272c7a 100644 --- a/cmake/gcc_flags.cmake +++ b/cmake/gcc_flags.cmake @@ -1,4 +1,4 @@ -# Warning flags determined for GCC 15.1.0 with https://github.com/nlohmann/gcc_flags: +# Warning flags determined for GCC 16.2.0 with https://github.com/nlohmann/gcc_flags: # Ignored GCC warnings: # -Wno-abi-tag We do not care about ABI tags. # -Wno-aggregate-return The library uses aggregate returns. @@ -16,6 +16,8 @@ set(GCC_CXXFLAGS --extra-warnings -W -WNSObject-attribute + -Wabbreviated-auto-in-template-arg + -Wabi -Wno-abi-tag -Waddress -Waddress-of-packed-member @@ -64,6 +66,7 @@ set(GCC_CXXFLAGS -Wanalyzer-tainted-divisor -Wanalyzer-tainted-offset -Wanalyzer-tainted-size + -Wanalyzer-throw-of-unexpected-type -Wanalyzer-too-complex -Wanalyzer-undefined-behavior-ptrdiff -Wanalyzer-undefined-behavior-strtok @@ -80,10 +83,13 @@ set(GCC_CXXFLAGS -Warith-conversion -Warray-bounds=2 -Warray-compare + -Warray-parameter -Warray-parameter=2 -Wattribute-alias=2 -Wattribute-warning -Wattributes + -Wauto-profile + -Wbidi-chars=any -Wbool-compare -Wbool-operation -Wbuiltin-declaration-mismatch @@ -99,6 +105,7 @@ set(GCC_CXXFLAGS -Wc++20-compat -Wc++20-extensions -Wc++23-extensions + -Wc++26-compat -Wc++26-extensions -Wc++2a-compat -Wcalloc-transposed-args @@ -142,6 +149,7 @@ set(GCC_CXXFLAGS -Wdeprecated-enum-enum-conversion -Wdeprecated-enum-float-conversion -Wdeprecated-literal-operator + -Wdeprecated-openmp -Wdeprecated-variadic-comma-omission -Wdisabled-optimization -Wdiv-by-zero @@ -156,21 +164,18 @@ set(GCC_CXXFLAGS -Wenum-conversion -Wexceptions -Wexpansion-to-defined + -Wexperimental-fmv-target + -Wexpose-global-module-tu-local + -Wexternal-tu-local -Wextra -Wextra-semi -Wflex-array-member-not-at-end -Wfloat-conversion -Wfloat-equal - -Wformat -Wformat-contains-nul - -Wformat -Wformat-diag - -Wformat -Wformat-extra-args - -Wformat -Wformat-nonliteral - -Wformat -Wformat-overflow=2 - -Wformat -Wformat-security - -Wformat -Wformat-signedness - -Wformat -Wformat-truncation=2 - -Wformat -Wformat-y2k - -Wformat -Wformat-zero-length + -Wformat-diag + -Wformat-overflow=2 + -Wformat-signedness + -Wformat-truncation=2 -Wformat=2 -Wframe-address -Wfree-nonheap-object @@ -197,6 +202,8 @@ set(GCC_CXXFLAGS -Winvalid-offsetof -Winvalid-pch -Winvalid-utf8 + -Wkeyword-macro + -Wleading-whitespace=spaces -Wliteral-suffix -Wlogical-not-parentheses -Wlogical-op @@ -227,6 +234,7 @@ set(GCC_CXXFLAGS -Wnarrowing -Wnoexcept -Wnoexcept-type + -Wnon-c-typedef-for-linkage -Wnon-template-friend -Wnon-virtual-dtor -Wnonnull @@ -269,6 +277,8 @@ set(GCC_CXXFLAGS -Wscalar-storage-order -Wself-move -Wsequence-point + -Wsfinae-incomplete + -Wsfinae-incomplete=2 -Wshadow=compatible-local -Wshadow=global -Wshadow=local @@ -289,6 +299,7 @@ set(GCC_CXXFLAGS -Wstrict-aliasing=3 -Wstrict-null-sentinel -Wstrict-overflow + -Wstrict-overflow=5 -Wstring-compare -Wstringop-overflow -Wstringop-overflow=4 @@ -333,8 +344,8 @@ set(GCC_CXXFLAGS -Wunreachable-code -Wunsafe-loop-optimizations -Wunused - -Wunused-but-set-parameter - -Wunused-but-set-variable + -Wunused-but-set-parameter=3 + -Wunused-but-set-variable=3 -Wunused-const-variable=2 -Wunused-function -Wunused-label diff --git a/include/nlohmann/detail/conversions/from_json.hpp b/include/nlohmann/detail/conversions/from_json.hpp index c68f51f69..d5c3328ca 100644 --- a/include/nlohmann/detail/conversions/from_json.hpp +++ b/include/nlohmann/detail/conversions/from_json.hpp @@ -354,22 +354,22 @@ void()) } template < typename BasicJsonType, typename T, std::size_t... Idx > -std::array from_json_inplace_array_impl(BasicJsonType&& j, +std::array from_json_inplace_array_impl(const BasicJsonType& j, identity_tag> /*unused*/, index_sequence /*unused*/) { - return { { std::forward(j).at(Idx).template get()... } }; + return { { j.at(Idx).template get()... } }; } template < typename BasicJsonType, typename T, std::size_t N > -auto from_json(BasicJsonType&& j, identity_tag> tag) --> decltype(from_json_inplace_array_impl(std::forward(j), tag, make_index_sequence {})) +auto from_json(const BasicJsonType& j, identity_tag> tag) +-> decltype(from_json_inplace_array_impl(j, tag, make_index_sequence {})) { if (JSON_HEDLEY_UNLIKELY(!j.is_array())) { JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); } - return from_json_inplace_array_impl(std::forward(j), tag, make_index_sequence {}); + return from_json_inplace_array_impl(j, tag, make_index_sequence {}); } template @@ -504,54 +504,54 @@ template using tuple_type = std::tuple < decltype(from_json_tuple_get_impl(std::declval(), detail::identity_tag {}, detail::priority_tag {}))... >; template -tuple_type from_json_tuple_impl_base(BasicJsonType&& j, index_sequence /*unused*/) +tuple_type from_json_tuple_impl_base(const BasicJsonType& j, index_sequence /*unused*/) { - return tuple_type(from_json_tuple_get_impl(std::forward(j).at(Idx), detail::identity_tag {}, detail::priority_tag {})...); + return tuple_type(from_json_tuple_get_impl(j.at(Idx), detail::identity_tag {}, detail::priority_tag {})...); } template -std::tuple<> from_json_tuple_impl_base(BasicJsonType& /*unused*/, index_sequence<> /*unused*/) +std::tuple<> from_json_tuple_impl_base(const BasicJsonType& /*unused*/, index_sequence<> /*unused*/) { return {}; } template < typename BasicJsonType, class A1, class A2 > -std::pair from_json_tuple_impl(BasicJsonType&& j, identity_tag> /*unused*/, priority_tag<0> /*unused*/) +std::pair from_json_tuple_impl(const BasicJsonType& j, identity_tag> /*unused*/, priority_tag<0> /*unused*/) { - return {std::forward(j).at(0).template get(), - std::forward(j).at(1).template get()}; + return {j.at(0).template get(), + j.at(1).template get()}; } template -inline void from_json_tuple_impl(BasicJsonType&& j, std::pair& p, priority_tag<1> /*unused*/) +inline void from_json_tuple_impl(const BasicJsonType& j, std::pair& p, priority_tag<1> /*unused*/) { - p = from_json_tuple_impl(std::forward(j), identity_tag> {}, priority_tag<0> {}); + p = from_json_tuple_impl(j, identity_tag> {}, priority_tag<0> {}); } template -std::tuple from_json_tuple_impl(BasicJsonType&& j, identity_tag> /*unused*/, priority_tag<2> /*unused*/) +std::tuple from_json_tuple_impl(const BasicJsonType& j, identity_tag> /*unused*/, priority_tag<2> /*unused*/) { - static_assert(cxpr_and>, is_compatible_reference_type>...>::value, + static_assert(cxpr_and>, is_compatible_reference_type>...>::value, "Can not return a tuple containing references to types not contained in a Json, try Json::get_to()"); - return from_json_tuple_impl_base<1, Args...>(std::forward(j), index_sequence_for {}); + return from_json_tuple_impl_base<1, Args...>(j, index_sequence_for {}); } template -inline void from_json_tuple_impl(BasicJsonType&& j, std::tuple& t, priority_tag<3> /*unused*/) +inline void from_json_tuple_impl(const BasicJsonType& j, std::tuple& t, priority_tag<3> /*unused*/) { - t = from_json_tuple_impl_base<2, Args...>(std::forward(j), index_sequence_for {}); + t = from_json_tuple_impl_base<2, Args...>(j, index_sequence_for {}); } template -auto from_json(BasicJsonType&& j, TupleRelated&& t) --> decltype(from_json_tuple_impl(std::forward(j), std::forward(t), priority_tag<3> {})) +auto from_json(const BasicJsonType& j, TupleRelated&& t) +-> decltype(from_json_tuple_impl(j, std::forward(t), priority_tag<3> {})) { if (JSON_HEDLEY_UNLIKELY(!j.is_array())) { JSON_THROW(type_error::create(302, concat("type must be array, but is ", j.type_name()), &j)); } - return from_json_tuple_impl(std::forward(j), std::forward(t), priority_tag<3> {}); + return from_json_tuple_impl(j, std::forward(t), priority_tag<3> {}); } template < typename BasicJsonType, typename Key, typename Value, typename Compare, typename Allocator, @@ -636,7 +636,7 @@ struct from_json_fn /// namespace to hold default `from_json` function /// to see why this is required: /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html -namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces) +namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces,misc-anonymous-namespace-in-header) { #endif JSON_INLINE_VARIABLE constexpr const auto& from_json = // NOLINT(misc-definitions-in-headers) diff --git a/include/nlohmann/detail/conversions/to_json.hpp b/include/nlohmann/detail/conversions/to_json.hpp index 92574c8ce..df5c88523 100644 --- a/include/nlohmann/detail/conversions/to_json.hpp +++ b/include/nlohmann/detail/conversions/to_json.hpp @@ -547,7 +547,7 @@ struct to_json_fn /// namespace to hold default `to_json` function /// to see why this is required: /// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4381.html -namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces) +namespace // NOLINT(cert-dcl59-cpp,fuchsia-header-anon-namespaces,google-build-namespaces,misc-anonymous-namespace-in-header) { #endif JSON_INLINE_VARIABLE constexpr const auto& to_json = // NOLINT(misc-definitions-in-headers) diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index ac5019842..9060d76a9 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -421,7 +421,7 @@ class binary_reader @brief Parses a C-style string from the BSON input. @param[in,out] result A reference to the string variable where the read string is to be stored. - @return `true` if the \x00-byte indicating the end of the string was + @return `true` if the \\x00-byte indicating the end of the string was encountered before the EOF; false` indicates an unexpected EOF. */ bool get_bson_cstr(string_t& result) @@ -451,7 +451,7 @@ class binary_reader @brief read a C-style string from contiguous input in one step @param[in,out] result the string to append to - @return whether the string was read; if the input has no \x00-byte, nothing + @return whether the string was read; if the input has no \\x00-byte, nothing is read, and @ref get_bson_cstr reports the end of the input */ bool get_bson_cstr_bulk(string_t& result, std::true_type /*bulk*/) diff --git a/include/nlohmann/detail/input/input_adapters.hpp b/include/nlohmann/detail/input/input_adapters.hpp index 41ec09ac5..09f0ded14 100644 --- a/include/nlohmann/detail/input/input_adapters.hpp +++ b/include/nlohmann/detail/input/input_adapters.hpp @@ -744,6 +744,9 @@ struct container_input_adapter_factory< ContainerType, static adapter_type create(ContainerType&& container) { + // container is forwarded twice on purpose: the resulting begin/end + // iterator types must match adapter_type, computed the same way + // NOLINTNEXTLINE(bugprone-use-after-move) return input_adapter(begin(std::forward(container)), end(std::forward(container))); } }; diff --git a/include/nlohmann/detail/input/lexer.hpp b/include/nlohmann/detail/input/lexer.hpp index f70e747d1..a67a0228c 100644 --- a/include/nlohmann/detail/input/lexer.hpp +++ b/include/nlohmann/detail/input/lexer.hpp @@ -222,9 +222,9 @@ class lexer : public lexer_base ///////////////////// /*! - @brief get codepoint from 4 hex characters following `\u` + @brief get codepoint from 4 hex characters following `\\u` - For input "\u c1 c2 c3 c4" the codepoint is: + For input "\\u c1 c2 c3 c4" the codepoint is: (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4 = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0) diff --git a/include/nlohmann/detail/iterators/iter_impl.hpp b/include/nlohmann/detail/iterators/iter_impl.hpp index 22f3ffc39..2115b6aeb 100644 --- a/include/nlohmann/detail/iterators/iter_impl.hpp +++ b/include/nlohmann/detail/iterators/iter_impl.hpp @@ -35,7 +35,7 @@ This class implements a both iterators (iterator and const_iterator) for the been set (e.g., by a constructor or a copy assignment). If the iterator is default-constructed, it is *uninitialized* and most methods are undefined. **The library uses assertions to detect calls on uninitialized iterators.** -@requirement REQ-JSON-01 The class satisfies the following concept requirements: +This class satisfies the following concept requirements (REQ-JSON-01): - [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): The iterator that can be moved can be moved in both directions (i.e. diff --git a/include/nlohmann/detail/iterators/iteration_proxy.hpp b/include/nlohmann/detail/iterators/iteration_proxy.hpp index c8aa50dd2..c66a5c0fd 100644 --- a/include/nlohmann/detail/iterators/iteration_proxy.hpp +++ b/include/nlohmann/detail/iterators/iteration_proxy.hpp @@ -213,11 +213,11 @@ namespace std JSON_HEDLEY_PRAGMA(clang diagnostic ignored "-Wmismatched-tags") #endif template -class tuple_size<::nlohmann::detail::iteration_proxy_value> // NOLINT(cert-dcl58-cpp) +class tuple_size<::nlohmann::detail::iteration_proxy_value> // NOLINT(cert-dcl58-cpp,bugprone-std-namespace-modification) : public std::integral_constant {}; template -class tuple_element> // NOLINT(cert-dcl58-cpp) +class tuple_element> // NOLINT(cert-dcl58-cpp,bugprone-std-namespace-modification) { public: using type = decltype( diff --git a/include/nlohmann/detail/iterators/json_reverse_iterator.hpp b/include/nlohmann/detail/iterators/json_reverse_iterator.hpp index b452cfcce..d718901ae 100644 --- a/include/nlohmann/detail/iterators/json_reverse_iterator.hpp +++ b/include/nlohmann/detail/iterators/json_reverse_iterator.hpp @@ -29,7 +29,7 @@ namespace detail iterator (to create @ref reverse_iterator) and @ref const_iterator (to create @ref const_reverse_iterator). -@requirement REQ-JSON-02 The class satisfies the following concept requirements: +This class satisfies the following concept requirements (REQ-JSON-02): - [BidirectionalIterator](https://en.cppreference.com/w/cpp/named_req/BidirectionalIterator): The iterator that can be moved can be moved in both directions (i.e. diff --git a/include/nlohmann/detail/json_pointer.hpp b/include/nlohmann/detail/json_pointer.hpp index 78074988e..f170de7dd 100644 --- a/include/nlohmann/detail/json_pointer.hpp +++ b/include/nlohmann/detail/json_pointer.hpp @@ -278,11 +278,11 @@ class json_pointer JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", s, "'"), nullptr)); } - // only triggered on special platforms (like 32bit), see also - // https://github.com/nlohmann/json/pull/2203 + // the index does not fit into size_type; on 64-bit platforms this is + // only SIZE_MAX itself (see #2203 and #5395) if (res >= static_cast((std::numeric_limits::max)())) // NOLINT(runtime/int) { - JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); // LCOV_EXCL_LINE + JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr)); } return static_cast(res); @@ -316,7 +316,7 @@ class json_pointer /*! @brief create and return a reference to the pointed to value - @complexity Linear in the number of reference tokens. + Complexity: Linear in the number of reference tokens. @throw parse_error.106 if an array index begins with '0' @throw parse_error.109 if array index is not a number @@ -403,7 +403,7 @@ class json_pointer @return reference to the JSON value pointed to by the JSON pointer - @complexity Linear in the length of the JSON pointer. + Complexity: Linear in the length of the JSON pointer. @throw parse_error.106 if an array index begins with '0' @throw parse_error.109 if an array index was not a number diff --git a/include/nlohmann/detail/macro_scope.hpp b/include/nlohmann/detail/macro_scope.hpp index 7c5ae3089..8850ca959 100644 --- a/include/nlohmann/detail/macro_scope.hpp +++ b/include/nlohmann/detail/macro_scope.hpp @@ -195,13 +195,6 @@ #define JSON_NO_THREAD_LOCAL 1 #endif -// disable documentation warnings on clang -#if defined(__clang__) - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdocumentation" - #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" -#endif - // allow disabling exceptions #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) #define JSON_THROW(exception) throw exception @@ -260,7 +253,7 @@ { \ /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \ static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on */ \ + /* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on */ \ static const std::pair m[] = __VA_ARGS__; \ auto it = std::find_if(std::begin(m), std::end(m), \ [e](const std::pair& ej_pair) -> bool \ @@ -274,7 +267,7 @@ { \ /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \ static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on */ \ + /* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on */ \ static const std::pair m[] = __VA_ARGS__; \ auto it = std::find_if(std::begin(m), std::end(m), \ [&j](const std::pair& ej_pair) -> bool \ @@ -313,7 +306,7 @@ void templated_json_throw(ExceptionType exception) { \ /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \ static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on */ \ + /* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on */ \ static const std::pair m[] = __VA_ARGS__; \ auto it = std::find_if(std::begin(m), std::end(m), \ [e](const std::pair& ej_pair) -> bool \ @@ -328,7 +321,7 @@ void templated_json_throw(ExceptionType exception) { \ /* NOLINTNEXTLINE(modernize-type-traits) we use C++11 */ \ static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - /* NOLINTNEXTLINE(modernize-avoid-c-arrays) we don't want to depend on */ \ + /* NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) we don't want to depend on */ \ static const std::pair m[] = __VA_ARGS__; \ auto it = std::find_if(std::begin(m), std::end(m), \ [&j](const std::pair& ej_pair) -> bool \ diff --git a/include/nlohmann/detail/macro_unscope.hpp b/include/nlohmann/detail/macro_unscope.hpp index d6aa831d7..1e6e6cce6 100644 --- a/include/nlohmann/detail/macro_unscope.hpp +++ b/include/nlohmann/detail/macro_unscope.hpp @@ -8,11 +8,6 @@ #pragma once -// restore clang diagnostic settings -#if defined(__clang__) - #pragma clang diagnostic pop -#endif - // clean up #undef JSON_ASSERT #undef JSON_INTERNAL_CATCH diff --git a/include/nlohmann/detail/output/output_adapters.hpp b/include/nlohmann/detail/output/output_adapters.hpp index 231cf53ce..53a14d42f 100644 --- a/include/nlohmann/detail/output/output_adapters.hpp +++ b/include/nlohmann/detail/output/output_adapters.hpp @@ -11,6 +11,7 @@ #include // size_t #include // shared_ptr, make_shared #include // basic_string +#include // conditional, integral_constant, is_same #include // move #include // vector @@ -118,11 +119,13 @@ class output_stream_adapter : public output_adapter_protocol : stream(s) {} + // NOLINTNEXTLINE(portability-template-virtual-member-function) void write_character(CharType c) override { stream.put(c); } + // NOLINTNEXTLINE(portability-template-virtual-member-function) void write_characters(const CharType* s, std::size_t length) override { stream.write(s, static_cast(length)); @@ -189,7 +192,82 @@ class output_adapter_sink output_adapter_t oa; }; -template> +/// @brief whether std::basic_string has a non-deprecated std::char_traits +/// specialization, and is therefore usable as output_adapter's default StringType +/// +/// std::char_traits is only guaranteed (and, on some standard libraries, only +/// implemented without a deprecation warning) for the character types listed +/// below; std::char_traits for any other T (e.g. std::uint8_t, as used by the +/// binary writers) is a non-standard extension some standard libraries deprecate. +/// See https://github.com/nlohmann/json/issues/5725 item 2. +template +struct is_output_adapter_string_char_type : std::integral_constant < bool, + std::is_same::value || + std::is_same::value || + std::is_same::value || + std::is_same::value +#if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201907L) + || std::is_same::value +#endif + > {}; + +/// @brief placeholder type for output_adapter's StringType and (with JSON_NO_IO +/// undefined) its std::basic_ostream constructor parameter, for CharType +/// with no non-deprecated std::char_traits specialization +/// +/// Never actually used: the StringType- and std::basic_ostream-based +/// output_adapter constructors are neither documented nor tested for such +/// CharType (only the std::vector-based constructor is used for them, by the +/// binary writers). Naming std::basic_string or +/// std::basic_ostream anywhere such a constructor would otherwise be +/// declared - even as an unused default template argument or an unused, +/// never-called overload - instantiates std::char_traits merely to +/// name the type, which is exactly what triggers the deprecation warning this +/// placeholder avoids. +template +struct output_adapter_no_string_type {}; + +// Select output_adapter's default StringType (and, below, its ostream +// constructor's parameter type) via partial specialization, not +// std::conditional: std::conditional requires both T and F to be named +// as template arguments up front, which would still instantiate (and thus name) +// std::basic_string / std::basic_ostream for every CharType, +// defeating the point. A bool non-type parameter with two specializations only +// ever names the type that is actually selected. +template::value> +struct output_adapter_default_string_type +{ + using type = output_adapter_no_string_type; +}; + +template +struct output_adapter_default_string_type +{ + using type = std::basic_string; +}; + +#ifndef JSON_NO_IO +/// distinct from output_adapter_no_string_type, so the placeholder overloads of +/// output_adapter's constructor (used when CharType is not a character type) +/// stay distinct overloads instead of colliding into a single redeclaration +template +struct output_adapter_no_ostream_type {}; + +template::value> +struct output_adapter_ostream_type +{ + using type = output_adapter_no_ostream_type; +}; + +template +struct output_adapter_ostream_type +{ + using type = std::basic_ostream; +}; +#endif // JSON_NO_IO + +template < typename CharType, typename StringType = + typename output_adapter_default_string_type::type > class output_adapter { public: @@ -198,7 +276,7 @@ class output_adapter : oa(std::make_shared>(vec)) {} #ifndef JSON_NO_IO - output_adapter(std::basic_ostream& s) + output_adapter(typename output_adapter_ostream_type::type& s) : oa(std::make_shared>(s)) {} #endif // JSON_NO_IO diff --git a/include/nlohmann/detail/output/serializer.hpp b/include/nlohmann/detail/output/serializer.hpp index 9715a7896..1c519d4c7 100644 --- a/include/nlohmann/detail/output/serializer.hpp +++ b/include/nlohmann/detail/output/serializer.hpp @@ -65,7 +65,7 @@ class serializer @param[in] ichar indentation character to use @param[in] pretty_print_ whether the output shall be pretty-printed @param[in] ensure_ascii_ If @a ensure_ascii_ is true, all non-ASCII - characters in the output are escaped with `\uXXXX` sequences, and the + characters in the output are escaped with `\\uXXXX` sequences, and the result consists of ASCII characters only. @param[in] indent_step_ the indent level @param[in] error_handler_ how to react on decoding errors @@ -690,7 +690,7 @@ class serializer @param[in] s the string to escape - @complexity Linear in the length of string @a s. + Complexity: Linear in the length of string @a s. */ void dump_escaped(const string_t& s) { @@ -1194,7 +1194,7 @@ class serializer } /*! - * @brief write a lowercase "\uXXXX" escape sequence into @a string_buffer + * @brief write a lowercase "\\uXXXX" escape sequence into @a string_buffer * * Branch-free replacement for `snprintf(buf, 7, "\\u%04x", codeunit)` in the * string escaping hot path. It writes exactly six characters ('\\', 'u' and @@ -1544,7 +1544,7 @@ class serializer /// whether to pretty-print the output const bool pretty_print; - /// whether to escape non-ASCII characters with \uXXXX sequences + /// whether to escape non-ASCII characters with \\uXXXX sequences const bool ensure_ascii; /// the indent level diff --git a/include/nlohmann/detail/string_escape.hpp b/include/nlohmann/detail/string_escape.hpp index 0d24a56bc..a6489e054 100644 --- a/include/nlohmann/detail/string_escape.hpp +++ b/include/nlohmann/detail/string_escape.hpp @@ -62,8 +62,7 @@ inline StringType escape(const StringType& s) /*! * @brief string unescaping as described in RFC 6901 (Sect. 4) - * @param[in] s string to unescape - * @return unescaped string + * @param[in,out] s string to unescape in place * * Note the order of escaping "~1" to "/" and "~0" to "~" is important. * diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index ef2c0e854..91efcf27c 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -18,16 +18,6 @@ #ifndef INCLUDE_NLOHMANN_JSON_HPP_ #define INCLUDE_NLOHMANN_JSON_HPP_ -// Workaround for GCC template redefinition errors in C++ modules -// When nlohmann/json.hpp is included in a C++20 module preamble after -// other module imports, GCC may report spurious redefinition errors for -// STL templates. These pragmas suppress those false positives. -// See: https://github.com/nlohmann/json/issues/5103 -#if defined(__GNUC__) && !defined(__clang__) && __cplusplus >= 202002L - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wignored-attributes" -#endif - #include // all_of, find, for_each, none_of #include // isnan #include // nullptr_t, ptrdiff_t, size_t @@ -2551,12 +2541,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @throw what @ref json_serializer `from_json()` method throws - @liveexample{The example below shows several conversions from JSON values + The example below shows several conversions from JSON values to other types. There a few things to note: (1) Floating-point numbers can - be converted to integers\, (2) A JSON array can be converted to a standard - `std::vector`\, (3) A JSON object can be converted to C++ - associative containers such as `std::unordered_map`.,get__ValueType_const} + be converted to integers, (2) A JSON array can be converted to a standard + `std::vector`, (3) A JSON object can be converted to C++ + associative containers such as `std::unordered_map`. @since version 2.1.0 */ @@ -2623,7 +2613,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @return a copy of *this, converted into @a BasicJsonType - @complexity Depending on the implementation of the called `from_json()` + Complexity: Depending on the implementation of the called `from_json()` method. @since version 3.2.0 @@ -2647,7 +2637,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @return a copy of *this - @complexity Constant. + Complexity: Constant. @since version 2.1.0 */ @@ -2693,7 +2683,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @tparam ValueTypeCV the provided value type @tparam ValueType the returned value type - @return copy of the JSON value, converted to @tparam ValueType if necessary + @return copy of the JSON value, converted to @a ValueType if necessary @throw what @ref json_serializer `from_json()` method throws if conversion is required @@ -2731,12 +2721,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec @return pointer to the internally stored JSON value if the requested pointer type @a PointerType fits to the JSON value; `nullptr` otherwise - @complexity Constant. + Complexity: Constant. - @liveexample{The example below shows how pointers to internal values of a + The example below shows how pointers to internal values of a JSON value can be requested. Note that no type conversions are made and a `nullptr` is returned if the value and the requested pointer type does not - match.,get__PointerType} + match. @sa see @ref get_ptr() for explicit pointer-member access @@ -2830,14 +2820,14 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec to the JSON value type (e.g., the JSON value is of type boolean, but a string is requested); see example below - @complexity Linear in the size of the JSON value. + Complexity: Linear in the size of the JSON value. - @liveexample{The example below shows several conversions from JSON values + The example below shows several conversions from JSON values to other types. There a few things to note: (1) Floating-point numbers can - be converted to integers\, (2) A JSON array can be converted to a standard - `std::vector`\, (3) A JSON object can be converted to C++ - associative containers such as `std::unordered_map`.,operator__ValueType} + be converted to integers, (2) A JSON array can be converted to a standard + `std::vector`, (3) A JSON object can be converted to C++ + associative containers such as `std::unordered_map`. @since version 1.0.0 */ @@ -5292,6 +5282,19 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec /// @deprecated This function is deprecated since 3.8.0 and will be removed in /// version 4.0.0 of the library. Please use /// sax_parse(ptr, ptr + len) instead. + // + // Clang reports "declaration is marked with '@deprecated' command but does + // not have a deprecation attribute" for this overload even though + // JSON_HEDLEY_DEPRECATED_FOR below does expand to __attribute__((deprecated)); + // isolated reproductions of this exact declaration shape (doc comment, + // template<>, two stacked __attribute__ lines, an overload set of the same + // name) do not reproduce it, so this looks like a Clang comment/declaration + // association quirk specific to this overload within basic_json, not a + // genuine documentation bug. See #5725 item 2. +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdocumentation-deprecated-sync" +#endif template JSON_HEDLEY_DEPRECATED_FOR(3.8.0, sax_parse(ptr, ptr + len, ...)) JSON_HEDLEY_NON_NULL(2) @@ -5308,6 +5311,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // NOLINTNEXTLINE(hicpp-move-const-arg,performance-move-const-arg) : detail::binary_reader(std::move(ia), format).sax_parse(sax, strict); } +#if defined(__clang__) +#pragma clang diagnostic pop +#endif #ifndef JSON_NO_IO /// @brief deserialize from stream /// @sa https://json.nlohmann.me/api/basic_json/operator_gtgt/ @@ -6970,7 +6976,7 @@ namespace std // NOLINT(cert-dcl58-cpp) /// @brief hash value for JSON objects /// @sa https://json.nlohmann.me/api/basic_json/std_hash/ NLOHMANN_BASIC_JSON_TPL_DECLARATION -struct hash // NOLINT(cert-dcl58-cpp) +struct hash // NOLINT(cert-dcl58-cpp,bugprone-std-namespace-modification) { std::size_t operator()(const nlohmann::NLOHMANN_BASIC_JSON_TPL& j) const { @@ -7003,7 +7009,7 @@ struct less< ::nlohmann::detail::value_t> // do not remove the space after '<', /// @brief exchanges the values of two JSON objects /// @sa https://json.nlohmann.me/api/basic_json/std_swap/ NLOHMANN_BASIC_JSON_TPL_DECLARATION -inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp) +inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC_JSON_TPL& j2) noexcept( // NOLINT(readability-inconsistent-declaration-parameter-name, cert-dcl58-cpp,bugprone-std-namespace-modification) is_nothrow_move_constructible::value&& // NOLINT(misc-redundant-expression,cppcoreguidelines-noexcept-swap,performance-noexcept-swap) is_nothrow_move_assignable::value) { @@ -7017,7 +7023,7 @@ inline void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL& j1, nlohmann::NLOHMANN_BASIC /// @brief std::formatter specialization for JSON values /// @sa https://json.nlohmann.me/api/basic_json/std_formatter/ NLOHMANN_BASIC_JSON_TPL_DECLARATION -struct formatter // NOLINT(cert-dcl58-cpp) +struct formatter // NOLINT(cert-dcl58-cpp,bugprone-std-namespace-modification) { // -1 means compact output (dump()); any value >= 0 means pretty-printed // output with that many spaces (or indent_char) per level (dump(indent, indent_char)). @@ -7097,11 +7103,6 @@ struct formatter // NOLINT(cert-dcl58-c // unit that includes this header. #include // IWYU pragma: keep -// End of GCC diagnostic pragmas for C++ modules support -#if defined(__GNUC__) && !defined(__clang__) && __cplusplus >= 202002L - #pragma GCC diagnostic pop -#endif - // The user-defined string literals are in a separate header, because their // bodies instantiate the parser in every translation unit that includes them. // Define JSON_NO_AUTOMATIC_UDLS to include only diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 430d80eff..ef1300ff6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -89,11 +89,11 @@ target_compile_options(test_main PUBLIC # https://github.com/nlohmann/json/pull/3229 $<$:-diag-disable=2196> - $<$>:-Wno-deprecated;-Wno-float-equal> $<$:-Wno-deprecated-declarations> $<$:-diag-disable=1786>) +target_include_directories(test_main SYSTEM PUBLIC + thirdparty/doctest) target_include_directories(test_main PUBLIC - thirdparty/doctest ${PROJECT_BINARY_DIR}/include) target_link_libraries(test_main PUBLIC ${NLOHMANN_JSON_TARGET_NAME}) diff --git a/tests/abi/CMakeLists.txt b/tests/abi/CMakeLists.txt index 542409977..c6cbfd7c1 100644 --- a/tests/abi/CMakeLists.txt +++ b/tests/abi/CMakeLists.txt @@ -12,7 +12,6 @@ target_compile_options(abi_compat_common INTERFACE # https://github.com/nlohmann/json/pull/3229 $<$:-diag-disable=2196> - $<$>:-Wno-deprecated;-Wno-float-equal> $<$:-Wno-deprecated-declarations> $<$:-diag-disable=1786>) target_include_directories(abi_compat_common SYSTEM INTERFACE diff --git a/tests/abi/config/config.hpp b/tests/abi/config/config.hpp index 63681899f..9247a0240 100644 --- a/tests/abi/config/config.hpp +++ b/tests/abi/config/config.hpp @@ -28,7 +28,7 @@ std::string namespace_name(std::string ns, T* /*unused*/ = nullptr) // NOLINT(pe std::smatch m; // extract the true namespace name from the function signature - CAPTURE(ns); + CAPTURE(ns) CHECK(std::regex_search(ns, m, std::regex("nlohmann(::[a-zA-Z0-9_]+)*::basic_json"))); return m.str(); diff --git a/tests/src/unit-allocator.cpp b/tests/src/unit-allocator.cpp index 151c268d7..f99abd2fc 100644 --- a/tests/src/unit-allocator.cpp +++ b/tests/src/unit-allocator.cpp @@ -239,7 +239,7 @@ TEST_CASE("controlled bad_alloc") // iterative path instead, part-way through its worklist. const auto check_deep_copy = [](bool objects) { - CAPTURE(objects); + CAPTURE(objects) next_construct_fails = false; @@ -315,7 +315,7 @@ struct nth_alloc_fails_allocator : std::allocator template void check_deep_copy_survives_failing_allocation(bool nest_objects) { - CAPTURE(nest_objects); + CAPTURE(nest_objects) fail_at_alloc_call = -1; @@ -352,7 +352,7 @@ void check_deep_copy_survives_failing_allocation(bool nest_objects) // must come out exactly as it went in for (std::size_t n = 0; n < total_allocations; ++n) { - CAPTURE(n); + CAPTURE(n) alloc_call_count = 0; fail_at_alloc_call = static_cast(n); diff --git a/tests/src/unit-assert_macro.cpp b/tests/src/unit-assert_macro.cpp index adedfc934..ab15b8e5f 100644 --- a/tests/src/unit-assert_macro.cpp +++ b/tests/src/unit-assert_macro.cpp @@ -18,7 +18,7 @@ DOCTEST_CLANG_SUPPRESS_WARNING("-Wstrict-overflow") static int assert_counter; /// set failure variable to true instead of calling assert(x) -#define JSON_ASSERT(x) {if (!(x)) ++assert_counter; } +#define JSON_ASSERT(x) do { if (!(x)) { ++assert_counter; } } while (false) #include using nlohmann::json; diff --git a/tests/src/unit-binary_writer_sinks.cpp b/tests/src/unit-binary_writer_sinks.cpp index d13f5e5ac..b780dc0b5 100644 --- a/tests/src/unit-binary_writer_sinks.cpp +++ b/tests/src/unit-binary_writer_sinks.cpp @@ -89,7 +89,7 @@ TEST_CASE("binary writer output sinks") // the first iteration for (const auto& j : test_values()) { - CAPTURE(j.dump(-1, ' ', false, json::error_handler_t::replace)); + CAPTURE(j.dump(-1, ' ', false, json::error_handler_t::replace)) std::vector cbor; json::to_cbor(j, cbor); @@ -120,8 +120,8 @@ TEST_CASE("binary writer output sinks") { continue; // not a supported combination } - CAPTURE(use_size); - CAPTURE(use_type); + CAPTURE(use_size) + CAPTURE(use_type) std::vector ubjson; json::to_ubjson(j, ubjson, use_size, use_type); CHECK(json::to_ubjson(j, use_size, use_type) == ubjson); @@ -141,7 +141,7 @@ TEST_CASE("binary writer output sinks") for (const auto& j : bson_values()) { - CAPTURE(j.dump()); + CAPTURE(j.dump()) std::vector bson; json::to_bson(j, bson); CHECK(json::to_bson(j) == bson); @@ -152,7 +152,7 @@ TEST_CASE("binary writer output sinks") { for (const auto& j : test_values()) { - CAPTURE(j.dump(-1, ' ', false, json::error_handler_t::replace)); + CAPTURE(j.dump(-1, ' ', false, json::error_handler_t::replace)) const std::vector expected = json::to_cbor(j); std::vector as_char; @@ -177,7 +177,7 @@ TEST_CASE("binary_reserve_hint never over-reserves") { for (const auto& j : test_values()) { - CAPTURE(j.dump(-1, ' ', false, json::error_handler_t::replace)); + CAPTURE(j.dump(-1, ' ', false, json::error_handler_t::replace)) const std::size_t hint = nlohmann::detail::binary_reserve_hint(j); @@ -194,7 +194,7 @@ TEST_CASE("binary_reserve_hint never over-reserves") for (const auto& j : bson_values()) { - CAPTURE(j.dump()); + CAPTURE(j.dump()) CHECK(nlohmann::detail::binary_reserve_hint(j) <= json::to_bson(j).size()); } diff --git a/tests/src/unit-bjdata.cpp b/tests/src/unit-bjdata.cpp index f458a360c..8a0c0fc58 100644 --- a/tests/src/unit-bjdata.cpp +++ b/tests/src/unit-bjdata.cpp @@ -2523,7 +2523,7 @@ TEST_CASE("BJData") {"uint8", "int8", "uint16", "int16", "uint32", "int32", "uint64", "int64", "char" }) { - CAPTURE(type); + CAPTURE(type) const std::string text = std::string(R"({"_ArrayType_":")") + type + R"(","_ArraySize_":[2,3],"_ArrayData_":[1,2,3,4,5,6]})"; const auto from_text = json::to_bjdata(json::parse(text)); @@ -2831,7 +2831,7 @@ TEST_CASE("BJData") R"({"_ArrayType_":"int16","_ArraySize_":[0,2],"_ArrayData_":[]})" }) { - CAPTURE(text); + CAPTURE(text) const json j = json::parse(text); for (const bool use_size : { @@ -2865,7 +2865,7 @@ TEST_CASE("BJData") R"({"_ArrayType_":"int16","_ArraySize_":[],"_ArrayData_":null})" }) { - CAPTURE(text); + CAPTURE(text) const json j = json::parse(text); const auto out = json::to_bjdata(j); CHECK(out.at(0) == '{'); @@ -4199,7 +4199,7 @@ TEST_CASE("BJData and UBJSON can be written to a string") for (const auto& j : values) { - CAPTURE(j.dump()); + CAPTURE(j.dump()) for (const bool use_size : { false, true @@ -4214,8 +4214,8 @@ TEST_CASE("BJData and UBJSON can be written to a string") { continue; } - CAPTURE(use_size); - CAPTURE(use_type); + CAPTURE(use_size) + CAPTURE(use_type) const auto bjdata = json::to_bjdata(j, use_size, use_type); std::string bjdata_string; diff --git a/tests/src/unit-bson.cpp b/tests/src/unit-bson.cpp index 969dfddc2..2f9a727ab 100644 --- a/tests/src/unit-bson.cpp +++ b/tests/src/unit-bson.cpp @@ -1752,7 +1752,7 @@ TEST_CASE("BSON: deeply nested values") json value = "leaf"; for (std::size_t depth = 0; depth <= 300; ++depth) { - CAPTURE(depth); + CAPTURE(depth) const json document = {{"value", value}, {"n", depth}}; CHECK(json::from_bson(json::to_bson(document)) == document); @@ -1800,7 +1800,7 @@ value = depth % 2 == 0 ? json{{"a", std::move(value)}, {"b", {1, "x"}}} : false, true }) { - CAPTURE(objects); + CAPTURE(objects) std::string text = "{\"a\":"; for (std::size_t i = 0; i < depth; ++i) { diff --git a/tests/src/unit-capacity.cpp b/tests/src/unit-capacity.cpp index 98fcd0089..5465ebc74 100644 --- a/tests/src/unit-capacity.cpp +++ b/tests/src/unit-capacity.cpp @@ -17,7 +17,7 @@ TEST_CASE("capacity") { SECTION("boolean") { - json j = true; // NOLINT(misc-const-correctness) + json j = true; const json j_const = true; SECTION("result of empty") @@ -35,7 +35,7 @@ TEST_CASE("capacity") SECTION("string") { - json j = "hello world"; // NOLINT(misc-const-correctness) + json j = "hello world"; const json j_const = "hello world"; SECTION("result of empty") @@ -55,7 +55,7 @@ TEST_CASE("capacity") { SECTION("empty array") { - json j = json::array(); // NOLINT(misc-const-correctness) + json j = json::array(); const json j_const = json::array(); SECTION("result of empty") @@ -73,7 +73,7 @@ TEST_CASE("capacity") SECTION("filled array") { - json j = {1, 2, 3}; // NOLINT(misc-const-correctness) + json j = {1, 2, 3}; const json j_const = {1, 2, 3}; SECTION("result of empty") @@ -94,7 +94,7 @@ TEST_CASE("capacity") { SECTION("empty object") { - json j = json::object(); // NOLINT(misc-const-correctness) + json j = json::object(); const json j_const = json::object(); SECTION("result of empty") @@ -112,7 +112,7 @@ TEST_CASE("capacity") SECTION("filled object") { - json j = {{"one", 1}, {"two", 2}, {"three", 3}}; // NOLINT(misc-const-correctness) + json j = {{"one", 1}, {"two", 2}, {"three", 3}}; const json j_const = {{"one", 1}, {"two", 2}, {"three", 3}}; SECTION("result of empty") @@ -131,7 +131,7 @@ TEST_CASE("capacity") SECTION("number (integer)") { - json j = -23; // NOLINT(misc-const-correctness) + json j = -23; const json j_const = -23; SECTION("result of empty") @@ -149,7 +149,7 @@ TEST_CASE("capacity") SECTION("number (unsigned)") { - json j = 23u; // NOLINT(misc-const-correctness) + json j = 23u; const json j_const = 23u; SECTION("result of empty") @@ -167,7 +167,7 @@ TEST_CASE("capacity") SECTION("number (float)") { - json j = 23.42; // NOLINT(misc-const-correctness) + json j = 23.42; const json j_const = 23.42; SECTION("result of empty") @@ -185,7 +185,7 @@ TEST_CASE("capacity") SECTION("null") { - json j = nullptr; // NOLINT(misc-const-correctness) + json j = nullptr; const json j_const = nullptr; SECTION("result of empty") @@ -206,7 +206,7 @@ TEST_CASE("capacity") { SECTION("boolean") { - json j = true; // NOLINT(misc-const-correctness) + json j = true; const json j_const = true; SECTION("result of size") @@ -226,7 +226,7 @@ TEST_CASE("capacity") SECTION("string") { - json j = "hello world"; // NOLINT(misc-const-correctness) + json j = "hello world"; const json j_const = "hello world"; SECTION("result of size") @@ -248,7 +248,7 @@ TEST_CASE("capacity") { SECTION("empty array") { - json j = json::array(); // NOLINT(misc-const-correctness) + json j = json::array(); const json j_const = json::array(); SECTION("result of size") @@ -268,7 +268,7 @@ TEST_CASE("capacity") SECTION("filled array") { - json j = {1, 2, 3}; // NOLINT(misc-const-correctness) + json j = {1, 2, 3}; const json j_const = {1, 2, 3}; SECTION("result of size") @@ -291,7 +291,7 @@ TEST_CASE("capacity") { SECTION("empty object") { - json j = json::object(); // NOLINT(misc-const-correctness) + json j = json::object(); const json j_const = json::object(); SECTION("result of size") @@ -311,7 +311,7 @@ TEST_CASE("capacity") SECTION("filled object") { - json j = {{"one", 1}, {"two", 2}, {"three", 3}}; // NOLINT(misc-const-correctness) + json j = {{"one", 1}, {"two", 2}, {"three", 3}}; const json j_const = {{"one", 1}, {"two", 2}, {"three", 3}}; SECTION("result of size") @@ -332,7 +332,7 @@ TEST_CASE("capacity") SECTION("number (integer)") { - json j = -23; // NOLINT(misc-const-correctness) + json j = -23; const json j_const = -23; SECTION("result of size") @@ -352,7 +352,7 @@ TEST_CASE("capacity") SECTION("number (unsigned)") { - json j = 23u; // NOLINT(misc-const-correctness) + json j = 23u; const json j_const = 23u; SECTION("result of size") @@ -372,7 +372,7 @@ TEST_CASE("capacity") SECTION("number (float)") { - json j = 23.42; // NOLINT(misc-const-correctness) + json j = 23.42; const json j_const = 23.42; SECTION("result of size") @@ -392,7 +392,7 @@ TEST_CASE("capacity") SECTION("null") { - json j = nullptr; // NOLINT(misc-const-correctness) + json j = nullptr; const json j_const = nullptr; SECTION("result of size") @@ -415,7 +415,7 @@ TEST_CASE("capacity") { SECTION("boolean") { - json j = true; // NOLINT(misc-const-correctness) + json j = true; const json j_const = true; SECTION("result of max_size") @@ -427,7 +427,7 @@ TEST_CASE("capacity") SECTION("string") { - json j = "hello world"; // NOLINT(misc-const-correctness) + json j = "hello world"; const json j_const = "hello world"; SECTION("result of max_size") @@ -441,7 +441,7 @@ TEST_CASE("capacity") { SECTION("empty array") { - json j = json::array(); // NOLINT(misc-const-correctness) + json j = json::array(); const json j_const = json::array(); SECTION("result of max_size") @@ -453,7 +453,7 @@ TEST_CASE("capacity") SECTION("filled array") { - json j = {1, 2, 3}; // NOLINT(misc-const-correctness) + json j = {1, 2, 3}; const json j_const = {1, 2, 3}; SECTION("result of max_size") @@ -468,7 +468,7 @@ TEST_CASE("capacity") { SECTION("empty object") { - json j = json::object(); // NOLINT(misc-const-correctness) + json j = json::object(); const json j_const = json::object(); SECTION("result of max_size") @@ -480,7 +480,7 @@ TEST_CASE("capacity") SECTION("filled object") { - json j = {{"one", 1}, {"two", 2}, {"three", 3}}; // NOLINT(misc-const-correctness) + json j = {{"one", 1}, {"two", 2}, {"three", 3}}; const json j_const = {{"one", 1}, {"two", 2}, {"three", 3}}; SECTION("result of max_size") @@ -493,7 +493,7 @@ TEST_CASE("capacity") SECTION("number (integer)") { - json j = -23; // NOLINT(misc-const-correctness) + json j = -23; const json j_const = -23; SECTION("result of max_size") @@ -505,7 +505,7 @@ TEST_CASE("capacity") SECTION("number (unsigned)") { - json j = 23u; // NOLINT(misc-const-correctness) + json j = 23u; const json j_const = 23u; SECTION("result of max_size") @@ -517,7 +517,7 @@ TEST_CASE("capacity") SECTION("number (float)") { - json j = 23.42; // NOLINT(misc-const-correctness) + json j = 23.42; const json j_const = 23.42; SECTION("result of max_size") @@ -529,7 +529,7 @@ TEST_CASE("capacity") SECTION("null") { - json j = nullptr; // NOLINT(misc-const-correctness) + json j = nullptr; const json j_const = nullptr; SECTION("result of max_size") diff --git a/tests/src/unit-cbor.cpp b/tests/src/unit-cbor.cpp index e12c789e4..c3a425a16 100644 --- a/tests/src/unit-cbor.cpp +++ b/tests/src/unit-cbor.cpp @@ -2878,7 +2878,7 @@ TEST_CASE("Tagged values") 0xD5, 0xD6, 0xD7 }) { - CAPTURE(b); + CAPTURE(b) // add tag to value auto v_tagged = v; @@ -3218,7 +3218,7 @@ TEST_CASE("CBOR large strings and binaries (chunked reader)") std::size_t{4097}, std::size_t{8192}, std::size_t{100000} }) { - CAPTURE(len); + CAPTURE(len) // text string const json j_string = std::string(len, 'x'); diff --git a/tests/src/unit-class_lexer.cpp b/tests/src/unit-class_lexer.cpp index b56e4bd0b..1d20901d6 100644 --- a/tests/src/unit-class_lexer.cpp +++ b/tests/src/unit-class_lexer.cpp @@ -272,7 +272,7 @@ TEST_CASE("lexer number fast path") std::stringstream ss(doc); const json b = json::parse(ss); - CAPTURE(n); + CAPTURE(n) CHECK(a == b); CHECK(a.dump() == b.dump()); CHECK(a[0].type() == b[0].type()); @@ -310,7 +310,7 @@ TEST_CASE("lexer number fast path") for (const auto& n : numbers) { - CAPTURE(n); + CAPTURE(n) const std::string doc = "[" + n + "]"; const json a = json::parse(doc); // contiguous fast path @@ -347,7 +347,7 @@ TEST_CASE("lexer number fast path") {"-", "1.", "1e", "1e+", "1.2e", "01", "-01", "1..2", "1.2.3" }) { - CAPTURE(bad); + CAPTURE(bad) // the contiguous fast path must decline and let the byte path report const std::string doc = std::string("[") + bad + "]"; CHECK_FALSE(json::accept(doc)); @@ -415,7 +415,7 @@ TEST_CASE("lexer number fast path") // 7 + 49 + 343 + 2401 tokens CHECK(tokens.size() == 2401); - CAPTURE(mismatches); + CAPTURE(mismatches) CHECK(mismatches.empty()); } @@ -459,7 +459,7 @@ TEST_CASE("lexer number fast path") "[1 \n2]", "[\n1\n2]", "1\n2", "[01\r\n]", "[1e\n]", "[-\n]" }) { - CAPTURE(bad); + CAPTURE(bad) const std::string doc = bad; const std::string contiguous_what = contiguous_error(doc); @@ -576,7 +576,7 @@ TEST_CASE("lexer string fast path") // 13 + 169 + 2197 tokens, each at two offsets CHECK(tokens.size() == 2197); - CAPTURE(mismatches); + CAPTURE(mismatches) CHECK(mismatches.empty()); } @@ -604,7 +604,7 @@ TEST_CASE("lexer string fast path") } } } - CAPTURE(mismatches); + CAPTURE(mismatches) CHECK(mismatches.empty()); } #endif @@ -649,10 +649,10 @@ TEST_CASE("lexer string fast path") for (const auto& test_case : cases) { - CAPTURE(test_case.description); + CAPTURE(test_case.description) for (const std::size_t offset : offsets) { - CAPTURE(offset); + CAPTURE(offset) const std::string doc = "[\"" + std::string(offset, 'a') + test_case.sequence + "\"]"; CHECK(json::accept(doc) == test_case.valid); #if !defined(JSON_NOEXCEPTION) @@ -1236,7 +1236,7 @@ TEST_CASE("Eisel-Lemire float conversion") for (const auto& c : known) { - CAPTURE(c.first); + CAPTURE(c.first) double out = 0; if (eisel_lemire(c.first, out)) { @@ -1277,7 +1277,7 @@ TEST_CASE("Eisel-Lemire float conversion") std::array buffer{}; const char* end = nlohmann::detail::to_chars(buffer.data(), buffer.data() + buffer.size(), d); const std::string token(buffer.data(), static_cast(end - buffer.data())); - CAPTURE(token); + CAPTURE(token) double out = 0; REQUIRE(eisel_lemire(token, out)); CHECK(bits_of(out) == b); @@ -1289,7 +1289,7 @@ TEST_CASE("Eisel-Lemire float conversion") const std::size_t dot = longer.find('.'); const std::string extra = dot == std::string::npos ? ".000000000000000000001" : "000000000000000000001"; longer.insert(e == std::string::npos ? longer.size() : e, extra); - CAPTURE(longer); + CAPTURE(longer) if (eisel_lemire(longer, out)) { CHECK(bits_of(out) == b); diff --git a/tests/src/unit-class_parser.cpp b/tests/src/unit-class_parser.cpp index 2d4ff6a38..9444c2a35 100644 --- a/tests/src/unit-class_parser.cpp +++ b/tests/src/unit-class_parser.cpp @@ -2561,7 +2561,7 @@ TEST_CASE("last-read diagnostics are identical across input adapters") for (const auto& s : inputs) { - CAPTURE(s); + CAPTURE(s) // reference: contiguous std::string -> seekable (lazy) path const std::string reference = parse_error_message(s); @@ -2645,7 +2645,7 @@ TEST_CASE("diagnostic positions: value lifetime, input adapters, and SAX") SECTION("move constructor resets the moved-from value to npos") { - // basic_json(basic_json&&) (json.hpp, around line 1265) copies + // basic_json(basic_json&&) (json.hpp, around line 1951) copies // other's start_position/end_position into *this and then resets // other's to npos (see the cppcheck-suppress[accessForwarded] // annotation there, which flags this reset as worth a second diff --git a/tests/src/unit-comparison.cpp b/tests/src/unit-comparison.cpp index 6dcec8390..febfd9b42 100644 --- a/tests/src/unit-comparison.cpp +++ b/tests/src/unit-comparison.cpp @@ -857,7 +857,7 @@ TEST_CASE("equality of objects whose entries have no fixed order") for (const std::size_t depth : std::vector {0, 200}) { - CAPTURE(depth); + CAPTURE(depth) const unordered_json descending = nest(make_unordered_object(true), depth); const unordered_json ascending = nest(make_unordered_object(false), depth); @@ -909,7 +909,7 @@ TEST_CASE("equality of an object whose comparator treats different keys as equiv for (const std::size_t depth : std::vector {0, 127, 128, 200}) { - CAPTURE(depth); + CAPTURE(depth) const ci_json x = nest(a, depth); const ci_json y = nest(b, depth); @@ -935,7 +935,7 @@ TEST_CASE("containers are compared element by element") for (const std::size_t depth : std::vector {0, 200}) { - CAPTURE(depth); + CAPTURE(depth) // objects with different keys { diff --git a/tests/src/unit-constructor2.cpp b/tests/src/unit-constructor2.cpp index a2c7e19bf..27bdcccd9 100644 --- a/tests/src/unit-constructor2.cpp +++ b/tests/src/unit-constructor2.cpp @@ -85,7 +85,7 @@ TEST_CASE("other constructors and destructor") CHECK(j.type() == json::value_t::object); const json k(std::move(j)); CHECK(k.type() == json::value_t::object); - CHECK(j.type() == json::value_t::null); // NOLINT: access after move is OK here + CHECK(j.type() == json::value_t::null); // NOLINT(bugprone-use-after-move,hicpp-invalid-access-moved) access after move is OK here } SECTION("copy assignment") diff --git a/tests/src/unit-conversions.cpp b/tests/src/unit-conversions.cpp index add465083..99a1140cf 100644 --- a/tests/src/unit-conversions.cpp +++ b/tests/src/unit-conversions.cpp @@ -1640,7 +1640,7 @@ TEST_CASE("value conversion") enum class cards {kreuz, pik, herz, karo}; -// NOLINTNEXTLINE(misc-use-internal-linkage,misc-const-correctness,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive +// NOLINTNEXTLINE(misc-use-internal-linkage,misc-const-correctness) - false positive NLOHMANN_JSON_SERIALIZE_ENUM(cards, { {cards::kreuz, "kreuz"}, @@ -1658,7 +1658,7 @@ enum TaskState // NOLINT(cert-int09-c,readability-enum-initial-value,cppcoreguid TS_INVALID = -1, }; -// NOLINTNEXTLINE(misc-const-correctness,misc-use-internal-linkage,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive +// NOLINTNEXTLINE(misc-const-correctness,misc-use-internal-linkage) - false positive NLOHMANN_JSON_SERIALIZE_ENUM(TaskState, { {TS_INVALID, nullptr}, @@ -1708,7 +1708,7 @@ TEST_CASE("JSON to enum mapping") enum class strict_cards {kreuz, pik, herz, karo, andere}; // andere not included in mapping -// NOLINTNEXTLINE(misc-use-internal-linkage,misc-const-correctness,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive +// NOLINTNEXTLINE(misc-use-internal-linkage,misc-const-correctness) - false positive NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(strict_cards, { {strict_cards::kreuz, "kreuz"}, @@ -1727,7 +1727,7 @@ enum StrictTaskState // NOLINT(cert-int09-c,readability-enum-initial-value,cppco STRICT_TS_INVALID = -1, }; -// NOLINTNEXTLINE(misc-const-correctness,misc-use-internal-linkage,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) - false positive +// NOLINTNEXTLINE(misc-const-correctness,misc-use-internal-linkage) - false positive NLOHMANN_JSON_SERIALIZE_ENUM_STRICT(StrictTaskState, { {STRICT_TS_INVALID, nullptr}, diff --git a/tests/src/unit-hash.cpp b/tests/src/unit-hash.cpp index eb843c291..382dfcaa2 100644 --- a/tests/src/unit-hash.cpp +++ b/tests/src/unit-hash.cpp @@ -191,7 +191,7 @@ TEST_CASE("hash of deeply nested values") // every depth on either side of where the iterative path takes over for (std::size_t depth = 0; depth <= (2 * nlohmann::detail::recursion_depth_limit()) + 10; ++depth) { - CAPTURE(depth); + CAPTURE(depth) const auto arrays = nested(depth, false); const auto objects = nested(depth, true); const auto ordered = nested(depth, true); @@ -212,7 +212,7 @@ TEST_CASE("hash of deeply nested values") false, true }) { - CAPTURE(objects); + CAPTURE(objects) const auto text = nested_text(depth, objects); const auto a = json::parse(text); const auto b = json::parse(text); diff --git a/tests/src/unit-json_patch.cpp b/tests/src/unit-json_patch.cpp index a78412b23..55775c0b6 100644 --- a/tests/src/unit-json_patch.cpp +++ b/tests/src/unit-json_patch.cpp @@ -1829,13 +1829,13 @@ TEST_CASE("JSON patch: diff of deeply nested values") for (const auto depth : depths) { - CAPTURE(depth); + CAPTURE(depth) for (int from = 0; from < 3; ++from) { for (int to = 0; to < 3; ++to) { - CAPTURE(from); - CAPTURE(to); + CAPTURE(from) + CAPTURE(to) const auto source = nested(depth, from); const auto target = nested(depth, to); const auto patch = json::diff(source, target); @@ -1854,7 +1854,7 @@ TEST_CASE("JSON patch: diff of deeply nested values") { for (std::size_t depth = 0; depth <= 300; ++depth) { - CAPTURE(depth); + CAPTURE(depth) json source = 1; json target = 2; for (std::size_t i = 0; i < depth; ++i) @@ -1878,7 +1878,7 @@ TEST_CASE("JSON patch: diff of deeply nested values") false, true }) { - CAPTURE(objects); + CAPTURE(objects) std::string source_text; std::string target_text; std::string equal_text; @@ -2046,7 +2046,7 @@ TEST_CASE("JSON patch - every operation on ordered_json") }; for (const auto& target : targets) { - CAPTURE(target.dump()); + CAPTURE(target.dump()) CHECK(source.patch(ordered_json::diff(source, target)) == target); } } diff --git a/tests/src/unit-large_json.cpp b/tests/src/unit-large_json.cpp index 97f665848..40025729a 100644 --- a/tests/src/unit-large_json.cpp +++ b/tests/src/unit-large_json.cpp @@ -135,7 +135,7 @@ TEST_CASE("tests on deeply nested JSONs") // are known to meet cleanly - wherever the bound is set. for (std::size_t d = 1; d <= 300; ++d) { - CAPTURE(d); + CAPTURE(d) const json array = json::parse(std::string(d, '[') + '0' + std::string(d, ']')); const json array_copy(array); // NOLINT(performance-unnecessary-copy-initialization): the copy is what is tested @@ -252,7 +252,7 @@ TEST_CASE("tests on deeply nested JSONs") { for (const auto& pattern : patterns) { - CAPTURE(pattern); + CAPTURE(pattern) const std::string text = nested_text(depth, pattern); const json j = json::parse(text); @@ -265,7 +265,7 @@ TEST_CASE("tests on deeply nested JSONs") { for (const auto& pattern : patterns) { - CAPTURE(pattern); + CAPTURE(pattern) const std::string text = nested_text(depth, pattern); const nlohmann::ordered_json o = nlohmann::ordered_json::parse(text); @@ -278,7 +278,7 @@ TEST_CASE("tests on deeply nested JSONs") { for (const auto& pattern : patterns) { - CAPTURE(pattern); + CAPTURE(pattern) const std::string text = nested_text(depth, pattern); const json j = json::parse(text); @@ -290,10 +290,10 @@ TEST_CASE("tests on deeply nested JSONs") { for (std::size_t d = 1; d <= 300; ++d) { - CAPTURE(d); + CAPTURE(d) for (const auto& pattern : patterns) { - CAPTURE(pattern); + CAPTURE(pattern) const std::string text = nested_text(d, pattern); const json j = json::parse(text); diff --git a/tests/src/unit-locale-cpp.cpp b/tests/src/unit-locale-cpp.cpp index 1a1f77c5d..3b9593a20 100644 --- a/tests/src/unit-locale-cpp.cpp +++ b/tests/src/unit-locale-cpp.cpp @@ -289,8 +289,8 @@ TEST_CASE("locale changes between lexer construction and number conversion (#519 for (const auto& transition : transitions) { - CAPTURE(transition.first); - CAPTURE(transition.second); + CAPTURE(transition.first) + CAPTURE(transition.second) if (std::setlocale(LC_NUMERIC, transition.first) == nullptr) { @@ -368,7 +368,7 @@ TEST_CASE("locale with a multi-byte decimal point") { continue; } - CAPTURE(name); + CAPTURE(name) tested = true; // too many significant digits for Clinger's fast path, and an underflow diff --git a/tests/src/unit-merge_patch.cpp b/tests/src/unit-merge_patch.cpp index 2e55a66e7..927eb8773 100644 --- a/tests/src/unit-merge_patch.cpp +++ b/tests/src/unit-merge_patch.cpp @@ -305,10 +305,10 @@ TEST_CASE("JSON Merge Patch on deeply nested values") // over (detail::recursion_depth_limit(), 128) for (std::size_t depth = 0; depth <= 300; ++depth) { - CAPTURE(depth); + CAPTURE(depth) for (int variant = 0; variant < 3; ++variant) { - CAPTURE(variant); + CAPTURE(variant) const json patch = json::parse(nested_objects(depth, variant)); json result = json::parse(nested_objects(depth, (variant + 1) % 3)); @@ -403,7 +403,7 @@ TEST_CASE("merge_patch() with an argument that aliases *this (#5641)") std::size_t{0}, std::size_t{127}, std::size_t{128}, std::size_t{300} }) { - CAPTURE(depth); + CAPTURE(depth) json j = json::parse(nested_objects(depth, 0)); const json expected = j; j.merge_patch(j); diff --git a/tests/src/unit-modifiers.cpp b/tests/src/unit-modifiers.cpp index d4ea6982a..ee81120cf 100644 --- a/tests/src/unit-modifiers.cpp +++ b/tests/src/unit-modifiers.cpp @@ -1084,10 +1084,10 @@ TEST_CASE("update() on deeply nested values") // over (detail::recursion_depth_limit(), 128) for (std::size_t depth = 0; depth <= 300; ++depth) { - CAPTURE(depth); + CAPTURE(depth) for (int variant = 0; variant < 3; ++variant) { - CAPTURE(variant); + CAPTURE(variant) const json source = json::parse(nested_objects(depth, variant)); json result = json::parse(nested_objects(depth, (variant + 1) % 3)); json expected = result; @@ -1177,7 +1177,7 @@ TEST_CASE("update() with an argument that aliases *this (#5641)") std::size_t{0}, std::size_t{127}, std::size_t{128}, std::size_t{300} }) { - CAPTURE(depth); + CAPTURE(depth) json j = json::parse(nested_objects(depth, 0)); const json expected = j; j.update(j, true); diff --git a/tests/src/unit-precise-stream-position.cpp b/tests/src/unit-precise-stream-position.cpp index be8cabd99..e2d9bd0c5 100644 --- a/tests/src/unit-precise-stream-position.cpp +++ b/tests/src/unit-precise-stream-position.cpp @@ -113,7 +113,7 @@ TEST_CASE("JSON_PRECISE_STREAM_POSITION") for (const auto& test : tests) { - CAPTURE(test.first); + CAPTURE(test.first) std::istringstream ss(test.first); json j; ss >> j; @@ -135,7 +135,7 @@ TEST_CASE("JSON_PRECISE_STREAM_POSITION") for (const auto& test : tests) { - CAPTURE(test.first); + CAPTURE(test.first) std::istringstream ss(test.first); json j; ss >> j; @@ -149,7 +149,7 @@ TEST_CASE("JSON_PRECISE_STREAM_POSITION") {"1", "12", "-3.5e2", " 7 " }) { - CAPTURE(s); + CAPTURE(s) std::istringstream ss(s); json j; ss >> j; diff --git a/tests/src/unit-regression2.cpp b/tests/src/unit-regression2.cpp index f14d9a8e4..281c160af 100644 --- a/tests/src/unit-regression2.cpp +++ b/tests/src/unit-regression2.cpp @@ -126,7 +126,7 @@ enum class for_1647 two }; -// NOLINTNEXTLINE(misc-const-correctness,cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays): this is a false positive +// NOLINTNEXTLINE(misc-const-correctness): this is a false positive NLOHMANN_JSON_SERIALIZE_ENUM(for_1647, { {for_1647::one, "one"}, diff --git a/tests/src/unit-regression3.cpp b/tests/src/unit-regression3.cpp index 1c2ebd3f0..95b2b6d4f 100644 --- a/tests/src/unit-regression3.cpp +++ b/tests/src/unit-regression3.cpp @@ -849,13 +849,13 @@ TEST_CASE("issue #5338 - truncated CBOR tagged binary subtype is rejected") for (const auto& data : truncated_tags) { - CAPTURE(data); + CAPTURE(data) for (const auto tag_handler : { json::cbor_tag_handler_t::ignore, json::cbor_tag_handler_t::store }) { - CAPTURE(tag_handler); + CAPTURE(tag_handler) const auto result = json::from_cbor(data, true, false, tag_handler); CHECK(result.is_discarded()); } diff --git a/tests/src/unit-serialization.cpp b/tests/src/unit-serialization.cpp index bfb510fd0..4b959021e 100644 --- a/tests/src/unit-serialization.cpp +++ b/tests/src/unit-serialization.cpp @@ -584,7 +584,7 @@ TEST_CASE("serialization of deeply nested values") // value are known to meet cleanly - wherever the bound is set. for (std::size_t d = 1; d <= 300; ++d) { - CAPTURE(d); + CAPTURE(d) const std::string array_text = std::string(d, '[') + '7' + std::string(d, ']'); CHECK(json::parse(array_text).dump() == array_text); @@ -604,7 +604,7 @@ TEST_CASE("serialization of deeply nested values") { for (std::size_t d = 120; d <= 140; ++d) { - CAPTURE(d); + CAPTURE(d) const json j = json::parse(std::string(d, '[') + '7' + std::string(d, ']')); @@ -629,7 +629,7 @@ TEST_CASE("serialization of deeply nested values") // so it must not gain a newline when it is reached iteratively for (std::size_t d = 125; d <= 135; ++d) { - CAPTURE(d); + CAPTURE(d) const std::string compact = std::string(d, '[') + "[]" + std::string(d, ']'); CHECK(json::parse(compact).dump() == compact); @@ -711,10 +711,10 @@ TEST_CASE("serialization of every kind of value below the bound of the descent") for (const std::size_t depth : std::vector {1, 200}) { - CAPTURE(depth); + CAPTURE(depth) for (const auto& inner : values) { - CAPTURE(inner.dump()); + CAPTURE(inner.dump()) const json j = wrap_in_arrays(inner, depth); CHECK(j.dump() == std::string(depth, '[') + inner.dump() + std::string(depth, ']')); CHECK(j.dump(2) == expected_pretty_in_arrays(inner, depth)); @@ -725,7 +725,7 @@ TEST_CASE("serialization of every kind of value below the bound of the descent") { for (std::size_t d = 120; d <= 140; ++d) { - CAPTURE(d); + CAPTURE(d) // built from the inside out: {"k": , "n": } json j = 7; diff --git a/tests/src/unit-user_defined_input.cpp b/tests/src/unit-user_defined_input.cpp index f07a8a608..0c5cb231e 100644 --- a/tests/src/unit-user_defined_input.cpp +++ b/tests/src/unit-user_defined_input.cpp @@ -350,7 +350,7 @@ TEST_CASE("std::counted_iterator reaches the contiguous fast paths") for (const auto& text : diagnostic_docs) { - CAPTURE(text); + CAPTURE(text) const std::counted_iterator it(text.data(), static_cast>(text.size())); std::string counted_message; std::string string_message; @@ -460,8 +460,8 @@ TEST_CASE("std::counted_iterator bulk scanning stops at the counted end") for (const auto& tc : cases) { - CAPTURE(tc.buffer); - CAPTURE(tc.count); + CAPTURE(tc.buffer) + CAPTURE(tc.count) const std::string buffer = tc.buffer; CHECK(via_counted(buffer, tc.count) == via_prefix(buffer, tc.count)); } diff --git a/tests/src/value_in_range_of_test.hpp b/tests/src/value_in_range_of_test.hpp index 067aef41b..39bf8ab04 100644 --- a/tests/src/value_in_range_of_test.hpp +++ b/tests/src/value_in_range_of_test.hpp @@ -63,10 +63,10 @@ TEST_CASE_TEMPLATE_DEFINE("value_in_range_of trait", T, value_in_range_of_test) INFO("type := ", type_str); - CAPTURE(val_min); - CAPTURE(min_in_range); - CAPTURE(val_max); - CAPTURE(max_in_range); + CAPTURE(val_min) + CAPTURE(min_in_range) + CAPTURE(val_max) + CAPTURE(max_in_range) if (min_in_range) {