mirror of
https://github.com/nlohmann/json.git
synced 2026-10-24 14:58:54 +00:00
from_json: number-first dispatch for arithmetic types, loop for std::array (#5891)
from_json(ArithmeticType&) now reads numbers through get_number_value() and handles a boolean on a cold path, which puts the three number types first in the per-element type dispatch. get<std::array<T, N>>() always took the identity_tag overload, a pack expansion of N calls j.at(i).get<T>() that clang unrolls into straight-line code (about 28,000 instructions for N = 1000), so its speed depended on inlining decisions in that body. For trivial element types, which cannot tell default construction plus assignment from construction in place, it now fills a std::array in a loop. That loop, shared with get_to(), checks the size once and reads the inner array directly; a short array still converts the elements it has and then throws the out_of_range error at() would throw. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
3 files changed
+140
-88
No files matched your search
@@ -361,6 +361,28 @@ TEST_CASE("constructors")
|
||||
CHECK_THROWS_WITH_AS((j.get<std::pair<int, int>>()), "[json.exception.out_of_range.401] array index 1 is out of range", json::out_of_range&);
|
||||
CHECK_THROWS_WITH_AS((j.get<std::tuple<int, int>>()), "[json.exception.out_of_range.401] array index 1 is out of range", json::out_of_range&);
|
||||
CHECK_THROWS_WITH_AS((j.get<std::array<int, 3>>()), "[json.exception.out_of_range.401] array index 1 is out of range", json::out_of_range&);
|
||||
CHECK_THROWS_WITH_AS((j.get<std::array<std::string, 3>>()), "[json.exception.type_error.302] type must be string, but is number", json::type_error&);
|
||||
|
||||
// the elements are converted in order, so a type error comes before a missing element
|
||||
json const j2{1, "two"};
|
||||
CHECK_THROWS_WITH_AS((j2.get<std::array<int, 3>>()), "[json.exception.type_error.302] type must be number, but is string", json::type_error&);
|
||||
std::array<int, 3> a{{0, 0, 0}};
|
||||
CHECK_THROWS_WITH_AS(j2.get_to(a), "[json.exception.type_error.302] type must be number, but is string", json::type_error&);
|
||||
CHECK_THROWS_WITH_AS(j.get_to(a), "[json.exception.out_of_range.401] array index 1 is out of range", json::out_of_range&);
|
||||
CHECK(a[0] == 1);
|
||||
|
||||
json const j3{"one", "two"};
|
||||
CHECK_THROWS_WITH_AS((j3.get<std::array<std::string, 3>>()), "[json.exception.out_of_range.401] array index 2 is out of range", json::out_of_range&);
|
||||
}
|
||||
|
||||
SECTION("std::array from a longer array or from booleans")
|
||||
{
|
||||
json const j{1, 2.5, true, 4u};
|
||||
CHECK(j.get<std::array<int, 3>>() == (std::array<int, 3> {{1, 2, 1}}));
|
||||
std::array<int, 4> a{{0, 0, 0, 0}};
|
||||
j.get_to(a);
|
||||
CHECK(a == (std::array<int, 4> {{1, 2, 1, 4}}));
|
||||
CHECK(j.get<std::array<int, 0>>().empty());
|
||||
}
|
||||
|
||||
SECTION("std::forward_list<json>")
|
||||
|
||||
Reference in new issue
Block a user