mirror of
https://github.com/nlohmann/json.git
synced 2026-10-15 02:37:13 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b8213a5a3 |
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3333,6 +3333,22 @@ public:
|
|||||||
return j.m_data.m_value.object->find(lookup_key(std::forward<KeyType>(key)));
|
return j.m_data.m_value.object->find(lookup_key(std::forward<KeyType>(key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief out-of-line throw helpers: building the message inline blocks inlining of the hot accessors
|
||||||
|
/// @throw out_of_range.401
|
||||||
|
JSON_HEDLEY_NO_RETURN JSON_HEDLEY_NEVER_INLINE
|
||||||
|
static void throw_array_index_out_of_range(size_type idx, const basic_json& j)
|
||||||
|
{
|
||||||
|
JSON_THROW(out_of_range::create(detail::exception_id::array_index_out_of_range, detail::concat("array index ", std::to_string(idx), " is out of range"), &j));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @throw out_of_range.403
|
||||||
|
template<typename KeyType>
|
||||||
|
JSON_HEDLEY_NO_RETURN JSON_HEDLEY_NEVER_INLINE
|
||||||
|
static void throw_key_not_found(const KeyType& key, const basic_json& j)
|
||||||
|
{
|
||||||
|
JSON_THROW(out_of_range::create(detail::exception_id::key_not_found, detail::concat("key '", key, "' not found"), &j));
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief checked object element access used by the at() overloads taking a key
|
/// @brief checked object element access used by the at() overloads taking a key
|
||||||
/// @throw type_error.304 if @a j is not an object
|
/// @throw type_error.304 if @a j is not an object
|
||||||
/// @throw out_of_range.403 if @a key is not found
|
/// @throw out_of_range.403 if @a key is not found
|
||||||
@@ -3353,7 +3369,7 @@ public:
|
|||||||
// std::map or ordered_map) never moves from its argument, so key is still
|
// std::map or ordered_map) never moves from its argument, so key is still
|
||||||
// valid here regardless of whether KeyType was deduced as an rvalue reference
|
// valid here regardless of whether KeyType was deduced as an rvalue reference
|
||||||
// NOLINTNEXTLINE(bugprone-use-after-move,hicpp-invalid-access-moved)
|
// NOLINTNEXTLINE(bugprone-use-after-move,hicpp-invalid-access-moved)
|
||||||
JSON_THROW(out_of_range::create(detail::exception_id::key_not_found, detail::concat("key '", key_for_message(key), "' not found"), &j));
|
throw_key_not_found(key_for_message(key), j);
|
||||||
}
|
}
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
@@ -3390,7 +3406,7 @@ public:
|
|||||||
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(idx >= j.m_data.m_value.array->size()))
|
if (JSON_HEDLEY_UNLIKELY(idx >= j.m_data.m_value.array->size()))
|
||||||
{
|
{
|
||||||
JSON_THROW(out_of_range::create(detail::exception_id::array_index_out_of_range, detail::concat("array index ", std::to_string(idx), " is out of range"), &j));
|
throw_array_index_out_of_range(idx, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*j.m_data.m_value.array)[idx];
|
return (*j.m_data.m_value.array)[idx];
|
||||||
|
|||||||
Generated
+39
-9
@@ -5962,6 +5962,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,
|
||||||
@@ -5971,17 +5987,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32681,6 +32695,22 @@ public:
|
|||||||
return j.m_data.m_value.object->find(lookup_key(std::forward<KeyType>(key)));
|
return j.m_data.m_value.object->find(lookup_key(std::forward<KeyType>(key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief out-of-line throw helpers: building the message inline blocks inlining of the hot accessors
|
||||||
|
/// @throw out_of_range.401
|
||||||
|
JSON_HEDLEY_NO_RETURN JSON_HEDLEY_NEVER_INLINE
|
||||||
|
static void throw_array_index_out_of_range(size_type idx, const basic_json& j)
|
||||||
|
{
|
||||||
|
JSON_THROW(out_of_range::create(detail::exception_id::array_index_out_of_range, detail::concat("array index ", std::to_string(idx), " is out of range"), &j));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @throw out_of_range.403
|
||||||
|
template<typename KeyType>
|
||||||
|
JSON_HEDLEY_NO_RETURN JSON_HEDLEY_NEVER_INLINE
|
||||||
|
static void throw_key_not_found(const KeyType& key, const basic_json& j)
|
||||||
|
{
|
||||||
|
JSON_THROW(out_of_range::create(detail::exception_id::key_not_found, detail::concat("key '", key, "' not found"), &j));
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief checked object element access used by the at() overloads taking a key
|
/// @brief checked object element access used by the at() overloads taking a key
|
||||||
/// @throw type_error.304 if @a j is not an object
|
/// @throw type_error.304 if @a j is not an object
|
||||||
/// @throw out_of_range.403 if @a key is not found
|
/// @throw out_of_range.403 if @a key is not found
|
||||||
@@ -32701,7 +32731,7 @@ public:
|
|||||||
// std::map or ordered_map) never moves from its argument, so key is still
|
// std::map or ordered_map) never moves from its argument, so key is still
|
||||||
// valid here regardless of whether KeyType was deduced as an rvalue reference
|
// valid here regardless of whether KeyType was deduced as an rvalue reference
|
||||||
// NOLINTNEXTLINE(bugprone-use-after-move,hicpp-invalid-access-moved)
|
// NOLINTNEXTLINE(bugprone-use-after-move,hicpp-invalid-access-moved)
|
||||||
JSON_THROW(out_of_range::create(detail::exception_id::key_not_found, detail::concat("key '", key_for_message(key), "' not found"), &j));
|
throw_key_not_found(key_for_message(key), j);
|
||||||
}
|
}
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
@@ -32738,7 +32768,7 @@ public:
|
|||||||
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(idx >= j.m_data.m_value.array->size()))
|
if (JSON_HEDLEY_UNLIKELY(idx >= j.m_data.m_value.array->size()))
|
||||||
{
|
{
|
||||||
JSON_THROW(out_of_range::create(detail::exception_id::array_index_out_of_range, detail::concat("array index ", std::to_string(idx), " is out of range"), &j));
|
throw_array_index_out_of_range(idx, j);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*j.m_data.m_value.array)[idx];
|
return (*j.m_data.m_value.array)[idx];
|
||||||
|
|||||||
@@ -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,51 @@ static void FromCborChunkedString(benchmark::State& state, const std::size_t chu
|
|||||||
|
|
||||||
BENCHMARK_CAPTURE(FromCborChunkedString, 10000 chunks, 10000);
|
BENCHMARK_CAPTURE(FromCborChunkedString, 10000 chunks, 10000);
|
||||||
|
|
||||||
|
// checked element access (at(i) must inline like operator[])
|
||||||
|
static void ArrayAt(benchmark::State& state)
|
||||||
|
{
|
||||||
|
json j = json::array();
|
||||||
|
for (int i = 0; i < 1000; ++i)
|
||||||
|
{
|
||||||
|
j.push_back(i);
|
||||||
|
}
|
||||||
|
const json& cj = j;
|
||||||
|
|
||||||
|
for (auto _ : state)
|
||||||
|
{
|
||||||
|
std::int64_t sum = 0;
|
||||||
|
for (std::size_t i = 0; i < 1000; ++i)
|
||||||
|
{
|
||||||
|
sum += cj.at(i).get<int>();
|
||||||
|
}
|
||||||
|
benchmark::DoNotOptimize(sum);
|
||||||
|
}
|
||||||
|
state.SetItemsProcessed(state.iterations() * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK(ArrayAt);
|
||||||
|
|
||||||
|
// 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