mirror of
https://github.com/nlohmann/json.git
synced 2026-11-02 19:05:35 +00:00
Construct a scalar member in place; only a throwing value goes through a temporary
Creating the value first and moving it over the member is needed only when creating it can throw (a string, a binary value or a container). A scalar or null is again constructed in place, without the extra move and destroy per member (and, with JSON_DIAGNOSTICS, without the extra set_parents()). Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
2 files changed
+44
-14
No files matched your search
Generated
+22
-7
@@ -16946,13 +16946,9 @@ class json_sax_dom_parser : public json_sax_dom_error_state
|
||||
{
|
||||
if (JSON_HEDLEY_LIKELY(member.is_null()))
|
||||
{
|
||||
// a new member is null and holds nothing: move the value over it
|
||||
// instead of destroying and swapping. The value is created first,
|
||||
// because creating a container or a string can throw, and a
|
||||
// constructor that was interrupted must not have touched the
|
||||
// member (#5985); the move constructor is noexcept
|
||||
BasicJsonType value(std::forward<Value>(v));
|
||||
::new (static_cast<void*>(&member)) BasicJsonType(std::move(value));
|
||||
// a new member is null and holds nothing: construct the value
|
||||
// over it instead of destroying and swapping
|
||||
construct_member(member, std::forward<Value>(v), std::is_nothrow_constructible < BasicJsonType, Value && > {});
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -16961,6 +16957,25 @@ class json_sax_dom_parser : public json_sax_dom_error_state
|
||||
}
|
||||
}
|
||||
|
||||
/// a scalar cannot throw: construct it in place
|
||||
template<typename Value>
|
||||
JSON_HEDLEY_ALWAYS_INLINE
|
||||
static void construct_member(BasicJsonType& member, Value&& v, std::true_type /*nothrow*/)
|
||||
{
|
||||
::new (static_cast<void*>(&member)) BasicJsonType(std::forward<Value>(v));
|
||||
}
|
||||
|
||||
/// creating a container or a string can throw, and a constructor that was
|
||||
/// interrupted must not have touched the member (#5985): create the value
|
||||
/// first, then move it over the member (the move constructor is noexcept)
|
||||
template<typename Value>
|
||||
JSON_HEDLEY_ALWAYS_INLINE
|
||||
static void construct_member(BasicJsonType& member, Value&& v, std::false_type /*may throw*/)
|
||||
{
|
||||
BasicJsonType value(std::forward<Value>(v));
|
||||
::new (static_cast<void*>(&member)) BasicJsonType(std::move(value));
|
||||
}
|
||||
|
||||
/// a custom base class may care about the lifetime of the value
|
||||
template<typename Value>
|
||||
static void set_member(BasicJsonType& member, Value&& v, std::false_type /*custom base*/)
|
||||
|
||||
Reference in new issue
Block a user