mirror of
https://github.com/nlohmann/json.git
synced 2026-09-03 06:57:15 +00:00
Make nesting_depth_guard usable regardless of JSON_NO_THREAD_LOCAL
nesting_depth_limit() and nesting_depth() stay behind #ifndef JSON_NO_THREAD_LOCAL, since a descent cannot be bounded without a per-thread count. But the guard itself now always exists, becoming a no-op that is never okay() under that macro - the same way the bound is already reached on every call without one. copy_structured() no longer needs to know which case it is in. This is what lets #5390 reuse the guard for comparison, which cannot test JSON_NO_THREAD_LOCAL where the macro-based operators use it: the guard now carries that distinction itself instead of requiring every caller to. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
@@ -824,9 +824,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
#ifndef JSON_NO_THREAD_LOCAL
|
||||
/// the number of levels an operation descends into before it finishes the
|
||||
/// value below it without the call stack
|
||||
///
|
||||
/// only meaningful together with @ref nesting_depth_guard, which is why
|
||||
/// both live inside this very guard's own #ifndef
|
||||
static constexpr std::uint8_t nesting_depth_limit()
|
||||
{
|
||||
return 128;
|
||||
@@ -849,6 +846,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
static thread_local std::uint8_t depth = 0; // NOLINT(misc-use-internal-linkage)
|
||||
return depth;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@brief counts one level of a bounded descent for as long as it runs, and
|
||||
@@ -857,19 +855,32 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
Looks the count up and tests it against the limit itself, rather than
|
||||
leaving that to the caller: either way it is reached exactly once, so
|
||||
there is nothing to be gained by making the caller do it.
|
||||
|
||||
Does nothing and is never @ref okay without thread-local storage, where no
|
||||
descent can be bounded at all: a caller that only descends while this says
|
||||
it may always ends up finishing without the call stack, exactly as if every
|
||||
value were nested past the limit.
|
||||
*/
|
||||
class nesting_depth_guard
|
||||
{
|
||||
public:
|
||||
nesting_depth_guard() noexcept
|
||||
#ifdef JSON_NO_THREAD_LOCAL
|
||||
: m_okay(false)
|
||||
#else
|
||||
: m_okay(nesting_depth() < nesting_depth_limit())
|
||||
#endif
|
||||
{
|
||||
#ifndef JSON_NO_THREAD_LOCAL
|
||||
++nesting_depth();
|
||||
#endif
|
||||
}
|
||||
|
||||
~nesting_depth_guard()
|
||||
{
|
||||
#ifndef JSON_NO_THREAD_LOCAL
|
||||
--nesting_depth();
|
||||
#endif
|
||||
}
|
||||
|
||||
nesting_depth_guard(const nesting_depth_guard&) = delete;
|
||||
@@ -885,7 +896,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
private:
|
||||
bool m_okay;
|
||||
};
|
||||
#endif
|
||||
|
||||
/// an entry of the iterative deep copy's worklist: a structured value and
|
||||
/// the value that is to become its copy
|
||||
@@ -1140,7 +1150,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
*/
|
||||
void copy_structured(const basic_json& src)
|
||||
{
|
||||
#ifndef JSON_NO_THREAD_LOCAL
|
||||
const nesting_depth_guard guard;
|
||||
|
||||
if (JSON_HEDLEY_LIKELY(guard.okay()))
|
||||
@@ -1148,7 +1157,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
copy_level(src);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Finish this value without descending any further. It is completed
|
||||
// before this returns, so a copy made by a custom base class - or by
|
||||
|
||||
Reference in New Issue
Block a user