mirror of
https://github.com/nlohmann/json.git
synced 2026-10-18 12:08:12 +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:
2 files changed
+28
-12
No files matched your search
@@ -824,9 +824,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
#ifndef JSON_NO_THREAD_LOCAL
|
#ifndef JSON_NO_THREAD_LOCAL
|
||||||
/// the number of levels an operation descends into before it finishes the
|
/// the number of levels an operation descends into before it finishes the
|
||||||
/// value below it without the call stack
|
/// 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()
|
static constexpr std::uint8_t nesting_depth_limit()
|
||||||
{
|
{
|
||||||
return 128;
|
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)
|
static thread_local std::uint8_t depth = 0; // NOLINT(misc-use-internal-linkage)
|
||||||
return depth;
|
return depth;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief counts one level of a bounded descent for as long as it runs, and
|
@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
|
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
|
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.
|
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
|
class nesting_depth_guard
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nesting_depth_guard() noexcept
|
nesting_depth_guard() noexcept
|
||||||
|
#ifdef JSON_NO_THREAD_LOCAL
|
||||||
|
: m_okay(false)
|
||||||
|
#else
|
||||||
: m_okay(nesting_depth() < nesting_depth_limit())
|
: m_okay(nesting_depth() < nesting_depth_limit())
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
|
#ifndef JSON_NO_THREAD_LOCAL
|
||||||
++nesting_depth();
|
++nesting_depth();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
~nesting_depth_guard()
|
~nesting_depth_guard()
|
||||||
{
|
{
|
||||||
|
#ifndef JSON_NO_THREAD_LOCAL
|
||||||
--nesting_depth();
|
--nesting_depth();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
nesting_depth_guard(const nesting_depth_guard&) = delete;
|
nesting_depth_guard(const nesting_depth_guard&) = delete;
|
||||||
@@ -885,7 +896,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
private:
|
private:
|
||||||
bool m_okay;
|
bool m_okay;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
/// an entry of the iterative deep copy's worklist: a structured value and
|
/// an entry of the iterative deep copy's worklist: a structured value and
|
||||||
/// the value that is to become its copy
|
/// 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)
|
void copy_structured(const basic_json& src)
|
||||||
{
|
{
|
||||||
#ifndef JSON_NO_THREAD_LOCAL
|
|
||||||
const nesting_depth_guard guard;
|
const nesting_depth_guard guard;
|
||||||
|
|
||||||
if (JSON_HEDLEY_LIKELY(guard.okay()))
|
if (JSON_HEDLEY_LIKELY(guard.okay()))
|
||||||
@@ -1148,7 +1157,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
copy_level(src);
|
copy_level(src);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Finish this value without descending any further. It is completed
|
// Finish this value without descending any further. It is completed
|
||||||
// before this returns, so a copy made by a custom base class - or by
|
// before this returns, so a copy made by a custom base class - or by
|
||||||
|
|||||||
@@ -22187,9 +22187,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
#ifndef JSON_NO_THREAD_LOCAL
|
#ifndef JSON_NO_THREAD_LOCAL
|
||||||
/// the number of levels an operation descends into before it finishes the
|
/// the number of levels an operation descends into before it finishes the
|
||||||
/// value below it without the call stack
|
/// 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()
|
static constexpr std::uint8_t nesting_depth_limit()
|
||||||
{
|
{
|
||||||
return 128;
|
return 128;
|
||||||
@@ -22212,6 +22209,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
static thread_local std::uint8_t depth = 0; // NOLINT(misc-use-internal-linkage)
|
static thread_local std::uint8_t depth = 0; // NOLINT(misc-use-internal-linkage)
|
||||||
return depth;
|
return depth;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief counts one level of a bounded descent for as long as it runs, and
|
@brief counts one level of a bounded descent for as long as it runs, and
|
||||||
@@ -22220,19 +22218,32 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
Looks the count up and tests it against the limit itself, rather than
|
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
|
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.
|
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
|
class nesting_depth_guard
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nesting_depth_guard() noexcept
|
nesting_depth_guard() noexcept
|
||||||
|
#ifdef JSON_NO_THREAD_LOCAL
|
||||||
|
: m_okay(false)
|
||||||
|
#else
|
||||||
: m_okay(nesting_depth() < nesting_depth_limit())
|
: m_okay(nesting_depth() < nesting_depth_limit())
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
|
#ifndef JSON_NO_THREAD_LOCAL
|
||||||
++nesting_depth();
|
++nesting_depth();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
~nesting_depth_guard()
|
~nesting_depth_guard()
|
||||||
{
|
{
|
||||||
|
#ifndef JSON_NO_THREAD_LOCAL
|
||||||
--nesting_depth();
|
--nesting_depth();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
nesting_depth_guard(const nesting_depth_guard&) = delete;
|
nesting_depth_guard(const nesting_depth_guard&) = delete;
|
||||||
@@ -22248,7 +22259,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
private:
|
private:
|
||||||
bool m_okay;
|
bool m_okay;
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
/// an entry of the iterative deep copy's worklist: a structured value and
|
/// an entry of the iterative deep copy's worklist: a structured value and
|
||||||
/// the value that is to become its copy
|
/// the value that is to become its copy
|
||||||
@@ -22503,7 +22513,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
*/
|
*/
|
||||||
void copy_structured(const basic_json& src)
|
void copy_structured(const basic_json& src)
|
||||||
{
|
{
|
||||||
#ifndef JSON_NO_THREAD_LOCAL
|
|
||||||
const nesting_depth_guard guard;
|
const nesting_depth_guard guard;
|
||||||
|
|
||||||
if (JSON_HEDLEY_LIKELY(guard.okay()))
|
if (JSON_HEDLEY_LIKELY(guard.okay()))
|
||||||
@@ -22511,7 +22520,6 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
copy_level(src);
|
copy_level(src);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Finish this value without descending any further. It is completed
|
// Finish this value without descending any further. It is completed
|
||||||
// before this returns, so a copy made by a custom base class - or by
|
// before this returns, so a copy made by a custom base class - or by
|
||||||
|
|||||||
Reference in new issue
Block a user