Compare commits

..

20 Commits

Author SHA1 Message Date
Daniel Lemire 82c9876aec Preparing release. 2023-01-21 18:07:06 -05:00
Daniel Lemire b9234be80f complete number_in_string for documents, stringify the version macro and improving trailing content errors (#1934)
* This completes the '*_in_string' support within documents.

* Minor updates.

* Additional fixes.
2023-01-21 15:29:08 -05:00
Daniel Lemire 0a2563e13e Testing and fixing log issues. (#1939)
* Testing and fixing log issues.

* Cleaning it a bit.
2023-01-21 15:28:56 -05:00
Daniel Lemire 727ec73c33 The fuzzer needs to be updated. (#1941) 2023-01-21 15:28:25 -05:00
Daniel Lemire 9a55a830ec Adding clang14 ci (#1940) 2023-01-21 15:27:21 -05:00
Daniel Lemire 8c89ae0cd9 Removing extra ';'. 2023-01-13 09:17:05 -05:00
Daniel Lemire 8c71ca1b1d Update implementation-selection.md 2023-01-07 13:43:26 -05:00
Daniel Lemire c72b4bc0f4 Update basics.md 2023-01-07 13:42:01 -05:00
Daniel Lemire 8a26cb3c8e Adding a couple of string tests. (#1935)
* Adding a couple of string tests.
2023-01-05 21:18:54 -05:00
Daniel Lemire bf2ba5c675 Update basics.md 2023-01-05 08:38:16 -05:00
Daniel Lemire f151300a76 Disabling fallback kernel on systems where it is not needed (#1930)
* Fixing issue 1772

* More cleaning.

* Allow disabling other kernels.

* Minor tweaks.
2023-01-03 09:52:41 -05:00
Daniel Lemire 9aa3563d99 Updating Google Benchmark. (#1929) 2023-01-03 09:52:26 -05:00
Daniel Lemire 9444c1a04f Merge branch 'master' of github.com:simdjson/simdjson 2022-12-19 21:07:17 -05:00
Daniel Lemire 883901a81b Updating users. 2022-12-19 21:07:07 -05:00
Daniel Lemire a2c96c9cca Update basics.md 2022-12-16 22:12:25 -05:00
Daniel Lemire c63da0ef2c Added a remark regarding assemblers. 2022-12-16 21:22:48 -05:00
Daniel Lemire c61cefda85 Merge branch 'master' of github.com:simdjson/simdjson 2022-12-05 12:25:52 -05:00
Daniel Lemire bffcbb444d Clarifying comment. 2022-12-05 12:25:29 -05:00
Daniel Lemire 0b2891aaab Trying fuzzer with llvm 14. (#1922) 2022-12-01 14:26:17 -05:00
wanweiqiangintel 983fb41802 Update README.md (#1925)
Add a real-word usage
2022-11-30 17:26:58 -05:00
46 changed files with 812 additions and 295 deletions
+7 -7
View File
@@ -24,7 +24,7 @@ jobs:
implementations: haswell westmere fallback
UBSAN_OPTIONS: halt_on_error=1
MAXLEN: -max_len=4000
CLANGVERSION: 11
CLANGVERSION: 15
# which optimization level to use for the sanitizer build (see build_fuzzer.variants.sh)
OPTLEVEL: -O3
@@ -32,7 +32,7 @@ jobs:
- name: Install packages necessary for building
run: |
sudo apt update
sudo apt-get install --quiet ninja-build valgrind zip unzip
sudo apt-get install --quiet ninja-build valgrind zip unzip lsb-release wget software-properties-common gnupg
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh $CLANGVERSION
@@ -50,12 +50,12 @@ jobs:
path: out/
key: corpus-${{ github.run_id }}
restore-keys: corpus-
- name: show statistics for the cached corpus
run: |
echo number of files in github action corpus cache:
find out -type f |wc -l
- name: Create and prepare the initial seed corpus
run: |
fuzz/build_corpus.sh
@@ -92,7 +92,7 @@ jobs:
export SIMDJSON_FORCE_IMPLEMENTATION=$implementation
build-sanitizers$OPTLEVEL/fuzz/fuzz_$fuzzer out/$fuzzer $others seedcorpus -max_total_time=20 $MAXLEN
done
echo now have $(ls out/$fuzzer |wc -l) files in corpus
echo now have $(ls out/$fuzzer |wc -l) files in corpus
done
- name: Fuzz differential impl. fuzzers with sanitizer+asserts (good at detecting errors)
@@ -119,7 +119,7 @@ jobs:
- name: Package the corpus into an artifact
run: |
for fuzzer in $defaultimplfuzzers $implfuzzers; do
for fuzzer in $defaultimplfuzzers $implfuzzers; do
tar rf corpus.tar out/$fuzzer
done
@@ -141,7 +141,7 @@ jobs:
run: |
for fuzzer in $defaultimplfuzzers $implfuzzers; do
find out/$fuzzer -type f |sort|head -n200|xargs -n40 valgrind build-replay/fuzz/fuzz_$fuzzer 2>&1|tee valgrind-$fuzzer.txt
done
done
- name: Compress the valgrind output
run: tar cf valgrind.tar valgrind-*.txt
+25
View File
@@ -0,0 +1,25 @@
name: Ubuntu 22.04 CI (CLANG 14)
on: [push, pull_request]
jobs:
ubuntu-build:
if: >-
! contains(toJSON(github.event.commits.*.message), '[skip ci]') &&
! contains(toJSON(github.event.commits.*.message), '[skip github]')
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
with:
path: dependencies/.cache
key: ${{ hashFiles('dependencies/CMakeLists.txt') }}
- name: Install clang++-14
run: sudo apt-get install -y clang++-14
- name: Use cmake
run: |
mkdir build &&
cd build &&
CXX=clang++-14 cmake -DSIMDJSON_DEVELOPER_MODE=ON .. &&
cmake --build . &&
ctest -j --output-on-failure -LE explicitonly
+3 -3
View File
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14)
project(
simdjson
# The version number is modified by tools/release.py
VERSION 3.0.1
VERSION 3.1.0
DESCRIPTION "Parsing gigabytes of JSON per second"
HOMEPAGE_URL "https://simdjson.org/"
LANGUAGES CXX C
@@ -20,8 +20,8 @@ string(
# ---- Options, variables ----
# These version numbers are modified by tools/release.py
set(SIMDJSON_LIB_VERSION "14.0.0" CACHE STRING "simdjson library version")
set(SIMDJSON_LIB_SOVERSION "14" CACHE STRING "simdjson library soversion")
set(SIMDJSON_LIB_VERSION "15.0.0" CACHE STRING "simdjson library version")
set(SIMDJSON_LIB_SOVERSION "15" CACHE STRING "simdjson library soversion")
option(SIMDJSON_ENABLE_THREADS "Link with thread support" ON)
+1 -1
View File
@@ -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.0.1"
PROJECT_NUMBER = "3.1.0"
# 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
+1 -1
View File
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2018-2019 The simdjson authors
Copyright 2018-2023 The simdjson authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
+4
View File
@@ -116,6 +116,10 @@ Real-world usage
- [Shopify HeapProfiler](https://github.com/Shopify/heap-profiler)
- [StarRocks](https://github.com/StarRocks/starrocks)
- [Microsoft FishStore](https://github.com/microsoft/FishStore)
- [Intel PCM](https://github.com/intel/pcm)
- [WatermelonDB](https://github.com/Nozbe/WatermelonDB)
- [Apache Doris](https://github.com/apache/doris)
- [Dgraph](https://github.com/dgraph-io/dgraph)
If you are planning to use simdjson in a product, please work from one of our releases.
+1 -1
View File
@@ -15,7 +15,7 @@ if(SIMDJSON_GOOGLE_BENCHMARKS)
set_off(BENCHMARK_ENABLE_INSTALL)
set_off(BENCHMARK_ENABLE_WERROR)
import_dependency(google_benchmarks google/benchmark f91b6b4)
import_dependency(google_benchmarks google/benchmark d572f47)
add_dependency(google_benchmarks)
endif()
+8 -3
View File
@@ -41,7 +41,9 @@ Requirements
- Visual Studio 2017 or better under 64-bit Windows. Users should target a 64-bit build (x64) instead of a 32-bit build (x86). We support the LLVM clang compiler under Visual Studio (clangcl) as well as as the regular Visual Studio compiler. We also support MinGW 64-bit under Windows.
Support for AVX-512 require a processor with AVX512-VBMI2 support (Ice Lake or better) under a 64-bit system and a recent compiler (LLVM clang 6 or better, GCC 8 or better, Visual Studio 2019 or better).
Support for AVX-512 require a processor with AVX512-VBMI2 support (Ice Lake or better) under a 64-bit system and a recent compiler (LLVM clang 6 or better, GCC 8 or better, Visual Studio 2019 or better). You need a correspondingly recent assembler such as gas (2.30+) or nasm (2.14+): recent compilers usually come with recent assemblers. If you mix a recent compiler with an incompatible/old assembler (e.g., when using a recent compiler with an old Linux distribution), you may get errors at build time because the compiler produces instructions that the assembler does not recognize: you should update your assembler to match your compiler (e.g., upgrade binutils to version 2.30 or better under Linux) or use an older compiler matching the capabilities of your assembler.
Because big-endian systems are effectively limited commercially to IBM mainframes today, the simdjson library is only tested on little-endian systems. Users who require big-endian support are invited to contribute to the library.
Including simdjson
------------------
@@ -61,7 +63,7 @@ c++ myproject.cpp simdjson.cpp
```
Note:
- Users on macOS and other platforms where default compilers do not provide C++11 compliant by default should request it with the appropriate flag (e.g., `c++ -std=c++17 myproject.cpp simdjson.cpp`).
- Users on macOS and other platforms where default compilers do not provide C++11 compliant by default should request it with the appropriate flag (e.g., `c++ -std=c++11 myproject.cpp simdjson.cpp`).
- The library relies on [runtime CPU detection](implementation-selection.md): avoid specifying an architecture at compile time (e.g., `-march-native`).
Using simdjson with package managers
@@ -297,7 +299,8 @@ support for users who avoid exceptions. See [the simdjson error handling documen
ondemand::object and ondemand::array. We also have explicit methods such as `get_string()`, `get_double()`,
`get_uint64()`, `get_int64()`, `get_bool()`, `get_object()` and `get_array()`. After a cast or an explicit method,
the number, string or boolean will be parsed, or the initial `[` or `{` will be verified. An exception is thrown if
the cast is not possible.
the cast is not possible. The `get_string()` returns a valid UTF-8 string, after
unescaping characters as needed: unmatched surrogate pairs are treated as an error. When calling `get_uint64()` and `get_int64()`, if the number does not fit in a corresponding 64-bit integer type, it is also considered an error.
> IMPORTANT NOTE: values can only be parsed once. Since documents are *iterators*, once you have
> parsed a value (such as by casting to double), you cannot get at it again. It is an error to call
@@ -1415,6 +1418,8 @@ if (error) {
It is also important to note that when dealing an invalid number inside a string, simdjson will report a `NUMBER_ERROR` error if the string begins with a number whereas simdjson
will report a `INCORRECT_TYPE` error otherwise.
The `*_in_string` methods can also be called on a single document instance:
e.g., when your document consist solely of a quoted number.
Dynamic Number Types
------------------------------
+4 -3
View File
@@ -65,7 +65,7 @@ Once you have an element, you can navigate it with idiomatic C++ iterators, oper
* **Extracting Values (with exceptions):** You can cast a JSON element to a native type: `double(element)` or
`double x = json_element`. This works for double, uint64_t, int64_t, bool,
dom::object and dom::array. An exception (`simdjson::simdjson_error`) is thrown if the cast is not possible.
* **Extracting Values (without exceptions):** You can use a variant usage of `get()` with error codes to avoid exceptions. You first declare the variable of the appropriate type (`double`, `uint64_t`, `int64_t`, `bool`,
* **Extracting Values (without exceptions):** You can use a variant usage of `get()` with error codes to avoid exceptions. You first declare the variable of the appropriate type (`double`, `uint64_t`, `int64_t`, `bool`, `std::string_view`,
`dom::object` and `dom::array`) and pass it by reference to `get()` which gives you back an error code: e.g.,
```c++
simdjson::error_code error;
@@ -76,6 +76,7 @@ Once you have an element, you can navigate it with idiomatic C++ iterators, oper
if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
std::cout << "I parsed " << value << " from " << numberstring.data() << std::endl;
```
The strings contain unescaped valid UTF-8 strings: no unmatched surrogate is allowed.
* **Field Access:** To get the value of the "foo" field in an object, use `object["foo"]`.
* **Array Iteration:** To iterate through an array, use `for (auto value : array) { ... }`. If you
know the type of the value, you can cast it right there, too! `for (double value : array) { ... }`
@@ -88,7 +89,7 @@ Once you have an element, you can navigate it with idiomatic C++ iterators, oper
* **Array and Object size** Given an array or an object, you can get its size (number of elements or keys)
with the `size()` method.
* **Checking an Element Type:** You can check an element's type with `element.type()`. It
returns an `element_type` with values such as `simdjson::dom::element_type::ARRAY`, `simdjson::dom::element_type::OBJECT`, `simdjson::dom::element_type::INT64`, `simdjson::dom::element_type::UINT64`,`simdjson::dom::element_type::DOUBLE`, `simdjson::dom::element_type::BOOL` or, `simdjson::dom::element_type::NULL_VALUE`.
returns an `element_type` with values such as `simdjson::dom::element_type::ARRAY`, `simdjson::dom::element_type::OBJECT`, `simdjson::dom::element_type::INT64`, `simdjson::dom::element_type::UINT64`,`simdjson::dom::element_type::DOUBLE`, `simdjson::dom::element_type::STRING`, `simdjson::dom::element_type::BOOL` or, `simdjson::dom::element_type::NULL_VALUE`.
* **Output to streams and strings:** Given a document or an element (or node) out of a JSON document, you can output a minified string version using the C++ stream idiom (`out << element`). You can also request the construction of a minified string version (`simdjson::minify(element)`). Numbers are serialized as 64-bit floating-point numbers (`double`).
### Examples
@@ -436,7 +437,7 @@ bool parse_double(const char *j, double &d) {
bool parse_string(const char *j, std::string &s) {
std::string_view answer;
auto error = parser.parse(j,strlen(j))
auto error = parser.parse(j, strlen(j))
.at(0)
.get(answer, error);
if (error) { return false; }
+2 -2
View File
@@ -21,7 +21,7 @@ The current implementations are:
* haswell: AVX2 (2013 Intel Haswell or later)
* westmere: SSE4.2 (2010 Westmere or later).
* arm64: 64-bit ARMv8-A NEON
* ppc64: 64-bit POWER8 and POWER9 with VSX and ALTIVEC extensions. Both big endian and little endian are implemented, depends on the compiler you are using.
* ppc64: 64-bit POWER8 and POWER9 with VSX and ALTIVEC extensions. Both big endian and little endian are implemented, depends on the compiler you are using. Users are advised that the library is not tested on big-endian systems.
* 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
@@ -51,7 +51,7 @@ Inspecting the Detected Implementation
You can check what implementation is running with `active_implementation`:
```c++
cout << "simdjson v" << SIMDJSON_STRINGIFY(SIMDJSON_VERSION) << endl;
cout << "simdjson v" << SIMDJSON_VERSION << endl;
cout << "Detected the best implementation for your machine: " << simdjson::get_active_implementation()->name();
cout << "(" << simdjson::get_active_implementation()->description() << ")" << endl;
```
+3 -3
View File
@@ -70,7 +70,7 @@ constexpr size_t DEFAULT_MAX_DEPTH = 1024;
#define SIMDJSON_ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0)
#if defined(SIMDJSON_REGULAR_VISUAL_STUDIO)
#if SIMDJSON_REGULAR_VISUAL_STUDIO
#define simdjson_really_inline __forceinline
#define simdjson_never_inline __declspec(noinline)
@@ -155,7 +155,7 @@ constexpr size_t DEFAULT_MAX_DEPTH = 1024;
#define SIMDJSON_PRAGMA(P) _Pragma(#P)
#define SIMDJSON_DISABLE_GCC_WARNING(WARNING) SIMDJSON_PRAGMA(GCC diagnostic ignored #WARNING)
#if defined(SIMDJSON_CLANG_VISUAL_STUDIO)
#if SIMDJSON_CLANG_VISUAL_STUDIO
#define SIMDJSON_DISABLE_UNDESIRED_WARNINGS SIMDJSON_DISABLE_GCC_WARNING(-Wmicrosoft-include)
#else
#define SIMDJSON_DISABLE_UNDESIRED_WARNINGS
@@ -180,7 +180,7 @@ constexpr size_t DEFAULT_MAX_DEPTH = 1024;
#define simdjson_inline simdjson_really_inline
#endif
#if defined(SIMDJSON_VISUAL_STUDIO)
#if SIMDJSON_VISUAL_STUDIO
/**
* Windows users need to do some extra work when building
* or using a dynamic library (DLL). When building, we need
+2 -2
View File
@@ -43,7 +43,7 @@ inline simdjson_result<size_t> parser::read_file(const std::string &path) noexce
// Get the file size
int ret;
#if defined(SIMDJSON_VISUAL_STUDIO) && !SIMDJSON_IS_32BITS
#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS
ret = _fseeki64(fp, 0, SEEK_END);
#else
ret = std::fseek(fp, 0, SEEK_END);
@@ -52,7 +52,7 @@ inline simdjson_result<size_t> parser::read_file(const std::string &path) noexce
std::fclose(fp);
return IO_ERROR;
}
#if defined(SIMDJSON_VISUAL_STUDIO) && !SIMDJSON_IS_32BITS
#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS
__int64 len = _ftelli64(fp);
if(len == -1L) {
std::fclose(fp);
+3 -3
View File
@@ -72,7 +72,7 @@ simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) {
return 0; // bad r
}
#ifdef SIMDJSON_IS_32BITS // _umul128 for x86, arm
#if SIMDJSON_IS_32BITS // _umul128 for x86, arm
// this is a slow emulation routine for 32-bit
//
static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) {
@@ -94,7 +94,7 @@ using internal::value128;
simdjson_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
value128 answer;
#if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
#ifdef _M_ARM64
// ARM64 has native support for 64-bit multiplications, no need to emultate
answer.high = __umulh(value1, value2);
@@ -102,7 +102,7 @@ simdjson_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
#else
answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64
#endif // _M_ARM64
#else // defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
__uint128_t r = (static_cast<__uint128_t>(value1)) * value2;
answer.low = uint64_t(r);
answer.high = uint64_t(r >> 64);
@@ -67,35 +67,44 @@ simdjson_inline simdjson_result<object> document::get_object() & noexcept {
auto value = get_root_value_iterator();
return object::start_root(value);
}
/**
* We decided that calling 'get_double()' on the JSON document '1.233 blabla' should
* give an error, so we check for trailing content. We want to disallow trailing
* content.
* Thus, in several implementations below, we pass a 'true' parameter value to
* a get_root_value_iterator() method: this indicates that we disallow trailing content.
*/
simdjson_inline simdjson_result<uint64_t> document::get_uint64() noexcept {
return get_root_value_iterator().get_root_uint64();
return get_root_value_iterator().get_root_uint64(true);
}
simdjson_inline simdjson_result<uint64_t> document::get_uint64_in_string() noexcept {
return get_root_value_iterator().get_root_uint64_in_string();
return get_root_value_iterator().get_root_uint64_in_string(true);
}
simdjson_inline simdjson_result<int64_t> document::get_int64() noexcept {
return get_root_value_iterator().get_root_int64();
return get_root_value_iterator().get_root_int64(true);
}
simdjson_inline simdjson_result<int64_t> document::get_int64_in_string() noexcept {
return get_root_value_iterator().get_root_int64_in_string();
return get_root_value_iterator().get_root_int64_in_string(true);
}
simdjson_inline simdjson_result<double> document::get_double() noexcept {
return get_root_value_iterator().get_root_double();
return get_root_value_iterator().get_root_double(true);
}
simdjson_inline simdjson_result<double> document::get_double_in_string() noexcept {
return get_root_value_iterator().get_root_double_in_string();
return get_root_value_iterator().get_root_double_in_string(true);
}
simdjson_inline simdjson_result<std::string_view> document::get_string() noexcept {
return get_root_value_iterator().get_root_string();
return get_root_value_iterator().get_root_string(true);
}
simdjson_inline simdjson_result<raw_json_string> document::get_raw_json_string() noexcept {
return get_root_value_iterator().get_root_raw_json_string();
return get_root_value_iterator().get_root_raw_json_string(true);
}
simdjson_inline simdjson_result<bool> document::get_bool() noexcept {
return get_root_value_iterator().get_root_bool();
return get_root_value_iterator().get_root_bool(true);
}
simdjson_inline simdjson_result<bool> document::is_null() noexcept {
return get_root_value_iterator().is_root_null();
return get_root_value_iterator().is_root_null(true);
}
template<> simdjson_inline simdjson_result<array> document::get() & noexcept { return get_array(); }
@@ -213,15 +222,15 @@ simdjson_inline bool document::is_negative() noexcept {
}
simdjson_inline simdjson_result<bool> document::is_integer() noexcept {
return get_root_value_iterator().is_root_integer();
return get_root_value_iterator().is_root_integer(true);
}
simdjson_inline simdjson_result<number_type> document::get_number_type() noexcept {
return get_root_value_iterator().get_root_number_type();
return get_root_value_iterator().get_root_number_type(true);
}
simdjson_inline simdjson_result<number> document::get_number() noexcept {
return get_root_value_iterator().get_root_number();
return get_root_value_iterator().get_root_number(true);
}
@@ -330,14 +339,26 @@ simdjson_inline simdjson_result<uint64_t> simdjson_result<SIMDJSON_IMPLEMENTATIO
if (error()) { return error(); }
return first.get_uint64();
}
simdjson_inline simdjson_result<uint64_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get_uint64_in_string() noexcept {
if (error()) { return error(); }
return first.get_uint64_in_string();
}
simdjson_inline simdjson_result<int64_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get_int64() noexcept {
if (error()) { return error(); }
return first.get_int64();
}
simdjson_inline simdjson_result<int64_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get_int64_in_string() noexcept {
if (error()) { return error(); }
return first.get_int64_in_string();
}
simdjson_inline simdjson_result<double> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get_double() noexcept {
if (error()) { return error(); }
return first.get_double();
}
simdjson_inline simdjson_result<double> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get_double_in_string() noexcept {
if (error()) { return error(); }
return first.get_double_in_string();
}
simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get_string() noexcept {
if (error()) { return error(); }
return first.get_string();
@@ -497,24 +518,41 @@ simdjson_inline document_reference::document_reference(document &d) noexcept : d
simdjson_inline void document_reference::rewind() noexcept { doc->rewind(); }
simdjson_inline simdjson_result<array> document_reference::get_array() & noexcept { return doc->get_array(); }
simdjson_inline simdjson_result<object> document_reference::get_object() & noexcept { return doc->get_object(); }
simdjson_inline simdjson_result<uint64_t> document_reference::get_uint64() noexcept { return doc->get_uint64(); }
simdjson_inline simdjson_result<int64_t> document_reference::get_int64() noexcept { return doc->get_int64(); }
simdjson_inline simdjson_result<double> document_reference::get_double() noexcept { return doc->get_double(); }
simdjson_inline simdjson_result<std::string_view> document_reference::get_string() noexcept { return doc->get_string(); }
simdjson_inline simdjson_result<raw_json_string> document_reference::get_raw_json_string() noexcept { return doc->get_raw_json_string(); }
simdjson_inline simdjson_result<bool> document_reference::get_bool() noexcept { return doc->get_bool(); }
/**
* The document_reference instances are used primarily/solely for streams of JSON
* documents.
* We decided that calling 'get_double()' on the JSON document '1.233 blabla' should
* give an error, so we check for trailing content.
*
* However, for streams of JSON documents, we want to be able to start from
* "321" "321" "321"
* and parse it successfully as a stream of JSON documents, calling get_uint64_in_string()
* successfully each time.
*
* To achieve this result, we pass a 'false' to a get_root_value_iterator() method:
* this indicates that we allow trailing content.
*/
simdjson_inline simdjson_result<uint64_t> document_reference::get_uint64() noexcept { return doc->get_root_value_iterator().get_root_uint64(false); }
simdjson_inline simdjson_result<uint64_t> document_reference::get_uint64_in_string() noexcept { return doc->get_root_value_iterator().get_root_uint64_in_string(false); }
simdjson_inline simdjson_result<int64_t> document_reference::get_int64() noexcept { return doc->get_root_value_iterator().get_root_int64(false); }
simdjson_inline simdjson_result<int64_t> document_reference::get_int64_in_string() noexcept { return doc->get_root_value_iterator().get_root_int64_in_string(false); }
simdjson_inline simdjson_result<double> document_reference::get_double() noexcept { return doc->get_root_value_iterator().get_root_double(false); }
simdjson_inline simdjson_result<double> document_reference::get_double_in_string() noexcept { return doc->get_root_value_iterator().get_root_double(false); }
simdjson_inline simdjson_result<std::string_view> document_reference::get_string() noexcept { return doc->get_root_value_iterator().get_root_string(false); }
simdjson_inline simdjson_result<raw_json_string> document_reference::get_raw_json_string() noexcept { return doc->get_root_value_iterator().get_root_raw_json_string(false); }
simdjson_inline simdjson_result<bool> document_reference::get_bool() noexcept { return doc->get_root_value_iterator().get_root_bool(false); }
simdjson_inline simdjson_result<value> document_reference::get_value() noexcept { return doc->get_value(); }
simdjson_inline simdjson_result<bool> document_reference::is_null() noexcept { return doc->is_null(); }
simdjson_inline simdjson_result<bool> document_reference::is_null() noexcept { return doc->get_root_value_iterator().is_root_null(false); }
#if SIMDJSON_EXCEPTIONS
simdjson_inline document_reference::operator array() & noexcept(false) { return array(*doc); }
simdjson_inline document_reference::operator object() & noexcept(false) { return object(*doc); }
simdjson_inline document_reference::operator uint64_t() noexcept(false) { return uint64_t(*doc); }
simdjson_inline document_reference::operator int64_t() noexcept(false) { return int64_t(*doc); }
simdjson_inline document_reference::operator double() noexcept(false) { return double(*doc); }
simdjson_inline document_reference::operator uint64_t() noexcept(false) { return get_uint64(); }
simdjson_inline document_reference::operator int64_t() noexcept(false) { return get_int64(); }
simdjson_inline document_reference::operator double() noexcept(false) { return get_double(); }
simdjson_inline document_reference::operator std::string_view() noexcept(false) { return std::string_view(*doc); }
simdjson_inline document_reference::operator raw_json_string() noexcept(false) { return raw_json_string(*doc); }
simdjson_inline document_reference::operator bool() noexcept(false) { return bool(*doc); }
simdjson_inline document_reference::operator bool() noexcept(false) { return get_bool(); }
simdjson_inline document_reference::operator value() noexcept(false) { return value(*doc); }
#endif
simdjson_inline simdjson_result<size_t> document_reference::count_elements() & noexcept { return doc->count_elements(); }
@@ -533,9 +571,9 @@ simdjson_inline simdjson_result<bool> document_reference::is_scalar() noexcept {
simdjson_inline simdjson_result<const char *> document_reference::current_location() noexcept { return doc->current_location(); }
simdjson_inline int32_t document_reference::current_depth() const noexcept { return doc->current_depth(); }
simdjson_inline bool document_reference::is_negative() noexcept { return doc->is_negative(); }
simdjson_inline simdjson_result<bool> document_reference::is_integer() noexcept { return doc->is_integer(); }
simdjson_inline simdjson_result<number_type> document_reference::get_number_type() noexcept { return doc->get_number_type(); }
simdjson_inline simdjson_result<number> document_reference::get_number() noexcept { return doc->get_number(); }
simdjson_inline simdjson_result<bool> document_reference::is_integer() noexcept { return doc->get_root_value_iterator().is_root_integer(false); }
simdjson_inline simdjson_result<number_type> document_reference::get_number_type() noexcept { return doc->get_root_value_iterator().get_root_number_type(false); }
simdjson_inline simdjson_result<number> document_reference::get_number() noexcept { return doc->get_root_value_iterator().get_root_number(false); }
simdjson_inline simdjson_result<std::string_view> document_reference::raw_json_token() noexcept { return doc->raw_json_token(); }
simdjson_inline simdjson_result<value> document_reference::at_pointer(std::string_view json_pointer) noexcept { return doc->at_pointer(json_pointer); }
simdjson_inline simdjson_result<std::string_view> document_reference::raw_json() noexcept { return doc->raw_json();}
@@ -612,14 +650,26 @@ simdjson_inline simdjson_result<uint64_t> simdjson_result<SIMDJSON_IMPLEMENTATIO
if (error()) { return error(); }
return first.get_uint64();
}
simdjson_inline simdjson_result<uint64_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::get_uint64_in_string() noexcept {
if (error()) { return error(); }
return first.get_uint64_in_string();
}
simdjson_inline simdjson_result<int64_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::get_int64() noexcept {
if (error()) { return error(); }
return first.get_int64();
}
simdjson_inline simdjson_result<int64_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::get_int64_in_string() noexcept {
if (error()) { return error(); }
return first.get_int64_in_string();
}
simdjson_inline simdjson_result<double> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::get_double() noexcept {
if (error()) { return error(); }
return first.get_double();
}
simdjson_inline simdjson_result<double> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::get_double_in_string() noexcept {
if (error()) { return error(); }
return first.get_double_in_string();
}
simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::get_string() noexcept {
if (error()) { return error(); }
return first.get_string();
+10 -1
View File
@@ -577,6 +577,7 @@ protected:
friend class field;
friend class token;
friend class document_stream;
friend class document_reference;
};
@@ -593,8 +594,11 @@ public:
simdjson_inline simdjson_result<array> get_array() & noexcept;
simdjson_inline simdjson_result<object> get_object() & noexcept;
simdjson_inline simdjson_result<uint64_t> get_uint64() noexcept;
simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string() noexcept;
simdjson_inline simdjson_result<raw_json_string> get_raw_json_string() noexcept;
simdjson_inline simdjson_result<bool> get_bool() noexcept;
@@ -658,9 +662,11 @@ public:
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array> get_array() & noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object> get_object() & noexcept;
simdjson_inline simdjson_result<uint64_t> get_uint64() noexcept;
simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_from_string() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string() noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
simdjson_inline simdjson_result<bool> get_bool() noexcept;
@@ -726,8 +732,11 @@ public:
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::array> get_array() & noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::object> get_object() & noexcept;
simdjson_inline simdjson_result<uint64_t> get_uint64() noexcept;
simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string() noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
simdjson_inline simdjson_result<bool> get_bool() noexcept;
+10 -4
View File
@@ -136,9 +136,15 @@ inline void log_line(const json_iterator &iter, token_position index, depth_t de
{
// Print the current structural.
printf("| ");
auto current_structural = &buf[*index];
for (int i=0;i<LOG_BUFFER_LEN;i++) {
printf("%c", printable_char(current_structural[i]));
// Before we begin, the index might point right before the document.
// This could be unsafe, see https://github.com/simdjson/simdjson/discussions/1938
if(index < iter._root) {
printf("%*s", LOG_BUFFER_LEN, "");
} else {
auto current_structural = &buf[*index];
for (int i=0;i<LOG_BUFFER_LEN;i++) {
printf("%c", printable_char(current_structural[i]));
}
}
printf(" ");
}
@@ -153,7 +159,7 @@ inline void log_line(const json_iterator &iter, token_position index, depth_t de
}
// printf("| %5u ", *(index+1));
printf("| %5i ", depth);
printf("| %.*s ", int(detail.size()), detail.data());
printf("| %6.*s ", int(detail.size()) , detail.data());
printf("|\n");
fflush(stdout);
}
@@ -544,7 +544,7 @@ simdjson_inline simdjson_result<number> value_iterator::get_number() noexcept {
return num;
}
simdjson_inline simdjson_result<bool> value_iterator::is_root_integer() noexcept {
simdjson_inline simdjson_result<bool> value_iterator::is_root_integer(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("is_root_integer");
uint8_t tmpbuf[20+1]; // <20 digits> is the longest possible unsigned integer
@@ -555,12 +555,11 @@ simdjson_inline simdjson_result<bool> value_iterator::is_root_integer() noexcept
// If the parsing was a success, we must still check that it is
// a single scalar. Note that we parse first because of cases like '[]' where
// getting TRAILING_CONTENT is wrong.
if((answer.error() == SUCCESS) && (!_json_iter->is_single_token())) { return TRAILING_CONTENT; }
if(check_trailing && (answer.error() == SUCCESS) && (!_json_iter->is_single_token())) { return TRAILING_CONTENT; }
return answer;
}
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::number_type> value_iterator::get_root_number_type() noexcept {
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::number_type> value_iterator::get_root_number_type(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("number");
// Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/,
@@ -571,14 +570,11 @@ simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::number_type>
logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters");
return NUMBER_ERROR;
}
// If the parsing was a success, we must still check that it is
// a single scalar. Note that we parse first because of cases like '[]' where
// getting TRAILING_CONTENT is wrong.
auto answer = numberparsing::get_number_type(tmpbuf);
if((answer.error() == SUCCESS) && (!_json_iter->is_single_token())) { return TRAILING_CONTENT; }
if (check_trailing && (answer.error() == SUCCESS) && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
return answer;
}
simdjson_inline simdjson_result<number> value_iterator::get_root_number() noexcept {
simdjson_inline simdjson_result<number> value_iterator::get_root_number(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("number");
// Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/,
@@ -592,18 +588,21 @@ simdjson_inline simdjson_result<number> value_iterator::get_root_number() noexce
number num;
error_code error = numberparsing::parse_number(tmpbuf, num);
if(error) { return error; }
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("number");
return num;
}
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> value_iterator::get_root_string() noexcept {
return get_string();
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> value_iterator::get_root_string(bool check_trailing) noexcept {
return get_root_raw_json_string(check_trailing).unescape(json_iter());
}
simdjson_warn_unused simdjson_inline simdjson_result<raw_json_string> value_iterator::get_root_raw_json_string() noexcept {
return get_raw_json_string();
simdjson_warn_unused simdjson_inline simdjson_result<raw_json_string> value_iterator::get_root_raw_json_string(bool check_trailing) noexcept {
auto json = peek_scalar("string");
if (*json != '"') { return incorrect_type_error("Not a string"); }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_scalar("string");
return raw_json_string(json+1);
}
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> value_iterator::get_root_uint64() noexcept {
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> value_iterator::get_root_uint64(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("uint64");
uint8_t tmpbuf[20+1]; // <20 digits> is the longest possible unsigned integer
@@ -613,12 +612,12 @@ simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> value_iterator::g
}
auto result = numberparsing::parse_unsigned(tmpbuf);
if(result.error() == SUCCESS) {
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("uint64");
}
return result;
}
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> value_iterator::get_root_uint64_in_string() noexcept {
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> value_iterator::get_root_uint64_in_string(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("uint64");
uint8_t tmpbuf[20+1]; // <20 digits> is the longest possible unsigned integer
@@ -628,12 +627,12 @@ simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> value_iterator::g
}
auto result = numberparsing::parse_unsigned_in_string(tmpbuf);
if(result.error() == SUCCESS) {
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("uint64");
}
return result;
}
simdjson_warn_unused simdjson_inline simdjson_result<int64_t> value_iterator::get_root_int64() noexcept {
simdjson_warn_unused simdjson_inline simdjson_result<int64_t> value_iterator::get_root_int64(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("int64");
uint8_t tmpbuf[20+1]; // -<19 digits> is the longest possible integer
@@ -644,12 +643,12 @@ simdjson_warn_unused simdjson_inline simdjson_result<int64_t> value_iterator::ge
auto result = numberparsing::parse_integer(tmpbuf);
if(result.error() == SUCCESS) {
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("int64");
}
return result;
}
simdjson_warn_unused simdjson_inline simdjson_result<int64_t> value_iterator::get_root_int64_in_string() noexcept {
simdjson_warn_unused simdjson_inline simdjson_result<int64_t> value_iterator::get_root_int64_in_string(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("int64");
uint8_t tmpbuf[20+1]; // -<19 digits> is the longest possible integer
@@ -660,12 +659,12 @@ simdjson_warn_unused simdjson_inline simdjson_result<int64_t> value_iterator::ge
auto result = numberparsing::parse_integer_in_string(tmpbuf);
if(result.error() == SUCCESS) {
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("int64");
}
return result;
}
simdjson_warn_unused simdjson_inline simdjson_result<double> value_iterator::get_root_double() noexcept {
simdjson_warn_unused simdjson_inline simdjson_result<double> value_iterator::get_root_double(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("double");
// Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/,
@@ -678,13 +677,13 @@ simdjson_warn_unused simdjson_inline simdjson_result<double> value_iterator::get
}
auto result = numberparsing::parse_double(tmpbuf);
if(result.error() == SUCCESS) {
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("double");
}
return result;
}
simdjson_warn_unused simdjson_inline simdjson_result<double> value_iterator::get_root_double_in_string() noexcept {
simdjson_warn_unused simdjson_inline simdjson_result<double> value_iterator::get_root_double_in_string(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("double");
// Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/,
@@ -697,31 +696,32 @@ simdjson_warn_unused simdjson_inline simdjson_result<double> value_iterator::get
}
auto result = numberparsing::parse_double_in_string(tmpbuf);
if(result.error() == SUCCESS) {
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("double");
}
return result;
}
simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::get_root_bool() noexcept {
simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::get_root_bool(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("bool");
uint8_t tmpbuf[5+1];
if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf)) { return incorrect_type_error("Not a boolean"); }
auto result = parse_bool(tmpbuf);
if(result.error() == SUCCESS) {
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("bool");
}
return result;
}
simdjson_inline bool value_iterator::is_root_null() noexcept {
// If there is trailing content, then the document is not null.
if (!_json_iter->is_single_token()) { return false; }
simdjson_inline simdjson_result<bool> value_iterator::is_root_null(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("null");
bool result = (max_len >= 4 && !atomparsing::str4ncmp(json, "null") &&
(max_len == 4 || jsoncharutils::is_structural_or_whitespace(json[5])));
if(result) { advance_root_scalar("null"); }
(max_len == 4 || jsoncharutils::is_structural_or_whitespace(json[4])));
if(result) { // we have something that looks like a null.
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("null");
}
return result;
}
@@ -295,20 +295,20 @@ public:
simdjson_warn_unused simdjson_inline simdjson_result<number_type> get_number_type() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<number> get_number() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> get_root_string() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<raw_json_string> get_root_raw_json_string() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> get_root_uint64() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> get_root_uint64_in_string() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<int64_t> get_root_int64() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<int64_t> get_root_int64_in_string() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<double> get_root_double() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<double> get_root_double_in_string() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<bool> get_root_bool() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> get_root_string(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<raw_json_string> get_root_raw_json_string(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> get_root_uint64(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> get_root_uint64_in_string(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<int64_t> get_root_int64(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<int64_t> get_root_int64_in_string(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<double> get_root_double(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<double> get_root_double_in_string(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<bool> get_root_bool(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline bool is_root_negative() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<bool> is_root_integer() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<number_type> get_root_number_type() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<number> get_root_number() noexcept;
simdjson_inline bool is_root_null() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<bool> is_root_integer(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<number_type> get_root_number_type(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<number> get_root_number(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<bool> is_root_null(bool check_trailing) noexcept;
simdjson_inline error_code error() const noexcept;
simdjson_inline uint8_t *&string_buf_loc() noexcept;
+3 -3
View File
@@ -10,7 +10,7 @@ namespace {
// Sadly, sanitizers are not smart enough to figure it out.
SIMDJSON_NO_SANITIZE_UNDEFINED
simdjson_inline int trailing_zeroes(uint64_t input_num) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
return (int)_tzcnt_u64(input_num);
#else // SIMDJSON_REGULAR_VISUAL_STUDIO
////////
@@ -32,7 +32,7 @@ simdjson_inline int leading_zeroes(uint64_t input_num) {
return int(_lzcnt_u64(input_num));
}
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
simdjson_inline unsigned __int64 count_ones(uint64_t input_num) {
// note: we do not support legacy 32-bit Windows
return __popcnt64(input_num);// Visual Studio wants two underscores
@@ -45,7 +45,7 @@ simdjson_inline long long int count_ones(uint64_t input_num) {
simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2,
uint64_t *result) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
return _addcarry_u64(0, value1, value2,
reinterpret_cast<unsigned __int64 *>(result));
#else
+2 -2
View File
@@ -3,14 +3,14 @@
#include "simdjson/base.h"
#ifdef SIMDJSON_VISUAL_STUDIO
#if SIMDJSON_VISUAL_STUDIO
// under clang within visual studio, this will include <x86intrin.h>
#include <intrin.h> // visual studio or clang
#else
#include <x86intrin.h> // elsewhere
#endif // SIMDJSON_VISUAL_STUDIO
#ifdef SIMDJSON_CLANG_VISUAL_STUDIO
#if SIMDJSON_CLANG_VISUAL_STUDIO
/**
* You are not supposed, normally, to include these
* headers directly. Instead you should either include intrin.h
+3 -3
View File
@@ -10,7 +10,7 @@ namespace {
// Sadly, sanitizers are not smart enough to figure it out.
SIMDJSON_NO_SANITIZE_UNDEFINED
simdjson_inline int trailing_zeroes(uint64_t input_num) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
return (int)_tzcnt_u64(input_num);
#else // SIMDJSON_REGULAR_VISUAL_STUDIO
////////
@@ -32,7 +32,7 @@ simdjson_inline int leading_zeroes(uint64_t input_num) {
return int(_lzcnt_u64(input_num));
}
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
simdjson_inline unsigned __int64 count_ones(uint64_t input_num) {
// note: we do not support legacy 32-bit Windows
return __popcnt64(input_num);// Visual Studio wants two underscores
@@ -45,7 +45,7 @@ simdjson_inline long long int count_ones(uint64_t input_num) {
simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2,
uint64_t *result) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
return _addcarry_u64(0, value1, value2,
reinterpret_cast<unsigned __int64 *>(result));
#else
+2 -2
View File
@@ -3,14 +3,14 @@
#include "simdjson/base.h"
#ifdef SIMDJSON_VISUAL_STUDIO
#if SIMDJSON_VISUAL_STUDIO
// under clang within visual studio, this will include <x86intrin.h>
#include <intrin.h> // visual studio or clang
#else
#include <x86intrin.h> // elsewhere
#endif // SIMDJSON_VISUAL_STUDIO
#ifdef SIMDJSON_CLANG_VISUAL_STUDIO
#if SIMDJSON_CLANG_VISUAL_STUDIO
/**
* You are not supposed, normally, to include these
* headers directly. Instead you should either include intrin.h
+1 -1
View File
@@ -87,7 +87,7 @@ public:
*
* @return a mask of all required `internal::instruction_set::` values.
*/
virtual uint32_t required_instruction_sets() const { return _required_instruction_sets; };
virtual uint32_t required_instruction_sets() const { return _required_instruction_sets; }
/**
* @private For internal implementation use
+18 -3
View File
@@ -51,8 +51,13 @@
// Default Haswell to on if this is x86-64. Even if we're not compiled for it, it could be selected
// at runtime.
#ifndef SIMDJSON_IMPLEMENTATION_HASWELL
#if SIMDJSON_CAN_ALWAYS_RUN_ICELAKE
// if icelake is always available, never enable haswell.
#define SIMDJSON_IMPLEMENTATION_HASWELL 0
#else
#define SIMDJSON_IMPLEMENTATION_HASWELL SIMDJSON_IS_X86_64
#endif
#endif
#ifdef _MSC_VER
// To see why (__BMI__) && (__PCLMUL__) && (__LZCNT__) are not part of this next line, see
// https://github.com/simdjson/simdjson/issues/1247
@@ -61,9 +66,14 @@
#define SIMDJSON_CAN_ALWAYS_RUN_HASWELL ((SIMDJSON_IMPLEMENTATION_HASWELL) && (SIMDJSON_IS_X86_64) && (__AVX2__) && (__BMI__) && (__PCLMUL__) && (__LZCNT__))
#endif
// Default Westmere to on if this is x86-64. Note that the macro SIMDJSON_REQUIRES_HASWELL appears unused.
// Default Westmere to on if this is x86-64.
#ifndef SIMDJSON_IMPLEMENTATION_WESTMERE
#define SIMDJSON_IMPLEMENTATION_WESTMERE (SIMDJSON_IS_X86_64 && !SIMDJSON_REQUIRES_HASWELL)
#if SIMDJSON_CAN_ALWAYS_RUN_ICELAKE || SIMDJSON_CAN_ALWAYS_RUN_HASWELL
// if icelake or haswell are always available, never enable westmere.
#define SIMDJSON_IMPLEMENTATION_WESTMERE 0
#else
#define SIMDJSON_IMPLEMENTATION_WESTMERE SIMDJSON_IS_X86_64
#endif
#endif
#define SIMDJSON_CAN_ALWAYS_RUN_WESTMERE (SIMDJSON_IMPLEMENTATION_WESTMERE && SIMDJSON_IS_X86_64 && __SSE4_2__ && __PCLMUL__)
@@ -74,7 +84,12 @@
// Default Fallback to on unless a builtin implementation has already been selected.
#ifndef SIMDJSON_IMPLEMENTATION_FALLBACK
#define SIMDJSON_IMPLEMENTATION_FALLBACK 1 // (!SIMDJSON_CAN_ALWAYS_RUN_ARM64 && !SIMDJSON_CAN_ALWAYS_RUN_HASWELL && !SIMDJSON_CAN_ALWAYS_RUN_WESTMERE && !SIMDJSON_CAN_ALWAYS_RUN_PPC64)
#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
// if anything at all except fallback can always run, then disable fallback.
#define SIMDJSON_IMPLEMENTATION_FALLBACK 0
#else
#define SIMDJSON_IMPLEMENTATION_FALLBACK 1
#endif
#endif
#define SIMDJSON_CAN_ALWAYS_RUN_FALLBACK SIMDJSON_IMPLEMENTATION_FALLBACK
+2 -2
View File
@@ -128,7 +128,7 @@ inline simdjson_result<padded_string> padded_string::load(std::string_view filen
// Get the file size
int ret;
#if defined(SIMDJSON_VISUAL_STUDIO) && !SIMDJSON_IS_32BITS
#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS
ret = _fseeki64(fp, 0, SEEK_END);
#else
ret = std::fseek(fp, 0, SEEK_END);
@@ -137,7 +137,7 @@ inline simdjson_result<padded_string> padded_string::load(std::string_view filen
std::fclose(fp);
return IO_ERROR;
}
#if defined(SIMDJSON_VISUAL_STUDIO) && !SIMDJSON_IS_32BITS
#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS
__int64 llen = _ftelli64(fp);
if(llen == -1L) {
std::fclose(fp);
+8 -5
View File
@@ -32,7 +32,7 @@
#endif // __clang__
#endif // _MSC_VER
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
// https://en.wikipedia.org/wiki/C_alternative_tokens
// This header should have no effect, except maybe
// under Visual Studio.
@@ -59,8 +59,11 @@
#endif
#endif // defined(__x86_64__) || defined(_M_AMD64)
#ifndef SIMDJSON_IS_32BITS
#define SIMDJSON_IS_32BITS 0
#endif
#ifdef SIMDJSON_IS_32BITS
#if SIMDJSON_IS_32BITS
#ifndef SIMDJSON_NO_PORTABILITY_WARNING
#pragma message("The simdjson library is designed \
for 64-bit processors and it seems that you are not \
@@ -91,7 +94,7 @@ use a 64-bit target such as x64, 64-bit ARM or 64-bit PPC.")
//
// We are going to use runtime dispatch.
#ifdef SIMDJSON_IS_X86_64
#if SIMDJSON_IS_X86_64
#ifdef __clang__
// clang does not have GCC push pop
// warning: clang attribute push can't be used within a namespace in clang up
@@ -145,7 +148,7 @@ use a 64-bit target such as x64, 64-bit ARM or 64-bit PPC.")
#define SIMDJSON_NO_SANITIZE_UNDEFINED
#endif
#ifdef SIMDJSON_VISUAL_STUDIO
#if SIMDJSON_VISUAL_STUDIO
// This is one case where we do not distinguish between
// regular visual studio and clang under visual studio.
// clang under Windows has _stricmp (like visual studio) but not strcasecmp (as clang normally has)
@@ -161,7 +164,7 @@ use a 64-bit target such as x64, 64-bit ARM or 64-bit PPC.")
#ifdef NDEBUG
#ifdef SIMDJSON_VISUAL_STUDIO
#if SIMDJSON_VISUAL_STUDIO
#define SIMDJSON_UNREACHABLE() __assume(0)
#define SIMDJSON_ASSUME(COND) __assume(COND)
#else
+4 -4
View File
@@ -10,7 +10,7 @@ namespace {
// Sadly, sanitizers are not smart enough to figure it out.
SIMDJSON_NO_SANITIZE_UNDEFINED
simdjson_inline int trailing_zeroes(uint64_t input_num) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
unsigned long ret;
// Search the mask data from least significant bit (LSB)
// to the most significant bit (MSB) for a set bit (1).
@@ -28,7 +28,7 @@ simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) {
/* result might be undefined when input_num is zero */
simdjson_inline int leading_zeroes(uint64_t input_num) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
unsigned long leading_zero = 0;
// Search the mask data from most significant bit (MSB)
// to least significant bit (LSB) for a set bit (1).
@@ -41,7 +41,7 @@ simdjson_inline int leading_zeroes(uint64_t input_num) {
#endif // SIMDJSON_REGULAR_VISUAL_STUDIO
}
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
simdjson_inline int count_ones(uint64_t input_num) {
// note: we do not support legacy 32-bit Windows
return __popcnt64(input_num); // Visual Studio wants two underscores
@@ -54,7 +54,7 @@ simdjson_inline int count_ones(uint64_t input_num) {
simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2,
uint64_t *result) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
*result = value1 + value2;
return *result < value1;
#else
+3 -3
View File
@@ -4,7 +4,7 @@
#define SIMDJSON_SIMDJSON_VERSION_H
/** The version of simdjson being used (major.minor.revision) */
#define SIMDJSON_VERSION 3.0.1
#define SIMDJSON_VERSION 3.1.0
namespace simdjson {
enum {
@@ -15,11 +15,11 @@ enum {
/**
* The minor version (major.MINOR.revision) of simdjson being used.
*/
SIMDJSON_VERSION_MINOR = 0,
SIMDJSON_VERSION_MINOR = 1,
/**
* The revision (major.minor.REVISION) of simdjson being used.
*/
SIMDJSON_VERSION_REVISION = 1
SIMDJSON_VERSION_REVISION = 0
};
} // namespace simdjson
+4 -4
View File
@@ -10,7 +10,7 @@ namespace {
// Sadly, sanitizers are not smart enough to figure it out.
SIMDJSON_NO_SANITIZE_UNDEFINED
simdjson_inline int trailing_zeroes(uint64_t input_num) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
unsigned long ret;
// Search the mask data from least significant bit (LSB)
// to the most significant bit (MSB) for a set bit (1).
@@ -28,7 +28,7 @@ simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) {
/* result might be undefined when input_num is zero */
simdjson_inline int leading_zeroes(uint64_t input_num) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
unsigned long leading_zero = 0;
// Search the mask data from most significant bit (MSB)
// to least significant bit (LSB) for a set bit (1).
@@ -41,7 +41,7 @@ simdjson_inline int leading_zeroes(uint64_t input_num) {
#endif// SIMDJSON_REGULAR_VISUAL_STUDIO
}
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
simdjson_inline unsigned __int64 count_ones(uint64_t input_num) {
// note: we do not support legacy 32-bit Windows
return __popcnt64(input_num);// Visual Studio wants two underscores
@@ -54,7 +54,7 @@ simdjson_inline long long int count_ones(uint64_t input_num) {
simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2,
uint64_t *result) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
return _addcarry_u64(0, value1, value2,
reinterpret_cast<unsigned __int64 *>(result));
#else
+2 -2
View File
@@ -1,7 +1,7 @@
#ifndef SIMDJSON_WESTMERE_INTRINSICS_H
#define SIMDJSON_WESTMERE_INTRINSICS_H
#ifdef SIMDJSON_VISUAL_STUDIO
#if SIMDJSON_VISUAL_STUDIO
// under clang within visual studio, this will include <x86intrin.h>
#include <intrin.h> // visual studio or clang
#else
@@ -9,7 +9,7 @@
#endif // SIMDJSON_VISUAL_STUDIO
#ifdef SIMDJSON_CLANG_VISUAL_STUDIO
#if SIMDJSON_CLANG_VISUAL_STUDIO
/**
* You are not supposed, normally, to include these
* headers directly. Instead you should either include intrin.h
+6 -7
View File
@@ -1,4 +1,4 @@
/* auto-generated on 2022-11-23 10:31:42 -0500. Do not edit! */
/* auto-generated on 2023-01-21 15:29:08 -0500. Do not edit! */
/* begin file src/simdjson.cpp */
#include "simdjson.h"
@@ -3783,7 +3783,7 @@ public:
// it helps tremendously.
if (bits == 0)
return;
#if defined(SIMDJSON_PREFER_REVERSE_BITS)
#if SIMDJSON_PREFER_REVERSE_BITS
/**
* ARM lacks a fast trailing zero instruction, but it has a fast
* bit reversal instruction and a fast leading zero instruction.
@@ -5147,7 +5147,6 @@ simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *
// redefining SIMDJSON_IMPLEMENTATION to "fallback"
// #define SIMDJSON_IMPLEMENTATION fallback
/* end file include/simdjson/fallback/begin.h */
namespace simdjson {
namespace fallback {
@@ -7577,7 +7576,7 @@ public:
// it helps tremendously.
if (bits == 0)
return;
#if defined(SIMDJSON_PREFER_REVERSE_BITS)
#if SIMDJSON_PREFER_REVERSE_BITS
/**
* ARM lacks a fast trailing zero instruction, but it has a fast
* bit reversal instruction and a fast leading zero instruction.
@@ -9969,7 +9968,7 @@ public:
// it helps tremendously.
if (bits == 0)
return;
#if defined(SIMDJSON_PREFER_REVERSE_BITS)
#if SIMDJSON_PREFER_REVERSE_BITS
/**
* ARM lacks a fast trailing zero instruction, but it has a fast
* bit reversal instruction and a fast leading zero instruction.
@@ -12277,7 +12276,7 @@ public:
// it helps tremendously.
if (bits == 0)
return;
#if defined(SIMDJSON_PREFER_REVERSE_BITS)
#if SIMDJSON_PREFER_REVERSE_BITS
/**
* ARM lacks a fast trailing zero instruction, but it has a fast
* bit reversal instruction and a fast leading zero instruction.
@@ -14620,7 +14619,7 @@ public:
// it helps tremendously.
if (bits == 0)
return;
#if defined(SIMDJSON_PREFER_REVERSE_BITS)
#if SIMDJSON_PREFER_REVERSE_BITS
/**
* ARM lacks a fast trailing zero instruction, but it has a fast
* bit reversal instruction and a fast leading zero instruction.
+220 -137
View File
@@ -1,4 +1,4 @@
/* auto-generated on 2022-11-23 10:31:42 -0500. Do not edit! */
/* auto-generated on 2023-01-21 15:29:08 -0500. 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.0.1
#define SIMDJSON_VERSION 3.1.0
namespace simdjson {
enum {
@@ -54,11 +54,11 @@ enum {
/**
* The minor version (major.MINOR.revision) of simdjson being used.
*/
SIMDJSON_VERSION_MINOR = 0,
SIMDJSON_VERSION_MINOR = 1,
/**
* The revision (major.minor.REVISION) of simdjson being used.
*/
SIMDJSON_VERSION_REVISION = 1
SIMDJSON_VERSION_REVISION = 0
};
} // namespace simdjson
@@ -149,7 +149,7 @@ enum {
#endif // __clang__
#endif // _MSC_VER
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
// https://en.wikipedia.org/wiki/C_alternative_tokens
// This header should have no effect, except maybe
// under Visual Studio.
@@ -176,8 +176,11 @@ enum {
#endif
#endif // defined(__x86_64__) || defined(_M_AMD64)
#ifndef SIMDJSON_IS_32BITS
#define SIMDJSON_IS_32BITS 0
#endif
#ifdef SIMDJSON_IS_32BITS
#if SIMDJSON_IS_32BITS
#ifndef SIMDJSON_NO_PORTABILITY_WARNING
#pragma message("The simdjson library is designed \
for 64-bit processors and it seems that you are not \
@@ -208,7 +211,7 @@ use a 64-bit target such as x64, 64-bit ARM or 64-bit PPC.")
//
// We are going to use runtime dispatch.
#ifdef SIMDJSON_IS_X86_64
#if SIMDJSON_IS_X86_64
#ifdef __clang__
// clang does not have GCC push pop
// warning: clang attribute push can't be used within a namespace in clang up
@@ -262,7 +265,7 @@ use a 64-bit target such as x64, 64-bit ARM or 64-bit PPC.")
#define SIMDJSON_NO_SANITIZE_UNDEFINED
#endif
#ifdef SIMDJSON_VISUAL_STUDIO
#if SIMDJSON_VISUAL_STUDIO
// This is one case where we do not distinguish between
// regular visual studio and clang under visual studio.
// clang under Windows has _stricmp (like visual studio) but not strcasecmp (as clang normally has)
@@ -278,7 +281,7 @@ use a 64-bit target such as x64, 64-bit ARM or 64-bit PPC.")
#ifdef NDEBUG
#ifdef SIMDJSON_VISUAL_STUDIO
#if SIMDJSON_VISUAL_STUDIO
#define SIMDJSON_UNREACHABLE() __assume(0)
#define SIMDJSON_ASSUME(COND) __assume(COND)
#else
@@ -362,7 +365,7 @@ constexpr size_t DEFAULT_MAX_DEPTH = 1024;
#define SIMDJSON_ISALIGNED_N(ptr, n) (((uintptr_t)(ptr) & ((n)-1)) == 0)
#if defined(SIMDJSON_REGULAR_VISUAL_STUDIO)
#if SIMDJSON_REGULAR_VISUAL_STUDIO
#define simdjson_really_inline __forceinline
#define simdjson_never_inline __declspec(noinline)
@@ -447,7 +450,7 @@ constexpr size_t DEFAULT_MAX_DEPTH = 1024;
#define SIMDJSON_PRAGMA(P) _Pragma(#P)
#define SIMDJSON_DISABLE_GCC_WARNING(WARNING) SIMDJSON_PRAGMA(GCC diagnostic ignored #WARNING)
#if defined(SIMDJSON_CLANG_VISUAL_STUDIO)
#if SIMDJSON_CLANG_VISUAL_STUDIO
#define SIMDJSON_DISABLE_UNDESIRED_WARNINGS SIMDJSON_DISABLE_GCC_WARNING(-Wmicrosoft-include)
#else
#define SIMDJSON_DISABLE_UNDESIRED_WARNINGS
@@ -472,7 +475,7 @@ constexpr size_t DEFAULT_MAX_DEPTH = 1024;
#define simdjson_inline simdjson_really_inline
#endif
#if defined(SIMDJSON_VISUAL_STUDIO)
#if SIMDJSON_VISUAL_STUDIO
/**
* Windows users need to do some extra work when building
* or using a dynamic library (DLL). When building, we need
@@ -3405,7 +3408,7 @@ public:
*
* @return a mask of all required `internal::instruction_set::` values.
*/
virtual uint32_t required_instruction_sets() const { return _required_instruction_sets; };
virtual uint32_t required_instruction_sets() const { return _required_instruction_sets; }
/**
* @private For internal implementation use
@@ -3887,7 +3890,7 @@ inline simdjson_result<padded_string> padded_string::load(std::string_view filen
// Get the file size
int ret;
#if defined(SIMDJSON_VISUAL_STUDIO) && !SIMDJSON_IS_32BITS
#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS
ret = _fseeki64(fp, 0, SEEK_END);
#else
ret = std::fseek(fp, 0, SEEK_END);
@@ -3896,7 +3899,7 @@ inline simdjson_result<padded_string> padded_string::load(std::string_view filen
std::fclose(fp);
return IO_ERROR;
}
#if defined(SIMDJSON_VISUAL_STUDIO) && !SIMDJSON_IS_32BITS
#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS
__int64 llen = _ftelli64(fp);
if(llen == -1L) {
std::fclose(fp);
@@ -8695,7 +8698,7 @@ inline simdjson_result<size_t> parser::read_file(const std::string &path) noexce
// Get the file size
int ret;
#if defined(SIMDJSON_VISUAL_STUDIO) && !SIMDJSON_IS_32BITS
#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS
ret = _fseeki64(fp, 0, SEEK_END);
#else
ret = std::fseek(fp, 0, SEEK_END);
@@ -8704,7 +8707,7 @@ inline simdjson_result<size_t> parser::read_file(const std::string &path) noexce
std::fclose(fp);
return IO_ERROR;
}
#if defined(SIMDJSON_VISUAL_STUDIO) && !SIMDJSON_IS_32BITS
#if SIMDJSON_VISUAL_STUDIO && !SIMDJSON_IS_32BITS
__int64 len = _ftelli64(fp);
if(len == -1L) {
std::fclose(fp);
@@ -9620,8 +9623,13 @@ extern SIMDJSON_DLLIMPORTEXPORT const uint64_t thintable_epi8[256];
// Default Haswell to on if this is x86-64. Even if we're not compiled for it, it could be selected
// at runtime.
#ifndef SIMDJSON_IMPLEMENTATION_HASWELL
#if SIMDJSON_CAN_ALWAYS_RUN_ICELAKE
// if icelake is always available, never enable haswell.
#define SIMDJSON_IMPLEMENTATION_HASWELL 0
#else
#define SIMDJSON_IMPLEMENTATION_HASWELL SIMDJSON_IS_X86_64
#endif
#endif
#ifdef _MSC_VER
// To see why (__BMI__) && (__PCLMUL__) && (__LZCNT__) are not part of this next line, see
// https://github.com/simdjson/simdjson/issues/1247
@@ -9630,9 +9638,14 @@ extern SIMDJSON_DLLIMPORTEXPORT const uint64_t thintable_epi8[256];
#define SIMDJSON_CAN_ALWAYS_RUN_HASWELL ((SIMDJSON_IMPLEMENTATION_HASWELL) && (SIMDJSON_IS_X86_64) && (__AVX2__) && (__BMI__) && (__PCLMUL__) && (__LZCNT__))
#endif
// Default Westmere to on if this is x86-64. Note that the macro SIMDJSON_REQUIRES_HASWELL appears unused.
// Default Westmere to on if this is x86-64.
#ifndef SIMDJSON_IMPLEMENTATION_WESTMERE
#define SIMDJSON_IMPLEMENTATION_WESTMERE (SIMDJSON_IS_X86_64 && !SIMDJSON_REQUIRES_HASWELL)
#if SIMDJSON_CAN_ALWAYS_RUN_ICELAKE || SIMDJSON_CAN_ALWAYS_RUN_HASWELL
// if icelake or haswell are always available, never enable westmere.
#define SIMDJSON_IMPLEMENTATION_WESTMERE 0
#else
#define SIMDJSON_IMPLEMENTATION_WESTMERE SIMDJSON_IS_X86_64
#endif
#endif
#define SIMDJSON_CAN_ALWAYS_RUN_WESTMERE (SIMDJSON_IMPLEMENTATION_WESTMERE && SIMDJSON_IS_X86_64 && __SSE4_2__ && __PCLMUL__)
@@ -9643,7 +9656,12 @@ extern SIMDJSON_DLLIMPORTEXPORT const uint64_t thintable_epi8[256];
// Default Fallback to on unless a builtin implementation has already been selected.
#ifndef SIMDJSON_IMPLEMENTATION_FALLBACK
#define SIMDJSON_IMPLEMENTATION_FALLBACK 1 // (!SIMDJSON_CAN_ALWAYS_RUN_ARM64 && !SIMDJSON_CAN_ALWAYS_RUN_HASWELL && !SIMDJSON_CAN_ALWAYS_RUN_WESTMERE && !SIMDJSON_CAN_ALWAYS_RUN_PPC64)
#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
// if anything at all except fallback can always run, then disable fallback.
#define SIMDJSON_IMPLEMENTATION_FALLBACK 0
#else
#define SIMDJSON_IMPLEMENTATION_FALLBACK 1
#endif
#endif
#define SIMDJSON_CAN_ALWAYS_RUN_FALLBACK SIMDJSON_IMPLEMENTATION_FALLBACK
@@ -10542,7 +10560,7 @@ simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) {
return 0; // bad r
}
#ifdef SIMDJSON_IS_32BITS // _umul128 for x86, arm
#if SIMDJSON_IS_32BITS // _umul128 for x86, arm
// this is a slow emulation routine for 32-bit
//
static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) {
@@ -10564,7 +10582,7 @@ using internal::value128;
simdjson_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
value128 answer;
#if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
#ifdef _M_ARM64
// ARM64 has native support for 64-bit multiplications, no need to emultate
answer.high = __umulh(value1, value2);
@@ -10572,7 +10590,7 @@ simdjson_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
#else
answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64
#endif // _M_ARM64
#else // defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
__uint128_t r = (static_cast<__uint128_t>(value1)) * value2;
answer.low = uint64_t(r);
answer.high = uint64_t(r >> 64);
@@ -12249,7 +12267,7 @@ simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) {
return 0; // bad r
}
#ifdef SIMDJSON_IS_32BITS // _umul128 for x86, arm
#if SIMDJSON_IS_32BITS // _umul128 for x86, arm
// this is a slow emulation routine for 32-bit
//
static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) {
@@ -12271,7 +12289,7 @@ using internal::value128;
simdjson_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
value128 answer;
#if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
#ifdef _M_ARM64
// ARM64 has native support for 64-bit multiplications, no need to emultate
answer.high = __umulh(value1, value2);
@@ -12279,7 +12297,7 @@ simdjson_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
#else
answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64
#endif // _M_ARM64
#else // defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
__uint128_t r = (static_cast<__uint128_t>(value1)) * value2;
answer.low = uint64_t(r);
answer.high = uint64_t(r >> 64);
@@ -13753,14 +13771,14 @@ public:
#define SIMDJSON_ICELAKE_INTRINSICS_H
#ifdef SIMDJSON_VISUAL_STUDIO
#if SIMDJSON_VISUAL_STUDIO
// under clang within visual studio, this will include <x86intrin.h>
#include <intrin.h> // visual studio or clang
#else
#include <x86intrin.h> // elsewhere
#endif // SIMDJSON_VISUAL_STUDIO
#ifdef SIMDJSON_CLANG_VISUAL_STUDIO
#if SIMDJSON_CLANG_VISUAL_STUDIO
/**
* You are not supposed, normally, to include these
* headers directly. Instead you should either include intrin.h
@@ -13912,7 +13930,7 @@ namespace {
// Sadly, sanitizers are not smart enough to figure it out.
SIMDJSON_NO_SANITIZE_UNDEFINED
simdjson_inline int trailing_zeroes(uint64_t input_num) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
return (int)_tzcnt_u64(input_num);
#else // SIMDJSON_REGULAR_VISUAL_STUDIO
////////
@@ -13934,7 +13952,7 @@ simdjson_inline int leading_zeroes(uint64_t input_num) {
return int(_lzcnt_u64(input_num));
}
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
simdjson_inline unsigned __int64 count_ones(uint64_t input_num) {
// note: we do not support legacy 32-bit Windows
return __popcnt64(input_num);// Visual Studio wants two underscores
@@ -13947,7 +13965,7 @@ simdjson_inline long long int count_ones(uint64_t input_num) {
simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2,
uint64_t *result) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
return _addcarry_u64(0, value1, value2,
reinterpret_cast<unsigned __int64 *>(result));
#else
@@ -14436,7 +14454,7 @@ simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) {
return 0; // bad r
}
#ifdef SIMDJSON_IS_32BITS // _umul128 for x86, arm
#if SIMDJSON_IS_32BITS // _umul128 for x86, arm
// this is a slow emulation routine for 32-bit
//
static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) {
@@ -14458,7 +14476,7 @@ using internal::value128;
simdjson_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
value128 answer;
#if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
#ifdef _M_ARM64
// ARM64 has native support for 64-bit multiplications, no need to emultate
answer.high = __umulh(value1, value2);
@@ -14466,7 +14484,7 @@ simdjson_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
#else
answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64
#endif // _M_ARM64
#else // defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
__uint128_t r = (static_cast<__uint128_t>(value1)) * value2;
answer.low = uint64_t(r);
answer.high = uint64_t(r >> 64);
@@ -15951,14 +15969,14 @@ public:
#define SIMDJSON_HASWELL_INTRINSICS_H
#ifdef SIMDJSON_VISUAL_STUDIO
#if SIMDJSON_VISUAL_STUDIO
// under clang within visual studio, this will include <x86intrin.h>
#include <intrin.h> // visual studio or clang
#else
#include <x86intrin.h> // elsewhere
#endif // SIMDJSON_VISUAL_STUDIO
#ifdef SIMDJSON_CLANG_VISUAL_STUDIO
#if SIMDJSON_CLANG_VISUAL_STUDIO
/**
* You are not supposed, normally, to include these
* headers directly. Instead you should either include intrin.h
@@ -16102,7 +16120,7 @@ namespace {
// Sadly, sanitizers are not smart enough to figure it out.
SIMDJSON_NO_SANITIZE_UNDEFINED
simdjson_inline int trailing_zeroes(uint64_t input_num) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
return (int)_tzcnt_u64(input_num);
#else // SIMDJSON_REGULAR_VISUAL_STUDIO
////////
@@ -16124,7 +16142,7 @@ simdjson_inline int leading_zeroes(uint64_t input_num) {
return int(_lzcnt_u64(input_num));
}
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
simdjson_inline unsigned __int64 count_ones(uint64_t input_num) {
// note: we do not support legacy 32-bit Windows
return __popcnt64(input_num);// Visual Studio wants two underscores
@@ -16137,7 +16155,7 @@ simdjson_inline long long int count_ones(uint64_t input_num) {
simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2,
uint64_t *result) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
return _addcarry_u64(0, value1, value2,
reinterpret_cast<unsigned __int64 *>(result));
#else
@@ -16620,7 +16638,7 @@ simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) {
return 0; // bad r
}
#ifdef SIMDJSON_IS_32BITS // _umul128 for x86, arm
#if SIMDJSON_IS_32BITS // _umul128 for x86, arm
// this is a slow emulation routine for 32-bit
//
static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) {
@@ -16642,7 +16660,7 @@ using internal::value128;
simdjson_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
value128 answer;
#if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
#ifdef _M_ARM64
// ARM64 has native support for 64-bit multiplications, no need to emultate
answer.high = __umulh(value1, value2);
@@ -16650,7 +16668,7 @@ simdjson_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
#else
answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64
#endif // _M_ARM64
#else // defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
__uint128_t r = (static_cast<__uint128_t>(value1)) * value2;
answer.low = uint64_t(r);
answer.high = uint64_t(r >> 64);
@@ -18244,7 +18262,7 @@ namespace {
// Sadly, sanitizers are not smart enough to figure it out.
SIMDJSON_NO_SANITIZE_UNDEFINED
simdjson_inline int trailing_zeroes(uint64_t input_num) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
unsigned long ret;
// Search the mask data from least significant bit (LSB)
// to the most significant bit (MSB) for a set bit (1).
@@ -18262,7 +18280,7 @@ simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) {
/* result might be undefined when input_num is zero */
simdjson_inline int leading_zeroes(uint64_t input_num) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
unsigned long leading_zero = 0;
// Search the mask data from most significant bit (MSB)
// to least significant bit (LSB) for a set bit (1).
@@ -18275,7 +18293,7 @@ simdjson_inline int leading_zeroes(uint64_t input_num) {
#endif // SIMDJSON_REGULAR_VISUAL_STUDIO
}
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
simdjson_inline int count_ones(uint64_t input_num) {
// note: we do not support legacy 32-bit Windows
return __popcnt64(input_num); // Visual Studio wants two underscores
@@ -18288,7 +18306,7 @@ simdjson_inline int count_ones(uint64_t input_num) {
simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2,
uint64_t *result) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
*result = value1 + value2;
return *result < value1;
#else
@@ -18891,7 +18909,7 @@ simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) {
return 0; // bad r
}
#ifdef SIMDJSON_IS_32BITS // _umul128 for x86, arm
#if SIMDJSON_IS_32BITS // _umul128 for x86, arm
// this is a slow emulation routine for 32-bit
//
static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) {
@@ -18913,7 +18931,7 @@ using internal::value128;
simdjson_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
value128 answer;
#if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
#ifdef _M_ARM64
// ARM64 has native support for 64-bit multiplications, no need to emultate
answer.high = __umulh(value1, value2);
@@ -18921,7 +18939,7 @@ simdjson_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
#else
answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64
#endif // _M_ARM64
#else // defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
__uint128_t r = (static_cast<__uint128_t>(value1)) * value2;
answer.low = uint64_t(r);
answer.high = uint64_t(r >> 64);
@@ -20427,7 +20445,7 @@ public:
#ifndef SIMDJSON_WESTMERE_INTRINSICS_H
#define SIMDJSON_WESTMERE_INTRINSICS_H
#ifdef SIMDJSON_VISUAL_STUDIO
#if SIMDJSON_VISUAL_STUDIO
// under clang within visual studio, this will include <x86intrin.h>
#include <intrin.h> // visual studio or clang
#else
@@ -20435,7 +20453,7 @@ public:
#endif // SIMDJSON_VISUAL_STUDIO
#ifdef SIMDJSON_CLANG_VISUAL_STUDIO
#if SIMDJSON_CLANG_VISUAL_STUDIO
/**
* You are not supposed, normally, to include these
* headers directly. Instead you should either include intrin.h
@@ -20557,7 +20575,7 @@ namespace {
// Sadly, sanitizers are not smart enough to figure it out.
SIMDJSON_NO_SANITIZE_UNDEFINED
simdjson_inline int trailing_zeroes(uint64_t input_num) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
unsigned long ret;
// Search the mask data from least significant bit (LSB)
// to the most significant bit (MSB) for a set bit (1).
@@ -20575,7 +20593,7 @@ simdjson_inline uint64_t clear_lowest_bit(uint64_t input_num) {
/* result might be undefined when input_num is zero */
simdjson_inline int leading_zeroes(uint64_t input_num) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
unsigned long leading_zero = 0;
// Search the mask data from most significant bit (MSB)
// to least significant bit (LSB) for a set bit (1).
@@ -20588,7 +20606,7 @@ simdjson_inline int leading_zeroes(uint64_t input_num) {
#endif// SIMDJSON_REGULAR_VISUAL_STUDIO
}
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
simdjson_inline unsigned __int64 count_ones(uint64_t input_num) {
// note: we do not support legacy 32-bit Windows
return __popcnt64(input_num);// Visual Studio wants two underscores
@@ -20601,7 +20619,7 @@ simdjson_inline long long int count_ones(uint64_t input_num) {
simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2,
uint64_t *result) {
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO
#if SIMDJSON_REGULAR_VISUAL_STUDIO
return _addcarry_u64(0, value1, value2,
reinterpret_cast<unsigned __int64 *>(result));
#else
@@ -21055,7 +21073,7 @@ simdjson_inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) {
return 0; // bad r
}
#ifdef SIMDJSON_IS_32BITS // _umul128 for x86, arm
#if SIMDJSON_IS_32BITS // _umul128 for x86, arm
// this is a slow emulation routine for 32-bit
//
static simdjson_inline uint64_t __emulu(uint32_t x, uint32_t y) {
@@ -21077,7 +21095,7 @@ using internal::value128;
simdjson_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
value128 answer;
#if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#if SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
#ifdef _M_ARM64
// ARM64 has native support for 64-bit multiplications, no need to emultate
answer.high = __umulh(value1, value2);
@@ -21085,7 +21103,7 @@ simdjson_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
#else
answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64
#endif // _M_ARM64
#else // defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#else // SIMDJSON_REGULAR_VISUAL_STUDIO || SIMDJSON_IS_32BITS
__uint128_t r = (static_cast<__uint128_t>(value1)) * value2;
answer.low = uint64_t(r);
answer.high = uint64_t(r >> 64);
@@ -23836,20 +23854,20 @@ public:
simdjson_warn_unused simdjson_inline simdjson_result<number_type> get_number_type() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<number> get_number() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> get_root_string() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<raw_json_string> get_root_raw_json_string() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> get_root_uint64() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> get_root_uint64_in_string() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<int64_t> get_root_int64() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<int64_t> get_root_int64_in_string() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<double> get_root_double() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<double> get_root_double_in_string() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<bool> get_root_bool() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> get_root_string(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<raw_json_string> get_root_raw_json_string(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> get_root_uint64(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> get_root_uint64_in_string(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<int64_t> get_root_int64(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<int64_t> get_root_int64_in_string(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<double> get_root_double(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<double> get_root_double_in_string(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<bool> get_root_bool(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline bool is_root_negative() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<bool> is_root_integer() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<number_type> get_root_number_type() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<number> get_root_number() noexcept;
simdjson_inline bool is_root_null() noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<bool> is_root_integer(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<number_type> get_root_number_type(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<number> get_root_number(bool check_trailing) noexcept;
simdjson_warn_unused simdjson_inline simdjson_result<bool> is_root_null(bool check_trailing) noexcept;
simdjson_inline error_code error() const noexcept;
simdjson_inline uint8_t *&string_buf_loc() noexcept;
@@ -24943,6 +24961,7 @@ protected:
friend class field;
friend class token;
friend class document_stream;
friend class document_reference;
};
@@ -24959,8 +24978,11 @@ public:
simdjson_inline simdjson_result<array> get_array() & noexcept;
simdjson_inline simdjson_result<object> get_object() & noexcept;
simdjson_inline simdjson_result<uint64_t> get_uint64() noexcept;
simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string() noexcept;
simdjson_inline simdjson_result<raw_json_string> get_raw_json_string() noexcept;
simdjson_inline simdjson_result<bool> get_bool() noexcept;
@@ -25024,9 +25046,11 @@ public:
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::array> get_array() & noexcept;
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::object> get_object() & noexcept;
simdjson_inline simdjson_result<uint64_t> get_uint64() noexcept;
simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_from_string() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string() noexcept;
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
simdjson_inline simdjson_result<bool> get_bool() noexcept;
@@ -25092,8 +25116,11 @@ public:
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::array> get_array() & noexcept;
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::object> get_object() & noexcept;
simdjson_inline simdjson_result<uint64_t> get_uint64() noexcept;
simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string() noexcept;
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
simdjson_inline simdjson_result<bool> get_bool() noexcept;
@@ -27217,9 +27244,15 @@ inline void log_line(const json_iterator &iter, token_position index, depth_t de
{
// Print the current structural.
printf("| ");
auto current_structural = &buf[*index];
for (int i=0;i<LOG_BUFFER_LEN;i++) {
printf("%c", printable_char(current_structural[i]));
// Before we begin, the index might point right before the document.
// This could be unsafe, see https://github.com/simdjson/simdjson/discussions/1938
if(index < iter._root) {
printf("%*s", LOG_BUFFER_LEN, "");
} else {
auto current_structural = &buf[*index];
for (int i=0;i<LOG_BUFFER_LEN;i++) {
printf("%c", printable_char(current_structural[i]));
}
}
printf(" ");
}
@@ -27234,7 +27267,7 @@ inline void log_line(const json_iterator &iter, token_position index, depth_t de
}
// printf("| %5u ", *(index+1));
printf("| %5i ", depth);
printf("| %.*s ", int(detail.size()), detail.data());
printf("| %6.*s ", int(detail.size()) , detail.data());
printf("|\n");
fflush(stdout);
}
@@ -28445,7 +28478,7 @@ simdjson_inline simdjson_result<number> value_iterator::get_number() noexcept {
return num;
}
simdjson_inline simdjson_result<bool> value_iterator::is_root_integer() noexcept {
simdjson_inline simdjson_result<bool> value_iterator::is_root_integer(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("is_root_integer");
uint8_t tmpbuf[20+1]; // <20 digits> is the longest possible unsigned integer
@@ -28456,12 +28489,11 @@ simdjson_inline simdjson_result<bool> value_iterator::is_root_integer() noexcept
// If the parsing was a success, we must still check that it is
// a single scalar. Note that we parse first because of cases like '[]' where
// getting TRAILING_CONTENT is wrong.
if((answer.error() == SUCCESS) && (!_json_iter->is_single_token())) { return TRAILING_CONTENT; }
if(check_trailing && (answer.error() == SUCCESS) && (!_json_iter->is_single_token())) { return TRAILING_CONTENT; }
return answer;
}
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::number_type> value_iterator::get_root_number_type() noexcept {
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::number_type> value_iterator::get_root_number_type(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("number");
// Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/,
@@ -28472,14 +28504,11 @@ simdjson_inline simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::numbe
logger::log_error(*_json_iter, start_position(), depth(), "Root number more than 1082 characters");
return NUMBER_ERROR;
}
// If the parsing was a success, we must still check that it is
// a single scalar. Note that we parse first because of cases like '[]' where
// getting TRAILING_CONTENT is wrong.
auto answer = numberparsing::get_number_type(tmpbuf);
if((answer.error() == SUCCESS) && (!_json_iter->is_single_token())) { return TRAILING_CONTENT; }
if (check_trailing && (answer.error() == SUCCESS) && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
return answer;
}
simdjson_inline simdjson_result<number> value_iterator::get_root_number() noexcept {
simdjson_inline simdjson_result<number> value_iterator::get_root_number(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("number");
// Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/,
@@ -28493,18 +28522,21 @@ simdjson_inline simdjson_result<number> value_iterator::get_root_number() noexce
number num;
error_code error = numberparsing::parse_number(tmpbuf, num);
if(error) { return error; }
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("number");
return num;
}
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> value_iterator::get_root_string() noexcept {
return get_string();
simdjson_warn_unused simdjson_inline simdjson_result<std::string_view> value_iterator::get_root_string(bool check_trailing) noexcept {
return get_root_raw_json_string(check_trailing).unescape(json_iter());
}
simdjson_warn_unused simdjson_inline simdjson_result<raw_json_string> value_iterator::get_root_raw_json_string() noexcept {
return get_raw_json_string();
simdjson_warn_unused simdjson_inline simdjson_result<raw_json_string> value_iterator::get_root_raw_json_string(bool check_trailing) noexcept {
auto json = peek_scalar("string");
if (*json != '"') { return incorrect_type_error("Not a string"); }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_scalar("string");
return raw_json_string(json+1);
}
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> value_iterator::get_root_uint64() noexcept {
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> value_iterator::get_root_uint64(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("uint64");
uint8_t tmpbuf[20+1]; // <20 digits> is the longest possible unsigned integer
@@ -28514,12 +28546,12 @@ simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> value_iterator::g
}
auto result = numberparsing::parse_unsigned(tmpbuf);
if(result.error() == SUCCESS) {
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("uint64");
}
return result;
}
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> value_iterator::get_root_uint64_in_string() noexcept {
simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> value_iterator::get_root_uint64_in_string(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("uint64");
uint8_t tmpbuf[20+1]; // <20 digits> is the longest possible unsigned integer
@@ -28529,12 +28561,12 @@ simdjson_warn_unused simdjson_inline simdjson_result<uint64_t> value_iterator::g
}
auto result = numberparsing::parse_unsigned_in_string(tmpbuf);
if(result.error() == SUCCESS) {
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("uint64");
}
return result;
}
simdjson_warn_unused simdjson_inline simdjson_result<int64_t> value_iterator::get_root_int64() noexcept {
simdjson_warn_unused simdjson_inline simdjson_result<int64_t> value_iterator::get_root_int64(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("int64");
uint8_t tmpbuf[20+1]; // -<19 digits> is the longest possible integer
@@ -28545,12 +28577,12 @@ simdjson_warn_unused simdjson_inline simdjson_result<int64_t> value_iterator::ge
auto result = numberparsing::parse_integer(tmpbuf);
if(result.error() == SUCCESS) {
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("int64");
}
return result;
}
simdjson_warn_unused simdjson_inline simdjson_result<int64_t> value_iterator::get_root_int64_in_string() noexcept {
simdjson_warn_unused simdjson_inline simdjson_result<int64_t> value_iterator::get_root_int64_in_string(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("int64");
uint8_t tmpbuf[20+1]; // -<19 digits> is the longest possible integer
@@ -28561,12 +28593,12 @@ simdjson_warn_unused simdjson_inline simdjson_result<int64_t> value_iterator::ge
auto result = numberparsing::parse_integer_in_string(tmpbuf);
if(result.error() == SUCCESS) {
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("int64");
}
return result;
}
simdjson_warn_unused simdjson_inline simdjson_result<double> value_iterator::get_root_double() noexcept {
simdjson_warn_unused simdjson_inline simdjson_result<double> value_iterator::get_root_double(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("double");
// Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/,
@@ -28579,13 +28611,13 @@ simdjson_warn_unused simdjson_inline simdjson_result<double> value_iterator::get
}
auto result = numberparsing::parse_double(tmpbuf);
if(result.error() == SUCCESS) {
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("double");
}
return result;
}
simdjson_warn_unused simdjson_inline simdjson_result<double> value_iterator::get_root_double_in_string() noexcept {
simdjson_warn_unused simdjson_inline simdjson_result<double> value_iterator::get_root_double_in_string(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("double");
// Per https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/,
@@ -28598,31 +28630,32 @@ simdjson_warn_unused simdjson_inline simdjson_result<double> value_iterator::get
}
auto result = numberparsing::parse_double_in_string(tmpbuf);
if(result.error() == SUCCESS) {
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("double");
}
return result;
}
simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::get_root_bool() noexcept {
simdjson_warn_unused simdjson_inline simdjson_result<bool> value_iterator::get_root_bool(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("bool");
uint8_t tmpbuf[5+1];
if (!_json_iter->copy_to_buffer(json, max_len, tmpbuf)) { return incorrect_type_error("Not a boolean"); }
auto result = parse_bool(tmpbuf);
if(result.error() == SUCCESS) {
if (!_json_iter->is_single_token()) { return TRAILING_CONTENT; }
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("bool");
}
return result;
}
simdjson_inline bool value_iterator::is_root_null() noexcept {
// If there is trailing content, then the document is not null.
if (!_json_iter->is_single_token()) { return false; }
simdjson_inline simdjson_result<bool> value_iterator::is_root_null(bool check_trailing) noexcept {
auto max_len = peek_start_length();
auto json = peek_root_scalar("null");
bool result = (max_len >= 4 && !atomparsing::str4ncmp(json, "null") &&
(max_len == 4 || jsoncharutils::is_structural_or_whitespace(json[5])));
if(result) { advance_root_scalar("null"); }
(max_len == 4 || jsoncharutils::is_structural_or_whitespace(json[4])));
if(result) { // we have something that looks like a null.
if (check_trailing && !_json_iter->is_single_token()) { return TRAILING_CONTENT; }
advance_root_scalar("null");
}
return result;
}
@@ -29382,35 +29415,44 @@ simdjson_inline simdjson_result<object> document::get_object() & noexcept {
auto value = get_root_value_iterator();
return object::start_root(value);
}
/**
* We decided that calling 'get_double()' on the JSON document '1.233 blabla' should
* give an error, so we check for trailing content. We want to disallow trailing
* content.
* Thus, in several implementations below, we pass a 'true' parameter value to
* a get_root_value_iterator() method: this indicates that we disallow trailing content.
*/
simdjson_inline simdjson_result<uint64_t> document::get_uint64() noexcept {
return get_root_value_iterator().get_root_uint64();
return get_root_value_iterator().get_root_uint64(true);
}
simdjson_inline simdjson_result<uint64_t> document::get_uint64_in_string() noexcept {
return get_root_value_iterator().get_root_uint64_in_string();
return get_root_value_iterator().get_root_uint64_in_string(true);
}
simdjson_inline simdjson_result<int64_t> document::get_int64() noexcept {
return get_root_value_iterator().get_root_int64();
return get_root_value_iterator().get_root_int64(true);
}
simdjson_inline simdjson_result<int64_t> document::get_int64_in_string() noexcept {
return get_root_value_iterator().get_root_int64_in_string();
return get_root_value_iterator().get_root_int64_in_string(true);
}
simdjson_inline simdjson_result<double> document::get_double() noexcept {
return get_root_value_iterator().get_root_double();
return get_root_value_iterator().get_root_double(true);
}
simdjson_inline simdjson_result<double> document::get_double_in_string() noexcept {
return get_root_value_iterator().get_root_double_in_string();
return get_root_value_iterator().get_root_double_in_string(true);
}
simdjson_inline simdjson_result<std::string_view> document::get_string() noexcept {
return get_root_value_iterator().get_root_string();
return get_root_value_iterator().get_root_string(true);
}
simdjson_inline simdjson_result<raw_json_string> document::get_raw_json_string() noexcept {
return get_root_value_iterator().get_root_raw_json_string();
return get_root_value_iterator().get_root_raw_json_string(true);
}
simdjson_inline simdjson_result<bool> document::get_bool() noexcept {
return get_root_value_iterator().get_root_bool();
return get_root_value_iterator().get_root_bool(true);
}
simdjson_inline simdjson_result<bool> document::is_null() noexcept {
return get_root_value_iterator().is_root_null();
return get_root_value_iterator().is_root_null(true);
}
template<> simdjson_inline simdjson_result<array> document::get() & noexcept { return get_array(); }
@@ -29528,15 +29570,15 @@ simdjson_inline bool document::is_negative() noexcept {
}
simdjson_inline simdjson_result<bool> document::is_integer() noexcept {
return get_root_value_iterator().is_root_integer();
return get_root_value_iterator().is_root_integer(true);
}
simdjson_inline simdjson_result<number_type> document::get_number_type() noexcept {
return get_root_value_iterator().get_root_number_type();
return get_root_value_iterator().get_root_number_type(true);
}
simdjson_inline simdjson_result<number> document::get_number() noexcept {
return get_root_value_iterator().get_root_number();
return get_root_value_iterator().get_root_number(true);
}
@@ -29645,14 +29687,26 @@ simdjson_inline simdjson_result<uint64_t> simdjson_result<SIMDJSON_BUILTIN_IMPLE
if (error()) { return error(); }
return first.get_uint64();
}
simdjson_inline simdjson_result<uint64_t> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document>::get_uint64_in_string() noexcept {
if (error()) { return error(); }
return first.get_uint64_in_string();
}
simdjson_inline simdjson_result<int64_t> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document>::get_int64() noexcept {
if (error()) { return error(); }
return first.get_int64();
}
simdjson_inline simdjson_result<int64_t> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document>::get_int64_in_string() noexcept {
if (error()) { return error(); }
return first.get_int64_in_string();
}
simdjson_inline simdjson_result<double> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document>::get_double() noexcept {
if (error()) { return error(); }
return first.get_double();
}
simdjson_inline simdjson_result<double> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document>::get_double_in_string() noexcept {
if (error()) { return error(); }
return first.get_double_in_string();
}
simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document>::get_string() noexcept {
if (error()) { return error(); }
return first.get_string();
@@ -29812,24 +29866,41 @@ simdjson_inline document_reference::document_reference(document &d) noexcept : d
simdjson_inline void document_reference::rewind() noexcept { doc->rewind(); }
simdjson_inline simdjson_result<array> document_reference::get_array() & noexcept { return doc->get_array(); }
simdjson_inline simdjson_result<object> document_reference::get_object() & noexcept { return doc->get_object(); }
simdjson_inline simdjson_result<uint64_t> document_reference::get_uint64() noexcept { return doc->get_uint64(); }
simdjson_inline simdjson_result<int64_t> document_reference::get_int64() noexcept { return doc->get_int64(); }
simdjson_inline simdjson_result<double> document_reference::get_double() noexcept { return doc->get_double(); }
simdjson_inline simdjson_result<std::string_view> document_reference::get_string() noexcept { return doc->get_string(); }
simdjson_inline simdjson_result<raw_json_string> document_reference::get_raw_json_string() noexcept { return doc->get_raw_json_string(); }
simdjson_inline simdjson_result<bool> document_reference::get_bool() noexcept { return doc->get_bool(); }
/**
* The document_reference instances are used primarily/solely for streams of JSON
* documents.
* We decided that calling 'get_double()' on the JSON document '1.233 blabla' should
* give an error, so we check for trailing content.
*
* However, for streams of JSON documents, we want to be able to start from
* "321" "321" "321"
* and parse it successfully as a stream of JSON documents, calling get_uint64_in_string()
* successfully each time.
*
* To achieve this result, we pass a 'false' to a get_root_value_iterator() method:
* this indicates that we allow trailing content.
*/
simdjson_inline simdjson_result<uint64_t> document_reference::get_uint64() noexcept { return doc->get_root_value_iterator().get_root_uint64(false); }
simdjson_inline simdjson_result<uint64_t> document_reference::get_uint64_in_string() noexcept { return doc->get_root_value_iterator().get_root_uint64_in_string(false); }
simdjson_inline simdjson_result<int64_t> document_reference::get_int64() noexcept { return doc->get_root_value_iterator().get_root_int64(false); }
simdjson_inline simdjson_result<int64_t> document_reference::get_int64_in_string() noexcept { return doc->get_root_value_iterator().get_root_int64_in_string(false); }
simdjson_inline simdjson_result<double> document_reference::get_double() noexcept { return doc->get_root_value_iterator().get_root_double(false); }
simdjson_inline simdjson_result<double> document_reference::get_double_in_string() noexcept { return doc->get_root_value_iterator().get_root_double(false); }
simdjson_inline simdjson_result<std::string_view> document_reference::get_string() noexcept { return doc->get_root_value_iterator().get_root_string(false); }
simdjson_inline simdjson_result<raw_json_string> document_reference::get_raw_json_string() noexcept { return doc->get_root_value_iterator().get_root_raw_json_string(false); }
simdjson_inline simdjson_result<bool> document_reference::get_bool() noexcept { return doc->get_root_value_iterator().get_root_bool(false); }
simdjson_inline simdjson_result<value> document_reference::get_value() noexcept { return doc->get_value(); }
simdjson_inline simdjson_result<bool> document_reference::is_null() noexcept { return doc->is_null(); }
simdjson_inline simdjson_result<bool> document_reference::is_null() noexcept { return doc->get_root_value_iterator().is_root_null(false); }
#if SIMDJSON_EXCEPTIONS
simdjson_inline document_reference::operator array() & noexcept(false) { return array(*doc); }
simdjson_inline document_reference::operator object() & noexcept(false) { return object(*doc); }
simdjson_inline document_reference::operator uint64_t() noexcept(false) { return uint64_t(*doc); }
simdjson_inline document_reference::operator int64_t() noexcept(false) { return int64_t(*doc); }
simdjson_inline document_reference::operator double() noexcept(false) { return double(*doc); }
simdjson_inline document_reference::operator uint64_t() noexcept(false) { return get_uint64(); }
simdjson_inline document_reference::operator int64_t() noexcept(false) { return get_int64(); }
simdjson_inline document_reference::operator double() noexcept(false) { return get_double(); }
simdjson_inline document_reference::operator std::string_view() noexcept(false) { return std::string_view(*doc); }
simdjson_inline document_reference::operator raw_json_string() noexcept(false) { return raw_json_string(*doc); }
simdjson_inline document_reference::operator bool() noexcept(false) { return bool(*doc); }
simdjson_inline document_reference::operator bool() noexcept(false) { return get_bool(); }
simdjson_inline document_reference::operator value() noexcept(false) { return value(*doc); }
#endif
simdjson_inline simdjson_result<size_t> document_reference::count_elements() & noexcept { return doc->count_elements(); }
@@ -29848,9 +29919,9 @@ simdjson_inline simdjson_result<bool> document_reference::is_scalar() noexcept {
simdjson_inline simdjson_result<const char *> document_reference::current_location() noexcept { return doc->current_location(); }
simdjson_inline int32_t document_reference::current_depth() const noexcept { return doc->current_depth(); }
simdjson_inline bool document_reference::is_negative() noexcept { return doc->is_negative(); }
simdjson_inline simdjson_result<bool> document_reference::is_integer() noexcept { return doc->is_integer(); }
simdjson_inline simdjson_result<number_type> document_reference::get_number_type() noexcept { return doc->get_number_type(); }
simdjson_inline simdjson_result<number> document_reference::get_number() noexcept { return doc->get_number(); }
simdjson_inline simdjson_result<bool> document_reference::is_integer() noexcept { return doc->get_root_value_iterator().is_root_integer(false); }
simdjson_inline simdjson_result<number_type> document_reference::get_number_type() noexcept { return doc->get_root_value_iterator().get_root_number_type(false); }
simdjson_inline simdjson_result<number> document_reference::get_number() noexcept { return doc->get_root_value_iterator().get_root_number(false); }
simdjson_inline simdjson_result<std::string_view> document_reference::raw_json_token() noexcept { return doc->raw_json_token(); }
simdjson_inline simdjson_result<value> document_reference::at_pointer(std::string_view json_pointer) noexcept { return doc->at_pointer(json_pointer); }
simdjson_inline simdjson_result<std::string_view> document_reference::raw_json() noexcept { return doc->raw_json();}
@@ -29927,14 +29998,26 @@ simdjson_inline simdjson_result<uint64_t> simdjson_result<SIMDJSON_BUILTIN_IMPLE
if (error()) { return error(); }
return first.get_uint64();
}
simdjson_inline simdjson_result<uint64_t> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document_reference>::get_uint64_in_string() noexcept {
if (error()) { return error(); }
return first.get_uint64_in_string();
}
simdjson_inline simdjson_result<int64_t> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document_reference>::get_int64() noexcept {
if (error()) { return error(); }
return first.get_int64();
}
simdjson_inline simdjson_result<int64_t> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document_reference>::get_int64_in_string() noexcept {
if (error()) { return error(); }
return first.get_int64_in_string();
}
simdjson_inline simdjson_result<double> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document_reference>::get_double() noexcept {
if (error()) { return error(); }
return first.get_double();
}
simdjson_inline simdjson_result<double> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document_reference>::get_double_in_string() noexcept {
if (error()) { return error(); }
return first.get_double_in_string();
}
simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_BUILTIN_IMPLEMENTATION::ondemand::document_reference>::get_string() noexcept {
if (error()) { return error(); }
return first.get_string();
-1
View File
@@ -1,5 +1,4 @@
#include "simdjson/fallback/begin.h"
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
+1 -1
View File
@@ -37,7 +37,7 @@ public:
// it helps tremendously.
if (bits == 0)
return;
#if defined(SIMDJSON_PREFER_REVERSE_BITS)
#if SIMDJSON_PREFER_REVERSE_BITS
/**
* ARM lacks a fast trailing zero instruction, but it has a fast
* bit reversal instruction and a fast leading zero instruction.
+1 -1
View File
@@ -3,7 +3,7 @@
#include <cstring>
int main(int argc, const char *argv[]) {
std::cout << "simdjson v" << SIMDJSON_STRINGIFY(SIMDJSON_VERSION) << " is running the " << simdjson::get_active_implementation()->name() << " implementation." << std::endl;
std::cout << "simdjson v" << SIMDJSON_VERSION << " is running the " << simdjson::get_active_implementation()->name() << " implementation." << std::endl;
const char *expected_implementation = nullptr;
if (argc > 1) {
expected_implementation = argv[1];
+3 -1
View File
@@ -21,7 +21,9 @@
*/
#if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined (__linux__) || defined (__APPLE__) || defined(__FreeBSD__)
// Finally, we want to exclude legacy 32-bit systems.
#ifndef SIMDJSON_IS_32BITS
#if SIMDJSON_IS_32BITS
// floating-point tests are omitted under 32-bit systems
#else
// So we only run some of the floating-point tests under 64-bit linux, apple, regular visual studio, freebsd.
#define TEST_FLOATS
#endif
+3 -1
View File
@@ -33,7 +33,9 @@ void found_unsigned_integer(uint64_t result, const uint8_t *buf);
// or cygwin.
//
// Finally, we want to exclude legacy 32-bit systems.
#ifndef SIMDJSON_IS_32BITS
#if SIMDJSON_IS_32BITS
// we omit 32-bit tests
#else
// So we only run some of the floating-point tests under 64-bit linux, apple, regular visual studio, freebsd.
#define TEST_FLOATS
// Apple and freebsd need a special header, typically.
+3 -1
View File
@@ -21,7 +21,9 @@
// or cygwin.
//
// Finally, we want to exclude legacy 32-bit systems.
#ifndef SIMDJSON_IS_32BITS
#if SIMDJSON_IS_32BITS
// we omit 32-bit tests
#else
// So we only run some of the floating-point tests under 64-bit linux, apple, regular visual studio, freebsd.
#define TEST_FLOATS
// Apple and freebsd need a special header, typically.
+1 -1
View File
@@ -267,7 +267,7 @@ void basics_ndjson_parse_many() {
}
}
void implementation_selection_1() {
cout << "simdjson v" << SIMDJSON_STRINGIFY(SIMDJSON_VERSION) << endl;
cout << "simdjson v" << SIMDJSON_VERSION << endl;
cout << "Detected the best implementation for your machine: " << simdjson::get_active_implementation()->name();
cout << "(" << simdjson::get_active_implementation()->description() << ")" << endl;
}
+1
View File
@@ -2,6 +2,7 @@
link_libraries(simdjson)
include_directories(..)
add_subdirectory(compilation_failure_tests)
add_cpp_test(ondemand_log_tests LABELS ondemand acceptance per_implementation)
add_cpp_test(ondemand_tostring_tests LABELS ondemand acceptance per_implementation)
add_cpp_test(ondemand_active_tests LABELS ondemand acceptance per_implementation)
add_cpp_test(ondemand_array_tests LABELS ondemand acceptance per_implementation)
@@ -714,8 +714,86 @@ namespace document_stream_tests {
return (bool_count == 0) && (total_count == 1);
}
bool string_with_trailing() {
TEST_START();
auto json = R"( "a string" badstuff )"_padded;
ondemand::parser parser;
ondemand::document_stream doc;
ASSERT_SUCCESS(parser.iterate_many(json).get(doc));
std::string_view view;
ASSERT_SUCCESS((*doc.begin()).get_string().get(view));
ASSERT_EQUAL(view,"a string");
TEST_SUCCEED();
}
bool uint64_with_trailing() {
TEST_START();
auto json = R"( 133 badstuff )"_padded;
ondemand::parser parser;
ondemand::document_stream doc;
ASSERT_SUCCESS(parser.iterate_many(json).get(doc));
uint64_t x;
ASSERT_SUCCESS((*doc.begin()).get_uint64().get(x));
ASSERT_EQUAL(x,133);
TEST_SUCCEED();
}
bool int64_with_trailing() {
TEST_START();
auto json = R"( 133 badstuff )"_padded;
ondemand::parser parser;
ondemand::document_stream doc;
ASSERT_SUCCESS(parser.iterate_many(json).get(doc));
int64_t x;
ASSERT_SUCCESS((*doc.begin()).get_int64().get(x));
ASSERT_EQUAL(x,133);
TEST_SUCCEED();
}
bool double_with_trailing() {
TEST_START();
auto json = R"( 133 badstuff )"_padded;
ondemand::parser parser;
ondemand::document_stream doc;
ASSERT_SUCCESS(parser.iterate_many(json).get(doc));
double x;
ASSERT_SUCCESS((*doc.begin()).get_double().get(x));
ASSERT_EQUAL(x,133);
TEST_SUCCEED();
}
bool bool_with_trailing() {
TEST_START();
auto json = R"( true badstuff )"_padded;
ondemand::parser parser;
ondemand::document_stream doc;
ASSERT_SUCCESS(parser.iterate_many(json).get(doc));
bool x;
ASSERT_SUCCESS((*doc.begin()).get_bool().get(x));
ASSERT_EQUAL(x,true);
TEST_SUCCEED();
}
bool null_with_trailing() {
TEST_START();
auto json = R"( null badstuff )"_padded;
ondemand::parser parser;
ondemand::document_stream doc;
ASSERT_SUCCESS(parser.iterate_many(json).get(doc));
bool n;
ASSERT_SUCCESS((*doc.begin()).is_null().get(n));
ASSERT_EQUAL(n,true);
TEST_SUCCEED();
}
bool run() {
return
string_with_trailing() &&
uint64_with_trailing() &&
int64_with_trailing() &&
bool_with_trailing() &&
null_with_trailing() &&
truncated_utf8() &&
issue1729() &&
fuzzaccess() &&
+30
View File
@@ -0,0 +1,30 @@
#define SIMDJSON_VERBOSE_LOGGING 1
#include "simdjson.h"
#include <iostream>
#include <vector>
#include <string>
using namespace simdjson;
int main() {
#if SIMDJSON_EXCEPTIONS
auto cars_json = R"( [
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
] )"_padded;
ondemand::parser parser;
ondemand::document doc = parser.iterate(cars_json);
std::vector<std::string> container;
for(ondemand::object o : doc) {
container.emplace_back(std::string_view(o["make"]));
}
std::cout << "---" << std::endl;
for(std::string& m : container) {
std::cout << m << std::endl;
}
#endif // #if SIMDJSON_EXCEPTIONS
return EXIT_SUCCESS;
}
+26
View File
@@ -52,6 +52,30 @@ namespace misc_tests {
TEST_SUCCEED();
}
bool issue_uffff() {
TEST_START();
ondemand::parser parser;
auto json = R"( "wow:\uFFFF" )"_padded;
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(json).get(doc));
std::string_view view;
ASSERT_SUCCESS( doc.get_string().get(view));
ASSERT_EQUAL(view, u8"wow:\uFFFF");
TEST_SUCCEED();
}
bool issue_backslash() {
TEST_START();
ondemand::parser parser;
auto json = R"( "sc:\\./" )"_padded;
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(json).get(doc));
std::string_view view;
ASSERT_SUCCESS( doc.get_string().get(view));
ASSERT_EQUAL(view, "sc:\\./");
TEST_SUCCEED();
}
bool issue1870() {
TEST_START();
ondemand::parser parser;
@@ -496,6 +520,8 @@ namespace misc_tests {
bool run() {
return
issue_uffff() &&
issue_backslash() &&
issue1870() &&
issue1894() &&
issue1894toolarge() &&
@@ -36,6 +36,93 @@ namespace number_in_string_tests {
}
)"_padded;
bool in_document_int64() {
TEST_START();
auto json = R"( "-11232321" )"_padded;
ondemand::parser parser;
auto doc = parser.iterate(json);
int64_t result;
ASSERT_SUCCESS(doc.get_int64_in_string().get(result));
ASSERT_EQUAL(result,-11232321);
TEST_SUCCEED();
}
bool in_document_uint64() {
TEST_START();
auto json = R"( "11232321" )"_padded;
ondemand::parser parser;
auto doc = parser.iterate(json);
uint64_t result;
ASSERT_SUCCESS(doc.get_uint64_in_string().get(result));
ASSERT_EQUAL(result,11232321);
TEST_SUCCEED();
}
bool in_document_double() {
TEST_START();
auto json = R"( "11232321.12" )"_padded;
ondemand::parser parser;
auto doc = parser.iterate(json);
double result;
ASSERT_SUCCESS(doc.get_double_in_string().get(result));
ASSERT_EQUAL(result,11232321.12);
TEST_SUCCEED();
}
bool stream_of_pure_int64() {
TEST_START();
auto json = R"( 1 2 3 )"_padded;
ondemand::parser parser;
ondemand::document_stream stream;
ASSERT_SUCCESS(parser.iterate_many(json).get(stream));
int document_index = 0;
for (auto doc : stream) {
document_index++;
int64_t result;
ASSERT_SUCCESS(doc.get_int64().get(result));
ASSERT_EQUAL(result,document_index);
}
ASSERT_EQUAL(3,document_index);
TEST_SUCCEED();
}
bool stream_of_direct_int64() {
TEST_START();
auto json = R"( "1" "2" "3" )"_padded;
ondemand::parser parser;
ondemand::document_stream stream;
ASSERT_SUCCESS(parser.iterate_many(json).get(stream));
int document_index = 0;
for (auto doc : stream) {
document_index++;
int64_t result;
ASSERT_SUCCESS(doc.get_int64_in_string().get(result));
ASSERT_EQUAL(result,document_index);
}
ASSERT_EQUAL(3,document_index);
TEST_SUCCEED();
}
bool stream_of_int64() {
TEST_START();
auto json = R"( ["1"] ["2"] ["3"] )"_padded;
ondemand::parser parser;
ondemand::document_stream stream;
ASSERT_SUCCESS(parser.iterate_many(json).get(stream));
int document_index = 0;
for (auto doc : stream) {
document_index++;
int64_t result;
ASSERT_SUCCESS(doc.get_array().at(0).get_int64_in_string().get(result));
ASSERT_EQUAL(result,document_index);
}
ASSERT_EQUAL(3,document_index);
TEST_SUCCEED();
}
bool array_double() {
TEST_START();
auto json = R"(["1.2","2.3","-42.3","2.43442e3", "-1.234e3"])"_padded;
@@ -255,7 +342,13 @@ namespace number_in_string_tests {
}
bool run() {
return array_double() &&
return stream_of_pure_int64() &&
stream_of_direct_int64() &&
stream_of_int64() &&
in_document_int64() &&
in_document_uint64() &&
in_document_double() &&
array_double() &&
array_int() &&
array_unsigned() &&
object() &&
+84
View File
@@ -297,8 +297,92 @@ namespace scalar_tests {
#endif // SIMDJSON_EXCEPTIONS
bool string_with_trailing() {
TEST_START();
auto json = R"( "a string" badstuff )"_padded;
ondemand::parser parser;
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(json).get(doc));
std::string_view view;
ASSERT_ERROR(doc.get_string().get(view), TRAILING_CONTENT);
TEST_SUCCEED();
}
bool uint64_with_trailing() {
TEST_START();
auto json = R"( 133 badstuff )"_padded;
ondemand::parser parser;
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(json).get(doc));
uint64_t x;
ASSERT_ERROR(doc.get_uint64().get(x), TRAILING_CONTENT);
TEST_SUCCEED();
}
bool int64_with_trailing() {
TEST_START();
auto json = R"( 133 badstuff )"_padded;
ondemand::parser parser;
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(json).get(doc));
int64_t x;
ASSERT_ERROR(doc.get_int64().get(x), TRAILING_CONTENT);
TEST_SUCCEED();
}
bool double_with_trailing() {
TEST_START();
auto json = R"( 133 badstuff )"_padded;
ondemand::parser parser;
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(json).get(doc));
double x;
ASSERT_ERROR(doc.get_double().get(x), TRAILING_CONTENT);
TEST_SUCCEED();
}
bool bool_with_trailing() {
TEST_START();
auto json = R"( true badstuff )"_padded;
ondemand::parser parser;
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(json).get(doc));
bool x;
ASSERT_ERROR(doc.get_bool().get(x), TRAILING_CONTENT);
TEST_SUCCEED();
}
bool null_with_trailing() {
TEST_START();
auto json = R"( null badstuff )"_padded;
ondemand::parser parser;
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(json).get(doc));
ASSERT_ERROR(doc.is_null(), TRAILING_CONTENT);
TEST_SUCCEED();
}
bool nully() {
TEST_START();
auto json = R"( nully )"_padded;
ondemand::parser parser;
ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(json).get(doc));
bool x;
ASSERT_SUCCESS(doc.is_null().get(x));
ASSERT_TRUE(!x);
TEST_SUCCEED();
}
bool run() {
return
nully() &&
string_with_trailing() &&
uint64_with_trailing() &&
int64_with_trailing() &&
bool_with_trailing() &&
null_with_trailing() &&
string_value() &&
numeric_values() &&
boolean_values() &&
+1 -1
View File
@@ -20,7 +20,7 @@ int main(int argc, const char *argv[]) {
std::string progName = "json2json";
std::string progUsage = "json2json version ";
progUsage += SIMDJSON_STRINGIFY(SIMDJSON_VERSION);
progUsage += SIMDJSON_VERSION;
progUsage += " (";
progUsage += simdjson::get_active_implementation()->name();
progUsage += ")\n";