mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b1c31b428d | |||
| 56ac56ba32 | |||
| 19549c60ec | |||
| 16e99f229b | |||
| 21342a4142 | |||
| d0e841d3e9 | |||
| a962652ec3 | |||
| 77d73b068a | |||
| 19ff7a572d | |||
| 235dbc5369 | |||
| 2b9c8977af |
+1
-1
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14)
|
||||
project(
|
||||
simdjson
|
||||
# The version number is modified by tools/release.py
|
||||
VERSION 4.2.0
|
||||
VERSION 4.2.2
|
||||
DESCRIPTION "Parsing gigabytes of JSON per second"
|
||||
HOMEPAGE_URL "https://simdjson.org/"
|
||||
LANGUAGES CXX C
|
||||
|
||||
@@ -38,7 +38,7 @@ PROJECT_NAME = simdjson
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = "4.2.0"
|
||||
PROJECT_NUMBER = "4.2.2"
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
||||
+10
-6
@@ -1,6 +1,7 @@
|
||||
The Basics
|
||||
==========
|
||||
|
||||
|
||||
An overview of what you need to know to use simdjson to parse JSON documents, with examples.
|
||||
[Our documentation regarding the generation (serialization) of JSON documents is in a
|
||||
separate document](https://github.com/simdjson/simdjson/blob/master/doc/builder.md).
|
||||
@@ -182,6 +183,9 @@ auto json = padded_string::load("twitter.json"); // load JSON file 'twitter.json
|
||||
ondemand::document doc = parser.iterate(json); // position a pointer at the beginning of the JSON data
|
||||
```
|
||||
|
||||
(Windows users compiling with C++17 or better may use `wchar_t` strings to support non-ASCII
|
||||
filenames: `padded_string::load(L"twitter.json")`.)
|
||||
|
||||
If you prefer not to create your own `ondemand::parser` instance, you can access
|
||||
a thread-local version by calling `ondemand::parser.get_parser()`.
|
||||
|
||||
@@ -448,7 +452,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
|
||||
When you are iterating through an object, you are advancing through its keys and values. You should not also access the object or other objects. E.g. within a loop over `myobject`, you should not be accessing `myobject`. The following is an anti-pattern: `for(auto value: myobject) {myobject["mykey"]}`.
|
||||
|
||||
You should never reset an object as you are iterating through it. The following is an anti-pattern: `for(auto value: myobject) {myobject.reset()}`.
|
||||
* **Array Index:** Because it is forward-only, you cannot look up an array element by index by index. Instead,
|
||||
* **Array Index:** Because it is forward-only, you cannot look up an array element by index. Instead,
|
||||
you should iterate through the array and keep an index yourself. Exceptionally, if need a single value
|
||||
out of the array, you may use an array access (e.g., `array[1]`). You should never reset an array as you are iterating through it. The following is an anti-pattern: `for(auto value: myarray) {myarray.reset()}`.
|
||||
* **Field Access:** To get the value of the "foo" field in an object, use `object["foo"]`. This will
|
||||
@@ -477,7 +481,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
|
||||
> unlike `key()`, it has to determine the location of the final quote character.
|
||||
>
|
||||
> ```cpp
|
||||
> auto json = R"({"k\u0065y": 1})"_padded;
|
||||
> auto json = R"({"k\u0065y": 1})"_padded; // R"( ... )" is a C++ raw string literal.
|
||||
> ondemand::parser parser;
|
||||
> auto doc = parser.iterate(json);
|
||||
> ondemand::object object = doc.get_object();
|
||||
@@ -502,7 +506,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
|
||||
>
|
||||
> ```cpp
|
||||
> ondemand::parser parser;
|
||||
> auto json = R"( { "x": 1, "y": 2 } )"_padded;
|
||||
> auto json = R"( { "x": 1, "y": 2 } )"_padded; // R"( ... )" is a C++ raw string literal.
|
||||
> auto doc = parser.iterate(json);
|
||||
> double y = doc.find_field("y"); // The cursor is now after the 2 (at })
|
||||
> double x = doc.find_field("x"); // This fails, because there are no more fields after "y"
|
||||
@@ -523,13 +527,13 @@ support for users who avoid exceptions. See [the simdjson error handling documen
|
||||
> auto silly_json = R"( { "test": "result" } )"_padded;
|
||||
> ondemand::document doc = parser.iterate(silly_json);
|
||||
> std::cout << simdjson::to_json_string(doc["test"]) << std::endl; // Requires simdjson 1.0 or better
|
||||
>````
|
||||
> ```
|
||||
> ```cpp
|
||||
> // retrieves an unescaped string value as a string_view instance
|
||||
> auto silly_json = R"( { "test": "result" } )"_padded;
|
||||
> ondemand::document doc = parser.iterate(silly_json);
|
||||
> std::cout << std::string_view(doc["test"]) << std::endl;
|
||||
>````
|
||||
> ```
|
||||
You can use `to_json_string` to efficiently extract components of a JSON document to reconstruct a new JSON document, as in the following example:
|
||||
> ```cpp
|
||||
> auto cars_json = R"( [
|
||||
@@ -558,7 +562,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
|
||||
> oss << "]";
|
||||
> auto json_string = oss.str();
|
||||
> // json_string == "[[ 40.1, 39.9, 37.7, 40.4 ],[ 30.1, 31.0, 28.6, 28.7 ]]"
|
||||
>````
|
||||
> ```
|
||||
* **Extracting Values (without exceptions):** You can use a variant usage of `get()` with error
|
||||
codes to avoid exceptions. You first declare the variable of the appropriate type (`double`,
|
||||
`uint64_t`, `int64_t`, `bool`, `ondemand::object` and `ondemand::array`) and pass it by reference
|
||||
|
||||
+83
-5
@@ -1,6 +1,7 @@
|
||||
# Parse json at compile time
|
||||
* [Introduction](#introduction)
|
||||
* [Example](#example)
|
||||
* [Concepts](#concepts)
|
||||
* [Loading from disk](#loading-from-disk)
|
||||
* [Limitations (compile-time errors)](#limitations-compile-time-errors)
|
||||
|
||||
@@ -53,15 +54,22 @@ Suppose you want to parse the following JSON document:
|
||||
}
|
||||
```
|
||||
|
||||
**Reminder**: In C++, `R"( )"` allows us to write multi-line strings with unescaped quotes.
|
||||
|
||||
|
||||
You can do so, at compile-time, as follows:
|
||||
|
||||
|
||||
```cpp
|
||||
constexpr auto cfg = simdjson::compile_time::parse_json<R"({
|
||||
constexpr auto cfg = R"(
|
||||
|
||||
{
|
||||
"port": 8080,
|
||||
"host": "localhost",
|
||||
"debug": true
|
||||
})">();
|
||||
}
|
||||
|
||||
)"_json;
|
||||
|
||||
// cfg.port == 8080
|
||||
// std::string_view(cfg.host) == "localhost"
|
||||
@@ -71,12 +79,16 @@ constexpr auto cfg = simdjson::compile_time::parse_json<R"({
|
||||
You can nest objects and arrays:
|
||||
|
||||
```cpp
|
||||
constexpr auto data = simdjson::compile_time::parse_json<R"({
|
||||
constexpr auto data = R"(
|
||||
|
||||
{
|
||||
"servers": [
|
||||
{"host": "s1", "port": 3000},
|
||||
{"host": "s2", "port": 3001}
|
||||
]
|
||||
})">();
|
||||
}
|
||||
|
||||
)"_json;
|
||||
|
||||
|
||||
// data.servers.size() == 2
|
||||
@@ -86,11 +98,77 @@ constexpr auto data = simdjson::compile_time::parse_json<R"({
|
||||
Top-level arrays are allowed:
|
||||
|
||||
```cpp
|
||||
constexpr auto arr = simdjson::compile_time::parse_json<R"([1, 2, 3])">();
|
||||
constexpr auto arr = R"(
|
||||
|
||||
[1, 2, 3]
|
||||
|
||||
)"_json;
|
||||
static_assert(arr.size() == 3);
|
||||
static_assert(arr[1] == 2);
|
||||
```
|
||||
|
||||
|
||||
## Concepts
|
||||
|
||||
Given that the parsed data is made of structures that depend on the JSON input, you might
|
||||
want to check that it conforms to your expectation. You can do so with concepts.
|
||||
|
||||
Let us consider this example:
|
||||
|
||||
```cpp
|
||||
constexpr auto config = R"(
|
||||
|
||||
[
|
||||
{ "name": "Alice", "age": 30 },
|
||||
{ "name": "Bob", "age": 25 },
|
||||
{ "name": "Charlie", "age": 35 }
|
||||
]
|
||||
|
||||
)"_json;
|
||||
```
|
||||
|
||||
You might want to ensure that the result is an array of persons. You can define your
|
||||
expection with concepts like so:
|
||||
|
||||
```cpp
|
||||
template <typename T>
|
||||
concept person = requires(T p) {
|
||||
std::string_view(p.name); // has name field convertible to string_view
|
||||
p.age; // has age field
|
||||
requires std::is_integral_v<decltype(p.age)>; // age is integral
|
||||
};
|
||||
|
||||
/**
|
||||
* Concept to validate that a type is an array of person objects
|
||||
*/
|
||||
template <typename T>
|
||||
concept array_of_person = requires(T arr) {
|
||||
arr.size(); // has size method
|
||||
arr[0]; // can access elements with []
|
||||
requires person<decltype(arr[0])>; // elements satisfy person concept
|
||||
};
|
||||
```
|
||||
|
||||
And then a simple static assert with `decltype` is sufficient to check that the expectation is met:
|
||||
|
||||
```cpp
|
||||
constexpr auto config = R"(
|
||||
|
||||
[
|
||||
{ "name": "Alice", "age": 30 },
|
||||
{ "name": "Bob", "age": 25 },
|
||||
{ "name": "Charlie", "age": 35 }
|
||||
]
|
||||
|
||||
)"_json;
|
||||
|
||||
|
||||
// Validate that the array satisfies the array_of_person concept
|
||||
static_assert(array_of_person<decltype(config)>);
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Loading from disk
|
||||
|
||||
In practice, you may have a JSON file, say `json_data` that you want to parse
|
||||
|
||||
@@ -40,6 +40,7 @@ struct User {
|
||||
std::vector<std::string> emails;
|
||||
};
|
||||
|
||||
// R"( ... )" is a C++ raw string literal.
|
||||
const padded_string json = R"({
|
||||
"name": "Alice",
|
||||
"age": 30,
|
||||
|
||||
+19
-1
@@ -54,6 +54,22 @@ dom::parser parser;
|
||||
dom::element doc = parser.parse("[1,2,3]"_padded); // parse a string, the _padded suffix creates a simdjson::padded_string instance
|
||||
```
|
||||
|
||||
You can also load a `padded_string` from a file.
|
||||
|
||||
|
||||
```cpp
|
||||
auto json = padded_string::load("twitter.json"); // load JSON file 'twitter.json'.
|
||||
dom::element doc = parser.parse(json);
|
||||
```
|
||||
|
||||
(Windows users compiling with C++17 or better may use `wchar_t` strings to support non-ASCII
|
||||
filenames: `padded_string::load(L"twitter.json")`.)
|
||||
|
||||
|
||||
(Windows users compiling with C++17 or better may use `wchar_t` strings to support non-ASCII
|
||||
filenames: `padded_string::load(L"twitter.json")`.)
|
||||
|
||||
|
||||
You can copy your data directly on a `simdjson::padded_string` as follows:
|
||||
|
||||
```cpp
|
||||
@@ -119,6 +135,7 @@ Once you have an element, you can navigate it with idiomatic C++ iterators, oper
|
||||
`dom::object` and `dom::array`) and pass it by reference to `get()` which gives you back an error code: e.g.,
|
||||
```cpp
|
||||
simdjson::error_code error;
|
||||
// _padded returns an simdjson::padded_string instance
|
||||
simdjson::padded_string numberstring = "1.2"_padded; // our JSON input ("1.2")
|
||||
simdjson::dom::parser parser;
|
||||
double value; // variable where we store the value to be parsed
|
||||
@@ -153,6 +170,7 @@ Once you have an element, you can navigate it with idiomatic C++ iterators, oper
|
||||
The following code illustrates all of the above:
|
||||
|
||||
```cpp
|
||||
// R"( ... )" is a C++ raw string literal.
|
||||
auto cars_json = R"( [
|
||||
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
|
||||
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
|
||||
@@ -825,7 +843,7 @@ memcpy(padded_json_copy.get(), json, json_len);
|
||||
memset(padded_json_copy.get() + json_len, 0, SIMDJSON_PADDING);
|
||||
simdjson::dom::parser parser;
|
||||
simdjson::dom::element element = parser.parse(padded_json_copy.get(), json_len, false);
|
||||
````
|
||||
```
|
||||
|
||||
Setting the `realloc_if_needed` parameter `false` in this manner may lead to better performance since copies are avoided, but it requires that the user takes more responsibilities: the simdjson library cannot verify that the input buffer was padded with SIMDJSON_PADDING extra bytes.
|
||||
|
||||
|
||||
+4
-2
@@ -8,7 +8,7 @@ library provides high-speed access to files or streams containing multiple small
|
||||
{"text":"a"}
|
||||
{"text":"b"}
|
||||
{"text":"c"}
|
||||
...
|
||||
"..."
|
||||
```
|
||||
... you want to read the entries (individual JSON documents) as quickly and as conveniently as possible. Importantly, the input might span several gigabytes, but you want to use a small (fixed) amount of memory. Ideally, you'd also like the parallelize the processing (using more than one core) to speed up the process.
|
||||
|
||||
@@ -141,7 +141,9 @@ API
|
||||
Example:
|
||||
|
||||
```cpp
|
||||
// R"( ... )" is a C++ raw string literal.
|
||||
auto json = R"({ "foo": 1 } { "foo": 2 } { "foo": 3 } )"_padded;
|
||||
// _padded returns an simdjson::padded_string instance
|
||||
ondemand::parser parser;
|
||||
ondemand::document_stream docs = parser.iterate_many(json);
|
||||
for (auto doc : docs) {
|
||||
@@ -401,4 +403,4 @@ Otherwise you may use this longer version for explicit handling of errors:
|
||||
}
|
||||
cars.push_back(c);
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
@@ -545,7 +545,7 @@ To help visualize the algorithm, we'll walk through the example C++ given at the
|
||||
"statuses": [
|
||||
{ "id": 1, "text": "first!", "user": { "screen_name": "lemire", "name": "Daniel" }, "retweet_count": 40 },
|
||||
{ "id": 2, "text": "second!", "user": { "screen_name": "jkeiser2", "name": "John" }, "retweet_count": 3 }
|
||||
^ (depth 3 - root > statuses > tweet)
|
||||
^ (depth 4 - root > statuses > tweet > field)
|
||||
],
|
||||
"search_metadata": { "count": 2 }
|
||||
}
|
||||
@@ -672,7 +672,9 @@ in production systems:
|
||||
|
||||
```cpp
|
||||
ondemand::parser parser;
|
||||
// R"( ... )" is a C++ raw string literal.
|
||||
const padded_string json = R"({ "parent": {"child1": {"name": "John"} , "child2": {"name": "Daniel"}} })"_padded;
|
||||
// _padded returns an simdjson padded_string instance
|
||||
auto doc = parser.iterate(json);
|
||||
ondemand::object parent = doc["parent"];
|
||||
// parent owns the focus
|
||||
|
||||
@@ -65,5 +65,11 @@ template <constevalutil::fixed_string json_str> consteval auto parse_json();
|
||||
} // namespace compile_time
|
||||
} // namespace simdjson
|
||||
|
||||
|
||||
template <simdjson::constevalutil::fixed_string str>
|
||||
consteval auto operator ""_json() {
|
||||
return simdjson::compile_time::parse_json<str>();
|
||||
}
|
||||
|
||||
#endif // SIMDJSON_STATIC_REFLECTION
|
||||
#endif // SIMDJSON_GENERIC_COMPILE_TIME_JSON_H
|
||||
|
||||
@@ -265,6 +265,8 @@ struct simdjson_result_base : protected std::pair<T, error_code> {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
}; // struct simdjson_result_base
|
||||
|
||||
} // namespace internal
|
||||
@@ -376,6 +378,8 @@ struct simdjson_result : public internal::simdjson_result_base<T> {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
}; // struct simdjson_result
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
|
||||
@@ -138,6 +138,9 @@ struct implementation_simdjson_result_base {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
|
||||
protected:
|
||||
/** users should never directly access first and second. **/
|
||||
T first{}; /** Users should never directly access 'first'. **/
|
||||
|
||||
@@ -167,7 +167,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
|
||||
#else
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
|
||||
@@ -205,7 +205,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
|
||||
#else
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
|
||||
|
||||
@@ -538,7 +538,7 @@ template <std::ranges::range R>
|
||||
simdjson_inline void string_builder::append(const R &range) noexcept {
|
||||
auto it = std::ranges::begin(range);
|
||||
auto end = std::ranges::end(range);
|
||||
if constexpr (concepts::is_pair<typename R::value_type>) {
|
||||
if constexpr (concepts::is_pair<std::ranges::range_value_t<R>>) {
|
||||
start_object();
|
||||
|
||||
if (it == end) {
|
||||
|
||||
@@ -53,7 +53,7 @@ extern SIMDJSON_DLLIMPORTEXPORT const double power_of_ten[];
|
||||
// The mantissa is truncated to 128 bits, and
|
||||
// never rounded up. Uses about 10KB.
|
||||
// We use the template trick to allow inclusion in multiple translation units.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
template <typename unused = void> struct powers_template {
|
||||
constexpr static uint64_t power_of_five_128[651*2]= {
|
||||
0xeef453d6923bd65a,0x113faa2906a13b3f,
|
||||
@@ -708,7 +708,7 @@ constexpr static uint64_t power_of_five_128[651*2]= {
|
||||
0xe3d8f9e563a198e5,0x58180fddd97723a6,
|
||||
0x8e679c2f5e44ff8f,0x570f09eaa7ea7648,};
|
||||
};
|
||||
#endif // SIMDJSON_CPLUSPLUS26
|
||||
#endif // SIMDJSON_STATIC_REFLECTION
|
||||
|
||||
extern SIMDJSON_DLLIMPORTEXPORT const uint64_t power_of_five_128[651*2];
|
||||
} // namespace internal
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "simdjson/padded_string_view-inl.h"
|
||||
|
||||
#include <climits>
|
||||
#include <cwchar>
|
||||
|
||||
namespace simdjson {
|
||||
namespace internal {
|
||||
@@ -185,6 +186,62 @@ inline simdjson_result<padded_string> padded_string::load(std::string_view filen
|
||||
return s;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && SIMDJSON_CPLUSPLUS17
|
||||
inline simdjson_result<padded_string> padded_string::load(std::wstring_view filename) noexcept {
|
||||
// Open the file using the wide characters
|
||||
SIMDJSON_PUSH_DISABLE_WARNINGS
|
||||
SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe
|
||||
std::FILE *fp = _wfopen(filename.data(), L"rb");
|
||||
SIMDJSON_POP_DISABLE_WARNINGS
|
||||
|
||||
if (fp == nullptr) {
|
||||
return IO_ERROR;
|
||||
}
|
||||
|
||||
// Get the file size
|
||||
int ret;
|
||||
#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS
|
||||
ret = _fseeki64(fp, 0, SEEK_END);
|
||||
#else
|
||||
ret = std::fseek(fp, 0, SEEK_END);
|
||||
#endif // _WIN64
|
||||
if(ret < 0) {
|
||||
std::fclose(fp);
|
||||
return IO_ERROR;
|
||||
}
|
||||
#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS
|
||||
__int64 llen = _ftelli64(fp);
|
||||
if(llen == -1L) {
|
||||
std::fclose(fp);
|
||||
return IO_ERROR;
|
||||
}
|
||||
#else
|
||||
long llen = std::ftell(fp);
|
||||
if((llen < 0) || (llen == LONG_MAX)) {
|
||||
std::fclose(fp);
|
||||
return IO_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Allocate the padded_string
|
||||
size_t len = static_cast<size_t>(llen);
|
||||
padded_string s(len);
|
||||
if (s.data() == nullptr) {
|
||||
std::fclose(fp);
|
||||
return MEMALLOC;
|
||||
}
|
||||
|
||||
// Read the padded_string
|
||||
std::rewind(fp);
|
||||
size_t bytes_read = std::fread(s.data(), 1, len, fp);
|
||||
if (std::fclose(fp) != 0 || bytes_read != len) {
|
||||
return IO_ERROR;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace simdjson
|
||||
|
||||
inline simdjson::padded_string operator ""_padded(const char *str, size_t len) {
|
||||
@@ -192,7 +249,7 @@ inline simdjson::padded_string operator ""_padded(const char *str, size_t len) {
|
||||
}
|
||||
#ifdef __cpp_char8_t
|
||||
inline simdjson::padded_string operator ""_padded(const char8_t *str, size_t len) {
|
||||
return simdjson::padded_string(reinterpret_cast<const char8_t *>(str), len);
|
||||
return simdjson::padded_string(reinterpret_cast<const char *>(str), len);
|
||||
}
|
||||
#endif
|
||||
#endif // SIMDJSON_PADDED_STRING_INL_H
|
||||
|
||||
@@ -127,6 +127,19 @@ struct padded_string final {
|
||||
**/
|
||||
inline static simdjson_result<padded_string> load(std::string_view path) noexcept;
|
||||
|
||||
#if defined(_WIN32) && SIMDJSON_CPLUSPLUS17
|
||||
/**
|
||||
* This function accepts a wide string path (UTF-16) and converts it to
|
||||
* UTF-8 before loading the file. This allows windows users to work
|
||||
* with unicode file paths without manually converting the paths everytime.
|
||||
*
|
||||
* @return IO_ERROR on error, including conversion failures.
|
||||
*
|
||||
* @param path the path to the file as a wide string.
|
||||
**/
|
||||
inline static simdjson_result<padded_string> load(std::wstring_view path) noexcept;
|
||||
#endif
|
||||
|
||||
private:
|
||||
padded_string &operator=(const padded_string &o) = delete;
|
||||
padded_string(const padded_string &o) = delete;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#define SIMDJSON_SIMDJSON_VERSION_H
|
||||
|
||||
/** The version of simdjson being used (major.minor.revision) */
|
||||
#define SIMDJSON_VERSION "4.2.0"
|
||||
#define SIMDJSON_VERSION "4.2.2"
|
||||
|
||||
namespace simdjson {
|
||||
enum {
|
||||
@@ -19,7 +19,7 @@ enum {
|
||||
/**
|
||||
* The revision (major.minor.REVISION) of simdjson being used.
|
||||
*/
|
||||
SIMDJSON_VERSION_REVISION = 0
|
||||
SIMDJSON_VERSION_REVISION = 2
|
||||
};
|
||||
} // namespace simdjson
|
||||
|
||||
|
||||
+47
-19
@@ -1,4 +1,4 @@
|
||||
/* auto-generated on 2025-11-02 11:53:56 -0500. version 4.2.0 Do not edit! */
|
||||
/* auto-generated on 2025-11-11 14:17:08 -0500. version 4.2.2 Do not edit! */
|
||||
/* including simdjson.cpp: */
|
||||
/* begin file simdjson.cpp */
|
||||
#define SIMDJSON_SRC_SIMDJSON_CPP
|
||||
@@ -2752,6 +2752,8 @@ struct simdjson_result_base : protected std::pair<T, error_code> {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
}; // struct simdjson_result_base
|
||||
|
||||
} // namespace internal
|
||||
@@ -2863,6 +2865,8 @@ struct simdjson_result : public internal::simdjson_result_base<T> {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
}; // struct simdjson_result
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
@@ -5357,7 +5361,7 @@ extern SIMDJSON_DLLIMPORTEXPORT const double power_of_ten[];
|
||||
// The mantissa is truncated to 128 bits, and
|
||||
// never rounded up. Uses about 10KB.
|
||||
// We use the template trick to allow inclusion in multiple translation units.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
template <typename unused = void> struct powers_template {
|
||||
constexpr static uint64_t power_of_five_128[651*2]= {
|
||||
0xeef453d6923bd65a,0x113faa2906a13b3f,
|
||||
@@ -6012,7 +6016,7 @@ constexpr static uint64_t power_of_five_128[651*2]= {
|
||||
0xe3d8f9e563a198e5,0x58180fddd97723a6,
|
||||
0x8e679c2f5e44ff8f,0x570f09eaa7ea7648,};
|
||||
};
|
||||
#endif // SIMDJSON_CPLUSPLUS26
|
||||
#endif // SIMDJSON_STATIC_REFLECTION
|
||||
|
||||
extern SIMDJSON_DLLIMPORTEXPORT const uint64_t power_of_five_128[651*2];
|
||||
} // namespace internal
|
||||
@@ -10105,6 +10109,9 @@ struct implementation_simdjson_result_base {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
|
||||
protected:
|
||||
/** users should never directly access first and second. **/
|
||||
T first{}; /** Users should never directly access 'first'. **/
|
||||
@@ -10287,7 +10294,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
|
||||
#else
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
|
||||
@@ -10325,7 +10332,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
|
||||
#else
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
|
||||
@@ -16600,6 +16607,9 @@ struct implementation_simdjson_result_base {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
|
||||
protected:
|
||||
/** users should never directly access first and second. **/
|
||||
T first{}; /** Users should never directly access 'first'. **/
|
||||
@@ -16782,7 +16792,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
|
||||
#else
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
|
||||
@@ -16820,7 +16830,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
|
||||
#else
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
|
||||
@@ -22950,6 +22960,9 @@ struct implementation_simdjson_result_base {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
|
||||
protected:
|
||||
/** users should never directly access first and second. **/
|
||||
T first{}; /** Users should never directly access 'first'. **/
|
||||
@@ -23132,7 +23145,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
|
||||
#else
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
|
||||
@@ -23170,7 +23183,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
|
||||
#else
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
|
||||
@@ -29457,6 +29470,9 @@ struct implementation_simdjson_result_base {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
|
||||
protected:
|
||||
/** users should never directly access first and second. **/
|
||||
T first{}; /** Users should never directly access 'first'. **/
|
||||
@@ -29639,7 +29655,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
|
||||
#else
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
|
||||
@@ -29677,7 +29693,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
|
||||
#else
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
|
||||
@@ -36323,6 +36339,9 @@ struct implementation_simdjson_result_base {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
|
||||
protected:
|
||||
/** users should never directly access first and second. **/
|
||||
T first{}; /** Users should never directly access 'first'. **/
|
||||
@@ -36505,7 +36524,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
|
||||
#else
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
|
||||
@@ -36543,7 +36562,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
|
||||
#else
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
|
||||
@@ -43011,6 +43030,9 @@ struct implementation_simdjson_result_base {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
|
||||
protected:
|
||||
/** users should never directly access first and second. **/
|
||||
T first{}; /** Users should never directly access 'first'. **/
|
||||
@@ -43193,7 +43215,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
|
||||
#else
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
|
||||
@@ -43231,7 +43253,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
|
||||
#else
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
|
||||
@@ -49145,6 +49167,9 @@ struct implementation_simdjson_result_base {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
|
||||
protected:
|
||||
/** users should never directly access first and second. **/
|
||||
T first{}; /** Users should never directly access 'first'. **/
|
||||
@@ -49327,7 +49352,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
|
||||
#else
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
|
||||
@@ -49365,7 +49390,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
|
||||
#else
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
|
||||
@@ -54871,6 +54896,9 @@ struct implementation_simdjson_result_base {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
|
||||
protected:
|
||||
/** users should never directly access first and second. **/
|
||||
T first{}; /** Users should never directly access 'first'. **/
|
||||
@@ -55053,7 +55081,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
|
||||
#else
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
|
||||
@@ -55091,7 +55119,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
|
||||
#else
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
|
||||
|
||||
+134
-30
@@ -1,4 +1,4 @@
|
||||
/* auto-generated on 2025-11-02 11:53:56 -0500. version 4.2.0 Do not edit! */
|
||||
/* auto-generated on 2025-11-11 14:17:08 -0500. version 4.2.2 Do not edit! */
|
||||
/* including simdjson.h: */
|
||||
/* begin file simdjson.h */
|
||||
#ifndef SIMDJSON_H
|
||||
@@ -2513,7 +2513,7 @@ namespace std {
|
||||
#define SIMDJSON_SIMDJSON_VERSION_H
|
||||
|
||||
/** The version of simdjson being used (major.minor.revision) */
|
||||
#define SIMDJSON_VERSION "4.2.0"
|
||||
#define SIMDJSON_VERSION "4.2.2"
|
||||
|
||||
namespace simdjson {
|
||||
enum {
|
||||
@@ -2528,7 +2528,7 @@ enum {
|
||||
/**
|
||||
* The revision (major.minor.REVISION) of simdjson being used.
|
||||
*/
|
||||
SIMDJSON_VERSION_REVISION = 0
|
||||
SIMDJSON_VERSION_REVISION = 2
|
||||
};
|
||||
} // namespace simdjson
|
||||
|
||||
@@ -2815,6 +2815,8 @@ struct simdjson_result_base : protected std::pair<T, error_code> {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
}; // struct simdjson_result_base
|
||||
|
||||
} // namespace internal
|
||||
@@ -2926,6 +2928,8 @@ struct simdjson_result : public internal::simdjson_result_base<T> {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
}; // struct simdjson_result
|
||||
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
@@ -4165,6 +4169,19 @@ struct padded_string final {
|
||||
**/
|
||||
inline static simdjson_result<padded_string> load(std::string_view path) noexcept;
|
||||
|
||||
#if defined(_WIN32) && SIMDJSON_CPLUSPLUS17
|
||||
/**
|
||||
* This function accepts a wide string path (UTF-16) and converts it to
|
||||
* UTF-8 before loading the file. This allows windows users to work
|
||||
* with unicode file paths without manually converting the paths everytime.
|
||||
*
|
||||
* @return IO_ERROR on error, including conversion failures.
|
||||
*
|
||||
* @param path the path to the file as a wide string.
|
||||
**/
|
||||
inline static simdjson_result<padded_string> load(std::wstring_view path) noexcept;
|
||||
#endif
|
||||
|
||||
private:
|
||||
padded_string &operator=(const padded_string &o) = delete;
|
||||
padded_string(const padded_string &o) = delete;
|
||||
@@ -4476,6 +4493,7 @@ inline padded_string_view pad_with_reserve(std::string& s) noexcept {
|
||||
/* end file simdjson/padded_string_view-inl.h */
|
||||
|
||||
#include <climits>
|
||||
#include <cwchar>
|
||||
|
||||
namespace simdjson {
|
||||
namespace internal {
|
||||
@@ -4653,6 +4671,62 @@ inline simdjson_result<padded_string> padded_string::load(std::string_view filen
|
||||
return s;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && SIMDJSON_CPLUSPLUS17
|
||||
inline simdjson_result<padded_string> padded_string::load(std::wstring_view filename) noexcept {
|
||||
// Open the file using the wide characters
|
||||
SIMDJSON_PUSH_DISABLE_WARNINGS
|
||||
SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe
|
||||
std::FILE *fp = _wfopen(filename.data(), L"rb");
|
||||
SIMDJSON_POP_DISABLE_WARNINGS
|
||||
|
||||
if (fp == nullptr) {
|
||||
return IO_ERROR;
|
||||
}
|
||||
|
||||
// Get the file size
|
||||
int ret;
|
||||
#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS
|
||||
ret = _fseeki64(fp, 0, SEEK_END);
|
||||
#else
|
||||
ret = std::fseek(fp, 0, SEEK_END);
|
||||
#endif // _WIN64
|
||||
if(ret < 0) {
|
||||
std::fclose(fp);
|
||||
return IO_ERROR;
|
||||
}
|
||||
#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS
|
||||
__int64 llen = _ftelli64(fp);
|
||||
if(llen == -1L) {
|
||||
std::fclose(fp);
|
||||
return IO_ERROR;
|
||||
}
|
||||
#else
|
||||
long llen = std::ftell(fp);
|
||||
if((llen < 0) || (llen == LONG_MAX)) {
|
||||
std::fclose(fp);
|
||||
return IO_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Allocate the padded_string
|
||||
size_t len = static_cast<size_t>(llen);
|
||||
padded_string s(len);
|
||||
if (s.data() == nullptr) {
|
||||
std::fclose(fp);
|
||||
return MEMALLOC;
|
||||
}
|
||||
|
||||
// Read the padded_string
|
||||
std::rewind(fp);
|
||||
size_t bytes_read = std::fread(s.data(), 1, len, fp);
|
||||
if (std::fclose(fp) != 0 || bytes_read != len) {
|
||||
return IO_ERROR;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace simdjson
|
||||
|
||||
inline simdjson::padded_string operator ""_padded(const char *str, size_t len) {
|
||||
@@ -4660,7 +4734,7 @@ inline simdjson::padded_string operator ""_padded(const char *str, size_t len) {
|
||||
}
|
||||
#ifdef __cpp_char8_t
|
||||
inline simdjson::padded_string operator ""_padded(const char8_t *str, size_t len) {
|
||||
return simdjson::padded_string(reinterpret_cast<const char8_t *>(str), len);
|
||||
return simdjson::padded_string(reinterpret_cast<const char *>(str), len);
|
||||
}
|
||||
#endif
|
||||
#endif // SIMDJSON_PADDED_STRING_INL_H
|
||||
@@ -10615,7 +10689,7 @@ extern SIMDJSON_DLLIMPORTEXPORT const double power_of_ten[];
|
||||
// The mantissa is truncated to 128 bits, and
|
||||
// never rounded up. Uses about 10KB.
|
||||
// We use the template trick to allow inclusion in multiple translation units.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
template <typename unused = void> struct powers_template {
|
||||
constexpr static uint64_t power_of_five_128[651*2]= {
|
||||
0xeef453d6923bd65a,0x113faa2906a13b3f,
|
||||
@@ -11270,7 +11344,7 @@ constexpr static uint64_t power_of_five_128[651*2]= {
|
||||
0xe3d8f9e563a198e5,0x58180fddd97723a6,
|
||||
0x8e679c2f5e44ff8f,0x570f09eaa7ea7648,};
|
||||
};
|
||||
#endif // SIMDJSON_CPLUSPLUS26
|
||||
#endif // SIMDJSON_STATIC_REFLECTION
|
||||
|
||||
extern SIMDJSON_DLLIMPORTEXPORT const uint64_t power_of_five_128[651*2];
|
||||
} // namespace internal
|
||||
@@ -12996,6 +13070,9 @@ struct implementation_simdjson_result_base {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
|
||||
protected:
|
||||
/** users should never directly access first and second. **/
|
||||
T first{}; /** Users should never directly access 'first'. **/
|
||||
@@ -13178,7 +13255,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
|
||||
#else
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
|
||||
@@ -13216,7 +13293,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
|
||||
#else
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
|
||||
@@ -15191,6 +15268,9 @@ struct implementation_simdjson_result_base {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
|
||||
protected:
|
||||
/** users should never directly access first and second. **/
|
||||
T first{}; /** Users should never directly access 'first'. **/
|
||||
@@ -15373,7 +15453,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
|
||||
#else
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
|
||||
@@ -15411,7 +15491,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
|
||||
#else
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
|
||||
@@ -17885,6 +17965,9 @@ struct implementation_simdjson_result_base {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
|
||||
protected:
|
||||
/** users should never directly access first and second. **/
|
||||
T first{}; /** Users should never directly access 'first'. **/
|
||||
@@ -18067,7 +18150,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
|
||||
#else
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
|
||||
@@ -18105,7 +18188,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
|
||||
#else
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
|
||||
@@ -20579,6 +20662,9 @@ struct implementation_simdjson_result_base {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
|
||||
protected:
|
||||
/** users should never directly access first and second. **/
|
||||
T first{}; /** Users should never directly access 'first'. **/
|
||||
@@ -20761,7 +20847,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
|
||||
#else
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
|
||||
@@ -20799,7 +20885,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
|
||||
#else
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
|
||||
@@ -23388,6 +23474,9 @@ struct implementation_simdjson_result_base {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
|
||||
protected:
|
||||
/** users should never directly access first and second. **/
|
||||
T first{}; /** Users should never directly access 'first'. **/
|
||||
@@ -23570,7 +23659,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
|
||||
#else
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
|
||||
@@ -23608,7 +23697,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
|
||||
#else
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
|
||||
@@ -26513,6 +26602,9 @@ struct implementation_simdjson_result_base {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
|
||||
protected:
|
||||
/** users should never directly access first and second. **/
|
||||
T first{}; /** Users should never directly access 'first'. **/
|
||||
@@ -26695,7 +26787,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
|
||||
#else
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
|
||||
@@ -26733,7 +26825,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
|
||||
#else
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
|
||||
@@ -29115,6 +29207,9 @@ struct implementation_simdjson_result_base {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
|
||||
protected:
|
||||
/** users should never directly access first and second. **/
|
||||
T first{}; /** Users should never directly access 'first'. **/
|
||||
@@ -29297,7 +29392,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
|
||||
#else
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
|
||||
@@ -29335,7 +29430,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
|
||||
#else
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
|
||||
@@ -31730,6 +31825,9 @@ struct implementation_simdjson_result_base {
|
||||
*/
|
||||
simdjson_inline T&& value_unsafe() && noexcept;
|
||||
|
||||
using value_type = T;
|
||||
using error_type = error_code;
|
||||
|
||||
protected:
|
||||
/** users should never directly access first and second. **/
|
||||
T first{}; /** Users should never directly access 'first'. **/
|
||||
@@ -31912,7 +32010,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
|
||||
#else
|
||||
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]);
|
||||
@@ -31950,7 +32048,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
|
||||
// with a returned value of type value128 with a "low component" corresponding to the
|
||||
// 64-bit least significant bits of the product and with a "high component" corresponding
|
||||
// to the 64-bit most significant bits of the product.
|
||||
#if SIMDJSON_CPLUSPLUS26
|
||||
#if SIMDJSON_STATIC_REFLECTION
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
|
||||
#else
|
||||
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
|
||||
@@ -46859,7 +46957,7 @@ template <std::ranges::range R>
|
||||
simdjson_inline void string_builder::append(const R &range) noexcept {
|
||||
auto it = std::ranges::begin(range);
|
||||
auto end = std::ranges::end(range);
|
||||
if constexpr (concepts::is_pair<typename R::value_type>) {
|
||||
if constexpr (concepts::is_pair<std::ranges::range_value_t<R>>) {
|
||||
start_object();
|
||||
|
||||
if (it == end) {
|
||||
@@ -61324,7 +61422,7 @@ template <std::ranges::range R>
|
||||
simdjson_inline void string_builder::append(const R &range) noexcept {
|
||||
auto it = std::ranges::begin(range);
|
||||
auto end = std::ranges::end(range);
|
||||
if constexpr (concepts::is_pair<typename R::value_type>) {
|
||||
if constexpr (concepts::is_pair<std::ranges::range_value_t<R>>) {
|
||||
start_object();
|
||||
|
||||
if (it == end) {
|
||||
@@ -76288,7 +76386,7 @@ template <std::ranges::range R>
|
||||
simdjson_inline void string_builder::append(const R &range) noexcept {
|
||||
auto it = std::ranges::begin(range);
|
||||
auto end = std::ranges::end(range);
|
||||
if constexpr (concepts::is_pair<typename R::value_type>) {
|
||||
if constexpr (concepts::is_pair<std::ranges::range_value_t<R>>) {
|
||||
start_object();
|
||||
|
||||
if (it == end) {
|
||||
@@ -91252,7 +91350,7 @@ template <std::ranges::range R>
|
||||
simdjson_inline void string_builder::append(const R &range) noexcept {
|
||||
auto it = std::ranges::begin(range);
|
||||
auto end = std::ranges::end(range);
|
||||
if constexpr (concepts::is_pair<typename R::value_type>) {
|
||||
if constexpr (concepts::is_pair<std::ranges::range_value_t<R>>) {
|
||||
start_object();
|
||||
|
||||
if (it == end) {
|
||||
@@ -106331,7 +106429,7 @@ template <std::ranges::range R>
|
||||
simdjson_inline void string_builder::append(const R &range) noexcept {
|
||||
auto it = std::ranges::begin(range);
|
||||
auto end = std::ranges::end(range);
|
||||
if constexpr (concepts::is_pair<typename R::value_type>) {
|
||||
if constexpr (concepts::is_pair<std::ranges::range_value_t<R>>) {
|
||||
start_object();
|
||||
|
||||
if (it == end) {
|
||||
@@ -121726,7 +121824,7 @@ template <std::ranges::range R>
|
||||
simdjson_inline void string_builder::append(const R &range) noexcept {
|
||||
auto it = std::ranges::begin(range);
|
||||
auto end = std::ranges::end(range);
|
||||
if constexpr (concepts::is_pair<typename R::value_type>) {
|
||||
if constexpr (concepts::is_pair<std::ranges::range_value_t<R>>) {
|
||||
start_object();
|
||||
|
||||
if (it == end) {
|
||||
@@ -136598,7 +136696,7 @@ template <std::ranges::range R>
|
||||
simdjson_inline void string_builder::append(const R &range) noexcept {
|
||||
auto it = std::ranges::begin(range);
|
||||
auto end = std::ranges::end(range);
|
||||
if constexpr (concepts::is_pair<typename R::value_type>) {
|
||||
if constexpr (concepts::is_pair<std::ranges::range_value_t<R>>) {
|
||||
start_object();
|
||||
|
||||
if (it == end) {
|
||||
@@ -151483,7 +151581,7 @@ template <std::ranges::range R>
|
||||
simdjson_inline void string_builder::append(const R &range) noexcept {
|
||||
auto it = std::ranges::begin(range);
|
||||
auto end = std::ranges::end(range);
|
||||
if constexpr (concepts::is_pair<typename R::value_type>) {
|
||||
if constexpr (concepts::is_pair<std::ranges::range_value_t<R>>) {
|
||||
start_object();
|
||||
|
||||
if (it == end) {
|
||||
@@ -153374,6 +153472,12 @@ template <constevalutil::fixed_string json_str> consteval auto parse_json();
|
||||
} // namespace compile_time
|
||||
} // namespace simdjson
|
||||
|
||||
|
||||
template <simdjson::constevalutil::fixed_string str>
|
||||
consteval auto operator ""_json() {
|
||||
return simdjson::compile_time::parse_json<str>();
|
||||
}
|
||||
|
||||
#endif // SIMDJSON_STATIC_REFLECTION
|
||||
#endif // SIMDJSON_GENERIC_COMPILE_TIME_JSON_H
|
||||
/* end file simdjson/compile_time_json.h */
|
||||
|
||||
Binary file not shown.
@@ -4,6 +4,10 @@
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#if SIMDJSON_SUPPORTS_RANGES
|
||||
#include <ranges>
|
||||
#endif
|
||||
|
||||
using namespace simdjson;
|
||||
|
||||
struct Car {
|
||||
@@ -517,6 +521,24 @@ bool map_test() {
|
||||
ASSERT_EQUAL(s, "{\"key1\":1.0,\"key2\":1.0}");
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
bool ranges_test() {
|
||||
TEST_START();
|
||||
struct Foo {
|
||||
int a;
|
||||
float b;
|
||||
};
|
||||
std::vector<Foo> c = {{1, 2.0f}, {3, 4.0f}, {5, 6.0f}, {7, 8.0f}};
|
||||
simdjson::builder::string_builder sb;
|
||||
sb.append(c | std::views::transform(&Foo::b));
|
||||
std::string_view p;
|
||||
auto result = sb.view().get(p);
|
||||
ASSERT_SUCCESS(result);
|
||||
ASSERT_EQUAL(p, "[2.0,4.0,6.0,8.0]");
|
||||
std::string s;
|
||||
ASSERT_SUCCESS(simdjson::to_json(c | std::views::transform(&Foo::b)).get(s));
|
||||
ASSERT_EQUAL(s, "[2.0,4.0,6.0,8.0]");
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
bool double_double_test() {
|
||||
TEST_START();
|
||||
std::vector<std::vector<double>> c = {{1.0, 2.0}, {3.0, 4.0}};
|
||||
@@ -586,8 +608,9 @@ bool run() {
|
||||
car_test_exception() && string_convertion_except() &&
|
||||
#endif
|
||||
#if SIMDJSON_SUPPORTS_RANGES && SIMDJSON_SUPPORTS_CONCEPTS
|
||||
map_test() && double_double_test() && double_double_test_to_string() &&
|
||||
car_test_simple() && car_test_simple_complete() &&
|
||||
map_test() && ranges_test() && double_double_test() &&
|
||||
double_double_test_to_string() && car_test_simple() &&
|
||||
car_test_simple_complete() &&
|
||||
#if SIMDJSON_EXCEPTIONS
|
||||
car_test_simple_complete_exceptions() &&
|
||||
#endif
|
||||
|
||||
+6
-6
@@ -87,16 +87,16 @@ bool cast_tester<T>::test_get_error(simdjson_result<element> element, error_code
|
||||
|
||||
template<typename T>
|
||||
bool cast_tester<T>::test_get_t(element element, T expected) {
|
||||
auto actual = element.get<T>();
|
||||
ASSERT_SUCCESS(actual.error());
|
||||
return assert_equal(actual.value_unsafe(), expected);
|
||||
T value;
|
||||
ASSERT_SUCCESS(element.get<T>().get(value));
|
||||
return assert_equal(value, expected);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool cast_tester<T>::test_get_t(simdjson_result<element> element, T expected) {
|
||||
auto actual = element.get<T>();
|
||||
ASSERT_SUCCESS(actual.error());
|
||||
return assert_equal(actual.value_unsafe(), expected);
|
||||
T value;
|
||||
ASSERT_SUCCESS(element.get<T>().get(value));
|
||||
return assert_equal(value, expected);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
#include <print>
|
||||
|
||||
using namespace simdjson;
|
||||
using namespace std::string_view_literals;
|
||||
using namespace simdjson;
|
||||
|
||||
namespace compile_time_json_tests {
|
||||
/**
|
||||
@@ -479,6 +479,216 @@ bool array_of_objects() {
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
|
||||
bool test_complex_mixed_str() {
|
||||
TEST_START();
|
||||
auto f= "fds"_padded;
|
||||
|
||||
constexpr auto config = R"(
|
||||
{
|
||||
"app": "myapp",
|
||||
"version": 1.0,
|
||||
"config": {
|
||||
"ports": [8080, 8081, 8082],
|
||||
"enabled": true
|
||||
},
|
||||
"servers": [
|
||||
{"host": "server1", "port": 3000},
|
||||
{"host": "server2", "port": 3001}
|
||||
]
|
||||
}
|
||||
|
||||
)"_json;
|
||||
|
||||
static_assert(std::string_view(config.app) == "myapp");
|
||||
static_assert(config.version == 1.0);
|
||||
static_assert(config.config.ports[0] == 8080);
|
||||
static_assert(config.config.enabled == true);
|
||||
static_assert(std::string_view(config.servers[0].host) == "server1");
|
||||
static_assert(config.servers[1].port == 3001);
|
||||
|
||||
ASSERT_EQUAL(std::string_view(config.app), "myapp"sv);
|
||||
ASSERT_EQUAL(config.config.ports[0], 8080);
|
||||
ASSERT_EQUAL(std::string_view(config.servers[0].host), "server1"sv);
|
||||
ASSERT_EQUAL(config.servers[1].port, 3001);
|
||||
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: User config example - basic object with primitives
|
||||
*/
|
||||
bool test_user_config_example() {
|
||||
TEST_START();
|
||||
|
||||
constexpr auto cfg = R"(
|
||||
|
||||
{
|
||||
"port": 8080,
|
||||
"host": "localhost",
|
||||
"debug": true
|
||||
}
|
||||
|
||||
)"_json;
|
||||
|
||||
static_assert(cfg.port == 8080);
|
||||
static_assert(std::string_view(cfg.host) == "localhost");
|
||||
static_assert(cfg.debug == true);
|
||||
|
||||
ASSERT_EQUAL(cfg.port, 8080);
|
||||
ASSERT_EQUAL(std::string_view(cfg.host), "localhost"sv);
|
||||
ASSERT_TRUE(cfg.debug);
|
||||
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Nested objects and arrays example
|
||||
*/
|
||||
bool test_nested_servers_example() {
|
||||
TEST_START();
|
||||
|
||||
constexpr auto data = R"(
|
||||
|
||||
{
|
||||
"servers": [
|
||||
{"host": "s1", "port": 3000},
|
||||
{"host": "s2", "port": 3001}
|
||||
]
|
||||
}
|
||||
|
||||
)"_json;
|
||||
|
||||
static_assert(data.servers.size() == 2);
|
||||
static_assert(std::string_view(data.servers[0].host) == "s1");
|
||||
static_assert(data.servers[0].port == 3000);
|
||||
static_assert(std::string_view(data.servers[1].host) == "s2");
|
||||
static_assert(data.servers[1].port == 3001);
|
||||
|
||||
ASSERT_EQUAL(data.servers.size(), 2);
|
||||
ASSERT_EQUAL(std::string_view(data.servers[0].host), "s1"sv);
|
||||
ASSERT_EQUAL(data.servers[0].port, 3000);
|
||||
ASSERT_EQUAL(std::string_view(data.servers[1].host), "s2"sv);
|
||||
ASSERT_EQUAL(data.servers[1].port, 3001);
|
||||
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Top-level array example
|
||||
*/
|
||||
bool test_top_level_array_example() {
|
||||
TEST_START();
|
||||
|
||||
constexpr auto arr = R"(
|
||||
[1, 2, 3]
|
||||
)"_json;
|
||||
|
||||
static_assert(arr.size() == 3);
|
||||
static_assert(arr[0] == 1);
|
||||
static_assert(arr[1] == 2);
|
||||
static_assert(arr[2] == 3);
|
||||
|
||||
ASSERT_EQUAL(arr.size(), 3);
|
||||
ASSERT_EQUAL(arr[0], 1);
|
||||
ASSERT_EQUAL(arr[1], 2);
|
||||
ASSERT_EQUAL(arr[2], 3);
|
||||
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
/**
|
||||
* Concept to validate that a type represents a person with name and age
|
||||
*/
|
||||
template <typename T>
|
||||
concept person = requires(T p) {
|
||||
std::string_view(p.name); // has name field convertible to string_view
|
||||
p.age; // has age field
|
||||
requires std::is_integral_v<decltype(p.age)>; // age is integral
|
||||
};
|
||||
|
||||
/**
|
||||
* Concept to validate that a type is an array of person objects
|
||||
*/
|
||||
template <typename T>
|
||||
concept array_of_person = requires(T arr) {
|
||||
arr.size(); // has size method
|
||||
arr[0]; // can access elements with []
|
||||
requires person<decltype(arr[0])>; // elements satisfy person concept
|
||||
};
|
||||
|
||||
/**
|
||||
* Test: Array of objects with concept validation
|
||||
*/
|
||||
bool test_array_of_objects_with_concept() {
|
||||
TEST_START();
|
||||
|
||||
constexpr auto config = R"(
|
||||
|
||||
[
|
||||
{ "name": "Alice", "age": 30 },
|
||||
{ "name": "Bob", "age": 25 },
|
||||
{ "name": "Charlie", "age": 35 }
|
||||
]
|
||||
|
||||
)"_json;
|
||||
|
||||
std::print("Array size: {}\n", config.size());
|
||||
|
||||
static_assert(config.size() == 3);
|
||||
|
||||
// Validate that the array satisfies the array_of_person concept
|
||||
static_assert(array_of_person<decltype(config)>);
|
||||
|
||||
|
||||
// Test the actual values
|
||||
static_assert(std::string_view(config[0].name) == "Alice");
|
||||
static_assert(config[0].age == 30);
|
||||
static_assert(std::string_view(config[1].name) == "Bob");
|
||||
static_assert(config[1].age == 25);
|
||||
static_assert(std::string_view(config[2].name) == "Charlie");
|
||||
static_assert(config[2].age == 35);
|
||||
|
||||
// Runtime assertions
|
||||
ASSERT_EQUAL(config.size(), 3);
|
||||
ASSERT_EQUAL(std::string_view(config[0].name), "Alice"sv);
|
||||
ASSERT_EQUAL(config[0].age, 30);
|
||||
ASSERT_EQUAL(std::string_view(config[1].name), "Bob"sv);
|
||||
ASSERT_EQUAL(config[1].age, 25);
|
||||
ASSERT_EQUAL(std::string_view(config[2].name), "Charlie"sv);
|
||||
ASSERT_EQUAL(config[2].age, 35);
|
||||
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: #embed support for external JSON files (C++26)
|
||||
*/
|
||||
bool test_embed_twitter_json() {
|
||||
TEST_START();
|
||||
|
||||
// C++26 #embed allows embedding files directly into the binary at compile time
|
||||
// This creates a const char array with the file contents plus null terminator
|
||||
constexpr const char twitter_json[] = {
|
||||
#embed TWITTER_JSON
|
||||
, 0
|
||||
};
|
||||
|
||||
// Parse the embedded JSON at compile time
|
||||
constexpr auto parsed_twitter = simdjson::compile_time::parse_json<twitter_json>();
|
||||
|
||||
// Verify the structure - twitter.json should have a "statuses" array
|
||||
static_assert(parsed_twitter.statuses.size() > 0);
|
||||
|
||||
// Runtime verification
|
||||
ASSERT_TRUE(parsed_twitter.statuses.size() > 0);
|
||||
|
||||
std::cout << "Successfully parsed embedded twitter.json with "
|
||||
<< parsed_twitter.statuses.size() << " statuses" << std::endl;
|
||||
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
bool run() {
|
||||
return test_basic_object() &&
|
||||
test_nested_objects() &&
|
||||
@@ -498,7 +708,13 @@ bool run() {
|
||||
test_simple_object_str_with_obj() &&
|
||||
test_empty_arrays() &&
|
||||
simple_array() &&
|
||||
array_of_objects();
|
||||
test_complex_mixed_str() &&
|
||||
array_of_objects() &&
|
||||
test_user_config_example() &&
|
||||
test_nested_servers_example() &&
|
||||
test_top_level_array_example() &&
|
||||
test_array_of_objects_with_concept() &&
|
||||
test_embed_twitter_json();
|
||||
}
|
||||
|
||||
} // namespace compile_time_json_tests
|
||||
|
||||
Reference in New Issue
Block a user