mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 88bf5cb6d9 | |||
| 9b0435d864 | |||
| ddecadde86 | |||
| 02bee7d1b9 | |||
| 6ef555e6fb | |||
| 6952f8dfce | |||
| 03d0a4731a | |||
| 185ff4e8fe | |||
| 5bf6d9f3f0 | |||
| 2fa729922e | |||
| ebd09cb2a3 | |||
| 3978b9f159 | |||
| edc36a87ab | |||
| 6060be2fdf | |||
| 3251f61c9d | |||
| 561ffcd519 |
@@ -9,7 +9,7 @@ jobs:
|
||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
image: debian:testing
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Doxygen
|
||||
run: sudo apt-get install doxygen graphviz -y
|
||||
- run: mkdir docs
|
||||
|
||||
@@ -6,7 +6,7 @@ jobs:
|
||||
whitespace:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Remove whitespace and check the diff
|
||||
run: |
|
||||
set -eu
|
||||
|
||||
@@ -38,7 +38,7 @@ jobs:
|
||||
chmod +x llvm.sh
|
||||
sudo ./llvm.sh $CLANGVERSION
|
||||
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
CMAKE_GENERATOR: Ninja
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
CMAKE_GENERATOR: Ninja
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
name: Build on ubuntu-20.04 ppc64le
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: uraimo/run-on-arch-action@v2.0.5
|
||||
name: Run commands
|
||||
id: runcmd
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: uraimo/run-on-arch-action@v2
|
||||
name: Test
|
||||
id: runcmd
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: uraimo/run-on-arch-action@v2
|
||||
name: Test
|
||||
id: runcmd
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: uraimo/run-on-arch-action@v2
|
||||
name: Test
|
||||
id: runcmd
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
CXX: g++-8
|
||||
CC: gcc-8
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
@@ -27,7 +27,7 @@ jobs:
|
||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
|
||||
@@ -9,13 +9,11 @@ jobs:
|
||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
key: ${{ hashFiles('dependencies/CMakeLists.txt') }}
|
||||
- name: Install gcc12
|
||||
run: sudo apt-get install -y g++-12
|
||||
- name: Use cmake
|
||||
run: |
|
||||
mkdir build &&
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
name: Ubuntu 22.04 CI (GCC 13)
|
||||
|
||||
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@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
key: ${{ hashFiles('dependencies/CMakeLists.txt') }}
|
||||
- name: Use cmake
|
||||
run: |
|
||||
mkdir build &&
|
||||
cd build &&
|
||||
CXX=g++-13 cmake -DSIMDJSON_DEVELOPER_MODE=ON .. &&
|
||||
cmake --build . &&
|
||||
ctest --output-on-failure -LE explicitonly -j
|
||||
@@ -8,7 +8,7 @@ jobs:
|
||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
- {arch: ARM64}
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Use cmake
|
||||
run: |
|
||||
cmake -A ${{ matrix.arch }} -DCMAKE_CROSSCOMPILING=1 -DSIMDJSON_DEVELOPER_MODE=ON -D SIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_EXCEPTIONS=OFF -B build &&
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
- {gen: Visual Studio 17 2022, arch: x64, shared: OFF}
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake -DSIMDJSON_CXX_STANDARD=20 -G "${{matrix.gen}}" -A ${{matrix.arch}} -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -DBUILD_SHARED_LIBS=${{matrix.shared}} -B build
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
- {gen: Visual Studio 17 2022, arch: x64, shared: OFF}
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake -G "${{matrix.gen}}" -A ${{matrix.arch}} -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -DBUILD_SHARED_LIBS=${{matrix.shared}} -B build
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
- {gen: Visual Studio 17 2022, arch: x64}
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake -G "${{matrix.gen}}" -A ${{matrix.arch}} -T ClangCL -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -B build
|
||||
|
||||
@@ -7,7 +7,7 @@ jobs:
|
||||
name: windows-vs17
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: dependencies/.cache
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14)
|
||||
project(
|
||||
simdjson
|
||||
# The version number is modified by tools/release.py
|
||||
VERSION 3.6.2
|
||||
VERSION 3.6.4
|
||||
DESCRIPTION "Parsing gigabytes of JSON per second"
|
||||
HOMEPAGE_URL "https://simdjson.org/"
|
||||
LANGUAGES CXX C
|
||||
|
||||
@@ -38,7 +38,7 @@ PROJECT_NAME = simdjson
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = "3.6.2"
|
||||
PROJECT_NUMBER = "3.6.4"
|
||||
|
||||
# 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
|
||||
|
||||
@@ -29,6 +29,7 @@ Table of Contents
|
||||
* [Real-world usage](#real-world-usage)
|
||||
* [Quick Start](#quick-start)
|
||||
* [Documentation](#documentation)
|
||||
* [Godbolt](#godbolt)
|
||||
* [Performance results](#performance-results)
|
||||
* [Bindings and Ports of simdjson](#bindings-and-ports-of-simdjson)
|
||||
* [About simdjson](#about-simdjson)
|
||||
@@ -68,9 +69,9 @@ The simdjson library is easily consumable with a single .h and .cpp file.
|
||||
|
||||
0. Prerequisites: `g++` (version 7 or better) or `clang++` (version 6 or better), and a 64-bit
|
||||
system with a command-line shell (e.g., Linux, macOS, freeBSD). We also support programming
|
||||
environments like Visual Studio and Xcode, but different steps are needed.
|
||||
environments like Visual Studio and Xcode, but different steps are needed. Users of clang++ may need to specify the C++ version (e.g., `c++ -std=c++17`) since clang++ tends to default on C++98.
|
||||
1. Pull [simdjson.h](singleheader/simdjson.h) and [simdjson.cpp](singleheader/simdjson.cpp) into a
|
||||
directory, along with the sample file [twitter.json](jsonexamples/twitter.json).
|
||||
directory, along with the sample file [twitter.json](jsonexamples/twitter.json). You can download them with the `wget` utility:
|
||||
|
||||
```
|
||||
wget https://raw.githubusercontent.com/simdjson/simdjson/master/singleheader/simdjson.h https://raw.githubusercontent.com/simdjson/simdjson/master/singleheader/simdjson.cpp https://raw.githubusercontent.com/simdjson/simdjson/master/jsonexamples/twitter.json
|
||||
@@ -95,6 +96,7 @@ int main(void) {
|
||||
100 results.
|
||||
```
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
@@ -106,11 +108,12 @@ Usage documentation is available:
|
||||
how you can work with it.
|
||||
* [API](https://simdjson.github.io/simdjson/) contains the automatically generated API documentation.
|
||||
|
||||
Godbolt
|
||||
-------------
|
||||
|
||||
Some users may want to browse code along with the compiled assembly. You want to check out the following lists of examples:
|
||||
|
||||
* [simdjson examples with errors handled through exceptions](https://godbolt.org/z/98Kx9Kqjn)
|
||||
* [simdjson examples with errors without exceptions](https://godbolt.org/z/PKG7GdbPo)
|
||||
* [simdjson examples with errors handled through exceptions](https://godbolt.org/z/7G5qE4sr9)
|
||||
* [simdjson examples with errors without exceptions](https://godbolt.org/z/e9dWb9E4v)
|
||||
|
||||
Performance results
|
||||
-------------------
|
||||
@@ -174,7 +177,11 @@ The simdjson library takes advantage of modern microarchitectures, parallelizing
|
||||
instructions, reducing branch misprediction, and reducing data dependency to take advantage of each
|
||||
CPU's multiple execution cores.
|
||||
|
||||
Some people [enjoy reading our paper](https://arxiv.org/abs/1902.08318): A description of the design
|
||||
Our default front-end is called On Demand, and we wrote a paper about it:
|
||||
|
||||
- John Keiser, Daniel Lemire, [On-Demand JSON: A Better Way to Parse Documents?](http://arxiv.org/abs/2312.17149), Software: Practice and Experience (to appear)
|
||||
|
||||
Some people [enjoy reading the first (2019) simdjson paper](https://arxiv.org/abs/1902.08318): A description of the design
|
||||
and implementation of simdjson is in our research article:
|
||||
- Geoff Langdale, Daniel Lemire, [Parsing Gigabytes of JSON per Second](https://arxiv.org/abs/1902.08318), VLDB Journal 28 (6), 2019.
|
||||
|
||||
|
||||
@@ -26,6 +26,9 @@ if (TARGET benchmark::benchmark)
|
||||
if(TARGET nlohmann_json)
|
||||
target_link_libraries(bench_ondemand PRIVATE nlohmann_json)
|
||||
endif()
|
||||
if(TARGET boostjson)
|
||||
target_link_libraries(bench_ondemand PRIVATE boostjson)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
@@ -21,6 +21,10 @@ SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
|
||||
#include <nlohmann/json.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef SIMDJSON_COMPETITION_BOOSTJSON
|
||||
#include <boost/json.hpp>
|
||||
#endif
|
||||
|
||||
// This has to be last, for reasons I don't yet understand
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
@@ -33,6 +37,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
|
||||
#include "json2msgpack/sajson.h"
|
||||
#endif // SIMDJSON_COMPETITION_ONDEMAND_SAJSON
|
||||
#include "json2msgpack/nlohmann_json.h"
|
||||
#include "json2msgpack/boostjson.h"
|
||||
|
||||
#include "partial_tweets/simdjson_ondemand.h"
|
||||
#include "partial_tweets/simdjson_dom.h"
|
||||
@@ -48,6 +53,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
|
||||
#if SIMDJSON_COMPETITION_SAX
|
||||
#include "partial_tweets/nlohmann_json_sax.h"
|
||||
#endif // SIMDJSON_COMPETITION_SAX
|
||||
#include "partial_tweets/boostjson.h"
|
||||
|
||||
|
||||
#include "distinct_user_id/simdjson_ondemand.h"
|
||||
@@ -66,6 +72,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
|
||||
#if SIMDJSON_COMPETITION_SAX
|
||||
#include "distinct_user_id/nlohmann_json_sax.h"
|
||||
#endif // SIMDJSON_COMPETITION_SAX
|
||||
#include "distinct_user_id/boostjson.h"
|
||||
|
||||
#include "find_tweet/simdjson_ondemand.h"
|
||||
#include "find_tweet/simdjson_dom.h"
|
||||
@@ -81,6 +88,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
|
||||
#if SIMDJSON_COMPETITION_SAX
|
||||
#include "find_tweet/nlohmann_json_sax.h"
|
||||
#endif // SIMDJSON_COMPETITION_SAX
|
||||
#include "find_tweet/boostjson.h"
|
||||
|
||||
#include "top_tweet/simdjson_ondemand.h"
|
||||
#include "top_tweet/simdjson_dom.h"
|
||||
@@ -96,6 +104,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
|
||||
#if SIMDJSON_COMPETITION_SAX
|
||||
#include "top_tweet/nlohmann_json_sax.h"
|
||||
#endif // SIMDJSON_COMPETITION_SAX
|
||||
#include "top_tweet/boostjson.h"
|
||||
|
||||
|
||||
#include "kostya/simdjson_ondemand.h"
|
||||
@@ -112,6 +121,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
|
||||
#if SIMDJSON_COMPETITION_SAX
|
||||
#include "kostya/nlohmann_json_sax.h"
|
||||
#endif // SIMDJSON_COMPETITION_SAX
|
||||
#include "kostya/boostjson.h"
|
||||
|
||||
#include "large_random/simdjson_ondemand.h"
|
||||
#if SIMDJSON_COMPETITION_ONDEMAND_UNORDERED
|
||||
@@ -130,6 +140,7 @@ SIMDJSON_POP_DISABLE_WARNINGS
|
||||
#if SIMDJSON_COMPETITION_SAX
|
||||
#include "large_random/nlohmann_json_sax.h"
|
||||
#endif // SIMDJSON_COMPETITION_SAX
|
||||
#include "large_random/boostjson.h"
|
||||
|
||||
#include "amazon_cellphones/simdjson_dom.h"
|
||||
#include "amazon_cellphones/simdjson_ondemand.h"
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SIMDJSON_COMPETITION_BOOSTJSON
|
||||
|
||||
#include "distinct_user_id.h"
|
||||
|
||||
namespace distinct_user_id {
|
||||
|
||||
struct boostjson {
|
||||
bool run(simdjson::padded_string &json, std::vector<uint64_t> &result) {
|
||||
|
||||
auto root = boost::json::parse(json);
|
||||
for (const auto &tweet : root.at("statuses").as_array()) {
|
||||
result.push_back(tweet.at("user").at("id").to_number<uint64_t>());
|
||||
|
||||
if (tweet.as_object().if_contains("retweeted_status")) {
|
||||
result.push_back(tweet.at("retweeted_status").at("user").at("id").to_number<uint64_t>());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
BENCHMARK_TEMPLATE(distinct_user_id, boostjson)->UseManualTime();
|
||||
|
||||
} // namespace distinct_user_id
|
||||
|
||||
#endif // SIMDJSON_COMPETITION_BOOSTJSON
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SIMDJSON_COMPETITION_BOOSTJSON
|
||||
|
||||
#include "find_tweet.h"
|
||||
|
||||
namespace find_tweet {
|
||||
|
||||
struct boostjson {
|
||||
using StringType=std::string;
|
||||
|
||||
bool run(simdjson::padded_string &json, uint64_t find_id, std::string &result) {
|
||||
|
||||
auto root = boost::json::parse(json);
|
||||
for (const auto &tweet : root.at("statuses").as_array()) {
|
||||
if (tweet.at("id") == find_id) {
|
||||
result = tweet.at("text").as_string();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
BENCHMARK_TEMPLATE(find_tweet, boostjson)->UseManualTime();
|
||||
|
||||
} // namespace find_tweet
|
||||
|
||||
#endif // SIMDJSON_COMPETITION_BOOSTJSON
|
||||
@@ -0,0 +1,104 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SIMDJSON_COMPETITION_BOOSTJSON
|
||||
|
||||
#include "json2msgpack.h"
|
||||
|
||||
namespace json2msgpack {
|
||||
|
||||
struct boostjson2msgpack {
|
||||
inline std::string_view to_msgpack(const boost::json::value &root, uint8_t *buf) {
|
||||
buff = buf;
|
||||
recursive_processor(root);
|
||||
return std::string_view(reinterpret_cast<char *>(buf), size_t(buff - buf));
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t *buff{};
|
||||
|
||||
inline void write_double(const double d) noexcept {
|
||||
*buff++ = 0xcb;
|
||||
::memcpy(buff, &d, sizeof(d));
|
||||
buff += sizeof(d);
|
||||
}
|
||||
|
||||
inline void write_byte(const uint8_t b) noexcept {
|
||||
*buff = b;
|
||||
buff++;
|
||||
}
|
||||
|
||||
inline void write_uint32(const uint32_t w) noexcept {
|
||||
::memcpy(buff, &w, sizeof(w));
|
||||
buff += sizeof(w);
|
||||
}
|
||||
|
||||
inline void write_string(const std::string & str) {
|
||||
write_byte(0xdb);
|
||||
write_uint32(uint32_t(str.size()));
|
||||
::memcpy(buff, str.data(), str.size());
|
||||
buff += str.size();
|
||||
}
|
||||
|
||||
inline void recursive_processor(const boost::json::value &element) {
|
||||
switch(element.kind()) {
|
||||
case boost::json::kind::array: {
|
||||
write_byte(0xdd);
|
||||
const auto &array = element.as_array();
|
||||
write_uint32(static_cast<uint32_t>(array.size()));
|
||||
for (const auto &child : array) {
|
||||
recursive_processor(child);
|
||||
}
|
||||
} break;
|
||||
|
||||
case boost::json::kind::object: {
|
||||
write_byte(0xdf);
|
||||
const auto &object = element.as_object();
|
||||
write_uint32(static_cast<uint32_t>(object.size()));
|
||||
for (const auto &child : object) {
|
||||
write_string(child.key_c_str());
|
||||
recursive_processor(child.value());
|
||||
}
|
||||
} break;
|
||||
|
||||
case boost::json::kind::int64:
|
||||
case boost::json::kind::uint64:
|
||||
case boost::json::kind::double_:
|
||||
write_double(element.to_number<double>());
|
||||
break;
|
||||
|
||||
case boost::json::kind::string:
|
||||
write_string(element.as_string().c_str());
|
||||
break;
|
||||
|
||||
case boost::json::kind::bool_:
|
||||
write_byte(0xc2 + element.as_bool());
|
||||
break;
|
||||
|
||||
case boost::json::kind::null:
|
||||
write_byte(0xc0);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("unexpected\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct boostjson {
|
||||
using StringType=std::string;
|
||||
|
||||
boostjson2msgpack parser{};
|
||||
|
||||
bool run(simdjson::padded_string &json, char *buffer, std::string_view &result) {
|
||||
auto root = boost::json::parse(json);
|
||||
result = parser.to_msgpack(root, reinterpret_cast<uint8_t *>(buffer));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
BENCHMARK_TEMPLATE(json2msgpack, boostjson)->UseManualTime();
|
||||
|
||||
} // namespace json2msgpack
|
||||
|
||||
#endif // SIMDJSON_COMPETITION_BOOSTJSON
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SIMDJSON_COMPETITION_BOOSTJSON
|
||||
|
||||
#include "kostya.h"
|
||||
|
||||
namespace kostya {
|
||||
|
||||
struct boostjson {
|
||||
static constexpr diff_flags DiffFlags = diff_flags::IMPRECISE_FLOATS;
|
||||
|
||||
bool run(simdjson::padded_string &json, std::vector<point> &result) {
|
||||
auto root = boost::json::parse(json);
|
||||
for (const auto &point : root.at("coordinates").as_array()) {
|
||||
result.emplace_back(json_benchmark::point{
|
||||
point.at("x").to_number<double>(),
|
||||
point.at("y").to_number<double>(),
|
||||
point.at("z").to_number<double>()
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
BENCHMARK_TEMPLATE(kostya, boostjson)->UseManualTime();
|
||||
|
||||
} // namespace kostya
|
||||
|
||||
#endif // SIMDJSON_COMPETITION_BOOSTJSON
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SIMDJSON_COMPETITION_BOOSTJSON
|
||||
|
||||
#include "large_random.h"
|
||||
|
||||
namespace large_random {
|
||||
|
||||
struct boostjson {
|
||||
static constexpr diff_flags DiffFlags = diff_flags::IMPRECISE_FLOATS;
|
||||
|
||||
bool run(simdjson::padded_string &json, std::vector<point> &result) {
|
||||
auto root = boost::json::parse(json);
|
||||
for (const auto &point : root.as_array()) {
|
||||
result.emplace_back(json_benchmark::point{
|
||||
point.at("x").to_number<double>(),
|
||||
point.at("y").to_number<double>(),
|
||||
point.at("z").to_number<double>()
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
BENCHMARK_TEMPLATE(large_random, boostjson)->UseManualTime();
|
||||
|
||||
} // namespace large_random
|
||||
|
||||
#endif // SIMDJSON_COMPETITION_BOOSTJSON
|
||||
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SIMDJSON_COMPETITION_BOOSTJSON
|
||||
|
||||
#include "partial_tweets.h"
|
||||
|
||||
namespace partial_tweets {
|
||||
|
||||
struct boostjson {
|
||||
using StringType=std::string;
|
||||
|
||||
bool run(simdjson::padded_string &json, std::vector<tweet<StringType>> &result) {
|
||||
|
||||
auto root = boost::json::parse(json);
|
||||
for (const auto &tweet : root.at("statuses").as_array()) {
|
||||
const auto &user = tweet.at("user");
|
||||
|
||||
auto in_reply_to_status_id = tweet.as_object().if_contains("in_reply_to_status_id")
|
||||
? tweet.at("in_reply_to_status_id") : boost::json::value();
|
||||
|
||||
result.emplace_back(partial_tweets::tweet<StringType>{
|
||||
tweet.at("created_at").as_string().c_str(),
|
||||
tweet.at("id").to_number<uint64_t>(),
|
||||
tweet.at("text").as_string().c_str(),
|
||||
in_reply_to_status_id.is_null() ? 0 : in_reply_to_status_id.to_number<uint64_t>(),
|
||||
{
|
||||
user.at("id").to_number<uint64_t>(),
|
||||
user.at("screen_name").as_string().c_str()
|
||||
},
|
||||
tweet.at("retweet_count").to_number<uint64_t>(),
|
||||
tweet.at("favorite_count").to_number<uint64_t>()
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
BENCHMARK_TEMPLATE(partial_tweets, boostjson)->UseManualTime();
|
||||
|
||||
} // namespace partial_tweets
|
||||
|
||||
#endif // SIMDJSON_COMPETITION_BOOSTJSON
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#if SIMDJSON_COMPETITION_BOOSTJSON
|
||||
|
||||
#include "top_tweet.h"
|
||||
|
||||
namespace top_tweet {
|
||||
|
||||
using namespace simdjson;
|
||||
|
||||
struct boostjson {
|
||||
using StringType=std::string;
|
||||
|
||||
bool run(simdjson::padded_string &json, int64_t max_retweet_count, top_tweet_result<StringType> &result) {
|
||||
result.retweet_count = -1;
|
||||
boost::json::value top_tweet{};
|
||||
|
||||
auto root = boost::json::parse(json);
|
||||
for (const auto &tweet : root.at("statuses").as_array()) {
|
||||
int64_t retweet_count = tweet.at("retweet_count").as_int64();
|
||||
if (retweet_count <= max_retweet_count && retweet_count >= result.retweet_count) {
|
||||
result.retweet_count = retweet_count;
|
||||
top_tweet = tweet;
|
||||
}
|
||||
}
|
||||
|
||||
result.text = top_tweet.at("text").as_string();
|
||||
result.screen_name = top_tweet.at("user").at("screen_name").as_string();
|
||||
return result.retweet_count != -1;
|
||||
}
|
||||
};
|
||||
|
||||
BENCHMARK_TEMPLATE(top_tweet, boostjson)->UseManualTime();
|
||||
|
||||
} // namespace top_tweet
|
||||
|
||||
#endif // SIMDJSON_COMPETITION_BOOSTJSON
|
||||
+9
-2
@@ -36,6 +36,7 @@ An overview of what you need to know to use simdjson, with examples.
|
||||
- [Backwards Compatibility](#backwards-compatibility)
|
||||
- [Examples](#examples)
|
||||
- [Performance Tips](#performance-tips)
|
||||
- [Further Reading](#further-reading)
|
||||
|
||||
|
||||
Requirements
|
||||
@@ -1656,8 +1657,8 @@ JSON string to a user-provided buffer:
|
||||
General Direct Access to the Raw JSON String
|
||||
--------------------------------
|
||||
If your value is a string, the `raw_json_string` you with `get_raw_json_string()` gives you direct access to the unprocessed
|
||||
string. The simdjson library allows you to have access to the raw underlying JSON
|
||||
more generally.
|
||||
string. But the simdjson library allows you to have access to the raw underlying JSON
|
||||
more generally, not just for strings.
|
||||
|
||||
The simdjson library makes explicit assumptions about types. For examples, numbers
|
||||
must be integers (up to 64-bit integers) or binary64 floating-point numbers. Some users
|
||||
@@ -2127,3 +2128,9 @@ Performance Tips
|
||||
std::string_view rating = data["rating"];
|
||||
```
|
||||
- To better understand the operation of your On Demand parser, and whether it is performing as well as you think it should be, there is a logger feature built in to simdjson! To use it, define the pre-processor directive `SIMDJSON_VERBOSE_LOGGING` prior to including the `simdjson.h` header, which enables logging in simdjson. Run your code. It may generate a lot of logging output; adding printouts from your application that show each section may be helpful. The log's output will show step-by-step information on state, buffer pointer position, depth, and key retrieval status. Importantly, unless `SIMDJSON_VERBOSE_LOGGING` is defined, logging is entirely disabled and thus carries no overhead.
|
||||
|
||||
Further reading
|
||||
--------
|
||||
|
||||
|
||||
- John Keiser, Daniel Lemire, [On-Demand JSON: A Better Way to Parse Documents?](http://arxiv.org/abs/2312.17149), Software: Practice and Experience (to appear)
|
||||
|
||||
@@ -214,7 +214,7 @@ public:
|
||||
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. "
|
||||
"The supported types are Boolean (bool), numbers (double, uint64_t, int64_t), "
|
||||
"strings (std::string_view, const char *), arrays (dom::array) and objects (dom::object). "
|
||||
"We recommand you use get_double(), get_bool(), get_uint64(), get_int64(), "
|
||||
"We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), "
|
||||
"get_object(), get_array() or get_string() instead of the get template.");
|
||||
}
|
||||
|
||||
|
||||
@@ -92,10 +92,14 @@ inline simdjson_result<size_t> parser::read_file(const std::string &path) noexce
|
||||
}
|
||||
|
||||
inline simdjson_result<element> parser::load(const std::string &path) & noexcept {
|
||||
return load_into_document(doc, path);
|
||||
}
|
||||
|
||||
inline simdjson_result<element> parser::load_into_document(document& provided_doc, const std::string &path) & noexcept {
|
||||
size_t len;
|
||||
auto _error = read_file(path).get(len);
|
||||
if (_error) { return _error; }
|
||||
return parse(loaded_bytes.get(), len, false);
|
||||
return parse_into_document(provided_doc, loaded_bytes.get(), len, false);
|
||||
}
|
||||
|
||||
inline simdjson_result<document_stream> parser::load_many(const std::string &path, size_t batch_size) noexcept {
|
||||
|
||||
@@ -95,6 +95,53 @@ public:
|
||||
*/
|
||||
inline simdjson_result<element> load(const std::string &path) & noexcept;
|
||||
inline simdjson_result<element> load(const std::string &path) && = delete ;
|
||||
|
||||
/**
|
||||
* Load a JSON document from a file into a provide document instance and return a temporary reference to it.
|
||||
* It is similar to the function `load` except that instead of parsing into the internal
|
||||
* `document` instance associated with the parser, it allows the user to provide a document
|
||||
* instance.
|
||||
*
|
||||
* dom::parser parser;
|
||||
* dom::document doc;
|
||||
* element doc_root = parser.load_into_document(doc, "jsonexamples/twitter.json");
|
||||
*
|
||||
* The function is eager: the file's content is loaded in memory inside the parser instance
|
||||
* and immediately parsed. The file can be deleted after the `parser.load_into_document` call.
|
||||
*
|
||||
* ### IMPORTANT: Document Lifetime
|
||||
*
|
||||
* After the call to load_into_document, the parser is no longer needed.
|
||||
*
|
||||
* The JSON document lives in the document instance: you must keep the document
|
||||
* instance alive while you navigate through it (i.e., used the returned value from
|
||||
* load_into_document). You are encourage to reuse the document instance
|
||||
* many times with new data to avoid reallocations:
|
||||
*
|
||||
* dom::document doc;
|
||||
* element doc_root1 = parser.load_into_document(doc, "jsonexamples/twitter.json");
|
||||
* //... doc_root1 is a pointer inside doc
|
||||
* element doc_root2 = parser.load_into_document(doc, "jsonexamples/twitter.json");
|
||||
* //... doc_root2 is a pointer inside doc
|
||||
* // at this point doc_root1 is no longer safe
|
||||
*
|
||||
* Moving the document instance is safe, but it invalidates the element instances. After
|
||||
* moving a document, you can recover safe access to the document root with its `root()` method.
|
||||
*
|
||||
* @param doc The document instance where the parsed data will be stored (on success).
|
||||
* @param path The path to load.
|
||||
* @return The document, or an error:
|
||||
* - IO_ERROR if there was an error opening or reading the file.
|
||||
* Be mindful that on some 32-bit systems,
|
||||
* the file size might be limited to 2 GB.
|
||||
* - MEMALLOC if the parser does not have enough capacity and memory allocation fails.
|
||||
* - CAPACITY if the parser does not have enough capacity and len > max_capacity.
|
||||
* - other json errors if parsing fails. You should not rely on these errors to always the same for the
|
||||
* same document: they may vary under runtime dispatch (so they may vary depending on your system and hardware).
|
||||
*/
|
||||
inline simdjson_result<element> load_into_document(document& doc, const std::string &path) & noexcept;
|
||||
inline simdjson_result<element> load_into_document(document& doc, const std::string &path) && =delete;
|
||||
|
||||
/**
|
||||
* Parse a JSON document and return a temporary reference to it.
|
||||
*
|
||||
|
||||
@@ -446,11 +446,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
||||
} // unnamed namespace
|
||||
|
||||
/** @private */
|
||||
template<typename W>
|
||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
||||
double d;
|
||||
if (parse_float_fallback(src, &d)) {
|
||||
writer.append_double(d);
|
||||
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||
if (parse_float_fallback(src, answer)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
return INVALID_NUMBER(src);
|
||||
@@ -474,13 +471,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
||||
// 10000000000000000000000000000000000000000000e+308
|
||||
// 3.1415926535897932384626433832795028841971693993751
|
||||
//
|
||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
||||
// This is what forces the skip_double, as well.
|
||||
error_code error = slow_float_parsing(src, writer);
|
||||
writer.skip_double();
|
||||
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||
// it gets slow.
|
||||
double d;
|
||||
error_code error = slow_float_parsing(src, &d);
|
||||
writer.append_double(d);
|
||||
return error;
|
||||
}
|
||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||
@@ -1004,7 +1001,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double(const uint8
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -1203,7 +1200,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(c
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
|
||||
@@ -92,8 +92,6 @@ protected:
|
||||
*/
|
||||
friend class value_iterator;
|
||||
template<typename W>
|
||||
friend error_code numberparsing::slow_float_parsing(simdjson_unused const uint8_t * src, W writer);
|
||||
template<typename W>
|
||||
friend error_code numberparsing::write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer);
|
||||
template<typename W>
|
||||
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#pragma once
|
||||
// #pragma once // We remove #pragma once here as it generates a warning in some cases. We rely on the include guard.
|
||||
|
||||
#ifndef NONSTD_SV_LITE_H_INCLUDED
|
||||
#define NONSTD_SV_LITE_H_INCLUDED
|
||||
@@ -69,6 +69,10 @@
|
||||
# define nssv_CONFIG_NO_STREAM_INSERTION 0
|
||||
#endif
|
||||
|
||||
#ifndef nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||
# define nssv_CONFIG_CONSTEXPR11_STD_SEARCH 1
|
||||
#endif
|
||||
|
||||
// Control presence of exception handling (try and auto discover):
|
||||
|
||||
#ifndef nssv_CONFIG_NO_EXCEPTIONS
|
||||
@@ -267,7 +271,7 @@ using std::operator<<;
|
||||
# define nssv_HAS_CPP0X 0
|
||||
#endif
|
||||
|
||||
// Unless defined otherwise below, consider VC14 as C++11 for variant-lite:
|
||||
// Unless defined otherwise below, consider VC14 as C++11 for string-view-lite:
|
||||
|
||||
#if nssv_COMPILER_MSVC_VER >= 1900
|
||||
# undef nssv_CPP11_OR_GREATER
|
||||
@@ -434,9 +438,9 @@ using std::operator<<;
|
||||
# pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wuser-defined-literals"
|
||||
#elif defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wliteral-suffix"
|
||||
#elif nssv_COMPILER_GNUC_VERSION >= 480
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wliteral-suffix"
|
||||
#endif // __clang__
|
||||
|
||||
#if nssv_COMPILER_MSVC_VERSION >= 140
|
||||
@@ -451,8 +455,8 @@ using std::operator<<;
|
||||
|
||||
#if defined(__clang__)
|
||||
# define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
|
||||
#elif defined(__GNUC__)
|
||||
# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
|
||||
#elif nssv_COMPILER_GNUC_VERSION >= 480
|
||||
# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
|
||||
#elif nssv_COMPILER_MSVC_VERSION >= 140
|
||||
# define nssv_RESTORE_WARNINGS() __pragma(warning(pop ))
|
||||
#else
|
||||
@@ -567,12 +571,31 @@ constexpr const CharT* search( basic_string_view<CharT, Traits> haystack, basic_
|
||||
|
||||
// non-recursive:
|
||||
|
||||
#if nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||
|
||||
template< class CharT, class Traits = std::char_traits<CharT> >
|
||||
constexpr const CharT* search( basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle )
|
||||
{
|
||||
return std::search( haystack.begin(), haystack.end(), needle.begin(), needle.end() );
|
||||
}
|
||||
|
||||
#else // nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||
|
||||
template< class CharT, class Traits = std::char_traits<CharT> >
|
||||
nssv_constexpr14 const CharT* search( basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle )
|
||||
{
|
||||
while ( needle.size() <= haystack.size() )
|
||||
{
|
||||
if ( haystack.starts_with(needle) )
|
||||
{
|
||||
return haystack.cbegin();
|
||||
}
|
||||
haystack = basic_string_view<CharT, Traits>{ haystack.begin() + 1, haystack.size() - 1U };
|
||||
}
|
||||
return haystack.cend();
|
||||
}
|
||||
#endif // nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||
|
||||
#endif // OPTIMIZE
|
||||
#endif // nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
|
||||
|
||||
@@ -845,7 +868,7 @@ public:
|
||||
|
||||
// find(), 4x:
|
||||
|
||||
nssv_constexpr size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
|
||||
nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
|
||||
{
|
||||
return assert( v.size() == 0 || v.data() != nssv_nullptr )
|
||||
, pos >= size()
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#define SIMDJSON_SIMDJSON_VERSION_H
|
||||
|
||||
/** The version of simdjson being used (major.minor.revision) */
|
||||
#define SIMDJSON_VERSION "3.6.2"
|
||||
#define SIMDJSON_VERSION "3.6.4"
|
||||
|
||||
namespace simdjson {
|
||||
enum {
|
||||
@@ -19,7 +19,7 @@ enum {
|
||||
/**
|
||||
* The revision (major.minor.REVISION) of simdjson being used.
|
||||
*/
|
||||
SIMDJSON_VERSION_REVISION = 2
|
||||
SIMDJSON_VERSION_REVISION = 4
|
||||
};
|
||||
} // namespace simdjson
|
||||
|
||||
|
||||
+128
-127
@@ -1,4 +1,4 @@
|
||||
/* auto-generated on 2023-12-01 13:55:28 -0500. Do not edit! */
|
||||
/* auto-generated on 2024-01-28 12:42:59 -0500. Do not edit! */
|
||||
/* including simdjson.cpp: */
|
||||
/* begin file simdjson.cpp */
|
||||
#define SIMDJSON_SRC_SIMDJSON_CPP
|
||||
@@ -525,7 +525,7 @@ SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#pragma once
|
||||
// #pragma once // We remove #pragma once here as it generates a warning in some cases. We rely on the include guard.
|
||||
|
||||
#ifndef NONSTD_SV_LITE_H_INCLUDED
|
||||
#define NONSTD_SV_LITE_H_INCLUDED
|
||||
@@ -588,6 +588,10 @@ SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
|
||||
# define nssv_CONFIG_NO_STREAM_INSERTION 0
|
||||
#endif
|
||||
|
||||
#ifndef nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||
# define nssv_CONFIG_CONSTEXPR11_STD_SEARCH 1
|
||||
#endif
|
||||
|
||||
// Control presence of exception handling (try and auto discover):
|
||||
|
||||
#ifndef nssv_CONFIG_NO_EXCEPTIONS
|
||||
@@ -786,7 +790,7 @@ using std::operator<<;
|
||||
# define nssv_HAS_CPP0X 0
|
||||
#endif
|
||||
|
||||
// Unless defined otherwise below, consider VC14 as C++11 for variant-lite:
|
||||
// Unless defined otherwise below, consider VC14 as C++11 for string-view-lite:
|
||||
|
||||
#if nssv_COMPILER_MSVC_VER >= 1900
|
||||
# undef nssv_CPP11_OR_GREATER
|
||||
@@ -953,9 +957,9 @@ using std::operator<<;
|
||||
# pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wuser-defined-literals"
|
||||
#elif defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wliteral-suffix"
|
||||
#elif nssv_COMPILER_GNUC_VERSION >= 480
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wliteral-suffix"
|
||||
#endif // __clang__
|
||||
|
||||
#if nssv_COMPILER_MSVC_VERSION >= 140
|
||||
@@ -970,8 +974,8 @@ using std::operator<<;
|
||||
|
||||
#if defined(__clang__)
|
||||
# define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
|
||||
#elif defined(__GNUC__)
|
||||
# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
|
||||
#elif nssv_COMPILER_GNUC_VERSION >= 480
|
||||
# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
|
||||
#elif nssv_COMPILER_MSVC_VERSION >= 140
|
||||
# define nssv_RESTORE_WARNINGS() __pragma(warning(pop ))
|
||||
#else
|
||||
@@ -1086,12 +1090,31 @@ constexpr const CharT* search( basic_string_view<CharT, Traits> haystack, basic_
|
||||
|
||||
// non-recursive:
|
||||
|
||||
#if nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||
|
||||
template< class CharT, class Traits = std::char_traits<CharT> >
|
||||
constexpr const CharT* search( basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle )
|
||||
{
|
||||
return std::search( haystack.begin(), haystack.end(), needle.begin(), needle.end() );
|
||||
}
|
||||
|
||||
#else // nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||
|
||||
template< class CharT, class Traits = std::char_traits<CharT> >
|
||||
nssv_constexpr14 const CharT* search( basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle )
|
||||
{
|
||||
while ( needle.size() <= haystack.size() )
|
||||
{
|
||||
if ( haystack.starts_with(needle) )
|
||||
{
|
||||
return haystack.cbegin();
|
||||
}
|
||||
haystack = basic_string_view<CharT, Traits>{ haystack.begin() + 1, haystack.size() - 1U };
|
||||
}
|
||||
return haystack.cend();
|
||||
}
|
||||
#endif // nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||
|
||||
#endif // OPTIMIZE
|
||||
#endif // nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
|
||||
|
||||
@@ -1364,7 +1387,7 @@ public:
|
||||
|
||||
// find(), 4x:
|
||||
|
||||
nssv_constexpr size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
|
||||
nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
|
||||
{
|
||||
return assert( v.size() == 0 || v.data() != nssv_nullptr )
|
||||
, pos >= size()
|
||||
@@ -9025,11 +9048,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
||||
} // unnamed namespace
|
||||
|
||||
/** @private */
|
||||
template<typename W>
|
||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
||||
double d;
|
||||
if (parse_float_fallback(src, &d)) {
|
||||
writer.append_double(d);
|
||||
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||
if (parse_float_fallback(src, answer)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
return INVALID_NUMBER(src);
|
||||
@@ -9053,13 +9073,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
||||
// 10000000000000000000000000000000000000000000e+308
|
||||
// 3.1415926535897932384626433832795028841971693993751
|
||||
//
|
||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
||||
// This is what forces the skip_double, as well.
|
||||
error_code error = slow_float_parsing(src, writer);
|
||||
writer.skip_double();
|
||||
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||
// it gets slow.
|
||||
double d;
|
||||
error_code error = slow_float_parsing(src, &d);
|
||||
writer.append_double(d);
|
||||
return error;
|
||||
}
|
||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||
@@ -9583,7 +9603,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double(const uint8
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -9782,7 +9802,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(c
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -10852,7 +10872,7 @@ namespace simdjson {
|
||||
namespace arm64 {
|
||||
namespace {
|
||||
|
||||
simdjson_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3);
|
||||
simdjson_inline simd8<uint8_t> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3);
|
||||
simdjson_inline bool is_ascii(const simd8x64<uint8_t>& input);
|
||||
|
||||
} // unnamed namespace
|
||||
@@ -11419,7 +11439,7 @@ using namespace simd;
|
||||
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
||||
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
||||
simd8<uint8_t> prev3 = input.prev<3>(prev_input);
|
||||
simd8<uint8_t> must23 = simd8<uint8_t>(must_be_2_3_continuation(prev2, prev3));
|
||||
simd8<uint8_t> must23 = must_be_2_3_continuation(prev2, prev3);
|
||||
simd8<uint8_t> must23_80 = must23 & uint8_t(0x80);
|
||||
return must23_80 ^ sc;
|
||||
}
|
||||
@@ -13614,10 +13634,10 @@ simdjson_unused simdjson_inline simd8<bool> must_be_continuation(const simd8<uin
|
||||
return is_second_byte ^ is_third_byte ^ is_fourth_byte;
|
||||
}
|
||||
|
||||
simdjson_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<bool> is_third_byte = prev2 >= uint8_t(0xe0u);
|
||||
simd8<bool> is_fourth_byte = prev3 >= uint8_t(0xf0u);
|
||||
return is_third_byte ^ is_fourth_byte;
|
||||
simdjson_inline simd8<uint8_t> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-0x80); // Only 111_____ will be >= 0x80
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||
return is_third_byte | is_fourth_byte;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
@@ -14823,11 +14843,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
||||
} // unnamed namespace
|
||||
|
||||
/** @private */
|
||||
template<typename W>
|
||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
||||
double d;
|
||||
if (parse_float_fallback(src, &d)) {
|
||||
writer.append_double(d);
|
||||
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||
if (parse_float_fallback(src, answer)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
return INVALID_NUMBER(src);
|
||||
@@ -14851,13 +14868,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
||||
// 10000000000000000000000000000000000000000000e+308
|
||||
// 3.1415926535897932384626433832795028841971693993751
|
||||
//
|
||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
||||
// This is what forces the skip_double, as well.
|
||||
error_code error = slow_float_parsing(src, writer);
|
||||
writer.skip_double();
|
||||
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||
// it gets slow.
|
||||
double d;
|
||||
error_code error = slow_float_parsing(src, &d);
|
||||
writer.append_double(d);
|
||||
return error;
|
||||
}
|
||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||
@@ -15381,7 +15398,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double(const uint8
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -15580,7 +15597,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(c
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -19226,11 +19243,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
||||
} // unnamed namespace
|
||||
|
||||
/** @private */
|
||||
template<typename W>
|
||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
||||
double d;
|
||||
if (parse_float_fallback(src, &d)) {
|
||||
writer.append_double(d);
|
||||
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||
if (parse_float_fallback(src, answer)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
return INVALID_NUMBER(src);
|
||||
@@ -19254,13 +19268,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
||||
// 10000000000000000000000000000000000000000000e+308
|
||||
// 3.1415926535897932384626433832795028841971693993751
|
||||
//
|
||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
||||
// This is what forces the skip_double, as well.
|
||||
error_code error = slow_float_parsing(src, writer);
|
||||
writer.skip_double();
|
||||
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||
// it gets slow.
|
||||
double d;
|
||||
error_code error = slow_float_parsing(src, &d);
|
||||
writer.append_double(d);
|
||||
return error;
|
||||
}
|
||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||
@@ -19784,7 +19798,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double(const uint8
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -19983,7 +19997,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(c
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -20930,7 +20944,7 @@ namespace simdjson {
|
||||
namespace haswell {
|
||||
namespace {
|
||||
|
||||
simdjson_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3);
|
||||
simdjson_inline simd8<uint8_t> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3);
|
||||
simdjson_inline bool is_ascii(const simd8x64<uint8_t>& input);
|
||||
|
||||
} // unnamed namespace
|
||||
@@ -21497,7 +21511,7 @@ using namespace simd;
|
||||
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
||||
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
||||
simd8<uint8_t> prev3 = input.prev<3>(prev_input);
|
||||
simd8<uint8_t> must23 = simd8<uint8_t>(must_be_2_3_continuation(prev2, prev3));
|
||||
simd8<uint8_t> must23 = must_be_2_3_continuation(prev2, prev3);
|
||||
simd8<uint8_t> must23_80 = must23 & uint8_t(0x80);
|
||||
return must23_80 ^ sc;
|
||||
}
|
||||
@@ -23689,11 +23703,10 @@ simdjson_unused simdjson_inline simd8<bool> must_be_continuation(const simd8<uin
|
||||
return simd8<int8_t>(is_second_byte | is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
}
|
||||
|
||||
simdjson_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-1); // Only 111_____ will be > 0
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-1); // Only 1111____ will be > 0
|
||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
||||
return simd8<int8_t>(is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
simdjson_inline simd8<uint8_t> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-0x80); // Only 111_____ will be >= 0x80
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||
return is_third_byte | is_fourth_byte;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
@@ -25390,11 +25403,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
||||
} // unnamed namespace
|
||||
|
||||
/** @private */
|
||||
template<typename W>
|
||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
||||
double d;
|
||||
if (parse_float_fallback(src, &d)) {
|
||||
writer.append_double(d);
|
||||
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||
if (parse_float_fallback(src, answer)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
return INVALID_NUMBER(src);
|
||||
@@ -25418,13 +25428,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
||||
// 10000000000000000000000000000000000000000000e+308
|
||||
// 3.1415926535897932384626433832795028841971693993751
|
||||
//
|
||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
||||
// This is what forces the skip_double, as well.
|
||||
error_code error = slow_float_parsing(src, writer);
|
||||
writer.skip_double();
|
||||
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||
// it gets slow.
|
||||
double d;
|
||||
error_code error = slow_float_parsing(src, &d);
|
||||
writer.append_double(d);
|
||||
return error;
|
||||
}
|
||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||
@@ -25948,7 +25958,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double(const uint8
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -26147,7 +26157,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(c
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -27092,7 +27102,7 @@ namespace simdjson {
|
||||
namespace icelake {
|
||||
namespace {
|
||||
|
||||
simdjson_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3);
|
||||
simdjson_inline simd8<uint8_t> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3);
|
||||
simdjson_inline bool is_ascii(const simd8x64<uint8_t>& input);
|
||||
|
||||
} // unnamed namespace
|
||||
@@ -27659,7 +27669,7 @@ using namespace simd;
|
||||
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
||||
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
||||
simd8<uint8_t> prev3 = input.prev<3>(prev_input);
|
||||
simd8<uint8_t> must23 = simd8<uint8_t>(must_be_2_3_continuation(prev2, prev3));
|
||||
simd8<uint8_t> must23 = must_be_2_3_continuation(prev2, prev3);
|
||||
simd8<uint8_t> must23_80 = must23 & uint8_t(0x80);
|
||||
return must23_80 ^ sc;
|
||||
}
|
||||
@@ -29850,11 +29860,10 @@ simdjson_unused simdjson_inline simd8<bool> must_be_continuation(const simd8<uin
|
||||
return simd8<int8_t>(is_second_byte | is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
}
|
||||
|
||||
simdjson_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-1); // Only 111_____ will be > 0
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-1); // Only 1111____ will be > 0
|
||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
||||
return simd8<int8_t>(is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
simdjson_inline simd8<uint8_t> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-0x80); // Only 111_____ will be >= 0x80
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||
return is_third_byte | is_fourth_byte;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
@@ -31710,11 +31719,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
||||
} // unnamed namespace
|
||||
|
||||
/** @private */
|
||||
template<typename W>
|
||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
||||
double d;
|
||||
if (parse_float_fallback(src, &d)) {
|
||||
writer.append_double(d);
|
||||
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||
if (parse_float_fallback(src, answer)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
return INVALID_NUMBER(src);
|
||||
@@ -31738,13 +31744,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
||||
// 10000000000000000000000000000000000000000000e+308
|
||||
// 3.1415926535897932384626433832795028841971693993751
|
||||
//
|
||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
||||
// This is what forces the skip_double, as well.
|
||||
error_code error = slow_float_parsing(src, writer);
|
||||
writer.skip_double();
|
||||
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||
// it gets slow.
|
||||
double d;
|
||||
error_code error = slow_float_parsing(src, &d);
|
||||
writer.append_double(d);
|
||||
return error;
|
||||
}
|
||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||
@@ -32268,7 +32274,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double(const uint8
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -32467,7 +32473,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(c
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -33525,7 +33531,7 @@ namespace simdjson {
|
||||
namespace ppc64 {
|
||||
namespace {
|
||||
|
||||
simdjson_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3);
|
||||
simdjson_inline simd8<uint8_t> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3);
|
||||
simdjson_inline bool is_ascii(const simd8x64<uint8_t>& input);
|
||||
|
||||
} // unnamed namespace
|
||||
@@ -34092,7 +34098,7 @@ using namespace simd;
|
||||
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
||||
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
||||
simd8<uint8_t> prev3 = input.prev<3>(prev_input);
|
||||
simd8<uint8_t> must23 = simd8<uint8_t>(must_be_2_3_continuation(prev2, prev3));
|
||||
simd8<uint8_t> must23 = must_be_2_3_continuation(prev2, prev3);
|
||||
simd8<uint8_t> must23_80 = must23 & uint8_t(0x80);
|
||||
return must23_80 ^ sc;
|
||||
}
|
||||
@@ -36257,11 +36263,10 @@ simdjson_unused simdjson_inline simd8<bool> must_be_continuation(const simd8<uin
|
||||
return simd8<int8_t>(is_second_byte | is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
}
|
||||
|
||||
simdjson_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-1); // Only 111_____ will be > 0
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-1); // Only 1111____ will be > 0
|
||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
||||
return simd8<int8_t>(is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
simdjson_inline simd8<uint8_t> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-0x80); // Only 111_____ will be >= 0x80
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||
return is_third_byte | is_fourth_byte;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
@@ -38396,11 +38401,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
||||
} // unnamed namespace
|
||||
|
||||
/** @private */
|
||||
template<typename W>
|
||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
||||
double d;
|
||||
if (parse_float_fallback(src, &d)) {
|
||||
writer.append_double(d);
|
||||
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||
if (parse_float_fallback(src, answer)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
return INVALID_NUMBER(src);
|
||||
@@ -38424,13 +38426,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
||||
// 10000000000000000000000000000000000000000000e+308
|
||||
// 3.1415926535897932384626433832795028841971693993751
|
||||
//
|
||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
||||
// This is what forces the skip_double, as well.
|
||||
error_code error = slow_float_parsing(src, writer);
|
||||
writer.skip_double();
|
||||
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||
// it gets slow.
|
||||
double d;
|
||||
error_code error = slow_float_parsing(src, &d);
|
||||
writer.append_double(d);
|
||||
return error;
|
||||
}
|
||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||
@@ -38954,7 +38956,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double(const uint8
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -39153,7 +39155,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(c
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -40532,7 +40534,7 @@ namespace simdjson {
|
||||
namespace westmere {
|
||||
namespace {
|
||||
|
||||
simdjson_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3);
|
||||
simdjson_inline simd8<uint8_t> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3);
|
||||
simdjson_inline bool is_ascii(const simd8x64<uint8_t>& input);
|
||||
|
||||
} // unnamed namespace
|
||||
@@ -41099,7 +41101,7 @@ using namespace simd;
|
||||
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
||||
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
||||
simd8<uint8_t> prev3 = input.prev<3>(prev_input);
|
||||
simd8<uint8_t> must23 = simd8<uint8_t>(must_be_2_3_continuation(prev2, prev3));
|
||||
simd8<uint8_t> must23 = must_be_2_3_continuation(prev2, prev3);
|
||||
simd8<uint8_t> must23_80 = must23 & uint8_t(0x80);
|
||||
return must23_80 ^ sc;
|
||||
}
|
||||
@@ -43295,11 +43297,10 @@ simdjson_unused simdjson_inline simd8<bool> must_be_continuation(const simd8<uin
|
||||
return simd8<int8_t>(is_second_byte | is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
}
|
||||
|
||||
simdjson_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-1); // Only 111_____ will be > 0
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-1); // Only 1111____ will be > 0
|
||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
||||
return simd8<int8_t>(is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
simdjson_inline simd8<uint8_t> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-0x80); // Only 111_____ will be >= 0x80
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||
return is_third_byte | is_fourth_byte;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
+153
-109
@@ -1,4 +1,4 @@
|
||||
/* auto-generated on 2023-12-01 13:55:28 -0500. Do not edit! */
|
||||
/* auto-generated on 2024-01-28 12:42:59 -0500. Do not edit! */
|
||||
/* including simdjson.h: */
|
||||
/* begin file simdjson.h */
|
||||
#ifndef SIMDJSON_H
|
||||
@@ -545,7 +545,7 @@ SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#pragma once
|
||||
// #pragma once // We remove #pragma once here as it generates a warning in some cases. We rely on the include guard.
|
||||
|
||||
#ifndef NONSTD_SV_LITE_H_INCLUDED
|
||||
#define NONSTD_SV_LITE_H_INCLUDED
|
||||
@@ -608,6 +608,10 @@ SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
|
||||
# define nssv_CONFIG_NO_STREAM_INSERTION 0
|
||||
#endif
|
||||
|
||||
#ifndef nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||
# define nssv_CONFIG_CONSTEXPR11_STD_SEARCH 1
|
||||
#endif
|
||||
|
||||
// Control presence of exception handling (try and auto discover):
|
||||
|
||||
#ifndef nssv_CONFIG_NO_EXCEPTIONS
|
||||
@@ -806,7 +810,7 @@ using std::operator<<;
|
||||
# define nssv_HAS_CPP0X 0
|
||||
#endif
|
||||
|
||||
// Unless defined otherwise below, consider VC14 as C++11 for variant-lite:
|
||||
// Unless defined otherwise below, consider VC14 as C++11 for string-view-lite:
|
||||
|
||||
#if nssv_COMPILER_MSVC_VER >= 1900
|
||||
# undef nssv_CPP11_OR_GREATER
|
||||
@@ -973,9 +977,9 @@ using std::operator<<;
|
||||
# pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wuser-defined-literals"
|
||||
#elif defined(__GNUC__)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wliteral-suffix"
|
||||
#elif nssv_COMPILER_GNUC_VERSION >= 480
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wliteral-suffix"
|
||||
#endif // __clang__
|
||||
|
||||
#if nssv_COMPILER_MSVC_VERSION >= 140
|
||||
@@ -990,8 +994,8 @@ using std::operator<<;
|
||||
|
||||
#if defined(__clang__)
|
||||
# define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
|
||||
#elif defined(__GNUC__)
|
||||
# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
|
||||
#elif nssv_COMPILER_GNUC_VERSION >= 480
|
||||
# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
|
||||
#elif nssv_COMPILER_MSVC_VERSION >= 140
|
||||
# define nssv_RESTORE_WARNINGS() __pragma(warning(pop ))
|
||||
#else
|
||||
@@ -1106,12 +1110,31 @@ constexpr const CharT* search( basic_string_view<CharT, Traits> haystack, basic_
|
||||
|
||||
// non-recursive:
|
||||
|
||||
#if nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||
|
||||
template< class CharT, class Traits = std::char_traits<CharT> >
|
||||
constexpr const CharT* search( basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle )
|
||||
{
|
||||
return std::search( haystack.begin(), haystack.end(), needle.begin(), needle.end() );
|
||||
}
|
||||
|
||||
#else // nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||
|
||||
template< class CharT, class Traits = std::char_traits<CharT> >
|
||||
nssv_constexpr14 const CharT* search( basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle )
|
||||
{
|
||||
while ( needle.size() <= haystack.size() )
|
||||
{
|
||||
if ( haystack.starts_with(needle) )
|
||||
{
|
||||
return haystack.cbegin();
|
||||
}
|
||||
haystack = basic_string_view<CharT, Traits>{ haystack.begin() + 1, haystack.size() - 1U };
|
||||
}
|
||||
return haystack.cend();
|
||||
}
|
||||
#endif // nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||
|
||||
#endif // OPTIMIZE
|
||||
#endif // nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
|
||||
|
||||
@@ -1384,7 +1407,7 @@ public:
|
||||
|
||||
// find(), 4x:
|
||||
|
||||
nssv_constexpr size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
|
||||
nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
|
||||
{
|
||||
return assert( v.size() == 0 || v.data() != nssv_nullptr )
|
||||
, pos >= size()
|
||||
@@ -2321,7 +2344,7 @@ namespace std {
|
||||
#define SIMDJSON_SIMDJSON_VERSION_H
|
||||
|
||||
/** The version of simdjson being used (major.minor.revision) */
|
||||
#define SIMDJSON_VERSION "3.6.2"
|
||||
#define SIMDJSON_VERSION "3.6.4"
|
||||
|
||||
namespace simdjson {
|
||||
enum {
|
||||
@@ -2336,7 +2359,7 @@ enum {
|
||||
/**
|
||||
* The revision (major.minor.REVISION) of simdjson being used.
|
||||
*/
|
||||
SIMDJSON_VERSION_REVISION = 2
|
||||
SIMDJSON_VERSION_REVISION = 4
|
||||
};
|
||||
} // namespace simdjson
|
||||
|
||||
@@ -4449,6 +4472,53 @@ public:
|
||||
*/
|
||||
inline simdjson_result<element> load(const std::string &path) & noexcept;
|
||||
inline simdjson_result<element> load(const std::string &path) && = delete ;
|
||||
|
||||
/**
|
||||
* Load a JSON document from a file into a provide document instance and return a temporary reference to it.
|
||||
* It is similar to the function `load` except that instead of parsing into the internal
|
||||
* `document` instance associated with the parser, it allows the user to provide a document
|
||||
* instance.
|
||||
*
|
||||
* dom::parser parser;
|
||||
* dom::document doc;
|
||||
* element doc_root = parser.load_into_document(doc, "jsonexamples/twitter.json");
|
||||
*
|
||||
* The function is eager: the file's content is loaded in memory inside the parser instance
|
||||
* and immediately parsed. The file can be deleted after the `parser.load_into_document` call.
|
||||
*
|
||||
* ### IMPORTANT: Document Lifetime
|
||||
*
|
||||
* After the call to load_into_document, the parser is no longer needed.
|
||||
*
|
||||
* The JSON document lives in the document instance: you must keep the document
|
||||
* instance alive while you navigate through it (i.e., used the returned value from
|
||||
* load_into_document). You are encourage to reuse the document instance
|
||||
* many times with new data to avoid reallocations:
|
||||
*
|
||||
* dom::document doc;
|
||||
* element doc_root1 = parser.load_into_document(doc, "jsonexamples/twitter.json");
|
||||
* //... doc_root1 is a pointer inside doc
|
||||
* element doc_root2 = parser.load_into_document(doc, "jsonexamples/twitter.json");
|
||||
* //... doc_root2 is a pointer inside doc
|
||||
* // at this point doc_root1 is no longer safe
|
||||
*
|
||||
* Moving the document instance is safe, but it invalidates the element instances. After
|
||||
* moving a document, you can recover safe access to the document root with its `root()` method.
|
||||
*
|
||||
* @param doc The document instance where the parsed data will be stored (on success).
|
||||
* @param path The path to load.
|
||||
* @return The document, or an error:
|
||||
* - IO_ERROR if there was an error opening or reading the file.
|
||||
* Be mindful that on some 32-bit systems,
|
||||
* the file size might be limited to 2 GB.
|
||||
* - MEMALLOC if the parser does not have enough capacity and memory allocation fails.
|
||||
* - CAPACITY if the parser does not have enough capacity and len > max_capacity.
|
||||
* - other json errors if parsing fails. You should not rely on these errors to always the same for the
|
||||
* same document: they may vary under runtime dispatch (so they may vary depending on your system and hardware).
|
||||
*/
|
||||
inline simdjson_result<element> load_into_document(document& doc, const std::string &path) & noexcept;
|
||||
inline simdjson_result<element> load_into_document(document& doc, const std::string &path) && =delete;
|
||||
|
||||
/**
|
||||
* Parse a JSON document and return a temporary reference to it.
|
||||
*
|
||||
@@ -5484,7 +5554,7 @@ public:
|
||||
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. "
|
||||
"The supported types are Boolean (bool), numbers (double, uint64_t, int64_t), "
|
||||
"strings (std::string_view, const char *), arrays (dom::array) and objects (dom::object). "
|
||||
"We recommand you use get_double(), get_bool(), get_uint64(), get_int64(), "
|
||||
"We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), "
|
||||
"get_object(), get_array() or get_string() instead of the get template.");
|
||||
}
|
||||
|
||||
@@ -7556,10 +7626,14 @@ inline simdjson_result<size_t> parser::read_file(const std::string &path) noexce
|
||||
}
|
||||
|
||||
inline simdjson_result<element> parser::load(const std::string &path) & noexcept {
|
||||
return load_into_document(doc, path);
|
||||
}
|
||||
|
||||
inline simdjson_result<element> parser::load_into_document(document& provided_doc, const std::string &path) & noexcept {
|
||||
size_t len;
|
||||
auto _error = read_file(path).get(len);
|
||||
if (_error) { return _error; }
|
||||
return parse(loaded_bytes.get(), len, false);
|
||||
return parse_into_document(provided_doc, loaded_bytes.get(), len, false);
|
||||
}
|
||||
|
||||
inline simdjson_result<document_stream> parser::load_many(const std::string &path, size_t batch_size) noexcept {
|
||||
@@ -12109,11 +12183,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
||||
} // unnamed namespace
|
||||
|
||||
/** @private */
|
||||
template<typename W>
|
||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
||||
double d;
|
||||
if (parse_float_fallback(src, &d)) {
|
||||
writer.append_double(d);
|
||||
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||
if (parse_float_fallback(src, answer)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
return INVALID_NUMBER(src);
|
||||
@@ -12137,13 +12208,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
||||
// 10000000000000000000000000000000000000000000e+308
|
||||
// 3.1415926535897932384626433832795028841971693993751
|
||||
//
|
||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
||||
// This is what forces the skip_double, as well.
|
||||
error_code error = slow_float_parsing(src, writer);
|
||||
writer.skip_double();
|
||||
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||
// it gets slow.
|
||||
double d;
|
||||
error_code error = slow_float_parsing(src, &d);
|
||||
writer.append_double(d);
|
||||
return error;
|
||||
}
|
||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||
@@ -12667,7 +12738,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double(const uint8
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -12866,7 +12937,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(c
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -14161,11 +14232,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
||||
} // unnamed namespace
|
||||
|
||||
/** @private */
|
||||
template<typename W>
|
||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
||||
double d;
|
||||
if (parse_float_fallback(src, &d)) {
|
||||
writer.append_double(d);
|
||||
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||
if (parse_float_fallback(src, answer)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
return INVALID_NUMBER(src);
|
||||
@@ -14189,13 +14257,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
||||
// 10000000000000000000000000000000000000000000e+308
|
||||
// 3.1415926535897932384626433832795028841971693993751
|
||||
//
|
||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
||||
// This is what forces the skip_double, as well.
|
||||
error_code error = slow_float_parsing(src, writer);
|
||||
writer.skip_double();
|
||||
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||
// it gets slow.
|
||||
double d;
|
||||
error_code error = slow_float_parsing(src, &d);
|
||||
writer.append_double(d);
|
||||
return error;
|
||||
}
|
||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||
@@ -14719,7 +14787,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double(const uint8
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -14918,7 +14986,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(c
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -16705,11 +16773,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
||||
} // unnamed namespace
|
||||
|
||||
/** @private */
|
||||
template<typename W>
|
||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
||||
double d;
|
||||
if (parse_float_fallback(src, &d)) {
|
||||
writer.append_double(d);
|
||||
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||
if (parse_float_fallback(src, answer)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
return INVALID_NUMBER(src);
|
||||
@@ -16733,13 +16798,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
||||
// 10000000000000000000000000000000000000000000e+308
|
||||
// 3.1415926535897932384626433832795028841971693993751
|
||||
//
|
||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
||||
// This is what forces the skip_double, as well.
|
||||
error_code error = slow_float_parsing(src, writer);
|
||||
writer.skip_double();
|
||||
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||
// it gets slow.
|
||||
double d;
|
||||
error_code error = slow_float_parsing(src, &d);
|
||||
writer.append_double(d);
|
||||
return error;
|
||||
}
|
||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||
@@ -17263,7 +17328,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double(const uint8
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -17462,7 +17527,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(c
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -19248,11 +19313,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
||||
} // unnamed namespace
|
||||
|
||||
/** @private */
|
||||
template<typename W>
|
||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
||||
double d;
|
||||
if (parse_float_fallback(src, &d)) {
|
||||
writer.append_double(d);
|
||||
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||
if (parse_float_fallback(src, answer)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
return INVALID_NUMBER(src);
|
||||
@@ -19276,13 +19338,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
||||
// 10000000000000000000000000000000000000000000e+308
|
||||
// 3.1415926535897932384626433832795028841971693993751
|
||||
//
|
||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
||||
// This is what forces the skip_double, as well.
|
||||
error_code error = slow_float_parsing(src, writer);
|
||||
writer.skip_double();
|
||||
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||
// it gets slow.
|
||||
double d;
|
||||
error_code error = slow_float_parsing(src, &d);
|
||||
writer.append_double(d);
|
||||
return error;
|
||||
}
|
||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||
@@ -19806,7 +19868,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double(const uint8
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -20005,7 +20067,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(c
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -21906,11 +21968,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
||||
} // unnamed namespace
|
||||
|
||||
/** @private */
|
||||
template<typename W>
|
||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
||||
double d;
|
||||
if (parse_float_fallback(src, &d)) {
|
||||
writer.append_double(d);
|
||||
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||
if (parse_float_fallback(src, answer)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
return INVALID_NUMBER(src);
|
||||
@@ -21934,13 +21993,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
||||
// 10000000000000000000000000000000000000000000e+308
|
||||
// 3.1415926535897932384626433832795028841971693993751
|
||||
//
|
||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
||||
// This is what forces the skip_double, as well.
|
||||
error_code error = slow_float_parsing(src, writer);
|
||||
writer.skip_double();
|
||||
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||
// it gets slow.
|
||||
double d;
|
||||
error_code error = slow_float_parsing(src, &d);
|
||||
writer.append_double(d);
|
||||
return error;
|
||||
}
|
||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||
@@ -22464,7 +22523,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double(const uint8
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -22663,7 +22722,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(c
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -24887,11 +24946,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
||||
} // unnamed namespace
|
||||
|
||||
/** @private */
|
||||
template<typename W>
|
||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
||||
double d;
|
||||
if (parse_float_fallback(src, &d)) {
|
||||
writer.append_double(d);
|
||||
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||
if (parse_float_fallback(src, answer)) {
|
||||
return SUCCESS;
|
||||
}
|
||||
return INVALID_NUMBER(src);
|
||||
@@ -24915,13 +24971,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
||||
// 10000000000000000000000000000000000000000000e+308
|
||||
// 3.1415926535897932384626433832795028841971693993751
|
||||
//
|
||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
||||
// This is what forces the skip_double, as well.
|
||||
error_code error = slow_float_parsing(src, writer);
|
||||
writer.skip_double();
|
||||
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||
// it gets slow.
|
||||
double d;
|
||||
error_code error = slow_float_parsing(src, &d);
|
||||
writer.append_double(d);
|
||||
return error;
|
||||
}
|
||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||
@@ -25445,7 +25501,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double(const uint8
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -25644,7 +25700,7 @@ simdjson_unused simdjson_inline simdjson_result<double> parse_double_in_string(c
|
||||
// Skip leading 0.00000 and see if it still overflows
|
||||
const uint8_t *start_digits = src + 2;
|
||||
while (*start_digits == '0') { start_digits++; }
|
||||
overflow = start_digits-src > 19;
|
||||
overflow = p-start_digits > 19;
|
||||
}
|
||||
} else {
|
||||
overflow = p-src > 19;
|
||||
@@ -28613,8 +28669,6 @@ protected:
|
||||
*/
|
||||
friend class value_iterator;
|
||||
template<typename W>
|
||||
friend error_code numberparsing::slow_float_parsing(simdjson_unused const uint8_t * src, W writer);
|
||||
template<typename W>
|
||||
friend error_code numberparsing::write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer);
|
||||
template<typename W>
|
||||
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
||||
@@ -38534,8 +38588,6 @@ protected:
|
||||
*/
|
||||
friend class value_iterator;
|
||||
template<typename W>
|
||||
friend error_code numberparsing::slow_float_parsing(simdjson_unused const uint8_t * src, W writer);
|
||||
template<typename W>
|
||||
friend error_code numberparsing::write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer);
|
||||
template<typename W>
|
||||
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
||||
@@ -48947,8 +48999,6 @@ protected:
|
||||
*/
|
||||
friend class value_iterator;
|
||||
template<typename W>
|
||||
friend error_code numberparsing::slow_float_parsing(simdjson_unused const uint8_t * src, W writer);
|
||||
template<typename W>
|
||||
friend error_code numberparsing::write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer);
|
||||
template<typename W>
|
||||
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
||||
@@ -59359,8 +59409,6 @@ protected:
|
||||
*/
|
||||
friend class value_iterator;
|
||||
template<typename W>
|
||||
friend error_code numberparsing::slow_float_parsing(simdjson_unused const uint8_t * src, W writer);
|
||||
template<typename W>
|
||||
friend error_code numberparsing::write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer);
|
||||
template<typename W>
|
||||
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
||||
@@ -69886,8 +69934,6 @@ protected:
|
||||
*/
|
||||
friend class value_iterator;
|
||||
template<typename W>
|
||||
friend error_code numberparsing::slow_float_parsing(simdjson_unused const uint8_t * src, W writer);
|
||||
template<typename W>
|
||||
friend error_code numberparsing::write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer);
|
||||
template<typename W>
|
||||
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
||||
@@ -80736,8 +80782,6 @@ protected:
|
||||
*/
|
||||
friend class value_iterator;
|
||||
template<typename W>
|
||||
friend error_code numberparsing::slow_float_parsing(simdjson_unused const uint8_t * src, W writer);
|
||||
template<typename W>
|
||||
friend error_code numberparsing::write_float(const uint8_t *const src, bool negative, uint64_t i, const uint8_t * start_digits, size_t digit_count, int64_t exponent, W &writer);
|
||||
template<typename W>
|
||||
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
||||
|
||||
+4
-4
@@ -108,10 +108,10 @@ simdjson_unused simdjson_inline simd8<bool> must_be_continuation(const simd8<uin
|
||||
return is_second_byte ^ is_third_byte ^ is_fourth_byte;
|
||||
}
|
||||
|
||||
simdjson_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<bool> is_third_byte = prev2 >= uint8_t(0xe0u);
|
||||
simd8<bool> is_fourth_byte = prev3 >= uint8_t(0xf0u);
|
||||
return is_third_byte ^ is_fourth_byte;
|
||||
simdjson_inline simd8<uint8_t> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-0x80); // Only 111_____ will be >= 0x80
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||
return is_third_byte | is_fourth_byte;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace simdjson {
|
||||
namespace SIMDJSON_IMPLEMENTATION {
|
||||
namespace {
|
||||
|
||||
simdjson_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3);
|
||||
simdjson_inline simd8<uint8_t> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3);
|
||||
simdjson_inline bool is_ascii(const simd8x64<uint8_t>& input);
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
@@ -107,7 +107,7 @@ using namespace simd;
|
||||
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
||||
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
||||
simd8<uint8_t> prev3 = input.prev<3>(prev_input);
|
||||
simd8<uint8_t> must23 = simd8<uint8_t>(must_be_2_3_continuation(prev2, prev3));
|
||||
simd8<uint8_t> must23 = must_be_2_3_continuation(prev2, prev3);
|
||||
simd8<uint8_t> must23_80 = must23 & uint8_t(0x80);
|
||||
return must23_80 ^ sc;
|
||||
}
|
||||
|
||||
+4
-5
@@ -105,11 +105,10 @@ simdjson_unused simdjson_inline simd8<bool> must_be_continuation(const simd8<uin
|
||||
return simd8<int8_t>(is_second_byte | is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
}
|
||||
|
||||
simdjson_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-1); // Only 111_____ will be > 0
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-1); // Only 1111____ will be > 0
|
||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
||||
return simd8<int8_t>(is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
simdjson_inline simd8<uint8_t> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-0x80); // Only 111_____ will be >= 0x80
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||
return is_third_byte | is_fourth_byte;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
+4
-5
@@ -107,11 +107,10 @@ simdjson_unused simdjson_inline simd8<bool> must_be_continuation(const simd8<uin
|
||||
return simd8<int8_t>(is_second_byte | is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
}
|
||||
|
||||
simdjson_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-1); // Only 111_____ will be > 0
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-1); // Only 1111____ will be > 0
|
||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
||||
return simd8<int8_t>(is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
simdjson_inline simd8<uint8_t> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-0x80); // Only 111_____ will be >= 0x80
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||
return is_third_byte | is_fourth_byte;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
+4
-5
@@ -78,11 +78,10 @@ simdjson_unused simdjson_inline simd8<bool> must_be_continuation(const simd8<uin
|
||||
return simd8<int8_t>(is_second_byte | is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
}
|
||||
|
||||
simdjson_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-1); // Only 111_____ will be > 0
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-1); // Only 1111____ will be > 0
|
||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
||||
return simd8<int8_t>(is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
simdjson_inline simd8<uint8_t> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-0x80); // Only 111_____ will be >= 0x80
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||
return is_third_byte | is_fourth_byte;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
+4
-5
@@ -109,11 +109,10 @@ simdjson_unused simdjson_inline simd8<bool> must_be_continuation(const simd8<uin
|
||||
return simd8<int8_t>(is_second_byte | is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
}
|
||||
|
||||
simdjson_inline simd8<bool> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-1); // Only 111_____ will be > 0
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-1); // Only 1111____ will be > 0
|
||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
||||
return simd8<int8_t>(is_third_byte | is_fourth_byte) > int8_t(0);
|
||||
simdjson_inline simd8<uint8_t> must_be_2_3_continuation(const simd8<uint8_t> prev2, const simd8<uint8_t> prev3) {
|
||||
simd8<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-0x80); // Only 111_____ will be >= 0x80
|
||||
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||
return is_third_byte | is_fourth_byte;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
@@ -452,14 +452,18 @@ namespace parse_api_tests {
|
||||
element doc_root1 = parser.parse_into_document(doc, input);
|
||||
if(simdjson::to_string(doc_root1) != "[1,2,3]") { return false; }
|
||||
//... doc_root1 is a pointer inside doc
|
||||
element doc_root2 = parser.parse_into_document(doc, input);
|
||||
element doc_root2 = parser.load_into_document(doc, TWITTER_JSON);
|
||||
//... doc_root2 is a pointer inside doc
|
||||
if(simdjson::to_string(doc_root2) != "[1,2,3]") { return false; }
|
||||
if(uint64_t(doc_root2["search_metadata"]["count"]) != 100) { return false; }
|
||||
if(uint64_t(doc.root()["search_metadata"]["count"]) != 100) { return false; }
|
||||
element doc_root3 = parser.parse_into_document(doc, input);
|
||||
//... doc_root3 is a pointer inside doc
|
||||
if(simdjson::to_string(doc_root3) != "[1,2,3]") { return false; }
|
||||
|
||||
// Here let us take moving the document:
|
||||
dom::document docm = std::move(doc);
|
||||
element doc_root3 = docm.root();
|
||||
if(simdjson::to_string(doc_root3) != "[1,2,3]") { return false; }
|
||||
element doc_root4 = docm.root();
|
||||
if(simdjson::to_string(doc_root4) != "[1,2,3]") { return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -278,6 +278,19 @@ namespace number_tests {
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
bool issue2099() {
|
||||
TEST_START();
|
||||
ondemand::parser parser;
|
||||
auto json = "1000000000.000000001"_padded;
|
||||
ondemand::document doc;
|
||||
ASSERT_SUCCESS(parser.iterate(json).get(doc));
|
||||
ondemand::number number;
|
||||
ASSERT_SUCCESS(doc.get_number().get(number));
|
||||
ASSERT_EQUAL(number.get_number_type(), ondemand::number_type::floating_point_number);
|
||||
ASSERT_EQUAL(number.get_double(), 1e9);
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
bool issue1878() {
|
||||
TEST_START();
|
||||
ondemand::parser parser;
|
||||
@@ -415,8 +428,23 @@ namespace number_tests {
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
|
||||
bool issue2093() {
|
||||
TEST_START();
|
||||
ondemand::parser parser;
|
||||
ondemand::document doc;
|
||||
padded_string docdata = R"(0.95000000000000000000)"_padded;
|
||||
ASSERT_SUCCESS(parser.iterate(docdata).get(doc));
|
||||
double d;
|
||||
ASSERT_SUCCESS(doc.get_double().get(d));
|
||||
ASSERT_EQUAL(d, 0.95);
|
||||
TEST_SUCCEED();
|
||||
}
|
||||
|
||||
bool run() {
|
||||
return issue2045() &&
|
||||
return issue2099() &&
|
||||
issue2093() &&
|
||||
issue2045() &&
|
||||
issue2017() &&
|
||||
issue_1898() &&
|
||||
issue1878() &&
|
||||
|
||||
Reference in New Issue
Block a user