Compare commits

..

1 Commits

Author SHA1 Message Date
Daniel Lemire 44c69f64f6 bumping up cmake 2026-03-25 10:21:18 -04:00
114 changed files with 11224 additions and 14883 deletions
+1 -1
View File
@@ -24,6 +24,6 @@ jobs:
apt-get update -q -y apt-get update -q -y
apt-get install -y cmake make g++ apt-get install -y cmake make g++
run: | run: |
cmake -DSIMDJSON_SANITIZE_UNDEFINED=ON -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -B build cmake -DSIMDJSON_SANITIZE_UNDEFINED=ON -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
cmake --build build -j=2 cmake --build build -j=2
ctest --output-on-failure --test-dir build ctest --output-on-failure --test-dir build
+3 -3
View File
@@ -18,13 +18,13 @@ jobs:
run: | run: |
mkdir builddebug && mkdir builddebug &&
cd builddebug && cd builddebug &&
cmake -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF .. && cmake -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . && cmake --build . &&
ctest --output-on-failure -LE explicitonly -j && ctest --output-on-failure -LE explicitonly -j &&
cd .. && cd .. &&
mkdir build && mkdir build &&
cd build && cd build &&
cmake -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination .. && cmake -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . && cmake --build . &&
ctest --output-on-failure -LE explicitonly -j && ctest --output-on-failure -LE explicitonly -j &&
cmake --install . && cmake --install . &&
@@ -35,7 +35,7 @@ jobs:
run: | run: |
mkdir buildshared && mkdir buildshared &&
cd buildshared && cd buildshared &&
cmake -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX:PATH=destination .. && cmake -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX:PATH=destination -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . && cmake --build . &&
ctest --output-on-failure -LE explicitonly -j && ctest --output-on-failure -LE explicitonly -j &&
cmake --install . && cmake --install . &&
+1 -1
View File
@@ -43,6 +43,6 @@ jobs:
run: | run: |
mkdir build mkdir build
cd build cd build
cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_BUILD_TYPE=${{ matrix.type }} -DBUILD_SHARED_LIBS=OFF -DSIMDJSON_DO_NOT_USE_THREADS_NO_MATTER_WHAT=ON .. cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_BUILD_TYPE=${{ matrix.type }} -DBUILD_SHARED_LIBS=OFF -DSIMDJSON_DO_NOT_USE_THREADS_NO_MATTER_WHAT=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON ..
cmake --build . --verbose cmake --build . --verbose
ctest -j4 --output-on-failure -LE explicitonly ctest -j4 --output-on-failure -LE explicitonly
+1 -1
View File
@@ -24,6 +24,6 @@ jobs:
apt-get update -q -y apt-get update -q -y
apt-get install -y cmake make g++ apt-get install -y cmake make g++
run: | run: |
cmake -DCMAKE_BUILD_TYPE=Release -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -B build cmake -DCMAKE_BUILD_TYPE=Release -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
cmake --build build -j=2 cmake --build build -j=2
ctest --output-on-failure --test-dir build ctest --output-on-failure --test-dir build
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
- name: Build - name: Build
run: | run: |
CC=clang-18 CXX=clang++-18 CFLAGS="--target=riscv64-linux-gnu -march=rv64gcv_zvbb" CXXFLAGS="${CFLAGS}" \ CC=clang-18 CXX=clang++-18 CFLAGS="--target=riscv64-linux-gnu -march=rv64gcv_zvbb" CXXFLAGS="${CFLAGS}" \
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -B build cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
cmake --build build/ -j$(nproc) --config Release cmake --build build/ -j$(nproc) --config Release
- name: Test VLEN=1024 - name: Test VLEN=1024
run: | run: |
+2 -2
View File
@@ -20,7 +20,7 @@ jobs:
- name: Build - name: Build
run: | run: |
CC=clang-20 CXX=clang++-20 CFLAGS="--target=riscv64-linux-gnu -march=rv64gcv" CXXFLAGS="${CFLAGS}" \ CC=clang-20 CXX=clang++-20 CFLAGS="--target=riscv64-linux-gnu -march=rv64gcv" CXXFLAGS="${CFLAGS}" \
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -B build cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
cmake --build build/ -j$(nproc) --config Release cmake --build build/ -j$(nproc) --config Release
- name: Test VLEN=128 - name: Test VLEN=128
run: | run: |
@@ -30,7 +30,7 @@ jobs:
- name: Build VLS - name: Build VLS
run: | run: |
CC=clang-20 CXX=clang++-20 CFLAGS="--target=riscv64-linux-gnu -march=rv64gcv_zvl128b_zba_zbb_zbc -mrvv-vector-bits=zvl" CXXFLAGS="${CFLAGS}" \ CC=clang-20 CXX=clang++-20 CFLAGS="--target=riscv64-linux-gnu -march=rv64gcv_zvl128b_zba_zbb_zbc -mrvv-vector-bits=zvl" CXXFLAGS="${CFLAGS}" \
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -B build-vls cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build-vls
cmake --build build-vls/ -j$(nproc) --config Release cmake --build build-vls/ -j$(nproc) --config Release
- name: Test VLEN=128 VLS - name: Test VLEN=128 VLS
run: | run: |
+2 -2
View File
@@ -20,7 +20,7 @@ jobs:
- name: Build - name: Build
run: | run: |
CC=riscv64-linux-gnu-gcc-14 CXX=riscv64-linux-gnu-g++-14 CFLAGS=-march=rv64gcv CXXFLAGS="${CFLAGS}" \ CC=riscv64-linux-gnu-gcc-14 CXX=riscv64-linux-gnu-g++-14 CFLAGS=-march=rv64gcv CXXFLAGS="${CFLAGS}" \
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -B build cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
cmake --build build/ -j$(nproc) --config Release cmake --build build/ -j$(nproc) --config Release
- name: Test VLEN=256 - name: Test VLEN=256
run: | run: |
@@ -30,7 +30,7 @@ jobs:
- name: Build VLS - name: Build VLS
run: | run: |
CC=riscv64-linux-gnu-gcc-14 CXX=riscv64-linux-gnu-g++-14 CFLAGS="-march=rv64gcv_zvl256b -mrvv-vector-bits=zvl" CXXFLAGS="${CFLAGS}" \ CC=riscv64-linux-gnu-gcc-14 CXX=riscv64-linux-gnu-g++-14 CFLAGS="-march=rv64gcv_zvl256b -mrvv-vector-bits=zvl" CXXFLAGS="${CFLAGS}" \
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -B build-vls cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build-vls
cmake --build build-vls/ -j$(nproc) --config Release cmake --build build-vls/ -j$(nproc) --config Release
- name: Test VLEN=256 VLS - name: Test VLEN=256 VLS
run: | run: |
+2 -2
View File
@@ -20,7 +20,7 @@ jobs:
- name: Build - name: Build
run: | run: |
CC=clang-19 CXX=clang++-19 CFLAGS="--target=riscv64-linux-gnu -march=rv64gcv" CXXFLAGS="${CFLAGS}" \ CC=clang-19 CXX=clang++-19 CFLAGS="--target=riscv64-linux-gnu -march=rv64gcv" CXXFLAGS="${CFLAGS}" \
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -B build cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
cmake --build build/ -j$(nproc) --config Release cmake --build build/ -j$(nproc) --config Release
- name: Test VLEN=512 - name: Test VLEN=512
run: | run: |
@@ -30,7 +30,7 @@ jobs:
- name: Build VLS - name: Build VLS
run: | run: |
CC=clang-19 CXX=clang++-19 CFLAGS="--target=riscv64-linux-gnu -march=rv64gcv_zvl512b_zba_zbb_zbc -mrvv-vector-bits=zvl" CXXFLAGS="${CFLAGS}" \ CC=clang-19 CXX=clang++-19 CFLAGS="--target=riscv64-linux-gnu -march=rv64gcv_zvl512b_zba_zbb_zbc -mrvv-vector-bits=zvl" CXXFLAGS="${CFLAGS}" \
cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -B build-vls cmake --toolchain=cmake/toolchains-ci/riscv64-linux-gnu.cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build-vls
cmake --build build-vls/ -j$(nproc) --config Release cmake --build build-vls/ -j$(nproc) --config Release
- name: Test VLEN=512 VLS - name: Test VLEN=512 VLS
run: | run: |
+1 -1
View File
@@ -24,6 +24,6 @@ jobs:
apt-get update -q -y apt-get update -q -y
apt-get install -y cmake make g++ apt-get install -y cmake make g++
run: | run: |
cmake -DCMAKE_BUILD_TYPE=Release -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -B build cmake -DCMAKE_BUILD_TYPE=Release -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_COMPETITION=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
cmake --build build -j=2 cmake --build build -j=2
ctest --output-on-failure --test-dir build ctest --output-on-failure --test-dir build
+1 -1
View File
@@ -18,6 +18,6 @@ jobs:
run: | run: |
mkdir build && mkdir build &&
cd build && cd build &&
CXX=clang++-13 cmake -DSIMDJSON_DEVELOPER_MODE=ON .. && CXX=clang++-13 cmake -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . && cmake --build . &&
ctest --output-on-failure -LE explicitonly -j ctest --output-on-failure -LE explicitonly -j
@@ -19,6 +19,6 @@ jobs:
run: | run: |
mkdir build && mkdir build &&
cd build && cd build &&
CXX=g++-12 cmake -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GLIBCXX_ASSERTIONS=ON -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON .. && CXX=g++-12 cmake -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GLIBCXX_ASSERTIONS=ON -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . && cmake --build . &&
ctest . -E avoid_ ctest . -E avoid_
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
run: | run: |
mkdir build && mkdir build &&
cd build && cd build &&
CXX=g++-12 cmake -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_SANITIZE_THREADS=ON .. && CXX=g++-12 cmake -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_SANITIZE_THREADS=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . --target document_stream_tests --target ondemand_document_stream_tests --target parse_many_test && cmake --build . --target document_stream_tests --target ondemand_document_stream_tests --target parse_many_test &&
ctest --output-on-failure -R parse_many_test && ctest --output-on-failure -R parse_many_test &&
ctest --output-on-failure -R document_stream_tests ctest --output-on-failure -R document_stream_tests
+1 -1
View File
@@ -24,6 +24,6 @@ jobs:
run: | run: |
mkdir build && mkdir build &&
cd build && cd build &&
cmake -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_ENABLE_DOM_CHECKPERF=ON -DCMAKE_CXX_FLAGS="-Werror=old-style-cast -pedantic -Wpedantic" -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination .. && cmake -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_ENABLE_DOM_CHECKPERF=ON -DCMAKE_CXX_FLAGS="-Werror=old-style-cast -pedantic -Wpedantic" -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . --target checkperf && cmake --build . --target checkperf &&
ctest --output-on-failure -R checkperf ctest --output-on-failure -R checkperf
@@ -13,7 +13,7 @@ jobs:
steps: steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Prepare - name: Prepare
run: cmake -DSIMDJSON_CXX_STANDARD=20 -DSIMDJSON_EXCEPTIONS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -B build run: cmake -DSIMDJSON_CXX_STANDARD=20 -DSIMDJSON_EXCEPTIONS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
env: env:
CXX: ${{matrix.cxx}} CXX: ${{matrix.cxx}}
- name: Build - name: Build
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
steps: steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Prepare - name: Prepare
run: cmake -DSIMDJSON_CXX_STANDARD=20 -DSIMDJSON_DEVELOPER_MODE=ON -B build run: cmake -DSIMDJSON_CXX_STANDARD=20 -DSIMDJSON_DEVELOPER_MODE=ON -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
env: env:
CXX: ${{matrix.cxx}} CXX: ${{matrix.cxx}}
- name: Build - name: Build
+2 -2
View File
@@ -18,13 +18,13 @@ jobs:
run: | run: |
mkdir builddebug && mkdir builddebug &&
cd builddebug && cd builddebug &&
cmake -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_EXCEPTIONS=OFF -DBUILD_SHARED_LIBS=OFF .. && cmake -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_EXCEPTIONS=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . && cmake --build . &&
ctest --output-on-failure -LE explicitonly -j && ctest --output-on-failure -LE explicitonly -j &&
cd .. && cd .. &&
mkdir build && mkdir build &&
cd build && cd build &&
cmake -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_EXCEPTIONS=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination .. && cmake -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_EXCEPTIONS=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . && cmake --build . &&
ctest --output-on-failure -LE explicitonly -j && ctest --output-on-failure -LE explicitonly -j &&
make install && make install &&
+2 -2
View File
@@ -18,13 +18,13 @@ jobs:
run: | run: |
mkdir builddebug && mkdir builddebug &&
cd builddebug && cd builddebug &&
cmake -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_ENABLE_THREADS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF .. && cmake -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_ENABLE_THREADS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . && cmake --build . &&
ctest --output-on-failure -LE explicitonly -j && ctest --output-on-failure -LE explicitonly -j &&
cd .. && cd .. &&
mkdir build && mkdir build &&
cd build && cd build &&
cmake -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_ENABLE_THREADS=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination .. && cmake -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_ENABLE_THREADS=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . && cmake --build . &&
ctest --output-on-failure -LE explicitonly -j && ctest --output-on-failure -LE explicitonly -j &&
make install && make install &&
+2 -2
View File
@@ -18,7 +18,7 @@ jobs:
run: | run: |
mkdir builddebug && mkdir builddebug &&
cd builddebug && cd builddebug &&
cmake -DSIMDJSON_SANITIZE=ON -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF .. && cmake -DSIMDJSON_SANITIZE=ON -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . && cmake --build . &&
ctest --output-on-failure -LE explicitonly -j ctest --output-on-failure -LE explicitonly -j
ubuntu-build-undefined-sanitizer: ubuntu-build-undefined-sanitizer:
@@ -36,6 +36,6 @@ jobs:
run: | run: |
mkdir builddebugundefsani && mkdir builddebugundefsani &&
cd builddebugundefsani && cd builddebugundefsani &&
cmake -DSIMDJSON_SANITIZE_UNDEFINED=ON -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF .. && cmake -DSIMDJSON_SANITIZE_UNDEFINED=ON -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON .. &&
cmake --build . && cmake --build . &&
ctest --output-on-failure -LE explicitonly -j ctest --output-on-failure -LE explicitonly -j
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
steps: steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6 - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
- name: Prepare - name: Prepare
run: cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_SANITIZE=${{matrix.sanitizer}} -DBUILD_SHARED_LIBS=${{matrix.shared}} -B build run: cmake -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DSIMDJSON_DEVELOPER_MODE=ON -DSIMDJSON_SANITIZE=${{matrix.sanitizer}} -DBUILD_SHARED_LIBS=${{matrix.shared}} -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
env: env:
CXX: ${{matrix.cxx}} CXX: ${{matrix.cxx}}
- name: Build - name: Build
+1 -1
View File
@@ -17,5 +17,5 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Use cmake - name: Use cmake
run: | run: |
cmake -A ${{ matrix.arch }} -DCMAKE_SYSTEM_VERSION="10.0.22621.0" -DCMAKE_CROSSCOMPILING=1 -DSIMDJSON_DEVELOPER_MODE=ON -D SIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_EXCEPTIONS=OFF -B build && cmake -A ${{ matrix.arch }} -DCMAKE_SYSTEM_VERSION="10.0.22621.0" -DCMAKE_CROSSCOMPILING=1 -DSIMDJSON_DEVELOPER_MODE=ON -D SIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_EXCEPTIONS=OFF -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build &&
cmake --build build --verbose cmake --build build --verbose
+1 -1
View File
@@ -22,7 +22,7 @@ jobs:
uses: actions/checkout@v4 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}} -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
- name: Build Debug - name: Build Debug
run: cmake --build build --config Debug --verbose run: cmake --build build --config Debug --verbose
- name: Build Release - name: Build Release
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
uses: actions/checkout@v4 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 -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -B build
- name: Build - name: Build
run: cmake --build build --config ${{matrix.build_type}} --verbose run: cmake --build build --config ${{matrix.build_type}} --verbose
- name: Run tests - name: Run tests
+91 -150
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.14) cmake_minimum_required(VERSION 3.24)
# Build performance optimizations # Build performance optimizations
set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE BOOL "Export compile commands for faster IDE integration") set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE BOOL "Export compile commands for faster IDE integration")
@@ -12,7 +12,7 @@ endif()
project( project(
simdjson simdjson
# The version number is modified by tools/release.py # The version number is modified by tools/release.py
VERSION 4.6.1 VERSION 4.4.2
DESCRIPTION "Parsing gigabytes of JSON per second" DESCRIPTION "Parsing gigabytes of JSON per second"
HOMEPAGE_URL "https://simdjson.org/" HOMEPAGE_URL "https://simdjson.org/"
LANGUAGES CXX C LANGUAGES CXX C
@@ -29,8 +29,8 @@ string(
# ---- Options, variables ---- # ---- Options, variables ----
# These version numbers are modified by tools/release.py # These version numbers are modified by tools/release.py
set(SIMDJSON_LIB_VERSION "33.0.0" CACHE STRING "simdjson library version") set(SIMDJSON_LIB_VERSION "31.0.0" CACHE STRING "simdjson library version")
set(SIMDJSON_LIB_SOVERSION "33" CACHE STRING "simdjson library soversion") set(SIMDJSON_LIB_SOVERSION "31" CACHE STRING "simdjson library soversion")
option(SIMDJSON_BUILD_STATIC_LIB "Build simdjson_static library along with simdjson (only makes sense if BUILD_SHARED_LIBS=ON)" OFF) option(SIMDJSON_BUILD_STATIC_LIB "Build simdjson_static library along with simdjson (only makes sense if BUILD_SHARED_LIBS=ON)" OFF)
if(SIMDJSON_BUILD_STATIC_LIB AND NOT BUILD_SHARED_LIBS) if(SIMDJSON_BUILD_STATIC_LIB AND NOT BUILD_SHARED_LIBS)
@@ -52,20 +52,6 @@ if(SIMDJSON_DISABLE_DEPRECATED_API)
) )
endif() endif()
option(SIMDJSON_FEATURE_ONDEMAND_API "Enable ondemand API" ON)
option(SIMDJSON_FEATURE_DOM_API "Enable DOM API" ON)
option(SIMDJSON_FEATURE_BUILDER_API "Enable builder API" ON)
if(NOT SIMDJSON_FEATURE_ONDEMAND_API)
add_compile_definitions(SIMDJSON_FEATURE_ONDEMAND_API=0)
endif()
if(NOT SIMDJSON_FEATURE_DOM_API)
add_compile_definitions(SIMDJSON_FEATURE_DOM_API=0)
endif()
if(NOT SIMDJSON_FEATURE_BUILDER_API)
add_compile_definitions(SIMDJSON_FEATURE_BUILDER_API=0)
endif()
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.25.0") if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.25.0")
option(SIMDJSON_STATIC_REFLECTION "Enables static reflection (experimental), requires C++26" OFF) option(SIMDJSON_STATIC_REFLECTION "Enables static reflection (experimental), requires C++26" OFF)
else() else()
@@ -90,12 +76,9 @@ if(SIMDJSON_DEVELOPMENT_CHECKS)
endif() endif()
if(is_top_project) if(is_top_project)
option(SIMDJSON_INSTALL "Enable target install" ON)
option(SIMDJSON_DEVELOPER_MODE "Enable targets for developing simdjson" OFF) option(SIMDJSON_DEVELOPER_MODE "Enable targets for developing simdjson" OFF)
option(BUILD_SHARED_LIBS "Build simdjson as a shared library" OFF) option(BUILD_SHARED_LIBS "Build simdjson as a shared library" OFF)
option(SIMDJSON_SINGLEHEADER "Disable singleheader generation" ON) option(SIMDJSON_SINGLEHEADER "Disable singleheader generation" ON)
else()
option(SIMDJSON_INSTALL "Enable target install" ${BUILD_SHARED_LIBS})
endif() endif()
include(cmake/handle-deprecations.cmake) include(cmake/handle-deprecations.cmake)
@@ -109,16 +92,13 @@ add_library(simdjson ${SIMDJSON_SOURCES})
add_library(simdjson::simdjson ALIAS simdjson) add_library(simdjson::simdjson ALIAS simdjson)
set(SIMDJSON_LIBRARIES simdjson) set(SIMDJSON_LIBRARIES simdjson)
# Check for <bit> header compatibility
include(CheckIncludeFileCXX)
check_include_file_cxx(bit SIMDJSON_HAS_BIT_HEADER)
# Enable precompiled headers for faster builds # Enable precompiled headers for faster builds
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.16") if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.16")
set(SIMDJSON_PRECOMPILE_HEADERS target_precompile_headers(simdjson PRIVATE
<algorithm> <algorithm>
<array> <array>
<atomic> <atomic>
<bit>
<cassert> <cassert>
<cctype> <cctype>
<cerrno> <cerrno>
@@ -131,12 +111,6 @@ if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.16")
<utility> <utility>
<vector> <vector>
) )
if(SIMDJSON_HAS_BIT_HEADER)
list(APPEND SIMDJSON_PRECOMPILE_HEADERS <bit>)
endif()
target_precompile_headers(simdjson PRIVATE ${SIMDJSON_PRECOMPILE_HEADERS})
endif() endif()
if(SIMDJSON_BUILD_STATIC_LIB) if(SIMDJSON_BUILD_STATIC_LIB)
@@ -181,37 +155,13 @@ if(MSVC)
endif() endif()
endif() endif()
if(SIMDJSON_STATIC_REFLECTION) if(SIMDJSON_STATIC_REFLECTION)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION MATCHES "^21")
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} --version
OUTPUT_VARIABLE CLANG_VERSION_OUTPUT
ERROR_VARIABLE CLANG_VERSION_ERROR
RESULT_VARIABLE CLANG_VERSION_RESULT
)
if(CLANG_VERSION_RESULT EQUAL 0 AND CLANG_VERSION_OUTPUT MATCHES "https://github.com/bloomberg/clang-p2996.git")
set(IS_BLOOMBERG_P2996_CLANG ON)
message(STATUS "Using Bloomberg P2996 Clang fork")
endif()
endif()
# We would like to require C++26, but no compiler supports that! # We would like to require C++26, but no compiler supports that!
# This is a hack: # This is a hack:
if(IS_BLOOMBERG_P2996_CLANG)
simdjson_add_props( simdjson_add_props(
target_compile_options PUBLIC target_compile_options PUBLIC
-freflection -fexpansion-statements -stdlib=libc++ -std=c++26 -freflection -fexpansion-statements -stdlib=libc++ -std=c++26
) )
else()
simdjson_add_props(
target_compile_options PUBLIC
-freflection -std=c++26
)
endif()
else() else()
simdjson_add_props(target_compile_features PUBLIC cxx_std_11) simdjson_add_props(target_compile_features PUBLIC cxx_std_11)
endif() endif()
@@ -266,89 +216,87 @@ endif()
# ---- Install rules ---- # ---- Install rules ----
if(SIMDJSON_INSTALL) include(CMakePackageConfigHelpers)
include(CMakePackageConfigHelpers) include(GNUInstallDirs)
include(GNUInstallDirs)
if(SIMDJSON_SINGLEHEADER) if(SIMDJSON_SINGLEHEADER)
install( install(
FILES singleheader/simdjson.h FILES singleheader/simdjson.h
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
COMPONENT simdjson_Development COMPONENT simdjson_Development
) )
endif()
install(
TARGETS simdjson
EXPORT simdjsonTargets
RUNTIME COMPONENT simdjson_Runtime
LIBRARY COMPONENT simdjson_Runtime
NAMELINK_COMPONENT simdjson_Development
ARCHIVE COMPONENT simdjson_Development
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
configure_file(cmake/simdjson-config.cmake.in simdjson-config.cmake @ONLY)
write_basic_package_version_file(
simdjson-config-version.cmake
COMPATIBILITY SameMinorVersion
)
set(
SIMDJSON_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/simdjson"
CACHE STRING "CMake package config location relative to the install prefix"
)
mark_as_advanced(SIMDJSON_INSTALL_CMAKEDIR)
install(
FILES
"${PROJECT_BINARY_DIR}/simdjson-config.cmake"
"${PROJECT_BINARY_DIR}/simdjson-config-version.cmake"
DESTINATION "${SIMDJSON_INSTALL_CMAKEDIR}"
COMPONENT simdjson_Development
)
install(
EXPORT simdjsonTargets
NAMESPACE simdjson::
DESTINATION "${SIMDJSON_INSTALL_CMAKEDIR}"
COMPONENT simdjson_Development
)
if(SIMDJSON_BUILD_STATIC_LIB)
install(
TARGETS simdjson_static
EXPORT simdjson_staticTargets
ARCHIVE COMPONENT simdjson_Development
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
install(
EXPORT simdjson_staticTargets
NAMESPACE simdjson::
DESTINATION "${SIMDJSON_INSTALL_CMAKEDIR}"
COMPONENT simdjson_Development
)
endif()
# pkg-config
include(cmake/JoinPaths.cmake)
join_paths(PKGCONFIG_INCLUDEDIR "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
join_paths(PKGCONFIG_LIBDIR "\${prefix}" "${CMAKE_INSTALL_LIBDIR}")
if(SIMDJSON_ENABLE_THREADS)
set(PKGCONFIG_CFLAGS "-DSIMDJSON_THREADS_ENABLED=1")
if(CMAKE_THREAD_LIBS_INIT)
set(PKGCONFIG_LIBS_PRIVATE "Libs.private: ${CMAKE_THREAD_LIBS_INIT}")
endif()
endif()
configure_file("simdjson.pc.in" "simdjson.pc" @ONLY)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/simdjson.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
)
endif() endif()
install(
TARGETS simdjson
EXPORT simdjsonTargets
RUNTIME COMPONENT simdjson_Runtime
LIBRARY COMPONENT simdjson_Runtime
NAMELINK_COMPONENT simdjson_Development
ARCHIVE COMPONENT simdjson_Development
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
configure_file(cmake/simdjson-config.cmake.in simdjson-config.cmake @ONLY)
write_basic_package_version_file(
simdjson-config-version.cmake
COMPATIBILITY SameMinorVersion
)
set(
SIMDJSON_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/simdjson"
CACHE STRING "CMake package config location relative to the install prefix"
)
mark_as_advanced(SIMDJSON_INSTALL_CMAKEDIR)
install(
FILES
"${PROJECT_BINARY_DIR}/simdjson-config.cmake"
"${PROJECT_BINARY_DIR}/simdjson-config-version.cmake"
DESTINATION "${SIMDJSON_INSTALL_CMAKEDIR}"
COMPONENT simdjson_Development
)
install(
EXPORT simdjsonTargets
NAMESPACE simdjson::
DESTINATION "${SIMDJSON_INSTALL_CMAKEDIR}"
COMPONENT simdjson_Development
)
if(SIMDJSON_BUILD_STATIC_LIB)
install(
TARGETS simdjson_static
EXPORT simdjson_staticTargets
ARCHIVE COMPONENT simdjson_Development
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
install(
EXPORT simdjson_staticTargets
NAMESPACE simdjson::
DESTINATION "${SIMDJSON_INSTALL_CMAKEDIR}"
COMPONENT simdjson_Development
)
endif()
# pkg-config
include(cmake/JoinPaths.cmake)
join_paths(PKGCONFIG_INCLUDEDIR "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
join_paths(PKGCONFIG_LIBDIR "\${prefix}" "${CMAKE_INSTALL_LIBDIR}")
if(SIMDJSON_ENABLE_THREADS)
set(PKGCONFIG_CFLAGS "-DSIMDJSON_THREADS_ENABLED=1")
if(CMAKE_THREAD_LIBS_INIT)
set(PKGCONFIG_LIBS_PRIVATE "Libs.private: ${CMAKE_THREAD_LIBS_INIT}")
endif()
endif()
configure_file("simdjson.pc.in" "simdjson.pc" @ONLY)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/simdjson.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
)
# #
# CPack # CPack
# #
@@ -425,25 +373,18 @@ add_subdirectory(fuzz)
# #
# Source files should be just ASCII # Source files should be just ASCII
# #
find_program(FIND_CMD find) find_program(FIND find)
find_program(FILE_CMD file) find_program(FILE file)
find_program(GREP_CMD grep) find_program(GREP grep)
if(FIND_CMD AND FILE_CMD AND GREP_CMD) if(FIND AND FILE AND GREP)
add_test( add_test(
NAME just_ascii NAME just_ascii
COMMAND sh -c "\ COMMAND sh -c "\
non_ascii=$(${FIND_CMD} include src windows tools singleheader tests examples benchmark \ ${FIND} include src windows tools singleheader tests examples benchmark \
-path benchmark/checkperf-reference -prune -name '*.h' -o -name '*.cpp' \ -path benchmark/checkperf-reference -prune -name '*.h' -o -name '*.cpp' \
-type f -exec ${FILE_CMD} '{}' \; | ${GREP_CMD} -v ASCII); \ -type f -exec ${FILE} '{}' \; | ${GREP} -qv ASCII || exit 0 && exit 1"
if [ -n \"$non_ascii\" ]; then \
echo 'The following files contain non-ASCII characters:'; \
echo \"$non_ascii\"; \
exit 1; \
fi"
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
) )
else()
message(WARNING "just_ascii test disabled because required tools were not found: find='${FIND_CMD}', file='${FILE_CMD}', grep='${GREP_CMD}'")
endif() endif()
## ##
+1 -1
View File
@@ -38,7 +38,7 @@ PROJECT_NAME = simdjson
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # control system is used.
PROJECT_NUMBER = "4.6.1" PROJECT_NUMBER = "4.4.2"
# Using the PROJECT_BRIEF tag one can provide an optional one line description # Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a # for a project that appears at the top of each page and should give viewer a
-18
View File
@@ -32,24 +32,6 @@ It is similar for Visual Studio users, please see the CMake or Visual Studio doc
By default the library is built in Release mode. By default the library is built in Release mode.
## Optional APIs (Feature Flags)
simdjson provides three APIs:
- DOM (`simdjson::dom`)
- OnDemand (`simdjson::ondemand`)
- Builder (`simdjson::builder`) — requires DOM
You can enable or disable these APIs at compile time to reduce binary size and compile time.
At least one of DOM or OnDemand must be enabled.
### Configuration
Using CMake:
```bash
cmake -DSIMDJSON_FEATURE_DOM_API=OFF \
-DSIMDJSON_FEATURE_ONDEMAND_API=ON \
-DSIMDJSON_FEATURE_BUILDER_API=OFF ..
Assertions and development checks Assertions and development checks
------------------------------ ------------------------------
+1 -1
View File
@@ -10,7 +10,7 @@ namespace partial_tweets {
// { // {
// "created_at": "Sun Aug 31 00:29:15 +0000 2014", // "created_at": "Sun Aug 31 00:29:15 +0000 2014",
// "id": 505874924095815700, // "id": 505874924095815700,
// "text": "@aym0566x ...", // "text": "@aym0566x \n\n名前:前田あゆみ\n第一印象:なんか怖っ!\n今の印象:とりあえずキモい。噛み合わない\n好きなところ:ぶすでキモいとこ😋✨✨\n思い出:んーーー、ありすぎ😊❤️\nLINE交換できる?:あぁ……ごめん✋\nトプ画をみて:照れますがな😘✨\n一言:お前は一生もんのダチ💖",
// "in_reply_to_status_id": null, // "in_reply_to_status_id": null,
// "user": { // "user": {
// "id": 1186275104, // "id": 1186275104,
+1 -1
View File
@@ -171,7 +171,7 @@ We recommend Visual Studio 2019 or better on a 64-bit system.")
else() else()
target_compile_options( target_compile_options(
simdjson-internal-flags INTERFACE simdjson-internal-flags INTERFACE
-Werror -Wall -Wextra -Weffc++ -Wsign-compare -Wshadow -Wwrite-strings -Wall -Wextra -Weffc++ -Wsign-compare -Wshadow -Wwrite-strings
-Wpointer-arith -Winit-self -Wconversion -Wno-sign-conversion -Wpointer-arith -Winit-self -Wconversion -Wno-sign-conversion
) )
if(CMAKE_CXX_STANDARD VERSION_GREATER_EQUAL 20) if(CMAKE_CXX_STANDARD VERSION_GREATER_EQUAL 20)
+75 -93
View File
@@ -161,77 +161,54 @@ The basics: loading and parsing JSON documents
---------------------------------------------- ----------------------------------------------
The simdjson library allows you to navigate and validate JSON documents ([RFC 8259](https://www.tbray.org/ongoing/When/201x/2017/12/14/rfc8259.html)). The simdjson library allows you to navigate and validate JSON documents ([RFC 8259](https://www.tbray.org/ongoing/When/201x/2017/12/14/rfc8259.html)).
Your JSON document should be a valid Unicode (UTF-8) string. As required by the standard, your JSON document should be in a Unicode (UTF-8) string. The whole
string, from the beginning to the end, needs to be valid: we do not attempt to tolerate bad
inputs before or after a document.
To parse JSON, create a `ondemand::parser` and call its `iterate()` method on a padded input. For efficiency reasons, simdjson requires a string with a few bytes (`simdjson::SIMDJSON_PADDING`)
The simplest way to load a JSON file is with `padded_string::load`: at the end, these bytes may be read but their content does not affect the parsing. In practice,
it means that the JSON inputs should be stored in a memory region with `simdjson::SIMDJSON_PADDING`
extra bytes at the end. You do not have to set these bytes to specific values though you may
want to if you want to avoid runtime warnings with some sanitizers. We expect the user
of the library to load the data (from disk or from the network) into a padded buffer. To make
this easy, we provide the `padded_string::load` function which loads files from disk in a padded buffer.
[You can similarly fetch a file from a URL to a padded string](https://github.com/simdjson/curltostring) using our `simdjson::padded_string_builder`. Advanced users may want to read the section Free Padding in [our performance notes](performance.md).
The simdjson library offers a tree-like [API](https://en.wikipedia.org/wiki/API), which you can
access by creating a `ondemand::parser` and calling the `iterate()` method. The iterate method
quickly indexes the input string and may detect some errors. The following example illustrates
how to get started with an input JSON file (`"twitter.json"`):
```cpp ```cpp
ondemand::parser parser; ondemand::parser parser;
auto json = padded_string::load("twitter.json"); auto json = padded_string::load("twitter.json"); // load JSON file 'twitter.json'.
ondemand::document doc = parser.iterate(json); ondemand::document doc = parser.iterate(json); // position a pointer at the beginning of the JSON data
``` ```
For inline JSON strings, use the `_padded` suffix: (Windows users compiling with C++17 or better may use `wchar_t` strings to support non-ASCII
filenames: `padded_string::load(L"twitter.json")`.)
```cpp If you prefer not to create your own `ondemand::parser` instance, you can access
ondemand::parser parser; a thread-local version by calling `ondemand::parser.get_parser()`.
auto json = "[1,2,3]"_padded;
ondemand::document doc = parser.iterate(json);
```
If you are compiling with C++17 or better, you can use `simdjson::padded_input`
which accepts any string-like input and handles padding automatically:
```cpp
ondemand::parser parser;
std::string_view json = "[1,2,3]";
simdjson::padded_input input(json);
ondemand::document doc = parser.iterate(input);
// Also works with std::string, considering reserved capacity
std::string json_str = "[1,2,3]";
json_str.reserve(100); // Reserve extra space
simdjson::padded_input input2(json_str); // May avoid copying
ondemand::document doc2 = parser.iterate(input2);
```
The simdjson library also accepts `std::string` instances directly---if the provided
reference is non-const, it will allocate padding as needed:
```cpp
ondemand::parser parser;
std::string json = "[1,2,3]";
ondemand::document doc = parser.iterate(json);
```
By default, the simdjson library throws exceptions (`simdjson_error`) on errors. We omit `try`-`catch` clauses from our illustrating examples: if you omit `try`-`catch` in your code, an uncaught exception will halt your program. It is also possible to use simdjson without generating exceptions, and you may even build the library without exception support at all. See [Error handling](#error-handling) for details.
### Advanced input options
This section covers additional ways to provide JSON input to simdjson, including
options for fine-grained control over padding and memory.
**Thread-local parser.** If you prefer not to create your own `ondemand::parser` instance, you can access
a thread-local version by calling `ondemand::parser.get_parser()`:
```cpp ```cpp
ondemand::document doc = ondemand::parser.get_parser().iterate(json); ondemand::document doc = ondemand::parser.get_parser().iterate(json);
``` ```
A parser instance can only be used for one document at a time, so However, you should be careful because a parser instance can only be used for one
the thread-local parser is only applicable when you parse one document at a time, thus it is only applicable when you are only parsing one
document per thread at any one time. document per thread at any one time.
**`padded_input` details (C++17+).** The actual padding only occurs when the JSON string ends near the boundary of a memory page, which is You can also create a padded string---and call `iterate()`:
uncommon. Using a `simdjson::padded_input` is safe although sanitizers and tools like valgrind
might report illegal reads (which are safe in our case because they remain in the mapped page). You should avoid `simdjson::padded_input`
on systems without a page size of at least 4096: virtually all systems qualify except for
some niche embedded systems running custom operating systems. Standard Linux, Windows, macOS, Android, iOS, etc., are all fine. Note that, most times, a `simdjson::padded_input` instance will not copy the data and will only act
as a view (it does not own the memory).
**User-managed buffers.** If you have a buffer of your own with enough padding already (`SIMDJSON_PADDING` extra bytes allocated), you can use `padded_string_view` to pass it in: ```cpp
ondemand::parser parser;
auto json = "[1,2,3]"_padded; // The _padded suffix creates a simdjson::padded_string instance
ondemand::document doc = parser.iterate(json); // parse a string
```
If you have a buffer of your own with enough padding already (SIMDJSON_PADDING extra bytes allocated), you can use `padded_string_view` to pass it in:
```cpp ```cpp
ondemand::parser parser; ondemand::parser parser;
@@ -240,72 +217,73 @@ strcpy(json, "[1]");
ondemand::document doc = parser.iterate(json, strlen(json), sizeof(json)); ondemand::document doc = parser.iterate(json, strlen(json), sizeof(json));
``` ```
**Copying into a `padded_string`.** You can copy your data directly into a `simdjson::padded_string`: The simdjson library will also accept `std::string` instances. If the provided
reference is non-const, it will allocate padding as needed.
You can copy your data directly on a `simdjson::padded_string` as follows:
```cpp ```cpp
const char * data = "my data"; // 7 bytes const char * data = "my data"; // 7 bytes
simdjson::padded_string my_padded_data(data, 7); // copies to a padded buffer simdjson::padded_string my_padded_data(data, 7); // copies to a padded buffer
``` ```
Or from a `std::string`: Or as follows...
```cpp ```cpp
std::string data = "my data"; std::string data = "my data";
simdjson::padded_string my_padded_data(data); // copies to a padded buffer simdjson::padded_string my_padded_data(data); // copies to a padded buffer
``` ```
**`std::string` and sanitizer warnings.** Whenever you pass an `std::string` reference to `parser::iterate`, You can then parse the JSON data from the `simdjson::padded_string` instance:
the parser may access bytes beyond the end of
```cpp
ondemand::document doc = parser.iterate(my_padded_data);
```
Whenever you pass an `std::string` reference to `parser::iterate`,
the parser will access the bytes beyond the end of
the string but before the end of the allocated memory (`std::string::capacity()`). the string but before the end of the allocated memory (`std::string::capacity()`).
Sanitizers that check for reading uninitialized bytes may produce warnings. If you are using a sanitizer that checks for reading uninitialized bytes or `std::string`'s
You can safely ignore these warnings, or call `simdjson::pad(std::string&)` to pad the container-overflow checks, you may encounter sanitizer warnings.
string explicitly: You can safely ignore these warnings. Or you can call `simdjson::pad(std::string&)` to pad the
string with `SIMDJSON_PADDING` spaces: this function returns a `simdjson::padding_string_view` which can be be passed to the parser's iterator function:
```cpp ```cpp
std::string json = "[1]"; std::string json = "[1]";
ondemand::document doc = parser.iterate(simdjson::pad(json)); ondemand::document doc = parser.iterate(simdjson::pad(json));
``` ```
We recommend against creating many `std::string` or many `std::padded_string` instances in your application to store your JSON data. We recommend against creating many `std::string` or many `std::padding_string` instances in your application to store your JSON data.
Consider reusing the same buffers and limiting memory allocations. Consider reusing the same buffers and limiting memory allocations.
**Memory-file mapping (non-Windows).** You can use memory-file mapping to create a `simdjson::padded_string_view` By default, the simdjson library throws exceptions (`simdjson_error`) on errors. We omit `try`-`catch` clauses from our illustrating examples: if you omit `try`-`catch` in your code, an uncaught exception will halt your program. It is also possible to use simdjson without generating exceptions, and you may even build the library without exception support at all. See [Error handling](#error-handling) for details.
from a file on disk:
```cpp Some users may want to browse code along with the compiled assembly. You want to check out the following lists of examples:
simdjson::padded_memory_map map(myfilename);
if (!map.is_valid()) { /* handle error */ }
simdjson::padded_string_view view = map.view();
ondemand::document doc = parser.iterate(view);
```
**Windows-specific notes.** Windows users compiling with C++17 or better may use `wchar_t` strings to support non-ASCII * [simdjson examples with errors handled through exceptions](https://godbolt.org/z/98Kx9Kqjn)
filenames: `padded_string::load(L"twitter.json")`. Windows users who need to read files with * [simdjson examples with errors without exceptions](https://godbolt.org/z/PKG7GdbPo)
*Windows-specific*: Windows users who need to read files with
non-ANSI characters in the name should set their code page to non-ANSI characters in the name should set their code page to
UTF-8 (65001). This should be the default with Windows 11 and better. UTF-8 (65001). This should be the default with Windows 11 and better.
Further, they may use the AreFileApisANSI function to determine whether Further, they may use the AreFileApisANSI function to determine whether
the filename is interpreted using the ANSI or the system default OEM the filename is interpreted using the ANSI or the system default OEM
codepage, and they may call SetFileApisToOEM accordingly. codepage, and they may call SetFileApisToOEM accordingly.
Some users may want to browse code along with the compiled assembly:
* [simdjson examples with errors handled through exceptions](https://godbolt.org/z/98Kx9Kqjn) **Advanced feature:**
* [simdjson examples with errors without exceptions](https://godbolt.org/z/PKG7GdbPo) On non-Windows systems, you can use memory-file mapping to create a `simdjson::padded_string_view`
from a file on disk.
**Summary of input types:** ```cpp
// If the macro _WIN32 is defined, this will not work since we do not support memory-file mapping
// under Windows at this time.
| Input Type / Method | Padding Requirement | How Padding is Handled | Ownership / Copying | Notes / Warnings | simdjson::padded_memory_map map(myfilename);
|----------------------------------------------|-------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------|----------------------------------------------|----------------------------------------------------------------------------------| if (!map.is_valid()) { /* handle error */ }
| `padded_string::load("file.json")` | Automatic (SIMDJSON_PADDING extra bytes) | Library allocates padded buffer and loads file into it | Owned by `padded_string` | Recommended for files; safest and simplest. | simdjson::padded_string_view view = map.view(); // view is usable while padded_memory_map is in scope
| `"...json..."_padded` literal | Automatic (built-in padding) | Creates `padded_string` with padding | Owned by `padded_string` | Convenient for small hardcoded JSON. | ondemand::document doc = parser.iterate(view); // parse the JSON
| `simdjson::padded_input` (C++17+) | Automatic when needed | Adds padding **only** if the string ends near a memory page boundary. For `std::string`, considers `capacity()` | Usually a non-owning view (no copy most times) | Safe on standard OS (page size ≥ 4096). May trigger sanitizer/valgrind warnings (harmless). Avoid on niche embedded systems. | ```
| User buffer with explicit padding | Must have at least `SIMDJSON_PADDING` extra allocated bytes after JSON content | Pass via `iterate(ptr, json_length, total_allocated_size)` or `padded_string_view` | User-owned (no copy) | Use `char buf[len + SIMDJSON_PADDING]`. Library reads (but never writes) into padding. |
| `std::string` (non-const) | Library checks `capacity()` | If insufficient, library may allocate a padded copy | May copy (depends on capacity) | Can trigger sanitizer warnings on uninitialized bytes. Use `simdjson::pad(json)` to avoid. |
| `simdjson::pad(std::string&)` | Adds padding if needed | Returns `padded_string_view` pointing to the (possibly resized) string | References original string | Recommended to silence sanitizers when using `std::string`. |
| `padded_string(data, length)` or `padded_string(std::string)` | Automatic (copies into padded buffer) | Explicit copy into owned padded buffer | Owned by `padded_string` | Safe when you want full ownership and padding guaranteed. |
| `padded_string_view` (manual) | User guarantees `SIMDJSON_PADDING` extra bytes after the viewed length | User provides pointer + length + capacity | Non-owning view | Low-level; requires careful buffer management. |
| Memory-mapped file (`padded_memory_map`) | Automatic via mapping (non-Windows only) | Creates view with sufficient padding | Non-owning (tied to map lifetime) | Advanced; efficient for large files on Linux/macOS/etc. |
Documents are iterators Documents are iterators
@@ -458,7 +436,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
* **Extracting Values:** You can cast a JSON element to a native type: * **Extracting Values:** You can cast a JSON element to a native type:
`double(element)`. This works for `std::string_view`, double, uint64_t, int64_t, bool, `double(element)`. This works for `std::string_view`, double, uint64_t, int64_t, bool,
ondemand::object and ondemand::array. We also have explicit methods such as `get_string()`, `get_double()`, ondemand::object and ondemand::array. We also have explicit methods such as `get_string()`, `get_double()`,
`get_uint64()`, `get_int64()`, `get_uint32()`, `get_int32()`, `get_bool()`, `get_object()` and `get_array()`. After a cast or an explicit method, `get_uint64()`, `get_int64()`, `get_bool()`, `get_object()` and `get_array()`. After a cast or an explicit method,
the number, string or boolean will be parsed, or the initial `{` or `[` will be verified for `ondemand::object` and `ondemand::array`. An exception may be thrown if the number, string or boolean will be parsed, or the initial `{` or `[` will be verified for `ondemand::object` and `ondemand::array`. An exception may be thrown if
the cast is not possible: the error code is `simdjson::INCORRECT_TYPE` (see [Error handling](#error-handling)). Importantly, when getting an ondemand::object or ondemand::array instance, its content is the cast is not possible: the error code is `simdjson::INCORRECT_TYPE` (see [Error handling](#error-handling)). Importantly, when getting an ondemand::object or ondemand::array instance, its content is
not validated: you are only guaranteed that the corresponding initial character (`{` or `[`) is present. Thus, not validated: you are only guaranteed that the corresponding initial character (`{` or `[`) is present. Thus,
@@ -468,8 +446,8 @@ support for users who avoid exceptions. See [the simdjson error handling documen
pass `true` (`get_string(true)`) as a parameter to get replacement characters where errors pass `true` (`get_string(true)`) as a parameter to get replacement characters where errors
occur. If you somehow need to access non-UTF-8 strings in a lossless manner occur. If you somehow need to access non-UTF-8 strings in a lossless manner
(e.g., if you strings contain unpaired surrogates), you may use the `get_wobbly_string()` function to get a string in the [WTF-8 format](https://simonsapin.github.io/wtf-8). (e.g., if you strings contain unpaired surrogates), you may use the `get_wobbly_string()` function to get a string in the [WTF-8 format](https://simonsapin.github.io/wtf-8).
When calling `get_uint64()`, `get_int64()`, `get_uint32()` or `get_int32()`, if the number does not fit in the When calling `get_uint64()` and `get_int64()`, if the number does not fit in a corresponding
corresponding integer type, it is also considered an error (`NUMBER_OUT_OF_RANGE`). When parsing numbers or other scalar values, the library checks 64-bit integer type, it is also considered an error. When parsing numbers or other scalar values, the library checks
that the value is followed by an expected character, thus you *may* get a number parsing error when accessing the digits that the value is followed by an expected character, thus you *may* get a number parsing error when accessing the digits
as an integer in the following strings: `{"number":12332a`, `{"number":12332\0`, `{"number":12332` (the digits appear at the end). We always abide by the [RFC 8259](https://www.tbray.org/ongoing/When/201x/2017/12/14/rfc8259.html) JSON specification so that, for example, numbers prefixed by the `+` sign are in error. as an integer in the following strings: `{"number":12332a`, `{"number":12332\0`, `{"number":12332` (the digits appear at the end). We always abide by the [RFC 8259](https://www.tbray.org/ongoing/When/201x/2017/12/14/rfc8259.html) JSON specification so that, for example, numbers prefixed by the `+` sign are in error.
@@ -1322,6 +1300,10 @@ You can also use the custom `Car` type as part of a template such as `std::vecto
simdjson::ondemand::parser parser; simdjson::ondemand::parser parser;
simdjson::ondemand::document doc = parser.iterate(json); simdjson::ondemand::document doc = parser.iterate(json);
std::vector<Car> cars(doc); std::vector<Car> cars(doc);
// visual studio users need an explicit call:
// std::vector<Car> cars = doc.get<std::vector<Car>>();
// because the compiler does not know whether to convert
// doc to an unsigned int or to a vector.
for(Car& c : cars) { for(Car& c : cars) {
std::cout << c.year << std::endl; std::cout << c.year << std::endl;
} }
-23
View File
@@ -32,21 +32,6 @@ your code with the `SIMDJSON_STATIC_REFLECTION` macro set:
The `simdjson::compile_time::parse_json` function parses a JSON document at **compile time** and returns a `constexpr` structure reflecting its content. We support the full range of JSON values, which are mapped to C++ types as in The `simdjson::compile_time::parse_json` function parses a JSON document at **compile time** and returns a `constexpr` structure reflecting its content. We support the full range of JSON values, which are mapped to C++ types as in
the following table. the following table.
For convenience, you can also use the `""_json` user-defined literal operator, which is available in the `simdjson::literals` namespace:
```cpp
using namespace simdjson::literals;
constexpr auto cfg = R"(
{
"port": 8080,
"host": "localhost"
}
)"_json;
```
Alternatively, you can use the qualified name `simdjson::literals::operator""_json`.
| JSON type | C++ type | | JSON type | C++ type |
|----------------|----------------------------------| |----------------|----------------------------------|
@@ -76,8 +61,6 @@ You can do so, at compile-time, as follows:
```cpp ```cpp
using namespace simdjson::literals;
constexpr auto cfg = R"( constexpr auto cfg = R"(
{ {
@@ -96,8 +79,6 @@ constexpr auto cfg = R"(
You can nest objects and arrays: You can nest objects and arrays:
```cpp ```cpp
using namespace simdjson::literals;
constexpr auto data = R"( constexpr auto data = R"(
{ {
@@ -117,8 +98,6 @@ constexpr auto data = R"(
Top-level arrays are allowed: Top-level arrays are allowed:
```cpp ```cpp
using namespace simdjson::literals;
constexpr auto arr = R"( constexpr auto arr = R"(
[1, 2, 3] [1, 2, 3]
@@ -137,8 +116,6 @@ want to check that it conforms to your expectation. You can do so with concepts.
Let us consider this example: Let us consider this example:
```cpp ```cpp
using namespace simdjson::literals;
constexpr auto config = R"( constexpr auto config = R"(
[ [
+1 -31
View File
@@ -168,23 +168,6 @@ Once you have an element, you can navigate it with idiomatic C++ iterators, oper
`SIMDJSON_MINUS_ZERO_AS_FLOAT` to `1` when building simdjson, you can get that `-0` is mapped to `-0.0` `SIMDJSON_MINUS_ZERO_AS_FLOAT` to `1` when building simdjson, you can get that `-0` is mapped to `-0.0`
as in JavaScript. You can get the desired effect by building simdjson with cmake setting the as in JavaScript. You can get the desired effect by building simdjson with cmake setting the
`SIMDJSON_MINUS_ZERO_AS_FLOAT` to on: `cmake -B build -D SIMDJSON_MINUS_ZERO_AS_FLOAT=ON`. `SIMDJSON_MINUS_ZERO_AS_FLOAT` to on: `cmake -B build -D SIMDJSON_MINUS_ZERO_AS_FLOAT=ON`.
* **Big Integer Support (opt-in):** By default, integers that exceed the 64-bit range cause parsing to fail with `BIGINT_ERROR`. You can opt in to big integer support so that these numbers are stored as raw digit strings on the tape instead:
```cpp
simdjson::dom::parser parser;
parser.number_as_string(true); // opt-in, default false
simdjson::dom::element doc;
auto error = parser.parse("[1, 123456789012345678901]"_padded).get(doc);
if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
for (simdjson::dom::element elem : doc) {
if (elem.is_bigint()) {
std::string_view digits;
error = elem.get_bigint().get(digits);
if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
std::cout << "big integer: " << digits << std::endl;
}
}
```
When enabled, big integers have type `element_type::BIGINT`. Calling `get_int64()`, `get_uint64()`, or `get_double()` on a big integer returns `INCORRECT_TYPE`. Normal numbers (int64, uint64, double) are unaffected.
* **Field Access:** To get the value of the "foo" field in an object, use `object["foo"]`. * **Field Access:** To get the value of the "foo" field in an object, use `object["foo"]`.
* **Array Iteration:** To iterate through an array, use `for (auto value : array) { ... }`. If you * **Array Iteration:** To iterate through an array, use `for (auto value : array) { ... }`. If you
know the type of the value, you can cast it right there, too! `for (double value : array) { ... }` know the type of the value, you can cast it right there, too! `for (double value : array) { ... }`
@@ -197,7 +180,7 @@ Once you have an element, you can navigate it with idiomatic C++ iterators, oper
* **Array and Object size** Given an array or an object, you can get its size (number of elements or keys) * **Array and Object size** Given an array or an object, you can get its size (number of elements or keys)
with the `size()` method. with the `size()` method.
* **Checking an Element Type:** You can check an element's type with `element.type()`. It * **Checking an Element Type:** You can check an element's type with `element.type()`. It
returns an `element_type` with values such as `simdjson::dom::element_type::ARRAY`, `simdjson::dom::element_type::OBJECT`, `simdjson::dom::element_type::INT64`, `simdjson::dom::element_type::UINT64`,`simdjson::dom::element_type::DOUBLE`, `simdjson::dom::element_type::STRING`, `simdjson::dom::element_type::BOOL`, `simdjson::dom::element_type::NULL_VALUE` or, `simdjson::dom::element_type::BIGINT` (when big integer support is enabled). returns an `element_type` with values such as `simdjson::dom::element_type::ARRAY`, `simdjson::dom::element_type::OBJECT`, `simdjson::dom::element_type::INT64`, `simdjson::dom::element_type::UINT64`,`simdjson::dom::element_type::DOUBLE`, `simdjson::dom::element_type::STRING`, `simdjson::dom::element_type::BOOL` or, `simdjson::dom::element_type::NULL_VALUE`.
* **Output to streams and strings:** Given a document or an element (or node) out of a JSON document, you can output a minified string version using the C++ stream idiom (`out << element`). You can also request the construction of a minified string version (`simdjson::minify(element)`) or a prettified string version (`simdjson::prettify(element)`). Numbers are serialized as 64-bit floating-point numbers (`double`). * **Output to streams and strings:** Given a document or an element (or node) out of a JSON document, you can output a minified string version using the C++ stream idiom (`out << element`). You can also request the construction of a minified string version (`simdjson::minify(element)`) or a prettified string version (`simdjson::prettify(element)`). Numbers are serialized as 64-bit floating-point numbers (`double`).
### Examples ### Examples
@@ -882,19 +865,6 @@ simdjson::dom::element element = parser.parse(padded_json_copy.get(), json_len,
Setting the `realloc_if_needed` parameter `false` in this manner may lead to better performance since copies are avoided, but it requires that the user takes more responsibilities: the simdjson library cannot verify that the input buffer was padded with SIMDJSON_PADDING extra bytes. Setting the `realloc_if_needed` parameter `false` in this manner may lead to better performance since copies are avoided, but it requires that the user takes more responsibilities: the simdjson library cannot verify that the input buffer was padded with SIMDJSON_PADDING extra bytes.
If you are compiling your project with C++17 or better, you can use a `simdjson::padded_input`:
```cpp
simdjson::dom::parser parser;
std::string_view json = "[1,2,3]";
simdjson::padded_input input(json); // Automatically pads if needed
simdjson::dom::element element = parser.parse(input);
```
The actual padding only occurs if the JSON string ends near the boundary of a memory page, which is uncommon. Using a `simdjson::padded_input` is safe although sanitizers and tools like valgrind might report illegal reads (which are safe in our case because they remain in the mapped page). You should avoid `simdjson::padded_input` on systems without a page size of at least 4096: virtually all systems qualify except for some niche embedded systems running custom operating systems. Standard Linux, Windows, macOS, Android, iOS, etc., are all fine. Note that, most times, an `simdjson::padded_input` instance will not copy the data and will only act
as a view (it does not own the memory).
Performance Tips Performance Tips
--------------------- ---------------------
+4 -20
View File
@@ -204,25 +204,9 @@ but can be significantly larger. E.g., Apple systems favour pages spanning 16 ki
In effect, it means that you can almost always read a few bytes beyond your current buffer---without In effect, it means that you can almost always read a few bytes beyond your current buffer---without
allocating extra memory. However, tools such as valgrind or memory sanitizers will flag such behavior as unsafe. allocating extra memory. However, tools such as valgrind or memory sanitizers will flag such behavior as unsafe.
You can still make sure of this capability in your code if you are an expert Nevertheless, you can still make sure of this capability in your code if you are an expert
programmer and you are willing to silence sanitizer warnings. programmer and you are willing to silence sanitizer warnings. The following code provides
a portable example.
If you are building simdjson with C++17 or better, you can use `simdjson::padded_input`.
The `padded_input` struct automatically manages padding for you. It can be constructed from a `std::string_view` or a C-style string with length. If the input already has sufficient padding (up to the end of the memory page), it creates a view without copying. Otherwise, it copies the data into a `padded_string` with proper padding.
Example usage:
```cpp
std::string_view json = get_json_data();
simdjson::padded_input input(json); // Automatically pads if needed
auto result = parser.parse(input);
```
This simplifies padding management compared to manually checking and allocating.
More generally, the following code provides a portable example.
The conditional compilation checks for the `_MSC_VER` macro (indicating Microsoft Visual Studio) The conditional compilation checks for the `_MSC_VER` macro (indicating Microsoft Visual Studio)
@@ -266,7 +250,7 @@ long page_size() {
} }
// Returns true if the buffer + len + simdjson::SIMDJSON_PADDING crosses the // Returns true if the buffer + len + simdjson::SIMDJSON_PADDING crosses the
// page boundary. Assumes len != 0. // page boundary.
bool need_allocation(const char *buf, size_t len) { bool need_allocation(const char *buf, size_t len) {
return ((reinterpret_cast<uintptr_t>(buf + len - 1) % page_size()) return ((reinterpret_cast<uintptr_t>(buf + len - 1) % page_size())
+ simdjson::SIMDJSON_PADDING >= static_cast<uintptr_t>(page_size())); + simdjson::SIMDJSON_PADDING >= static_cast<uintptr_t>(page_size()));
-8
View File
@@ -93,14 +93,6 @@ Float values are represented as two 64-bit tape elements:
Performance consideration: We store numbers of the main tape because we believe that locality of reference is helpful for performance. Performance consideration: We store numbers of the main tape because we believe that locality of reference is helpful for performance.
## Big Integers
When a JSON integer exceeds the 64-bit range (both signed and unsigned), it is classified as a big integer. By default, parsing returns `BIGINT_ERROR`. When `parser.number_as_string(true)` is set, the raw digits are stored on the string tape using the same format as strings (4-byte little-endian length prefix, followed by the UTF-8 digit bytes, followed by a null terminator).
A big integer is represented on the main tape as the 64-bit tape element `('Z' << 56) + x` where the payload `x` is the location on the string tape of the null-terminated digit string.
For example, the JSON value `99999999999999999999` would be stored as the string `"99999999999999999999"` on the string tape, with a `'Z'` tag on the main tape. Negative big integers include the leading minus sign.
## Root node ## Root node
Each JSON document will have two special 64-bit tape elements representing a root node, one at the beginning and one at the end. Each JSON document will have two special 64-bit tape elements representing a root node, one at the beginning and one at the end.
@@ -2,13 +2,6 @@
function(add_quickstart_test TEST_NAME SOURCE_FILE) function(add_quickstart_test TEST_NAME SOURCE_FILE)
cmake_parse_arguments(PARSE_ARGV 2 ARGS "NO_EXCEPTIONS;NATIVE_ARCH" "" "CXX_STANDARD;LABELS") cmake_parse_arguments(PARSE_ARGV 2 ARGS "NO_EXCEPTIONS;NATIVE_ARCH" "" "CXX_STANDARD;LABELS")
# Standard compiler flags
if (MSVC)
list(APPEND QUICKSTART_FLAGS /WX)
else()
list(APPEND QUICKSTART_FLAGS -Werror)
endif()
# Native architecture compiler flag # Native architecture compiler flag
if (ARGS_NATIVE_ARCH) if (ARGS_NATIVE_ARCH)
if (MSVC) if (MSVC)
-3
View File
@@ -54,9 +54,6 @@ static void print_json(std::ostream& os, simdjson::dom::element element) noexcep
case simdjson::dom::element_type::NULL_VALUE: case simdjson::dom::element_type::NULL_VALUE:
os << "null" << endl; os << "null" << endl;
break; break;
case simdjson::dom::element_type::BIGINT:
os << element.get_bigint().value_unsafe() << endl;
break;
} }
} }
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+1 -12
View File
@@ -35,7 +35,6 @@
*/ */
#include "simdjson/common_defs.h" #include "simdjson/common_defs.h"
#include "simdjson/feature_macros.h"
// This provides the public API for simdjson. // This provides the public API for simdjson.
// DOM and ondemand are amalgamated separately, in simdjson.h // DOM and ondemand are amalgamated separately, in simdjson.h
@@ -46,29 +45,19 @@
#include "simdjson/error.h" #include "simdjson/error.h"
#include "simdjson/error-inl.h" #include "simdjson/error-inl.h"
#include "simdjson/implementation.h" #include "simdjson/implementation.h"
#include "simdjson/builtin.h"
#include "simdjson/minify.h" #include "simdjson/minify.h"
#include "simdjson/padded_string.h" #include "simdjson/padded_string.h"
#include "simdjson/padded_string-inl.h" #include "simdjson/padded_string-inl.h"
#include "simdjson/padded_string_view.h" #include "simdjson/padded_string_view.h"
#include "simdjson/padded_string_view-inl.h" #include "simdjson/padded_string_view-inl.h"
#if SIMDJSON_FEATURE_DOM_API
#include "simdjson/dom.h" #include "simdjson/dom.h"
#if SIMDJSON_FEATURE_BUILDER_API
#include "simdjson/builder.h" #include "simdjson/builder.h"
#endif // SIMDJSON_FEATURE_BUILDER_API
#endif // SIMDJSON_FEATURE_DOM_API
#if SIMDJSON_FEATURE_ONDEMAND_API
#include "simdjson/ondemand.h" #include "simdjson/ondemand.h"
#endif // SIMDJSON_FEATURE_ONDEMAND_API
#if SIMDJSON_FEATURE_DOM_API && SIMDJSON_FEATURE_ONDEMAND_API
#include "simdjson/convert.h" #include "simdjson/convert.h"
#include "simdjson/convert-inl.h" #include "simdjson/convert-inl.h"
#endif // SIMDJSON_FEATURE_DOM_API && SIMDJSON_FEATURE_ONDEMAND_API
// Compile-time JSON parsing (C++26 P2996 reflection)
#include "simdjson/compile_time_json.h" #include "simdjson/compile_time_json.h"
#include "simdjson/compile_time_json-inl.h" #include "simdjson/compile_time_json-inl.h"
+34 -35
View File
@@ -266,12 +266,6 @@ consteval std::pair<double, size_t> parse_double(const char *src,
} }
} // namespace number_parsing } // namespace number_parsing
consteval auto make_data_member_options(auto&& name_str) {
std::meta::data_member_options options{};
options.name = std::forward<decltype(name_str)>(name_str);
return options;
}
// JSON string may contain embedded nulls, and C++26 reflection does not yet // JSON string may contain embedded nulls, and C++26 reflection does not yet
// support std::string_view as a data member type. As a workaround, we define // support std::string_view as a data member type. As a workaround, we define
// a custom type that holds a const char* and a size. // a custom type that holds a const char* and a size.
@@ -326,8 +320,7 @@ using class_type = type_builder<meta_info...>::constructed_type;
/** /**
* @brief Variable template for constructing instances with values * @brief Variable template for constructing instances with values
*/ */
template <typename T, auto... Vs> constexpr T construct_from = T{Vs...}; template <typename T, auto... Vs> constexpr auto construct_from = T{Vs...};
// in JSON, there are only a few whitespace characters that are allowed // in JSON, there are only a few whitespace characters that are allowed
// outside of objects, arrays, strings, and numbers. // outside of objects, arrays, strings, and numbers.
@@ -417,7 +410,7 @@ parse_number(std::string_view json,
std::from_chars(json.data(), json.data() + json.size(), int_value); std::from_chars(json.data(), json.data() + json.size(), int_value);
if (res.ec == std::errc()) { if (res.ec == std::errc()) {
out = int_value; out = int_value;
if (static_cast<std::size_t>(res.ptr - json.data()) != scope) { if ((res.ptr - json.data()) != scope) {
simdjson_consteval_error( simdjson_consteval_error(
"Internal error: cannot agree on the character range of the float"); "Internal error: cannot agree on the character range of the float");
} }
@@ -431,7 +424,7 @@ parse_number(std::string_view json,
std::from_chars(json.data(), json.data() + json.size(), uint_value); std::from_chars(json.data(), json.data() + json.size(), uint_value);
if (res.ec == std::errc()) { if (res.ec == std::errc()) {
out = uint_value; out = uint_value;
if (static_cast<std::size_t>(res.ptr - json.data()) != scope) { if ((res.ptr - json.data()) != scope) {
simdjson_consteval_error( simdjson_consteval_error(
"Internal error: cannot agree on the character range of the float"); "Internal error: cannot agree on the character range of the float");
} }
@@ -540,7 +533,7 @@ parse_string(std::string_view json) {
// present, we have an error (isolated high surrogate), which we // present, we have an error (isolated high surrogate), which we
// tolerate by substituting the substitution_code_point. // tolerate by substituting the substitution_code_point.
if (end - cursor < 6 || *cursor != '\\' || if (end - cursor < 6 || *cursor != '\\' ||
*(cursor + 1) != 'u') { *(cursor + 1) != 'u' > 0xFFFF) {
code_point = substitution_code_point; code_point = substitution_code_point;
} else { // we have \u following the high surrogate } else { // we have \u following the high surrogate
cursor += 2; // skip \u cursor += 2; // skip \u
@@ -894,19 +887,10 @@ parse_json_array_impl(const std::string_view json) {
std::size_t count = values.size() - 1; std::size_t count = values.size() - 1;
// We assume all elements have the same type as the first element. // We assume all elements have the same type as the first element.
// However, if the array is heterogeneous, we should use std::variant. // However, if the array is heterogeneous, we should use std::variant.
auto elem_type = std::meta::type_of(values[1]);
// String literals reflected via reflect_constant_string have type const
// char[N], but when passed as template auto parameters they decay to
// const char*. Use const char* as the element type so that
// construct_from can aggregate-initialize the array.
if (std::meta::is_array_type(elem_type) &&
std::meta::remove_all_extents(elem_type) == ^^const char) {
elem_type = ^^const char *;
}
auto array_type = std::meta::substitute( auto array_type = std::meta::substitute(
^^std::array, ^^std::array,
{ {
elem_type, std::meta::reflect_constant(count)}); std::meta::type_of(values[1]), std::meta::reflect_constant(count)});
// Create array instance with values // Create array instance with values
values[0] = array_type; values[0] = array_type;
@@ -973,7 +957,8 @@ parse_json_object_impl(std::string_view json) {
simdjson_consteval_error("Expected '}'"); simdjson_consteval_error("Expected '}'");
} }
cursor += object_size; cursor += object_size;
auto dms = std::meta::data_member_spec(std::meta::type_of(parsed), make_data_member_options(field_name)); auto dms = std::meta::data_member_spec(std::meta::type_of(parsed),
{.name = field_name});
members.push_back(std::meta::reflect_constant(dms)); members.push_back(std::meta::reflect_constant(dms));
values.push_back(parsed); values.push_back(parsed);
@@ -982,7 +967,8 @@ parse_json_object_impl(std::string_view json) {
case '[': { case '[': {
std::string_view value(cursor, end); std::string_view value(cursor, end);
auto [parsed, array_size] = parse_json_array_impl(value); auto [parsed, array_size] = parse_json_array_impl(value);
auto dms = std::meta::data_member_spec(std::meta::type_of(parsed), make_data_member_options(field_name)); auto dms = std::meta::data_member_spec(std::meta::type_of(parsed),
{.name = field_name});
members.push_back(std::meta::reflect_constant(dms)); members.push_back(std::meta::reflect_constant(dms));
values.push_back(parsed); values.push_back(parsed);
if (*(cursor + array_size - 1) != ']') { if (*(cursor + array_size - 1) != ']') {
@@ -1003,7 +989,8 @@ parse_json_object_impl(std::string_view json) {
} }
} }
auto dms = auto dms =
std::meta::data_member_spec(^^const char *, make_data_member_options(field_name)); std::meta::data_member_spec(^^const char *, {
.name = field_name});
members.push_back(std::meta::reflect_constant(dms)); members.push_back(std::meta::reflect_constant(dms));
values.push_back(std::meta::reflect_constant_string(value)); values.push_back(std::meta::reflect_constant_string(value));
break; break;
@@ -1014,7 +1001,8 @@ parse_json_object_impl(std::string_view json) {
} }
cursor += 4; cursor += 4;
auto dms = std::meta::data_member_spec(^^bool, make_data_member_options(field_name)); auto dms = std::meta::data_member_spec(^^bool, {
.name = field_name});
members.push_back(std::meta::reflect_constant(dms)); members.push_back(std::meta::reflect_constant(dms));
values.push_back(std::meta::reflect_constant(true)); values.push_back(std::meta::reflect_constant(true));
break; break;
@@ -1025,7 +1013,8 @@ parse_json_object_impl(std::string_view json) {
} }
cursor += 5; cursor += 5;
auto dms = std::meta::data_member_spec(^^bool, make_data_member_options(field_name)); auto dms = std::meta::data_member_spec(^^bool, {
.name = field_name});
members.push_back(std::meta::reflect_constant(dms)); members.push_back(std::meta::reflect_constant(dms));
values.push_back(std::meta::reflect_constant(false)); values.push_back(std::meta::reflect_constant(false));
break; break;
@@ -1036,7 +1025,9 @@ parse_json_object_impl(std::string_view json) {
} }
cursor += 4; cursor += 4;
auto dms = std::meta::data_member_spec(^^std::nullptr_t, make_data_member_options(field_name)); auto dms = std::meta::data_member_spec(^^std::nullptr_t,
{
.name = field_name});
members.push_back(std::meta::reflect_constant(dms)); members.push_back(std::meta::reflect_constant(dms));
values.push_back(std::meta::reflect_constant(nullptr)); values.push_back(std::meta::reflect_constant(nullptr));
break; break;
@@ -1060,19 +1051,22 @@ parse_json_object_impl(std::string_view json) {
if (std::holds_alternative<int64_t>(out)) { if (std::holds_alternative<int64_t>(out)) {
int64_t int_value = std::get<int64_t>(out); int64_t int_value = std::get<int64_t>(out);
auto dms = auto dms =
std::meta::data_member_spec(^^int64_t, make_data_member_options(field_name)); std::meta::data_member_spec(^^int64_t, {
.name = field_name});
members.push_back(std::meta::reflect_constant(dms)); members.push_back(std::meta::reflect_constant(dms));
values.push_back(std::meta::reflect_constant(int_value)); values.push_back(std::meta::reflect_constant(int_value));
} else if (std::holds_alternative<uint64_t>(out)) { } else if (std::holds_alternative<uint64_t>(out)) {
uint64_t uint_value = std::get<uint64_t>(out); uint64_t uint_value = std::get<uint64_t>(out);
auto dms = auto dms =
std::meta::data_member_spec(^^uint64_t, make_data_member_options(field_name)); std::meta::data_member_spec(^^uint64_t, {
.name = field_name});
members.push_back(std::meta::reflect_constant(dms)); members.push_back(std::meta::reflect_constant(dms));
values.push_back(std::meta::reflect_constant(uint_value)); values.push_back(std::meta::reflect_constant(uint_value));
} else { } else {
double float_value = std::get<double>(out); double float_value = std::get<double>(out);
auto dms = auto dms =
std::meta::data_member_spec(^^double, make_data_member_options(field_name)); std::meta::data_member_spec(^^double, {
.name = field_name});
members.push_back(std::meta::reflect_constant(dms)); members.push_back(std::meta::reflect_constant(dms));
values.push_back(std::meta::reflect_constant(float_value)); values.push_back(std::meta::reflect_constant(float_value));
} }
@@ -1117,11 +1111,16 @@ template <constevalutil::fixed_string json_str> consteval auto parse_json() {
"Only JSON objects and arrays are supported at the top level, this " "Only JSON objects and arrays are supported at the top level, this "
"limitation will be lifted in the future.");*/ "limitation will be lifted in the future.");*/
if constexpr (json.front() == '[') { constexpr auto result = json.front() == '['
return [: parse_json_array_impl(json).first :]; ? parse_json_array_impl(json)
} else { : parse_json_object_impl(json);
return [: parse_json_object_impl(json).first :]; return [: result.first :];
} /*
if(json.front() == '[') {
return [:parse_json_array_impl(json).first:];
} else if(json.front() == '{') {
// return [:parse_json_object_impl(json).first:];
}*/
} }
} // namespace compile_time } // namespace compile_time
+1 -4
View File
@@ -63,16 +63,13 @@ namespace compile_time {
template <constevalutil::fixed_string json_str> consteval auto parse_json(); template <constevalutil::fixed_string json_str> consteval auto parse_json();
} // namespace compile_time } // namespace compile_time
} // namespace simdjson
inline namespace literals {
template <simdjson::constevalutil::fixed_string str> template <simdjson::constevalutil::fixed_string str>
consteval auto operator ""_json() { consteval auto operator ""_json() {
return simdjson::compile_time::parse_json<str>(); return simdjson::compile_time::parse_json<str>();
} }
} // namespace literals
} // namespace simdjson
#endif // SIMDJSON_STATIC_REFLECTION #endif // SIMDJSON_STATIC_REFLECTION
#endif // SIMDJSON_GENERIC_COMPILE_TIME_JSON_H #endif // SIMDJSON_GENERIC_COMPILE_TIME_JSON_H
-5
View File
@@ -58,11 +58,6 @@ struct fixed_string {
data[i] = str[i]; data[i] = str[i];
} }
} }
constexpr fixed_string(const unsigned char (&str)[N]) {
for (std::size_t i = 0; i < N; ++i) {
data[i] = static_cast<char>(str[i]);
}
}
char data[N]; char data[N];
constexpr std::string_view view() const { return {data, N - 1}; } constexpr std::string_view view() const { return {data, N - 1}; }
constexpr size_t size() const { return N ; } constexpr size_t size() const { return N ; }
-9
View File
@@ -141,15 +141,6 @@ inline bool document::dump_raw_tape(std::ostream &os) const noexcept {
case 'r': // we start and end with the root node case 'r': // we start and end with the root node
// should we be hitting the root node? // should we be hitting the root node?
return false; return false;
case 'Z': // we have a big integer
os << "bigint ";
std::memcpy(&string_length, string_buf.get() + payload, sizeof(uint32_t));
os << std::string_view(
reinterpret_cast<const char *>(string_buf.get() + payload + sizeof(uint32_t)),
string_length
);
os << '\n';
break;
default: default:
return false; return false;
} }
-22
View File
@@ -81,10 +81,6 @@ simdjson_inline simdjson_result<bool> simdjson_result<dom::element>::get_bool()
if (error()) { return error(); } if (error()) { return error(); }
return first.get_bool(); return first.get_bool();
} }
simdjson_inline simdjson_result<std::string_view> simdjson_result<dom::element>::get_bigint() const noexcept {
if (error()) { return error(); }
return first.get_bigint();
}
simdjson_inline bool simdjson_result<dom::element>::is_array() const noexcept { simdjson_inline bool simdjson_result<dom::element>::is_array() const noexcept {
return !error() && first.is_array(); return !error() && first.is_array();
@@ -114,9 +110,6 @@ simdjson_inline bool simdjson_result<dom::element>::is_bool() const noexcept {
simdjson_inline bool simdjson_result<dom::element>::is_null() const noexcept { simdjson_inline bool simdjson_result<dom::element>::is_null() const noexcept {
return !error() && first.is_null(); return !error() && first.is_null();
} }
simdjson_inline bool simdjson_result<dom::element>::is_bigint() const noexcept {
return !error() && first.is_bigint();
}
simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::operator[](std::string_view key) const noexcept { simdjson_inline simdjson_result<dom::element> simdjson_result<dom::element>::operator[](std::string_view key) const noexcept {
if (error()) { return error(); } if (error()) { return error(); }
@@ -225,15 +218,6 @@ inline simdjson_result<bool> element::get_bool() const noexcept {
} }
return INCORRECT_TYPE; return INCORRECT_TYPE;
} }
inline simdjson_result<std::string_view> element::get_bigint() const noexcept {
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable());
switch (tape.tape_ref_type()) {
case internal::tape_type::BIGINT:
return tape.get_string_view();
default:
return INCORRECT_TYPE;
}
}
inline simdjson_result<const char *> element::get_c_str() const noexcept { inline simdjson_result<const char *> element::get_c_str() const noexcept {
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914 SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
switch (tape.tape_ref_type()) { switch (tape.tape_ref_type()) {
@@ -376,10 +360,6 @@ inline bool element::is_null() const noexcept {
return tape.is_null_on_tape(); return tape.is_null_on_tape();
} }
inline bool element::is_bigint() const noexcept {
return tape.tape_ref_type() == internal::tape_type::BIGINT;
}
#if SIMDJSON_EXCEPTIONS #if SIMDJSON_EXCEPTIONS
inline element::operator bool() const noexcept(false) { return get<bool>(); } inline element::operator bool() const noexcept(false) { return get<bool>(); }
@@ -512,8 +492,6 @@ inline std::ostream& operator<<(std::ostream& out, element_type type) {
return out << "bool"; return out << "bool";
case element_type::NULL_VALUE: case element_type::NULL_VALUE:
return out << "null"; return out << "null";
case element_type::BIGINT:
return out << "bigint";
default: default:
return out << "unexpected content!!!"; // abort() usage is forbidden in the library return out << "unexpected content!!!"; // abort() usage is forbidden in the library
} }
+1 -17
View File
@@ -21,8 +21,7 @@ enum class element_type {
DOUBLE = 'd', ///< double: Any number with a "." or "e" that fits in double. DOUBLE = 'd', ///< double: Any number with a "." or "e" that fits in double.
STRING = '"', ///< std::string_view STRING = '"', ///< std::string_view
BOOL = 't', ///< bool BOOL = 't', ///< bool
NULL_VALUE = 'n', ///< null NULL_VALUE = 'n' ///< null
BIGINT = 'Z' ///< std::string_view: big integer stored as raw digit string
}; };
/** /**
@@ -121,14 +120,6 @@ public:
*/ */
inline simdjson_result<bool> get_bool() const noexcept; inline simdjson_result<bool> get_bool() const noexcept;
/**
* Read this element as a big integer (raw digit string).
*
* @returns A string_view of the raw digits, or:
* INCORRECT_TYPE if the JSON element is not a big integer.
*/
inline simdjson_result<std::string_view> get_bigint() const noexcept;
/** /**
* Whether this element is a json array. * Whether this element is a json array.
* *
@@ -184,11 +175,6 @@ public:
*/ */
inline bool is_null() const noexcept; inline bool is_null() const noexcept;
/**
* Whether this element is a big integer (number exceeding 64-bit range).
*/
inline bool is_bigint() const noexcept;
/** /**
* Tell whether the value can be cast to provided type (T). * Tell whether the value can be cast to provided type (T).
* *
@@ -547,7 +533,6 @@ public:
simdjson_inline simdjson_result<uint64_t> get_uint64() const noexcept; simdjson_inline simdjson_result<uint64_t> get_uint64() const noexcept;
simdjson_inline simdjson_result<double> get_double() const noexcept; simdjson_inline simdjson_result<double> get_double() const noexcept;
simdjson_inline simdjson_result<bool> get_bool() const noexcept; simdjson_inline simdjson_result<bool> get_bool() const noexcept;
simdjson_inline simdjson_result<std::string_view> get_bigint() const noexcept;
simdjson_inline bool is_array() const noexcept; simdjson_inline bool is_array() const noexcept;
simdjson_inline bool is_object() const noexcept; simdjson_inline bool is_object() const noexcept;
@@ -558,7 +543,6 @@ public:
simdjson_inline bool is_number() const noexcept; simdjson_inline bool is_number() const noexcept;
simdjson_inline bool is_bool() const noexcept; simdjson_inline bool is_bool() const noexcept;
simdjson_inline bool is_null() const noexcept; simdjson_inline bool is_null() const noexcept;
simdjson_inline bool is_bigint() const noexcept;
simdjson_inline simdjson_result<dom::element> operator[](std::string_view key) const noexcept; simdjson_inline simdjson_result<dom::element> operator[](std::string_view key) const noexcept;
simdjson_inline simdjson_result<dom::element> operator[](const char *key) const noexcept; simdjson_inline simdjson_result<dom::element> operator[](const char *key) const noexcept;
+1 -3
View File
@@ -36,11 +36,10 @@ inline bool parser::dump_raw_tape(std::ostream &os) const noexcept {
} }
inline simdjson_result<size_t> parser::read_file(std::string_view path) noexcept { inline simdjson_result<size_t> parser::read_file(std::string_view path) noexcept {
const std::string path_copy(path);
// Open the file // Open the file
SIMDJSON_PUSH_DISABLE_WARNINGS SIMDJSON_PUSH_DISABLE_WARNINGS
SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe
std::FILE *fp = std::fopen(path_copy.c_str(), "rb"); std::FILE *fp = std::fopen(path.data(), "rb");
SIMDJSON_POP_DISABLE_WARNINGS SIMDJSON_POP_DISABLE_WARNINGS
if (fp == nullptr) { if (fp == nullptr) {
@@ -133,7 +132,6 @@ inline simdjson_result<element> parser::parse_into_document(document& provided_d
buf += 3; buf += 3;
len -= 3; len -= 3;
} }
implementation->_number_as_string = _number_as_string;
_error = implementation->parse(buf, len, provided_doc); _error = implementation->parse(buf, len, provided_doc);
if (_error) { return _error; } if (_error) { return _error; }
-10
View File
@@ -610,13 +610,6 @@ public:
inline bool dump_raw_tape(std::ostream &os) const noexcept; inline bool dump_raw_tape(std::ostream &os) const noexcept;
/**
* When enabled, big integers (exceeding uint64 range) are stored as strings
* in the tape instead of returning BIGINT_ERROR. Default: false.
*/
inline void number_as_string(bool enabled) noexcept { _number_as_string = enabled; }
inline bool number_as_string() const noexcept { return _number_as_string; }
private: private:
/** /**
* The maximum document length this parser will automatically support. * The maximum document length this parser will automatically support.
@@ -625,9 +618,6 @@ private:
*/ */
size_t _max_capacity; size_t _max_capacity;
/** Whether to store big integers as strings instead of returning BIGINT_ERROR */
bool _number_as_string{false};
/** /**
* The loaded buffer (reused each time load() is called) * The loaded buffer (reused each time load() is called)
*/ */
-6
View File
@@ -460,12 +460,6 @@ inline void string_builder<serializer>::append(simdjson::dom::element value) {
case tape_type::STRING: case tape_type::STRING:
format.string(iter.get_string_view()); format.string(iter.get_string_view());
break; break;
case tape_type::BIGINT: {
// Big integer stored as string — output raw digits (no quotes)
auto sv = iter.get_string_view();
format.chars(sv.data(), sv.data() + sv.size());
break;
}
case tape_type::INT64: case tape_type::INT64:
format.number(iter.next_tape_value<int64_t>()); format.number(iter.next_tape_value<int64_t>());
iter.json_index++; // numbers take up 2 spots, so we need to increment iter.json_index++; // numbers take up 2 spots, so we need to increment
-17
View File
@@ -1,17 +0,0 @@
#pragma once
#if !defined(SIMDJSON_FEATURE_DOM_API)
#define SIMDJSON_FEATURE_DOM_API 1
#endif
#if !defined(SIMDJSON_FEATURE_ONDEMAND_API)
#define SIMDJSON_FEATURE_ONDEMAND_API 1
#endif
#if !defined(SIMDJSON_FEATURE_BUILDER_API)
#define SIMDJSON_FEATURE_BUILDER_API 1
#endif
#if !SIMDJSON_FEATURE_DOM_API && !SIMDJSON_FEATURE_ONDEMAND_API
#error "simdjson: at least one of SIMDJSON_FEATURE_DOM_API or SIMDJSON_FEATURE_ONDEMAND_API must be enabled."
#endif
@@ -22,7 +22,7 @@ namespace SIMDJSON_IMPLEMENTATION {
namespace builder { namespace builder {
template <class T> template <class T>
requires(concepts::container_but_not_string<T> && ! concepts::optional_type<T> && !require_custom_serialization<T>) requires(concepts::container_but_not_string<T> && !require_custom_serialization<T>)
constexpr void atom(string_builder &b, const T &t) { constexpr void atom(string_builder &b, const T &t) {
auto it = t.begin(); auto it = t.begin();
auto end = t.end(); auto end = t.end();
@@ -130,7 +130,7 @@ template <typename T>
requires(std::is_enum_v<T> && !require_custom_serialization<T>) requires(std::is_enum_v<T> && !require_custom_serialization<T>)
void atom(string_builder &b, const T &e) { void atom(string_builder &b, const T &e) {
#if SIMDJSON_STATIC_REFLECTION #if SIMDJSON_STATIC_REFLECTION
static constexpr auto enumerators = std::define_static_array(std::meta::enumerators_of(^^T)); constexpr auto enumerators = std::define_static_array(std::meta::enumerators_of(^^T));
template for (constexpr auto enum_val : enumerators) { template for (constexpr auto enum_val : enumerators) {
constexpr auto enum_str = std::define_static_string(constevalutil::consteval_to_quoted_escaped(std::meta::identifier_of(enum_val))); constexpr auto enum_str = std::define_static_string(constevalutil::consteval_to_quoted_escaped(std::meta::identifier_of(enum_val)));
if (e == [:enum_val:]) { if (e == [:enum_val:]) {
@@ -294,23 +294,30 @@ string_builder& operator<<(string_builder& b, const Z& z) {
template<constevalutil::fixed_string... FieldNames, typename T> template<constevalutil::fixed_string... FieldNames, typename T>
requires(std::is_class_v<T> && (sizeof...(FieldNames) > 0)) requires(std::is_class_v<T> && (sizeof...(FieldNames) > 0))
void extract_from(string_builder &b, const T &obj) { void extract_from(string_builder &b, const T &obj) {
// Helper to check if a field name matches any of the requested fields
auto should_extract = [](std::string_view field_name) constexpr -> bool {
return ((FieldNames.view() == field_name) || ...);
};
b.append('{'); b.append('{');
bool first = true; bool first = true;
// Iterate through all members of T using reflection // Iterate through all members of T using reflection
static constexpr auto members = std::define_static_array(std::meta::nonstatic_data_members_of(^^T, std::meta::access_context::unchecked())); template for (constexpr auto mem : std::define_static_array(
template for (constexpr auto mem : members) { std::meta::nonstatic_data_members_of(^^T, std::meta::access_context::unchecked()))) {
if constexpr (std::meta::is_public(mem)) { if constexpr (std::meta::is_public(mem)) {
static constexpr std::string_view key = std::define_static_string(std::meta::identifier_of(mem)); constexpr std::string_view key = std::define_static_string(std::meta::identifier_of(mem));
// Only serialize this field if it's in our list of requested fields // Only serialize this field if it's in our list of requested fields
if constexpr (((FieldNames.view() == key) || ...)) { if constexpr (should_extract(key)) {
if (!first) { if (!first) {
b.append(','); b.append(',');
} }
first = false; first = false;
// Serialize the key // Serialize the key
static constexpr auto quoted_key = std::define_static_string(constevalutil::consteval_to_quoted_escaped(std::meta::identifier_of(mem))); constexpr auto quoted_key = std::define_static_string(constevalutil::consteval_to_quoted_escaped(std::meta::identifier_of(mem)));
b.append_raw(quoted_key); b.append_raw(quoted_key);
b.append(':'); b.append(':');
@@ -505,7 +505,7 @@ simdjson_inline bool string_builder::capacity_check(size_t upcoming_bytes) {
return is_valid; return is_valid;
} }
inline void string_builder::grow_buffer(size_t desired_capacity) { simdjson_inline void string_builder::grow_buffer(size_t desired_capacity) {
if (!is_valid) { if (!is_valid) {
return; return;
} }
@@ -842,7 +842,7 @@ simdjson_inline void string_builder::append(const T &value) {
#if SIMDJSON_SUPPORTS_RANGES && SIMDJSON_SUPPORTS_CONCEPTS #if SIMDJSON_SUPPORTS_RANGES && SIMDJSON_SUPPORTS_CONCEPTS
// Support for range-based appending (std::ranges::view, etc.) // Support for range-based appending (std::ranges::view, etc.)
template <std::ranges::range R> template <std::ranges::range R>
requires(!std::is_convertible<R, std::string_view>::value && !concepts::optional_type<R> && !require_custom_serialization<R>) requires(!std::is_convertible<R, std::string_view>::value && !require_custom_serialization<R>)
simdjson_inline void string_builder::append(const R &range) noexcept { simdjson_inline void string_builder::append(const R &range) noexcept {
auto it = std::ranges::begin(range); auto it = std::ranges::begin(range);
auto end = std::ranges::end(range); auto end = std::ranges::end(range);
@@ -171,7 +171,7 @@ public:
#if SIMDJSON_SUPPORTS_RANGES && SIMDJSON_SUPPORTS_CONCEPTS #if SIMDJSON_SUPPORTS_RANGES && SIMDJSON_SUPPORTS_CONCEPTS
// Support for range-based appending (std::ranges::view, etc.) // Support for range-based appending (std::ranges::view, etc.)
template <std::ranges::range R> template <std::ranges::range R>
requires (!std::is_convertible<R, std::string_view>::value && !concepts::optional_type<R> && !require_custom_serialization<R>) requires (!std::is_convertible<R, std::string_view>::value && !require_custom_serialization<R>)
simdjson_inline void append(const R &range) noexcept; simdjson_inline void append(const R &range) noexcept;
#endif #endif
/** /**
@@ -249,7 +249,7 @@ private:
* If the allocation fails, is_valid is set to false. We expect * If the allocation fails, is_valid is set to false. We expect
* that this function would not be repeatedly called. * that this function would not be repeatedly called.
*/ */
inline void grow_buffer(size_t desired_capacity); simdjson_inline void grow_buffer(size_t desired_capacity);
/** /**
* We use this helper function to make sure that is_valid is kept consistent. * We use this helper function to make sure that is_valid is kept consistent.
@@ -1,10 +1,4 @@
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_BUILDER_DEPENDENCIES_H)
#include "simdjson/feature_macros.h"
#endif // SIMDJSON_CONDITIONAL_INCLUDE
#if SIMDJSON_FEATURE_ONDEMAND_API
#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_ONDEMAND_DEPENDENCIES_H)
#error simdjson/generic/ondemand/dependencies.h must be included before simdjson/generic/ondemand/amalgamated.h! #error simdjson/generic/ondemand/dependencies.h must be included before simdjson/generic/ondemand/amalgamated.h!
#endif #endif
@@ -54,5 +48,3 @@
// JSON path accessor (compile-time) - must be after inline definitions // JSON path accessor (compile-time) - must be after inline definitions
#include "simdjson/generic/ondemand/compile_time_accessors.h" #include "simdjson/generic/ondemand/compile_time_accessors.h"
#endif // SIMDJSON_FEATURE_ONDEMAND_API
@@ -8,7 +8,6 @@
// Internal headers needed for ondemand generics. // Internal headers needed for ondemand generics.
// All includes not under simdjson/generic/ondemand must be here! // All includes not under simdjson/generic/ondemand must be here!
// Otherwise, amalgamation will fail. // Otherwise, amalgamation will fail.
#include "simdjson/feature_macros.h"
#include "simdjson/dom/base.h" // for MINIMAL_DOCUMENT_CAPACITY #include "simdjson/dom/base.h" // for MINIMAL_DOCUMENT_CAPACITY
#include "simdjson/implementation.h" #include "simdjson/implementation.h"
#include "simdjson/padded_string.h" #include "simdjson/padded_string.h"
@@ -16,8 +16,6 @@
#include "simdjson/generic/ondemand/deserialize.h" #include "simdjson/generic/ondemand/deserialize.h"
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
#include <limits>
namespace simdjson { namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION { namespace SIMDJSON_IMPLEMENTATION {
namespace ondemand { namespace ondemand {
@@ -133,18 +131,6 @@ simdjson_inline simdjson_result<int64_t> document::get_int64() noexcept {
simdjson_inline simdjson_result<int64_t> document::get_int64_in_string() noexcept { simdjson_inline simdjson_result<int64_t> document::get_int64_in_string() noexcept {
return get_root_value_iterator().get_root_int64_in_string(true); return get_root_value_iterator().get_root_int64_in_string(true);
} }
simdjson_inline simdjson_result<uint32_t> document::get_uint32() noexcept {
uint64_t result;
SIMDJSON_TRY(get_uint64().get(result));
if (result > (std::numeric_limits<uint32_t>::max)()) { return NUMBER_OUT_OF_RANGE; }
return static_cast<uint32_t>(result);
}
simdjson_inline simdjson_result<int32_t> document::get_int32() noexcept {
int64_t result;
SIMDJSON_TRY(get_int64().get(result));
if (result > (std::numeric_limits<int32_t>::max)() || result < (std::numeric_limits<int32_t>::min)()) { return NUMBER_OUT_OF_RANGE; }
return static_cast<int32_t>(result);
}
simdjson_inline simdjson_result<double> document::get_double() noexcept { simdjson_inline simdjson_result<double> document::get_double() noexcept {
return get_root_value_iterator().get_root_double(true); return get_root_value_iterator().get_root_double(true);
} }
@@ -178,8 +164,6 @@ template<> simdjson_inline simdjson_result<std::string_view> document::get() & n
template<> simdjson_inline simdjson_result<double> document::get() & noexcept { return get_double(); } template<> simdjson_inline simdjson_result<double> document::get() & noexcept { return get_double(); }
template<> simdjson_inline simdjson_result<uint64_t> document::get() & noexcept { return get_uint64(); } template<> simdjson_inline simdjson_result<uint64_t> document::get() & noexcept { return get_uint64(); }
template<> simdjson_inline simdjson_result<int64_t> document::get() & noexcept { return get_int64(); } template<> simdjson_inline simdjson_result<int64_t> document::get() & noexcept { return get_int64(); }
template<> simdjson_inline simdjson_result<uint32_t> document::get() & noexcept { return get_uint32(); }
template<> simdjson_inline simdjson_result<int32_t> document::get() & noexcept { return get_int32(); }
template<> simdjson_inline simdjson_result<bool> document::get() & noexcept { return get_bool(); } template<> simdjson_inline simdjson_result<bool> document::get() & noexcept { return get_bool(); }
template<> simdjson_inline simdjson_result<value> document::get() & noexcept { return get_value(); } template<> simdjson_inline simdjson_result<value> document::get() & noexcept { return get_value(); }
@@ -190,8 +174,6 @@ template<> simdjson_warn_unused simdjson_inline error_code document::get(std::st
template<> simdjson_warn_unused simdjson_inline error_code document::get(double& out) & noexcept { return get_double().get(out); } template<> simdjson_warn_unused simdjson_inline error_code document::get(double& out) & noexcept { return get_double().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code document::get(uint64_t& out) & noexcept { return get_uint64().get(out); } template<> simdjson_warn_unused simdjson_inline error_code document::get(uint64_t& out) & noexcept { return get_uint64().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code document::get(int64_t& out) & noexcept { return get_int64().get(out); } template<> simdjson_warn_unused simdjson_inline error_code document::get(int64_t& out) & noexcept { return get_int64().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code document::get(uint32_t& out) & noexcept { return get_uint32().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code document::get(int32_t& out) & noexcept { return get_int32().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code document::get(bool& out) & noexcept { return get_bool().get(out); } template<> simdjson_warn_unused simdjson_inline error_code document::get(bool& out) & noexcept { return get_bool().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code document::get(value& out) & noexcept { return get_value().get(out); } template<> simdjson_warn_unused simdjson_inline error_code document::get(value& out) & noexcept { return get_value().get(out); }
@@ -522,14 +504,6 @@ simdjson_inline simdjson_result<int64_t> simdjson_result<SIMDJSON_IMPLEMENTATION
if (error()) { return error(); } if (error()) { return error(); }
return first.get_int64_in_string(); return first.get_int64_in_string();
} }
simdjson_inline simdjson_result<uint32_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get_uint32() noexcept {
if (error()) { return error(); }
return first.get_uint32();
}
simdjson_inline simdjson_result<int32_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get_int32() noexcept {
if (error()) { return error(); }
return first.get_int32();
}
simdjson_inline simdjson_result<double> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get_double() noexcept { simdjson_inline simdjson_result<double> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get_double() noexcept {
if (error()) { return error(); } if (error()) { return error(); }
return first.get_double(); return first.get_double();
@@ -653,27 +627,27 @@ simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::op
} }
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator uint64_t() noexcept(false) { simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator uint64_t() noexcept(false) {
if (error()) { throw simdjson_error(error()); } if (error()) { throw simdjson_error(error()); }
return first.get_uint64(); return first;
} }
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator int64_t() noexcept(false) { simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator int64_t() noexcept(false) {
if (error()) { throw simdjson_error(error()); } if (error()) { throw simdjson_error(error()); }
return first.get_int64(); return first;
} }
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator double() noexcept(false) { simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator double() noexcept(false) {
if (error()) { throw simdjson_error(error()); } if (error()) { throw simdjson_error(error()); }
return first.get_double(); return first;
} }
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator std::string_view() noexcept(false) { simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator std::string_view() noexcept(false) {
if (error()) { throw simdjson_error(error()); } if (error()) { throw simdjson_error(error()); }
return first.get_string(); return first;
} }
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false) { simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false) {
if (error()) { throw simdjson_error(error()); } if (error()) { throw simdjson_error(error()); }
return first.get_raw_json_string(); return first;
} }
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator bool() noexcept(false) { simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator bool() noexcept(false) {
if (error()) { throw simdjson_error(error()); } if (error()) { throw simdjson_error(error()); }
return first.get_bool(); return first;
} }
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false) { simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false) {
if (error()) { throw simdjson_error(error()); } if (error()) { throw simdjson_error(error()); }
@@ -757,18 +731,6 @@ simdjson_inline simdjson_result<uint64_t> document_reference::get_uint64() noexc
simdjson_inline simdjson_result<uint64_t> document_reference::get_uint64_in_string() noexcept { return doc->get_root_value_iterator().get_root_uint64_in_string(false); } simdjson_inline simdjson_result<uint64_t> document_reference::get_uint64_in_string() noexcept { return doc->get_root_value_iterator().get_root_uint64_in_string(false); }
simdjson_inline simdjson_result<int64_t> document_reference::get_int64() noexcept { return doc->get_root_value_iterator().get_root_int64(false); } simdjson_inline simdjson_result<int64_t> document_reference::get_int64() noexcept { return doc->get_root_value_iterator().get_root_int64(false); }
simdjson_inline simdjson_result<int64_t> document_reference::get_int64_in_string() noexcept { return doc->get_root_value_iterator().get_root_int64_in_string(false); } simdjson_inline simdjson_result<int64_t> document_reference::get_int64_in_string() noexcept { return doc->get_root_value_iterator().get_root_int64_in_string(false); }
simdjson_inline simdjson_result<uint32_t> document_reference::get_uint32() noexcept {
uint64_t result;
SIMDJSON_TRY(doc->get_root_value_iterator().get_root_uint64(false).get(result));
if (result > (std::numeric_limits<uint32_t>::max)()) { return NUMBER_OUT_OF_RANGE; }
return static_cast<uint32_t>(result);
}
simdjson_inline simdjson_result<int32_t> document_reference::get_int32() noexcept {
int64_t result;
SIMDJSON_TRY(doc->get_root_value_iterator().get_root_int64(false).get(result));
if (result > (std::numeric_limits<int32_t>::max)() || result < (std::numeric_limits<int32_t>::min)()) { return NUMBER_OUT_OF_RANGE; }
return static_cast<int32_t>(result);
}
simdjson_inline simdjson_result<double> document_reference::get_double() noexcept { return doc->get_root_value_iterator().get_root_double(false); } simdjson_inline simdjson_result<double> document_reference::get_double() noexcept { return doc->get_root_value_iterator().get_root_double(false); }
simdjson_inline simdjson_result<double> document_reference::get_double_in_string() noexcept { return doc->get_root_value_iterator().get_root_double(false); } simdjson_inline simdjson_result<double> document_reference::get_double_in_string() noexcept { return doc->get_root_value_iterator().get_root_double(false); }
simdjson_inline simdjson_result<std::string_view> document_reference::get_string(bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(false, allow_replacement); } simdjson_inline simdjson_result<std::string_view> document_reference::get_string(bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(false, allow_replacement); }
@@ -786,8 +748,6 @@ template<> simdjson_inline simdjson_result<std::string_view> document_reference:
template<> simdjson_inline simdjson_result<double> document_reference::get() & noexcept { return get_double(); } template<> simdjson_inline simdjson_result<double> document_reference::get() & noexcept { return get_double(); }
template<> simdjson_inline simdjson_result<uint64_t> document_reference::get() & noexcept { return get_uint64(); } template<> simdjson_inline simdjson_result<uint64_t> document_reference::get() & noexcept { return get_uint64(); }
template<> simdjson_inline simdjson_result<int64_t> document_reference::get() & noexcept { return get_int64(); } template<> simdjson_inline simdjson_result<int64_t> document_reference::get() & noexcept { return get_int64(); }
template<> simdjson_inline simdjson_result<uint32_t> document_reference::get() & noexcept { return get_uint32(); }
template<> simdjson_inline simdjson_result<int32_t> document_reference::get() & noexcept { return get_int32(); }
template<> simdjson_inline simdjson_result<bool> document_reference::get() & noexcept { return get_bool(); } template<> simdjson_inline simdjson_result<bool> document_reference::get() & noexcept { return get_bool(); }
template<> simdjson_inline simdjson_result<value> document_reference::get() & noexcept { return get_value(); } template<> simdjson_inline simdjson_result<value> document_reference::get() & noexcept { return get_value(); }
#if SIMDJSON_EXCEPTIONS #if SIMDJSON_EXCEPTIONS
@@ -919,14 +879,6 @@ simdjson_inline simdjson_result<int64_t> simdjson_result<SIMDJSON_IMPLEMENTATION
if (error()) { return error(); } if (error()) { return error(); }
return first.get_int64_in_string(); return first.get_int64_in_string();
} }
simdjson_inline simdjson_result<uint32_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::get_uint32() noexcept {
if (error()) { return error(); }
return first.get_uint32();
}
simdjson_inline simdjson_result<int32_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::get_int32() noexcept {
if (error()) { return error(); }
return first.get_int32();
}
simdjson_inline simdjson_result<double> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::get_double() noexcept { simdjson_inline simdjson_result<double> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::get_double() noexcept {
if (error()) { return error(); } if (error()) { return error(); }
return first.get_double(); return first.get_double();
@@ -1042,27 +994,27 @@ simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_refe
} }
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator uint64_t() noexcept(false) { simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator uint64_t() noexcept(false) {
if (error()) { throw simdjson_error(error()); } if (error()) { throw simdjson_error(error()); }
return first.get_uint64(); return first;
} }
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator int64_t() noexcept(false) { simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator int64_t() noexcept(false) {
if (error()) { throw simdjson_error(error()); } if (error()) { throw simdjson_error(error()); }
return first.get_int64(); return first;
} }
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator double() noexcept(false) { simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator double() noexcept(false) {
if (error()) { throw simdjson_error(error()); } if (error()) { throw simdjson_error(error()); }
return first.get_double(); return first;
} }
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator std::string_view() noexcept(false) { simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator std::string_view() noexcept(false) {
if (error()) { throw simdjson_error(error()); } if (error()) { throw simdjson_error(error()); }
return first.get_string(); return first;
} }
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false) { simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false) {
if (error()) { throw simdjson_error(error()); } if (error()) { throw simdjson_error(error()); }
return first.get_raw_json_string(); return first;
} }
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator bool() noexcept(false) { simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator bool() noexcept(false) {
if (error()) { throw simdjson_error(error()); } if (error()) { throw simdjson_error(error()); }
return first.get_bool(); return first;
} }
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false) { simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false) {
if (error()) { throw simdjson_error(error()); } if (error()) { throw simdjson_error(error()); }
+24 -50
View File
@@ -76,26 +76,6 @@ public:
* @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer. * @returns INCORRECT_TYPE If the JSON value is not a 64-bit integer.
*/ */
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept; simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
/**
* Cast this JSON value to a 32-bit unsigned integer.
*
* Calls get_uint64() and checks that the result fits in a uint32_t.
*
* @returns A 32-bit unsigned integer.
* @returns INCORRECT_TYPE If the JSON value is not an unsigned integer.
* @returns NUMBER_OUT_OF_RANGE If the value does not fit in a uint32_t.
*/
simdjson_inline simdjson_result<uint32_t> get_uint32() noexcept;
/**
* Cast this JSON value to a 32-bit signed integer.
*
* Calls get_int64() and checks that the result fits in an int32_t.
*
* @returns A 32-bit signed integer.
* @returns INCORRECT_TYPE If the JSON value is not an integer.
* @returns NUMBER_OUT_OF_RANGE If the value does not fit in an int32_t.
*/
simdjson_inline simdjson_result<int32_t> get_int32() noexcept;
/** /**
* Cast this JSON value to a double. * Cast this JSON value to a double.
* *
@@ -319,21 +299,21 @@ public:
* @returns A signed 64-bit integer. * @returns A signed 64-bit integer.
* @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit unsigned integer. * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit unsigned integer.
*/ */
explicit simdjson_inline operator uint64_t() noexcept(false); simdjson_inline operator uint64_t() noexcept(false);
/** /**
* Cast this JSON value to a signed integer. * Cast this JSON value to a signed integer.
* *
* @returns A signed 64-bit integer. * @returns A signed 64-bit integer.
* @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit integer. * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a 64-bit integer.
*/ */
explicit simdjson_inline operator int64_t() noexcept(false); simdjson_inline operator int64_t() noexcept(false);
/** /**
* Cast this JSON value to a double. * Cast this JSON value to a double.
* *
* @returns A double. * @returns A double.
* @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a valid floating-point number. * @exception simdjson_error(INCORRECT_TYPE) If the JSON value is not a valid floating-point number.
*/ */
explicit simdjson_inline operator double() noexcept(false); simdjson_inline operator double() noexcept(false);
/** /**
* Cast this JSON value to a string. * Cast this JSON value to a string.
* *
@@ -343,7 +323,7 @@ public:
* time it parses a document or when it is destroyed. * time it parses a document or when it is destroyed.
* @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string.
*/ */
explicit simdjson_inline operator std::string_view() noexcept(false) simdjson_lifetime_bound; simdjson_inline operator std::string_view() noexcept(false) simdjson_lifetime_bound;
/** /**
* Cast this JSON value to a raw_json_string. * Cast this JSON value to a raw_json_string.
* *
@@ -352,14 +332,14 @@ public:
* @returns A pointer to the raw JSON for the given string. * @returns A pointer to the raw JSON for the given string.
* @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string. * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not a string.
*/ */
explicit simdjson_inline operator raw_json_string() noexcept(false) simdjson_lifetime_bound; simdjson_inline operator raw_json_string() noexcept(false) simdjson_lifetime_bound;
/** /**
* Cast this JSON value to a bool. * Cast this JSON value to a bool.
* *
* @returns A bool value. * @returns A bool value.
* @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not true or false. * @exception simdjson_error(INCORRECT_TYPE) if the JSON value is not true or false.
*/ */
explicit simdjson_inline operator bool() noexcept(false); simdjson_inline operator bool() noexcept(false);
/** /**
* Cast this JSON value to a value when the document is an object or an array. * Cast this JSON value to a value when the document is an object or an array.
* *
@@ -849,8 +829,6 @@ public:
simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept; simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64() noexcept; simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept; simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
simdjson_inline simdjson_result<uint32_t> get_uint32() noexcept;
simdjson_inline simdjson_result<int32_t> get_int32() noexcept;
simdjson_inline simdjson_result<double> get_double() noexcept; simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept; simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept; simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
@@ -945,12 +923,12 @@ public:
explicit simdjson_inline operator T() noexcept(false); explicit simdjson_inline operator T() noexcept(false);
simdjson_inline operator array() & noexcept(false); simdjson_inline operator array() & noexcept(false);
simdjson_inline operator object() & noexcept(false); simdjson_inline operator object() & noexcept(false);
explicit simdjson_inline operator uint64_t() noexcept(false); simdjson_inline operator uint64_t() noexcept(false);
explicit simdjson_inline operator int64_t() noexcept(false); simdjson_inline operator int64_t() noexcept(false);
explicit simdjson_inline operator double() noexcept(false); simdjson_inline operator double() noexcept(false);
explicit simdjson_inline operator std::string_view() noexcept(false); simdjson_inline operator std::string_view() noexcept(false);
explicit simdjson_inline operator raw_json_string() noexcept(false); simdjson_inline operator raw_json_string() noexcept(false);
explicit simdjson_inline operator bool() noexcept(false); simdjson_inline operator bool() noexcept(false);
simdjson_inline operator value() noexcept(false); simdjson_inline operator value() noexcept(false);
#endif #endif
simdjson_inline simdjson_result<size_t> count_elements() & noexcept; simdjson_inline simdjson_result<size_t> count_elements() & noexcept;
@@ -1004,8 +982,6 @@ public:
simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept; simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64() noexcept; simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept; simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
simdjson_inline simdjson_result<uint32_t> get_uint32() noexcept;
simdjson_inline simdjson_result<int32_t> get_int32() noexcept;
simdjson_inline simdjson_result<double> get_double() noexcept; simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept; simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept; simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
@@ -1030,12 +1006,12 @@ public:
explicit simdjson_inline operator T() noexcept(false); explicit simdjson_inline operator T() noexcept(false);
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::array() & noexcept(false); simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::array() & noexcept(false);
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::object() & noexcept(false); simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::object() & noexcept(false);
explicit simdjson_inline operator uint64_t() noexcept(false); simdjson_inline operator uint64_t() noexcept(false);
explicit simdjson_inline operator int64_t() noexcept(false); simdjson_inline operator int64_t() noexcept(false);
explicit simdjson_inline operator double() noexcept(false); simdjson_inline operator double() noexcept(false);
explicit simdjson_inline operator std::string_view() noexcept(false); simdjson_inline operator std::string_view() noexcept(false);
explicit simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false); simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false);
explicit simdjson_inline operator bool() noexcept(false); simdjson_inline operator bool() noexcept(false);
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false); simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false);
#endif #endif
simdjson_inline simdjson_result<size_t> count_elements() & noexcept; simdjson_inline simdjson_result<size_t> count_elements() & noexcept;
@@ -1093,8 +1069,6 @@ public:
simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept; simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64() noexcept; simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept; simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
simdjson_inline simdjson_result<uint32_t> get_uint32() noexcept;
simdjson_inline simdjson_result<int32_t> get_int32() noexcept;
simdjson_inline simdjson_result<double> get_double() noexcept; simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept; simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept; simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
@@ -1116,12 +1090,12 @@ public:
explicit simdjson_inline operator T() noexcept(false); explicit simdjson_inline operator T() noexcept(false);
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::array() & noexcept(false); simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::array() & noexcept(false);
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::object() & noexcept(false); simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::object() & noexcept(false);
explicit simdjson_inline operator uint64_t() noexcept(false); simdjson_inline operator uint64_t() noexcept(false);
explicit simdjson_inline operator int64_t() noexcept(false); simdjson_inline operator int64_t() noexcept(false);
explicit simdjson_inline operator double() noexcept(false); simdjson_inline operator double() noexcept(false);
explicit simdjson_inline operator std::string_view() noexcept(false); simdjson_inline operator std::string_view() noexcept(false);
explicit simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false); simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string() noexcept(false);
explicit simdjson_inline operator bool() noexcept(false); simdjson_inline operator bool() noexcept(false);
simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false); simdjson_inline operator SIMDJSON_IMPLEMENTATION::ondemand::value() noexcept(false);
#endif #endif
simdjson_inline simdjson_result<size_t> count_elements() & noexcept; simdjson_inline simdjson_result<size_t> count_elements() & noexcept;
@@ -172,7 +172,7 @@ simdjson_pure simdjson_inline size_t parser::max_depth() const noexcept {
} }
simdjson_inline void parser::set_max_capacity(size_t max_capacity) noexcept { simdjson_inline void parser::set_max_capacity(size_t max_capacity) noexcept {
if(max_capacity > dom::MINIMAL_DOCUMENT_CAPACITY) { if(max_capacity < dom::MINIMAL_DOCUMENT_CAPACITY) {
_max_capacity = max_capacity; _max_capacity = max_capacity;
} else { } else {
_max_capacity = dom::MINIMAL_DOCUMENT_CAPACITY; _max_capacity = dom::MINIMAL_DOCUMENT_CAPACITY;
@@ -305,7 +305,7 @@ error_code tag_invoke(deserialize_tag, ValT &val, T &out) noexcept {
#if SIMDJSON_STATIC_REFLECTION #if SIMDJSON_STATIC_REFLECTION
std::string_view str; std::string_view str;
SIMDJSON_TRY(val.get_string().get(str)); SIMDJSON_TRY(val.get_string().get(str));
static constexpr auto enumerators = std::define_static_array(std::meta::enumerators_of(^^T)); constexpr auto enumerators = std::define_static_array(std::meta::enumerators_of(^^T));
template for (constexpr auto enum_val : enumerators) { template for (constexpr auto enum_val : enumerators) {
if (str == std::meta::identifier_of(enum_val)) { if (str == std::meta::identifier_of(enum_val)) {
out = [:enum_val:]; out = [:enum_val:];
@@ -12,8 +12,6 @@
#include "simdjson/generic/ondemand/value.h" #include "simdjson/generic/ondemand/value.h"
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
#include <limits>
namespace simdjson { namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION { namespace SIMDJSON_IMPLEMENTATION {
namespace ondemand { namespace ondemand {
@@ -74,18 +72,6 @@ simdjson_inline simdjson_result<int64_t> value::get_int64() noexcept {
simdjson_inline simdjson_result<int64_t> value::get_int64_in_string() noexcept { simdjson_inline simdjson_result<int64_t> value::get_int64_in_string() noexcept {
return iter.get_int64_in_string(); return iter.get_int64_in_string();
} }
simdjson_inline simdjson_result<uint32_t> value::get_uint32() noexcept {
uint64_t result;
SIMDJSON_TRY(get_uint64().get(result));
if (result > (std::numeric_limits<uint32_t>::max)()) { return NUMBER_OUT_OF_RANGE; }
return static_cast<uint32_t>(result);
}
simdjson_inline simdjson_result<int32_t> value::get_int32() noexcept {
int64_t result;
SIMDJSON_TRY(get_int64().get(result));
if (result > (std::numeric_limits<int32_t>::max)() || result < (std::numeric_limits<int32_t>::min)()) { return NUMBER_OUT_OF_RANGE; }
return static_cast<int32_t>(result);
}
simdjson_inline simdjson_result<bool> value::get_bool() noexcept { simdjson_inline simdjson_result<bool> value::get_bool() noexcept {
return iter.get_bool(); return iter.get_bool();
} }
@@ -101,8 +87,6 @@ template<> simdjson_inline simdjson_result<number> value::get() noexcept { retur
template<> simdjson_inline simdjson_result<double> value::get() noexcept { return get_double(); } template<> simdjson_inline simdjson_result<double> value::get() noexcept { return get_double(); }
template<> simdjson_inline simdjson_result<uint64_t> value::get() noexcept { return get_uint64(); } template<> simdjson_inline simdjson_result<uint64_t> value::get() noexcept { return get_uint64(); }
template<> simdjson_inline simdjson_result<int64_t> value::get() noexcept { return get_int64(); } template<> simdjson_inline simdjson_result<int64_t> value::get() noexcept { return get_int64(); }
template<> simdjson_inline simdjson_result<uint32_t> value::get() noexcept { return get_uint32(); }
template<> simdjson_inline simdjson_result<int32_t> value::get() noexcept { return get_int32(); }
template<> simdjson_inline simdjson_result<bool> value::get() noexcept { return get_bool(); } template<> simdjson_inline simdjson_result<bool> value::get() noexcept { return get_bool(); }
@@ -114,8 +98,6 @@ template<> simdjson_warn_unused simdjson_inline error_code value::get(number& ou
template<> simdjson_warn_unused simdjson_inline error_code value::get(double& out) noexcept { return get_double().get(out); } template<> simdjson_warn_unused simdjson_inline error_code value::get(double& out) noexcept { return get_double().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code value::get(uint64_t& out) noexcept { return get_uint64().get(out); } template<> simdjson_warn_unused simdjson_inline error_code value::get(uint64_t& out) noexcept { return get_uint64().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code value::get(int64_t& out) noexcept { return get_int64().get(out); } template<> simdjson_warn_unused simdjson_inline error_code value::get(int64_t& out) noexcept { return get_int64().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code value::get(uint32_t& out) noexcept { return get_uint32().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code value::get(int32_t& out) noexcept { return get_int32().get(out); }
template<> simdjson_warn_unused simdjson_inline error_code value::get(bool& out) noexcept { return get_bool().get(out); } template<> simdjson_warn_unused simdjson_inline error_code value::get(bool& out) noexcept { return get_bool().get(out); }
#if SIMDJSON_EXCEPTIONS #if SIMDJSON_EXCEPTIONS
@@ -419,14 +401,6 @@ simdjson_inline simdjson_result<int64_t> simdjson_result<SIMDJSON_IMPLEMENTATION
if (error()) { return error(); } if (error()) { return error(); }
return first.get_int64_in_string(); return first.get_int64_in_string();
} }
simdjson_inline simdjson_result<uint32_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_uint32() noexcept {
if (error()) { return error(); }
return first.get_uint32();
}
simdjson_inline simdjson_result<int32_t> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_int32() noexcept {
if (error()) { return error(); }
return first.get_int32();
}
simdjson_inline simdjson_result<double> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_double() noexcept { simdjson_inline simdjson_result<double> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_double() noexcept {
if (error()) { return error(); } if (error()) { return error(); }
return first.get_double(); return first.get_double();
-24
View File
@@ -161,28 +161,6 @@ public:
*/ */
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept; simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
/**
* Cast this JSON value to a 32-bit unsigned integer.
*
* Calls get_uint64() and checks that the result fits in a uint32_t.
*
* @returns A 32-bit unsigned integer.
* @returns INCORRECT_TYPE If the JSON value is not an unsigned integer.
* @returns NUMBER_OUT_OF_RANGE If the value does not fit in a uint32_t.
*/
simdjson_inline simdjson_result<uint32_t> get_uint32() noexcept;
/**
* Cast this JSON value to a 32-bit signed integer.
*
* Calls get_int64() and checks that the result fits in an int32_t.
*
* @returns A 32-bit signed integer.
* @returns INCORRECT_TYPE If the JSON value is not an integer.
* @returns NUMBER_OUT_OF_RANGE If the value does not fit in an int32_t.
*/
simdjson_inline simdjson_result<int32_t> get_int32() noexcept;
/** /**
* Cast this JSON value to a double. * Cast this JSON value to a double.
* *
@@ -768,8 +746,6 @@ public:
simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept; simdjson_inline simdjson_result<uint64_t> get_uint64_in_string() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64() noexcept; simdjson_inline simdjson_result<int64_t> get_int64() noexcept;
simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept; simdjson_inline simdjson_result<int64_t> get_int64_in_string() noexcept;
simdjson_inline simdjson_result<uint32_t> get_uint32() noexcept;
simdjson_inline simdjson_result<int32_t> get_int32() noexcept;
simdjson_inline simdjson_result<double> get_double() noexcept; simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept; simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept; simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
@@ -212,12 +212,6 @@ protected:
*/ */
size_t _max_depth{0}; size_t _max_depth{0};
public:
/** Whether to store big integers as strings instead of returning BIGINT_ERROR */
bool _number_as_string{false};
protected:
// Declaring these so that subclasses can use them to implement their constructors. // Declaring these so that subclasses can use them to implement their constructors.
simdjson_inline dom_parser_implementation() noexcept; simdjson_inline dom_parser_implementation() noexcept;
simdjson_inline dom_parser_implementation(dom_parser_implementation &&other) noexcept; simdjson_inline dom_parser_implementation(dom_parser_implementation &&other) noexcept;
+1 -2
View File
@@ -19,8 +19,7 @@ enum class tape_type {
DOUBLE = 'd', DOUBLE = 'd',
TRUE_VALUE = 't', TRUE_VALUE = 't',
FALSE_VALUE = 'f', FALSE_VALUE = 'f',
NULL_VALUE = 'n', NULL_VALUE = 'n'
BIGINT = 'Z' // Big integer stored as string in string buffer
}; // enum class tape_type }; // enum class tape_type
} // namespace internal } // namespace internal
+1 -3
View File
@@ -8,14 +8,12 @@ namespace simdjson {
* @copydoc simdjson::builtin::ondemand * @copydoc simdjson::builtin::ondemand
*/ */
namespace ondemand = builtin::ondemand; namespace ondemand = builtin::ondemand;
#if SIMDJSON_FEATURE_BUILDER_API
/** /**
* @copydoc simdjson::builtin::builder * @copydoc simdjson::builtin::builder
*/ */
namespace builder = builtin::builder; namespace builder = builtin::builder;
#endif // SIMDJSON_FEATURE_BUILDER_API
#if SIMDJSON_STATIC_REFLECTION && SIMDJSON_FEATURE_BUILDER_API #if SIMDJSON_STATIC_REFLECTION
/** /**
* Create a JSON string from any user-defined type using static reflection. * Create a JSON string from any user-defined type using static reflection.
* Only available when SIMDJSON_STATIC_REFLECTION is enabled. * Only available when SIMDJSON_STATIC_REFLECTION is enabled.
+4 -14
View File
@@ -168,13 +168,10 @@ inline padded_string::operator padded_string_view() const noexcept simdjson_life
} }
inline simdjson_result<padded_string> padded_string::load(std::string_view filename) noexcept { inline simdjson_result<padded_string> padded_string::load(std::string_view filename) noexcept {
// std::string_view is not guaranteed to be null-terminated, but std::fopen requires
// a null-terminated C string. Construct a temporary std::string to ensure null-termination.
const std::string null_terminated_filename(filename);
// Open the file // Open the file
SIMDJSON_PUSH_DISABLE_WARNINGS SIMDJSON_PUSH_DISABLE_WARNINGS
SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe
std::FILE *fp = std::fopen(null_terminated_filename.c_str(), "rb"); std::FILE *fp = std::fopen(filename.data(), "rb");
SIMDJSON_POP_DISABLE_WARNINGS SIMDJSON_POP_DISABLE_WARNINGS
if (fp == nullptr) { if (fp == nullptr) {
@@ -226,13 +223,10 @@ inline simdjson_result<padded_string> padded_string::load(std::string_view filen
#if defined(_WIN32) && SIMDJSON_CPLUSPLUS17 #if defined(_WIN32) && SIMDJSON_CPLUSPLUS17
inline simdjson_result<padded_string> padded_string::load(std::wstring_view filename) noexcept { inline simdjson_result<padded_string> padded_string::load(std::wstring_view filename) noexcept {
// std::wstring_view is not guaranteed to be null-terminated, but _wfopen requires
// a null-terminated wide C string. Construct a temporary std::wstring to ensure null-termination.
const std::wstring null_terminated_filename(filename);
// Open the file using the wide characters // Open the file using the wide characters
SIMDJSON_PUSH_DISABLE_WARNINGS SIMDJSON_PUSH_DISABLE_WARNINGS
SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe SIMDJSON_DISABLE_DEPRECATED_WARNING // Disable CRT_SECURE warning on MSVC: manually verified this is safe
std::FILE *fp = _wfopen(null_terminated_filename.c_str(), L"rb"); std::FILE *fp = _wfopen(filename.data(), L"rb");
SIMDJSON_POP_DISABLE_WARNINGS SIMDJSON_POP_DISABLE_WARNINGS
if (fp == nullptr) { if (fp == nullptr) {
@@ -355,9 +349,6 @@ inline padded_string padded_string_builder::convert() noexcept {
} }
inline bool padded_string_builder::reserve(size_t additional) noexcept { inline bool padded_string_builder::reserve(size_t additional) noexcept {
if (simdjson_unlikely(additional + size < size)) {
return false; // overflow: cannot satisfy request
}
size_t needed = size + additional; size_t needed = size + additional;
if (needed <= capacity) { if (needed <= capacity) {
return true; return true;
@@ -367,9 +358,8 @@ inline bool padded_string_builder::reserve(size_t additional) noexcept {
// repeated allocations. // repeated allocations.
if (new_capacity < 4096) { if (new_capacity < 4096) {
new_capacity *= 2; new_capacity *= 2;
// overflow guard: ensure new_capacity + new_capacity/2 does not overflow } else {
} else if (new_capacity + new_capacity / 2 > new_capacity) { new_capacity += new_capacity/2; // grow by 1.5x
new_capacity += new_capacity / 2; // grow by 1.5x
} }
char *new_data = internal::allocate_padded_buffer(new_capacity); char *new_data = internal::allocate_padded_buffer(new_capacity);
if (new_data == nullptr) { if (new_data == nullptr) {
-85
View File
@@ -6,15 +6,6 @@
#include <cstring> /* memcmp */ #include <cstring> /* memcmp */
// for page size computation.
#if defined(__unix__) || defined(__APPLE__) || defined(__linux__)
#include <unistd.h>
#if defined(__APPLE__)
#include <sys/sysctl.h>
#endif
#endif
namespace simdjson { namespace simdjson {
inline padded_string_view::padded_string_view(const char* s, size_t len, size_t capacity) noexcept inline padded_string_view::padded_string_view(const char* s, size_t len, size_t capacity) noexcept
@@ -104,83 +95,7 @@ inline padded_string_view pad_with_reserve(std::string& s) noexcept {
return padded_string_view(s.data(), s.size(), s.capacity()); return padded_string_view(s.data(), s.size(), s.capacity());
} }
inline uint32_t get_page_size() noexcept {
#if defined(_WINDOWS_) // if and only if someone loaded Windows.h, we can get the page size from there.
// Otherwise, we assume 4096.
static const uint32_t cached = []() -> uint32_t {
SYSTEM_INFO si;
GetSystemInfo(&si);
return static_cast<std::uint32_t>(si.dwPageSize);
}();
return cached;
#elif defined(__unix__) || defined(__APPLE__) || defined(__linux__)
static const uint32_t cached = []() -> uint32_t {
long page_size = sysconf(_SC_PAGESIZE);
if (page_size > 0) {
return static_cast<uint32_t>(page_size);
}
return 4096; // fallback
}();
return cached;
#else
return 4096; // fallback
#endif
}
#if SIMDJSON_CPLUSPLUS17
inline padded_input::padded_input(std::string_view sv)
: storage(simdjson::padded_string_view{}) {
if (needs_allocation(sv.data(), sv.size())) {
storage = simdjson::padded_string(sv);
} else {
storage = simdjson::padded_string_view(
sv.data(), sv.size(), sv.size() + simdjson::SIMDJSON_PADDING);
}
}
inline padded_input::padded_input(const char *data, size_t length)
: storage(simdjson::padded_string_view{}) {
if (needs_allocation(data, length)) {
storage = simdjson::padded_string(data, length);
} else {
storage = simdjson::padded_string_view(
data, length, length + simdjson::SIMDJSON_PADDING);
}
}
inline padded_input::padded_input(const std::string &s)
: storage(simdjson::padded_string_view{}) {
const size_t len = s.size();
const size_t cap = s.capacity();
// Here we have the string content from data() to data() + size(),
// but the memory is accessible from data() to data() + capacity().
const size_t needed_padding = (cap - len) < simdjson::SIMDJSON_PADDING
? simdjson::SIMDJSON_PADDING - (cap - len) : 0;
if (needed_padding > 0 && needs_allocation(s.data(), cap, needed_padding)) {
storage = simdjson::padded_string(s);
} else {
storage = simdjson::padded_string_view(
s.data(), len, len + simdjson::SIMDJSON_PADDING);
}
}
inline bool padded_input::is_view() const noexcept {
return std::holds_alternative<simdjson::padded_string_view>(storage);
}
inline padded_input::operator simdjson::padded_string_view() const noexcept {
return std::visit([](const auto& p) -> simdjson::padded_string_view {
return p;
}, storage);
}
inline bool padded_input::needs_allocation(const char* buf, size_t len, size_t padding) noexcept {
if(len == 0) { return false; }
const auto page_size = get_page_size();
return ((reinterpret_cast<uintptr_t>(buf + len - 1) % page_size)
+ padding >= static_cast<uintptr_t>(page_size));
}
#endif // SIMDJSON_CPLUSPLUS17
} // namespace simdjson } // namespace simdjson
-66
View File
@@ -9,9 +9,6 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <ostream> #include <ostream>
#if SIMDJSON_CPLUSPLUS17
#include <variant>
#endif
namespace simdjson { namespace simdjson {
@@ -76,68 +73,6 @@ public:
}; // padded_string_view }; // padded_string_view
/**
* Get the system's memory page size. By default, we return
* 4096 bytes, which is the most common page size. On systems
* where the page size is not a multiple of 4096 bytes, and not
* a unix-like system, nor Windows, this function may return an
* incorrect value.
*
* @return The page size in bytes.
*/
inline uint32_t get_page_size() noexcept;
#if SIMDJSON_CPLUSPLUS17
/**
* A padded_input is a wrapper around either a padded_string_view or a padded_string.
* It will automatically pad a string_view if it does not have sufficient padding
* up to the end of the memory page. Note that a requirement for this method to
* make sense is to be on a system with a page size of at least 4096 (which is
* universal except on some embedded systems).
*/
struct padded_input {
/**
* Construct a padded_input from a string_view. If the string_view does not have sufficient padding,
* the data will be copied into a padded_string and the padded_string_view will point to the
* padded_string's data. Otherwise, the padded_string_view will point to the original string_view's data.
*/
inline explicit padded_input(std::string_view sv);
/**
* Construct a padded_input from a C-style string (length specified). If the string does not have sufficient padding,
* the data will be copied into a padded_string and the padded_string_view will point to the
* padded_string's data. Otherwise, the padded_string_view will point to the original string's data.
*/
inline explicit padded_input(const char *data, size_t length);
/**
* Construct a padded_input from a std::string. If the string does not have sufficient padding
* (considering its capacity), the data will be copied into a padded_string and the padded_string_view
* will point to the padded_string's data. Otherwise, the padded_string_view will point to the
* original string's data.
*/
inline explicit padded_input(const std::string &s);
/**
* Check if the padded_input is a view.
*
* @return true if the padded_input is a view, false otherwise.
*/
inline bool is_view() const noexcept;
/**
* Convert the padded_input to a padded_string_view.
*
* @return The padded_string_view.
*/
inline operator simdjson::padded_string_view() const noexcept;
private:
std::variant<simdjson::padded_string_view, simdjson::padded_string> storage;
// whether we cross a page boundary and need to allocate a new padded string.
static inline bool needs_allocation(const char* buf, size_t len, size_t padding = SIMDJSON_PADDING) noexcept;
};
#endif // SIMDJSON_CPLUSPLUS17
#if SIMDJSON_EXCEPTIONS #if SIMDJSON_EXCEPTIONS
/** /**
* Send padded_string instance to an output stream. * Send padded_string instance to an output stream.
@@ -170,7 +105,6 @@ inline padded_string_view pad(std::string& s) noexcept;
* @return The padded string. * @return The padded string.
*/ */
inline padded_string_view pad_with_reserve(std::string& s) noexcept; inline padded_string_view pad_with_reserve(std::string& s) noexcept;
} // namespace simdjson } // namespace simdjson
#endif // SIMDJSON_PADDED_STRING_VIEW_H #endif // SIMDJSON_PADDED_STRING_VIEW_H
+3 -3
View File
@@ -4,7 +4,7 @@
#define SIMDJSON_SIMDJSON_VERSION_H #define SIMDJSON_SIMDJSON_VERSION_H
/** The version of simdjson being used (major.minor.revision) */ /** The version of simdjson being used (major.minor.revision) */
#define SIMDJSON_VERSION "4.6.1" #define SIMDJSON_VERSION "4.4.2"
namespace simdjson { namespace simdjson {
enum { enum {
@@ -15,11 +15,11 @@ enum {
/** /**
* The minor version (major.MINOR.revision) of simdjson being used. * The minor version (major.MINOR.revision) of simdjson being used.
*/ */
SIMDJSON_VERSION_MINOR = 6, SIMDJSON_VERSION_MINOR = 4,
/** /**
* The revision (major.minor.REVISION) of simdjson being used. * The revision (major.minor.REVISION) of simdjson being used.
*/ */
SIMDJSON_VERSION_REVISION = 1 SIMDJSON_VERSION_REVISION = 2
}; };
} // namespace simdjson } // namespace simdjson
-11
View File
@@ -1,11 +0,0 @@
{
"app_name": "MyApp",
"version": "1.0.0",
"port": 8080,
"debug": true,
"features": ["logging", "caching"],
"database": {
"host": "localhost",
"port": 5432
}
}
-226
View File
@@ -1,226 +0,0 @@
#!/usr/bin/env python3
"""
Amalgamates simdjson into temporary files, then builds and runs 7 feature-flag
test programs. Reports compile time and binary size for each configuration.
"""
import os
import sys
import subprocess
import tempfile
import time
import shutil
SCRIPTPATH = os.path.dirname(os.path.abspath(__file__))
PROJECTPATH = os.path.dirname(SCRIPTPATH)
TESTSRC = os.path.join(PROJECTPATH, "tests", "feature_flag_tests")
# ── feature-flag configurations ──────────────────────────────────────────────
CONFIGS = [
{
"name": "dom_only",
"flags": {"SIMDJSON_FEATURE_DOM_API": 1,
"SIMDJSON_FEATURE_ONDEMAND_API": 0,
"SIMDJSON_FEATURE_BUILDER_API": 0},
},
{
"name": "ondemand_only",
"flags": {"SIMDJSON_FEATURE_DOM_API": 1,
"SIMDJSON_FEATURE_ONDEMAND_API": 1,
"SIMDJSON_FEATURE_BUILDER_API": 0},
},
{
"name": "dom_and_ondemand",
"flags": {"SIMDJSON_FEATURE_DOM_API": 1,
"SIMDJSON_FEATURE_ONDEMAND_API": 1,
"SIMDJSON_FEATURE_BUILDER_API": 0},
},
{
"name": "builder_and_dom",
"flags": {"SIMDJSON_FEATURE_DOM_API": 1,
"SIMDJSON_FEATURE_ONDEMAND_API": 0,
"SIMDJSON_FEATURE_BUILDER_API": 1},
},
{
"name": "builder_and_ondemand",
"flags": {"SIMDJSON_FEATURE_DOM_API": 1,
"SIMDJSON_FEATURE_ONDEMAND_API": 1,
"SIMDJSON_FEATURE_BUILDER_API": 1},
},
{
"name": "builder_dom_and_ondemand",
"flags": {"SIMDJSON_FEATURE_DOM_API": 1,
"SIMDJSON_FEATURE_ONDEMAND_API": 1,
"SIMDJSON_FEATURE_BUILDER_API": 1},
},
{
"name": "builder_only",
"flags": {"SIMDJSON_FEATURE_DOM_API": 1,
"SIMDJSON_FEATURE_ONDEMAND_API": 0,
"SIMDJSON_FEATURE_BUILDER_API": 1},
},
]
CXX = os.environ.get("CXX", "c++")
CXXSTD = os.environ.get("CXXSTD", "-std=c++17")
OPT = os.environ.get("OPT", "-O2")
def amalgamate(output_dir):
"""Run amalgamate.py, writing simdjson.h / simdjson.cpp into *output_dir*."""
env = os.environ.copy()
env["AMALGAMATE_OUTPUT_PATH"] = output_dir
cmd = [sys.executable, os.path.join(SCRIPTPATH, "amalgamate.py")]
result = subprocess.run(cmd, env=env, capture_output=True, text=True)
if result.returncode != 0:
print("amalgamate.py failed:")
print(result.stdout)
print(result.stderr)
sys.exit(1)
header = os.path.join(output_dir, "simdjson.h")
source = os.path.join(output_dir, "simdjson.cpp")
assert os.path.isfile(header), f"missing {header}"
assert os.path.isfile(source), f"missing {source}"
return header, source
def compile_and_run(name, flags, amal_dir, build_dir):
"""
1. Compile simdjson.cpp -> simdjson.o (timed, size reported)
2. Compile test .cpp -> test.o (timed, size reported)
3. Link and run the test program
Returns (lib_time, lib_size, test_time, test_size) or Nones on failure.
"""
src = os.path.join(TESTSRC, f"{name}.cpp")
simdjson_cpp = os.path.join(amal_dir, "simdjson.cpp")
simdjson_o = os.path.join(build_dir, f"{name}_simdjson.o")
test_o = os.path.join(build_dir, f"{name}.o")
binary = os.path.join(build_dir, name)
defs = [f"-D{k}={v}" for k, v in flags.items()]
# ── compile simdjson.o (timed) ────────────────────────────────────────
cmd_lib = [CXX, CXXSTD, OPT, "-c"] + defs + [
f"-I{amal_dir}", "-o", simdjson_o, simdjson_cpp,
]
t0 = time.monotonic()
result = subprocess.run(cmd_lib, capture_output=True, text=True)
lib_time = time.monotonic() - t0
if result.returncode != 0:
print(f" COMPILE FAILED (simdjson.o): {name}")
print(f" command: {' '.join(cmd_lib)}")
print(result.stderr)
return None, None, None, None
lib_size = os.path.getsize(simdjson_o)
# ── compile test source (timed) ───────────────────────────────────────
cmd_test = [CXX, CXXSTD, OPT, "-c"] + defs + [
f"-I{amal_dir}", "-o", test_o, src,
]
t0 = time.monotonic()
result = subprocess.run(cmd_test, capture_output=True, text=True)
test_time = time.monotonic() - t0
if result.returncode != 0:
print(f" COMPILE FAILED (test): {name}")
print(f" command: {' '.join(cmd_test)}")
print(result.stderr)
return None, None, None, None
test_size = os.path.getsize(test_o)
# ── link ──────────────────────────────────────────────────────────────
cmd_link = [CXX, "-o", binary, test_o, simdjson_o]
result = subprocess.run(cmd_link, capture_output=True, text=True)
if result.returncode != 0:
print(f" LINK FAILED: {name}")
print(f" command: {' '.join(cmd_link)}")
print(result.stderr)
return None, None, None, None
# ── run ───────────────────────────────────────────────────────────────
result = subprocess.run([binary], capture_output=True, text=True)
if result.returncode != 0:
print(f" RUN FAILED: {name}")
print(result.stdout)
print(result.stderr)
return lib_time, lib_size, test_time, test_size
print(f" {result.stdout.strip()}")
return lib_time, lib_size, test_time, test_size
def human_size(n):
"""Return e.g. '1.23 MB' or '456 KB'."""
if n is None:
return "N/A"
if n >= 1_000_000:
return f"{n / 1_000_000:.2f} MB"
if n >= 1_000:
return f"{n / 1_000:.1f} KB"
return f"{n} B"
def main():
tmpdir = tempfile.mkdtemp(prefix="simdjson_features_")
amal_dir = os.path.join(tmpdir, "amalgamated")
build_dir = os.path.join(tmpdir, "build")
os.makedirs(amal_dir, exist_ok=True)
os.makedirs(build_dir, exist_ok=True)
print(f"Working directory: {tmpdir}")
print(f"Compiler: {CXX} flags: {CXXSTD} {OPT}")
print()
# ── amalgamate ────────────────────────────────────────────────────────
print("Amalgamating...")
amalgamate(amal_dir)
print("Amalgamation done.\n")
# ── build & run each configuration ────────────────────────────────────
results = []
for cfg in CONFIGS:
name = cfg["name"]
flags = cfg["flags"]
enabled = [k.replace("SIMDJSON_FEATURE_", "").replace("_API", "")
for k, v in flags.items() if v]
label = " + ".join(enabled) if enabled else "none"
print(f"[{name}] ({label})")
lib_time, lib_size, test_time, test_size = \
compile_and_run(name, flags, amal_dir, build_dir)
results.append((name, label, lib_time, lib_size, test_time, test_size))
print()
# ── summary table ─────────────────────────────────────────────────────
name_w = max(len(r[0]) for r in results)
label_w = max(len(r[1]) for r in results)
hdr = (f"{'Test':<{name_w}} {'APIs':<{label_w}}"
f" {'lib time':>9} {'simdjson.o':>11}"
f" {'test time':>10} {'test .o':>11}")
print(hdr)
print("-" * len(hdr))
for name, label, lt, ls, tt, ts in results:
lt_s = f"{lt:.2f} s" if lt is not None else "FAIL"
ls_s = human_size(ls)
tt_s = f"{tt:.2f} s" if tt is not None else "FAIL"
ts_s = human_size(ts)
print(f"{name:<{name_w}} {label:<{label_w}}"
f" {lt_s:>9} {ls_s:>11}"
f" {tt_s:>10} {ts_s:>11}")
# ── cleanup ───────────────────────────────────────────────────────────
shutil.rmtree(tmpdir, ignore_errors=True)
# exit non-zero if anything failed
if any(lt is None for _, _, lt, _, _, _ in results):
print("\nSome tests FAILED.")
sys.exit(1)
print("\nAll tests passed.")
if __name__ == "__main__":
main()
+3 -54
View File
@@ -268,21 +268,7 @@ class SimdjsonFile:
print(f" Adding include: {self} includes {include}") print(f" Adding include: {self} includes {include}")
if self.is_conditional_include: if self.is_conditional_include:
# If I have a dependency file, I can only include something that has a dependency file. # If I have a dependency file, I can only include something that has a dependency file.
if not include.is_conditional_include: assert include.is_conditional_include, f"Error: Amalgamated file '{self}' is trying to include '{include}', but '{include}' is not an amalgamated file. Amalgamated files can only include other amalgamated files to maintain conditional inclusion structure. Check the inclusion rules in the script's 'rules' variable. {rules}"
dep = self.dependency_file
dep_hint = f" and add it to the dependency file '{dep}'" if dep else ""
raise AssertionError(
f"Error: Amalgamated file '{self}' is trying to include '{include}', "
f"but '{include}' is not an amalgamated file.\n\n"
f"FIX: Wrap the #include \"{include}\" in a conditional block:\n\n"
f" #ifndef SIMDJSON_CONDITIONAL_INCLUDE\n"
f" #include \"{include}\"\n"
f" #endif // SIMDJSON_CONDITIONAL_INCLUDE\n\n"
f"This makes the include editor-only (skipped during amalgamation){dep_hint}.\n\n"
f"During amalgamation, '{include}' is already included earlier in the "
f"amalgamated output, so it does not need to be included again.\n\n"
f"{rules}"
)
# TODO make sure we only include amalgamated files that are guaranteed to be included with us (or before us) # TODO make sure we only include amalgamated files that are guaranteed to be included with us (or before us)
# if include.amalgamator_file: # if include.amalgamator_file:
# assert include.amalgamator_file == self, f"{self} cannot include {include}: it should be included from {include.amalgamator_file} instead." # assert include.amalgamator_file == self, f"{self} cannot include {include}: it should be included from {include.amalgamator_file} instead."
@@ -439,10 +425,8 @@ class Amalgamator:
self.implementation = "SIMDJSON_BUILTIN_IMPLEMENTATION" self.implementation = "SIMDJSON_BUILTIN_IMPLEMENTATION"
assert not self.editor_only_region, f"Error: Already in an editor-only region when starting to write '{file}'. Ensure proper nesting of conditional blocks." assert not self.editor_only_region, f"Error: Already in an editor-only region when starting to write '{file}'. Ensure proper nesting of conditional blocks."
editor_only_start_line = None
bare_endif_lines = []
with open(file.absolute_path, 'r') as fid2: with open(file.absolute_path, 'r') as fid2:
for line_number, line in enumerate(fid2, 1): for line in fid2:
line = line.rstrip('\n') line = line.rstrip('\n')
# Ignore #pragma once, it causes warnings if it ends up in a .cpp file # Ignore #pragma once, it causes warnings if it ends up in a .cpp file
@@ -455,7 +439,6 @@ class Amalgamator:
assert self.in_conditional_include_block, f"Error: File '{file}' uses '#ifndef SIMDJSON_CONDITIONAL_INCLUDE' without a prior '#define SIMDJSON_CONDITIONAL_INCLUDE'. Ensure the define comes first. Stack: {self.include_stack}. {rules}" assert self.in_conditional_include_block, f"Error: File '{file}' uses '#ifndef SIMDJSON_CONDITIONAL_INCLUDE' without a prior '#define SIMDJSON_CONDITIONAL_INCLUDE'. Ensure the define comes first. Stack: {self.include_stack}. {rules}"
assert not self.editor_only_region, f"Error: File '{file}' uses '#ifndef SIMDJSON_CONDITIONAL_INCLUDE' twice in a row. Ensure conditional blocks are properly nested and closed. {rules}" assert not self.editor_only_region, f"Error: File '{file}' uses '#ifndef SIMDJSON_CONDITIONAL_INCLUDE' twice in a row. Ensure conditional blocks are properly nested and closed. {rules}"
self.editor_only_region = True self.editor_only_region = True
editor_only_start_line = line_number
# Handle ignored lines (and ending ignore blocks) # Handle ignored lines (and ending ignore blocks)
end_ignore = endif_conditional_re.search(line) end_ignore = endif_conditional_re.search(line)
@@ -470,12 +453,6 @@ class Amalgamator:
file.add_editor_only_include(included_file) file.add_editor_only_include(included_file)
if end_ignore: if end_ignore:
self.editor_only_region = False self.editor_only_region = False
editor_only_start_line = None
else:
# Track bare #endif lines that might be the intended closer
stripped = line.strip()
if stripped == '#endif' or (stripped.startswith('#endif') and 'SIMDJSON_CONDITIONAL_INCLUDE' not in stripped):
bare_endif_lines.append((line_number, line.strip()))
continue continue
assert not end_ignore, f"Error: File '{file}' has '#endif // SIMDJSON_CONDITIONAL_INCLUDE' without a matching '#ifndef'. Ensure proper conditional block structure. {rules}" assert not end_ignore, f"Error: File '{file}' has '#endif // SIMDJSON_CONDITIONAL_INCLUDE' without a matching '#ifndef'. Ensure proper conditional block structure. {rules}"
@@ -524,35 +501,7 @@ class Amalgamator:
self.write(line) self.write(line)
if self.editor_only_region: assert not self.editor_only_region, f"Error: File '{file}' ended without closing the '#endif // SIMDJSON_CONDITIONAL_INCLUDE'. Ensure all conditional blocks are properly closed. {rules}"
msg = (
f"Error: File '{file}' ended without closing the "
f"'#endif // SIMDJSON_CONDITIONAL_INCLUDE' block "
f"(opened at line {editor_only_start_line}).\n\n"
)
if bare_endif_lines:
msg += (
f"HINT: Found #endif line(s) inside the block that are missing "
f"the required comment. The amalgamation script looks for exactly:\n\n"
f" #endif // SIMDJSON_CONDITIONAL_INCLUDE\n\n"
f"but found:\n"
)
for ln, text in bare_endif_lines:
msg += f" line {ln}: {text}\n"
msg += (
f"\nFIX: Change the #endif to:\n\n"
f" #endif // SIMDJSON_CONDITIONAL_INCLUDE\n\n"
f"The '// SIMDJSON_CONDITIONAL_INCLUDE' comment is required "
f"for the amalgamation script to recognize it as the closing "
f"of the conditional block.\n"
)
else:
msg += (
f"FIX: Add '#endif // SIMDJSON_CONDITIONAL_INCLUDE' to close "
f"the '#ifndef SIMDJSON_CONDITIONAL_INCLUDE' block.\n"
)
msg += f"\n{rules}"
raise AssertionError(msg)
self.write(f"/* end file {self.file_to_str(file)} */") self.write(f"/* end file {self.file_to_str(file)} */")
+2020 -2422
View File
File diff suppressed because it is too large Load Diff
+8722 -10121
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
-5
View File
@@ -2,7 +2,6 @@
#define SIMDJSON_SRC_ARM64_CPP #define SIMDJSON_SRC_ARM64_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -143,7 +142,6 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
return arm64::stage1::generic_validate_utf8(buf,len); return arm64::stage1::generic_validate_utf8(buf,len);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -151,7 +149,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
@@ -162,13 +159,11 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return arm64::stringparsing::parse_wobbly_string(src, dst); return arm64::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace arm64 } // namespace arm64
} // namespace simdjson } // namespace simdjson
-8
View File
@@ -2,7 +2,6 @@
#define SIMDJSON_SRC_FALLBACK_CPP #define SIMDJSON_SRC_FALLBACK_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -12,13 +11,10 @@
#include <simdjson/fallback/begin.h> #include <simdjson/fallback/begin.h>
#include <generic/stage1/find_next_document_index.h> #include <generic/stage1/find_next_document_index.h>
#include <generic/stage2/stringparsing.h> #include <generic/stage2/stringparsing.h>
#if SIMDJSON_FEATURE_DOM_API
#include <generic/stage2/logger.h> #include <generic/stage2/logger.h>
#include <generic/stage2/json_iterator.h> #include <generic/stage2/json_iterator.h>
#include <generic/stage2/tape_writer.h> #include <generic/stage2/tape_writer.h>
#include <generic/stage2/tape_builder.h> #include <generic/stage2/tape_builder.h>
#endif // SIMDJSON_FEATURE_DOM_API
// //
// Stage 1 // Stage 1
@@ -440,7 +436,6 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
namespace simdjson { namespace simdjson {
namespace fallback { namespace fallback {
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -448,7 +443,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
@@ -459,13 +453,11 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return fallback::stringparsing::parse_wobbly_string(src, dst); return fallback::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace fallback } // namespace fallback
} // namespace simdjson } // namespace simdjson
-1
View File
@@ -5,7 +5,6 @@
#ifndef SIMDJSON_SRC_GENERIC_DEPENDENCIES_H #ifndef SIMDJSON_SRC_GENERIC_DEPENDENCIES_H
#define SIMDJSON_SRC_GENERIC_DEPENDENCIES_H #define SIMDJSON_SRC_GENERIC_DEPENDENCIES_H
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_SRC_GENERIC_DEPENDENCIES_H #endif // SIMDJSON_SRC_GENERIC_DEPENDENCIES_H
+1 -6
View File
@@ -1,7 +1,3 @@
#include <generic/stage2/stringparsing.h>
#if SIMDJSON_FEATURE_DOM_API
// Stuff other things depend on // Stuff other things depend on
#include <generic/stage2/base.h> #include <generic/stage2/base.h>
#include <generic/stage2/tape_writer.h> #include <generic/stage2/tape_writer.h>
@@ -9,7 +5,6 @@
// All other declarations // All other declarations
#include <generic/stage2/json_iterator.h> #include <generic/stage2/json_iterator.h>
#include <generic/stage2/stringparsing.h>
#include <generic/stage2/structural_iterator.h> #include <generic/stage2/structural_iterator.h>
#include <generic/stage2/tape_builder.h> #include <generic/stage2/tape_builder.h>
#endif // SIMDJSON_FEATURE_DOM_API
+1 -17
View File
@@ -172,23 +172,7 @@ simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_string(
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept { simdjson_warn_unused simdjson_inline error_code tape_builder::visit_number(json_iterator &iter, const uint8_t *value) noexcept {
iter.log_value("number"); iter.log_value("number");
error_code err = numberparsing::parse_number(value, tape); return numberparsing::parse_number(value, tape);
if (simdjson_unlikely(err == BIGINT_ERROR &&
iter.dom_parser._number_as_string)) {
// Write big integer to string buffer using the same format as strings.
// Scan digits the same way parse_number does (skip optional '-', then digits).
const uint8_t *p = value;
if (*p == '-') p++;
while (numberparsing::is_digit(*p)) p++;
size_t len = size_t(p - value);
tape.append(current_string_buf_loc - iter.dom_parser.doc->string_buf.get(), internal::tape_type::BIGINT);
uint8_t *dst = current_string_buf_loc + sizeof(uint32_t);
memcpy(dst, value, len);
dst += len;
on_end_string(dst);
return SUCCESS;
}
return err;
} }
simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept { simdjson_warn_unused simdjson_inline error_code tape_builder::visit_root_number(json_iterator &iter, const uint8_t *value) noexcept {
-15
View File
@@ -26,9 +26,6 @@ struct tape_writer {
/** Write a double value to tape. */ /** Write a double value to tape. */
simdjson_inline void append_double(double value) noexcept; simdjson_inline void append_double(double value) noexcept;
/** Write a big integer (as string) to tape. src points to first digit, len is byte count. */
simdjson_inline void append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept;
/** /**
* Append a tape entry (an 8-bit type,and 56 bits worth of value). * Append a tape entry (an 8-bit type,and 56 bits worth of value).
*/ */
@@ -112,18 +109,6 @@ simdjson_inline void tape_writer::write(uint64_t &tape_loc, uint64_t val, intern
tape_loc = val | ((uint64_t(char(t))) << 56); tape_loc = val | ((uint64_t(char(t))) << 56);
} }
simdjson_inline void tape_writer::append_bigint(const uint8_t *src, size_t len, uint8_t *&string_buf) noexcept {
// Write to string buffer: [4-byte LE length][digits][null]
uint32_t str_len = uint32_t(len);
memcpy(string_buf, &str_len, sizeof(uint32_t));
memcpy(string_buf + sizeof(uint32_t), src, len);
string_buf[sizeof(uint32_t) + len] = 0;
// Tape entry: offset into string buffer
// The caller must set the offset relative to doc.string_buf base
append(0, internal::tape_type::BIGINT); // placeholder offset, caller patches
string_buf += sizeof(uint32_t) + len + 1;
}
} // namespace stage2 } // namespace stage2
} // unnamed namespace } // unnamed namespace
} // namespace SIMDJSON_IMPLEMENTATION } // namespace SIMDJSON_IMPLEMENTATION
-5
View File
@@ -2,7 +2,6 @@
#define SIMDJSON_SRC_HASWELL_CPP #define SIMDJSON_SRC_HASWELL_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -140,7 +139,6 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
return haswell::stage1::generic_validate_utf8(buf,len); return haswell::stage1::generic_validate_utf8(buf,len);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -148,7 +146,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
@@ -159,13 +156,11 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return haswell::stringparsing::parse_wobbly_string(src, dst); return haswell::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace SIMDJSON_IMPLEMENTATION } // namespace SIMDJSON_IMPLEMENTATION
} // namespace simdjson } // namespace simdjson
-5
View File
@@ -2,7 +2,6 @@
#define SIMDJSON_SRC_ICELAKE_CPP #define SIMDJSON_SRC_ICELAKE_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -186,7 +185,6 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
return icelake::stage1::generic_validate_utf8(buf,len); return icelake::stage1::generic_validate_utf8(buf,len);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -194,7 +192,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
@@ -205,13 +202,11 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return icelake::stringparsing::parse_wobbly_string(src, dst); return icelake::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace icelake } // namespace icelake
} // namespace simdjson } // namespace simdjson
-5
View File
@@ -2,7 +2,6 @@
#define SIMDJSON_SRC_LASX_CPP #define SIMDJSON_SRC_LASX_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -103,7 +102,6 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
return lasx::stage1::generic_validate_utf8(buf,len); return lasx::stage1::generic_validate_utf8(buf,len);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -111,7 +109,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
@@ -122,13 +119,11 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return lasx::stringparsing::parse_wobbly_string(src, dst); return lasx::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace lasx } // namespace lasx
} // namespace simdjson } // namespace simdjson
-5
View File
@@ -2,7 +2,6 @@
#define SIMDJSON_SRC_LSX_CPP #define SIMDJSON_SRC_LSX_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -107,7 +106,6 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
return lsx::stage1::generic_validate_utf8(buf,len); return lsx::stage1::generic_validate_utf8(buf,len);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -115,7 +113,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
@@ -126,13 +123,11 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return lsx::stringparsing::parse_wobbly_string(src, dst); return lsx::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace lsx } // namespace lsx
} // namespace simdjson } // namespace simdjson
-5
View File
@@ -2,7 +2,6 @@
#define SIMDJSON_SRC_PPC64_CPP #define SIMDJSON_SRC_PPC64_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -113,7 +112,6 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
return ppc64::stage1::generic_validate_utf8(buf,len); return ppc64::stage1::generic_validate_utf8(buf,len);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -121,7 +119,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
@@ -132,13 +129,11 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return ppc64::stringparsing::parse_wobbly_string(src, dst); return ppc64::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace ppc64 } // namespace ppc64
} // namespace simdjson } // namespace simdjson
-5
View File
@@ -2,7 +2,6 @@
#define SIMDJSON_SRC_RVV_VLS_CPP #define SIMDJSON_SRC_RVV_VLS_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -102,7 +101,6 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
return rvv_vls::stage1::generic_validate_utf8(buf,len); return rvv_vls::stage1::generic_validate_utf8(buf,len);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -110,7 +108,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
@@ -121,13 +118,11 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return rvv_vls::stringparsing::parse_wobbly_string(src, dst); return rvv_vls::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace rvv_vls } // namespace rvv_vls
} // namespace simdjson } // namespace simdjson
+1 -5
View File
@@ -1,7 +1,5 @@
#define SIMDJSON_SRC_SIMDJSON_CPP #define SIMDJSON_SRC_SIMDJSON_CPP
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS
@@ -15,11 +13,8 @@ SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS
#include <simdjson/generic/dependencies.h> #include <simdjson/generic/dependencies.h>
#include <generic/dependencies.h> #include <generic/dependencies.h>
#if SIMDJSON_FEATURE_DOM_API
#include <generic/stage1/dependencies.h> #include <generic/stage1/dependencies.h>
#include <generic/stage2/dependencies.h> #include <generic/stage2/dependencies.h>
#endif
#include <implementation.cpp> #include <implementation.cpp>
@@ -55,3 +50,4 @@ SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS
#undef SIMDJSON_CONDITIONAL_INCLUDE #undef SIMDJSON_CONDITIONAL_INCLUDE
SIMDJSON_POP_DISABLE_UNUSED_WARNINGS SIMDJSON_POP_DISABLE_UNUSED_WARNINGS
-5
View File
@@ -2,7 +2,6 @@
#define SIMDJSON_SRC_WESTMERE_CPP #define SIMDJSON_SRC_WESTMERE_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -145,7 +144,6 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
return westmere::stage1::generic_validate_utf8(buf,len); return westmere::stage1::generic_validate_utf8(buf,len);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -153,7 +151,6 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
@@ -164,13 +161,11 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return westmere::stringparsing::parse_wobbly_string(src, dst); return westmere::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace westmere } // namespace westmere
} // namespace simdjson } // namespace simdjson
-1
View File
@@ -30,4 +30,3 @@ add_cpp_test(checkimplementation LABELS other per_implementation)
add_subdirectory(compilation_failure_tests) add_subdirectory(compilation_failure_tests)
add_subdirectory(builder) add_subdirectory(builder)
add_subdirectory(compile_time) add_subdirectory(compile_time)
add_subdirectory(feature_flag_tests)
-3
View File
@@ -1,8 +1,5 @@
# All remaining tests link with simdjson proper # All remaining tests link with simdjson proper
include_directories(..) include_directories(..)
if(NOT SIMDJSON_FEATURE_BUILDER_API)
return()
endif()
add_cpp_test(builder_string_builder_tests LABELS ondemand acceptance per_implementation) add_cpp_test(builder_string_builder_tests LABELS ondemand acceptance per_implementation)
if(SIMDJSON_STATIC_REFLECTION) if(SIMDJSON_STATIC_REFLECTION)
add_cpp_test(static_reflection_custom_tests LABELS ondemand acceptance per_implementation) add_cpp_test(static_reflection_custom_tests LABELS ondemand acceptance per_implementation)
@@ -6,40 +6,40 @@
using namespace simdjson; using namespace simdjson;
struct Car { struct Car {
std::string make{}; std::string make;
std::string model{}; std::string model;
int64_t year{}; int64_t year;
std::vector<double> tire_pressure{}; std::vector<double> tire_pressure;
}; };
struct kid { struct kid {
int age{}; int age;
std::string name{}; std::string name;
std::vector<std::string> toys{}; std::vector<std::string> toys;
bool operator<=> (const kid&) const = default; bool operator<=> (const kid&) const = default;
}; };
struct Z { struct Z {
int x{}; int x;
bool operator<=> (const Z&) const = default; bool operator<=> (const Z&) const = default;
}; };
struct Y { struct Y {
int g{}; int g;
std::string h{}; std::string h;
std::vector<int> i{}; std::vector<int> i;
Z z{}; Z z;
bool operator<=> (const Y&) const = default; bool operator<=> (const Y&) const = default;
}; };
struct X { struct X {
char a{}; char a;
int b{}; int b;
int c{}; int c;
std::string d{}; std::string d;
std::vector<int> e{}; std::vector<int> e;
std::vector<std::string> f{}; std::vector<std::string> f;
Y y{}; Y y;
bool operator<=> (const X&) const = default; bool operator<=> (const X&) const = default;
}; };
@@ -16,8 +16,8 @@ namespace builder_tests {
#if SIMDJSON_STATIC_REFLECTION #if SIMDJSON_STATIC_REFLECTION
// Custom type for testing tag_invoke with extract_into // Custom type for testing tag_invoke with extract_into
struct Price { struct Price {
double amount{}; double amount;
std::string currency{}; std::string currency;
// Custom deserializer that applies currency conversion // Custom deserializer that applies currency conversion
friend error_code tag_invoke(deserialize_tag, friend error_code tag_invoke(deserialize_tag,
@@ -46,37 +46,17 @@ namespace builder_tests {
return SUCCESS; return SUCCESS;
} }
}; };
struct Car {
std::string make{};
std::string model{};
int year{};
double price{};
bool electric{};
};
struct CarOpt {
std::string make;
std::string model;
int year;
double price;
std::optional<std::string> color;
};
struct CarColor {
std::string make;
std::string model;
int year;
double price;
std::string color;
};
struct Product { struct Product {
std::string name{}; std::string name;
Price price{}; // Custom deserializable type Price price; // Custom deserializable type
int stock{}; int stock;
}; };
// Another custom type for testing // Another custom type for testing
struct Dimensions { struct Dimensions {
double value{}; double value;
std::string unit{}; std::string unit;
// Custom deserializer that converts to metric // Custom deserializer that converts to metric
friend error_code tag_invoke(deserialize_tag, friend error_code tag_invoke(deserialize_tag,
@@ -109,13 +89,6 @@ namespace builder_tests {
Dimensions weight; Dimensions weight;
Dimensions length; Dimensions length;
}; };
struct Person {
std::string name;
int age;
std::optional<std::string> email;
std::optional<std::string> phone;
};
#endif #endif
bool test_primitive_types() { bool test_primitive_types() {
@@ -159,8 +132,8 @@ namespace builder_tests {
TEST_START(); TEST_START();
#if SIMDJSON_STATIC_REFLECTION #if SIMDJSON_STATIC_REFLECTION
struct StringTypes { struct StringTypes {
std::string string_val{}; std::string string_val;
std::string_view string_view_val{}; std::string_view string_view_val;
}; };
StringTypes test{"hello world", "test_view"}; StringTypes test{"hello world", "test_view"};
@@ -186,10 +159,10 @@ namespace builder_tests {
TEST_START(); TEST_START();
#if SIMDJSON_STATIC_REFLECTION #if SIMDJSON_STATIC_REFLECTION
struct OptionalTypes { struct OptionalTypes {
std::optional<int> opt_int_with_value{}; std::optional<int> opt_int_with_value;
std::optional<std::string> opt_string_with_value{}; std::optional<std::string> opt_string_with_value;
std::optional<int> opt_int_null{}; std::optional<int> opt_int_null;
std::optional<std::string> opt_string_null{}; std::optional<std::string> opt_string_null;
}; };
OptionalTypes test; OptionalTypes test;
@@ -227,11 +200,11 @@ namespace builder_tests {
TEST_START(); TEST_START();
#if SIMDJSON_STATIC_REFLECTION #if SIMDJSON_STATIC_REFLECTION
struct SmartPointerTypes { struct SmartPointerTypes {
std::unique_ptr<int> unique_int_with_value{}; std::unique_ptr<int> unique_int_with_value;
std::shared_ptr<std::string> shared_string_with_value{}; std::shared_ptr<std::string> shared_string_with_value;
std::unique_ptr<bool> unique_bool_with_value{}; std::unique_ptr<bool> unique_bool_with_value;
std::unique_ptr<int> unique_int_null{}; std::unique_ptr<int> unique_int_null;
std::shared_ptr<std::string> shared_string_null{}; std::shared_ptr<std::string> shared_string_null;
}; };
SmartPointerTypes test; SmartPointerTypes test;
@@ -272,9 +245,9 @@ namespace builder_tests {
#if SIMDJSON_STATIC_REFLECTION #if SIMDJSON_STATIC_REFLECTION
// Test basic container types // Test basic container types
struct ContainerTypes { struct ContainerTypes {
std::vector<int> int_vector{}; std::vector<int> int_vector;
std::set<std::string> string_set{}; std::set<std::string> string_set;
std::map<std::string, int> string_map{}; std::map<std::string, int> string_map;
}; };
ContainerTypes test; ContainerTypes test;
@@ -305,8 +278,8 @@ namespace builder_tests {
// Test std::list with iterator-based serialization // Test std::list with iterator-based serialization
struct ListContainer { struct ListContainer {
std::list<int> int_list{}; std::list<int> int_list;
std::list<std::string> string_list{}; std::list<std::string> string_list;
}; };
ListContainer list_test; ListContainer list_test;
@@ -346,7 +319,13 @@ namespace builder_tests {
bool test_extract_into() { bool test_extract_into() {
TEST_START(); TEST_START();
#if SIMDJSON_STATIC_REFLECTION #if SIMDJSON_STATIC_REFLECTION
struct Car {
std::string make;
std::string model;
int year;
double price;
std::optional<std::string> color;
};
ondemand::parser parser; ondemand::parser parser;
@@ -362,7 +341,7 @@ namespace builder_tests {
"transmission": "Automatic" "transmission": "Automatic"
})"_padded; })"_padded;
CarOpt car{}; Car car{};
ondemand::document doc; ondemand::document doc;
ASSERT_SUCCESS( parser.iterate(padded).get(doc) ); ASSERT_SUCCESS( parser.iterate(padded).get(doc) );
@@ -398,7 +377,7 @@ namespace builder_tests {
"color": "Red" "color": "Red"
})"_padded; })"_padded;
CarOpt car{}; Car car{};
ondemand::document doc; ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(padded).get(doc)); ASSERT_SUCCESS(parser.iterate(padded).get(doc));
@@ -423,7 +402,7 @@ namespace builder_tests {
"price": 35999.99 "price": 35999.99
})"_padded; })"_padded;
CarOpt car{}; Car car{};
ondemand::document doc; ondemand::document doc;
ASSERT_SUCCESS(parser.iterate(padded).get(doc)); ASSERT_SUCCESS(parser.iterate(padded).get(doc));
@@ -516,6 +495,13 @@ namespace builder_tests {
#if SIMDJSON_STATIC_REFLECTION #if SIMDJSON_STATIC_REFLECTION
// Test 1: Extract specific fields from Car struct // Test 1: Extract specific fields from Car struct
{ {
struct Car {
std::string make;
std::string model;
int year;
double price;
bool electric;
};
Car car{"Tesla", "Model 3", 2023, 42000.0, true}; Car car{"Tesla", "Model 3", 2023, 42000.0, true};
@@ -547,7 +533,13 @@ namespace builder_tests {
// Test 2: Extract different field combination // Test 2: Extract different field combination
{ {
struct Car {
std::string make;
std::string model;
int year;
double price;
bool electric;
};
Car car{"Ford", "F-150", 2024, 55000.0, false}; Car car{"Ford", "F-150", 2024, 55000.0, false};
@@ -574,6 +566,13 @@ namespace builder_tests {
// Test 3: Extract from struct with optional fields // Test 3: Extract from struct with optional fields
{ {
struct Person {
std::string name;
int age;
std::optional<std::string> email;
std::optional<std::string> phone;
};
Person person{"John Doe", 30, "john@example.com", std::nullopt}; Person person{"John Doe", 30, "john@example.com", std::nullopt};
// Extract name and email // Extract name and email
@@ -595,6 +594,13 @@ namespace builder_tests {
// Test 4: Extract with optional that has value // Test 4: Extract with optional that has value
{ {
struct Person {
std::string name;
int age;
std::optional<std::string> email;
std::optional<std::string> phone;
};
Person person{"Jane Smith", 25, "jane@example.com", "555-1234"}; Person person{"Jane Smith", 25, "jane@example.com", "555-1234"};
// Extract name, age, and phone // Extract name, age, and phone
@@ -623,21 +629,21 @@ namespace builder_tests {
// Test 5: Round-trip test - serialize with extract_from, deserialize with extract_into // Test 5: Round-trip test - serialize with extract_from, deserialize with extract_into
{ {
struct MyProduct { struct Product {
std::string id{}; std::string id;
std::string name{}; std::string name;
double price{}; double price;
int stock{}; int stock;
}; };
MyProduct original{"P123", "Widget", 19.99, 100}; Product original{"P123", "Widget", 19.99, 100};
// Extract specific fields to JSON // Extract specific fields to JSON
std::string json; std::string json;
ASSERT_SUCCESS((extract_from<"id", "name", "price">(original).get(json))); ASSERT_SUCCESS((extract_from<"id", "name", "price">(original).get(json)));
// Parse and extract back // Parse and extract back
MyProduct restored{"", "", 0.0, 0}; Product restored{"", "", 0.0, 0};
auto padded = pad(json); auto padded = pad(json);
ondemand::parser parser; ondemand::parser parser;
auto doc = parser.iterate(padded); auto doc = parser.iterate(padded);
@@ -11,10 +11,10 @@ using namespace simdjson;
// Suppose that we want to serialize/deserialize Car using // Suppose that we want to serialize/deserialize Car using
// strings for the year // strings for the year
struct Car { struct Car {
std::string make{}; std::string make;
std::string model{}; std::string model;
int64_t year{}; int64_t year;
std::vector<float> tire_pressure{}; std::vector<float> tire_pressure;
}; };
@@ -14,11 +14,11 @@ namespace builder_tests {
TEST_START(); TEST_START();
#if SIMDJSON_STATIC_REFLECTION #if SIMDJSON_STATIC_REFLECTION
struct EmptyValues { struct EmptyValues {
std::string empty_string{}; std::string empty_string;
std::vector<int> empty_vector{}; std::vector<int> empty_vector;
std::optional<int> null_optional{}; std::optional<int> null_optional;
std::unique_ptr<int> null_unique_ptr{}; std::unique_ptr<int> null_unique_ptr;
std::shared_ptr<std::string> null_shared_ptr{}; std::shared_ptr<std::string> null_shared_ptr;
}; };
EmptyValues test; EmptyValues test;
@@ -56,18 +56,18 @@ namespace builder_tests {
TEST_START(); TEST_START();
#if SIMDJSON_STATIC_REFLECTION #if SIMDJSON_STATIC_REFLECTION
struct SpecialChars { struct SpecialChars {
std::string quotes{}; std::string quotes;
std::string backslashes{}; std::string backslashes;
std::string newlines{}; std::string newlines;
std::string unicode{}; std::string unicode;
char null_char{}; char null_char;
}; };
SpecialChars test; SpecialChars test;
test.quotes = "He said \"Hello\""; test.quotes = "He said \"Hello\"";
test.backslashes = "Path\\to\\file"; test.backslashes = "Path\\to\\file";
test.newlines = "Line1\nLine2\tTabbed"; test.newlines = "Line1\nLine2\tTabbed";
test.unicode = "Caf\xc3\xa9 r\xc3\xa9sum\xc3\xa9"; test.unicode = "Café résumé";
test.null_char = '\0'; test.null_char = '\0';
std::string json; std::string json;
@@ -82,10 +82,10 @@ namespace builder_tests {
// Test round-trip (excluding null char which has special handling) // Test round-trip (excluding null char which has special handling)
struct SpecialCharsNoNull { struct SpecialCharsNoNull {
std::string quotes{}; std::string quotes;
std::string backslashes{}; std::string backslashes;
std::string newlines{}; std::string newlines;
std::string unicode{}; std::string unicode;
}; };
SpecialCharsNoNull test_no_null; SpecialCharsNoNull test_no_null;
@@ -157,15 +157,15 @@ namespace builder_tests {
TEST_START(); TEST_START();
#if SIMDJSON_STATIC_REFLECTION #if SIMDJSON_STATIC_REFLECTION
struct Inner { struct Inner {
int value{}; int value;
std::string name{}; std::string name;
}; };
struct Outer { struct Outer {
Inner inner_obj{}; Inner inner_obj;
std::vector<Inner> inner_vector{}; std::vector<Inner> inner_vector;
std::optional<Inner> optional_inner{}; std::optional<Inner> optional_inner;
std::unique_ptr<Inner> unique_inner{}; std::unique_ptr<Inner> unique_inner;
}; };
Outer test; Outer test;
@@ -51,8 +51,8 @@ namespace builder_tests {
}; };
struct StatusStruct { struct StatusStruct {
Status status{}; Status status;
std::string name{}; std::string name;
}; };
// Test deserialization of different enum values with string representation // Test deserialization of different enum values with string representation
@@ -104,9 +104,9 @@ namespace builder_tests {
}; };
struct Task { struct Task {
Priority priority{}; Priority priority;
std::string description{}; std::string description;
int id{}; int id;
}; };
Task original{Priority::High, "Important task", 123}; Task original{Priority::High, "Important task", 123};
@@ -144,8 +144,8 @@ namespace builder_tests {
}; };
struct Response { struct Response {
ErrorCode error{}; ErrorCode error;
std::string message{}; std::string message;
}; };
Response test{ErrorCode::NotFound, "Resource not found"}; Response test{ErrorCode::NotFound, "Resource not found"};
@@ -8,26 +8,26 @@ using namespace simdjson;
// Test structures for FracturedJson builder integration // Test structures for FracturedJson builder integration
struct SimpleUser { struct SimpleUser {
int id{}; int id;
std::string name{}; std::string name;
bool active{}; bool active;
}; };
struct UserWithEmail { struct UserWithEmail {
int id{}; int id;
std::string name{}; std::string name;
std::string email{}; std::string email;
bool active{}; bool active;
}; };
struct NestedData { struct NestedData {
std::string title{}; std::string title;
std::vector<SimpleUser> users{}; std::vector<SimpleUser> users;
int count{}; int count;
}; };
struct TableTestData { struct TableTestData {
std::vector<SimpleUser> records{}; std::vector<SimpleUser> records;
}; };
namespace fractured_json_builder_tests { namespace fractured_json_builder_tests {
+11 -11
View File
@@ -10,7 +10,6 @@
using namespace std::string_view_literals; using namespace std::string_view_literals;
using namespace simdjson; using namespace simdjson;
using namespace simdjson::literals;
namespace compile_time_json_tests { namespace compile_time_json_tests {
/** /**
@@ -667,27 +666,27 @@ bool test_array_of_objects_with_concept() {
/** /**
* Test: #embed support for external JSON files (C++26) * Test: #embed support for external JSON files (C++26)
*/ */
bool test_embed_example_config_json() { bool test_embed_twitter_json() {
TEST_START(); TEST_START();
// C++26 #embed allows embedding files directly into the binary at compile time // C++26 #embed allows embedding files directly into the binary at compile time
// This creates a const char array with the file contents plus null terminator // This creates a const char array with the file contents plus null terminator
constexpr const unsigned char example_config_json[] = { constexpr const char twitter_json[] = {
#embed "../../jsonexamples/example_config.json" #embed TWITTER_JSON
, 0 , 0
}; };
// Parse the embedded JSON at compile time // Parse the embedded JSON at compile time
constexpr auto parsed_example_config = simdjson::compile_time::parse_json<example_config_json>(); constexpr auto parsed_twitter = simdjson::compile_time::parse_json<twitter_json>();
// Verify the structure - example_config.json should have an "app_name" field // Verify the structure - twitter.json should have a "statuses" array
static_assert(std::string_view(parsed_example_config.app_name) == "MyApp"); static_assert(parsed_twitter.statuses.size() > 0);
// Runtime verification // Runtime verification
ASSERT_TRUE(std::string_view(parsed_example_config.app_name) == "MyApp"); ASSERT_TRUE(parsed_twitter.statuses.size() > 0);
std::cout << "Successfully parsed embedded example_config.json with " std::cout << "Successfully parsed embedded twitter.json with "
<< parsed_example_config.app_name << " as app_name" << std::endl; << parsed_twitter.statuses.size() << " statuses" << std::endl;
TEST_SUCCEED(); TEST_SUCCEED();
} }
@@ -719,10 +718,11 @@ bool run() {
test_top_level_array_example() && test_top_level_array_example() &&
test_array_of_objects_with_concept() test_array_of_objects_with_concept()
#ifdef TEST_EMBED_SUPPORTED #ifdef TEST_EMBED_SUPPORTED
&& test_embed_example_config_json() && test_embed_twitter_json()
#endif #endif
; ;
} }
} // namespace compile_time_json_tests } // namespace compile_time_json_tests
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
-1
View File
@@ -11,7 +11,6 @@ add_cpp_test(document_tests LABELS dom acceptance per_implementation
add_cpp_test(errortests LABELS dom acceptance per_implementation) add_cpp_test(errortests LABELS dom acceptance per_implementation)
add_cpp_test(extracting_values_example LABELS dom acceptance per_implementation) add_cpp_test(extracting_values_example LABELS dom acceptance per_implementation)
add_cpp_test(integer_tests LABELS dom acceptance per_implementation) add_cpp_test(integer_tests LABELS dom acceptance per_implementation)
add_cpp_test(big_integer_tests LABELS dom acceptance per_implementation)
add_cpp_test(jsoncheck LABELS dom acceptance per_implementation) add_cpp_test(jsoncheck LABELS dom acceptance per_implementation)
add_cpp_test(json_path_tests LABELS dom acceptance per_implementation) add_cpp_test(json_path_tests LABELS dom acceptance per_implementation)
add_cpp_test(minefieldcheck LABELS dom acceptance per_implementation) add_cpp_test(minefieldcheck LABELS dom acceptance per_implementation)
-151
View File
@@ -1,151 +0,0 @@
#include "simdjson.h"
#include "test_macros.h"
#include <sstream>
using namespace simdjson;
namespace big_integer_tests {
bool option_off_by_default() {
TEST_START();
dom::parser parser;
ASSERT_EQUAL(parser.number_as_string(), false);
TEST_SUCCEED();
}
bool default_returns_bigint_error() {
TEST_START();
dom::parser parser;
auto result = parser.parse(R"({"val":123456789012345678901})"_padded);
ASSERT_EQUAL(result.error(), BIGINT_ERROR);
TEST_SUCCEED();
}
bool opt_in_parses_big_integer() {
TEST_START();
dom::parser parser;
parser.number_as_string(true);
dom::element doc;
ASSERT_SUCCESS(parser.parse(R"({"val":123456789012345678901})"_padded).get(doc));
dom::element val;
ASSERT_SUCCESS(doc["val"].get(val));
ASSERT_EQUAL(val.type(), dom::element_type::BIGINT);
ASSERT_TRUE(val.is_bigint());
std::string_view digits;
ASSERT_SUCCESS(val.get_bigint().get(digits));
ASSERT_EQUAL(digits, "123456789012345678901");
// Verify streaming works (same pattern as readme_examples)
std::ostringstream os;
os << val.get_bigint().value_unsafe();
ASSERT_EQUAL(os.str(), "123456789012345678901");
TEST_SUCCEED();
}
bool negative_big_integer() {
TEST_START();
dom::parser parser;
parser.number_as_string(true);
dom::element doc;
ASSERT_SUCCESS(parser.parse(R"({"val":-12345678901234567890})"_padded).get(doc));
dom::element val;
ASSERT_SUCCESS(doc["val"].get(val));
ASSERT_EQUAL(val.type(), dom::element_type::BIGINT);
std::string_view digits;
ASSERT_SUCCESS(val.get_bigint().get(digits));
ASSERT_EQUAL(digits, "-12345678901234567890");
TEST_SUCCEED();
}
bool big_integer_in_array() {
TEST_START();
dom::parser parser;
parser.number_as_string(true);
dom::element doc;
ASSERT_SUCCESS(parser.parse(R"([1, 123456789012345678901, 3])"_padded).get(doc));
dom::array arr;
ASSERT_SUCCESS(doc.get_array().get(arr));
size_t count = 0;
for (auto elem : arr) { (void)elem; count++; }
ASSERT_EQUAL(count, 3);
TEST_SUCCEED();
}
bool serialization_preserves_digits() {
TEST_START();
dom::parser parser;
parser.number_as_string(true);
dom::element doc;
ASSERT_SUCCESS(parser.parse(R"({"val":123456789012345678901})"_padded).get(doc));
std::string output = simdjson::to_string(doc);
// Raw digits should appear
ASSERT_TRUE(output.find("123456789012345678901") != std::string::npos);
// Must not be quoted - it's a number, not a string
ASSERT_EQUAL(output.find("\"123456789012345678901\""), std::string::npos);
TEST_SUCCEED();
}
bool normal_numbers_unaffected() {
TEST_START();
dom::parser parser;
parser.number_as_string(true);
dom::element doc;
ASSERT_SUCCESS(parser.parse(R"({"a":42,"b":-1,"c":3.14,"d":18446744073709551615})"_padded).get(doc));
int64_t a;
ASSERT_SUCCESS(doc["a"].get_int64().get(a));
ASSERT_EQUAL(a, 42);
uint64_t d;
ASSERT_SUCCESS(doc["d"].get_uint64().get(d));
ASSERT_EQUAL(d, 18446744073709551615ULL);
TEST_SUCCEED();
}
bool type_checks() {
TEST_START();
dom::parser parser;
parser.number_as_string(true);
dom::element doc;
ASSERT_SUCCESS(parser.parse(R"({"val":123456789012345678901})"_padded).get(doc));
dom::element val;
ASSERT_SUCCESS(doc["val"].get(val));
// is_bigint should be true
ASSERT_TRUE(val.is_bigint());
// other type checks should be false
ASSERT_FALSE(val.is_int64());
ASSERT_FALSE(val.is_uint64());
ASSERT_FALSE(val.is_double());
ASSERT_FALSE(val.is_string());
ASSERT_FALSE(val.is_bool());
ASSERT_FALSE(val.is_null());
// get_int64/uint64/double should return INCORRECT_TYPE
ASSERT_ERROR(val.get_int64(), INCORRECT_TYPE);
ASSERT_ERROR(val.get_uint64(), INCORRECT_TYPE);
ASSERT_ERROR(val.get_double(), INCORRECT_TYPE);
ASSERT_ERROR(val.get_string(), INCORRECT_TYPE);
TEST_SUCCEED();
}
bool element_type_output() {
TEST_START();
std::ostringstream os;
os << dom::element_type::BIGINT;
ASSERT_EQUAL(os.str(), "bigint");
TEST_SUCCEED();
}
bool run() {
return option_off_by_default() &&
default_returns_bigint_error() &&
opt_in_parses_big_integer() &&
negative_big_integer() &&
big_integer_in_array() &&
serialization_preserves_digits() &&
normal_numbers_unaffected() &&
type_checks() &&
element_type_output();
}
} // namespace big_integer_tests
int main() {
return big_integer_tests::run() ? 0 : 1;
}
-15
View File
@@ -114,20 +114,6 @@ namespace parser_load {
TEST_SUCCEED(); TEST_SUCCEED();
} }
bool parser_load_string_view_subpath() {
TEST_START();
const std::string valid_path(TWITTER_JSON);
const std::string backing = valid_path + ".extra";
const std::string_view view(backing.data(), valid_path.size());
uint64_t count_from_string = 0;
uint64_t count_from_view = 0;
dom::parser parser;
ASSERT_SUCCESS(parser.load(valid_path)["search_metadata"]["count"].get(count_from_string));
ASSERT_SUCCESS(parser.load(view)["search_metadata"]["count"].get(count_from_view));
ASSERT_EQUAL(count_from_view, count_from_string);
TEST_SUCCEED();
}
bool parser_load_chain() { bool parser_load_chain() {
TEST_START(); TEST_START();
dom::parser parser; dom::parser parser;
@@ -150,7 +136,6 @@ namespace parser_load {
&& parser_load_nonexistent() && parser_load_nonexistent()
&& parser_load_many_nonexistent() && parser_load_many_nonexistent()
&& padded_string_load_nonexistent() && padded_string_load_nonexistent()
&& parser_load_string_view_subpath()
&& parser_load_chain() && parser_load_chain()
&& parser_load_many_chain() && parser_load_many_chain()
&& parser_parse_many_documents_error_in_the_middle() && parser_parse_many_documents_error_in_the_middle()
-33
View File
@@ -1,6 +1,5 @@
#include <iostream> #include <iostream>
#include "simdjson.h" #include "simdjson.h"
#include "simdjson/padded_string_view.h"
using namespace std; using namespace std;
using namespace simdjson; using namespace simdjson;
@@ -274,9 +273,6 @@ namespace treewalk_1 {
case dom::element_type::NULL_VALUE: case dom::element_type::NULL_VALUE:
cout << "null" << endl; cout << "null" << endl;
break; break;
case dom::element_type::BIGINT:
cout << element.get_bigint().value_unsafe() << endl;
break;
} }
} }
@@ -532,35 +528,6 @@ void simplepad() {
if(error) { exit(-1); } if(error) { exit(-1); }
} }
#if SIMDJSON_CPLUSPLUS17
void simpleinputpad_dom1() {
std::string_view json = "[1,2,3]";
simdjson::padded_input input(json);
dom::parser parser;
dom::element doc;
auto error = parser.parse(input).get(doc);
if(error) { exit(-1); }
}
void simpleinputpad_dom2() {
const char *jsonpointer = R"(
{
"key": "value"
}
)";
size_t len = strlen(jsonpointer);
simdjson::padded_input input(jsonpointer, len);
dom::parser parser;
dom::element doc;
auto error = parser.parse(input).get(doc);
if(error) { exit(-1); }
std::string_view val;
error = doc["key"].get(val);
if(error) { exit(-1); }
if(val != "value") { exit(-1); }
}
#endif // SIMDJSON_CPLUSPLUS17
void jsondollar() { void jsondollar() {
dom::parser parser; dom::parser parser;
auto json = R"( { "c" :{ "foo": { "a": [ 10, 20, 30 ] }}, "d": { "foo2": { "a": [ 10, 20, 30 ] }} , "e": 120 })"_padded; auto json = R"( { "c" :{ "foo": { "a": [ 10, 20, 30 ] }}, "d": { "foo2": { "a": [ 10, 20, 30 ] }} , "e": 120 })"_padded;
-36
View File
@@ -1,36 +0,0 @@
# Feature flag tests: compile and run against the amalgamated single-header file.
# Each test uses target_compile_definitions to set its own feature macros,
# independent of the project-wide settings.
set(SINGLEHEADER_DIR ${PROJECT_SOURCE_DIR}/singleheader)
function(add_feature_flag_test TEST_NAME)
cmake_parse_arguments(PARSE_ARGV 1 ARG "" "" "DEFS")
add_executable(${TEST_NAME} ${TEST_NAME}.cpp ${SINGLEHEADER_DIR}/simdjson.cpp)
target_include_directories(${TEST_NAME} PRIVATE ${SINGLEHEADER_DIR})
target_compile_features(${TEST_NAME} PRIVATE cxx_std_17)
# Override any inherited feature flag definitions with our own.
target_compile_definitions(${TEST_NAME} PRIVATE ${ARG_DEFS})
# Remove inherited link libraries (simdjson-internal-flags brings -Werror
# which conflicts with the amalgamated header's warning profile).
set_target_properties(${TEST_NAME} PROPERTIES LINK_LIBRARIES "")
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
set_property(TEST ${TEST_NAME} APPEND PROPERTY LABELS feature_flags acceptance)
endfunction()
add_feature_flag_test(dom_only DEFS
SIMDJSON_FEATURE_DOM_API=1 SIMDJSON_FEATURE_ONDEMAND_API=0 SIMDJSON_FEATURE_BUILDER_API=0)
# Note: OnDemand tests also enable DOM because the builtin infrastructure
# is currently included via the DOM/builtin path in the amalgamated header.
add_feature_flag_test(ondemand_only DEFS
SIMDJSON_FEATURE_DOM_API=1 SIMDJSON_FEATURE_ONDEMAND_API=1 SIMDJSON_FEATURE_BUILDER_API=0)
add_feature_flag_test(dom_and_ondemand DEFS
SIMDJSON_FEATURE_DOM_API=1 SIMDJSON_FEATURE_ONDEMAND_API=1 SIMDJSON_FEATURE_BUILDER_API=0)
add_feature_flag_test(builder_and_dom DEFS
SIMDJSON_FEATURE_DOM_API=1 SIMDJSON_FEATURE_ONDEMAND_API=0 SIMDJSON_FEATURE_BUILDER_API=1)
add_feature_flag_test(builder_and_ondemand DEFS
SIMDJSON_FEATURE_DOM_API=1 SIMDJSON_FEATURE_ONDEMAND_API=1 SIMDJSON_FEATURE_BUILDER_API=1)
add_feature_flag_test(builder_dom_and_ondemand DEFS
SIMDJSON_FEATURE_DOM_API=1 SIMDJSON_FEATURE_ONDEMAND_API=1 SIMDJSON_FEATURE_BUILDER_API=1)
add_feature_flag_test(builder_only DEFS
SIMDJSON_FEATURE_DOM_API=1 SIMDJSON_FEATURE_ONDEMAND_API=0 SIMDJSON_FEATURE_BUILDER_API=1)
@@ -1,42 +0,0 @@
// Test: Builder + DOM APIs (OnDemand disabled)
// Feature flags set via target_compile_definitions in CMakeLists.txt
#include "simdjson.h"
#include <iostream>
int main() {
auto json = R"({"key": "value"})"_padded;
// Use DOM API
simdjson::dom::parser parser;
simdjson::dom::element doc;
auto error = parser.parse(json).get(doc);
if (error) {
std::cerr << "DOM parse error: " << error << std::endl;
return EXIT_FAILURE;
}
std::string_view val;
error = doc["key"].get_string().get(val);
if (error || val != "value") {
std::cerr << "DOM key lookup failed" << std::endl;
return EXIT_FAILURE;
}
// Use Builder API
simdjson::builder::string_builder sb;
sb.start_object();
sb.append_key_value("greeting", "hello");
sb.end_object();
std::string_view result;
error = sb.view().get(result);
if (error) {
std::cerr << "Builder error: " << error << std::endl;
return EXIT_FAILURE;
}
if (result != R"({"greeting":"hello"})") {
std::cerr << "Builder output mismatch: " << result << std::endl;
return EXIT_FAILURE;
}
std::cout << "Builder+DOM test passed." << std::endl;
return EXIT_SUCCESS;
}
@@ -1,45 +0,0 @@
// Test: Builder + OnDemand APIs (DOM also enabled since Builder depends on it)
// Feature flags set via target_compile_definitions in CMakeLists.txt
#include "simdjson.h"
#include <iostream>
int main() {
// Use OnDemand API
auto json = R"({"key": "value"})"_padded;
simdjson::ondemand::parser parser;
simdjson::ondemand::document doc;
auto error = parser.iterate(json).get(doc);
if (error) {
std::cerr << "OnDemand parse error: " << error << std::endl;
return EXIT_FAILURE;
}
std::string_view val;
error = doc["key"].get_string().get(val);
if (error || val != "value") {
std::cerr << "OnDemand key lookup failed" << std::endl;
return EXIT_FAILURE;
}
// Use Builder API
simdjson::builder::string_builder sb;
sb.start_array();
sb.append(1);
sb.append_comma();
sb.append(2);
sb.append_comma();
sb.append(3);
sb.end_array();
std::string_view result;
error = sb.view().get(result);
if (error) {
std::cerr << "Builder error: " << error << std::endl;
return EXIT_FAILURE;
}
if (result != "[1,2,3]") {
std::cerr << "Builder output mismatch: " << result << std::endl;
return EXIT_FAILURE;
}
std::cout << "Builder+OnDemand test passed." << std::endl;
return EXIT_SUCCESS;
}
@@ -1,59 +0,0 @@
// Test: All three APIs enabled (Builder + DOM + OnDemand)
// Feature flags set via target_compile_definitions in CMakeLists.txt
#include "simdjson.h"
#include <iostream>
int main() {
auto json = R"({"name": "simdjson", "version": 5})"_padded;
// Use DOM API
simdjson::dom::parser dom_parser;
simdjson::dom::element dom_doc;
auto error = dom_parser.parse(json).get(dom_doc);
if (error) {
std::cerr << "DOM parse error: " << error << std::endl;
return EXIT_FAILURE;
}
std::string_view name;
error = dom_doc["name"].get_string().get(name);
if (error || name != "simdjson") {
std::cerr << "DOM name lookup failed" << std::endl;
return EXIT_FAILURE;
}
// Use OnDemand API
simdjson::ondemand::parser od_parser;
simdjson::ondemand::document od_doc;
error = od_parser.iterate(json).get(od_doc);
if (error) {
std::cerr << "OnDemand parse error: " << error << std::endl;
return EXIT_FAILURE;
}
std::string_view od_name;
error = od_doc["name"].get_string().get(od_name);
if (error || od_name != "simdjson") {
std::cerr << "OnDemand name lookup failed" << std::endl;
return EXIT_FAILURE;
}
// Use Builder API
simdjson::builder::string_builder sb;
sb.start_object();
sb.append_key_value("name", "simdjson");
sb.append_comma();
sb.append_key_value("version", 5);
sb.end_object();
std::string_view result;
error = sb.view().get(result);
if (error) {
std::cerr << "Builder error: " << error << std::endl;
return EXIT_FAILURE;
}
if (result != R"({"name":"simdjson","version":5})") {
std::cerr << "Builder output mismatch: " << result << std::endl;
return EXIT_FAILURE;
}
std::cout << "Builder+DOM+OnDemand test passed." << std::endl;
return EXIT_SUCCESS;
}

Some files were not shown because too many files have changed in this diff Show More