Compare commits

...

11 Commits

Author SHA1 Message Date
Daniel Lemire b1c31b428d update 2025-11-11 14:21:04 -05:00
Daniel Lemire 56ac56ba32 Merge branch 'master' of github.com:simdjson/simdjson 2025-11-11 14:17:08 -05:00
Muhammad Rizal Nurromdhoni 19549c60ec string_builder range-based append fix (#2544)
* Use std::ranges::range_value_t on range

* Add ranges test
2025-11-11 14:15:00 -05:00
Daniel Lemire 16e99f229b Update iterate_many.md for clarity on JSON processing
Clarified the example JSON format and emphasized the need for efficient processing.
2025-11-10 13:49:13 -05:00
Liqiang TAO 21342a4142 Fix some wrong content in doc (#2542) 2025-11-10 11:24:38 -05:00
Daniel Lemire d0e841d3e9 Release Candidate 4.2.2 (#2539)
* adding documentation.

* release candidate
2025-11-06 12:00:21 -05:00
Daniel Lemire a962652ec3 adding documentation. 2025-11-05 11:42:38 -05:00
hiteshmk05 77d73b068a add: windows wstring support for padded_str (#2537)
* add: windows wstring support for padded_str

* add: padded_string::load for wstring windows

* fix: extra space

* change: file path
2025-11-05 11:29:30 -05:00
Daniel Lemire 19ff7a572d adding concept examples to the compile-time JSON. (#2538) 2025-11-04 15:06:40 -05:00
Daniel Lemire 235dbc5369 4.2.1 2025-11-03 11:04:23 -05:00
Daniel Lemire 2b9c8977af using _json for compile-time JSON strings. (#2536) 2025-11-03 11:03:21 -05:00
23 changed files with 643 additions and 84 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14)
project( project(
simdjson simdjson
# The version number is modified by tools/release.py # The version number is modified by tools/release.py
VERSION 4.2.0 VERSION 4.2.2
DESCRIPTION "Parsing gigabytes of JSON per second" DESCRIPTION "Parsing gigabytes of JSON per second"
HOMEPAGE_URL "https://simdjson.org/" HOMEPAGE_URL "https://simdjson.org/"
LANGUAGES CXX C LANGUAGES CXX C
+1 -1
View File
@@ -38,7 +38,7 @@ PROJECT_NAME = simdjson
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # 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 # 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 # for a project that appears at the top of each page and should give viewer a
+10 -6
View File
@@ -1,6 +1,7 @@
The Basics The Basics
========== ==========
An overview of what you need to know to use simdjson to parse JSON documents, with examples. 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 [Our documentation regarding the generation (serialization) of JSON documents is in a
separate document](https://github.com/simdjson/simdjson/blob/master/doc/builder.md). 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 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 If you prefer not to create your own `ondemand::parser` instance, you can access
a thread-local version by calling `ondemand::parser.get_parser()`. 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"]}`. 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()}`. 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 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()}`. 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 * **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. > unlike `key()`, it has to determine the location of the final quote character.
> >
> ```cpp > ```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; > ondemand::parser parser;
> auto doc = parser.iterate(json); > auto doc = parser.iterate(json);
> ondemand::object object = doc.get_object(); > ondemand::object object = doc.get_object();
@@ -502,7 +506,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
> >
> ```cpp > ```cpp
> ondemand::parser parser; > 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); > auto doc = parser.iterate(json);
> double y = doc.find_field("y"); // The cursor is now after the 2 (at }) > 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" > 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; > auto silly_json = R"( { "test": "result" } )"_padded;
> ondemand::document doc = parser.iterate(silly_json); > ondemand::document doc = parser.iterate(silly_json);
> std::cout << simdjson::to_json_string(doc["test"]) << std::endl; // Requires simdjson 1.0 or better > std::cout << simdjson::to_json_string(doc["test"]) << std::endl; // Requires simdjson 1.0 or better
>```` > ```
> ```cpp > ```cpp
> // retrieves an unescaped string value as a string_view instance > // retrieves an unescaped string value as a string_view instance
> auto silly_json = R"( { "test": "result" } )"_padded; > auto silly_json = R"( { "test": "result" } )"_padded;
> ondemand::document doc = parser.iterate(silly_json); > ondemand::document doc = parser.iterate(silly_json);
> std::cout << std::string_view(doc["test"]) << std::endl; > 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: 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 > ```cpp
> auto cars_json = R"( [ > auto cars_json = R"( [
@@ -558,7 +562,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
> oss << "]"; > oss << "]";
> auto json_string = oss.str(); > auto json_string = oss.str();
> // json_string == "[[ 40.1, 39.9, 37.7, 40.4 ],[ 30.1, 31.0, 28.6, 28.7 ]]" > // 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 * **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`, 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 `uint64_t`, `int64_t`, `bool`, `ondemand::object` and `ondemand::array`) and pass it by reference
+83 -5
View File
@@ -1,6 +1,7 @@
# Parse json at compile time # Parse json at compile time
* [Introduction](#introduction) * [Introduction](#introduction)
* [Example](#example) * [Example](#example)
* [Concepts](#concepts)
* [Loading from disk](#loading-from-disk) * [Loading from disk](#loading-from-disk)
* [Limitations (compile-time errors)](#limitations-compile-time-errors) * [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: You can do so, at compile-time, as follows:
```cpp ```cpp
constexpr auto cfg = simdjson::compile_time::parse_json<R"({ constexpr auto cfg = R"(
{
"port": 8080, "port": 8080,
"host": "localhost", "host": "localhost",
"debug": true "debug": true
})">(); }
)"_json;
// cfg.port == 8080 // cfg.port == 8080
// std::string_view(cfg.host) == "localhost" // 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: You can nest objects and arrays:
```cpp ```cpp
constexpr auto data = simdjson::compile_time::parse_json<R"({ constexpr auto data = R"(
{
"servers": [ "servers": [
{"host": "s1", "port": 3000}, {"host": "s1", "port": 3000},
{"host": "s2", "port": 3001} {"host": "s2", "port": 3001}
] ]
})">(); }
)"_json;
// data.servers.size() == 2 // data.servers.size() == 2
@@ -86,11 +98,77 @@ constexpr auto data = simdjson::compile_time::parse_json<R"({
Top-level arrays are allowed: Top-level arrays are allowed:
```cpp ```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.size() == 3);
static_assert(arr[1] == 2); 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 ## Loading from disk
In practice, you may have a JSON file, say `json_data` that you want to parse In practice, you may have a JSON file, say `json_data` that you want to parse
+1
View File
@@ -40,6 +40,7 @@ struct User {
std::vector<std::string> emails; std::vector<std::string> emails;
}; };
// R"( ... )" is a C++ raw string literal.
const padded_string json = R"({ const padded_string json = R"({
"name": "Alice", "name": "Alice",
"age": 30, "age": 30,
+19 -1
View File
@@ -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 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: You can copy your data directly on a `simdjson::padded_string` as follows:
```cpp ```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., `dom::object` and `dom::array`) and pass it by reference to `get()` which gives you back an error code: e.g.,
```cpp ```cpp
simdjson::error_code error; simdjson::error_code error;
// _padded returns an simdjson::padded_string instance
simdjson::padded_string numberstring = "1.2"_padded; // our JSON input ("1.2") simdjson::padded_string numberstring = "1.2"_padded; // our JSON input ("1.2")
simdjson::dom::parser parser; simdjson::dom::parser parser;
double value; // variable where we store the value to be parsed 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: The following code illustrates all of the above:
```cpp ```cpp
// R"( ... )" is a C++ raw string literal.
auto cars_json = R"( [ auto cars_json = R"( [
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] }, { "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 ] }, { "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); memset(padded_json_copy.get() + json_len, 0, SIMDJSON_PADDING);
simdjson::dom::parser parser; simdjson::dom::parser parser;
simdjson::dom::element element = parser.parse(padded_json_copy.get(), json_len, false); 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. 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
View File
@@ -8,7 +8,7 @@ library provides high-speed access to files or streams containing multiple small
{"text":"a"} {"text":"a"}
{"text":"b"} {"text":"b"}
{"text":"c"} {"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. ... 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: Example:
```cpp ```cpp
// R"( ... )" is a C++ raw string literal.
auto json = R"({ "foo": 1 } { "foo": 2 } { "foo": 3 } )"_padded; auto json = R"({ "foo": 1 } { "foo": 2 } { "foo": 3 } )"_padded;
// _padded returns an simdjson::padded_string instance
ondemand::parser parser; ondemand::parser parser;
ondemand::document_stream docs = parser.iterate_many(json); ondemand::document_stream docs = parser.iterate_many(json);
for (auto doc : docs) { for (auto doc : docs) {
@@ -401,4 +403,4 @@ Otherwise you may use this longer version for explicit handling of errors:
} }
cars.push_back(c); cars.push_back(c);
} }
``` ```
+3 -1
View File
@@ -545,7 +545,7 @@ To help visualize the algorithm, we'll walk through the example C++ given at the
"statuses": [ "statuses": [
{ "id": 1, "text": "first!", "user": { "screen_name": "lemire", "name": "Daniel" }, "retweet_count": 40 }, { "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 } { "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 } "search_metadata": { "count": 2 }
} }
@@ -672,7 +672,9 @@ in production systems:
```cpp ```cpp
ondemand::parser parser; ondemand::parser parser;
// R"( ... )" is a C++ raw string literal.
const padded_string json = R"({ "parent": {"child1": {"name": "John"} , "child2": {"name": "Daniel"}} })"_padded; 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); auto doc = parser.iterate(json);
ondemand::object parent = doc["parent"]; ondemand::object parent = doc["parent"];
// parent owns the focus // parent owns the focus
+6
View File
@@ -65,5 +65,11 @@ template <constevalutil::fixed_string json_str> consteval auto parse_json();
} // namespace compile_time } // namespace compile_time
} // namespace simdjson } // 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_STATIC_REFLECTION
#endif // SIMDJSON_GENERIC_COMPILE_TIME_JSON_H #endif // SIMDJSON_GENERIC_COMPILE_TIME_JSON_H
+4
View File
@@ -265,6 +265,8 @@ struct simdjson_result_base : protected std::pair<T, error_code> {
*/ */
simdjson_inline T&& value_unsafe() && noexcept; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
}; // struct simdjson_result_base }; // struct simdjson_result_base
} // namespace internal } // namespace internal
@@ -376,6 +378,8 @@ struct simdjson_result : public internal::simdjson_result_base<T> {
*/ */
simdjson_inline T&& value_unsafe() && noexcept; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
}; // struct simdjson_result }; // struct simdjson_result
#if SIMDJSON_EXCEPTIONS #if SIMDJSON_EXCEPTIONS
@@ -138,6 +138,9 @@ struct implementation_simdjson_result_base {
*/ */
simdjson_inline T&& value_unsafe() && noexcept; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
protected: protected:
/** users should never directly access first and second. **/ /** users should never directly access first and second. **/
T first{}; /** Users should never directly access 'first'. **/ T first{}; /** Users should never directly access 'first'. **/
+2 -2
View File
@@ -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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
#else #else
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
#else #else
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); 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 { simdjson_inline void string_builder::append(const R &range) noexcept {
auto it = std::ranges::begin(range); auto it = std::ranges::begin(range);
auto end = std::ranges::end(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(); start_object();
if (it == end) { if (it == end) {
@@ -53,7 +53,7 @@ extern SIMDJSON_DLLIMPORTEXPORT const double power_of_ten[];
// The mantissa is truncated to 128 bits, and // The mantissa is truncated to 128 bits, and
// never rounded up. Uses about 10KB. // never rounded up. Uses about 10KB.
// We use the template trick to allow inclusion in multiple translation units. // 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 { template <typename unused = void> struct powers_template {
constexpr static uint64_t power_of_five_128[651*2]= { constexpr static uint64_t power_of_five_128[651*2]= {
0xeef453d6923bd65a,0x113faa2906a13b3f, 0xeef453d6923bd65a,0x113faa2906a13b3f,
@@ -708,7 +708,7 @@ constexpr static uint64_t power_of_five_128[651*2]= {
0xe3d8f9e563a198e5,0x58180fddd97723a6, 0xe3d8f9e563a198e5,0x58180fddd97723a6,
0x8e679c2f5e44ff8f,0x570f09eaa7ea7648,}; 0x8e679c2f5e44ff8f,0x570f09eaa7ea7648,};
}; };
#endif // SIMDJSON_CPLUSPLUS26 #endif // SIMDJSON_STATIC_REFLECTION
extern SIMDJSON_DLLIMPORTEXPORT const uint64_t power_of_five_128[651*2]; extern SIMDJSON_DLLIMPORTEXPORT const uint64_t power_of_five_128[651*2];
} // namespace internal } // namespace internal
+58 -1
View File
@@ -8,6 +8,7 @@
#include "simdjson/padded_string_view-inl.h" #include "simdjson/padded_string_view-inl.h"
#include <climits> #include <climits>
#include <cwchar>
namespace simdjson { namespace simdjson {
namespace internal { namespace internal {
@@ -185,6 +186,62 @@ inline simdjson_result<padded_string> padded_string::load(std::string_view filen
return s; 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 } // namespace simdjson
inline simdjson::padded_string operator ""_padded(const char *str, size_t len) { 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 #ifdef __cpp_char8_t
inline simdjson::padded_string operator ""_padded(const char8_t *str, size_t len) { 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
#endif // SIMDJSON_PADDED_STRING_INL_H #endif // SIMDJSON_PADDED_STRING_INL_H
+13
View File
@@ -127,6 +127,19 @@ struct padded_string final {
**/ **/
inline static simdjson_result<padded_string> load(std::string_view path) noexcept; 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: private:
padded_string &operator=(const padded_string &o) = delete; padded_string &operator=(const padded_string &o) = delete;
padded_string(const padded_string &o) = delete; padded_string(const padded_string &o) = delete;
+2 -2
View File
@@ -4,7 +4,7 @@
#define SIMDJSON_SIMDJSON_VERSION_H #define SIMDJSON_SIMDJSON_VERSION_H
/** The version of simdjson being used (major.minor.revision) */ /** The version of simdjson being used (major.minor.revision) */
#define SIMDJSON_VERSION "4.2.0" #define SIMDJSON_VERSION "4.2.2"
namespace simdjson { namespace simdjson {
enum { enum {
@@ -19,7 +19,7 @@ enum {
/** /**
* The revision (major.minor.REVISION) of simdjson being used. * The revision (major.minor.REVISION) of simdjson being used.
*/ */
SIMDJSON_VERSION_REVISION = 0 SIMDJSON_VERSION_REVISION = 2
}; };
} // namespace simdjson } // namespace simdjson
+47 -19
View File
@@ -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: */ /* including simdjson.cpp: */
/* begin file simdjson.cpp */ /* begin file simdjson.cpp */
#define SIMDJSON_SRC_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; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
}; // struct simdjson_result_base }; // struct simdjson_result_base
} // namespace internal } // namespace internal
@@ -2863,6 +2865,8 @@ struct simdjson_result : public internal::simdjson_result_base<T> {
*/ */
simdjson_inline T&& value_unsafe() && noexcept; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
}; // struct simdjson_result }; // struct simdjson_result
#if SIMDJSON_EXCEPTIONS #if SIMDJSON_EXCEPTIONS
@@ -5357,7 +5361,7 @@ extern SIMDJSON_DLLIMPORTEXPORT const double power_of_ten[];
// The mantissa is truncated to 128 bits, and // The mantissa is truncated to 128 bits, and
// never rounded up. Uses about 10KB. // never rounded up. Uses about 10KB.
// We use the template trick to allow inclusion in multiple translation units. // 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 { template <typename unused = void> struct powers_template {
constexpr static uint64_t power_of_five_128[651*2]= { constexpr static uint64_t power_of_five_128[651*2]= {
0xeef453d6923bd65a,0x113faa2906a13b3f, 0xeef453d6923bd65a,0x113faa2906a13b3f,
@@ -6012,7 +6016,7 @@ constexpr static uint64_t power_of_five_128[651*2]= {
0xe3d8f9e563a198e5,0x58180fddd97723a6, 0xe3d8f9e563a198e5,0x58180fddd97723a6,
0x8e679c2f5e44ff8f,0x570f09eaa7ea7648,}; 0x8e679c2f5e44ff8f,0x570f09eaa7ea7648,};
}; };
#endif // SIMDJSON_CPLUSPLUS26 #endif // SIMDJSON_STATIC_REFLECTION
extern SIMDJSON_DLLIMPORTEXPORT const uint64_t power_of_five_128[651*2]; extern SIMDJSON_DLLIMPORTEXPORT const uint64_t power_of_five_128[651*2];
} // namespace internal } // namespace internal
@@ -10105,6 +10109,9 @@ struct implementation_simdjson_result_base {
*/ */
simdjson_inline T&& value_unsafe() && noexcept; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
protected: protected:
/** users should never directly access first and second. **/ /** users should never directly access first and second. **/
T first{}; /** Users should never directly access 'first'. **/ 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
#else #else
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
#else #else
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); 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; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
protected: protected:
/** users should never directly access first and second. **/ /** users should never directly access first and second. **/
T first{}; /** Users should never directly access 'first'. **/ 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
#else #else
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
#else #else
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); 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; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
protected: protected:
/** users should never directly access first and second. **/ /** users should never directly access first and second. **/
T first{}; /** Users should never directly access 'first'. **/ 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
#else #else
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
#else #else
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); 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; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
protected: protected:
/** users should never directly access first and second. **/ /** users should never directly access first and second. **/
T first{}; /** Users should never directly access 'first'. **/ 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
#else #else
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
#else #else
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); 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; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
protected: protected:
/** users should never directly access first and second. **/ /** users should never directly access first and second. **/
T first{}; /** Users should never directly access 'first'. **/ 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
#else #else
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
#else #else
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); 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; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
protected: protected:
/** users should never directly access first and second. **/ /** users should never directly access first and second. **/
T first{}; /** Users should never directly access 'first'. **/ 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
#else #else
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
#else #else
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); 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; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
protected: protected:
/** users should never directly access first and second. **/ /** users should never directly access first and second. **/
T first{}; /** Users should never directly access 'first'. **/ 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
#else #else
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
#else #else
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); 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; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
protected: protected:
/** users should never directly access first and second. **/ /** users should never directly access first and second. **/
T first{}; /** Users should never directly access 'first'. **/ 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
#else #else
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
#else #else
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
+134 -30
View File
@@ -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: */ /* including simdjson.h: */
/* begin file simdjson.h */ /* begin file simdjson.h */
#ifndef SIMDJSON_H #ifndef SIMDJSON_H
@@ -2513,7 +2513,7 @@ namespace std {
#define SIMDJSON_SIMDJSON_VERSION_H #define SIMDJSON_SIMDJSON_VERSION_H
/** The version of simdjson being used (major.minor.revision) */ /** The version of simdjson being used (major.minor.revision) */
#define SIMDJSON_VERSION "4.2.0" #define SIMDJSON_VERSION "4.2.2"
namespace simdjson { namespace simdjson {
enum { enum {
@@ -2528,7 +2528,7 @@ enum {
/** /**
* The revision (major.minor.REVISION) of simdjson being used. * The revision (major.minor.REVISION) of simdjson being used.
*/ */
SIMDJSON_VERSION_REVISION = 0 SIMDJSON_VERSION_REVISION = 2
}; };
} // namespace simdjson } // namespace simdjson
@@ -2815,6 +2815,8 @@ struct simdjson_result_base : protected std::pair<T, error_code> {
*/ */
simdjson_inline T&& value_unsafe() && noexcept; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
}; // struct simdjson_result_base }; // struct simdjson_result_base
} // namespace internal } // namespace internal
@@ -2926,6 +2928,8 @@ struct simdjson_result : public internal::simdjson_result_base<T> {
*/ */
simdjson_inline T&& value_unsafe() && noexcept; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
}; // struct simdjson_result }; // struct simdjson_result
#if SIMDJSON_EXCEPTIONS #if SIMDJSON_EXCEPTIONS
@@ -4165,6 +4169,19 @@ struct padded_string final {
**/ **/
inline static simdjson_result<padded_string> load(std::string_view path) noexcept; 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: private:
padded_string &operator=(const padded_string &o) = delete; padded_string &operator=(const padded_string &o) = delete;
padded_string(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 */ /* end file simdjson/padded_string_view-inl.h */
#include <climits> #include <climits>
#include <cwchar>
namespace simdjson { namespace simdjson {
namespace internal { namespace internal {
@@ -4653,6 +4671,62 @@ inline simdjson_result<padded_string> padded_string::load(std::string_view filen
return s; 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 } // namespace simdjson
inline simdjson::padded_string operator ""_padded(const char *str, size_t len) { 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 #ifdef __cpp_char8_t
inline simdjson::padded_string operator ""_padded(const char8_t *str, size_t len) { 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
#endif // SIMDJSON_PADDED_STRING_INL_H #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 // The mantissa is truncated to 128 bits, and
// never rounded up. Uses about 10KB. // never rounded up. Uses about 10KB.
// We use the template trick to allow inclusion in multiple translation units. // 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 { template <typename unused = void> struct powers_template {
constexpr static uint64_t power_of_five_128[651*2]= { constexpr static uint64_t power_of_five_128[651*2]= {
0xeef453d6923bd65a,0x113faa2906a13b3f, 0xeef453d6923bd65a,0x113faa2906a13b3f,
@@ -11270,7 +11344,7 @@ constexpr static uint64_t power_of_five_128[651*2]= {
0xe3d8f9e563a198e5,0x58180fddd97723a6, 0xe3d8f9e563a198e5,0x58180fddd97723a6,
0x8e679c2f5e44ff8f,0x570f09eaa7ea7648,}; 0x8e679c2f5e44ff8f,0x570f09eaa7ea7648,};
}; };
#endif // SIMDJSON_CPLUSPLUS26 #endif // SIMDJSON_STATIC_REFLECTION
extern SIMDJSON_DLLIMPORTEXPORT const uint64_t power_of_five_128[651*2]; extern SIMDJSON_DLLIMPORTEXPORT const uint64_t power_of_five_128[651*2];
} // namespace internal } // namespace internal
@@ -12996,6 +13070,9 @@ struct implementation_simdjson_result_base {
*/ */
simdjson_inline T&& value_unsafe() && noexcept; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
protected: protected:
/** users should never directly access first and second. **/ /** users should never directly access first and second. **/
T first{}; /** Users should never directly access 'first'. **/ 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
#else #else
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
#else #else
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); 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; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
protected: protected:
/** users should never directly access first and second. **/ /** users should never directly access first and second. **/
T first{}; /** Users should never directly access 'first'. **/ 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
#else #else
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
#else #else
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); 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; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
protected: protected:
/** users should never directly access first and second. **/ /** users should never directly access first and second. **/
T first{}; /** Users should never directly access 'first'. **/ 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
#else #else
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
#else #else
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); 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; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
protected: protected:
/** users should never directly access first and second. **/ /** users should never directly access first and second. **/
T first{}; /** Users should never directly access 'first'. **/ 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
#else #else
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
#else #else
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); 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; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
protected: protected:
/** users should never directly access first and second. **/ /** users should never directly access first and second. **/
T first{}; /** Users should never directly access 'first'. **/ 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
#else #else
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
#else #else
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); 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; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
protected: protected:
/** users should never directly access first and second. **/ /** users should never directly access first and second. **/
T first{}; /** Users should never directly access 'first'. **/ 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
#else #else
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
#else #else
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); 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; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
protected: protected:
/** users should never directly access first and second. **/ /** users should never directly access first and second. **/
T first{}; /** Users should never directly access 'first'. **/ 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
#else #else
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
#else #else
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); 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; simdjson_inline T&& value_unsafe() && noexcept;
using value_type = T;
using error_type = error_code;
protected: protected:
/** users should never directly access first and second. **/ /** users should never directly access first and second. **/
T first{}; /** Users should never directly access 'first'. **/ 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index]);
#else #else
simdjson::internal::value128 firstproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index]); 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 // 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 // 64-bit least significant bits of the product and with a "high component" corresponding
// to the 64-bit most significant bits of the product. // 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]); simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::powers_template<>::power_of_five_128[index + 1]);
#else #else
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]); 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 { simdjson_inline void string_builder::append(const R &range) noexcept {
auto it = std::ranges::begin(range); auto it = std::ranges::begin(range);
auto end = std::ranges::end(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(); start_object();
if (it == end) { if (it == end) {
@@ -61324,7 +61422,7 @@ template <std::ranges::range R>
simdjson_inline void string_builder::append(const R &range) noexcept { simdjson_inline void string_builder::append(const R &range) noexcept {
auto it = std::ranges::begin(range); auto it = std::ranges::begin(range);
auto end = std::ranges::end(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(); start_object();
if (it == end) { if (it == end) {
@@ -76288,7 +76386,7 @@ template <std::ranges::range R>
simdjson_inline void string_builder::append(const R &range) noexcept { simdjson_inline void string_builder::append(const R &range) noexcept {
auto it = std::ranges::begin(range); auto it = std::ranges::begin(range);
auto end = std::ranges::end(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(); start_object();
if (it == end) { if (it == end) {
@@ -91252,7 +91350,7 @@ template <std::ranges::range R>
simdjson_inline void string_builder::append(const R &range) noexcept { simdjson_inline void string_builder::append(const R &range) noexcept {
auto it = std::ranges::begin(range); auto it = std::ranges::begin(range);
auto end = std::ranges::end(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(); start_object();
if (it == end) { if (it == end) {
@@ -106331,7 +106429,7 @@ template <std::ranges::range R>
simdjson_inline void string_builder::append(const R &range) noexcept { simdjson_inline void string_builder::append(const R &range) noexcept {
auto it = std::ranges::begin(range); auto it = std::ranges::begin(range);
auto end = std::ranges::end(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(); start_object();
if (it == end) { if (it == end) {
@@ -121726,7 +121824,7 @@ template <std::ranges::range R>
simdjson_inline void string_builder::append(const R &range) noexcept { simdjson_inline void string_builder::append(const R &range) noexcept {
auto it = std::ranges::begin(range); auto it = std::ranges::begin(range);
auto end = std::ranges::end(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(); start_object();
if (it == end) { if (it == end) {
@@ -136598,7 +136696,7 @@ template <std::ranges::range R>
simdjson_inline void string_builder::append(const R &range) noexcept { simdjson_inline void string_builder::append(const R &range) noexcept {
auto it = std::ranges::begin(range); auto it = std::ranges::begin(range);
auto end = std::ranges::end(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(); start_object();
if (it == end) { if (it == end) {
@@ -151483,7 +151581,7 @@ template <std::ranges::range R>
simdjson_inline void string_builder::append(const R &range) noexcept { simdjson_inline void string_builder::append(const R &range) noexcept {
auto it = std::ranges::begin(range); auto it = std::ranges::begin(range);
auto end = std::ranges::end(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(); start_object();
if (it == end) { if (it == end) {
@@ -153374,6 +153472,12 @@ template <constevalutil::fixed_string json_str> consteval auto parse_json();
} // namespace compile_time } // namespace compile_time
} // namespace simdjson } // 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_STATIC_REFLECTION
#endif // SIMDJSON_GENERIC_COMPILE_TIME_JSON_H #endif // SIMDJSON_GENERIC_COMPILE_TIME_JSON_H
/* end file simdjson/compile_time_json.h */ /* end file simdjson/compile_time_json.h */
Binary file not shown.
+25 -2
View File
@@ -4,6 +4,10 @@
#include <string> #include <string>
#include <string_view> #include <string_view>
#if SIMDJSON_SUPPORTS_RANGES
#include <ranges>
#endif
using namespace simdjson; using namespace simdjson;
struct Car { struct Car {
@@ -517,6 +521,24 @@ bool map_test() {
ASSERT_EQUAL(s, "{\"key1\":1.0,\"key2\":1.0}"); ASSERT_EQUAL(s, "{\"key1\":1.0,\"key2\":1.0}");
TEST_SUCCEED(); 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() { bool double_double_test() {
TEST_START(); TEST_START();
std::vector<std::vector<double>> c = {{1.0, 2.0}, {3.0, 4.0}}; 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() && car_test_exception() && string_convertion_except() &&
#endif #endif
#if SIMDJSON_SUPPORTS_RANGES && SIMDJSON_SUPPORTS_CONCEPTS #if SIMDJSON_SUPPORTS_RANGES && SIMDJSON_SUPPORTS_CONCEPTS
map_test() && double_double_test() && double_double_test_to_string() && map_test() && ranges_test() && double_double_test() &&
car_test_simple() && car_test_simple_complete() && double_double_test_to_string() && car_test_simple() &&
car_test_simple_complete() &&
#if SIMDJSON_EXCEPTIONS #if SIMDJSON_EXCEPTIONS
car_test_simple_complete_exceptions() && car_test_simple_complete_exceptions() &&
#endif #endif
+6 -6
View File
@@ -87,16 +87,16 @@ bool cast_tester<T>::test_get_error(simdjson_result<element> element, error_code
template<typename T> template<typename T>
bool cast_tester<T>::test_get_t(element element, T expected) { bool cast_tester<T>::test_get_t(element element, T expected) {
auto actual = element.get<T>(); T value;
ASSERT_SUCCESS(actual.error()); ASSERT_SUCCESS(element.get<T>().get(value));
return assert_equal(actual.value_unsafe(), expected); return assert_equal(value, expected);
} }
template<typename T> template<typename T>
bool cast_tester<T>::test_get_t(simdjson_result<element> element, T expected) { bool cast_tester<T>::test_get_t(simdjson_result<element> element, T expected) {
auto actual = element.get<T>(); T value;
ASSERT_SUCCESS(actual.error()); ASSERT_SUCCESS(element.get<T>().get(value));
return assert_equal(actual.value_unsafe(), expected); return assert_equal(value, expected);
} }
template<typename T> template<typename T>
+218 -2
View File
@@ -8,8 +8,8 @@
#include <print> #include <print>
using namespace simdjson;
using namespace std::string_view_literals; using namespace std::string_view_literals;
using namespace simdjson;
namespace compile_time_json_tests { namespace compile_time_json_tests {
/** /**
@@ -479,6 +479,216 @@ bool array_of_objects() {
TEST_SUCCEED(); 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() { bool run() {
return test_basic_object() && return test_basic_object() &&
test_nested_objects() && test_nested_objects() &&
@@ -498,7 +708,13 @@ bool run() {
test_simple_object_str_with_obj() && test_simple_object_str_with_obj() &&
test_empty_arrays() && test_empty_arrays() &&
simple_array() && 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 } // namespace compile_time_json_tests