mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 11d9dbb7b7 | |||
| 896fb5d6a5 | |||
| e3d3b4b5a4 | |||
| 08e5943efc | |||
| 7068894be3 |
@@ -31,4 +31,4 @@ jobs:
|
|||||||
echo -e '#include <simdjson.h>\nint main(int argc,char**argv) {simdjson::dom::parser parser;simdjson::dom::element tweets = parser.load(argv[1]); }' > tmp.cpp && c++ -Idestination/include -Ldestination/lib -std=c++17 -Wl,-rpath,destination/lib -o linkandrun tmp.cpp -lsimdjson && ./linkandrun jsonexamples/twitter.json &&
|
echo -e '#include <simdjson.h>\nint main(int argc,char**argv) {simdjson::dom::parser parser;simdjson::dom::element tweets = parser.load(argv[1]); }' > tmp.cpp && c++ -Idestination/include -Ldestination/lib -std=c++17 -Wl,-rpath,destination/lib -o linkandrun tmp.cpp -lsimdjson && ./linkandrun jsonexamples/twitter.json &&
|
||||||
mkdir testfindpackage &&
|
mkdir testfindpackage &&
|
||||||
cd testfindpackage &&
|
cd testfindpackage &&
|
||||||
echo -e 'cmake_minimum_required(VERSION 3.14)\nproject(simdjsontester)\nset(CMAKE_CXX_STANDARD 17)\nfind_package(simdjson REQUIRED)'> CMakeLists.txt && mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX:PATH=../destination .. && cmake --build .
|
echo -e 'cmake_minimum_required(VERSION 3.1)\nproject(simdjsontester)\nset(CMAKE_CXX_STANDARD 17)\nfind_package(simdjson REQUIRED)'> CMakeLists.txt && mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX:PATH=../destination .. && cmake --build .
|
||||||
|
|||||||
@@ -31,4 +31,4 @@ jobs:
|
|||||||
echo -e '#include <simdjson.h>\nint main(int argc,char**argv) {simdjson::dom::parser parser;simdjson::dom::element tweets = parser.load(argv[1]); }' > tmp.cpp && c++ -Idestination/include -Ldestination/lib -std=c++17 -Wl,-rpath,destination/lib -o linkandrun tmp.cpp -lsimdjson && ./linkandrun jsonexamples/twitter.json &&
|
echo -e '#include <simdjson.h>\nint main(int argc,char**argv) {simdjson::dom::parser parser;simdjson::dom::element tweets = parser.load(argv[1]); }' > tmp.cpp && c++ -Idestination/include -Ldestination/lib -std=c++17 -Wl,-rpath,destination/lib -o linkandrun tmp.cpp -lsimdjson && ./linkandrun jsonexamples/twitter.json &&
|
||||||
mkdir testfindpackage &&
|
mkdir testfindpackage &&
|
||||||
cd testfindpackage &&
|
cd testfindpackage &&
|
||||||
echo -e 'cmake_minimum_required(VERSION 3.14)\nproject(simdjsontester)\nset(CMAKE_CXX_STANDARD 17)\nfind_package(simdjson REQUIRED)'> CMakeLists.txt && mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX:PATH=../destination .. && cmake --build .
|
echo -e 'cmake_minimum_required(VERSION 3.1)\nproject(simdjsontester)\nset(CMAKE_CXX_STANDARD 17)\nfind_package(simdjson REQUIRED)'> CMakeLists.txt && mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX:PATH=../destination .. && cmake --build .
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ objs
|
|||||||
# Build outputs
|
# Build outputs
|
||||||
/build*/
|
/build*/
|
||||||
/visual_studio/
|
/visual_studio/
|
||||||
|
/originbuild/
|
||||||
|
|
||||||
# Fuzzer outputs generated by instructions in fuzz/Fuzzing.md
|
# Fuzzer outputs generated by instructions in fuzz/Fuzzing.md
|
||||||
/corpus.zip
|
/corpus.zip
|
||||||
|
|||||||
+1
-1
@@ -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.0.4
|
VERSION 4.0.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
|
||||||
|
|||||||
@@ -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.0.4"
|
PROJECT_NUMBER = "4.0.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
|
||||||
|
|||||||
@@ -117,9 +117,9 @@ Godbolt
|
|||||||
-------------
|
-------------
|
||||||
|
|
||||||
Some users may want to browse code along with the compiled assembly. You want to check out the following lists of examples:
|
Some users may want to browse code along with the compiled assembly. You want to check out the following lists of examples:
|
||||||
* [C++26 reflection example](https://godbolt.org/z/K3Px64TqK)
|
|
||||||
* [simdjson examples with errors handled through exceptions](https://godbolt.org/z/7G5qE4sr9)
|
* [simdjson examples with errors handled through exceptions](https://godbolt.org/z/7G5qE4sr9)
|
||||||
* [simdjson examples with errors without exceptions](https://godbolt.org/z/e9dWb9E4v)
|
* [simdjson examples with errors without exceptions](https://godbolt.org/z/e9dWb9E4v)
|
||||||
|
* [C++26 reflection example](https://godbolt.org/z/xK5TGKdPb)
|
||||||
|
|
||||||
Performance results
|
Performance results
|
||||||
-------------------
|
-------------------
|
||||||
|
|||||||
@@ -6,9 +6,8 @@ CPMAddPackage(
|
|||||||
EXCLUDE_FROM_ALL YES
|
EXCLUDE_FROM_ALL YES
|
||||||
)
|
)
|
||||||
|
|
||||||
option(SIMDJSON_USE_RUST "Build the static_reflect benchmark" OFF)
|
|
||||||
|
|
||||||
if(SIMDJSON_USER_RUST)
|
|
||||||
if(NOT WIN32)
|
if(NOT WIN32)
|
||||||
# We want the check whether Rust is available before trying to build a crate.
|
# We want the check whether Rust is available before trying to build a crate.
|
||||||
CPMAddPackage(
|
CPMAddPackage(
|
||||||
@@ -39,9 +38,6 @@ if(SIMDJSON_USER_RUST)
|
|||||||
message(STATUS "curl https://sh.rustup.rs -sSf | sh")
|
message(STATUS "curl https://sh.rustup.rs -sSf | sh")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
else(SIMDJSON_USER_RUST)
|
|
||||||
message(STATUS "We will not benchmark serde-benchmark." )
|
|
||||||
endif(SIMDJSON_USER_RUST)
|
|
||||||
|
|
||||||
# Add the benchmark executable targets
|
# Add the benchmark executable targets
|
||||||
add_subdirectory(twitter_benchmark)
|
add_subdirectory(twitter_benchmark)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Implementation selection
|
# Implementation selection
|
||||||
#
|
#
|
||||||
set(SIMDJSON_ALL_IMPLEMENTATIONS fallback westmere haswell icelake arm64 ppc64)
|
set(SIMDJSON_ALL_IMPLEMENTATIONS fallback westmere haswell icelake arm64 ppc64 rvv)
|
||||||
|
|
||||||
set(
|
set(
|
||||||
SIMDJSON_IMPLEMENTATION ""
|
SIMDJSON_IMPLEMENTATION ""
|
||||||
@@ -15,7 +15,7 @@ set(
|
|||||||
SIMDJSON_EXCLUDE_IMPLEMENTATION ""
|
SIMDJSON_EXCLUDE_IMPLEMENTATION ""
|
||||||
CACHE STRING "\
|
CACHE STRING "\
|
||||||
Semicolon-separated list of implementations to exclude \
|
Semicolon-separated list of implementations to exclude \
|
||||||
(icelake/haswell/westmere/arm64/ppc64/fallback). By default, excludes any \
|
(icelake/haswell/westmere/arm64/ppc64/rvv/fallback). By default, excludes any \
|
||||||
implementations that are unsupported at compile time or cannot be selected at \
|
implementations that are unsupported at compile time or cannot be selected at \
|
||||||
runtime."
|
runtime."
|
||||||
)
|
)
|
||||||
|
|||||||
+2
-8
@@ -1395,7 +1395,7 @@ Car c = doc.get<Car>();
|
|||||||
|
|
||||||
We try to automate the parsing of any given structure or class
|
We try to automate the parsing of any given structure or class
|
||||||
by looking at its non-static public members. At compile-time,
|
by looking at its non-static public members. At compile-time,
|
||||||
the library looks at a simple structure like `Car` and
|
the library looks at a simple structre like `Car` and
|
||||||
maps it to parsing code. We call the default constructor,
|
maps it to parsing code. We call the default constructor,
|
||||||
and then assign values to the public members.
|
and then assign values to the public members.
|
||||||
|
|
||||||
@@ -1450,7 +1450,7 @@ struct complicated_weather_data {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
The code might be as simple as the following.
|
The code might as simple as the following.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
auto padded = R"({"time":["2023-03-15T12:00:00Z"],"temperature":[42]})"_padded;
|
auto padded = R"({"time":["2023-03-15T12:00:00Z"],"temperature":[42]})"_padded;
|
||||||
@@ -1477,12 +1477,6 @@ type without a document instance like so:
|
|||||||
Car car = simdjson::from(json);
|
Car car = simdjson::from(json);
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also use the `simdjson::from` syntax without exceptions, like so:
|
|
||||||
```cpp
|
|
||||||
Car car;
|
|
||||||
simdjson::error_code err = simdjson::from(json_car).get(car);
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also use the `simdjson::from` syntax to iterate over an array.
|
You can also use the `simdjson::from` syntax to iterate over an array.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
|
|||||||
+10
-11
@@ -34,15 +34,14 @@ It has the following methods to add content to the string:
|
|||||||
- `append_null()`: Appends the string "null" to the JSON buffer.
|
- `append_null()`: Appends the string "null" to the JSON buffer.
|
||||||
- `clear()`: Clears the contents of the JSON buffer, resetting the position to 0 while retaining the allocated capacity.
|
- `clear()`: Clears the contents of the JSON buffer, resetting the position to 0 while retaining the allocated capacity.
|
||||||
- `escape_and_append(std::string_view input)`: Appends a string view to the JSON buffer after escaping special characters (e.g., quotes, backslashes) as required by JSON.
|
- `escape_and_append(std::string_view input)`: Appends a string view to the JSON buffer after escaping special characters (e.g., quotes, backslashes) as required by JSON.
|
||||||
- `escape_and_append_with_quotes(std::string_view input)` Appends a string view surrounded by double quotes (e.g., "input") to the JSON buffer after escaping special characters. For constant strings, you may also do `escape_and_append_with_quotes<"mystring">()`.
|
- `escape_and_append_with_quotes(std::string_view input)` Appends a string view surrounded by double quotes (e.g., "input") to the JSON buffer after escaping special characters.
|
||||||
|
Parameters:
|
||||||
- `escape_and_append_with_quotes(char input)`: Appends a single character surrounded by double quotes (e.g., "c") to the JSON buffer after escaping it if necessary.
|
- `escape_and_append_with_quotes(char input)`: Appends a single character surrounded by double quotes (e.g., "c") to the JSON buffer after escaping it if necessary.
|
||||||
- `append_raw(const char *c)`: Appends a null-terminated C string directly to the JSON buffer without escaping.
|
- `append_raw(const char *c)`: Appends a null-terminated C string directly to the JSON buffer without escaping.
|
||||||
- `append_raw(std::string_view input)`: Appends a string view directly to the JSON buffer without escaping.
|
- `append_raw(std::string_view input)`: Appends a string view directly to the JSON buffer without escaping.
|
||||||
- `append_raw(const char *str, size_t len)`: Appends a specified number of characters from a C string directly to the JSON
|
- `append_raw(const char *str, size_t len)`: Appends a specified number of characters from a C string directly to the JSON
|
||||||
- `append_key_value(key,value)`: Appends a key and a value (`"json":somevalue`)
|
|
||||||
- `append_key_value<"mykey">(value)`: Appends a key and a value (`"json":somevalue`), useful when the key is a compile-time constant (C++20).
|
|
||||||
|
|
||||||
After writing the content, if you have reasons to believe that the content might violate UTF-8 conventions, you can check it as follows:
|
After writting the content, if you have reasons to believe that the content might violate UTF-8 conventions, you can check it as follows:
|
||||||
|
|
||||||
- `validate_unicode()`: Checks if the content in the JSON buffer is valid UTF-8. Returns: true if the content is valid UTF-8, false otherwise.
|
- `validate_unicode()`: Checks if the content in the JSON buffer is valid UTF-8. Returns: true if the content is valid UTF-8, false otherwise.
|
||||||
|
|
||||||
@@ -53,7 +52,7 @@ Once you are satisfied, you can recover the string as follows:
|
|||||||
|
|
||||||
- `operator std::string()`: Converts the JSON buffer to an std::string. (Might throw if an error occurred.)
|
- `operator std::string()`: Converts the JSON buffer to an std::string. (Might throw if an error occurred.)
|
||||||
- `operator std::string_view()`: Converts the JSON buffer to an std::string_view. (Might throw if an error occurred.)
|
- `operator std::string_view()`: Converts the JSON buffer to an std::string_view. (Might throw if an error occurred.)
|
||||||
- `view()`: Returns a view of the written JSON buffer as a `simdjson_result<std::string_view>` (C++20).
|
- `view()`: Returns a view of the written JSON buffer as a `simdjson_result<std::string_view>`.
|
||||||
|
|
||||||
The later method (`view()`) is recommended. For performance reasons, we expect you to explicitly call `validate_unicode()` as needed (e.g., prior to calling `view()`).
|
The later method (`view()`) is recommended. For performance reasons, we expect you to explicitly call `validate_unicode()` as needed (e.g., prior to calling `view()`).
|
||||||
|
|
||||||
@@ -132,20 +131,20 @@ In all cases, the `std::string_view` instance depends the corresponding `string_
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
If you have C++20, you can simplify the code, as the `std::vector<double>` is automatically supported. Further, we can pass the keys (which are compile-time
|
If you have C++20, you can simplify the code, as the `std::vector<double>` is automatically
|
||||||
constant) as template parameter (for improved performance).
|
supported.
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
Car c = {"Toyota", "Corolla", 2017, {30.0,30.2,30.513,30.79}};
|
Car c = {"Toyota", "Corolla", 2017, {30.0,30.2,30.513,30.79}};
|
||||||
simdjson::builder::string_builder sb;
|
simdjson::builder::string_builder sb;
|
||||||
sb.start_object();
|
sb.start_object();
|
||||||
sb.append_key_value<"make">(c.make);
|
sb.append_key_value("make", c.make);
|
||||||
sb.append_comma();
|
sb.append_comma();
|
||||||
sb.append_key_value<"model">(c.model);
|
sb.append_key_value("model", c.model);
|
||||||
sb.append_comma();
|
sb.append_comma();
|
||||||
sb.append_key_value<"year">(c.year);
|
sb.append_key_value("year", c.year);
|
||||||
sb.append_comma();
|
sb.append_comma();
|
||||||
sb.append_key_value<"tire_pressure">(c.tire_pressure);
|
sb.append_key_value("tire_pressure", c.tire_pressure);
|
||||||
sb.end_object();
|
sb.end_object();
|
||||||
std::string_view p = sb.view();
|
std::string_view p = sb.view();
|
||||||
```
|
```
|
||||||
|
|||||||
+1
-1
@@ -129,7 +129,7 @@ Once you have an element, you can navigate it with idiomatic C++ iterators, oper
|
|||||||
The strings contain unescaped valid UTF-8 strings: no unmatched surrogate is allowed.
|
The strings contain unescaped valid UTF-8 strings: no unmatched surrogate is allowed.
|
||||||
Internally, numbers are stored as either 64-bit integers or 64-bit floating-point numbers.
|
Internally, numbers are stored as either 64-bit integers or 64-bit floating-point numbers.
|
||||||
Thus it is possible to get the full 64-bit integer range (either signed or unsigned).
|
Thus it is possible to get the full 64-bit integer range (either signed or unsigned).
|
||||||
By default, the string `-0` is parsed as the integer 0 as in Python or C++. If you set the macro
|
By default, the string `-0` is parsed as the integer 0 as in Pytho or C++. If you set the macro
|
||||||
`SIMDJSON_MINUS_ZERO_AS_FLOAT` to `1` when building simdjson, you can get that `-0` is mapped to `-0.0`
|
`SIMDJSON_MINUS_ZERO_AS_FLOAT` to `1` when building simdjson, you can get that `-0` is mapped to `-0.0`
|
||||||
as in JavaScript. You can get the desired effect by building simdjson with cmake setting the
|
as in JavaScript. You can get the desired effect by building simdjson with cmake setting the
|
||||||
`SIMDJSON_MINUS_ZERO_AS_FLOAT` to on: `cmake -B build -D SIMDJSON_MINUS_ZERO_AS_FLOAT=ON`.
|
`SIMDJSON_MINUS_ZERO_AS_FLOAT` to on: `cmake -B build -D SIMDJSON_MINUS_ZERO_AS_FLOAT=ON`.
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
#include "simdjson/lsx.h"
|
#include "simdjson/lsx.h"
|
||||||
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lasx)
|
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lasx)
|
||||||
#include "simdjson/lasx.h"
|
#include "simdjson/lasx.h"
|
||||||
|
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(rvv)
|
||||||
|
#include "simdjson/rvv.h"
|
||||||
#else
|
#else
|
||||||
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
|
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ namespace simdjson {
|
|||||||
namespace lsx {}
|
namespace lsx {}
|
||||||
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lasx)
|
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lasx)
|
||||||
namespace lasx {}
|
namespace lasx {}
|
||||||
|
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(rvv)
|
||||||
|
namespace rvv {}
|
||||||
#else
|
#else
|
||||||
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
|
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
#include "simdjson/lsx/implementation.h"
|
#include "simdjson/lsx/implementation.h"
|
||||||
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lasx)
|
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lasx)
|
||||||
#include "simdjson/lasx/implementation.h"
|
#include "simdjson/lasx/implementation.h"
|
||||||
|
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(rvv)
|
||||||
|
#include "simdjson/rvv/implementation.h"
|
||||||
#else
|
#else
|
||||||
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
|
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
#include "simdjson/lsx/ondemand.h"
|
#include "simdjson/lsx/ondemand.h"
|
||||||
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lasx)
|
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(lasx)
|
||||||
#include "simdjson/lasx/ondemand.h"
|
#include "simdjson/lasx/ondemand.h"
|
||||||
|
#elif SIMDJSON_BUILTIN_IMPLEMENTATION_IS(rvv)
|
||||||
|
#include "simdjson/rvv/ondemand.h"
|
||||||
#else
|
#else
|
||||||
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
|
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -58,12 +58,6 @@ inline simdjson_result<T> auto_parser<parser_type>::result() noexcept(is_nothrow
|
|||||||
return m_doc.get<T>();
|
return m_doc.get<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename parser_type>
|
|
||||||
template <typename T>
|
|
||||||
simdjson_warn_unused simdjson_inline error_code auto_parser<parser_type>::get(T &value) && noexcept(is_nothrow_gettable<T>) {
|
|
||||||
return result<T>().get(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename parser_type>
|
template <typename parser_type>
|
||||||
inline simdjson_result<ondemand::array> auto_parser<parser_type>::array() noexcept {
|
inline simdjson_result<ondemand::array> auto_parser<parser_type>::array() noexcept {
|
||||||
return result<ondemand::array>();
|
return result<ondemand::array>();
|
||||||
@@ -79,6 +73,12 @@ inline simdjson_result<ondemand::number> auto_parser<parser_type>::number() noex
|
|||||||
return result<ondemand::number>();
|
return result<ondemand::number>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename parser_type>
|
||||||
|
template <typename T>
|
||||||
|
inline auto_parser<parser_type>::operator simdjson_result<T>() noexcept(is_nothrow_gettable<T>) {
|
||||||
|
return result<T>();
|
||||||
|
}
|
||||||
|
|
||||||
template <typename parser_type>
|
template <typename parser_type>
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline auto_parser<parser_type>::operator T() noexcept(false) {
|
inline auto_parser<parser_type>::operator T() noexcept(false) {
|
||||||
@@ -116,16 +116,6 @@ template <typename T>
|
|||||||
inline auto to_adaptor<T>::operator()(ondemand::parser &parser, padded_string_view const str) const noexcept {
|
inline auto to_adaptor<T>::operator()(ondemand::parser &parser, padded_string_view const str) const noexcept {
|
||||||
return auto_parser<ondemand::parser *>{parser, str};
|
return auto_parser<ondemand::parser *>{parser, str};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline auto to_adaptor<T>::operator()(std::string str) const noexcept {
|
|
||||||
return auto_parser{pad_with_reserve(str)};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline auto to_adaptor<T>::operator()(ondemand::parser &parser, std::string str) const noexcept {
|
|
||||||
return auto_parser<ondemand::parser *>{parser, pad_with_reserve(str)};
|
|
||||||
}
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace convert
|
} // namespace convert
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|||||||
@@ -46,16 +46,14 @@ public:
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
simdjson_warn_unused simdjson_inline simdjson_result<T> result() noexcept(is_nothrow_gettable<T>);
|
simdjson_warn_unused simdjson_inline simdjson_result<T> result() noexcept(is_nothrow_gettable<T>);
|
||||||
template <typename T>
|
|
||||||
simdjson_warn_unused simdjson_inline error_code get(T &value) && noexcept(is_nothrow_gettable<T>);
|
|
||||||
|
|
||||||
|
|
||||||
simdjson_warn_unused simdjson_inline simdjson_result<ondemand::array> array() noexcept;
|
simdjson_warn_unused simdjson_inline simdjson_result<ondemand::array> array() noexcept;
|
||||||
simdjson_warn_unused simdjson_inline simdjson_result<ondemand::object> object() noexcept;
|
simdjson_warn_unused simdjson_inline simdjson_result<ondemand::object> object() noexcept;
|
||||||
simdjson_warn_unused simdjson_inline simdjson_result<ondemand::number> number() noexcept;
|
simdjson_warn_unused simdjson_inline simdjson_result<ondemand::number> number() noexcept;
|
||||||
|
|
||||||
//template <typename T>
|
template <typename T>
|
||||||
//simdjson_warn_unused simdjson_inline explicit(false) operator simdjson_result<T>() noexcept(is_nothrow_gettable<T>);
|
simdjson_warn_unused simdjson_inline explicit(false) operator simdjson_result<T>() noexcept(is_nothrow_gettable<T>);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
simdjson_warn_unused simdjson_inline explicit(false) operator T() noexcept(false);
|
simdjson_warn_unused simdjson_inline explicit(false) operator T() noexcept(false);
|
||||||
|
|
||||||
@@ -74,11 +72,6 @@ struct to_adaptor {
|
|||||||
T operator()(simdjson_result<ondemand::value> &val) const noexcept;
|
T operator()(simdjson_result<ondemand::value> &val) const noexcept;
|
||||||
auto operator()(padded_string_view const str) const noexcept;
|
auto operator()(padded_string_view const str) const noexcept;
|
||||||
auto operator()(ondemand::parser &parser, padded_string_view const str) const noexcept;
|
auto operator()(ondemand::parser &parser, padded_string_view const str) const noexcept;
|
||||||
// The std::string is padded with reserve to ensure there is enough space for padding.
|
|
||||||
// Some sanitizers may not like this, so you can use simdjson::pad instead.
|
|
||||||
// simdjson::from(simdjson::pad(str))
|
|
||||||
auto operator()(std::string str) const noexcept;
|
|
||||||
auto operator()(ondemand::parser &parser, std::string str) const noexcept;
|
|
||||||
};
|
};
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace convert
|
} // namespace convert
|
||||||
|
|||||||
@@ -284,12 +284,10 @@ simdjson_inline void string_builder::clear() noexcept {
|
|||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
// We could specialize further for 32-bit integers.
|
||||||
|
simdjson_really_inline int int_log2(uint32_t x) { return (63 - leading_zeroes(x | 1)); }
|
||||||
|
|
||||||
template <typename number_type, typename = typename std::enable_if<
|
simdjson_really_inline int fast_digit_count(uint32_t x) {
|
||||||
std::is_unsigned<number_type>::value>::type>
|
|
||||||
simdjson_really_inline int int_log2(number_type x) { return 63 - leading_zeroes(uint64_t(x) | 1); }
|
|
||||||
|
|
||||||
simdjson_really_inline int fast_digit_count_32(uint32_t x) {
|
|
||||||
static uint64_t table[] = {
|
static uint64_t table[] = {
|
||||||
4294967296, 8589934582, 8589934582, 8589934582, 12884901788,
|
4294967296, 8589934582, 8589934582, 8589934582, 12884901788,
|
||||||
12884901788, 12884901788, 17179868184, 17179868184, 17179868184,
|
12884901788, 12884901788, 17179868184, 17179868184, 17179868184,
|
||||||
@@ -301,8 +299,9 @@ simdjson_really_inline int fast_digit_count_32(uint32_t x) {
|
|||||||
return uint32_t((x + table[int_log2(x)]) >> 32);
|
return uint32_t((x + table[int_log2(x)]) >> 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
simdjson_really_inline int int_log2(uint64_t x) { return 63 - leading_zeroes(x | 1); }
|
||||||
|
|
||||||
simdjson_really_inline int fast_digit_count_64(uint64_t x) {
|
simdjson_really_inline int fast_digit_count(uint64_t x) {
|
||||||
static uint64_t table[] = {9,
|
static uint64_t table[] = {9,
|
||||||
99,
|
99,
|
||||||
999,
|
999,
|
||||||
@@ -333,11 +332,7 @@ simdjson_really_inline size_t digit_count(number_type v) noexcept {
|
|||||||
static_assert(sizeof(number_type) == 8 || sizeof(number_type) == 4 ||
|
static_assert(sizeof(number_type) == 8 || sizeof(number_type) == 4 ||
|
||||||
sizeof(number_type) == 2 || sizeof(number_type) == 1,
|
sizeof(number_type) == 2 || sizeof(number_type) == 1,
|
||||||
"We only support 8-bit, 16-bit, 32-bit and 64-bit numbers");
|
"We only support 8-bit, 16-bit, 32-bit and 64-bit numbers");
|
||||||
SIMDJSON_IF_CONSTEXPR(sizeof(number_type) <= 4) {
|
return fast_digit_count(v);
|
||||||
return fast_digit_count_32(static_cast<uint32_t>(v));
|
|
||||||
} else {
|
|
||||||
return fast_digit_count_64(static_cast<uint64_t>(v));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
static const char decimal_table[200] = {
|
static const char decimal_table[200] = {
|
||||||
0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35,
|
0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35,
|
||||||
@@ -475,12 +470,6 @@ simdjson_inline void string_builder::escape_and_append_with_quotes(const char* i
|
|||||||
std::string_view cinput(input);
|
std::string_view cinput(input);
|
||||||
escape_and_append_with_quotes(cinput);
|
escape_and_append_with_quotes(cinput);
|
||||||
}
|
}
|
||||||
#if SIMDJSON_SUPPORTS_CONCEPTS
|
|
||||||
template<internal::fixed_string key>
|
|
||||||
simdjson_inline void string_builder::escape_and_append_with_quotes() noexcept {
|
|
||||||
escape_and_append_with_quotes(internal::string_constant<key>::value);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
simdjson_inline void string_builder::append_raw(const char *c) noexcept {
|
simdjson_inline void string_builder::append_raw(const char *c) noexcept {
|
||||||
size_t len = std::strlen(c);
|
size_t len = std::strlen(c);
|
||||||
@@ -660,25 +649,6 @@ simdjson_inline void string_builder::append_key_value(key_type key, value_type v
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SIMDJSON_SUPPORTS_CONCEPTS
|
|
||||||
template<internal::fixed_string key, typename value_type>
|
|
||||||
simdjson_inline void string_builder::append_key_value(value_type value) noexcept {
|
|
||||||
escape_and_append_with_quotes<key>();
|
|
||||||
append_colon();
|
|
||||||
SIMDJSON_IF_CONSTEXPR(std::is_same<value_type, std::nullptr_t>::value) {
|
|
||||||
append_null();
|
|
||||||
} else SIMDJSON_IF_CONSTEXPR(std::is_same<value_type, char>::value) {
|
|
||||||
escape_and_append_with_quotes(value);
|
|
||||||
} else SIMDJSON_IF_CONSTEXPR(std::is_convertible<value_type, std::string_view>::value) {
|
|
||||||
escape_and_append_with_quotes(value);
|
|
||||||
} else SIMDJSON_IF_CONSTEXPR(std::is_same<value_type, const char*>::value) {
|
|
||||||
escape_and_append_with_quotes(value);
|
|
||||||
} else {
|
|
||||||
append(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace builder
|
} // namespace builder
|
||||||
} // namespace SIMDJSON_IMPLEMENTATION
|
} // namespace SIMDJSON_IMPLEMENTATION
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|||||||
@@ -12,26 +12,7 @@
|
|||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
namespace SIMDJSON_IMPLEMENTATION {
|
namespace SIMDJSON_IMPLEMENTATION {
|
||||||
namespace builder {
|
namespace builder {
|
||||||
#if SIMDJSON_SUPPORTS_CONCEPTS
|
|
||||||
// Helper to create string constants
|
|
||||||
namespace internal {
|
|
||||||
template <std::size_t N>
|
|
||||||
struct fixed_string {
|
|
||||||
constexpr fixed_string(const char (&str)[N]) {
|
|
||||||
for (std::size_t i = 0; i < N; ++i) {
|
|
||||||
data[i] = str[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
char data[N];
|
|
||||||
constexpr std::string_view view() const { return {data, N - 1}; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <fixed_string str>
|
|
||||||
struct string_constant {
|
|
||||||
static constexpr std::string_view value = str.view();
|
|
||||||
};
|
|
||||||
} // namespace internal
|
|
||||||
#endif // SIMDJSON_SUPPORTS_CONCEPTS
|
|
||||||
/**
|
/**
|
||||||
* A builder for JSON strings representing documents. This is a low-level
|
* A builder for JSON strings representing documents. This is a low-level
|
||||||
* builder that is not meant to be used directly by end-users. Though it
|
* builder that is not meant to be used directly by end-users. Though it
|
||||||
@@ -81,10 +62,7 @@ public:
|
|||||||
* There is no UTF-8 validation.
|
* There is no UTF-8 validation.
|
||||||
*/
|
*/
|
||||||
simdjson_inline void escape_and_append_with_quotes(std::string_view input) noexcept;
|
simdjson_inline void escape_and_append_with_quotes(std::string_view input) noexcept;
|
||||||
#if SIMDJSON_SUPPORTS_CONCEPTS
|
|
||||||
template<internal::fixed_string key>
|
|
||||||
simdjson_inline void escape_and_append_with_quotes() noexcept;
|
|
||||||
#endif
|
|
||||||
/**
|
/**
|
||||||
* Append the character surrounded by double quotes, after escaping it.
|
* Append the character surrounded by double quotes, after escaping it.
|
||||||
* There is no UTF-8 validation.
|
* There is no UTF-8 validation.
|
||||||
@@ -141,9 +119,6 @@ public:
|
|||||||
template<typename key_type, typename value_type>
|
template<typename key_type, typename value_type>
|
||||||
simdjson_inline void append_key_value(key_type key, value_type value) noexcept;
|
simdjson_inline void append_key_value(key_type key, value_type value) noexcept;
|
||||||
#if SIMDJSON_SUPPORTS_CONCEPTS
|
#if SIMDJSON_SUPPORTS_CONCEPTS
|
||||||
template<internal::fixed_string key, typename value_type>
|
|
||||||
simdjson_inline void append_key_value(value_type value) noexcept;
|
|
||||||
|
|
||||||
// Support for optional types (std::optional, etc.)
|
// Support for optional types (std::optional, etc.)
|
||||||
template <concepts::optional_type T>
|
template <concepts::optional_type T>
|
||||||
simdjson_inline void append(const T &opt);
|
simdjson_inline void append(const T &opt);
|
||||||
|
|||||||
@@ -291,7 +291,7 @@ error_code tag_invoke(deserialize_tag, ValT &val, T &out) noexcept {
|
|||||||
if constexpr (!std::meta::is_const(mem) && std::meta::is_public(mem)) {
|
if constexpr (!std::meta::is_const(mem) && std::meta::is_public(mem)) {
|
||||||
constexpr std::string_view key = std::define_static_string(std::meta::identifier_of(mem));
|
constexpr std::string_view key = std::define_static_string(std::meta::identifier_of(mem));
|
||||||
// Note: removed static assert as optional types are now handled generically
|
// Note: removed static assert as optional types are now handled generically
|
||||||
// as long we are successful or the field is not found, we continue
|
// as long we are succesful or the field is not found, we continue
|
||||||
if(e == simdjson::SUCCESS || e == simdjson::NO_SUCH_FIELD) {
|
if(e == simdjson::SUCCESS || e == simdjson::NO_SUCH_FIELD) {
|
||||||
e = obj[key].get(out.[:mem:]);
|
e = obj[key].get(out.[:mem:]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#define SIMDJSON_IMPLEMENTATION_ID_westmere 6
|
#define SIMDJSON_IMPLEMENTATION_ID_westmere 6
|
||||||
#define SIMDJSON_IMPLEMENTATION_ID_lsx 7
|
#define SIMDJSON_IMPLEMENTATION_ID_lsx 7
|
||||||
#define SIMDJSON_IMPLEMENTATION_ID_lasx 8
|
#define SIMDJSON_IMPLEMENTATION_ID_lasx 8
|
||||||
|
#define SIMDJSON_IMPLEMENTATION_ID_rvv 9
|
||||||
|
|
||||||
#define SIMDJSON_IMPLEMENTATION_ID_FOR(IMPL) SIMDJSON_CAT(SIMDJSON_IMPLEMENTATION_ID_, IMPL)
|
#define SIMDJSON_IMPLEMENTATION_ID_FOR(IMPL) SIMDJSON_CAT(SIMDJSON_IMPLEMENTATION_ID_, IMPL)
|
||||||
#define SIMDJSON_IMPLEMENTATION_ID SIMDJSON_IMPLEMENTATION_ID_FOR(SIMDJSON_IMPLEMENTATION)
|
#define SIMDJSON_IMPLEMENTATION_ID SIMDJSON_IMPLEMENTATION_ID_FOR(SIMDJSON_IMPLEMENTATION)
|
||||||
@@ -23,6 +24,15 @@
|
|||||||
// in which we include them.
|
// in which we include them.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#ifndef SIMDJSON_IMPLEMENTATION_RVV
|
||||||
|
#define SIMDJSON_IMPLEMENTATION_RVV (SIMDJSON_IS_RISCV64 && SIMDJSON_IS_RVV)
|
||||||
|
#endif
|
||||||
|
#if SIMDJSON_IMPLEMENTATION_RVV && SIMDJSON_IS_RISCV64 && SIMDJSON_IS_RVV
|
||||||
|
#define SIMDJSON_CAN_ALWAYS_RUN_RVV 1
|
||||||
|
#else
|
||||||
|
#define SIMDJSON_CAN_ALWAYS_RUN_RVV 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef SIMDJSON_IMPLEMENTATION_ARM64
|
#ifndef SIMDJSON_IMPLEMENTATION_ARM64
|
||||||
#define SIMDJSON_IMPLEMENTATION_ARM64 (SIMDJSON_IS_ARM64)
|
#define SIMDJSON_IMPLEMENTATION_ARM64 (SIMDJSON_IS_ARM64)
|
||||||
#endif
|
#endif
|
||||||
@@ -128,7 +138,7 @@
|
|||||||
|
|
||||||
// Default Fallback to on unless a builtin implementation has already been selected.
|
// Default Fallback to on unless a builtin implementation has already been selected.
|
||||||
#ifndef SIMDJSON_IMPLEMENTATION_FALLBACK
|
#ifndef SIMDJSON_IMPLEMENTATION_FALLBACK
|
||||||
#if SIMDJSON_CAN_ALWAYS_RUN_ARM64 || SIMDJSON_CAN_ALWAYS_RUN_ICELAKE || SIMDJSON_CAN_ALWAYS_RUN_HASWELL || SIMDJSON_CAN_ALWAYS_RUN_WESTMERE || SIMDJSON_CAN_ALWAYS_RUN_PPC64 || SIMDJSON_CAN_ALWAYS_RUN_LSX || SIMDJSON_CAN_ALWAYS_RUN_LASX
|
#if SIMDJSON_CAN_ALWAYS_RUN_ARM64 || SIMDJSON_CAN_ALWAYS_RUN_ICELAKE || SIMDJSON_CAN_ALWAYS_RUN_HASWELL || SIMDJSON_CAN_ALWAYS_RUN_WESTMERE || SIMDJSON_CAN_ALWAYS_RUN_PPC64 || SIMDJSON_CAN_ALWAYS_RUN_LSX || SIMDJSON_CAN_ALWAYS_RUN_LASX || SIMDJSON_CAN_ALWAYS_RUN_RVV
|
||||||
// if anything at all except fallback can always run, then disable fallback.
|
// if anything at all except fallback can always run, then disable fallback.
|
||||||
#define SIMDJSON_IMPLEMENTATION_FALLBACK 0
|
#define SIMDJSON_IMPLEMENTATION_FALLBACK 0
|
||||||
#else
|
#else
|
||||||
@@ -154,6 +164,8 @@
|
|||||||
#define SIMDJSON_BUILTIN_IMPLEMENTATION lsx
|
#define SIMDJSON_BUILTIN_IMPLEMENTATION lsx
|
||||||
#elif SIMDJSON_CAN_ALWAYS_RUN_LASX
|
#elif SIMDJSON_CAN_ALWAYS_RUN_LASX
|
||||||
#define SIMDJSON_BUILTIN_IMPLEMENTATION lasx
|
#define SIMDJSON_BUILTIN_IMPLEMENTATION lasx
|
||||||
|
#elif SIMDJSON_CAN_ALWAYS_RUN_RVV
|
||||||
|
#define SIMDJSON_BUILTIN_IMPLEMENTATION rvv
|
||||||
#elif SIMDJSON_CAN_ALWAYS_RUN_FALLBACK
|
#elif SIMDJSON_CAN_ALWAYS_RUN_FALLBACK
|
||||||
#define SIMDJSON_BUILTIN_IMPLEMENTATION fallback
|
#define SIMDJSON_BUILTIN_IMPLEMENTATION fallback
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef SIMDJSON_RVV_H
|
||||||
|
#define SIMDJSON_RVV_H
|
||||||
|
|
||||||
|
#include "simdjson/rvv/begin.h"
|
||||||
|
#include "simdjson/generic/amalgamated.h"
|
||||||
|
#include "simdjson/rvv/end.h"
|
||||||
|
|
||||||
|
#endif // SIMDJSON_RVV_H
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef SIMDJSON_RVV_BASE_H
|
||||||
|
#define SIMDJSON_RVV_BASE_H
|
||||||
|
|
||||||
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#include "simdjson/base.h"
|
||||||
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
namespace simdjson {
|
||||||
|
namespace rvv {
|
||||||
|
|
||||||
|
class implementation;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
namespace simd {
|
||||||
|
template <typename T> struct simd8;
|
||||||
|
template <typename T> struct simd8x64;
|
||||||
|
} // namespace simd
|
||||||
|
} // unnamed namespace
|
||||||
|
} // namespace rvv
|
||||||
|
} // namespace simdjson
|
||||||
|
#endif // SIMDJSON_RVV_BASE_H
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#define SIMDJSON_IMPLEMENTATION rvv
|
||||||
|
|
||||||
|
// include RVV intrinsics and definitions
|
||||||
|
#include <riscv_vector.h>
|
||||||
|
#include "simdjson/rvv/base.h"
|
||||||
|
#include "simdjson/rvv/intrinsics.h"
|
||||||
|
#include "simdjson/rvv/bitmanipulation.h"
|
||||||
|
#include "simdjson/rvv/bitmask.h"
|
||||||
|
#include "simdjson/rvv/numberparsing_defs.h"
|
||||||
|
#include "simdjson/rvv/simd.h"
|
||||||
|
#include "simdjson/rvv/stringparsing_defs.h"
|
||||||
|
|
||||||
|
#define SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT 1
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#ifndef SIMDJSON_RVV_BITMANIPULATION_H
|
||||||
|
#define SIMDJSON_RVV_BITMANIPULATION_H
|
||||||
|
|
||||||
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#include "simdjson/rvv/base.h"
|
||||||
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
|
||||||
|
namespace simdjson {
|
||||||
|
namespace rvv {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
/* result might be undefined when input_num is zero */
|
||||||
|
simdjson_inline int leading_zeroes(uint64_t input_num) {
|
||||||
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||||||
|
unsigned long leading_zero = 0;
|
||||||
|
if (_BitScanReverse64(&leading_zero, input_num))
|
||||||
|
return (int)(63 - leading_zero);
|
||||||
|
else
|
||||||
|
return 64;
|
||||||
|
#else
|
||||||
|
return __builtin_clzll(input_num);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) {
|
||||||
|
return input_num & (input_num - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
simdjson_inline int count_ones(uint64_t input_num) {
|
||||||
|
return __builtin_popcountll(input_num);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline simdjson::internal::value128 full_multiplication(uint64_t a, uint64_t b) {
|
||||||
|
#if __SIZEOF_INT128__
|
||||||
|
unsigned __int128 p = (unsigned __int128)a * b;
|
||||||
|
return { (uint64_t)p, (uint64_t)(p >> 64) };
|
||||||
|
#else
|
||||||
|
uint64_t lo = a * b;
|
||||||
|
uint64_t a0 = (uint32_t)a, a1 = a >> 32;
|
||||||
|
uint64_t b0 = (uint32_t)b, b1 = b >> 32;
|
||||||
|
uint64_t mid1 = a0 * b1;
|
||||||
|
uint64_t mid2 = a1 * b0;
|
||||||
|
uint64_t carry = ((mid1 & 0xFFFFFFFF) + (mid2 & 0xFFFFFFFF) + (lo >> 32)) >> 32;
|
||||||
|
uint64_t hi = a1 * b1 + (mid1 >> 32) + (mid2 >> 32) + carry;
|
||||||
|
return { lo, hi };
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // unnamed namespace
|
||||||
|
} // namespace rvv
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
|
#endif // SIMDJSON_RVV_BITMANIPULATION_H
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#include "simdjson/rvv/base.h"
|
||||||
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
|
||||||
|
#undef SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT
|
||||||
|
#undef SIMDJSON_IMPLEMENTATION
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef SIMDJSON_RVV_IMPLEMENTATION_H
|
||||||
|
#define SIMDJSON_RVV_IMPLEMENTATION_H
|
||||||
|
|
||||||
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#define SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#include "simdjson/base.h"
|
||||||
|
#include "simdjson/implementation.h"
|
||||||
|
#include "simdjson/internal/instruction_set.h"
|
||||||
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
|
||||||
|
namespace simdjson {
|
||||||
|
namespace rvv {
|
||||||
|
|
||||||
|
class implementation final: public simdjson::implementation {
|
||||||
|
public:
|
||||||
|
simdjson_inline implementation() : simdjson::implementation("rvv", "RISC-V Vector Extension", 0) {}
|
||||||
|
simdjson_warn_unused error_code create_dom_parser_implementation(
|
||||||
|
size_t capacity,
|
||||||
|
size_t max_depth,
|
||||||
|
std::unique_ptr<internal::dom_parser_implementation>& dst
|
||||||
|
) const noexcept final;
|
||||||
|
simdjson_warn_unused error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) const noexcept final;
|
||||||
|
simdjson_warn_unused bool validate_utf8(const char *buf, size_t len) const noexcept final;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace rvv
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
|
#endif // SIMDJSON_RVV_IMPLEMENTATION_H
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef SIMDJSON_RVV_INTRINSICS_H
|
||||||
|
#define SIMDJSON_RVV_INTRINSICS_H
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#include "simdjson/rvv/base.h"
|
||||||
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#endif // SIMDJSON_RVV_INTRINSICS_H
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#ifndef SIMDJSON_RVV_ONDEMAND_H
|
||||||
|
#define SIMDJSON_RVV_ONDEMAND_H
|
||||||
|
|
||||||
|
#include "simdjson/rvv/begin.h"
|
||||||
|
#include "simdjson/generic/ondemand/amalgamated.h"
|
||||||
|
#include "simdjson/rvv/end.h"
|
||||||
|
|
||||||
|
#endif // SIMDJSON_RVV_ONDEMAND_H
|
||||||
|
|
||||||
@@ -0,0 +1,298 @@
|
|||||||
|
#ifndef SIMDJSON_RVV_SIMD_H
|
||||||
|
#define SIMDJSON_RVV_SIMD_H
|
||||||
|
|
||||||
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#include "simdjson/rvv/base.h"
|
||||||
|
#include "simdjson/rvv/intrinsics.h"
|
||||||
|
#include "simdjson/internal/simdprune_tables.h"
|
||||||
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
|
||||||
|
namespace simdjson {
|
||||||
|
namespace rvv {
|
||||||
|
namespace {
|
||||||
|
namespace simd {
|
||||||
|
|
||||||
|
// ---------- 128-bit fixed vectors ----------
|
||||||
|
using vuint8x16 = vuint8m1_t __attribute__((riscv_rvv_vector_bits(128)));
|
||||||
|
using vint8x16 = vint8m1_t __attribute__((riscv_rvv_vector_bits(128)));
|
||||||
|
using vbool8x16 = vbool8_t;
|
||||||
|
static constexpr size_t fixed_vl = 16;
|
||||||
|
|
||||||
|
// ---------- forward ----------
|
||||||
|
template<typename T> struct simd8;
|
||||||
|
template<typename T> struct simd8x64;
|
||||||
|
|
||||||
|
// ---------- base<Child> ----------
|
||||||
|
template<typename Child>
|
||||||
|
struct base {
|
||||||
|
vuint8x16 value{};
|
||||||
|
base() = default;
|
||||||
|
base(vuint8x16 v) : value(v) {}
|
||||||
|
operator vuint8x16() const { return value; }
|
||||||
|
operator vuint8x16&() { return value; }
|
||||||
|
|
||||||
|
simdjson_inline Child operator|(const Child o) const { return __riscv_vor_vv_u8m1(value, o, fixed_vl); }
|
||||||
|
simdjson_inline Child operator&(const Child o) const { return __riscv_vand_vv_u8m1(value, o, fixed_vl); }
|
||||||
|
simdjson_inline Child operator^(const Child o) const { return __riscv_vxor_vv_u8m1(value, o, fixed_vl); }
|
||||||
|
simdjson_inline Child bit_andnot(const Child o) const { return __riscv_vandn_vv_u8m1(value, o, fixed_vl); }
|
||||||
|
|
||||||
|
simdjson_inline Child& operator|=(const Child o) { auto* c = static_cast<Child*>(this); *c = *c | o; return *c; }
|
||||||
|
simdjson_inline Child& operator&=(const Child o) { auto* c = static_cast<Child*>(this); *c = *c & o; return *c; }
|
||||||
|
simdjson_inline Child& operator^=(const Child o) { auto* c = static_cast<Child*>(this); *c = *c ^ o; return *c; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------- base8<T,Mask> ----------
|
||||||
|
template<typename T, typename Mask = simd8<bool>>
|
||||||
|
struct base8 : base<simd8<T>> {
|
||||||
|
using base<simd8<T>>::value;
|
||||||
|
using bitmask_t = uint32_t;
|
||||||
|
base8() = default;
|
||||||
|
base8(vuint8x16 v) : base<simd8<T>>(v) {}
|
||||||
|
|
||||||
|
friend simdjson_inline Mask operator==(const simd8<T> a, const simd8<T> b) {
|
||||||
|
return simd8<bool>(__riscv_vmseq_vv_u8m1_b8(a, b, fixed_vl));
|
||||||
|
}
|
||||||
|
template<int N=1>
|
||||||
|
simdjson_inline simd8<T> prev(const simd8<T> prev_chunk) const {
|
||||||
|
return __riscv_vslideup_vx_u8m1(prev_chunk, value, fixed_vl - N, 2 * fixed_vl);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------- simd8<bool> ----------
|
||||||
|
template<>
|
||||||
|
struct simd8<bool> : base8<bool> {
|
||||||
|
simd8() = default;
|
||||||
|
simd8(vuint8x16 v) : base8(v) {}
|
||||||
|
simd8(vbool8_t m) : base8(__riscv_vmerge_vvm_u8m1(
|
||||||
|
__riscv_vmv_v_x_u8m1(0, fixed_vl),
|
||||||
|
__riscv_vmv_v_x_u8m1(0xFFu, fixed_vl),
|
||||||
|
m, fixed_vl)) {}
|
||||||
|
|
||||||
|
static simdjson_inline simd8<bool> splat(bool b) {
|
||||||
|
return __riscv_vmv_v_x_u8m1(uint8_t(-b), fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8(bool b) : simd8(splat(b)) {}
|
||||||
|
|
||||||
|
simdjson_inline int to_bitmask() const {
|
||||||
|
vuint8x16 bits = __riscv_vand_vx_u8m1(value, 0xFFu, fixed_vl);
|
||||||
|
vbool8x16 mask = __riscv_vmseq_vx_u8m1_b8(bits, 0xFFu, fixed_vl);
|
||||||
|
return __riscv_vcpop_m_b8(mask, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline bool any_bits_set_anywhere() const {
|
||||||
|
return to_bitmask() != 0;
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<bool> operator~() const { return *this ^ splat(true); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------- simd8<uint8_t> ----------
|
||||||
|
template<>
|
||||||
|
struct simd8<uint8_t> : base8<uint8_t> {
|
||||||
|
simd8() = default;
|
||||||
|
simd8(vuint8x16 v) : base8(v) {}
|
||||||
|
static simdjson_inline simd8<uint8_t> splat(uint8_t v) {
|
||||||
|
return __riscv_vmv_v_x_u8m1(v, fixed_vl);
|
||||||
|
}
|
||||||
|
static simdjson_inline simd8<uint8_t> zero() { return splat(0); }
|
||||||
|
static simdjson_inline simd8<uint8_t> load(const uint8_t* p) {
|
||||||
|
return __riscv_vle8_v_u8m1(p, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8(uint8_t v) : simd8(splat(v)) {}
|
||||||
|
simdjson_inline simd8(const uint8_t* p) : simd8(load(p)) {}
|
||||||
|
|
||||||
|
simdjson_inline void store(uint8_t* p) const {
|
||||||
|
__riscv_vse8_v_u8m1(p, value, fixed_vl);
|
||||||
|
}
|
||||||
|
|
||||||
|
simdjson_inline simd8<uint8_t> operator+(const simd8<uint8_t> o) const {
|
||||||
|
return __riscv_vadd_vv_u8m1(value, o, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<uint8_t> operator-(const simd8<uint8_t> o) const {
|
||||||
|
return __riscv_vsub_vv_u8m1(value, o, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<uint8_t>& operator+=(const simd8<uint8_t> o) {
|
||||||
|
*this = *this + o; return *this;
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<uint8_t>& operator-=(const simd8<uint8_t> o) {
|
||||||
|
*this = *this - o; return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
simdjson_inline simd8<uint8_t> saturating_add(const simd8<uint8_t> o) const {
|
||||||
|
return __riscv_vsaddu_vv_u8m1(value, o, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<uint8_t> saturating_sub(const simd8<uint8_t> o) const {
|
||||||
|
return __riscv_vssubu_vv_u8m1(value, o, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<uint8_t> max_val(const simd8<uint8_t> o) const {
|
||||||
|
return __riscv_vmaxu_vv_u8m1(value, o, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<uint8_t> min_val(const simd8<uint8_t> o) const {
|
||||||
|
return __riscv_vminu_vv_u8m1(value, o, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<bool> operator>(const simd8<uint8_t> o) const {
|
||||||
|
return simd8<bool>(__riscv_vmsgtu_vv_u8m1_b8(value, o, fixed_vl));
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<bool> operator<(const simd8<uint8_t> o) const {
|
||||||
|
return simd8<bool>(__riscv_vmsgtu_vv_u8m1_b8(o, value, fixed_vl));
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<bool> operator<=(const simd8<uint8_t> o) const {
|
||||||
|
return simd8<bool>(__riscv_vmsleu_vv_u8m1_b8(value, o, fixed_vl));
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<bool> operator>=(const simd8<uint8_t> o) const {
|
||||||
|
return simd8<bool>(__riscv_vmsleu_vv_u8m1_b8(o, value, fixed_vl));
|
||||||
|
}
|
||||||
|
template<int NS>
|
||||||
|
simdjson_inline simd8<uint8_t> shr() const {
|
||||||
|
return __riscv_vsrl_vx_u8m1(value, NS, fixed_vl);
|
||||||
|
}
|
||||||
|
template<int NS>
|
||||||
|
simdjson_inline simd8<uint8_t> shl() const {
|
||||||
|
return __riscv_vsll_vx_u8m1(value, NS, fixed_vl);
|
||||||
|
}
|
||||||
|
template <typename Ret>
|
||||||
|
simdjson_inline simd8<Ret> lookup_16(const Ret* table) const {
|
||||||
|
alignas(16) uint8_t idx[16];
|
||||||
|
store(idx);
|
||||||
|
alignas(16) Ret res[16];
|
||||||
|
for (int i = 0; i < 16; ++i) res[i] = table[idx[i]];
|
||||||
|
return simd8<Ret>::load(reinterpret_cast<const Ret*>(res));
|
||||||
|
}
|
||||||
|
simdjson_inline void compress(uint16_t mask, uint8_t* out) const {
|
||||||
|
alignas(16) uint8_t tmp[16];
|
||||||
|
store(tmp);
|
||||||
|
for (int i = 0, j = 0; i < 16; ++i)
|
||||||
|
if (mask & (1u << i)) out[j++] = tmp[i];
|
||||||
|
}
|
||||||
|
simdjson_inline uint64_t gt_bits(uint8_t max_value) const {
|
||||||
|
return (*this > splat(max_value)).to_bitmask();
|
||||||
|
}
|
||||||
|
simdjson_inline uint64_t gt_bits(const simd8<uint8_t>& max_vec) const {
|
||||||
|
return (*this > max_vec).to_bitmask();
|
||||||
|
}
|
||||||
|
simdjson_inline bool any_bits_set_anywhere() const {
|
||||||
|
return (*this > zero()).any_bits_set_anywhere();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------- simd8<int8_t> ----------
|
||||||
|
template<>
|
||||||
|
struct simd8<int8_t> {
|
||||||
|
vint8x16 value{};
|
||||||
|
simd8() = default;
|
||||||
|
simd8(vint8x16 v) : value(v) {}
|
||||||
|
static simdjson_inline simd8<int8_t> splat(int8_t v) {
|
||||||
|
return __riscv_vmv_v_x_i8m1(v, fixed_vl);
|
||||||
|
}
|
||||||
|
static simdjson_inline simd8<int8_t> zero() { return splat(0); }
|
||||||
|
static simdjson_inline simd8<int8_t> load(const int8_t* p) {
|
||||||
|
return __riscv_vle8_v_i8m1(p, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8(int8_t v) : simd8(splat(v)) {}
|
||||||
|
simdjson_inline simd8(const int8_t* p) : simd8(load(p)) {}
|
||||||
|
|
||||||
|
simdjson_inline void store(int8_t* p) const {
|
||||||
|
__riscv_vse8_v_i8m1(p, value, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<int8_t> operator+(const simd8<int8_t> o) const {
|
||||||
|
return __riscv_vadd_vv_i8m1(value, o.value, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<int8_t> operator-(const simd8<int8_t> o) const {
|
||||||
|
return __riscv_vsub_vv_i8m1(value, o.value, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<int8_t> max_val(const simd8<int8_t> o) const {
|
||||||
|
return __riscv_vmax_vv_i8m1(value, o.value, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<int8_t> min_val(const simd8<int8_t> o) const {
|
||||||
|
return __riscv_vmin_vv_i8m1(value, o.value, fixed_vl);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<bool> operator>(const simd8<int8_t> o) const {
|
||||||
|
return simd8<bool>(__riscv_vmsgt_vv_i8m1_b8(value, o.value, fixed_vl));
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<bool> operator<(const simd8<int8_t> o) const {
|
||||||
|
return simd8<bool>(__riscv_vmsgt_vv_i8m1_b8(o.value, value, fixed_vl));
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<bool> operator==(const simd8<int8_t> o) const {
|
||||||
|
return simd8<bool>(__riscv_vmseq_vv_i8m1_b8(value, o.value, fixed_vl));
|
||||||
|
}
|
||||||
|
template<int N=1>
|
||||||
|
simdjson_inline simd8<int8_t> prev(const simd8<int8_t> prev_chunk) const {
|
||||||
|
return __riscv_vslideup_vx_i8m1(prev_chunk.value, value, fixed_vl - N, 2 * fixed_vl);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------- simd8x64<T> ----------
|
||||||
|
template<typename T>
|
||||||
|
struct simd8x64 {
|
||||||
|
static constexpr int NUM_CHUNKS = 64 / sizeof(simd8<T>);
|
||||||
|
static_assert(NUM_CHUNKS == 4, "RVV kernel uses 4×128-bit chunks per 64-byte block.");
|
||||||
|
const simd8<T> chunks[4];
|
||||||
|
|
||||||
|
simd8x64(const simd8x64&) = delete;
|
||||||
|
simd8x64& operator=(const simd8x64&) = delete;
|
||||||
|
simd8x64() = delete;
|
||||||
|
|
||||||
|
simdjson_inline simd8x64(const simd8<T> c0, const simd8<T> c1,
|
||||||
|
const simd8<T> c2, const simd8<T> c3)
|
||||||
|
: chunks{c0, c1, c2, c3} {}
|
||||||
|
simdjson_inline simd8x64(const T* ptr)
|
||||||
|
: chunks{simd8<T>::load(ptr),
|
||||||
|
simd8<T>::load(ptr + 16),
|
||||||
|
simd8<T>::load(ptr + 32),
|
||||||
|
simd8<T>::load(ptr + 48)} {}
|
||||||
|
|
||||||
|
simdjson_inline void store(T* ptr) const {
|
||||||
|
chunks[0].store(ptr);
|
||||||
|
chunks[1].store(ptr + 16);
|
||||||
|
chunks[2].store(ptr + 32);
|
||||||
|
chunks[3].store(ptr + 48);
|
||||||
|
}
|
||||||
|
simdjson_inline simd8<T> reduce_or() const {
|
||||||
|
return (chunks[0] | chunks[1]) | (chunks[2] | chunks[3]);
|
||||||
|
}
|
||||||
|
simdjson_inline uint64_t to_bitmask() const {
|
||||||
|
uint16_t m0 = uint16_t(chunks[0].to_bitmask());
|
||||||
|
uint16_t m1 = uint16_t(chunks[1].to_bitmask());
|
||||||
|
uint16_t m2 = uint16_t(chunks[2].to_bitmask());
|
||||||
|
uint16_t m3 = uint16_t(chunks[3].to_bitmask());
|
||||||
|
return m0 | (uint64_t(m1) << 16) | (uint64_t(m2) << 32) | (uint64_t(m3) << 48);
|
||||||
|
}
|
||||||
|
simdjson_inline uint64_t eq(const T m) const {
|
||||||
|
simd8<T> spl = simd8<T>::splat(m);
|
||||||
|
return simd8x64<bool>(chunks[0] == spl,
|
||||||
|
chunks[1] == spl,
|
||||||
|
chunks[2] == spl,
|
||||||
|
chunks[3] == spl).to_bitmask();
|
||||||
|
}
|
||||||
|
simdjson_inline uint64_t lteq(const T m) const {
|
||||||
|
simd8<T> spl = simd8<T>::splat(m);
|
||||||
|
return simd8x64<bool>(chunks[0] <= spl,
|
||||||
|
chunks[1] <= spl,
|
||||||
|
chunks[2] <= spl,
|
||||||
|
chunks[3] <= spl).to_bitmask();
|
||||||
|
}
|
||||||
|
simdjson_inline uint64_t compress(uint64_t mask, T* out) const {
|
||||||
|
using internal::BitsSetTable256mul2;
|
||||||
|
uint32_t m0 = uint32_t(mask);
|
||||||
|
uint32_t m1 = uint32_t(mask >> 16);
|
||||||
|
uint32_t m2 = uint32_t(mask >> 32);
|
||||||
|
uint32_t m3 = uint32_t(mask >> 48);
|
||||||
|
|
||||||
|
int pop0 = BitsSetTable256mul2[uint8_t(m0)];
|
||||||
|
int pop1 = BitsSetTable256mul2[uint8_t(m1)];
|
||||||
|
int pop2 = BitsSetTable256mul2[uint8_t(m2)];
|
||||||
|
|
||||||
|
chunks[0].compress(uint16_t(m0), out);
|
||||||
|
chunks[1].compress(uint16_t(m1), out + 16 - pop0);
|
||||||
|
chunks[2].compress(uint16_t(m2), out + 32 - pop0 - pop1);
|
||||||
|
chunks[3].compress(uint16_t(m3), out + 48 - pop0 - pop1 - pop2);
|
||||||
|
return 64 - __builtin_popcountll(mask);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace simd
|
||||||
|
} // unnamed namespace
|
||||||
|
} // namespace rvv
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
|
|
||||||
|
#endif // SIMDJSON_RVV_SIMD_H
|
||||||
@@ -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.0.4"
|
#define SIMDJSON_VERSION "4.0.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 = 4
|
SIMDJSON_VERSION_REVISION = 2
|
||||||
};
|
};
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ else:
|
|||||||
RelativeRoot = str # Literal['src','include'] # Literal not supported in Python 3.7 (CI)
|
RelativeRoot = str # Literal['src','include'] # Literal not supported in Python 3.7 (CI)
|
||||||
RELATIVE_ROOTS: List[RelativeRoot] = ['src', 'include' ]
|
RELATIVE_ROOTS: List[RelativeRoot] = ['src', 'include' ]
|
||||||
Implementation = str # Literal['arm64', 'fallback', 'haswell', 'icelake', 'ppc64', 'westmere', 'lsx', 'lasx'] # Literal not supported in Python 3.7 (CI)
|
Implementation = str # Literal['arm64', 'fallback', 'haswell', 'icelake', 'ppc64', 'westmere', 'lsx', 'lasx'] # Literal not supported in Python 3.7 (CI)
|
||||||
IMPLEMENTATIONS: List[Implementation] = [ 'arm64', 'haswell', 'icelake', 'lasx', 'lsx', 'ppc64', 'westmere', 'fallback' ]
|
IMPLEMENTATIONS: List[Implementation] = [ 'arm64', 'haswell', 'icelake', 'lasx', 'lsx', 'ppc64', 'westmere', 'fallback', 'rvv' ]
|
||||||
GENERIC_INCLUDE = "simdjson/generic"
|
GENERIC_INCLUDE = "simdjson/generic"
|
||||||
GENERIC_SRC = "generic"
|
GENERIC_SRC = "generic"
|
||||||
BUILTIN = "simdjson/builtin"
|
BUILTIN = "simdjson/builtin"
|
||||||
@@ -358,7 +358,6 @@ class Amalgamator:
|
|||||||
self.include_stack.append(file)
|
self.include_stack.append(file)
|
||||||
|
|
||||||
file.processed = False
|
file.processed = False
|
||||||
|
|
||||||
self.write(f"/* begin file {self.file_to_str(file)} */")
|
self.write(f"/* begin file {self.file_to_str(file)} */")
|
||||||
|
|
||||||
if file == BUILTIN_BEGIN_H:
|
if file == BUILTIN_BEGIN_H:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* auto-generated on 2025-09-17 18:58:25 -0600. version 4.0.4 Do not edit! */
|
/* auto-generated on 2025-09-14 09:01:41 -0600. version 4.0.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
|
||||||
|
|||||||
+76
-533
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -21,6 +21,19 @@ bool implementation::supported_by_runtime_system() const {
|
|||||||
|
|
||||||
#define SIMDJSON_CONDITIONAL_INCLUDE
|
#define SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
|
||||||
|
#if SIMDJSON_IMPLEMENTATION_RVV
|
||||||
|
#include <simdjson/rvv/implementation.h>
|
||||||
|
namespace simdjson {
|
||||||
|
namespace internal {
|
||||||
|
static const rvv::implementation* get_rvv_singleton() {
|
||||||
|
static const rvv::implementation rvv_singleton{};
|
||||||
|
return &rvv_singleton;
|
||||||
|
}
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace simdjson
|
||||||
|
#endif // SIMDJSON_IMPLEMENTATION_RVV
|
||||||
|
|
||||||
|
|
||||||
#if SIMDJSON_IMPLEMENTATION_ARM64
|
#if SIMDJSON_IMPLEMENTATION_ARM64
|
||||||
#include <simdjson/arm64/implementation.h>
|
#include <simdjson/arm64/implementation.h>
|
||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
@@ -130,6 +143,7 @@ namespace internal {
|
|||||||
+ SIMDJSON_IMPLEMENTATION_HASWELL + SIMDJSON_IMPLEMENTATION_WESTMERE \
|
+ SIMDJSON_IMPLEMENTATION_HASWELL + SIMDJSON_IMPLEMENTATION_WESTMERE \
|
||||||
+ SIMDJSON_IMPLEMENTATION_ARM64 + SIMDJSON_IMPLEMENTATION_PPC64 \
|
+ SIMDJSON_IMPLEMENTATION_ARM64 + SIMDJSON_IMPLEMENTATION_PPC64 \
|
||||||
+ SIMDJSON_IMPLEMENTATION_LSX + SIMDJSON_IMPLEMENTATION_LASX \
|
+ SIMDJSON_IMPLEMENTATION_LSX + SIMDJSON_IMPLEMENTATION_LASX \
|
||||||
|
+ SIMDJSON_IMPLEMENTATION_RVV \
|
||||||
+ SIMDJSON_IMPLEMENTATION_FALLBACK == 1)
|
+ SIMDJSON_IMPLEMENTATION_FALLBACK == 1)
|
||||||
|
|
||||||
#if SIMDJSON_SINGLE_IMPLEMENTATION
|
#if SIMDJSON_SINGLE_IMPLEMENTATION
|
||||||
@@ -156,6 +170,9 @@ namespace internal {
|
|||||||
#if SIMDJSON_IMPLEMENTATION_LASX
|
#if SIMDJSON_IMPLEMENTATION_LASX
|
||||||
get_lasx_singleton();
|
get_lasx_singleton();
|
||||||
#endif
|
#endif
|
||||||
|
#if SIMDJSON_IMPLEMENTATION_RVV
|
||||||
|
get_rvv_singleton();
|
||||||
|
#endif
|
||||||
#if SIMDJSON_IMPLEMENTATION_FALLBACK
|
#if SIMDJSON_IMPLEMENTATION_FALLBACK
|
||||||
get_fallback_singleton();
|
get_fallback_singleton();
|
||||||
#endif
|
#endif
|
||||||
@@ -216,6 +233,9 @@ static const std::initializer_list<const implementation *>& get_available_implem
|
|||||||
#if SIMDJSON_IMPLEMENTATION_LASX
|
#if SIMDJSON_IMPLEMENTATION_LASX
|
||||||
get_lasx_singleton(),
|
get_lasx_singleton(),
|
||||||
#endif
|
#endif
|
||||||
|
#if SIMDJSON_IMPLEMENTATION_RVV
|
||||||
|
get_rvv_singleton(),
|
||||||
|
#endif
|
||||||
#if SIMDJSON_IMPLEMENTATION_FALLBACK
|
#if SIMDJSON_IMPLEMENTATION_FALLBACK
|
||||||
get_fallback_singleton(),
|
get_fallback_singleton(),
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef SIMDJSON_SRC_RVV_CPP
|
||||||
|
#define SIMDJSON_SRC_RVV_CPP
|
||||||
|
|
||||||
|
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
#include <base.h>
|
||||||
|
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||||
|
|
||||||
|
|
||||||
|
#include <simdjson/rvv.h>
|
||||||
|
#include <simdjson/rvv/implementation.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace simdjson {
|
||||||
|
namespace rvv {
|
||||||
|
error_code implementation::create_dom_parser_implementation(
|
||||||
|
size_t, size_t,
|
||||||
|
std::unique_ptr<simdjson::internal::dom_parser_implementation>&) const noexcept {
|
||||||
|
return error_code::UNSUPPORTED_ARCHITECTURE;
|
||||||
|
}
|
||||||
|
} // namespace rvv
|
||||||
|
} // namespace simdjson
|
||||||
|
#endif // SIMDJSON_SRC_RVV_CPP
|
||||||
@@ -41,6 +41,9 @@ SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS
|
|||||||
#if SIMDJSON_IMPLEMENTATION_LASX
|
#if SIMDJSON_IMPLEMENTATION_LASX
|
||||||
#include <lasx.cpp>
|
#include <lasx.cpp>
|
||||||
#endif
|
#endif
|
||||||
|
#if SIMDJSON_IMPLEMENTATION_RVV
|
||||||
|
#include <rvv.cpp>
|
||||||
|
#endif
|
||||||
#if SIMDJSON_IMPLEMENTATION_FALLBACK
|
#if SIMDJSON_IMPLEMENTATION_FALLBACK
|
||||||
#include <fallback.cpp>
|
#include <fallback.cpp>
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -331,6 +331,8 @@ namespace builder_tests {
|
|||||||
TEST_SUCCEED();
|
TEST_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void serialize_car(const Car& car, simdjson::builder::string_builder& builder) {
|
void serialize_car(const Car& car, simdjson::builder::string_builder& builder) {
|
||||||
// start of JSON
|
// start of JSON
|
||||||
builder.start_object();
|
builder.start_object();
|
||||||
@@ -367,43 +369,7 @@ namespace builder_tests {
|
|||||||
builder.end_object();
|
builder.end_object();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SIMDJSON_SUPPORTS_CONCEPTS
|
|
||||||
void serialize_car_template(const Car& car, simdjson::builder::string_builder& builder) {
|
|
||||||
// start of JSON
|
|
||||||
builder.start_object();
|
|
||||||
|
|
||||||
// "make"
|
|
||||||
builder.append_key_value<"make">(car.make);
|
|
||||||
builder.append_comma();
|
|
||||||
|
|
||||||
// "model"
|
|
||||||
builder.append_key_value<"model">(car.model);
|
|
||||||
|
|
||||||
builder.append_comma();
|
|
||||||
|
|
||||||
// "year"
|
|
||||||
builder.append_key_value<"year">(car.year);
|
|
||||||
|
|
||||||
builder.append_comma();
|
|
||||||
|
|
||||||
// "tire_pressure"
|
|
||||||
builder.escape_and_append_with_quotes<"tire_pressure">();
|
|
||||||
builder.append_colon();
|
|
||||||
builder.start_array();
|
|
||||||
// vector tire_pressure
|
|
||||||
for (size_t i = 0; i < car.tire_pressure.size(); ++i) {
|
|
||||||
builder.append(car.tire_pressure[i]);
|
|
||||||
if (i < car.tire_pressure.size() - 1) {
|
|
||||||
builder.append_comma();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// end of array
|
|
||||||
builder.end_array();
|
|
||||||
|
|
||||||
// end of object
|
|
||||||
builder.end_object();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
bool car_test() {
|
bool car_test() {
|
||||||
TEST_START();
|
TEST_START();
|
||||||
simdjson::builder::string_builder sb;
|
simdjson::builder::string_builder sb;
|
||||||
@@ -416,17 +382,6 @@ namespace builder_tests {
|
|||||||
TEST_SUCCEED();
|
TEST_SUCCEED();
|
||||||
}
|
}
|
||||||
#if SIMDJSON_SUPPORTS_CONCEPTS
|
#if SIMDJSON_SUPPORTS_CONCEPTS
|
||||||
bool car_test_template() {
|
|
||||||
TEST_START();
|
|
||||||
simdjson::builder::string_builder sb;
|
|
||||||
Car c = {"Toyota", "Corolla", 2017, {30.0,30.2,30.513,30.79}};
|
|
||||||
serialize_car_template(c, sb);
|
|
||||||
std::string_view p;
|
|
||||||
auto result = sb.view().get(p);
|
|
||||||
ASSERT_SUCCESS(result);
|
|
||||||
ASSERT_EQUAL(p, "{\"make\":\"Toyota\",\"model\":\"Corolla\",\"year\":2017,\"tire_pressure\":[30.0,30.2,30.513,30.79]}");
|
|
||||||
TEST_SUCCEED();
|
|
||||||
}
|
|
||||||
bool serialize_optional() {
|
bool serialize_optional() {
|
||||||
TEST_START();
|
TEST_START();
|
||||||
simdjson::builder::string_builder sb;
|
simdjson::builder::string_builder sb;
|
||||||
@@ -574,7 +529,6 @@ namespace builder_tests {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if SIMDJSON_SUPPORTS_CONCEPTS
|
#if SIMDJSON_SUPPORTS_CONCEPTS
|
||||||
car_test_template() &&
|
|
||||||
serialize_optional() &&
|
serialize_optional() &&
|
||||||
#endif
|
#endif
|
||||||
append_char() &&
|
append_char() &&
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ endif()
|
|||||||
|
|
||||||
# Add the tests if we're on:
|
# Add the tests if we're on:
|
||||||
# 1. Visual Studio 2022 v17.6 or later
|
# 1. Visual Studio 2022 v17.6 or later
|
||||||
# 2. GCC v14.0.0 or later (GCC v13.0.0 cannot handle pipe operator of lambda)
|
# 2. GCC v14.0.0 or later (GCC v13.0.0 cannot handle pipe oprator of lambda)
|
||||||
# 3. Clang v15.0.0 or later (certain version C++ headers occur error when compiling)
|
# 3. Clang v15.0.0 or later (certain version C++ headers occur error when compiling)
|
||||||
if(
|
if(
|
||||||
(MSVC AND MSVC_VERSION LESS 1930) OR
|
(MSVC AND MSVC_VERSION LESS 1930) OR
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
#include "simdjson/convert.h"
|
#include "simdjson/convert.h"
|
||||||
#include "test_ondemand.h"
|
#include "test_ondemand.h"
|
||||||
|
|
||||||
#include <chrono>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -22,24 +21,6 @@ private:
|
|||||||
std::string date_str;
|
std::string date_str;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Meeting {
|
|
||||||
std::string title;
|
|
||||||
std::vector<std::string> attendees;
|
|
||||||
std::optional<std::string> location;
|
|
||||||
bool is_recurring;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct MeetingTime {
|
|
||||||
std::string title;
|
|
||||||
std::chrono::system_clock::time_point start_time;
|
|
||||||
std::vector<std::string> attendees;
|
|
||||||
std::optional<std::string> location;
|
|
||||||
bool is_recurring;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
template <typename simdjson_value>
|
template <typename simdjson_value>
|
||||||
auto tag_invoke(deserialize_tag, simdjson_value &val, MyDate& date) {
|
auto tag_invoke(deserialize_tag, simdjson_value &val, MyDate& date) {
|
||||||
@@ -62,24 +43,7 @@ struct complicated_weather_data {
|
|||||||
#ifdef __cpp_lib_ranges
|
#ifdef __cpp_lib_ranges
|
||||||
|
|
||||||
namespace convert_tests {
|
namespace convert_tests {
|
||||||
|
#if SIMDJSON_EXCEPTIONS && SIMDJSON_SUPPORTS_CONCEPTS
|
||||||
simdjson::padded_string json_car =
|
|
||||||
R"( {
|
|
||||||
"make": "Toyota",
|
|
||||||
"model": "Camry",
|
|
||||||
"year": 2018,
|
|
||||||
"tire_pressure": [ 40.1, 39.9 ]
|
|
||||||
} )"_padded;
|
|
||||||
simdjson::padded_string json_cars =
|
|
||||||
R"( [ { "make": "Toyota", "model": "Camry", "year": 2018,
|
|
||||||
"tire_pressure": [ 40.1, 39.9 ] },
|
|
||||||
{ "make": "Kia", "model": "Soul", "year": 2012,
|
|
||||||
"tire_pressure": [ 30.1, 31.0 ] },
|
|
||||||
{ "make": "Toyota", "model": "Tercel", "year": 1999,
|
|
||||||
"tire_pressure": [ 29.8, 30.0 ] }
|
|
||||||
])"_padded;
|
|
||||||
|
|
||||||
#if SIMDJSON_SUPPORTS_CONCEPTS
|
|
||||||
struct Car {
|
struct Car {
|
||||||
std::string make{};
|
std::string make{};
|
||||||
std::string model{};
|
std::string model{};
|
||||||
@@ -131,17 +95,21 @@ simdjson::padded_string json_cars =
|
|||||||
"It should be deserializable");
|
"It should be deserializable");
|
||||||
|
|
||||||
|
|
||||||
bool simple_no_except() {
|
simdjson::padded_string json_car =
|
||||||
TEST_START();
|
R"( {
|
||||||
Car car;
|
"make": "Toyota",
|
||||||
ASSERT_SUCCESS(simdjson::from(json_car).get(car));
|
"model": "Camry",
|
||||||
if (car.make != "Toyota" || car.model != "Camry" || car.year != 2018) {
|
"year": 2018,
|
||||||
return false;
|
"tire_pressure": [ 40.1, 39.9 ]
|
||||||
}
|
} )"_padded;
|
||||||
TEST_SUCCEED();
|
simdjson::padded_string json_cars =
|
||||||
}
|
R"( [ { "make": "Toyota", "model": "Camry", "year": 2018,
|
||||||
#endif // SIMDJSON_SUPPORTS_CONCEPTS
|
"tire_pressure": [ 40.1, 39.9 ] },
|
||||||
#if SIMDJSON_EXCEPTIONS && SIMDJSON_SUPPORTS_CONCEPTS
|
{ "make": "Kia", "model": "Soul", "year": 2012,
|
||||||
|
"tire_pressure": [ 30.1, 31.0 ] },
|
||||||
|
{ "make": "Toyota", "model": "Tercel", "year": 1999,
|
||||||
|
"tire_pressure": [ 29.8, 30.0 ] }
|
||||||
|
])"_padded;
|
||||||
|
|
||||||
bool simple() {
|
bool simple() {
|
||||||
TEST_START();
|
TEST_START();
|
||||||
@@ -152,6 +120,7 @@ simdjson::padded_string json_cars =
|
|||||||
TEST_SUCCEED();
|
TEST_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct BadPlayer {
|
struct BadPlayer {
|
||||||
int username; // Oops, should be string!
|
int username; // Oops, should be string!
|
||||||
int level;
|
int level;
|
||||||
@@ -191,38 +160,6 @@ simdjson::padded_string json_cars =
|
|||||||
ASSERT_SUCCESS(doc.get(p));
|
ASSERT_SUCCESS(doc.get(p));
|
||||||
TEST_SUCCEED();
|
TEST_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool meeting_test() {
|
|
||||||
TEST_START();
|
|
||||||
std::string json = simdjson::to_json(Meeting{
|
|
||||||
.title = "CppCon Planning",
|
|
||||||
.attendees = {"Alice", "Bob", "Charlie"},
|
|
||||||
.location = "Denver",
|
|
||||||
.is_recurring = true
|
|
||||||
});
|
|
||||||
Meeting m2 = simdjson::from(json);
|
|
||||||
std::cout << m2.title << std::endl;
|
|
||||||
TEST_SUCCEED();
|
|
||||||
}
|
|
||||||
bool meeting_time_test() {
|
|
||||||
TEST_START();
|
|
||||||
auto start_time = std::chrono::system_clock::now();
|
|
||||||
std::string json = simdjson::to_json(MeetingTime{
|
|
||||||
.title = "CppCon Planning",
|
|
||||||
.start_time = start_time,
|
|
||||||
.attendees = {"Alice", "Bob", "Charlie"},
|
|
||||||
.location = "Denver",
|
|
||||||
.is_recurring = true
|
|
||||||
});
|
|
||||||
std::cout << json << std::endl;
|
|
||||||
MeetingTime m2 = simdjson::from(json);
|
|
||||||
//ASSERT_EQUAL(m2.start_time, start_time);
|
|
||||||
std::cout << m2.title << std::endl;
|
|
||||||
TEST_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
bool broken() {
|
bool broken() {
|
||||||
TEST_START();
|
TEST_START();
|
||||||
@@ -478,10 +415,7 @@ bool test_to_vs_from_equivalence() {
|
|||||||
bool run() {
|
bool run() {
|
||||||
return
|
return
|
||||||
#if SIMDJSON_STATIC_REFLECTION
|
#if SIMDJSON_STATIC_REFLECTION
|
||||||
meeting_time_test() && meeting_test() && bad_player() && good_player() && complicated_weather_test() &&
|
bad_player() && good_player() && complicated_weather_test() &&
|
||||||
#endif
|
|
||||||
#if SIMDJSON_SUPPORTS_CONCEPTS
|
|
||||||
simple_no_except() &&
|
|
||||||
#endif
|
#endif
|
||||||
#if SIMDJSON_EXCEPTIONS && SIMDJSON_SUPPORTS_CONCEPTS
|
#if SIMDJSON_EXCEPTIONS && SIMDJSON_SUPPORTS_CONCEPTS
|
||||||
broken() && simple() && simple_optional() && with_parser() && to_array() &&
|
broken() && simple() && simple_optional() && with_parser() && to_array() &&
|
||||||
|
|||||||
Reference in New Issue
Block a user