Make detail::json_ref do less work by deferring moves/copies
This commit is contained in:
parent
0f4978e503
commit
897879bccb
1 changed files with 22 additions and 16 deletions
38
src/json.hpp
38
src/json.hpp
|
@ -7088,50 +7088,55 @@ struct json_ref
|
||||||
typedef BasicJsonType value_type;
|
typedef BasicJsonType value_type;
|
||||||
|
|
||||||
json_ref(value_type&& value)
|
json_ref(value_type&& value)
|
||||||
: value_(std::move(value))
|
: value_ref_(&value)
|
||||||
, is_rvalue_(true)
|
, is_rvalue_(true)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json_ref(const value_type& value)
|
json_ref(const value_type& value)
|
||||||
: value_(value)
|
: value_ref_(const_cast<value_type*>(&value))
|
||||||
, is_rvalue_(false)
|
, is_rvalue_(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
json_ref(std::initializer_list<json_ref> init)
|
json_ref(std::initializer_list<json_ref> init)
|
||||||
: value_(init)
|
: owned_value_(init)
|
||||||
, is_rvalue_(true)
|
, is_rvalue_(true)
|
||||||
{}
|
{
|
||||||
|
value_ref_ = &owned_value_;
|
||||||
|
}
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
json_ref(Args... args)
|
json_ref(Args... args)
|
||||||
: value_(std::forward<Args>(args)...)
|
: owned_value_(std::forward<Args>(args)...)
|
||||||
, is_rvalue_(true)
|
, is_rvalue_(true)
|
||||||
{}
|
{
|
||||||
|
value_ref_ = &owned_value_;
|
||||||
|
}
|
||||||
|
|
||||||
value_type moved() const
|
value_type moved_or_copied() const
|
||||||
{
|
{
|
||||||
if (is_rvalue_)
|
if (is_rvalue_)
|
||||||
{
|
{
|
||||||
return std::move(value_);
|
return std::move(*value_ref_);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return value_;
|
return *value_ref_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type const& operator*() const
|
value_type const& operator*() const
|
||||||
{
|
{
|
||||||
return value_;
|
return *static_cast<value_type const*>(value_ref_);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_type const* operator->() const
|
value_type const* operator->() const
|
||||||
{
|
{
|
||||||
return &value_;
|
return static_cast<value_type const*>(value_ref_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable value_type value_;
|
value_type * value_ref_;
|
||||||
|
mutable value_type owned_value_;
|
||||||
bool is_rvalue_;
|
bool is_rvalue_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8747,7 +8752,7 @@ class basic_json
|
||||||
|
|
||||||
std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
|
std::for_each(init.begin(), init.end(), [this](const detail::json_ref<basic_json>& element_ref)
|
||||||
{
|
{
|
||||||
basic_json element = element_ref.moved();
|
basic_json element = element_ref.moved_or_copied();
|
||||||
m_value.object->emplace(
|
m_value.object->emplace(
|
||||||
std::move(*((*element.m_value.array)[0].m_value.string)),
|
std::move(*((*element.m_value.array)[0].m_value.string)),
|
||||||
std::move((*element.m_value.array)[1]));
|
std::move((*element.m_value.array)[1]));
|
||||||
|
@ -9010,7 +9015,7 @@ class basic_json
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
basic_json(const detail::json_ref<basic_json>& ref)
|
basic_json(const detail::json_ref<basic_json>& ref)
|
||||||
: basic_json(ref.moved())
|
: basic_json(ref.moved_or_copied())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11935,8 +11940,9 @@ class basic_json
|
||||||
{
|
{
|
||||||
if (is_object() and init.size() == 2 and (*init.begin())->is_string())
|
if (is_object() and init.size() == 2 and (*init.begin())->is_string())
|
||||||
{
|
{
|
||||||
basic_json&& key = init.begin()->moved();
|
basic_json&& key = init.begin()->moved_or_copied();
|
||||||
push_back(typename object_t::value_type(std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved()));
|
push_back(typename object_t::value_type(
|
||||||
|
std::move(key.get_ref<string_t&>()), (init.begin() + 1)->moved_or_copied()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue