Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
420e9218cd | ||
|
|
ad4c240e8b |
No files matched your search
@@ -266,6 +266,22 @@ template<typename ConstructibleArrayType>
|
|||||||
void from_json_array_reserve(ConstructibleArrayType& /*arr*/, std::size_t /*size*/, priority_tag<0> /*unused*/)
|
void from_json_array_reserve(ConstructibleArrayType& /*arr*/, std::size_t /*size*/, priority_tag<0> /*unused*/)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
// append through push_back() where available; containers without it (such as
|
||||||
|
// std::set) fall back to insert(end(), ...), which is what std::inserter did
|
||||||
|
template<typename ConstructibleArrayType, typename ValueType>
|
||||||
|
auto from_json_array_append(ConstructibleArrayType& arr, ValueType&& value, priority_tag<1> /*unused*/)
|
||||||
|
-> decltype(arr.push_back(std::forward<ValueType>(value)), void())
|
||||||
|
{
|
||||||
|
arr.push_back(std::forward<ValueType>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ConstructibleArrayType, typename ValueType>
|
||||||
|
void from_json_array_append(ConstructibleArrayType& arr, ValueType&& value, priority_tag<0> /*unused*/)
|
||||||
|
{
|
||||||
|
using std::end;
|
||||||
|
arr.insert(end(arr), std::forward<ValueType>(value));
|
||||||
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename ConstructibleArrayType,
|
template<typename BasicJsonType, typename ConstructibleArrayType,
|
||||||
enable_if_t<
|
enable_if_t<
|
||||||
std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
|
std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
|
||||||
@@ -275,17 +291,15 @@ auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, p
|
|||||||
j.template get<typename ConstructibleArrayType::value_type>(),
|
j.template get<typename ConstructibleArrayType::value_type>(),
|
||||||
void())
|
void())
|
||||||
{
|
{
|
||||||
using std::end;
|
|
||||||
|
|
||||||
ConstructibleArrayType ret;
|
ConstructibleArrayType ret;
|
||||||
from_json_array_reserve(ret, j.size(), priority_tag<1> {});
|
const auto* inner_array = j.template get_ptr<const typename BasicJsonType::array_t*>();
|
||||||
std::transform(j.begin(), j.end(),
|
from_json_array_reserve(ret, inner_array->size(), priority_tag<1> {});
|
||||||
std::inserter(ret, end(ret)), [](const BasicJsonType & i)
|
for (const auto& elem : *inner_array)
|
||||||
{
|
{
|
||||||
// get<BasicJsonType>() returns *this, this won't call a from_json
|
// get<BasicJsonType>() returns *this, this won't call a from_json
|
||||||
// method when value_type is BasicJsonType
|
// method when value_type is BasicJsonType
|
||||||
return i.template get<typename ConstructibleArrayType::value_type>();
|
from_json_array_append(ret, elem.template get<typename ConstructibleArrayType::value_type>(), priority_tag<1> {});
|
||||||
});
|
}
|
||||||
arr = std::move(ret);
|
arr = std::move(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,9 +397,13 @@ inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
|
|||||||
ConstructibleObjectType ret;
|
ConstructibleObjectType ret;
|
||||||
const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
|
const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
|
||||||
from_json_object_reserve(ret, inner_object->size(), priority_tag<1> {});
|
from_json_object_reserve(ret, inner_object->size(), priority_tag<1> {});
|
||||||
|
using value_type = typename ConstructibleObjectType::value_type;
|
||||||
for (const auto& p : *inner_object)
|
for (const auto& p : *inner_object)
|
||||||
{
|
{
|
||||||
ret.emplace(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
|
// the keys of the source are sorted for the usual object types, so
|
||||||
|
// hinting the end makes every insertion constant-time (for containers
|
||||||
|
// that order their keys the same way)
|
||||||
|
ret.insert(ret.end(), value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>()));
|
||||||
}
|
}
|
||||||
obj = std::move(ret);
|
obj = std::move(ret);
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+26
-8
@@ -5970,6 +5970,22 @@ template<typename ConstructibleArrayType>
|
|||||||
void from_json_array_reserve(ConstructibleArrayType& /*arr*/, std::size_t /*size*/, priority_tag<0> /*unused*/)
|
void from_json_array_reserve(ConstructibleArrayType& /*arr*/, std::size_t /*size*/, priority_tag<0> /*unused*/)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
// append through push_back() where available; containers without it (such as
|
||||||
|
// std::set) fall back to insert(end(), ...), which is what std::inserter did
|
||||||
|
template<typename ConstructibleArrayType, typename ValueType>
|
||||||
|
auto from_json_array_append(ConstructibleArrayType& arr, ValueType&& value, priority_tag<1> /*unused*/)
|
||||||
|
-> decltype(arr.push_back(std::forward<ValueType>(value)), void())
|
||||||
|
{
|
||||||
|
arr.push_back(std::forward<ValueType>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ConstructibleArrayType, typename ValueType>
|
||||||
|
void from_json_array_append(ConstructibleArrayType& arr, ValueType&& value, priority_tag<0> /*unused*/)
|
||||||
|
{
|
||||||
|
using std::end;
|
||||||
|
arr.insert(end(arr), std::forward<ValueType>(value));
|
||||||
|
}
|
||||||
|
|
||||||
template<typename BasicJsonType, typename ConstructibleArrayType,
|
template<typename BasicJsonType, typename ConstructibleArrayType,
|
||||||
enable_if_t<
|
enable_if_t<
|
||||||
std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
|
std::is_assignable<ConstructibleArrayType&, ConstructibleArrayType>::value,
|
||||||
@@ -5979,17 +5995,15 @@ auto from_json_array_impl(const BasicJsonType& j, ConstructibleArrayType& arr, p
|
|||||||
j.template get<typename ConstructibleArrayType::value_type>(),
|
j.template get<typename ConstructibleArrayType::value_type>(),
|
||||||
void())
|
void())
|
||||||
{
|
{
|
||||||
using std::end;
|
|
||||||
|
|
||||||
ConstructibleArrayType ret;
|
ConstructibleArrayType ret;
|
||||||
from_json_array_reserve(ret, j.size(), priority_tag<1> {});
|
const auto* inner_array = j.template get_ptr<const typename BasicJsonType::array_t*>();
|
||||||
std::transform(j.begin(), j.end(),
|
from_json_array_reserve(ret, inner_array->size(), priority_tag<1> {});
|
||||||
std::inserter(ret, end(ret)), [](const BasicJsonType & i)
|
for (const auto& elem : *inner_array)
|
||||||
{
|
{
|
||||||
// get<BasicJsonType>() returns *this, this won't call a from_json
|
// get<BasicJsonType>() returns *this, this won't call a from_json
|
||||||
// method when value_type is BasicJsonType
|
// method when value_type is BasicJsonType
|
||||||
return i.template get<typename ConstructibleArrayType::value_type>();
|
from_json_array_append(ret, elem.template get<typename ConstructibleArrayType::value_type>(), priority_tag<1> {});
|
||||||
});
|
}
|
||||||
arr = std::move(ret);
|
arr = std::move(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6087,9 +6101,13 @@ inline void from_json(const BasicJsonType& j, ConstructibleObjectType& obj)
|
|||||||
ConstructibleObjectType ret;
|
ConstructibleObjectType ret;
|
||||||
const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
|
const auto* inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
|
||||||
from_json_object_reserve(ret, inner_object->size(), priority_tag<1> {});
|
from_json_object_reserve(ret, inner_object->size(), priority_tag<1> {});
|
||||||
|
using value_type = typename ConstructibleObjectType::value_type;
|
||||||
for (const auto& p : *inner_object)
|
for (const auto& p : *inner_object)
|
||||||
{
|
{
|
||||||
ret.emplace(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
|
// the keys of the source are sorted for the usual object types, so
|
||||||
|
// hinting the end makes every insertion constant-time (for containers
|
||||||
|
// that order their keys the same way)
|
||||||
|
ret.insert(ret.end(), value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>()));
|
||||||
}
|
}
|
||||||
obj = std::move(ret);
|
obj = std::move(ret);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,10 @@
|
|||||||
#include <benchmark/benchmark.h>
|
#include <benchmark/benchmark.h>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <array>
|
||||||
|
#include <deque>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <test_data.hpp>
|
#include <test_data.hpp>
|
||||||
|
|
||||||
@@ -621,4 +624,27 @@ static void FromCborChunkedString(benchmark::State& state, const std::size_t chu
|
|||||||
|
|
||||||
BENCHMARK_CAPTURE(FromCborChunkedString, 10000 chunks, 10000);
|
BENCHMARK_CAPTURE(FromCborChunkedString, 10000 chunks, 10000);
|
||||||
|
|
||||||
|
// conversion of a JSON array into standard containers
|
||||||
|
template<typename Container>
|
||||||
|
static void GetArray(benchmark::State& state)
|
||||||
|
{
|
||||||
|
json j = json::array();
|
||||||
|
for (int i = 0; i < 1000; ++i)
|
||||||
|
{
|
||||||
|
j.push_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto _ : state)
|
||||||
|
{
|
||||||
|
auto c = j.get<Container>();
|
||||||
|
benchmark::DoNotOptimize(c);
|
||||||
|
}
|
||||||
|
state.SetItemsProcessed(state.iterations() * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE(GetArray, std::vector<int>);
|
||||||
|
BENCHMARK_TEMPLATE(GetArray, std::deque<int>);
|
||||||
|
BENCHMARK_TEMPLATE(GetArray, std::set<int>);
|
||||||
|
BENCHMARK_TEMPLATE(GetArray, std::array<int, 1000>);
|
||||||
|
|
||||||
BENCHMARK_MAIN();
|
BENCHMARK_MAIN();
|
||||||
Reference in new issue
Block a user