mirror of
https://github.com/nlohmann/json.git
synced 2026-09-09 09:47:58 +00:00
* Broaden JSON_HEDLEY_WARN_UNUSED_RESULT coverage to pure query functions Add JSON_HEDLEY_WARN_UNUSED_RESULT to the unambiguous, const, side-effect-free observer functions whose return value is the entire purpose of the call: - dump() - type(), type_name() - all is_* predicates (is_primitive, is_structured, is_null, is_boolean, is_number, is_number_integer, is_number_unsigned, is_number_float, is_object, is_array, is_string, is_binary, is_discarded) - empty(), size(), max_size() - count(...) (both overloads) and contains(...) (all overloads, including the deprecated json_pointer<BasicJsonType> overload) This mirrors the direction the standard library has taken with [[nodiscard]] on the analogous std::vector/std::map members, and catches real bugs such as `j.empty();` (meant `j.clear();`) or `j.contains(k);` with the result thrown away. Deliberately out of scope (left for a separate, later policy decision, per the issue): at(), value(), get*(), flatten(), unflatten(), patch(), merge_patch(), begin()/end(), comparison operators, erase(), and emplace(). Compiling the full test suite (tests/src/unit-*.cpp) with -Wunused-result -Werror uncovered one real hit: a regression test in unit-regression2.cpp called dump() purely to check it does not throw, discarding the result. Fixed by explicitly casting to void, since the call is intentionally result-less there. Fixes #5410 Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Fix discarded nodiscard results across the test suite for GCC's warn_unused_result A plain (void) cast on a call expression suppresses the C++17 [[nodiscard]] warning but not GCC's warning for functions annotated via the GNU __attribute__((warn_unused_result)) form -- which is what JSON_HEDLEY_WARN_UNUSED_RESULT expands to on GCC. Several existing tests that call a newly-annotated function (dump(), empty()) purely to check that it throws/does not throw, discarding the result via (void), newly warned (and failed -Werror builds) once the annotation was broadened. Route those discards through a small ignore_return_value() helper instead, which actually consumes the value and suppresses the warning on both attribute forms. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Use utils::ignore_return_value() for the issue #1445 dump() discard too Addresses review feedback from @gregmarr on PR #5477: this call site was still using the older "capture in a variable, then (void) it" pattern from before this PR introduced utils::ignore_return_value(), instead of the helper now used at every other discarded-nodiscard-result call site this PR touches. Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me>
56 lines
2.1 KiB
C++
56 lines
2.1 KiB
C++
// __ _____ _____ _____
|
|
// __| | __| | | | JSON for Modern C++ (supporting code)
|
|
// | | |__ | | | | | | version 3.12.0
|
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|
//
|
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#pragma once
|
|
|
|
#include <cstdint> // uint8_t
|
|
#include <fstream> // ifstream, istreambuf_iterator, ios
|
|
#include <vector> // vector
|
|
|
|
namespace utils
|
|
{
|
|
|
|
// Some tests intentionally discard the [[nodiscard]]/JSON_HEDLEY_WARN_UNUSED_RESULT
|
|
// return value of a call they only make to exercise its side effects (e.g. checking
|
|
// that it does not throw). A plain (void) cast on the call expression does not
|
|
// suppress GCC's warning for functions using the GNU __attribute__((warn_unused_result))
|
|
// form (as opposed to the C++17 [[nodiscard]] attribute) -- passing the value into an
|
|
// ordinary function call does.
|
|
template<typename T>
|
|
inline void ignore_return_value(T&& /*unused*/) noexcept {}
|
|
|
|
inline std::vector<std::uint8_t> read_binary_file(const std::string& filename)
|
|
{
|
|
std::ifstream file(filename, std::ios::binary);
|
|
file.unsetf(std::ios::skipws);
|
|
|
|
file.seekg(0, std::ios::end);
|
|
const auto size = file.tellg();
|
|
file.seekg(0, std::ios::beg);
|
|
|
|
std::vector<std::uint8_t> byte_vector;
|
|
byte_vector.reserve(static_cast<std::size_t>(size));
|
|
byte_vector.insert(byte_vector.begin(), std::istream_iterator<std::uint8_t>(file), std::istream_iterator<std::uint8_t>());
|
|
return byte_vector;
|
|
}
|
|
|
|
// sentinel for istreambuf_iterator; compares != true until EOF is reached
|
|
// lets tests read a file directly via the new iterator+sentinel overloads
|
|
// instead of buffering the whole file into a vector first.
|
|
// Only the iterator-first direction (it != sentinel) is ever evaluated by
|
|
// the library's parse loop, so no reversed-order overload is needed.
|
|
struct istreambuf_sentinel
|
|
{
|
|
friend bool operator!=(const std::istreambuf_iterator<char>& it, const istreambuf_sentinel& /*unused*/) noexcept
|
|
{
|
|
return it != std::istreambuf_iterator<char>();
|
|
}
|
|
};
|
|
|
|
} // namespace utils
|