mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 88bf5cb6d9 | |||
| 9b0435d864 | |||
| ddecadde86 | |||
| 02bee7d1b9 | |||
| 6ef555e6fb | |||
| 6952f8dfce | |||
| 03d0a4731a | |||
| 185ff4e8fe | |||
| 5bf6d9f3f0 | |||
| 2fa729922e | |||
| ebd09cb2a3 | |||
| 3978b9f159 | |||
| edc36a87ab |
@@ -9,7 +9,7 @@ jobs:
|
|||||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ jobs:
|
|||||||
image: debian:testing
|
image: debian:testing
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ jobs:
|
|||||||
url: ${{ steps.deployment.outputs.page_url }}
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- name: Install Doxygen
|
- name: Install Doxygen
|
||||||
run: sudo apt-get install doxygen graphviz -y
|
run: sudo apt-get install doxygen graphviz -y
|
||||||
- run: mkdir docs
|
- run: mkdir docs
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ jobs:
|
|||||||
whitespace:
|
whitespace:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- name: Remove whitespace and check the diff
|
- name: Remove whitespace and check the diff
|
||||||
run: |
|
run: |
|
||||||
set -eu
|
set -eu
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ jobs:
|
|||||||
chmod +x llvm.sh
|
chmod +x llvm.sh
|
||||||
sudo ./llvm.sh $CLANGVERSION
|
sudo ./llvm.sh $CLANGVERSION
|
||||||
|
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ jobs:
|
|||||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ jobs:
|
|||||||
CMAKE_GENERATOR: Ninja
|
CMAKE_GENERATOR: Ninja
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
CMAKE_GENERATOR: Ninja
|
CMAKE_GENERATOR: Ninja
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ jobs:
|
|||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
name: Build on ubuntu-20.04 ppc64le
|
name: Build on ubuntu-20.04 ppc64le
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: uraimo/run-on-arch-action@v2.0.5
|
- uses: uraimo/run-on-arch-action@v2.0.5
|
||||||
name: Run commands
|
name: Run commands
|
||||||
id: runcmd
|
id: runcmd
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: uraimo/run-on-arch-action@v2
|
- uses: uraimo/run-on-arch-action@v2
|
||||||
name: Test
|
name: Test
|
||||||
id: runcmd
|
id: runcmd
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: uraimo/run-on-arch-action@v2
|
- uses: uraimo/run-on-arch-action@v2
|
||||||
name: Test
|
name: Test
|
||||||
id: runcmd
|
id: runcmd
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: uraimo/run-on-arch-action@v2
|
- uses: uraimo/run-on-arch-action@v2
|
||||||
name: Test
|
name: Test
|
||||||
id: runcmd
|
id: runcmd
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ jobs:
|
|||||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ jobs:
|
|||||||
CXX: g++-8
|
CXX: g++-8
|
||||||
CC: gcc-8
|
CC: gcc-8
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ jobs:
|
|||||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ jobs:
|
|||||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ jobs:
|
|||||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
@@ -27,7 +27,7 @@ jobs:
|
|||||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ jobs:
|
|||||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ jobs:
|
|||||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ jobs:
|
|||||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ jobs:
|
|||||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
|
|||||||
@@ -9,13 +9,11 @@ jobs:
|
|||||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
key: ${{ hashFiles('dependencies/CMakeLists.txt') }}
|
key: ${{ hashFiles('dependencies/CMakeLists.txt') }}
|
||||||
- name: Install gcc12
|
|
||||||
run: sudo apt-get install -y g++-12
|
|
||||||
- name: Use cmake
|
- name: Use cmake
|
||||||
run: |
|
run: |
|
||||||
mkdir build &&
|
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]')
|
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ jobs:
|
|||||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ jobs:
|
|||||||
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
! contains(toJSON(github.event.commits.*.message), '[skip github]')
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ jobs:
|
|||||||
- {arch: ARM64}
|
- {arch: ARM64}
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: Use cmake
|
- name: Use cmake
|
||||||
run: |
|
run: |
|
||||||
cmake -A ${{ matrix.arch }} -DCMAKE_CROSSCOMPILING=1 -DSIMDJSON_DEVELOPER_MODE=ON -D SIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_EXCEPTIONS=OFF -B build &&
|
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}
|
- {gen: Visual Studio 17 2022, arch: x64, shared: OFF}
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: Configure
|
- name: Configure
|
||||||
run: |
|
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
|
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}
|
- {gen: Visual Studio 17 2022, arch: x64, shared: OFF}
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: Configure
|
- name: Configure
|
||||||
run: |
|
run: |
|
||||||
cmake -G "${{matrix.gen}}" -A ${{matrix.arch}} -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -DBUILD_SHARED_LIBS=${{matrix.shared}} -B build
|
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}
|
- {gen: Visual Studio 17 2022, arch: x64}
|
||||||
steps:
|
steps:
|
||||||
- name: checkout
|
- name: checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
- name: Configure
|
- name: Configure
|
||||||
run: |
|
run: |
|
||||||
cmake -G "${{matrix.gen}}" -A ${{matrix.arch}} -T ClangCL -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -B build
|
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
|
name: windows-vs17
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/cache@v3
|
- uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: dependencies/.cache
|
path: dependencies/.cache
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14)
|
|||||||
project(
|
project(
|
||||||
simdjson
|
simdjson
|
||||||
# The version number is modified by tools/release.py
|
# The version number is modified by tools/release.py
|
||||||
VERSION 3.6.3
|
VERSION 3.6.4
|
||||||
DESCRIPTION "Parsing gigabytes of JSON per second"
|
DESCRIPTION "Parsing gigabytes of JSON per second"
|
||||||
HOMEPAGE_URL "https://simdjson.org/"
|
HOMEPAGE_URL "https://simdjson.org/"
|
||||||
LANGUAGES CXX C
|
LANGUAGES CXX C
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ PROJECT_NAME = simdjson
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = "3.6.3"
|
PROJECT_NUMBER = "3.6.4"
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer a
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ Table of Contents
|
|||||||
* [Real-world usage](#real-world-usage)
|
* [Real-world usage](#real-world-usage)
|
||||||
* [Quick Start](#quick-start)
|
* [Quick Start](#quick-start)
|
||||||
* [Documentation](#documentation)
|
* [Documentation](#documentation)
|
||||||
|
* [Godbolt](#godbolt)
|
||||||
* [Performance results](#performance-results)
|
* [Performance results](#performance-results)
|
||||||
* [Bindings and Ports of simdjson](#bindings-and-ports-of-simdjson)
|
* [Bindings and Ports of simdjson](#bindings-and-ports-of-simdjson)
|
||||||
* [About simdjson](#about-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
|
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
|
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
|
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
|
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.
|
100 results.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
@@ -106,11 +108,12 @@ Usage documentation is available:
|
|||||||
how you can work with it.
|
how you can work with it.
|
||||||
* [API](https://simdjson.github.io/simdjson/) contains the automatically generated API documentation.
|
* [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:
|
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/7G5qE4sr9)
|
||||||
* [simdjson examples with errors handled through exceptions](https://godbolt.org/z/98Kx9Kqjn)
|
* [simdjson examples with errors without exceptions](https://godbolt.org/z/e9dWb9E4v)
|
||||||
* [simdjson examples with errors without exceptions](https://godbolt.org/z/PKG7GdbPo)
|
|
||||||
|
|
||||||
Performance results
|
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
|
instructions, reducing branch misprediction, and reducing data dependency to take advantage of each
|
||||||
CPU's multiple execution cores.
|
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:
|
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.
|
- Geoff Langdale, Daniel Lemire, [Parsing Gigabytes of JSON per Second](https://arxiv.org/abs/1902.08318), VLDB Journal 28 (6), 2019.
|
||||||
|
|
||||||
|
|||||||
+9
-2
@@ -36,6 +36,7 @@ An overview of what you need to know to use simdjson, with examples.
|
|||||||
- [Backwards Compatibility](#backwards-compatibility)
|
- [Backwards Compatibility](#backwards-compatibility)
|
||||||
- [Examples](#examples)
|
- [Examples](#examples)
|
||||||
- [Performance Tips](#performance-tips)
|
- [Performance Tips](#performance-tips)
|
||||||
|
- [Further Reading](#further-reading)
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
@@ -1656,8 +1657,8 @@ JSON string to a user-provided buffer:
|
|||||||
General Direct Access to the Raw JSON String
|
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
|
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
|
string. But the simdjson library allows you to have access to the raw underlying JSON
|
||||||
more generally.
|
more generally, not just for strings.
|
||||||
|
|
||||||
The simdjson library makes explicit assumptions about types. For examples, numbers
|
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
|
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"];
|
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.
|
- 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. "
|
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), "
|
"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). "
|
"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.");
|
"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 {
|
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;
|
size_t len;
|
||||||
auto _error = read_file(path).get(len);
|
auto _error = read_file(path).get(len);
|
||||||
if (_error) { return _error; }
|
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 {
|
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) & noexcept;
|
||||||
inline simdjson_result<element> load(const std::string &path) && = delete ;
|
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.
|
* 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
|
} // unnamed namespace
|
||||||
|
|
||||||
/** @private */
|
/** @private */
|
||||||
template<typename W>
|
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
if (parse_float_fallback(src, answer)) {
|
||||||
double d;
|
|
||||||
if (parse_float_fallback(src, &d)) {
|
|
||||||
writer.append_double(d);
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return INVALID_NUMBER(src);
|
return INVALID_NUMBER(src);
|
||||||
@@ -474,13 +471,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
|||||||
// 10000000000000000000000000000000000000000000e+308
|
// 10000000000000000000000000000000000000000000e+308
|
||||||
// 3.1415926535897932384626433832795028841971693993751
|
// 3.1415926535897932384626433832795028841971693993751
|
||||||
//
|
//
|
||||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
// it gets slow.
|
||||||
// This is what forces the skip_double, as well.
|
double d;
|
||||||
error_code error = slow_float_parsing(src, writer);
|
error_code error = slow_float_parsing(src, &d);
|
||||||
writer.skip_double();
|
writer.append_double(d);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||||
|
|||||||
@@ -92,8 +92,6 @@ protected:
|
|||||||
*/
|
*/
|
||||||
friend class value_iterator;
|
friend class value_iterator;
|
||||||
template<typename W>
|
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);
|
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>
|
template<typename W>
|
||||||
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
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.
|
// 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)
|
// (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
|
#ifndef NONSTD_SV_LITE_H_INCLUDED
|
||||||
#define NONSTD_SV_LITE_H_INCLUDED
|
#define NONSTD_SV_LITE_H_INCLUDED
|
||||||
@@ -69,6 +69,10 @@
|
|||||||
# define nssv_CONFIG_NO_STREAM_INSERTION 0
|
# define nssv_CONFIG_NO_STREAM_INSERTION 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||||
|
# define nssv_CONFIG_CONSTEXPR11_STD_SEARCH 1
|
||||||
|
#endif
|
||||||
|
|
||||||
// Control presence of exception handling (try and auto discover):
|
// Control presence of exception handling (try and auto discover):
|
||||||
|
|
||||||
#ifndef nssv_CONFIG_NO_EXCEPTIONS
|
#ifndef nssv_CONFIG_NO_EXCEPTIONS
|
||||||
@@ -267,7 +271,7 @@ using std::operator<<;
|
|||||||
# define nssv_HAS_CPP0X 0
|
# define nssv_HAS_CPP0X 0
|
||||||
#endif
|
#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
|
#if nssv_COMPILER_MSVC_VER >= 1900
|
||||||
# undef nssv_CPP11_OR_GREATER
|
# undef nssv_CPP11_OR_GREATER
|
||||||
@@ -434,9 +438,9 @@ using std::operator<<;
|
|||||||
# pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
|
# pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
|
||||||
# pragma clang diagnostic push
|
# pragma clang diagnostic push
|
||||||
# pragma clang diagnostic ignored "-Wuser-defined-literals"
|
# pragma clang diagnostic ignored "-Wuser-defined-literals"
|
||||||
#elif defined(__GNUC__)
|
#elif nssv_COMPILER_GNUC_VERSION >= 480
|
||||||
# pragma GCC diagnostic push
|
# pragma GCC diagnostic push
|
||||||
# pragma GCC diagnostic ignored "-Wliteral-suffix"
|
# pragma GCC diagnostic ignored "-Wliteral-suffix"
|
||||||
#endif // __clang__
|
#endif // __clang__
|
||||||
|
|
||||||
#if nssv_COMPILER_MSVC_VERSION >= 140
|
#if nssv_COMPILER_MSVC_VERSION >= 140
|
||||||
@@ -451,8 +455,8 @@ using std::operator<<;
|
|||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
# define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
|
# define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
|
||||||
#elif defined(__GNUC__)
|
#elif nssv_COMPILER_GNUC_VERSION >= 480
|
||||||
# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
|
# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
|
||||||
#elif nssv_COMPILER_MSVC_VERSION >= 140
|
#elif nssv_COMPILER_MSVC_VERSION >= 140
|
||||||
# define nssv_RESTORE_WARNINGS() __pragma(warning(pop ))
|
# define nssv_RESTORE_WARNINGS() __pragma(warning(pop ))
|
||||||
#else
|
#else
|
||||||
@@ -567,12 +571,31 @@ constexpr const CharT* search( basic_string_view<CharT, Traits> haystack, basic_
|
|||||||
|
|
||||||
// non-recursive:
|
// non-recursive:
|
||||||
|
|
||||||
|
#if nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||||
|
|
||||||
template< class CharT, class Traits = std::char_traits<CharT> >
|
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 )
|
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() );
|
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 // OPTIMIZE
|
||||||
#endif // nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
|
#endif // nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
|
||||||
|
|
||||||
@@ -845,7 +868,7 @@ public:
|
|||||||
|
|
||||||
// find(), 4x:
|
// 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 )
|
return assert( v.size() == 0 || v.data() != nssv_nullptr )
|
||||||
, pos >= size()
|
, pos >= size()
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#define SIMDJSON_SIMDJSON_VERSION_H
|
#define SIMDJSON_SIMDJSON_VERSION_H
|
||||||
|
|
||||||
/** The version of simdjson being used (major.minor.revision) */
|
/** The version of simdjson being used (major.minor.revision) */
|
||||||
#define SIMDJSON_VERSION "3.6.3"
|
#define SIMDJSON_VERSION "3.6.4"
|
||||||
|
|
||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
enum {
|
enum {
|
||||||
@@ -19,7 +19,7 @@ enum {
|
|||||||
/**
|
/**
|
||||||
* The revision (major.minor.REVISION) of simdjson being used.
|
* The revision (major.minor.REVISION) of simdjson being used.
|
||||||
*/
|
*/
|
||||||
SIMDJSON_VERSION_REVISION = 3
|
SIMDJSON_VERSION_REVISION = 4
|
||||||
};
|
};
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
|
|||||||
+116
-115
@@ -1,4 +1,4 @@
|
|||||||
/* auto-generated on 2023-12-07 12:42:28 -0500. Do not edit! */
|
/* auto-generated on 2024-01-28 12:42:59 -0500. Do not edit! */
|
||||||
/* including simdjson.cpp: */
|
/* including simdjson.cpp: */
|
||||||
/* begin file simdjson.cpp */
|
/* begin file simdjson.cpp */
|
||||||
#define SIMDJSON_SRC_SIMDJSON_CPP
|
#define SIMDJSON_SRC_SIMDJSON_CPP
|
||||||
@@ -525,7 +525,7 @@ SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
|
|||||||
// Distributed under the Boost Software License, Version 1.0.
|
// 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)
|
// (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
|
#ifndef NONSTD_SV_LITE_H_INCLUDED
|
||||||
#define 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
|
# define nssv_CONFIG_NO_STREAM_INSERTION 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||||
|
# define nssv_CONFIG_CONSTEXPR11_STD_SEARCH 1
|
||||||
|
#endif
|
||||||
|
|
||||||
// Control presence of exception handling (try and auto discover):
|
// Control presence of exception handling (try and auto discover):
|
||||||
|
|
||||||
#ifndef nssv_CONFIG_NO_EXCEPTIONS
|
#ifndef nssv_CONFIG_NO_EXCEPTIONS
|
||||||
@@ -786,7 +790,7 @@ using std::operator<<;
|
|||||||
# define nssv_HAS_CPP0X 0
|
# define nssv_HAS_CPP0X 0
|
||||||
#endif
|
#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
|
#if nssv_COMPILER_MSVC_VER >= 1900
|
||||||
# undef nssv_CPP11_OR_GREATER
|
# undef nssv_CPP11_OR_GREATER
|
||||||
@@ -953,9 +957,9 @@ using std::operator<<;
|
|||||||
# pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
|
# pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
|
||||||
# pragma clang diagnostic push
|
# pragma clang diagnostic push
|
||||||
# pragma clang diagnostic ignored "-Wuser-defined-literals"
|
# pragma clang diagnostic ignored "-Wuser-defined-literals"
|
||||||
#elif defined(__GNUC__)
|
#elif nssv_COMPILER_GNUC_VERSION >= 480
|
||||||
# pragma GCC diagnostic push
|
# pragma GCC diagnostic push
|
||||||
# pragma GCC diagnostic ignored "-Wliteral-suffix"
|
# pragma GCC diagnostic ignored "-Wliteral-suffix"
|
||||||
#endif // __clang__
|
#endif // __clang__
|
||||||
|
|
||||||
#if nssv_COMPILER_MSVC_VERSION >= 140
|
#if nssv_COMPILER_MSVC_VERSION >= 140
|
||||||
@@ -970,8 +974,8 @@ using std::operator<<;
|
|||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
# define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
|
# define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
|
||||||
#elif defined(__GNUC__)
|
#elif nssv_COMPILER_GNUC_VERSION >= 480
|
||||||
# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
|
# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
|
||||||
#elif nssv_COMPILER_MSVC_VERSION >= 140
|
#elif nssv_COMPILER_MSVC_VERSION >= 140
|
||||||
# define nssv_RESTORE_WARNINGS() __pragma(warning(pop ))
|
# define nssv_RESTORE_WARNINGS() __pragma(warning(pop ))
|
||||||
#else
|
#else
|
||||||
@@ -1086,12 +1090,31 @@ constexpr const CharT* search( basic_string_view<CharT, Traits> haystack, basic_
|
|||||||
|
|
||||||
// non-recursive:
|
// non-recursive:
|
||||||
|
|
||||||
|
#if nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||||
|
|
||||||
template< class CharT, class Traits = std::char_traits<CharT> >
|
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 )
|
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() );
|
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 // OPTIMIZE
|
||||||
#endif // nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
|
#endif // nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
|
||||||
|
|
||||||
@@ -1364,7 +1387,7 @@ public:
|
|||||||
|
|
||||||
// find(), 4x:
|
// 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 )
|
return assert( v.size() == 0 || v.data() != nssv_nullptr )
|
||||||
, pos >= size()
|
, pos >= size()
|
||||||
@@ -9025,11 +9048,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
|||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
/** @private */
|
/** @private */
|
||||||
template<typename W>
|
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
if (parse_float_fallback(src, answer)) {
|
||||||
double d;
|
|
||||||
if (parse_float_fallback(src, &d)) {
|
|
||||||
writer.append_double(d);
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return INVALID_NUMBER(src);
|
return INVALID_NUMBER(src);
|
||||||
@@ -9053,13 +9073,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
|||||||
// 10000000000000000000000000000000000000000000e+308
|
// 10000000000000000000000000000000000000000000e+308
|
||||||
// 3.1415926535897932384626433832795028841971693993751
|
// 3.1415926535897932384626433832795028841971693993751
|
||||||
//
|
//
|
||||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
// it gets slow.
|
||||||
// This is what forces the skip_double, as well.
|
double d;
|
||||||
error_code error = slow_float_parsing(src, writer);
|
error_code error = slow_float_parsing(src, &d);
|
||||||
writer.skip_double();
|
writer.append_double(d);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||||
@@ -10852,7 +10872,7 @@ namespace simdjson {
|
|||||||
namespace arm64 {
|
namespace arm64 {
|
||||||
namespace {
|
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);
|
simdjson_inline bool is_ascii(const simd8x64<uint8_t>& input);
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
@@ -11419,7 +11439,7 @@ using namespace simd;
|
|||||||
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
||||||
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
||||||
simd8<uint8_t> prev3 = input.prev<3>(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);
|
simd8<uint8_t> must23_80 = must23 & uint8_t(0x80);
|
||||||
return must23_80 ^ sc;
|
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;
|
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) {
|
simdjson_inline simd8<uint8_t> 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<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-0x80); // Only 111_____ will be >= 0x80
|
||||||
simd8<bool> is_fourth_byte = prev3 >= uint8_t(0xf0u);
|
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||||
return is_third_byte ^ is_fourth_byte;
|
return is_third_byte | is_fourth_byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
@@ -14823,11 +14843,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
|||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
/** @private */
|
/** @private */
|
||||||
template<typename W>
|
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
if (parse_float_fallback(src, answer)) {
|
||||||
double d;
|
|
||||||
if (parse_float_fallback(src, &d)) {
|
|
||||||
writer.append_double(d);
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return INVALID_NUMBER(src);
|
return INVALID_NUMBER(src);
|
||||||
@@ -14851,13 +14868,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
|||||||
// 10000000000000000000000000000000000000000000e+308
|
// 10000000000000000000000000000000000000000000e+308
|
||||||
// 3.1415926535897932384626433832795028841971693993751
|
// 3.1415926535897932384626433832795028841971693993751
|
||||||
//
|
//
|
||||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
// it gets slow.
|
||||||
// This is what forces the skip_double, as well.
|
double d;
|
||||||
error_code error = slow_float_parsing(src, writer);
|
error_code error = slow_float_parsing(src, &d);
|
||||||
writer.skip_double();
|
writer.append_double(d);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||||
@@ -19226,11 +19243,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
|||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
/** @private */
|
/** @private */
|
||||||
template<typename W>
|
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
if (parse_float_fallback(src, answer)) {
|
||||||
double d;
|
|
||||||
if (parse_float_fallback(src, &d)) {
|
|
||||||
writer.append_double(d);
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return INVALID_NUMBER(src);
|
return INVALID_NUMBER(src);
|
||||||
@@ -19254,13 +19268,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
|||||||
// 10000000000000000000000000000000000000000000e+308
|
// 10000000000000000000000000000000000000000000e+308
|
||||||
// 3.1415926535897932384626433832795028841971693993751
|
// 3.1415926535897932384626433832795028841971693993751
|
||||||
//
|
//
|
||||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
// it gets slow.
|
||||||
// This is what forces the skip_double, as well.
|
double d;
|
||||||
error_code error = slow_float_parsing(src, writer);
|
error_code error = slow_float_parsing(src, &d);
|
||||||
writer.skip_double();
|
writer.append_double(d);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||||
@@ -20930,7 +20944,7 @@ namespace simdjson {
|
|||||||
namespace haswell {
|
namespace haswell {
|
||||||
namespace {
|
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);
|
simdjson_inline bool is_ascii(const simd8x64<uint8_t>& input);
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
@@ -21497,7 +21511,7 @@ using namespace simd;
|
|||||||
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
||||||
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
||||||
simd8<uint8_t> prev3 = input.prev<3>(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);
|
simd8<uint8_t> must23_80 = must23 & uint8_t(0x80);
|
||||||
return must23_80 ^ sc;
|
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);
|
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) {
|
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-1); // Only 111_____ will be > 0
|
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-1); // Only 1111____ will be > 0
|
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
return is_third_byte | is_fourth_byte;
|
||||||
return simd8<int8_t>(is_third_byte | is_fourth_byte) > int8_t(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
@@ -25390,11 +25403,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
|||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
/** @private */
|
/** @private */
|
||||||
template<typename W>
|
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
if (parse_float_fallback(src, answer)) {
|
||||||
double d;
|
|
||||||
if (parse_float_fallback(src, &d)) {
|
|
||||||
writer.append_double(d);
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return INVALID_NUMBER(src);
|
return INVALID_NUMBER(src);
|
||||||
@@ -25418,13 +25428,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
|||||||
// 10000000000000000000000000000000000000000000e+308
|
// 10000000000000000000000000000000000000000000e+308
|
||||||
// 3.1415926535897932384626433832795028841971693993751
|
// 3.1415926535897932384626433832795028841971693993751
|
||||||
//
|
//
|
||||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
// it gets slow.
|
||||||
// This is what forces the skip_double, as well.
|
double d;
|
||||||
error_code error = slow_float_parsing(src, writer);
|
error_code error = slow_float_parsing(src, &d);
|
||||||
writer.skip_double();
|
writer.append_double(d);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||||
@@ -27092,7 +27102,7 @@ namespace simdjson {
|
|||||||
namespace icelake {
|
namespace icelake {
|
||||||
namespace {
|
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);
|
simdjson_inline bool is_ascii(const simd8x64<uint8_t>& input);
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
@@ -27659,7 +27669,7 @@ using namespace simd;
|
|||||||
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
||||||
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
||||||
simd8<uint8_t> prev3 = input.prev<3>(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);
|
simd8<uint8_t> must23_80 = must23 & uint8_t(0x80);
|
||||||
return must23_80 ^ sc;
|
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);
|
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) {
|
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-1); // Only 111_____ will be > 0
|
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-1); // Only 1111____ will be > 0
|
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
return is_third_byte | is_fourth_byte;
|
||||||
return simd8<int8_t>(is_third_byte | is_fourth_byte) > int8_t(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
@@ -31710,11 +31719,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
|||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
/** @private */
|
/** @private */
|
||||||
template<typename W>
|
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
if (parse_float_fallback(src, answer)) {
|
||||||
double d;
|
|
||||||
if (parse_float_fallback(src, &d)) {
|
|
||||||
writer.append_double(d);
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return INVALID_NUMBER(src);
|
return INVALID_NUMBER(src);
|
||||||
@@ -31738,13 +31744,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
|||||||
// 10000000000000000000000000000000000000000000e+308
|
// 10000000000000000000000000000000000000000000e+308
|
||||||
// 3.1415926535897932384626433832795028841971693993751
|
// 3.1415926535897932384626433832795028841971693993751
|
||||||
//
|
//
|
||||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
// it gets slow.
|
||||||
// This is what forces the skip_double, as well.
|
double d;
|
||||||
error_code error = slow_float_parsing(src, writer);
|
error_code error = slow_float_parsing(src, &d);
|
||||||
writer.skip_double();
|
writer.append_double(d);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||||
@@ -33525,7 +33531,7 @@ namespace simdjson {
|
|||||||
namespace ppc64 {
|
namespace ppc64 {
|
||||||
namespace {
|
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);
|
simdjson_inline bool is_ascii(const simd8x64<uint8_t>& input);
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
@@ -34092,7 +34098,7 @@ using namespace simd;
|
|||||||
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
||||||
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
||||||
simd8<uint8_t> prev3 = input.prev<3>(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);
|
simd8<uint8_t> must23_80 = must23 & uint8_t(0x80);
|
||||||
return must23_80 ^ sc;
|
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);
|
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) {
|
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-1); // Only 111_____ will be > 0
|
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-1); // Only 1111____ will be > 0
|
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
return is_third_byte | is_fourth_byte;
|
||||||
return simd8<int8_t>(is_third_byte | is_fourth_byte) > int8_t(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
@@ -38396,11 +38401,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
|||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
/** @private */
|
/** @private */
|
||||||
template<typename W>
|
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
if (parse_float_fallback(src, answer)) {
|
||||||
double d;
|
|
||||||
if (parse_float_fallback(src, &d)) {
|
|
||||||
writer.append_double(d);
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return INVALID_NUMBER(src);
|
return INVALID_NUMBER(src);
|
||||||
@@ -38424,13 +38426,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
|||||||
// 10000000000000000000000000000000000000000000e+308
|
// 10000000000000000000000000000000000000000000e+308
|
||||||
// 3.1415926535897932384626433832795028841971693993751
|
// 3.1415926535897932384626433832795028841971693993751
|
||||||
//
|
//
|
||||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
// it gets slow.
|
||||||
// This is what forces the skip_double, as well.
|
double d;
|
||||||
error_code error = slow_float_parsing(src, writer);
|
error_code error = slow_float_parsing(src, &d);
|
||||||
writer.skip_double();
|
writer.append_double(d);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||||
@@ -40532,7 +40534,7 @@ namespace simdjson {
|
|||||||
namespace westmere {
|
namespace westmere {
|
||||||
namespace {
|
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);
|
simdjson_inline bool is_ascii(const simd8x64<uint8_t>& input);
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
@@ -41099,7 +41101,7 @@ using namespace simd;
|
|||||||
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
||||||
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
||||||
simd8<uint8_t> prev3 = input.prev<3>(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);
|
simd8<uint8_t> must23_80 = must23 & uint8_t(0x80);
|
||||||
return must23_80 ^ sc;
|
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);
|
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) {
|
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-1); // Only 111_____ will be > 0
|
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-1); // Only 1111____ will be > 0
|
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
return is_third_byte | is_fourth_byte;
|
||||||
return simd8<int8_t>(is_third_byte | is_fourth_byte) > int8_t(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|||||||
+141
-97
@@ -1,4 +1,4 @@
|
|||||||
/* auto-generated on 2023-12-07 12:42:28 -0500. Do not edit! */
|
/* auto-generated on 2024-01-28 12:42:59 -0500. Do not edit! */
|
||||||
/* including simdjson.h: */
|
/* including simdjson.h: */
|
||||||
/* begin file simdjson.h */
|
/* begin file simdjson.h */
|
||||||
#ifndef SIMDJSON_H
|
#ifndef SIMDJSON_H
|
||||||
@@ -545,7 +545,7 @@ SIMDJSON_PUSH_DISABLE_ALL_WARNINGS
|
|||||||
// Distributed under the Boost Software License, Version 1.0.
|
// 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)
|
// (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
|
#ifndef NONSTD_SV_LITE_H_INCLUDED
|
||||||
#define 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
|
# define nssv_CONFIG_NO_STREAM_INSERTION 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||||
|
# define nssv_CONFIG_CONSTEXPR11_STD_SEARCH 1
|
||||||
|
#endif
|
||||||
|
|
||||||
// Control presence of exception handling (try and auto discover):
|
// Control presence of exception handling (try and auto discover):
|
||||||
|
|
||||||
#ifndef nssv_CONFIG_NO_EXCEPTIONS
|
#ifndef nssv_CONFIG_NO_EXCEPTIONS
|
||||||
@@ -806,7 +810,7 @@ using std::operator<<;
|
|||||||
# define nssv_HAS_CPP0X 0
|
# define nssv_HAS_CPP0X 0
|
||||||
#endif
|
#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
|
#if nssv_COMPILER_MSVC_VER >= 1900
|
||||||
# undef nssv_CPP11_OR_GREATER
|
# undef nssv_CPP11_OR_GREATER
|
||||||
@@ -973,9 +977,9 @@ using std::operator<<;
|
|||||||
# pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
|
# pragma clang diagnostic ignored "-Wreserved-user-defined-literal"
|
||||||
# pragma clang diagnostic push
|
# pragma clang diagnostic push
|
||||||
# pragma clang diagnostic ignored "-Wuser-defined-literals"
|
# pragma clang diagnostic ignored "-Wuser-defined-literals"
|
||||||
#elif defined(__GNUC__)
|
#elif nssv_COMPILER_GNUC_VERSION >= 480
|
||||||
# pragma GCC diagnostic push
|
# pragma GCC diagnostic push
|
||||||
# pragma GCC diagnostic ignored "-Wliteral-suffix"
|
# pragma GCC diagnostic ignored "-Wliteral-suffix"
|
||||||
#endif // __clang__
|
#endif // __clang__
|
||||||
|
|
||||||
#if nssv_COMPILER_MSVC_VERSION >= 140
|
#if nssv_COMPILER_MSVC_VERSION >= 140
|
||||||
@@ -990,8 +994,8 @@ using std::operator<<;
|
|||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
# define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
|
# define nssv_RESTORE_WARNINGS() _Pragma("clang diagnostic pop")
|
||||||
#elif defined(__GNUC__)
|
#elif nssv_COMPILER_GNUC_VERSION >= 480
|
||||||
# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
|
# define nssv_RESTORE_WARNINGS() _Pragma("GCC diagnostic pop")
|
||||||
#elif nssv_COMPILER_MSVC_VERSION >= 140
|
#elif nssv_COMPILER_MSVC_VERSION >= 140
|
||||||
# define nssv_RESTORE_WARNINGS() __pragma(warning(pop ))
|
# define nssv_RESTORE_WARNINGS() __pragma(warning(pop ))
|
||||||
#else
|
#else
|
||||||
@@ -1106,12 +1110,31 @@ constexpr const CharT* search( basic_string_view<CharT, Traits> haystack, basic_
|
|||||||
|
|
||||||
// non-recursive:
|
// non-recursive:
|
||||||
|
|
||||||
|
#if nssv_CONFIG_CONSTEXPR11_STD_SEARCH
|
||||||
|
|
||||||
template< class CharT, class Traits = std::char_traits<CharT> >
|
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 )
|
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() );
|
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 // OPTIMIZE
|
||||||
#endif // nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
|
#endif // nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
|
||||||
|
|
||||||
@@ -1384,7 +1407,7 @@ public:
|
|||||||
|
|
||||||
// find(), 4x:
|
// 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 )
|
return assert( v.size() == 0 || v.data() != nssv_nullptr )
|
||||||
, pos >= size()
|
, pos >= size()
|
||||||
@@ -2321,7 +2344,7 @@ namespace std {
|
|||||||
#define SIMDJSON_SIMDJSON_VERSION_H
|
#define SIMDJSON_SIMDJSON_VERSION_H
|
||||||
|
|
||||||
/** The version of simdjson being used (major.minor.revision) */
|
/** The version of simdjson being used (major.minor.revision) */
|
||||||
#define SIMDJSON_VERSION "3.6.3"
|
#define SIMDJSON_VERSION "3.6.4"
|
||||||
|
|
||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
enum {
|
enum {
|
||||||
@@ -2336,7 +2359,7 @@ enum {
|
|||||||
/**
|
/**
|
||||||
* The revision (major.minor.REVISION) of simdjson being used.
|
* The revision (major.minor.REVISION) of simdjson being used.
|
||||||
*/
|
*/
|
||||||
SIMDJSON_VERSION_REVISION = 3
|
SIMDJSON_VERSION_REVISION = 4
|
||||||
};
|
};
|
||||||
} // namespace simdjson
|
} // 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) & noexcept;
|
||||||
inline simdjson_result<element> load(const std::string &path) && = delete ;
|
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.
|
* 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. "
|
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), "
|
"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). "
|
"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.");
|
"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 {
|
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;
|
size_t len;
|
||||||
auto _error = read_file(path).get(len);
|
auto _error = read_file(path).get(len);
|
||||||
if (_error) { return _error; }
|
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 {
|
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
|
} // unnamed namespace
|
||||||
|
|
||||||
/** @private */
|
/** @private */
|
||||||
template<typename W>
|
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
if (parse_float_fallback(src, answer)) {
|
||||||
double d;
|
|
||||||
if (parse_float_fallback(src, &d)) {
|
|
||||||
writer.append_double(d);
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return INVALID_NUMBER(src);
|
return INVALID_NUMBER(src);
|
||||||
@@ -12137,13 +12208,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
|||||||
// 10000000000000000000000000000000000000000000e+308
|
// 10000000000000000000000000000000000000000000e+308
|
||||||
// 3.1415926535897932384626433832795028841971693993751
|
// 3.1415926535897932384626433832795028841971693993751
|
||||||
//
|
//
|
||||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
// it gets slow.
|
||||||
// This is what forces the skip_double, as well.
|
double d;
|
||||||
error_code error = slow_float_parsing(src, writer);
|
error_code error = slow_float_parsing(src, &d);
|
||||||
writer.skip_double();
|
writer.append_double(d);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||||
@@ -14161,11 +14232,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
|||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
/** @private */
|
/** @private */
|
||||||
template<typename W>
|
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
if (parse_float_fallback(src, answer)) {
|
||||||
double d;
|
|
||||||
if (parse_float_fallback(src, &d)) {
|
|
||||||
writer.append_double(d);
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return INVALID_NUMBER(src);
|
return INVALID_NUMBER(src);
|
||||||
@@ -14189,13 +14257,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
|||||||
// 10000000000000000000000000000000000000000000e+308
|
// 10000000000000000000000000000000000000000000e+308
|
||||||
// 3.1415926535897932384626433832795028841971693993751
|
// 3.1415926535897932384626433832795028841971693993751
|
||||||
//
|
//
|
||||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
// it gets slow.
|
||||||
// This is what forces the skip_double, as well.
|
double d;
|
||||||
error_code error = slow_float_parsing(src, writer);
|
error_code error = slow_float_parsing(src, &d);
|
||||||
writer.skip_double();
|
writer.append_double(d);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||||
@@ -16705,11 +16773,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
|||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
/** @private */
|
/** @private */
|
||||||
template<typename W>
|
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
if (parse_float_fallback(src, answer)) {
|
||||||
double d;
|
|
||||||
if (parse_float_fallback(src, &d)) {
|
|
||||||
writer.append_double(d);
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return INVALID_NUMBER(src);
|
return INVALID_NUMBER(src);
|
||||||
@@ -16733,13 +16798,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
|||||||
// 10000000000000000000000000000000000000000000e+308
|
// 10000000000000000000000000000000000000000000e+308
|
||||||
// 3.1415926535897932384626433832795028841971693993751
|
// 3.1415926535897932384626433832795028841971693993751
|
||||||
//
|
//
|
||||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
// it gets slow.
|
||||||
// This is what forces the skip_double, as well.
|
double d;
|
||||||
error_code error = slow_float_parsing(src, writer);
|
error_code error = slow_float_parsing(src, &d);
|
||||||
writer.skip_double();
|
writer.append_double(d);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||||
@@ -19248,11 +19313,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
|||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
/** @private */
|
/** @private */
|
||||||
template<typename W>
|
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
if (parse_float_fallback(src, answer)) {
|
||||||
double d;
|
|
||||||
if (parse_float_fallback(src, &d)) {
|
|
||||||
writer.append_double(d);
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return INVALID_NUMBER(src);
|
return INVALID_NUMBER(src);
|
||||||
@@ -19276,13 +19338,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
|||||||
// 10000000000000000000000000000000000000000000e+308
|
// 10000000000000000000000000000000000000000000e+308
|
||||||
// 3.1415926535897932384626433832795028841971693993751
|
// 3.1415926535897932384626433832795028841971693993751
|
||||||
//
|
//
|
||||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
// it gets slow.
|
||||||
// This is what forces the skip_double, as well.
|
double d;
|
||||||
error_code error = slow_float_parsing(src, writer);
|
error_code error = slow_float_parsing(src, &d);
|
||||||
writer.skip_double();
|
writer.append_double(d);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||||
@@ -21906,11 +21968,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
|||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
/** @private */
|
/** @private */
|
||||||
template<typename W>
|
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
if (parse_float_fallback(src, answer)) {
|
||||||
double d;
|
|
||||||
if (parse_float_fallback(src, &d)) {
|
|
||||||
writer.append_double(d);
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return INVALID_NUMBER(src);
|
return INVALID_NUMBER(src);
|
||||||
@@ -21934,13 +21993,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
|||||||
// 10000000000000000000000000000000000000000000e+308
|
// 10000000000000000000000000000000000000000000e+308
|
||||||
// 3.1415926535897932384626433832795028841971693993751
|
// 3.1415926535897932384626433832795028841971693993751
|
||||||
//
|
//
|
||||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
// it gets slow.
|
||||||
// This is what forces the skip_double, as well.
|
double d;
|
||||||
error_code error = slow_float_parsing(src, writer);
|
error_code error = slow_float_parsing(src, &d);
|
||||||
writer.skip_double();
|
writer.append_double(d);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||||
@@ -24887,11 +24946,8 @@ simdjson_inline size_t significant_digits(const uint8_t * start_digits, size_t d
|
|||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
/** @private */
|
/** @private */
|
||||||
template<typename W>
|
static error_code slow_float_parsing(simdjson_unused const uint8_t * src, double* answer) {
|
||||||
error_code slow_float_parsing(simdjson_unused const uint8_t * src, W writer) {
|
if (parse_float_fallback(src, answer)) {
|
||||||
double d;
|
|
||||||
if (parse_float_fallback(src, &d)) {
|
|
||||||
writer.append_double(d);
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
return INVALID_NUMBER(src);
|
return INVALID_NUMBER(src);
|
||||||
@@ -24915,13 +24971,13 @@ simdjson_inline error_code write_float(const uint8_t *const src, bool negative,
|
|||||||
// 10000000000000000000000000000000000000000000e+308
|
// 10000000000000000000000000000000000000000000e+308
|
||||||
// 3.1415926535897932384626433832795028841971693993751
|
// 3.1415926535897932384626433832795028841971693993751
|
||||||
//
|
//
|
||||||
// NOTE: This makes a *copy* of the writer and passes it to slow_float_parsing. This happens
|
// NOTE: We do not pass a reference to the to slow_float_parsing. If we passed our writer
|
||||||
// because slow_float_parsing is a non-inlined function. If we passed our writer reference to
|
// reference to it, it would force it to be stored in memory, preventing the compiler from
|
||||||
// it, it would force it to be stored in memory, preventing the compiler from picking it apart
|
// picking it apart and putting into registers. i.e. if we pass it as reference,
|
||||||
// and putting into registers. i.e. if we pass it as reference, it gets slow.
|
// it gets slow.
|
||||||
// This is what forces the skip_double, as well.
|
double d;
|
||||||
error_code error = slow_float_parsing(src, writer);
|
error_code error = slow_float_parsing(src, &d);
|
||||||
writer.skip_double();
|
writer.append_double(d);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
// NOTE: it's weird that the simdjson_unlikely() only wraps half the if, but it seems to get slower any other
|
||||||
@@ -28613,8 +28669,6 @@ protected:
|
|||||||
*/
|
*/
|
||||||
friend class value_iterator;
|
friend class value_iterator;
|
||||||
template<typename W>
|
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);
|
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>
|
template<typename W>
|
||||||
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
||||||
@@ -38534,8 +38588,6 @@ protected:
|
|||||||
*/
|
*/
|
||||||
friend class value_iterator;
|
friend class value_iterator;
|
||||||
template<typename W>
|
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);
|
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>
|
template<typename W>
|
||||||
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
||||||
@@ -48947,8 +48999,6 @@ protected:
|
|||||||
*/
|
*/
|
||||||
friend class value_iterator;
|
friend class value_iterator;
|
||||||
template<typename W>
|
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);
|
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>
|
template<typename W>
|
||||||
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
||||||
@@ -59359,8 +59409,6 @@ protected:
|
|||||||
*/
|
*/
|
||||||
friend class value_iterator;
|
friend class value_iterator;
|
||||||
template<typename W>
|
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);
|
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>
|
template<typename W>
|
||||||
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
||||||
@@ -69886,8 +69934,6 @@ protected:
|
|||||||
*/
|
*/
|
||||||
friend class value_iterator;
|
friend class value_iterator;
|
||||||
template<typename W>
|
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);
|
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>
|
template<typename W>
|
||||||
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
||||||
@@ -80736,8 +80782,6 @@ protected:
|
|||||||
*/
|
*/
|
||||||
friend class value_iterator;
|
friend class value_iterator;
|
||||||
template<typename W>
|
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);
|
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>
|
template<typename W>
|
||||||
friend error_code numberparsing::parse_number(const uint8_t *const src, W &writer);
|
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;
|
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) {
|
simdjson_inline simd8<uint8_t> 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<uint8_t> is_third_byte = prev2.saturating_sub(0xe0u-0x80); // Only 111_____ will be >= 0x80
|
||||||
simd8<bool> is_fourth_byte = prev3 >= uint8_t(0xf0u);
|
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||||
return is_third_byte ^ is_fourth_byte;
|
return is_third_byte | is_fourth_byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace simdjson {
|
|||||||
namespace SIMDJSON_IMPLEMENTATION {
|
namespace SIMDJSON_IMPLEMENTATION {
|
||||||
namespace {
|
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);
|
simdjson_inline bool is_ascii(const simd8x64<uint8_t>& input);
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ using namespace simd;
|
|||||||
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
const simd8<uint8_t> prev_input, const simd8<uint8_t> sc) {
|
||||||
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
simd8<uint8_t> prev2 = input.prev<2>(prev_input);
|
||||||
simd8<uint8_t> prev3 = input.prev<3>(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);
|
simd8<uint8_t> must23_80 = must23 & uint8_t(0x80);
|
||||||
return must23_80 ^ sc;
|
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);
|
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) {
|
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-1); // Only 111_____ will be > 0
|
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-1); // Only 1111____ will be > 0
|
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
return is_third_byte | is_fourth_byte;
|
||||||
return simd8<int8_t>(is_third_byte | is_fourth_byte) > int8_t(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // 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);
|
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) {
|
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-1); // Only 111_____ will be > 0
|
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-1); // Only 1111____ will be > 0
|
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
return is_third_byte | is_fourth_byte;
|
||||||
return simd8<int8_t>(is_third_byte | is_fourth_byte) > int8_t(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // 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);
|
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) {
|
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-1); // Only 111_____ will be > 0
|
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-1); // Only 1111____ will be > 0
|
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
return is_third_byte | is_fourth_byte;
|
||||||
return simd8<int8_t>(is_third_byte | is_fourth_byte) > int8_t(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // 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);
|
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) {
|
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-1); // Only 111_____ will be > 0
|
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-1); // Only 1111____ will be > 0
|
simd8<uint8_t> is_fourth_byte = prev3.saturating_sub(0xf0u-0x80); // Only 1111____ will be >= 0x80
|
||||||
// Caller requires a bool (all 1's). All values resulting from the subtraction will be <= 64, so signed comparison is fine.
|
return is_third_byte | is_fourth_byte;
|
||||||
return simd8<int8_t>(is_third_byte | is_fourth_byte) > int8_t(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|||||||
@@ -452,14 +452,18 @@ namespace parse_api_tests {
|
|||||||
element doc_root1 = parser.parse_into_document(doc, input);
|
element doc_root1 = parser.parse_into_document(doc, input);
|
||||||
if(simdjson::to_string(doc_root1) != "[1,2,3]") { return false; }
|
if(simdjson::to_string(doc_root1) != "[1,2,3]") { return false; }
|
||||||
//... doc_root1 is a pointer inside doc
|
//... 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
|
//... 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:
|
// Here let us take moving the document:
|
||||||
dom::document docm = std::move(doc);
|
dom::document docm = std::move(doc);
|
||||||
element doc_root3 = docm.root();
|
element doc_root4 = docm.root();
|
||||||
if(simdjson::to_string(doc_root3) != "[1,2,3]") { return false; }
|
if(simdjson::to_string(doc_root4) != "[1,2,3]") { return false; }
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -278,6 +278,19 @@ namespace number_tests {
|
|||||||
TEST_SUCCEED();
|
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() {
|
bool issue1878() {
|
||||||
TEST_START();
|
TEST_START();
|
||||||
ondemand::parser parser;
|
ondemand::parser parser;
|
||||||
@@ -429,7 +442,8 @@ namespace number_tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool run() {
|
bool run() {
|
||||||
return issue2093() &&
|
return issue2099() &&
|
||||||
|
issue2093() &&
|
||||||
issue2045() &&
|
issue2045() &&
|
||||||
issue2017() &&
|
issue2017() &&
|
||||||
issue_1898() &&
|
issue_1898() &&
|
||||||
|
|||||||
Reference in New Issue
Block a user