mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 25fcc8b432 | |||
| a9c120f779 | |||
| b1487e34c3 | |||
| 2a68a32012 | |||
| 21a2ccaeb8 | |||
| 6cbb6ac89b | |||
| e9f0f1bb9b | |||
| 7ef1ebd4fb | |||
| 8de540e267 | |||
| ebc51fbd1a | |||
| 84a31c1615 | |||
| f77ac963f4 | |||
| ae3d912f8d | |||
| abf3d7d440 | |||
| 3c313b8530 | |||
| f435fddda1 |
@@ -12,24 +12,26 @@ Before submitting an issue, please ensure that you have read the documentation:
|
||||
* Basics is an overview of how to use simdjson and its APIs: https://github.com/simdjson/simdjson/blob/master/doc/basics.md
|
||||
* Performance shows some more advanced scenarios and how to tune for them: https://github.com/simdjson/simdjson/blob/master/doc/performance.md
|
||||
* Contributing: https://github.com/simdjson/simdjson/blob/master/CONTRIBUTING.md
|
||||
* We follow the [JSON specification as described by RFC 8259](https://www.rfc-editor.org/rfc/rfc8259.txt) (T. Bray, 2017).
|
||||
* We follow the [JSON specification as described by RFC 8259](https://www.rfc-editor.org/rfc/rfc8259.txt) (T. Bray, 2017). If you wish to support features that are not part of RFC 8259, then you should not refer to your issue as a bug.
|
||||
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
A clear and concise description of what the bug is. A bug is a failure to build with normal compiler settings or a misbehaviour: when running the code, you get a result that differs from the expected result from our documentation.
|
||||
|
||||
A compiler or static-analyzer warning is not a bug.
|
||||
A compiler or static-analyzer warning is not a bug. It is possible with tools such as Visual Studio to require that rarely enabled warnings are considered errors. Do not report such cases as bugs. We do accept pull requests if you want to silence warnings issued by code analyzers, however.
|
||||
|
||||
We are committed to providing good documentation. We accept the lack of documentation or a misleading documentation as a bug (a 'documentation bug').
|
||||
|
||||
An unexpected poor software performance can be accepted as a bug (a 'performance bug').
|
||||
|
||||
We accept the identification of an issue by a sanitizer or some checker tool (e.g., valgrind) as a bug, but you must first ensure that it is not a false positive.
|
||||
|
||||
We recommend that you run your tests using different optimization levels.
|
||||
We recommend that you run your tests using different optimization levels. In particular, we recommend your run tests with the simdjson library and you code compiled in debug mode. The simdjson then sets the SIMDJSON_DEVELOPMENT_CHECKS macro to 1, and this triggers additional checks on your code and on the internals of the library. If possible, we recommend that you run tests with sanitizers (e.g., see [No more leaks with sanitize flags in gcc and clang](https://lemire.me/blog/2016/04/20/no-more-leaks-with-sanitize-flags-in-gcc-and-clang/)). You can compile the library with sanitizers for debugging purposes (e.g., set SIMDJSON_SANITIZE to ON using CMake), but you should also turn on sanitizers on your own code. You may also use tools like valgrind or the commercial equivalent.
|
||||
|
||||
Before reporting a bug, please ensure that you have read our documentation.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behaviour: provide a code sample if possible.
|
||||
Steps to reproduce the behaviour: provide a code sample if possible. Please provide a complete test with data. Remember that a bug is either a failure to build or an unexpected result when running the code.
|
||||
|
||||
If we cannot reproduce the issue, then we cannot address it. Note that a stack trace from your own program is not enough. A sample of your source code is insufficient: please provide a complete test for us to reproduce the issue. Please reduce the issue: use as small and as simple an example of the bug as possible.
|
||||
|
||||
@@ -51,6 +53,6 @@ We support up-to-date 64-bit ARM and x64 FreeBSD, macOS, Windows and Linux syste
|
||||
|
||||
**Indicate whether you are willing or able to provide a bug fix as a pull request**
|
||||
|
||||
If you plan to contribute to simdjson, please read our
|
||||
If you plan to contribute to simdjson, please read our guide:
|
||||
* CONTRIBUTING guide: https://github.com/simdjson/simdjson/blob/master/CONTRIBUTING.md and our
|
||||
* HACKING guide: https://github.com/simdjson/simdjson/blob/master/HACKING.md
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
name: Ubuntu ppc64le (GCC 11)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: uraimo/run-on-arch-action@v2
|
||||
name: Test
|
||||
id: runcmd
|
||||
with:
|
||||
arch: ppc64le
|
||||
distro: ubuntu_latest
|
||||
githubToken: ${{ github.token }}
|
||||
install: |
|
||||
apt-get update -q -y
|
||||
apt-get install -y cmake make g++
|
||||
run: |
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -B build
|
||||
cmake --build build -j=2
|
||||
ctest --output-on-failure --test-dir build
|
||||
@@ -14,10 +14,17 @@ jobs:
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
key: ${{ hashFiles('dependencies/CMakeLists.txt') }}
|
||||
- name: Use cmake
|
||||
- name: Use cmake with address sanitizer
|
||||
run: |
|
||||
mkdir builddebug &&
|
||||
cd builddebug &&
|
||||
cmake -DSIMDJSON_SANITIZE=ON -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF .. &&
|
||||
cmake --build . &&
|
||||
ctest -j --output-on-failure -LE explicitonly
|
||||
ctest -j --output-on-failure -LE explicitonly
|
||||
- name: Use cmake with undefined sanitizer
|
||||
run: |
|
||||
mkdir builddebugundefsani &&
|
||||
cd builddebugundefsani &&
|
||||
cmake -DSIMDJSON_SANITIZE_UNDEFINED=ON -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF .. &&
|
||||
cmake --build . &&
|
||||
ctest -j --output-on-failure -LE explicitonly
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14)
|
||||
project(
|
||||
simdjson
|
||||
# The version number is modified by tools/release.py
|
||||
VERSION 3.1.7
|
||||
VERSION 3.1.8
|
||||
DESCRIPTION "Parsing gigabytes of JSON per second"
|
||||
HOMEPAGE_URL "https://simdjson.org/"
|
||||
LANGUAGES CXX C
|
||||
|
||||
@@ -38,7 +38,7 @@ PROJECT_NAME = simdjson
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = "3.1.7"
|
||||
PROJECT_NUMBER = "3.1.8"
|
||||
|
||||
# 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
|
||||
|
||||
@@ -124,6 +124,8 @@ Real-world usage
|
||||
- [Dgraph](https://github.com/dgraph-io/dgraph)
|
||||
- [UJRPC](https://github.com/unum-cloud/ujrpc)
|
||||
- [fastgltf](https://github.com/spnda/fastgltf)
|
||||
- [Clang Build Analyzer](https://github.com/aras-p/ClangBuildAnalyzer)
|
||||
- [vast](https://github.com/tenzir/vast)
|
||||
|
||||
If you are planning to use simdjson in a product, please work from one of our releases.
|
||||
|
||||
@@ -146,10 +148,12 @@ We distinguish between "bindings" (which just wrap the C++ code) and a port to a
|
||||
- [simdjson-go](https://github.com/minio/simdjson-go): Go port using Golang assembly.
|
||||
- [rcppsimdjson](https://github.com/eddelbuettel/rcppsimdjson): R bindings.
|
||||
- [simdjson_erlang](https://github.com/ChomperT/simdjson_erlang): erlang bindings.
|
||||
- [simdjsone](https://github.com/saleyn/simdjsone): erlang bindings.
|
||||
- [lua-simdjson](https://github.com/FourierTransformer/lua-simdjson): lua bindings.
|
||||
- [hermes-json](https://hackage.haskell.org/package/hermes-json): haskell bindings.
|
||||
- [simdjzon](https://github.com/travisstaloch/simdjzon): zig port.
|
||||
- [JSON-Simd](https://github.com/rawleyfowler/JSON-simd): Raku bindings.
|
||||
- [JSON::SIMD](https://metacpan.org/pod/JSON::SIMD): Perl bindings; fully-featured JSON module that uses simdjson for decoding.
|
||||
|
||||
About simdjson
|
||||
--------------
|
||||
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
# 0.5
|
||||
|
||||
## Highlights
|
||||
|
||||
Performance
|
||||
* Faster and simpler UTF-8 validation with the lookup4 algorithm https://github.com/simdjson/simdjson/pull/993
|
||||
* We improved the performance of simdjson under Visual Studio by about 25%. Users will still get better performance with clang-cl (+30%) but the gap has been reduced. https://github.com/simdjson/simdjson/pull/1031
|
||||
|
||||
Code usability
|
||||
* In `parse_many`, when parsing streams of JSON documetns, we give to the users runtime control as to whether threads are used (via the parser.threaded attribute). https://github.com/simdjson/simdjson/issues/925
|
||||
* Prefixed public macros to avoid name clashes with other libraries. https://github.com/simdjson/simdjson/issues/1035
|
||||
* Better documentation regarding package managers (brew, MSYS2, conan, apt, vcpkg, FreeBSD package manager, etc.).
|
||||
* Better documentation regarding CMake usage.
|
||||
|
||||
Standards
|
||||
* We improved standard compliance with respect to both the JSON RFC 8259 and JSON Pointer RFC 6901. We added the at_pointer method to nodes for standard-compliant JSON Pointer queries. The legacy `at(std::string_view)` method remains but is deprecated since it is not standard-compliant as per RFC 6901.
|
||||
* We removed computed GOTOs without sacrificing performance thus improving the C++ standard compliance (since computed GOTOs are compiler-specific extensions).
|
||||
* Better support for C++20 https://github.com/simdjson/simdjson/pull/1050
|
||||
|
||||
# 0.4
|
||||
|
||||
## Highlights
|
||||
|
||||
- Test coverage has been greatly improved and we have resolved many static-analysis warnings on different systems.
|
||||
- We added a fast (8GB/s) minifier that works directly on JSON strings.
|
||||
- We added fast (10GB/s) UTF-8 validator that works directly on strings (any strings, including non-JSON).
|
||||
- The array and object elements have a constant-time size() method.
|
||||
- Performance improvements to the API (type(), get<>()).
|
||||
- The parse_many function (ndjson) has been entirely reworked. It now uses a single secondary thread instead of several new threads.
|
||||
- We have introduced a faster UTF-8 validation algorithm (lookup3) for all kernels (ARM, x64 SSE, x64 AVX).
|
||||
- C++11 support for older compilers and systems.
|
||||
- FreeBSD support (and tests).
|
||||
- We support the clang front-end compiler (clangcl) under Visual Studio.
|
||||
- It is now possible to target ARM platforms under Visual Studio.
|
||||
- The simdjson library will never abort or print to standard output/error.
|
||||
|
||||
# 0.3
|
||||
|
||||
## Highlights
|
||||
|
||||
- **Multi-Document Parsing:** Read a bundle of JSON documents (ndjson) 2-4x faster than doing it
|
||||
individually. [API docs](https://github.com/simdjson/simdjson/blob/master/doc/basics.md#newline-delimited-json-ndjson-and-json-lines) / [Design Details](https://github.com/simdjson/simdjson/blob/master/doc/parse_many.md)
|
||||
- **Simplified API:** The API has been completely revamped for ease of use, including a new JSON
|
||||
navigation API and fluent support for error code *and* exception styles of error handling with a
|
||||
single API. [Docs](https://github.com/simdjson/simdjson/blob/master/doc/basics.md#the-basics-loading-and-parsing-json-documents)
|
||||
- **Exact Float Parsing:** Now simdjson parses floats flawlessly *without* any performance loss,
|
||||
thanks to [great work by @michaeleisel and @lemire](https://github.com/simdjson/simdjson/pull/558).
|
||||
[Blog Post](https://lemire.me/blog/2020/03/10/fast-float-parsing-in-practice/)
|
||||
- **Even Faster:** The fastest parser got faster! With a [shiny new UTF-8 validator](https://github.com/simdjson/simdjson/pull/387)
|
||||
and meticulously refactored SIMD core, simdjson 0.3 is 15% faster than before, running at 2.5 GB/s
|
||||
(where 0.2 ran at 2.2 GB/s).
|
||||
|
||||
## Minor Highlights
|
||||
|
||||
- Fallback implementation: simdjson now has a non-SIMD fallback implementation, and can run even on
|
||||
very old 64-bit machines.
|
||||
- Automatic allocation: as part of API simplification, the parser no longer has to be preallocated--
|
||||
it will adjust automatically when it encounters larger files.
|
||||
- Runtime selection API: We've exposed simdjson's runtime CPU detection and implementation selection
|
||||
as an API, so you can tell what implementation we detected and test with other implementations.
|
||||
- Error handling your way: Whether you use exceptions or check error codes, simdjson lets you handle
|
||||
errors in your style. APIs that can fail return simdjson_result<T>, letting you check the error
|
||||
code before using the result. But if you are more comfortable with exceptions, skip the error code
|
||||
and cast straight to T, and exceptions will be thrown automatically if an error happens. Use the
|
||||
same API either way!
|
||||
- Error chaining: We also worked to keep non-exception error-handling short and sweet. Instead of
|
||||
having to check the error code after every single operation, now you can *chain* JSON navigation
|
||||
calls like looking up an object field or array element, or casting to a string, so that you only
|
||||
have to check the error code once at the very end.
|
||||
@@ -134,7 +134,7 @@ struct event_collector {
|
||||
|
||||
#if defined(__linux__)
|
||||
LinuxEvents<PERF_TYPE_HARDWARE> linux_events;
|
||||
event_collector(bool quiet = false) : linux_events(vector<int>{
|
||||
event_collector(simdjson_unused bool quiet = false) : linux_events(vector<int>{
|
||||
#if SIMDJSON_SIMPLE_PERFORMANCE_COUNTERS
|
||||
PERF_COUNT_HW_CPU_CYCLES,
|
||||
PERF_COUNT_HW_INSTRUCTIONS,
|
||||
@@ -145,7 +145,7 @@ struct event_collector {
|
||||
PERF_COUNT_HW_CACHE_REFERENCES,
|
||||
PERF_COUNT_HW_CACHE_MISSES
|
||||
#endif
|
||||
}, quiet) {}
|
||||
}) {}
|
||||
bool has_events() {
|
||||
return linux_events.is_working();
|
||||
}
|
||||
|
||||
@@ -1,22 +1,13 @@
|
||||
// https://github.com/WojciechMula/toys/blob/master/000helpers/linux-perf-events.h
|
||||
#pragma once
|
||||
#ifdef __linux__
|
||||
#ifdef __has_include
|
||||
#if __has_include(<asm/unistd.h>)
|
||||
|
||||
#include <asm/unistd.h> // for __NR_perf_event_open
|
||||
#else
|
||||
#warning "Header asm/unistd.h cannot be found though it is a linux system. Are linux headers missing?"
|
||||
#endif
|
||||
#else // no __has_include
|
||||
// Please insure that linux headers have been installed.
|
||||
#include <asm/unistd.h> // for __NR_perf_event_open
|
||||
#endif
|
||||
#include <linux/perf_event.h> // for perf event constants
|
||||
#include <sys/ioctl.h> // for ioctl
|
||||
#include <unistd.h> // for syscall
|
||||
|
||||
#include <cerrno> // for errno
|
||||
#include <cstring> // for std::memset
|
||||
#include <cstring> // for memset
|
||||
#include <stdexcept>
|
||||
|
||||
#include <iostream>
|
||||
@@ -28,13 +19,11 @@ template <int TYPE = PERF_TYPE_HARDWARE> class LinuxEvents {
|
||||
perf_event_attr attribs{};
|
||||
size_t num_events{};
|
||||
std::vector<uint64_t> temp_result_vec{};
|
||||
std::vector<uint64_t> result{};
|
||||
std::vector<int> fds{};
|
||||
bool quiet;
|
||||
std::vector<uint64_t> ids{};
|
||||
|
||||
public:
|
||||
explicit LinuxEvents(std::vector<int> config_vec, bool _quiet=false) : fd(0), working(true), quiet{_quiet} {
|
||||
std::memset(&attribs, 0, sizeof(attribs));
|
||||
explicit LinuxEvents(std::vector<int> config_vec) : fd(0), working(true) {
|
||||
memset(&attribs, 0, sizeof(attribs));
|
||||
attribs.type = TYPE;
|
||||
attribs.size = sizeof(attribs);
|
||||
attribs.disabled = 1;
|
||||
@@ -49,7 +38,7 @@ public:
|
||||
|
||||
int group = -1; // no group
|
||||
num_events = config_vec.size();
|
||||
result.resize(config_vec.size());
|
||||
ids.resize(config_vec.size());
|
||||
uint32_t i = 0;
|
||||
for (auto config : config_vec) {
|
||||
attribs.config = config;
|
||||
@@ -57,22 +46,17 @@ public:
|
||||
if (_fd == -1) {
|
||||
report_error("perf_event_open");
|
||||
}
|
||||
fd = _fd; // fd tracks the last _fd value.
|
||||
fds.push_back(fd);
|
||||
ioctl(fd, PERF_EVENT_IOC_ID, &result[i++]);
|
||||
ioctl(_fd, PERF_EVENT_IOC_ID, &ids[i++]);
|
||||
if (group == -1) {
|
||||
group = fd;
|
||||
group = _fd;
|
||||
fd = _fd;
|
||||
}
|
||||
}
|
||||
|
||||
temp_result_vec.resize(num_events * 2 + 1);
|
||||
}
|
||||
|
||||
~LinuxEvents() {
|
||||
for (auto tfd : fds) {
|
||||
if (tfd != -1) { close(tfd); }
|
||||
}
|
||||
}
|
||||
~LinuxEvents() { if (fd != -1) { close(fd); } }
|
||||
|
||||
inline void start() {
|
||||
if (fd != -1) {
|
||||
@@ -97,10 +81,16 @@ public:
|
||||
}
|
||||
}
|
||||
// our actual results are in slots 1,3,5, ... of this structure
|
||||
// we really should be checking our result obtained earlier to be safe
|
||||
for (uint32_t i = 1; i < temp_result_vec.size(); i += 2) {
|
||||
results[i / 2] = temp_result_vec[i];
|
||||
}
|
||||
for (uint32_t i = 2; i < temp_result_vec.size(); i += 2) {
|
||||
if(ids[i/2-1] != temp_result_vec[i]) {
|
||||
report_error("event mismatch");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool is_working() {
|
||||
@@ -108,13 +98,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void report_error(const std::string &context) {
|
||||
if (!quiet) {
|
||||
if (working) {
|
||||
std::cerr << (context + ": " + std::string(strerror(errno))) << std::endl;
|
||||
}
|
||||
}
|
||||
void report_error(const std::string &) {
|
||||
working = false;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
Vendored
+8
@@ -94,6 +94,14 @@ int main() {}
|
||||
import_dependency(rapidjson Tencent/rapidjson f54b0e4)
|
||||
add_library(rapidjson INTERFACE)
|
||||
target_compile_definitions(rapidjson INTERFACE RAPIDJSON_HAS_STDSTRING)
|
||||
include (TestBigEndian)
|
||||
TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
|
||||
if(IS_BIG_ENDIAN)
|
||||
target_compile_definitions(rapidjson INTERFACE RAPIDJSON_ENDIAN=1)
|
||||
else()
|
||||
target_compile_definitions(rapidjson INTERFACE RAPIDJSON_ENDIAN=0)
|
||||
endif()
|
||||
target_compile_definitions(rapidjson INTERFACE RAPIDJSON_HAS_STDSTRING)
|
||||
target_include_directories(rapidjson SYSTEM INTERFACE
|
||||
"${rapidjson_SOURCE_DIR}/include")
|
||||
target_compile_definitions(rapidjson INTERFACE SIMDJSON_COMPETITION_RAPIDJSON)
|
||||
|
||||
@@ -25,8 +25,9 @@ The current implementations are:
|
||||
* fallback: A generic implementation that runs on any 64-bit processor.
|
||||
|
||||
In many cases, you don't know where your compiled binary is going to run, so simdjson automatically
|
||||
compiles *all* the implementations into the executable. On Intel, it will include 3 implementations
|
||||
(haswell, westmere and fallback), on ARM it will include 2 (arm64 and fallback), and on PPC it will include 2 (ppc64 and fallback).
|
||||
compiles *all* the implementations into the executable. On Intel, it will include 4 implementations
|
||||
(icelake, haswell, westmere and fallback), on ARM it will include 2 (arm64 and fallback), and on PPC
|
||||
it will include 2 (ppc64 and fallback).
|
||||
|
||||
If you know more about where you're going to run and want to save the space, you can disable any of
|
||||
these implementations at compile time with `-DSIMDJSON_IMPLEMENTATION_X=0` (where X is ICELAKE, HASWELL,
|
||||
|
||||
@@ -752,7 +752,7 @@ On relevant systems, the On Demand API provides some support for runtime dispatc
|
||||
|
||||
Some users wish to run at the best possible speed. Under recent Intel and AMD processors, these users should take additional steps to verify that their code is well optimized.
|
||||
|
||||
Given that the On Demand API offer limited runtime dispatching, it matters that your code is compiled against a specific CPU target. You should verify that the code is compiled against the target you expect. Thankfully, the simdjson library will tell you exactly what it detects as an implementation: `haswell` (AVX2 x64 processors), `westmere` (SSE4 x64 processors), `arm64` (64-bit ARM), `ppc64` (64-bit POWER), `fallback` (others). Under x64 processors, many programmers will want to target `haswell` whereas under ARM, most programmers will want to target `arm64` (and it should do so automatically). The `fallback` is probably only good for testing purposes, not for deployment.
|
||||
Given that the On Demand API offer limited runtime dispatching, it matters that your code is compiled against a specific CPU target. You should verify that the code is compiled against the target you expect. Thankfully, the simdjson library will tell you exactly what it detects as an implementation: `icelake` (AVX512 x64 processors), `haswell` (AVX2 x64 processors), `westmere` (SSE4 x64 processors), `arm64` (64-bit ARM), `ppc64` (64-bit POWER), `fallback` (others). Under x64 processors, many programmers will want to target `haswell` whereas under ARM, most programmers will want to target `arm64` (and it should do so automatically). The `fallback` is probably only good for testing purposes, not for deployment.
|
||||
|
||||
```C++
|
||||
std::cout << simdjson::builtin_implementation()->name() << std::endl;
|
||||
|
||||
@@ -78,9 +78,9 @@
|
||||
#define SIMDJSON_CAN_ALWAYS_RUN_WESTMERE (SIMDJSON_IMPLEMENTATION_WESTMERE && SIMDJSON_IS_X86_64 && __SSE4_2__ && __PCLMUL__)
|
||||
|
||||
#ifndef SIMDJSON_IMPLEMENTATION_PPC64
|
||||
#define SIMDJSON_IMPLEMENTATION_PPC64 (SIMDJSON_IS_PPC64)
|
||||
#define SIMDJSON_IMPLEMENTATION_PPC64 (SIMDJSON_IS_PPC64 && SIMDJSON_IS_PPC64_VMX)
|
||||
#endif
|
||||
#define SIMDJSON_CAN_ALWAYS_RUN_PPC64 SIMDJSON_IMPLEMENTATION_PPC64 && SIMDJSON_IS_PPC64
|
||||
#define SIMDJSON_CAN_ALWAYS_RUN_PPC64 SIMDJSON_IMPLEMENTATION_PPC64 && SIMDJSON_IS_PPC64 && SIMDJSON_IS_PPC64_VMX
|
||||
|
||||
// Default Fallback to on unless a builtin implementation has already been selected.
|
||||
#ifndef SIMDJSON_IMPLEMENTATION_FALLBACK
|
||||
|
||||
@@ -57,7 +57,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
namespace simdjson {
|
||||
namespace internal {
|
||||
|
||||
|
||||
enum instruction_set {
|
||||
DEFAULT = 0x0,
|
||||
NEON = 0x1,
|
||||
@@ -107,7 +106,10 @@ constexpr uint32_t cpuid_avx512cd_bit = 1 << 28; ///< @private bit 28 of EBX
|
||||
constexpr uint32_t cpuid_avx512bw_bit = 1 << 30; ///< @private bit 30 of EBX for EAX=0x7
|
||||
constexpr uint32_t cpuid_avx512vl_bit = 1U << 31; ///< @private bit 31 of EBX for EAX=0x7
|
||||
constexpr uint32_t cpuid_avx512vbmi2_bit = 1 << 6; ///< @private bit 6 of ECX for EAX=0x7
|
||||
constexpr uint64_t cpuid_avx256_saved = uint64_t(1) << 2; ///< @private bit 2 = AVX
|
||||
constexpr uint64_t cpuid_avx512_saved = uint64_t(7) << 5; ///< @private bits 5,6,7 = opmask, ZMM_hi256, hi16_ZMM
|
||||
constexpr uint32_t cpuid_sse42_bit = 1 << 20; ///< @private bit 20 of ECX for EAX=0x1
|
||||
constexpr uint32_t cpuid_osxsave = (uint32_t(1) << 26) | (uint32_t(1) << 27); ///< @private bits 26+27 of ECX for EAX=0x1
|
||||
constexpr uint32_t cpuid_pclmulqdq_bit = 1 << 1; ///< @private bit 1 of ECX for EAX=0x1
|
||||
}
|
||||
|
||||
@@ -117,7 +119,7 @@ static inline void cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx,
|
||||
uint32_t *edx) {
|
||||
#if defined(_MSC_VER)
|
||||
int cpu_info[4];
|
||||
__cpuid(cpu_info, *eax);
|
||||
__cpuidex(cpu_info, *eax, *ecx);
|
||||
*eax = cpu_info[0];
|
||||
*ebx = cpu_info[1];
|
||||
*ecx = cpu_info[2];
|
||||
@@ -135,10 +137,48 @@ static inline void cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx,
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static inline uint64_t xgetbv() {
|
||||
#if defined(_MSC_VER)
|
||||
return _xgetbv(0);
|
||||
#else
|
||||
uint32_t xcr0_lo, xcr0_hi;
|
||||
asm volatile("xgetbv\n\t" : "=a" (xcr0_lo), "=d" (xcr0_hi) : "c" (0));
|
||||
return xcr0_lo | (uint64_t(xcr0_hi) << 32);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint32_t detect_supported_architectures() {
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
uint32_t host_isa = 0x0;
|
||||
|
||||
// EBX for EAX=0x1
|
||||
eax = 0x1;
|
||||
ecx = 0x0;
|
||||
cpuid(&eax, &ebx, &ecx, &edx);
|
||||
|
||||
if (ecx & cpuid_sse42_bit) {
|
||||
host_isa |= instruction_set::SSE42;
|
||||
} else {
|
||||
return host_isa; // everything after is redundant
|
||||
}
|
||||
|
||||
if (ecx & cpuid_pclmulqdq_bit) {
|
||||
host_isa |= instruction_set::PCLMULQDQ;
|
||||
}
|
||||
|
||||
|
||||
if ((ecx & cpuid_osxsave) != cpuid_osxsave) {
|
||||
return host_isa;
|
||||
}
|
||||
|
||||
// xgetbv for checking if the OS saves registers
|
||||
uint64_t xcr0 = xgetbv();
|
||||
|
||||
if ((xcr0 & cpuid_avx256_saved) == 0) {
|
||||
return host_isa;
|
||||
}
|
||||
|
||||
// ECX for EAX=0x7
|
||||
eax = 0x7;
|
||||
ecx = 0x0;
|
||||
@@ -154,6 +194,10 @@ static inline uint32_t detect_supported_architectures() {
|
||||
host_isa |= instruction_set::BMI2;
|
||||
}
|
||||
|
||||
if (!((xcr0 & cpuid_avx512_saved) == cpuid_avx512_saved)) {
|
||||
return host_isa;
|
||||
}
|
||||
|
||||
if (ebx & cpuid_avx512f_bit) {
|
||||
host_isa |= instruction_set::AVX512F;
|
||||
}
|
||||
@@ -190,18 +234,6 @@ static inline uint32_t detect_supported_architectures() {
|
||||
host_isa |= instruction_set::AVX512VBMI2;
|
||||
}
|
||||
|
||||
// EBX for EAX=0x1
|
||||
eax = 0x1;
|
||||
cpuid(&eax, &ebx, &ecx, &edx);
|
||||
|
||||
if (ecx & cpuid_sse42_bit) {
|
||||
host_isa |= instruction_set::SSE42;
|
||||
}
|
||||
|
||||
if (ecx & cpuid_pclmulqdq_bit) {
|
||||
host_isa |= instruction_set::PCLMULQDQ;
|
||||
}
|
||||
|
||||
return host_isa;
|
||||
}
|
||||
#else // fallback
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#define NONSTD_SV_LITE_H_INCLUDED
|
||||
|
||||
#define string_view_lite_MAJOR 1
|
||||
#define string_view_lite_MINOR 6
|
||||
#define string_view_lite_MINOR 7
|
||||
#define string_view_lite_PATCH 0
|
||||
|
||||
#define string_view_lite_VERSION nssv_STRINGIFY(string_view_lite_MAJOR) "." nssv_STRINGIFY(string_view_lite_MINOR) "." nssv_STRINGIFY(string_view_lite_PATCH)
|
||||
@@ -72,7 +72,7 @@
|
||||
// Control presence of exception handling (try and auto discover):
|
||||
|
||||
#ifndef nssv_CONFIG_NO_EXCEPTIONS
|
||||
# if _MSC_VER
|
||||
# if defined(_MSC_VER)
|
||||
# include <cstddef> // for _HAS_EXCEPTIONS
|
||||
# endif
|
||||
# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
|
||||
@@ -82,7 +82,7 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// C++ language version detection (C++20 is speculative):
|
||||
// C++ language version detection (C++23 is speculative):
|
||||
// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
|
||||
|
||||
#ifndef nssv_CPLUSPLUS
|
||||
@@ -98,7 +98,8 @@
|
||||
#define nssv_CPP11_OR_GREATER_ ( nssv_CPLUSPLUS >= 201103L )
|
||||
#define nssv_CPP14_OR_GREATER ( nssv_CPLUSPLUS >= 201402L )
|
||||
#define nssv_CPP17_OR_GREATER ( nssv_CPLUSPLUS >= 201703L )
|
||||
#define nssv_CPP20_OR_GREATER ( nssv_CPLUSPLUS >= 202000L )
|
||||
#define nssv_CPP20_OR_GREATER ( nssv_CPLUSPLUS >= 202002L )
|
||||
#define nssv_CPP23_OR_GREATER ( nssv_CPLUSPLUS >= 202300L )
|
||||
|
||||
// use C++17 std::string_view if available and requested:
|
||||
|
||||
@@ -288,6 +289,8 @@ using std::operator<<;
|
||||
#define nssv_HAVE_CONSTEXPR_11 nssv_CPP11_140
|
||||
#define nssv_HAVE_EXPLICIT_CONVERSION nssv_CPP11_140
|
||||
#define nssv_HAVE_INLINE_NAMESPACE nssv_CPP11_140
|
||||
#define nssv_HAVE_IS_DEFAULT nssv_CPP11_140
|
||||
#define nssv_HAVE_IS_DELETE nssv_CPP11_140
|
||||
#define nssv_HAVE_NOEXCEPT nssv_CPP11_140
|
||||
#define nssv_HAVE_NULLPTR nssv_CPP11_100
|
||||
#define nssv_HAVE_REF_QUALIFIER nssv_CPP11_140
|
||||
@@ -469,6 +472,17 @@ nssv_DISABLE_MSVC_WARNINGS( 4455 26481 26472 )
|
||||
|
||||
namespace nonstd { namespace sv_lite {
|
||||
|
||||
//
|
||||
// basic_string_view declaration:
|
||||
//
|
||||
|
||||
template
|
||||
<
|
||||
class CharT,
|
||||
class Traits = std::char_traits<CharT>
|
||||
>
|
||||
class basic_string_view;
|
||||
|
||||
namespace detail {
|
||||
|
||||
// support constexpr comparison in C++14;
|
||||
@@ -536,14 +550,33 @@ inline nssv_constexpr14 std::size_t length( CharT * s )
|
||||
|
||||
#endif // OPTIMIZE
|
||||
|
||||
} // namespace detail
|
||||
#if nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
|
||||
#if defined(__OPTIMIZE__)
|
||||
|
||||
template
|
||||
<
|
||||
class CharT,
|
||||
class Traits = std::char_traits<CharT>
|
||||
>
|
||||
class basic_string_view;
|
||||
// gcc, clang provide __OPTIMIZE__
|
||||
// Expect tail call optimization to make search() non-recursive:
|
||||
|
||||
template< class CharT, class Traits = std::char_traits<CharT> >
|
||||
constexpr const CharT* search( basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle )
|
||||
{
|
||||
return haystack.starts_with( needle ) ? haystack.begin() :
|
||||
haystack.empty() ? haystack.end() : search( haystack.substr(1), needle );
|
||||
}
|
||||
|
||||
#else // OPTIMIZE
|
||||
|
||||
// non-recursive:
|
||||
|
||||
template< class CharT, class Traits = std::char_traits<CharT> >
|
||||
constexpr const CharT* search( basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle )
|
||||
{
|
||||
return std::search( haystack.begin(), haystack.end(), needle.begin(), needle.end() );
|
||||
}
|
||||
|
||||
#endif // OPTIMIZE
|
||||
#endif // nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
|
||||
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// basic_string_view:
|
||||
@@ -570,7 +603,7 @@ public:
|
||||
typedef const_pointer iterator;
|
||||
typedef const_pointer const_iterator;
|
||||
typedef std::reverse_iterator< const_iterator > reverse_iterator;
|
||||
typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
|
||||
typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
|
||||
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
@@ -607,6 +640,14 @@ public:
|
||||
#endif
|
||||
{}
|
||||
|
||||
#if nssv_HAVE_NULLPTR
|
||||
# if nssv_HAVE_IS_DELETE
|
||||
nssv_constexpr basic_string_view( std::nullptr_t ) nssv_noexcept = delete;
|
||||
# else
|
||||
private: nssv_constexpr basic_string_view( std::nullptr_t ) nssv_noexcept; public:
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Assignment:
|
||||
|
||||
#if nssv_CPP11_OR_GREATER
|
||||
@@ -804,25 +845,30 @@ public:
|
||||
|
||||
// find(), 4x:
|
||||
|
||||
nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
|
||||
nssv_constexpr size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
|
||||
{
|
||||
return assert( v.size() == 0 || v.data() != nssv_nullptr )
|
||||
, pos >= size()
|
||||
? npos
|
||||
: to_pos( std::search( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) );
|
||||
? npos : to_pos(
|
||||
#if nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
|
||||
detail::search( substr(pos), v )
|
||||
#else
|
||||
std::search( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq )
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
nssv_constexpr14 size_type find( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
|
||||
nssv_constexpr size_type find( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
|
||||
{
|
||||
return find( basic_string_view( &c, 1 ), pos );
|
||||
}
|
||||
|
||||
nssv_constexpr14 size_type find( CharT const * s, size_type pos, size_type n ) const // (3)
|
||||
nssv_constexpr size_type find( CharT const * s, size_type pos, size_type n ) const // (3)
|
||||
{
|
||||
return find( basic_string_view( s, n ), pos );
|
||||
}
|
||||
|
||||
nssv_constexpr14 size_type find( CharT const * s, size_type pos = 0 ) const // (4)
|
||||
nssv_constexpr size_type find( CharT const * s, size_type pos = 0 ) const // (4)
|
||||
{
|
||||
return find( basic_string_view( s ), pos );
|
||||
}
|
||||
@@ -1381,7 +1427,7 @@ Stream & write_to_stream( Stream & os, View const & sv )
|
||||
{
|
||||
typename Stream::sentry sentry( os );
|
||||
|
||||
if ( !os )
|
||||
if ( !sentry )
|
||||
return os;
|
||||
|
||||
const std::streamsize length = static_cast<std::streamsize>( sv.length() );
|
||||
|
||||
@@ -44,7 +44,9 @@
|
||||
#elif defined(__aarch64__) || defined(_M_ARM64)
|
||||
#define SIMDJSON_IS_ARM64 1
|
||||
#elif defined(__PPC64__) || defined(_M_PPC64)
|
||||
#define SIMDJSON_IS_PPC64 1
|
||||
#if defined(__ALTIVEC__)
|
||||
#define SIMDJSON_IS_PPC64_VMX 1
|
||||
#endif // defined(__ALTIVEC__)
|
||||
#else
|
||||
#define SIMDJSON_IS_32BITS 1
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#define SIMDJSON_SIMDJSON_VERSION_H
|
||||
|
||||
/** The version of simdjson being used (major.minor.revision) */
|
||||
#define SIMDJSON_VERSION "3.1.7"
|
||||
#define SIMDJSON_VERSION "3.1.8"
|
||||
|
||||
namespace simdjson {
|
||||
enum {
|
||||
@@ -19,7 +19,7 @@ enum {
|
||||
/**
|
||||
* The revision (major.minor.REVISION) of simdjson being used.
|
||||
*/
|
||||
SIMDJSON_VERSION_REVISION = 7
|
||||
SIMDJSON_VERSION_REVISION = 8
|
||||
};
|
||||
} // namespace simdjson
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* auto-generated on 2023-04-08 16:11:40 -0400. Do not edit! */
|
||||
/* auto-generated on 2023-05-14 17:17:10 -0400. Do not edit! */
|
||||
/* begin file src/simdjson.cpp */
|
||||
#include "simdjson.h"
|
||||
|
||||
|
||||
+119
-39
@@ -1,4 +1,4 @@
|
||||
/* auto-generated on 2023-04-08 16:11:40 -0400. Do not edit! */
|
||||
/* auto-generated on 2023-05-14 17:17:10 -0400. Do not edit! */
|
||||
/* begin file include/simdjson.h */
|
||||
#ifndef SIMDJSON_H
|
||||
#define SIMDJSON_H
|
||||
@@ -43,7 +43,7 @@
|
||||
#define SIMDJSON_SIMDJSON_VERSION_H
|
||||
|
||||
/** The version of simdjson being used (major.minor.revision) */
|
||||
#define SIMDJSON_VERSION "3.1.7"
|
||||
#define SIMDJSON_VERSION "3.1.8"
|
||||
|
||||
namespace simdjson {
|
||||
enum {
|
||||
@@ -58,7 +58,7 @@ enum {
|
||||
/**
|
||||
* The revision (major.minor.REVISION) of simdjson being used.
|
||||
*/
|
||||
SIMDJSON_VERSION_REVISION = 7
|
||||
SIMDJSON_VERSION_REVISION = 8
|
||||
};
|
||||
} // namespace simdjson
|
||||
|
||||
@@ -161,7 +161,9 @@ enum {
|
||||
#elif defined(__aarch64__) || defined(_M_ARM64)
|
||||
#define SIMDJSON_IS_ARM64 1
|
||||
#elif defined(__PPC64__) || defined(_M_PPC64)
|
||||
#define SIMDJSON_IS_PPC64 1
|
||||
#if defined(__ALTIVEC__)
|
||||
#define SIMDJSON_IS_PPC64_VMX 1
|
||||
#endif // defined(__ALTIVEC__)
|
||||
#else
|
||||
#define SIMDJSON_IS_32BITS 1
|
||||
|
||||
@@ -589,7 +591,7 @@ SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
|
||||
#define NONSTD_SV_LITE_H_INCLUDED
|
||||
|
||||
#define string_view_lite_MAJOR 1
|
||||
#define string_view_lite_MINOR 6
|
||||
#define string_view_lite_MINOR 7
|
||||
#define string_view_lite_PATCH 0
|
||||
|
||||
#define string_view_lite_VERSION nssv_STRINGIFY(string_view_lite_MAJOR) "." nssv_STRINGIFY(string_view_lite_MINOR) "." nssv_STRINGIFY(string_view_lite_PATCH)
|
||||
@@ -649,7 +651,7 @@ SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
|
||||
// Control presence of exception handling (try and auto discover):
|
||||
|
||||
#ifndef nssv_CONFIG_NO_EXCEPTIONS
|
||||
# if _MSC_VER
|
||||
# if defined(_MSC_VER)
|
||||
# include <cstddef> // for _HAS_EXCEPTIONS
|
||||
# endif
|
||||
# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS)
|
||||
@@ -659,7 +661,7 @@ SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// C++ language version detection (C++20 is speculative):
|
||||
// C++ language version detection (C++23 is speculative):
|
||||
// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
|
||||
|
||||
#ifndef nssv_CPLUSPLUS
|
||||
@@ -675,7 +677,8 @@ SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
|
||||
#define nssv_CPP11_OR_GREATER_ ( nssv_CPLUSPLUS >= 201103L )
|
||||
#define nssv_CPP14_OR_GREATER ( nssv_CPLUSPLUS >= 201402L )
|
||||
#define nssv_CPP17_OR_GREATER ( nssv_CPLUSPLUS >= 201703L )
|
||||
#define nssv_CPP20_OR_GREATER ( nssv_CPLUSPLUS >= 202000L )
|
||||
#define nssv_CPP20_OR_GREATER ( nssv_CPLUSPLUS >= 202002L )
|
||||
#define nssv_CPP23_OR_GREATER ( nssv_CPLUSPLUS >= 202300L )
|
||||
|
||||
// use C++17 std::string_view if available and requested:
|
||||
|
||||
@@ -865,6 +868,8 @@ using std::operator<<;
|
||||
#define nssv_HAVE_CONSTEXPR_11 nssv_CPP11_140
|
||||
#define nssv_HAVE_EXPLICIT_CONVERSION nssv_CPP11_140
|
||||
#define nssv_HAVE_INLINE_NAMESPACE nssv_CPP11_140
|
||||
#define nssv_HAVE_IS_DEFAULT nssv_CPP11_140
|
||||
#define nssv_HAVE_IS_DELETE nssv_CPP11_140
|
||||
#define nssv_HAVE_NOEXCEPT nssv_CPP11_140
|
||||
#define nssv_HAVE_NULLPTR nssv_CPP11_100
|
||||
#define nssv_HAVE_REF_QUALIFIER nssv_CPP11_140
|
||||
@@ -1046,6 +1051,17 @@ nssv_DISABLE_MSVC_WARNINGS( 4455 26481 26472 )
|
||||
|
||||
namespace nonstd { namespace sv_lite {
|
||||
|
||||
//
|
||||
// basic_string_view declaration:
|
||||
//
|
||||
|
||||
template
|
||||
<
|
||||
class CharT,
|
||||
class Traits = std::char_traits<CharT>
|
||||
>
|
||||
class basic_string_view;
|
||||
|
||||
namespace detail {
|
||||
|
||||
// support constexpr comparison in C++14;
|
||||
@@ -1113,14 +1129,33 @@ inline nssv_constexpr14 std::size_t length( CharT * s )
|
||||
|
||||
#endif // OPTIMIZE
|
||||
|
||||
} // namespace detail
|
||||
#if nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
|
||||
#if defined(__OPTIMIZE__)
|
||||
|
||||
template
|
||||
<
|
||||
class CharT,
|
||||
class Traits = std::char_traits<CharT>
|
||||
>
|
||||
class basic_string_view;
|
||||
// gcc, clang provide __OPTIMIZE__
|
||||
// Expect tail call optimization to make search() non-recursive:
|
||||
|
||||
template< class CharT, class Traits = std::char_traits<CharT> >
|
||||
constexpr const CharT* search( basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle )
|
||||
{
|
||||
return haystack.starts_with( needle ) ? haystack.begin() :
|
||||
haystack.empty() ? haystack.end() : search( haystack.substr(1), needle );
|
||||
}
|
||||
|
||||
#else // OPTIMIZE
|
||||
|
||||
// non-recursive:
|
||||
|
||||
template< class CharT, class Traits = std::char_traits<CharT> >
|
||||
constexpr const CharT* search( basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle )
|
||||
{
|
||||
return std::search( haystack.begin(), haystack.end(), needle.begin(), needle.end() );
|
||||
}
|
||||
|
||||
#endif // OPTIMIZE
|
||||
#endif // nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
|
||||
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// basic_string_view:
|
||||
@@ -1147,7 +1182,7 @@ public:
|
||||
typedef const_pointer iterator;
|
||||
typedef const_pointer const_iterator;
|
||||
typedef std::reverse_iterator< const_iterator > reverse_iterator;
|
||||
typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
|
||||
typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
|
||||
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
@@ -1184,6 +1219,14 @@ public:
|
||||
#endif
|
||||
{}
|
||||
|
||||
#if nssv_HAVE_NULLPTR
|
||||
# if nssv_HAVE_IS_DELETE
|
||||
nssv_constexpr basic_string_view( std::nullptr_t ) nssv_noexcept = delete;
|
||||
# else
|
||||
private: nssv_constexpr basic_string_view( std::nullptr_t ) nssv_noexcept; public:
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Assignment:
|
||||
|
||||
#if nssv_CPP11_OR_GREATER
|
||||
@@ -1381,25 +1424,30 @@ public:
|
||||
|
||||
// find(), 4x:
|
||||
|
||||
nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
|
||||
nssv_constexpr size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
|
||||
{
|
||||
return assert( v.size() == 0 || v.data() != nssv_nullptr )
|
||||
, pos >= size()
|
||||
? npos
|
||||
: to_pos( std::search( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) );
|
||||
? npos : to_pos(
|
||||
#if nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
|
||||
detail::search( substr(pos), v )
|
||||
#else
|
||||
std::search( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq )
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
nssv_constexpr14 size_type find( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
|
||||
nssv_constexpr size_type find( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
|
||||
{
|
||||
return find( basic_string_view( &c, 1 ), pos );
|
||||
}
|
||||
|
||||
nssv_constexpr14 size_type find( CharT const * s, size_type pos, size_type n ) const // (3)
|
||||
nssv_constexpr size_type find( CharT const * s, size_type pos, size_type n ) const // (3)
|
||||
{
|
||||
return find( basic_string_view( s, n ), pos );
|
||||
}
|
||||
|
||||
nssv_constexpr14 size_type find( CharT const * s, size_type pos = 0 ) const // (4)
|
||||
nssv_constexpr size_type find( CharT const * s, size_type pos = 0 ) const // (4)
|
||||
{
|
||||
return find( basic_string_view( s ), pos );
|
||||
}
|
||||
@@ -1958,7 +2006,7 @@ Stream & write_to_stream( Stream & os, View const & sv )
|
||||
{
|
||||
typename Stream::sentry sentry( os );
|
||||
|
||||
if ( !os )
|
||||
if ( !sentry )
|
||||
return os;
|
||||
|
||||
const std::streamsize length = static_cast<std::streamsize>( sv.length() );
|
||||
@@ -3187,7 +3235,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
namespace simdjson {
|
||||
namespace internal {
|
||||
|
||||
|
||||
enum instruction_set {
|
||||
DEFAULT = 0x0,
|
||||
NEON = 0x1,
|
||||
@@ -3237,7 +3284,10 @@ constexpr uint32_t cpuid_avx512cd_bit = 1 << 28; ///< @private bit 28 of EBX
|
||||
constexpr uint32_t cpuid_avx512bw_bit = 1 << 30; ///< @private bit 30 of EBX for EAX=0x7
|
||||
constexpr uint32_t cpuid_avx512vl_bit = 1U << 31; ///< @private bit 31 of EBX for EAX=0x7
|
||||
constexpr uint32_t cpuid_avx512vbmi2_bit = 1 << 6; ///< @private bit 6 of ECX for EAX=0x7
|
||||
constexpr uint64_t cpuid_avx256_saved = uint64_t(1) << 2; ///< @private bit 2 = AVX
|
||||
constexpr uint64_t cpuid_avx512_saved = uint64_t(7) << 5; ///< @private bits 5,6,7 = opmask, ZMM_hi256, hi16_ZMM
|
||||
constexpr uint32_t cpuid_sse42_bit = 1 << 20; ///< @private bit 20 of ECX for EAX=0x1
|
||||
constexpr uint32_t cpuid_osxsave = (uint32_t(1) << 26) | (uint32_t(1) << 27); ///< @private bits 26+27 of ECX for EAX=0x1
|
||||
constexpr uint32_t cpuid_pclmulqdq_bit = 1 << 1; ///< @private bit 1 of ECX for EAX=0x1
|
||||
}
|
||||
|
||||
@@ -3247,7 +3297,7 @@ static inline void cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx,
|
||||
uint32_t *edx) {
|
||||
#if defined(_MSC_VER)
|
||||
int cpu_info[4];
|
||||
__cpuid(cpu_info, *eax);
|
||||
__cpuidex(cpu_info, *eax, *ecx);
|
||||
*eax = cpu_info[0];
|
||||
*ebx = cpu_info[1];
|
||||
*ecx = cpu_info[2];
|
||||
@@ -3265,10 +3315,48 @@ static inline void cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx,
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static inline uint64_t xgetbv() {
|
||||
#if defined(_MSC_VER)
|
||||
return _xgetbv(0);
|
||||
#else
|
||||
uint32_t xcr0_lo, xcr0_hi;
|
||||
asm volatile("xgetbv\n\t" : "=a" (xcr0_lo), "=d" (xcr0_hi) : "c" (0));
|
||||
return xcr0_lo | (uint64_t(xcr0_hi) << 32);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline uint32_t detect_supported_architectures() {
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
uint32_t host_isa = 0x0;
|
||||
|
||||
// EBX for EAX=0x1
|
||||
eax = 0x1;
|
||||
ecx = 0x0;
|
||||
cpuid(&eax, &ebx, &ecx, &edx);
|
||||
|
||||
if (ecx & cpuid_sse42_bit) {
|
||||
host_isa |= instruction_set::SSE42;
|
||||
} else {
|
||||
return host_isa; // everything after is redundant
|
||||
}
|
||||
|
||||
if (ecx & cpuid_pclmulqdq_bit) {
|
||||
host_isa |= instruction_set::PCLMULQDQ;
|
||||
}
|
||||
|
||||
|
||||
if ((ecx & cpuid_osxsave) != cpuid_osxsave) {
|
||||
return host_isa;
|
||||
}
|
||||
|
||||
// xgetbv for checking if the OS saves registers
|
||||
uint64_t xcr0 = xgetbv();
|
||||
|
||||
if ((xcr0 & cpuid_avx256_saved) == 0) {
|
||||
return host_isa;
|
||||
}
|
||||
|
||||
// ECX for EAX=0x7
|
||||
eax = 0x7;
|
||||
ecx = 0x0;
|
||||
@@ -3284,6 +3372,10 @@ static inline uint32_t detect_supported_architectures() {
|
||||
host_isa |= instruction_set::BMI2;
|
||||
}
|
||||
|
||||
if (!((xcr0 & cpuid_avx512_saved) == cpuid_avx512_saved)) {
|
||||
return host_isa;
|
||||
}
|
||||
|
||||
if (ebx & cpuid_avx512f_bit) {
|
||||
host_isa |= instruction_set::AVX512F;
|
||||
}
|
||||
@@ -3320,18 +3412,6 @@ static inline uint32_t detect_supported_architectures() {
|
||||
host_isa |= instruction_set::AVX512VBMI2;
|
||||
}
|
||||
|
||||
// EBX for EAX=0x1
|
||||
eax = 0x1;
|
||||
cpuid(&eax, &ebx, &ecx, &edx);
|
||||
|
||||
if (ecx & cpuid_sse42_bit) {
|
||||
host_isa |= instruction_set::SSE42;
|
||||
}
|
||||
|
||||
if (ecx & cpuid_pclmulqdq_bit) {
|
||||
host_isa |= instruction_set::PCLMULQDQ;
|
||||
}
|
||||
|
||||
return host_isa;
|
||||
}
|
||||
#else // fallback
|
||||
@@ -9677,9 +9757,9 @@ extern SIMDJSON_DLLIMPORTEXPORT const uint64_t thintable_epi8[256];
|
||||
#define SIMDJSON_CAN_ALWAYS_RUN_WESTMERE (SIMDJSON_IMPLEMENTATION_WESTMERE && SIMDJSON_IS_X86_64 && __SSE4_2__ && __PCLMUL__)
|
||||
|
||||
#ifndef SIMDJSON_IMPLEMENTATION_PPC64
|
||||
#define SIMDJSON_IMPLEMENTATION_PPC64 (SIMDJSON_IS_PPC64)
|
||||
#define SIMDJSON_IMPLEMENTATION_PPC64 (SIMDJSON_IS_PPC64 && SIMDJSON_IS_PPC64_VMX)
|
||||
#endif
|
||||
#define SIMDJSON_CAN_ALWAYS_RUN_PPC64 SIMDJSON_IMPLEMENTATION_PPC64 && SIMDJSON_IS_PPC64
|
||||
#define SIMDJSON_CAN_ALWAYS_RUN_PPC64 SIMDJSON_IMPLEMENTATION_PPC64 && SIMDJSON_IS_PPC64 && SIMDJSON_IS_PPC64_VMX
|
||||
|
||||
// Default Fallback to on unless a builtin implementation has already been selected.
|
||||
#ifndef SIMDJSON_IMPLEMENTATION_FALLBACK
|
||||
|
||||
@@ -1031,7 +1031,7 @@ namespace dom_api_tests {
|
||||
std::cout << "Running " << __func__ << std::endl;
|
||||
// Prints the number of results in twitter.json
|
||||
dom::parser parser;
|
||||
uint64_t result_count;
|
||||
uint64_t result_count{};
|
||||
ASSERT_SUCCESS( parser.load(TWITTER_JSON)["search_metadata"]["count"].get(result_count) );
|
||||
ASSERT_EQUAL( result_count, 100 );
|
||||
return true;
|
||||
|
||||
@@ -81,13 +81,13 @@ void basics_error_3() {
|
||||
dom::object innerobj;
|
||||
if ((error = key_value.value.get(innerobj))) { cerr << error << endl; exit(1); }
|
||||
|
||||
double va, vb;
|
||||
double va{}, vb{};
|
||||
if ((error = innerobj["a"].get(va))) { cerr << error << endl; exit(1); }
|
||||
cout << "a: " << va << ", ";
|
||||
if ((error = innerobj["b"].get(vb))) { cerr << error << endl; exit(1); }
|
||||
cout << "b: " << vb << ", ";
|
||||
|
||||
int64_t vc;
|
||||
int64_t vc{};
|
||||
if ((error = innerobj["c"].get(vc))) { cerr << error << endl; exit(1); }
|
||||
cout << "c: " << vc << endl;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user