Compare commits

...

53 Commits

Author SHA1 Message Date
Daniel Lemire 9dd6e9c959 version bump 2023-10-25 19:35:51 -04:00
Daniel Lemire 6db330c1a2 Automating string reallocation when it is possible (#2076)
* Automating string reallocation

* Typo
2023-10-25 19:34:52 -04:00
Daniel Lemire 993ac4b87c Adding the ability to write directly to an std::string. It is mostly syntaxic sugar (#2075) 2023-10-25 19:32:12 -04:00
Daniel Lemire 35e87896f0 minor tweak 2023-10-25 10:50:27 -04:00
Daniel Lemire f7e281cadc removing noisy warning 2023-10-20 15:45:40 -04:00
Daniel Lemire 13405afd4b This provides verbose static_assert messages (#2074)
* This provides verbose static_assert messages

* minor fix
2023-10-20 15:42:18 -04:00
Daniel Lemire 24b44309fb Removing commented code 2023-10-15 14:56:32 -04:00
Momtchil Momtchev e11ad58aad add a total order for elements (#2072) 2023-10-09 15:41:57 -04:00
Daniel Lemire 1875ed6550 Version bump. 2023-09-20 10:13:47 -04:00
Daniel Lemire 80d26298a0 Redesigning visit_primitive so that it is optimized for strings and (#2060)
numbers.

Co-authored-by: Daniel Lemire <dlemire@lemire.me>
2023-09-20 10:09:56 -04:00
Antoine Prouvost 25b5015c09 Add simdjson_static lib (#2068)
* Add simdjson_static lib

* Make simdjson_static a separate optional export file
2023-09-20 10:09:27 -04:00
Antoine Prouvost 26f8c566c7 Fix issue template bold text (#2067) 2023-09-19 11:15:54 -04:00
Daniel Lemire ff77ac801e Additional documentation based on issue 2063 (#2065)
* Additional documentation based on issue 2063

* Update basics.md
2023-09-11 10:01:35 -04:00
Daniel Lemire e0699994ef Testing macOS shared library support (#2062) 2023-09-09 12:48:42 -04:00
Daniel Lemire 68ba9a1b2a Adding a few spaces (minor formatting) (#2059) 2023-08-30 20:23:58 -04:00
Daniel Lemire 6fed6bd29b Update README.md 2023-08-30 19:26:34 -04:00
Piotr Rżysko cc24bb4114 Removed number parsing fallback (#2056) 2023-08-29 18:28:21 -04:00
John Keiser 14ec0ca8f4 Merge pull request #2052 from simdjson/jkeiser/structural_indexer_step
Write out 4 structural indexes at a time instead of 8
2023-08-29 15:24:54 -07:00
John Keiser 8dabd02c3a Default to step = 4 2023-08-29 15:48:52 -04:00
Daniel Lemire c9692005fd This allows us to pass SIMDJSON_STRUCTURAL_INDEXER_STEP as a command-line option. (#2055) 2023-08-25 13:47:20 -04:00
Daniel Lemire 2e0a9397c9 Merge branch 'master' into jkeiser/structural_indexer_step 2023-08-25 11:34:13 -04:00
Daniel Lemire f7922075c3 Adding support for Apple event counters (#2054) 2023-08-25 11:33:24 -04:00
Daniel Lemire b2e20e04c9 Standard compatibility fixes (#2053)
* Standard compatibility fixes

* missing commit

* Should work.

* Fix.

* Fix.

* Should work now.

---------

Co-authored-by: Daniel Lemire <dlemire@lemire.me>
2023-08-25 10:18:02 -04:00
John Keiser adc9d18efd Change step for structural_indexes to 2 2023-08-23 19:02:05 -07:00
Daniel Lemire bf849e3619 Preparing release 2023-08-22 14:05:14 -04:00
Daniel Lemire c09e8dc225 Icelake processes 64 bytes at a time when processing strings. (#2050)
Co-authored-by: Daniel Lemire <dlemire@lemire.me>
2023-08-18 14:37:10 -04:00
Daniel Lemire 5bf585ef02 Fixing failing thread sanitizer (#2051) 2023-08-18 14:35:12 -04:00
Daniel Lemire caff09cafc Update iterate_many.md 2023-08-14 12:18:09 -04:00
Daniel Lemire f043db4dca Preparing release. 2023-08-02 16:01:39 -04:00
Daniel Lemire e3bd0828d1 Fix for issue 2045. (#2046)
* Fix for issue 2045.

* Retauring single-header code.
2023-08-02 16:00:45 -04:00
John Keiser 9408298e0e Merge pull request #2042 from simdjson/jkeiser/escape3
New escape algorithm with significantly less data dependency
2023-08-02 10:38:09 -07:00
John Keiser 573bbac2d2 Reamalgamate again 2023-08-02 08:28:35 -07:00
John Keiser ac78c625df simdjson_inline -> simdjson_really_inline 2023-08-02 08:28:05 -07:00
John Keiser 390a66c6e8 Make next_structurals inline 2023-08-02 08:28:05 -07:00
John Keiser 210e0a56a1 Reamalgamate 2023-08-02 08:28:05 -07:00
John Keiser 084f662f32 Don't use C++20 designated initializers 2023-08-02 08:28:05 -07:00
John Keiser c878ff2500 Fix compiler warnings 2023-08-02 08:28:05 -07:00
John Keiser 06afe9ecb3 New escape algorithm with significantly less data dependency 2023-08-02 08:28:05 -07:00
Daniel Lemire e658502adb We are having issues with llvm.sh (#2044) 2023-08-02 11:24:28 -04:00
Daniel Lemire 6e7d415040 These lines should not be necessary. (#2043) 2023-08-01 19:33:27 -04:00
John Keiser 2ccd5b9c97 Merge pull request #2039 from simdjson/jkeiser/more-headers
Disallow including headers from implementation files
2023-07-21 12:09:57 -07:00
Daniel Lemire 1cdcbf79b3 We do actually support legacy 32-bit systems, although not with fast kernels. (#2041) 2023-07-21 13:53:10 -04:00
Calum McConnell 7013ed98cc Peek(0) is an error on 32-bit systems, where pointers are indistinguishable from int32_t (#2040) 2023-07-21 13:52:53 -04:00
John Keiser b383c717d7 Have amalgamate.py verify it's actually amalgamating all the files 2023-07-20 15:11:52 -07:00
John Keiser b8743bced0 Fix amalgamate.py under python 3.7 2023-07-20 14:14:44 -07:00
John Keiser ae9ba2bed2 Rename SIMDJSON_AMALGAMATED to SIMDJSON_CONDITIONAL_INCLUDE 2023-07-20 11:43:19 -07:00
Daniel Lemire 939844d79f Adding tests for issue 2037. (#2038)
* Adding tests for issue 2037.

* Fixed typo

* Simplifying.
2023-07-20 14:11:33 -04:00
John Keiser 4f4e81668e Change all include paths to <> instead of "" to avoid relative path includes 2023-07-20 10:48:25 -07:00
John Keiser bb54946b78 Disallow including headers from implementation files 2023-07-20 10:01:22 -07:00
John Keiser 4dec6ed5a7 Merge pull request #2036 from simdjson/jkeiser/more-header-fixes
A few more header fixes
2023-07-18 10:26:40 -07:00
John Keiser 1dfd48195d Merge pull request #2035 from simdjson/jkeiser/sanitizer-ci
Run sanitizers in parallel
2023-07-17 23:37:34 -07:00
John Keiser 23afc6b695 Merge branch 'master' into jkeiser/sanitizer-ci 2023-07-17 16:09:20 -07:00
John Keiser 80bc9e5051 Run sanitizers in parallel 2023-07-17 12:57:50 -07:00
202 changed files with 12424 additions and 32809 deletions
+22 -1
View File
@@ -1,5 +1,8 @@
CompileFlags:
CompilationDatabase: build
Add:
- -Werror -Wall -Wextra -Weffc++ -Wsign-compare -Wshadow -Wwrite-strings -Wpointer-arith -Winit-self -Wconversion -Wno-sign-conversion
- -Wundefined-inline
Diagnostics:
Suppress:
- misc-unused-alias-decls
@@ -16,10 +19,28 @@ If:
CompileFlags:
Add:
- -Wno-unneeded-internal-declaration
- -Wno-undefined-inline # TODO fix and remove these violations
- -Wno-undefined-internal # TODO fix and remove these violations
- -Wno-unused-function
- -Wno-unused-const-variable
Diagnostics:
Suppress:
- pp_including_mainfile_in_preamble
---
# Amalgamated files that require or partly define an implementation
If:
PathMatch:
- .*/(arm64|fallback|haswell|icelake|ppc64|westmere)/begin.h
- .*/generic/.*
Diagnostics:
Suppress:
- pragma_attribute_no_pop_eof
---
# clang has a bad time detecting the push/pop together in src/ for some reason
If:
PathMatch:
- include/simdjson/.*/end.h
- src/(arm64|fallback|haswell|icelake|ppc64|westmere).cpp
Diagnostics:
Suppress:
- pragma_attribute_no_pop_eof
- pragma_attribute_stack_mismatch
+1 -1
View File
@@ -49,7 +49,7 @@ It is fine to report bugs against our main branch, but if that is what you are d
- Version [e.g. 22]
- Optimization setting (e.g., -O3)
We support up-to-date 64-bit ARM and x64 FreeBSD, macOS, Windows and Linux systems. Please ensure that your configuration is supported before labelling the issue as a bug. In particular, we do not support legacy 32-bit systems.
We support up-to-date 64-bit ARM and x64 FreeBSD, macOS, Windows and Linux systems. Please ensure that your configuration is supported before labelling the issue as a bug.
**Indicate whether you are willing or able to provide a bug fix as a pull request**
+1 -1
View File
@@ -31,7 +31,7 @@ A clear and concise description of any alternative solutions or features you've
**Additional context**
Add any other context or screenshots about the feature request here.
** Are you willing to contribute code or documentation toward this new feature? **
**Are you willing to contribute code or documentation toward this new feature?**
If you plan to contribute to simdjson, please read our
* CONTRIBUTING guide: https://github.com/simdjson/simdjson/blob/master/CONTRIBUTING.md and our
* HACKING guide: https://github.com/simdjson/simdjson/blob/master/HACKING.md
+1
View File
@@ -34,6 +34,7 @@ jobs:
sudo apt update
sudo apt-get install --quiet ninja-build valgrind zip unzip lsb-release wget software-properties-common gnupg
wget https://apt.llvm.org/llvm.sh
sudo apt-get purge --auto-remove llvm python3-lldb-14 llvm-14
chmod +x llvm.sh
sudo ./llvm.sh $CLANGVERSION
+11
View File
@@ -31,3 +31,14 @@ jobs:
echo -e '#include <simdjson.h>\nint main(int argc,char**argv) {simdjson::dom::parser parser;simdjson::dom::element tweets = parser.load(argv[1]); }' > tmp.cpp && c++ -Idestination/include -Ldestination/lib -std=c++17 -Wl,-rpath,destination/lib -o linkandrun tmp.cpp -lsimdjson && ./linkandrun jsonexamples/twitter.json &&
cd ../tests/installation_tests/find &&
mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX:PATH=../../../build/destination .. && cmake --build .
- name: Use cmake (shared)
run: |
mkdir buildshared &&
cd buildshared &&
cmake -DSIMDJSON_GOOGLE_BENCHMARKS=ON -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX:PATH=destination .. &&
cmake --build . &&
ctest --output-on-failure -LE explicitonly -j &&
cmake --install . &&
echo -e '#include <simdjson.h>\nint main(int argc,char**argv) {simdjson::dom::parser parser;simdjson::dom::element tweets = parser.load(argv[1]); }' > tmp.cpp && c++ -Idestination/include -Ldestination/lib -std=c++17 -Wl,-rpath,destination/lib -o linkandrun tmp.cpp -lsimdjson && ./linkandrun jsonexamples/twitter.json &&
cd ../tests/installation_tests/find &&
mkdir buildshared && cd buildshared && cmake -DCMAKE_INSTALL_PREFIX:PATH=../../../buildshared/destination .. && cmake --build .
+13 -1
View File
@@ -3,7 +3,7 @@ name: Ubuntu 20.04 CI (GCC 9) With Memory Sanitizer
on: [push, pull_request]
jobs:
ubuntu-build:
ubuntu-build-address-sanitizier:
if: >-
! contains(toJSON(github.event.commits.*.message), '[skip ci]') &&
! contains(toJSON(github.event.commits.*.message), '[skip github]')
@@ -21,6 +21,18 @@ jobs:
cmake -DSIMDJSON_SANITIZE=ON -DCMAKE_BUILD_TYPE=Debug -DSIMDJSON_GOOGLE_BENCHMARKS=OFF -DSIMDJSON_DEVELOPER_MODE=ON -DBUILD_SHARED_LIBS=OFF .. &&
cmake --build . &&
ctest --output-on-failure -LE explicitonly -j
ubuntu-build-undefined-sanitizer:
if: >-
! contains(toJSON(github.event.commits.*.message), '[skip ci]') &&
! contains(toJSON(github.event.commits.*.message), '[skip github]')
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
with:
path: dependencies/.cache
key: ${{ hashFiles('dependencies/CMakeLists.txt') }}
ctest --output-on-failure -LE explicitonly -j
- name: Use cmake with undefined sanitizer
run: |
mkdir builddebugundefsani &&
+14
View File
@@ -14,6 +14,20 @@ jobs:
with:
path: dependencies/.cache
key: ${{ hashFiles('dependencies/CMakeLists.txt') }}
- name: Use cmake to build just the library
run: |
mkdir buildjustlib &&
cd buildjustlib &&
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DSIMDJSON_DEVELOPER_MODE=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination .. &&
cmake --build . &&
cmake --install . &&
echo -e '#include <simdjson.h>\nint main(int argc,char**argv) {simdjson::dom::parser parser;simdjson::dom::element tweets = parser.load(argv[1]); }' > tmp.cpp &&
c++ -Idestination/include -Ldestination/lib -std=c++17 -Wl,-rpath,destination/lib -o linkandrun tmp.cpp -lsimdjson &&
cd ../tests/installation_tests/find &&
mkdir buildjustlib &&
cd buildjustlib &&
cmake -DCMAKE_INSTALL_PREFIX:PATH=../../../buildjustlib/destination .. &&
cmake --build .
- name: Use cmake
run: |
mkdir builddebug &&
-2
View File
@@ -14,8 +14,6 @@ jobs:
with:
path: dependencies/.cache
key: ${{ hashFiles('dependencies/CMakeLists.txt') }}
- name: Install clang++-13
run: sudo apt-get install -y clang++-13
- name: Use cmake
run: |
mkdir build &&
-2
View File
@@ -14,8 +14,6 @@ jobs:
with:
path: dependencies/.cache
key: ${{ hashFiles('dependencies/CMakeLists.txt') }}
- name: Install clang++-14
run: sudo apt-get install -y clang++-14
- name: Use cmake
run: |
mkdir build &&
@@ -1,4 +1,4 @@
name: Ubuntu 20.04 CI (GCC 9) with Thread Sanitizer
name: Ubuntu 22.04 CI (GCC 11) with Thread Sanitizer
on: [push, pull_request]
@@ -7,7 +7,7 @@ jobs:
if: >-
! contains(toJSON(github.event.commits.*.message), '[skip ci]') &&
! contains(toJSON(github.event.commits.*.message), '[skip github]')
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
+14
View File
@@ -14,6 +14,20 @@ jobs:
with:
path: dependencies/.cache
key: ${{ hashFiles('dependencies/CMakeLists.txt') }}
- name: Use cmake to build just the library
run: |
mkdir buildjustlib &&
cd buildjustlib &&
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DSIMDJSON_DEVELOPER_MODE=OFF -DCMAKE_INSTALL_PREFIX:PATH=destination .. &&
cmake --build . &&
cmake --install . &&
echo -e '#include <simdjson.h>\nint main(int argc,char**argv) {simdjson::dom::parser parser;simdjson::dom::element tweets = parser.load(argv[1]); }' > tmp.cpp &&
c++ -Idestination/include -Ldestination/lib -std=c++17 -Wl,-rpath,destination/lib -o linkandrun tmp.cpp -lsimdjson &&
cd ../tests/installation_tests/find &&
mkdir buildjustlib &&
cd buildjustlib &&
cmake -DCMAKE_INSTALL_PREFIX:PATH=../../../buildjustlib/destination .. &&
cmake --build .
- name: Use cmake
run: |
mkdir builddebug &&
+32 -5
View File
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14)
project(
simdjson
# The version number is modified by tools/release.py
VERSION 3.2.1
VERSION 3.4.0
DESCRIPTION "Parsing gigabytes of JSON per second"
HOMEPAGE_URL "https://simdjson.org/"
LANGUAGES CXX C
@@ -20,8 +20,10 @@ string(
# ---- Options, variables ----
# These version numbers are modified by tools/release.py
set(SIMDJSON_LIB_VERSION "16.0.0" CACHE STRING "simdjson library version")
set(SIMDJSON_LIB_SOVERSION "16" CACHE STRING "simdjson library soversion")
set(SIMDJSON_LIB_VERSION "17.0.0" CACHE STRING "simdjson library version")
set(SIMDJSON_LIB_SOVERSION "17" CACHE STRING "simdjson library soversion")
option(SIMDJSON_BUILD_STATIC_LIB "Build simdjson_static library along with simdjson" OFF)
option(SIMDJSON_ENABLE_THREADS "Link with thread support" ON)
@@ -56,8 +58,17 @@ include(cmake/developer-options.cmake)
# ---- simdjson library ----
add_library(simdjson src/simdjson.cpp)
set(SIMDJSON_SOURCES src/simdjson.cpp)
add_library(simdjson ${SIMDJSON_SOURCES})
add_library(simdjson::simdjson ALIAS simdjson)
set(SIMDJSON_LIBRARIES simdjson)
if(SIMDJSON_BUILD_STATIC_LIB)
add_library(simdjson_static STATIC ${SIMDJSON_SOURCES})
add_library(simdjson::simdjson_static ALIAS simdjson_static)
list(APPEND SIMDJSON_LIBRARIES simdjson_static)
endif()
set_target_properties(
simdjson PROPERTIES
@@ -117,6 +128,9 @@ if(SIMDJSON_ENABLE_THREADS)
endif()
simdjson_apply_props(simdjson)
if(SIMDJSON_BUILD_STATIC_LIB)
simdjson_apply_props(simdjson_static)
endif()
# ---- Install rules ----
@@ -138,7 +152,6 @@ install(
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(
@@ -167,6 +180,20 @@ install(
COMPONENT simdjson_Development
)
if(SIMDJSON_BUILD_STATIC_LIB)
install(
TARGETS simdjson_static
EXPORT simdjson_staticTargets
ARCHIVE COMPONENT simdjson_Development
)
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}")
+1 -1
View File
@@ -38,7 +38,7 @@ PROJECT_NAME = simdjson
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = "3.2.1"
PROJECT_NUMBER = "3.4.0"
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
-2
View File
@@ -1,8 +1,6 @@
[![Ubuntu 20.04 CI](https://github.com/simdjson/simdjson/workflows/Ubuntu%2020.04%20CI%20(GCC%209)/badge.svg)](https://simdjson.org/plots.html)
![VS16-CI](https://github.com/simdjson/simdjson/workflows/VS16-CI/badge.svg)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/simdjson.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:simdjson)
![MinGW64-CI](https://github.com/simdjson/simdjson/workflows/MinGW64-CI/badge.svg)
[![][license img]][license]
[![Doxygen Documentation](https://img.shields.io/badge/docs-doxygen-green.svg)](https://simdjson.github.io/simdjson/)
File diff suppressed because it is too large Load Diff
+13 -9
View File
@@ -445,7 +445,7 @@ struct benchmarker {
return 100.0 * a / b;
}
void print(bool tabbed_output) const {
void print(bool tabbed_output, bool stage1_only) const {
if (tabbed_output) {
char* filename_copy = reinterpret_cast<char*>(malloc(strlen(filename)+1));
SIMDJSON_PUSH_DISABLE_WARNINGS
@@ -503,17 +503,21 @@ struct benchmarker {
stats->blocks_with_16_structurals_flipped, percent(stats->blocks_with_16_structurals_flipped, stats->blocks));
}
printf("\n");
printf("All Stages (excluding allocation)\n");
print_aggregate("| " , all_stages_without_allocation.best);
// frequently, allocation is a tiny fraction of the running time so we omit it
if(allocate_stage.best.elapsed_sec() > 0.01 * all_stages_without_allocation.best.elapsed_sec()) {
printf("|- Allocation\n");
print_aggregate("| ", allocate_stage.best);
if(!stage1_only) {
printf("All Stages (excluding allocation)\n");
print_aggregate("| " , all_stages_without_allocation.best);
// frequently, allocation is a tiny fraction of the running time so we omit it
if(allocate_stage.best.elapsed_sec() > 0.01 * all_stages_without_allocation.best.elapsed_sec()) {
printf("|- Allocation\n");
print_aggregate("| ", allocate_stage.best);
}
}
printf("|- Stage 1\n");
print_aggregate("| ", stage1.best);
printf("|- Stage 2\n");
print_aggregate("| ", stage2.best);
if(!stage1_only) {
printf("|- Stage 2\n");
print_aggregate("| ", stage2.best);
}
if (collector.has_events()) {
double freq1 = (stage1.best.cycles() / stage1.best.elapsed_sec()) / 1000000000.0;
double freq2 = (stage2.best.cycles() / stage2.best.elapsed_sec()) / 1000000000.0;
+1 -1
View File
@@ -218,7 +218,7 @@ int main(int argc, char *argv[]) {
if (!options.verbose) { progress.erase(); }
for (size_t i=0; i<options.files.size(); i++) {
benchmarkers[i]->print(options.tabbed_output);
benchmarkers[i]->print(options.tabbed_output, options.stage1_only);
delete benchmarkers[i];
}
+28 -3
View File
@@ -34,11 +34,15 @@
#include <string>
#include <vector>
#include "linux-perf-events.h"
#ifdef __linux__
#include "linux-perf-events.h"
#include <libgen.h>
#endif
#if __APPLE__ && __aarch64__
#include "apple/apple_arm_events.h"
#endif
#include "simdjson.h"
using std::string;
@@ -134,7 +138,7 @@ struct event_collector {
#if defined(__linux__)
LinuxEvents<PERF_TYPE_HARDWARE> linux_events;
event_collector(simdjson_unused bool quiet = false) : linux_events(vector<int>{
event_collector() : linux_events(vector<int>{
#if SIMDJSON_SIMPLE_PERFORMANCE_COUNTERS
PERF_COUNT_HW_CPU_CYCLES,
PERF_COUNT_HW_INSTRUCTIONS,
@@ -149,8 +153,17 @@ struct event_collector {
bool has_events() {
return linux_events.is_working();
}
#elif __APPLE__ && __aarch64__
AppleEvents apple_events;
performance_counters diff;
event_collector() : diff(0) {
apple_events.setup_performance_counters();
}
bool has_events() {
return apple_events.setup_performance_counters();
}
#else
event_collector(simdjson_unused bool _quiet = false) {}
event_collector() {}
bool has_events() {
return false;
}
@@ -159,6 +172,8 @@ struct event_collector {
simdjson_inline void start() {
#if defined(__linux)
linux_events.start();
#elif __APPLE__ && __aarch64__
if(has_events()) { diff = apple_events.get_counters(); }
#endif
start_clock = steady_clock::now();
}
@@ -166,6 +181,16 @@ struct event_collector {
time_point<steady_clock> end_clock = steady_clock::now();
#if defined(__linux)
linux_events.end(count.event_counts);
#elif __APPLE__ && __aarch64__
if(has_events()) {
performance_counters end = apple_events.get_counters();
diff = end - diff;
}
count.event_counts[0] = diff.cycles;
count.event_counts[1] = diff.instructions;
count.event_counts[2] = diff.missed_branches;
count.event_counts[3] = 0;
count.event_counts[4] = 0;
#endif
count.elapsed = end_clock - start_clock;
return count;
@@ -19,7 +19,7 @@ void maybe_display_implementation() {
template<typename B, typename R> static void run_json_benchmark(benchmark::State &state) {
maybe_display_implementation();
event_collector collector(true);
event_collector collector;
event_aggregate events;
// Warmup and equality check (make sure the data is right!)
+5 -1
View File
@@ -114,10 +114,14 @@ set(SIMDJSON_CXX_STANDARD 17 CACHE STRING "the C++ standard to use for simdjson"
set(CMAKE_CXX_STANDARD ${SIMDJSON_CXX_STANDARD})
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_MACOSX_RPATH OFF)
set(CMAKE_THREAD_PREFER_PTHREAD ON)
set(THREADS_PREFER_PTHREAD_FLAG ON)
set(SIMDJSON_STRUCTURAL_INDEXER_STEP CACHE STRING "the SIMDJSON_STRUCTURAL_INDEXER_STEP variable")
if(SIMDJSON_STRUCTURAL_INDEXER_STEP)
message(STATUS "Setting SIMDJSON_STRUCTURAL_INDEXER_STEP to ${SIMDJSON_STRUCTURAL_INDEXER_STEP}.")
add_compile_definitions(SIMDJSON_STRUCTURAL_INDEXER_STEP=${SIMDJSON_STRUCTURAL_INDEXER_STEP})
endif()
# LTO seems to create all sorts of fun problems. Let us
# disable temporarily.
#include(CheckIPOSupported)
+1
View File
@@ -4,3 +4,4 @@ if("@SIMDJSON_ENABLE_THREADS@")
endif()
include("${CMAKE_CURRENT_LIST_DIR}/simdjsonTargets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/simdjson_staticTargets.cmake" OPTIONAL)
+152 -38
View File
@@ -179,8 +179,8 @@ strcpy(json, "[1]");
ondemand::document doc = parser.iterate(json, strlen(json), sizeof(json));
```
The simdjson library will also accept `std::string` instances, as long as the `capacity()` of
the string exceeds the `size()` by at least `SIMDJSON_PADDING`. You can increase the `capacity()` with the `reserve()` function of your strings.
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:
@@ -355,7 +355,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
* **Field Access:** To get the value of the "foo" field in an object, use `object["foo"]`. This will
scan through the object looking for the field with the matching string, doing a character-by-character
comparison. It may generate the error `simdjson::NO_SUCH_FIELD` if there is no such key in the object, it may throw an exception (see [Error Handling](#error-handling)). For efficiency reason, you should avoid looking up the same field repeatedly: e.g., do
not do `object["foo"]` followed by `object["foo"]` with the same `object` instance. Keep in mind that On Demand does not buffer or save the result of the parsing: if you repeatedly access `object["foo"]`, then it must repeatedly seek the key and parse the content. The library does not provide a distinct function to check if a key is present, instead we recommend you attempt to access the key: e.g., by doing `ondemand::value val{}; if(!object["foo"].get(val)) {...}`, you have that `val` contains the requested value inside the if clause. It is your responsibility as a user to temporarily keep a reference to the value (`auto v = object["foo"]`), or to consume the content and store it in your own data structures. If you consume an
not do `object["foo"]` followed by `object["foo"]` with the same `object` instance. Keep in mind that On Demand does not buffer or save the result of the parsing: if you repeatedly access `object["foo"]`, then it must repeatedly seek the key and parse the content. The library does not provide a distinct function to check if a key is present, instead we recommend you attempt to access the key: e.g., by doing `ondemand::value val{}; if (!object["foo"].get(val)) {...}`, you have that `val` contains the requested value inside the if clause. It is your responsibility as a user to temporarily keep a reference to the value (`auto v = object["foo"]`), or to consume the content and store it in your own data structures. If you consume an
object twice: `std::string_view(object["foo"]` followed by `std::string_view(object["foo"]` then your code
is in error. Furthermore, you can only consume one field at a time, on the same object. The
value instance you get from `content["bids"]` becomes invalid when you call `content["asks"]`.
@@ -370,7 +370,11 @@ support for users who avoid exceptions. See [the simdjson error handling documen
> as a key, it will not be recognized. This is not generally a problem. Nevertheless, if you do need
> to support escaped keys, the method `unescaped_key()` provides the desired unescaped keys by
> parsing and writing out the unescaped keys to a string buffer and returning a `std::string_view`
> instance. You should expect a performance penalty when using `unescaped_key()`.
> instance. The `unescaped_key` takes an optional Boolean value: passing it true will decode invalid
> Unicode sequences with replacement, meaning that the decoding always succeeds but bogus Unicode
> replacement characters are inserted. In general, you should expect a performance penalty
> when using `unescaped_key()` compared to `key()` because of the string processing: the `key()`
> function just points inside the source JSON document.
>
> ```c++
> auto json = R"({"k\u0065y": 1})"_padded;
@@ -381,7 +385,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
> // parses and writes out the key, after unescaping it,
> // to a string buffer. It causes a performance penalty.
> std::string_view keyv = field.unescaped_key();
> if(keyv == "key") { std::cout << uint64_t(field.value()); }
> if (keyv == "key") { std::cout << uint64_t(field.value()); }
> }
> ```
>
@@ -414,8 +418,10 @@ support for users who avoid exceptions. See [the simdjson error handling documen
step through each value in the JSON array.
If you know the type of the value, you can cast it right there, too! `for (double value : array) { ... }`.
* **Object Iteration:** You can iterate through an object's fields, as well: `for (auto field : object) { ... }`
- `field.unescaped_key()` will get you the unescaped key string.
You may also use explicit iterators: `for(auto i = array.begin(); i != array.end(); i++) {}`. You can check that an array is empty with the condition `auto i = array.begin(); if(i == array.end()) {...}`.
* **Object Iteration:** You can iterate through an object's fields, as well: `for (auto field : object) { ... }`. You may also use explicit iterators : `for(auto i = object.begin(); i != object.end(); i++) { auto field = *i; .... }`. You can check that an object is empty with the condition `auto i = object.begin(); if(i == object.end()) {...}`.
- `field.unescaped_key()` will get you the unescaped key string. E.g., the JSON string `"\u00e1"` becomes the Unicode string `á`. Optionally, you pass `true` as a parameter to the `unescaped_key` method if you want invalid escape sequences to be replaced by a default replacement character (e.g., `\ud800\ud801\ud811`): otherwise bad escape sequences lead to an immediate error.
- `field.value()` will get you the value, which you can then use all these other methods on.
* **Array Index:** Because it is forward-only, you cannot look up an array element by index by index. Instead,
you should iterate through the array and keep an index yourself.
@@ -445,7 +451,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
> {
> ondemand::parser parser;
> for (ondemand::object car : parser.iterate(cars_json)) {
> if(uint64_t(car["year"]) > 2000) {
> if (uint64_t(car["year"]) > 2000) {
> arrays.push_back(simdjson::to_json_string(car["tire_pressure"]));
> }
> }
@@ -454,7 +460,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
> std::ostringstream oss;
> oss << "[";
> for(size_t i = 0; i < arrays.size(); i++) {
> if(i>0) { oss << ","; }
> if (i>0) { oss << ","; }
> oss << arrays[i];
> }
> oss << "]";
@@ -597,7 +603,7 @@ support for users who avoid exceptions. See [the simdjson error handling documen
case ondemand::json_type::null:
// We check that the value is indeed null
// otherwise: an error is thrown.
if(element.is_null()) {
if (element.is_null()) {
cout << "null";
}
break;
@@ -910,11 +916,11 @@ bool simple_error_example() {
ondemand::parser parser;
auto json = R"({"bad number":3.14.1 })"_padded;
ondemand::document doc;
if( parser.iterate(json).get(doc) != SUCCESS ) { return false; }
if (parser.iterate(json).get(doc) != SUCCESS) { return false; }
double x;
auto error = doc["bad number"].get_double().get(x);
// returns "simdjson::NUMBER_ERROR"
if(error != SUCCESS) {
if (error != SUCCESS) {
std::cout << error << std::endl;
return false;
}
@@ -976,10 +982,10 @@ it selects the key `"count"` within that object.
int main(void) {
simdjson::ondemand::parser parser;
auto error = padded_string::load("twitter.json").get(json);
if(error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
simdjson::ondemand::document tweets;
error = parser.iterate(json).get(tweets);
if( error ) { std::cerr << error << std::endl; return EXIT_FAILURE; }
if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
simdjson::ondemand::value res;
error = tweets["search_metadata"]["count"].get(res);
if (error != SUCCESS) {
@@ -1010,12 +1016,12 @@ int main(void) {
simdjson::ondemand::document tweets;
padded_string json;
auto error = padded_string::load("twitter.json").get(json);
if(error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
error = parser.iterate(json).get(tweets);
if(error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
uint64_t identifier;
error = tweets["statuses"].at(0)["id"].get(identifier);
if(error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
std::cout << identifier << std::endl;
}
```
@@ -1039,40 +1045,40 @@ bool parse() {
// Iterating through an array of objects
auto error = parser.iterate(cars_json).get(doc);
if(error) { std::cerr << error << std::endl; return false; }
if (error) { std::cerr << error << std::endl; return false; }
ondemand::array cars; // invalid until the get() succeeds
error = doc.get_array().get(cars);
for (auto car_value : cars) {
ondemand::object car; // invalid until the get() succeeds
error = car_value.get_object().get(car);
if(error) { std::cerr << error << std::endl; return false; }
if (error) { std::cerr << error << std::endl; return false; }
// Accessing a field by name
std::string_view make;
std::string_view model;
error = car["make"].get(make);
if(error) { std::cerr << error << std::endl; return false; }
if (error) { std::cerr << error << std::endl; return false; }
error = car["model"].get(model);
if(error) { std::cerr << error << std::endl; return false; }
if (error) { std::cerr << error << std::endl; return false; }
cout << "Make/Model: " << make << "/" << model << endl;
// Casting a JSON element to an integer
uint64_t year{};
error = car["year"].get(year);
if(error) { std::cerr << error << std::endl; return false; }
if (error) { std::cerr << error << std::endl; return false; }
cout << "- This car is " << 2020 - year << " years old." << endl;
// Iterating through an array of floats
double total_tire_pressure = 0;
ondemand::array pressures;
error = car["tire_pressure"].get_array().get(pressures);
if(error) { std::cerr << error << std::endl; return false; }
if (error) { std::cerr << error << std::endl; return false; }
for (auto tire_pressure_value : pressures) {
double tire_pressure;
error = tire_pressure_value.get_double().get(tire_pressure);
if(error) { std::cerr << error << std::endl; return false; }
if (error) { std::cerr << error << std::endl; return false; }
total_tire_pressure += tire_pressure;
}
cout << "- Average tire pressure: " << (total_tire_pressure / 4) << endl;
@@ -1088,7 +1094,7 @@ after you have initialized them and checked that there is no error:
ondemand::object car; // invalid until the get() succeeds
// the `car` instance should not use used before it is initialized
error = car_value.get_object().get(car);
if(error) {
if (error) {
// the `car` instance should not use used
} else {
// the `car` instance can be safely used
@@ -1102,20 +1108,20 @@ having to handle exceptions.
ondemand::parser parser;
ondemand::document doc;
auto error = parser.iterate(json).get(doc);
if(error) { return false; }
if (error) { return false; }
ondemand::object object; // invalid until the get() succeeds
error = doc.get_object().get(object);
if(error) { return false; }
if (error) { return false; }
for(auto field : object) {
// We could replace 'field.key() with field.unescaped_key(),
// and ondemand::raw_json_string by std::string_view.
ondemand::raw_json_string keyv;
error = field.key().get(keyv);
if(error) { return false; }
if(keyv == "key") {
if (error) { return false; }
if (keyv == "key") {
uint64_t intvalue;
error = field.value().get(intvalue);
if(error) { return false; }
if (error) { return false; }
std::cout << intvalue;
}
}
@@ -1294,7 +1300,7 @@ content.
for (uint64_t values : array) {
std::cout << values << std::endl;
}
if(!doc.at_end()) {
if (!doc.at_end()) {
// In this instance, we will be left pointing at 'foo' since we have consumed the array [1,2].
std::cerr << "trailing content at byte index " << doc.current_location() - json.data() << std::endl;
}
@@ -1324,7 +1330,7 @@ before printout the data.
auto doc = parser.iterate(cars_json);
for (simdjson_unused ondemand::object car : doc) {
if(car["make"] == "Toyota") { count++; }
if (car["make"] == "Toyota") { count++; }
}
std::cout << "We have " << count << " Toyota cars.\n";
doc.rewind(); // requires simdjson 1.0 or better
@@ -1392,18 +1398,18 @@ ondemand::parser parser;
ondemand::document_stream stream;
size_t counter{0};
auto error = parser.iterate_many(json, 50).get(stream);
if( error ) { /* handle the error */ }
if (error) { /* handle the error */ }
for (auto doc: stream) {
if(counter < 6) {
if (counter < 6) {
int64_t val;
error = doc.at_pointer("/4").get(val);
if( error ) { /* handle the error */ }
if (error) { /* handle the error */ }
std::cout << "5 = " << val << std::endl;
} else {
ondemand::value val;
error = doc.at_pointer("/4").get(val);
// error == simdjson::CAPACITY
if(error) {
if (error) {
std::cerr << error << std::endl;
// We left 293 bytes unprocessed at the tail end of the input.
std::cout << " unprocessed bytes at the end: " << stream.truncated_bytes() << std::endl;
@@ -1647,7 +1653,7 @@ JSON string to a user-provided buffer:
General Direct Access to the Raw JSON String
--------------------------------
If your value is a string, the `raw_json_string` gives you direct access to the unprocess
If your value is a string, the `raw_json_string` you with `get_raw_json_string()` gives you direct access to the unprocessed
string. The simdjson library allows you to have access to the raw underlying JSON
more generally.
@@ -1716,6 +1722,41 @@ obj.reset(); // revise the object
uint64_t x = obj["value"]; // gives me 123
```
Storing Directly into an Existing std::string Instance
-----------------------------------------------------
The simdjson library favours the use of `std::string_view` instances because
it tends to lead to better performance due to causing fewer memory allocations.
However, they are cases where you need to store a string result in an `std::string``
instance. You can do so with a version of the `to_string()` method which takes as
a parameter a reference to an `std::string`.
```C++
auto json = R"({
"name": "Daniel",
"age": 42
})"_padded;
ondemand::parser parser;
ondemand::document doc = parser.iterate(json);
std::string name;
doc["name"].get_string(name);
```
The same routine can be written without exceptions handling:
```C++
std::string name;
auto err = doc["name"].get_string(name);
if(err) { /* handle error */ }
```
The `std::string` instance, once created, is independent. Unlike our `std::string_view` instances, it does not point at data that is
within our `parser` instance. The same caveat applies: you should
only consume a JSON string once.
You should be mindful of the trade-off: allocating multiple
`std::string` instances can become expensive.
Thread Safety
-------------
@@ -1944,6 +1985,79 @@ bool example() {
}
```
* Example 3: CRT
```C++
bool example() {
padded_string padded_input_json = R"([
{ "monitor": [
{ "id": "monitor", "type": "toggle", "label": "monitor" },
{ "id": "profile", "type": "selector", "label": "collection" },
{ "id": "overlay", "type": "selector", "label": "overlay" },
{ "id": "zoom", "type": "toggleSlider", "label": "zoom" }
] },
{ "crt": [
{ "id": "system", "type": "multi", "label": "system", "choices": "PAL, NTSC" },
{ "type": "spacer" },
{ "id": "brightness", "type": "slider", "icon": "brightness" },
{ "id": "contrast", "type": "slider", "icon": "contrast" },
{ "id": "saturation", "type": "slider", "icon": "saturation" },
{ "type": "spacer" },
{ "id": "overscan", "type": "toggleSlider", "label": "overscan" },
{ "type": "spacer" },
{ "id": "emulation", "type": "toggle", "label": "CRT emulation" },
{ "type": "spacer" },
{ "id": "curve", "type": "toggleSlider", "label": "curve" },
{ "id": "bleed", "type": "toggleSlider", "label": "bleed" },
{ "id": "vignette", "type": "toggleSlider", "label": "vignette" },
{ "id": "scanlines", "type": "toggleSlider", "label": "scanlines" },
{ "id": "gridlines", "type": "toggleSlider", "label": "gridlines" },
{ "id": "glow", "type": "toggleSlider", "label": "glow" },
{ "id": "flicker", "type": "toggleSlider", "label": "flicker" },
{ "id": "noise", "type": "toggleSlider", "label": "noise" },
{}
] }
])"_padded;
auto parser = ondemand::parser{};
auto doc = parser.iterate(padded_input_json);
auto root_array = doc.get_array();
// the root should be an object, not an array, but that's the JSON we are
// given.
for (ondemand::object node : root_array) {
// We know that we are going to have just one element in the object.
for (auto field : node) {
std::cout << "\n\ntop level:" << field.key() << std::endl;
// You can get a proper std::string_view for the key with:
// std::string_view key = field.unescaped_key();
// and second for-range loop to get child-elements here
for (ondemand::object inner_object : field.value()) {
auto i = inner_object.begin();
if (i == inner_object.end()) {
std::cout << "empty object" << std::endl;
continue;
} else {
for (; i != inner_object.end(); ++i) {
auto inner_field = *i;
std::cout << '"' << inner_field.key()
<< "\" : " << inner_field.value() << ", ";
// You can get proper std::string_view for the key and value with:
// std::string_view inner_key = field.unescaped_key();
// std::string_view value_str = field.value();
}
}
std::cout << std::endl;
}
// You can break here if you only want just the first element.
// break;
}
}
return true;
}
```
Performance Tips
--------
@@ -1969,4 +2083,4 @@ Performance Tips
std::string_view year = data["year"];
std::string_view rating = data["rating"];
```
- To better understand the operation of your On Demand parser, and whether it is performing as well as you think it should be, there is a logger feature built in to simdjson! To use it, define the pre-processor directive `SIMDJSON_VERBOSE_LOGGING` prior to including the `simdjson.h` header, which enables logging in simdjson. Run your code. It may generate a lot of logging output; adding printouts from your application that show each section may be helpful. The log's output will show step-by-step information on state, buffer pointer position, depth, and key retrieval status. Importantly, unless `SIMDJSON_VERBOSE_LOGGING` is defined, logging is entirely disabled and thus carries no overhead.
- To better understand the operation of your On Demand parser, and whether it is performing as well as you think it should be, there is a logger feature built in to simdjson! To use it, define the pre-processor directive `SIMDJSON_VERBOSE_LOGGING` prior to including the `simdjson.h` header, which enables logging in simdjson. Run your code. It may generate a lot of logging output; adding printouts from your application that show each section may be helpful. The log's output will show step-by-step information on state, buffer pointer position, depth, and key retrieval status. Importantly, unless `SIMDJSON_VERBOSE_LOGGING` is defined, logging is entirely disabled and thus carries no overhead.
+2 -2
View File
@@ -329,10 +329,10 @@ int main(void) {
simdjson::dom::parser parser;
simdjson::dom::element tweets; // invalid until the get() succeeds
auto error = parser.load("twitter.json").get(tweets);
if(error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
uint64_t identifier;
error = tweets["statuses"].at(0)["id"].get(identifier);
if(error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
if (error) { std::cerr << error << std::endl; return EXIT_FAILURE; }
std::cout << identifier << std::endl;
return EXIT_SUCCESS;
}
+3 -3
View File
@@ -101,8 +101,8 @@ by comparing it with the null pointer.
```c++
auto my_implementation = simdjson::get_available_implementations()["haswell"];
if(! my_implementation) { exit(1); }
if(! my_implementation->supported_by_runtime_system()) { exit(1); }
if (! my_implementation) { exit(1); }
if (! my_implementation->supported_by_runtime_system()) { exit(1); }
simdjson::get_active_implementation() = my_implementation;
```
@@ -113,7 +113,7 @@ You should call `supported_by_runtime_system()` to compare the processor's featu
```c++
for (auto implementation : simdjson::get_available_implementations()) {
if(implementation->supported_by_runtime_system()) {
if (implementation->supported_by_runtime_system()) {
cout << implementation->name() << ": " << implementation->description() << endl;
}
}
+7 -4
View File
@@ -17,6 +17,9 @@ Contents
- [Motivations](#motivations)
- [How it works](#how-it-works)
- [Context](#context)
- [Design](#design)
- [Threads](#threads)
- [Support](#support)
- [API](#api)
- [Use cases](#use-cases)
@@ -193,12 +196,12 @@ Let us illustrate the idea with code:
simdjson::ondemand::parser parser;
simdjson::ondemand::document_stream stream;
auto error = parser.iterate_many(json).get(stream);
if( error ) { /* do something */ }
if (error) { /* do something */ }
auto i = stream.begin();
size_t count{0};
for(; i != stream.end(); ++i) {
auto doc = *i;
if(!i.error()) {
if (!i.error()) {
std::cout << "got full document at " << i.current_index() << std::endl;
std::cout << i.source() << std::endl;
count++;
@@ -234,7 +237,7 @@ Consider the following example where a truncated document (`{"key":"intentionall
simdjson::ondemand::parser parser;
simdjson::ondemand::document_stream stream;
auto error = parser.iterate_many(json,json.size()).get(stream);
if(error) { std::cerr << error << std::endl; return; }
if (error) { std::cerr << error << std::endl; return; }
for(auto i = stream.begin(); i != stream.end(); ++i) {
std::cout << i.source() << std::endl;
}
@@ -266,7 +269,7 @@ Example:
// we pass 'true' to the allow_comma parameter, the batch size will be set to at least
// the document size.
auto error = parser.iterate_many(json, 32, true).get(doc_stream);
if(error) { std::cerr << error << std::endl; return; }
if (error) { std::cerr << error << std::endl; return; }
for (auto doc : doc_stream) {
std::cout << doc.type() << std::endl;
}
+4 -4
View File
@@ -679,11 +679,11 @@ in production systems:
ondemand::object c1 = parent["child1"];
// c1 owns the focus
//
if(std::string_view(c1["name"]) != "John") { ... }
if (std::string_view(c1["name"]) != "John") { ... }
// c2 attempts to grab the focus from parent but fails
ondemand::object c2 = parent["child2"];
// c2 is now in an unsafe state and the following line would be unsafe
// if(std::string_view(c2["name"]) != "Daniel") { return false; }
// if (std::string_view(c2["name"]) != "Daniel") { return false; }
```
A correct usage is given by the following example:
@@ -697,7 +697,7 @@ in production systems:
{
ondemand::object c1 = parent["child1"];
// c1 grabbed the focus from parent
if(std::string_view(c1["name"]) != "John") { return false; }
if (std::string_view(c1["name"]) != "John") { return false; }
}
// c1 went out of scope, so its destructor was called and the focus
// was handed back to parent.
@@ -705,7 +705,7 @@ in production systems:
ondemand::object c2 = parent["child2"];
// c2 grabbed the focus from parent
// the following is safe:
if(std::string_view(c2["name"]) != "Daniel") { return false; }
if (std::string_view(c2["name"]) != "Daniel") { return false; }
}
```
+3 -3
View File
@@ -184,12 +184,12 @@ Let us illustrate the idea with code:
simdjson::dom::parser parser;
simdjson::dom::document_stream stream;
auto error = parser.parse_many(json).get(stream);
if( error ) { /* do something */ }
if (error) { /* do something */ }
auto i = stream.begin();
size_t count{0};
for(; i != stream.end(); ++i) {
auto doc = *i;
if(!doc.error()) {
if (!doc.error()) {
std::cout << "got full document at " << i.current_index() << std::endl;
std::cout << i.source() << std::endl;
count++;
@@ -225,7 +225,7 @@ Consider the following example where a truncated document (`{"key":"intentionall
simdjson::dom::parser parser;
simdjson::dom::document_stream stream;
auto error = parser.parse_many(json,json.size()).get(stream);
if(error) { std::cerr << error << std::endl; return; }
if (error) { std::cerr << error << std::endl; return; }
for(auto doc : stream) {
std::cout << doc << std::endl;
}
+2 -9
View File
@@ -1,9 +1,9 @@
#ifndef SIMDJSON_ARM64_BASE_H
#define SIMDJSON_ARM64_BASE_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/base.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
/**
@@ -23,11 +23,4 @@ template <typename T> struct simd8x64;
} // namespace arm64
} // namespace simdjson
#ifndef SIMDJSON_AMALGAMATED
// If we're editing one of the files in this directory, begin the implementation!
#ifndef SIMDJSON_IMPLEMENTATION
#include "simdjson/arm64/begin.h"
#endif
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_ARM64_BASE_H
+2
View File
@@ -6,3 +6,5 @@
#include "simdjson/arm64/numberparsing_defs.h"
#include "simdjson/arm64/simd.h"
#include "simdjson/arm64/stringparsing_defs.h"
#define SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT 1
+4 -2
View File
@@ -1,11 +1,13 @@
#ifndef SIMDJSON_ARM64_BITMANIPULATION_H
#define SIMDJSON_ARM64_BITMANIPULATION_H
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/arm64/base.h"
#include "simdjson/arm64/intrinsics.h"
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
namespace arm64 {
namespace {
// We sometimes call trailing_zero on inputs that are zero,
@@ -98,7 +100,7 @@ simdjson_inline bool add_overflow(uint64_t value1, uint64_t value2, uint64_t *re
}
} // unnamed namespace
} // namespace SIMDJSON_IMPLEMENTATION
} // namespace arm64
} // namespace simdjson
#endif // SIMDJSON_ARM64_BITMANIPULATION_H
+3 -1
View File
@@ -1,10 +1,12 @@
#ifndef SIMDJSON_ARM64_BITMASK_H
#define SIMDJSON_ARM64_BITMASK_H
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/arm64/base.h"
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
namespace arm64 {
namespace {
//
+5
View File
@@ -1 +1,6 @@
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/arm64/base.h"
#endif // SIMDJSON_CONDITIONAL_INCLUDE
#undef SIMDJSON_SKIP_BACKSLASH_SHORT_CIRCUIT
#undef SIMDJSON_IMPLEMENTATION
+3 -2
View File
@@ -1,10 +1,11 @@
#ifndef SIMDJSON_ARM64_IMPLEMENTATION_H
#define SIMDJSON_ARM64_IMPLEMENTATION_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/base.h"
#include "simdjson/implementation.h"
#include "simdjson/internal/instruction_set.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace arm64 {
+4 -2
View File
@@ -1,12 +1,14 @@
#ifndef SIMDJSON_ARM64_INTRINSICS_H
#define SIMDJSON_ARM64_INTRINSICS_H
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/arm64/base.h"
#endif // SIMDJSON_CONDITIONAL_INCLUDE
// This should be the correct header whether
// you use visual studio or other compilers.
#include <arm_neon.h>
#include "simdjson/arm64/base.h"
static_assert(sizeof(uint8x16_t) <= simdjson::SIMDJSON_PADDING, "insufficient padding for arm64");
#endif // SIMDJSON_ARM64_INTRINSICS_H
+7 -8
View File
@@ -1,22 +1,21 @@
#ifndef SIMDJSON_ARM64_NUMBERPARSING_DEFS_H
#define SIMDJSON_ARM64_NUMBERPARSING_DEFS_H
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/arm64/base.h"
#include "simdjson/arm64/intrinsics.h"
#include "simdjson/internal/numberparsing_tables.h"
#endif // SIMDJSON_CONDITIONAL_INCLUDE
#include <cstring>
#if _M_ARM64
// __umulh requires intrin.h
#include <intrin.h>
#endif // _M_ARM64
#include <cstring>
#ifndef SIMDJSON_AMALGAMATED
#include "simdjson/internal/numberparsing_tables.h"
#endif // SIMDJSON_AMALGAMATED
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
namespace arm64 {
namespace numberparsing {
// we don't have SSE, so let us use a scalar function
@@ -49,7 +48,7 @@ simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t
}
} // namespace numberparsing
} // namespace SIMDJSON_IMPLEMENTATION
} // namespace arm64
} // namespace simdjson
#define SIMDJSON_SWAR_NUMBER_PARSING 1
+4 -5
View File
@@ -1,15 +1,14 @@
#ifndef SIMDJSON_ARM64_SIMD_H
#define SIMDJSON_ARM64_SIMD_H
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/arm64/base.h"
#include "simdjson/arm64/bitmanipulation.h"
#ifndef SIMDJSON_AMALGAMATED
#include "simdjson/internal/simdprune_tables.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
namespace arm64 {
namespace {
namespace simd {
@@ -528,7 +527,7 @@ simdjson_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x3, int
} // namespace simd
} // unnamed namespace
} // namespace SIMDJSON_IMPLEMENTATION
} // namespace arm64
} // namespace simdjson
#endif // SIMDJSON_ARM64_SIMD_H
+4 -2
View File
@@ -1,12 +1,14 @@
#ifndef SIMDJSON_ARM64_STRINGPARSING_DEFS_H
#define SIMDJSON_ARM64_STRINGPARSING_DEFS_H
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/arm64/base.h"
#include "simdjson/arm64/simd.h"
#include "simdjson/arm64/bitmanipulation.h"
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
namespace arm64 {
namespace {
using namespace simd;
@@ -45,7 +47,7 @@ simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uin
}
} // unnamed namespace
} // namespace SIMDJSON_IMPLEMENTATION
} // namespace arm64
} // namespace simdjson
#endif // SIMDJSON_ARM64_STRINGPARSING_DEFS_H
+2 -2
View File
@@ -6,7 +6,7 @@
#include "simdjson/generic/dependencies.h"
#define SIMDJSON_AMALGAMATED
#define SIMDJSON_CONDITIONAL_INCLUDE
#if SIMDJSON_BUILTIN_IMPLEMENTATION_IS(arm64)
#include "simdjson/arm64.h"
@@ -24,6 +24,6 @@
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
#endif
#undef SIMDJSON_AMALGAMATED
#undef SIMDJSON_CONDITIONAL_INCLUDE
#endif // SIMDJSON_BUILTIN_H
+2 -2
View File
@@ -5,7 +5,7 @@
#include "simdjson/generic/dependencies.h"
#define SIMDJSON_AMALGAMATED
#define SIMDJSON_CONDITIONAL_INCLUDE
#if SIMDJSON_BUILTIN_IMPLEMENTATION_IS(arm64)
#include "simdjson/arm64/implementation.h"
@@ -23,7 +23,7 @@
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
#endif
#undef SIMDJSON_AMALGAMATED
#undef SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
/**
+2 -2
View File
@@ -6,7 +6,7 @@
#include "simdjson/generic/ondemand/dependencies.h"
#define SIMDJSON_AMALGAMATED
#define SIMDJSON_CONDITIONAL_INCLUDE
#if SIMDJSON_BUILTIN_IMPLEMENTATION_IS(arm64)
#include "simdjson/arm64/ondemand.h"
@@ -24,7 +24,7 @@
#error Unknown SIMDJSON_BUILTIN_IMPLEMENTATION
#endif
#undef SIMDJSON_AMALGAMATED
#undef SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
/**
+8
View File
@@ -32,4 +32,12 @@
#error simdjson requires a compiler compliant with the C++11 standard
#endif
#ifndef SIMDJSON_IF_CONSTEXPR
#if SIMDJSON_CPLUSPLUS17
#define SIMDJSON_IF_CONSTEXPR if constexpr
#else
#define SIMDJSON_IF_CONSTEXPR if
#endif
#endif
#endif // SIMDJSON_COMPILER_CHECK_H
+3 -1
View File
@@ -5,10 +5,12 @@
#include "simdjson/dom/base.h"
#include "simdjson/dom/document.h"
#include "simdjson/dom/element.h"
#include "simdjson/dom/element-inl.h"
#include "simdjson/internal/tape_ref-inl.h"
#include "simdjson/internal/jsonformatutils.h"
#include <cstring>
namespace simdjson {
namespace dom {
+10
View File
@@ -7,8 +7,12 @@
#include "simdjson/dom/object.h"
#include "simdjson/internal/tape_type.h"
#include "simdjson/dom/object-inl.h"
#include "simdjson/error-inl.h"
#include <ostream>
#include <limits>
namespace simdjson {
//
@@ -406,6 +410,12 @@ inline simdjson_result<element> element::at_key(std::string_view key) const noex
inline simdjson_result<element> element::at_key_case_insensitive(std::string_view key) const noexcept {
return get<object>().at_key_case_insensitive(key);
}
inline bool element::operator<(const element &other) const noexcept {
return tape.json_index < other.tape.json_index;
}
inline bool element::operator==(const element &other) const noexcept {
return tape.json_index == other.tape.json_index;
}
inline bool element::dump_raw_tape(std::ostream &out) const noexcept {
SIMDJSON_DEVELOPMENT_ASSERT(tape.usable()); // https://github.com/simdjson/simdjson/issues/1914
+21 -1
View File
@@ -211,7 +211,11 @@ public:
inline simdjson_result<T> get() const noexcept {
// Unless the simdjson library provides an inline implementation, calling this method should
// immediately fail.
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library.");
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. "
"The supported types are Boolean (bool), numbers (double, uint64_t, int64_t), "
"strings (std::string_view, const char *), arrays (dom::array) and objects (dom::object). "
"We recommand you use get_double(), get_bool(), get_uint64(), get_int64(), "
"get_object(), get_array() or get_string() instead of the get template.");
}
/**
@@ -451,6 +455,22 @@ public:
*/
inline simdjson_result<element> at_key_case_insensitive(std::string_view key) const noexcept;
/**
* operator< defines a total order for element allowing to use them in
* ordered C++ STL containers
*
* @return TRUE if the key appears before the other one in the tape
*/
inline bool operator<(const element &other) const noexcept;
/**
* operator== allows to verify if two element values reference the
* same JSON item
*
* @return TRUE if the two values references the same JSON element
*/
inline bool operator==(const element &other) const noexcept;
/** @private for debugging. Prints out the root element. */
inline bool dump_raw_tape(std::ostream &out) const noexcept;
+2
View File
@@ -7,6 +7,8 @@
#include "simdjson/dom/parser.h"
#include "simdjson/dom/element.h"
#include "simdjson/dom/parser-inl.h"
namespace simdjson {
//
+5
View File
@@ -5,6 +5,11 @@
#include "simdjson/dom/object.h"
#include "simdjson/dom/document.h"
#include "simdjson/dom/element-inl.h"
#include "simdjson/error-inl.h"
#include <cstring>
namespace simdjson {
//
@@ -3,10 +3,15 @@
#include "simdjson/dom/base.h"
#include "simdjson/dom/parsedjson_iterator.h"
#include "simdjson/internal/tape_ref-inl.h"
#include "simdjson/internal/jsonformatutils.h"
#include <ostream>
#include "simdjson/dom/parser-inl.h"
#include "simdjson/internal/tape_ref-inl.h"
#include <cstring>
#include <iterator>
#include <limits>
#include <ostream>
#ifndef SIMDJSON_DISABLE_DEPRECATED_API
+1
View File
@@ -8,6 +8,7 @@
#include "simdjson/error-inl.h"
#include "simdjson/padded_string-inl.h"
#include "simdjson/dom/document_stream-inl.h"
#include "simdjson/dom/element-inl.h"
#include <climits>
+42 -2
View File
@@ -7,6 +7,12 @@
#include "simdjson/dom/parser.h"
#include "simdjson/internal/tape_type.h"
#include "simdjson/dom/array-inl.h"
#include "simdjson/dom/object-inl.h"
#include "simdjson/internal/tape_ref-inl.h"
#include <cstring>
namespace simdjson {
namespace dom {
inline bool parser::print_json(std::ostream &os) const noexcept {
@@ -17,12 +23,46 @@ inline bool parser::print_json(std::ostream &os) const noexcept {
os << answer;
return true;
}
inline std::ostream& operator<<(std::ostream& out, simdjson::dom::element value) {
simdjson::internal::string_builder<> sb;
sb.append(value);
return (out << sb.str());
}
#if SIMDJSON_EXCEPTIONS
inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::dom::element> x) {
if (x.error()) { throw simdjson::simdjson_error(x.error()); }
return (out << x.value());
}
#endif
inline std::ostream& operator<<(std::ostream& out, simdjson::dom::array value) {
simdjson::internal::string_builder<> sb;
sb.append(value);
return (out << sb.str());
}
#if SIMDJSON_EXCEPTIONS
inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::dom::array> x) {
if (x.error()) { throw simdjson::simdjson_error(x.error()); }
return (out << x.value());
}
#endif
inline std::ostream& operator<<(std::ostream& out, simdjson::dom::object value) {
simdjson::internal::string_builder<> sb;
sb.append(value);
return (out << sb.str());
}
#if SIMDJSON_EXCEPTIONS
inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::dom::object> x) {
if (x.error()) { throw simdjson::simdjson_error(x.error()); }
return (out << x.value());
}
#endif
} // namespace dom
/***
* Number utility functions
**/
namespace {
/**@private
* Escape sequence like \b or \u0001
+6 -27
View File
@@ -146,16 +146,9 @@ namespace dom {
* @param value The element.
* @throw if there is an error with the underlying output stream. simdjson itself will not throw.
*/
inline std::ostream& operator<<(std::ostream& out, simdjson::dom::element value) {
simdjson::internal::string_builder<> sb;
sb.append(value);
return (out << sb.str());
}
inline std::ostream& operator<<(std::ostream& out, simdjson::dom::element value);
#if SIMDJSON_EXCEPTIONS
inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::dom::element> x) {
if (x.error()) { throw simdjson::simdjson_error(x.error()); }
return (out << x.value());
}
inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::dom::element> x);
#endif
/**
* Print JSON to an output stream.
@@ -164,16 +157,9 @@ inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<sim
* @param value The array.
* @throw if there is an error with the underlying output stream. simdjson itself will not throw.
*/
inline std::ostream& operator<<(std::ostream& out, simdjson::dom::array value) {
simdjson::internal::string_builder<> sb;
sb.append(value);
return (out << sb.str());
}
inline std::ostream& operator<<(std::ostream& out, simdjson::dom::array value);
#if SIMDJSON_EXCEPTIONS
inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::dom::array> x) {
if (x.error()) { throw simdjson::simdjson_error(x.error()); }
return (out << x.value());
}
inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::dom::array> x);
#endif
/**
* Print JSON to an output stream.
@@ -182,16 +168,9 @@ inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<sim
* @param value The object.
* @throw if there is an error with the underlying output stream. simdjson itself will not throw.
*/
inline std::ostream& operator<<(std::ostream& out, simdjson::dom::object value) {
simdjson::internal::string_builder<> sb;
sb.append(value);
return (out << sb.str());
}
inline std::ostream& operator<<(std::ostream& out, simdjson::dom::object value);
#if SIMDJSON_EXCEPTIONS
inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::dom::object> x) {
if (x.error()) { throw simdjson::simdjson_error(x.error()); }
return (out << x.value());
}
inline std::ostream& operator<<(std::ostream& out, simdjson::simdjson_result<simdjson::dom::object> x);
#endif
} // namespace dom
+2 -2
View File
@@ -1,10 +1,10 @@
#ifndef SIMDJSON_ERROR_INL_H
#define SIMDJSON_ERROR_INL_H
#include <iostream>
#include "simdjson/error.h"
#include <iostream>
namespace simdjson {
namespace internal {
// We store the error code so we can validate the error message is associated with the right code
+2
View File
@@ -2,7 +2,9 @@
#define SIMDJSON_ERROR_H
#include "simdjson/base.h"
#include <string>
#include <ostream>
namespace simdjson {
+2 -9
View File
@@ -1,9 +1,9 @@
#ifndef SIMDJSON_FALLBACK_BASE_H
#define SIMDJSON_FALLBACK_BASE_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/base.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
/**
@@ -16,11 +16,4 @@ class implementation;
} // namespace fallback
} // namespace simdjson
#ifndef SIMDJSON_AMALGAMATED
// If we're editing one of the files in this directory, begin the implementation!
#ifndef SIMDJSON_IMPLEMENTATION
#include "simdjson/fallback/begin.h"
#endif
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_FALLBACK_BASE_H
+4 -2
View File
@@ -1,10 +1,12 @@
#ifndef SIMDJSON_FALLBACK_BITMANIPULATION_H
#define SIMDJSON_FALLBACK_BITMANIPULATION_H
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/fallback/base.h"
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
namespace fallback {
namespace {
#if defined(_MSC_VER) && !defined(_M_ARM64) && !defined(_M_X64)
@@ -40,7 +42,7 @@ simdjson_inline int leading_zeroes(uint64_t input_num) {
}
} // unnamed namespace
} // namespace SIMDJSON_IMPLEMENTATION
} // namespace fallback
} // namespace simdjson
#endif // SIMDJSON_FALLBACK_BITMANIPULATION_H
+4
View File
@@ -1 +1,5 @@
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/fallback/base.h"
#endif // SIMDJSON_CONDITIONAL_INCLUDE
#undef SIMDJSON_IMPLEMENTATION
+3 -2
View File
@@ -1,9 +1,10 @@
#ifndef SIMDJSON_FALLBACK_IMPLEMENTATION_H
#define SIMDJSON_FALLBACK_IMPLEMENTATION_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/fallback/base.h"
#include "simdjson/implementation.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace fallback {
@@ -1,11 +1,12 @@
#ifndef SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H
#define SIMDJSON_FALLBACK_NUMBERPARSING_DEFS_H
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/fallback/base.h"
#ifndef SIMDJSON_AMALGAMATED
#include "simdjson/internal/numberparsing_tables.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
#include <cstring>
#ifdef JSON_TEST_NUMBERS // for unit testing
void found_invalid_number(const uint8_t *buf);
@@ -15,7 +16,7 @@ void found_float(double result, const uint8_t *buf);
#endif
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
namespace fallback {
namespace numberparsing {
// credit: https://johnnylee-sde.github.io/Fast-numeric-string-to-int/
@@ -71,7 +72,7 @@ simdjson_inline internal::value128 full_multiplication(uint64_t value1, uint64_t
}
} // namespace numberparsing
} // namespace SIMDJSON_IMPLEMENTATION
} // namespace fallback
} // namespace simdjson
#define SIMDJSON_SWAR_NUMBER_PARSING 1
@@ -1,10 +1,12 @@
#ifndef SIMDJSON_FALLBACK_STRINGPARSING_DEFS_H
#define SIMDJSON_FALLBACK_STRINGPARSING_DEFS_H
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/fallback/base.h"
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
namespace fallback {
namespace {
// Holds backslashes and quotes locations.
@@ -28,7 +30,7 @@ simdjson_inline backslash_and_quote backslash_and_quote::copy_and_find(const uin
}
} // unnamed namespace
} // namespace SIMDJSON_IMPLEMENTATION
} // namespace fallback
} // namespace simdjson
#endif // SIMDJSON_FALLBACK_STRINGPARSING_DEFS_H
+1 -1
View File
@@ -1,4 +1,4 @@
#if defined(SIMDJSON_AMALGAMATED) && !defined(SIMDJSON_GENERIC_DEPENDENCIES_H)
#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_DEPENDENCIES_H)
#error simdjson/generic/dependencies.h must be included before simdjson/generic/amalgamated.h!
#endif
+4 -2
View File
@@ -1,10 +1,12 @@
#ifndef SIMDJSON_GENERIC_ATOMPARSING_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ATOMPARSING_H
#include "simdjson/generic/base.h"
#include "simdjson/generic/jsoncharutils.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
#include <cstring>
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
+2 -2
View File
@@ -1,6 +1,6 @@
#ifndef SIMDJSON_GENERIC_BASE_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_BASE_H
#include "simdjson/base.h"
// If we haven't got an implementation yet, we're in the editor, editing a generic file! Just
@@ -23,7 +23,7 @@
#error "All possible implementations (including fallback) have been disabled! simdjson will not run."
#endif
#endif // SIMDJSON_IMPLEMENTATION
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
+3 -2
View File
@@ -1,5 +1,5 @@
#ifdef SIMDJSON_AMALGAMATED
#error simdjson/generic/dependencies.h must be included before defining SIMDJSON_AMALGAMATED!
#ifdef SIMDJSON_CONDITIONAL_INCLUDE
#error simdjson/generic/dependencies.h must be included before defining SIMDJSON_CONDITIONAL_INCLUDE!
#endif
#ifndef SIMDJSON_GENERIC_DEPENDENCIES_H
@@ -10,6 +10,7 @@
// Otherwise, amalgamation will fail.
#include "simdjson/base.h"
#include "simdjson/implementation.h"
#include "simdjson/implementation_detection.h"
#include "simdjson/internal/instruction_set.h"
#include "simdjson/internal/dom_parser_implementation.h"
#include "simdjson/internal/jsoncharutils_tables.h"
@@ -1,10 +1,10 @@
#ifndef SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_DOM_PARSER_IMPLEMENTATION_H
#include "simdjson/generic/base.h"
#include "simdjson/internal/dom_parser_implementation.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -1,10 +1,10 @@
#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_INL_H
#include "simdjson/generic/base.h"
#include "simdjson/generic/implementation_simdjson_result_base.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -1,9 +1,9 @@
#ifndef SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_IMPLEMENTATION_SIMDJSON_RESULT_BASE_H
#include "simdjson/generic/base.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
+2 -2
View File
@@ -1,11 +1,11 @@
#ifndef SIMDJSON_GENERIC_JSONCHARUTILS_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_JSONCHARUTILS_H
#include "simdjson/generic/base.h"
#include "simdjson/internal/jsoncharutils_tables.h"
#include "simdjson/internal/numberparsing_tables.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
+7 -10
View File
@@ -1,14 +1,15 @@
#ifndef SIMDJSON_GENERIC_NUMBERPARSING_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_NUMBERPARSING_H
#include "simdjson/generic/base.h"
#include "simdjson/generic/jsoncharutils.h"
#include "simdjson/internal/numberparsing_tables.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
#include <limits>
#include <ostream>
#include <cstring>
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -185,8 +186,7 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
// power_of_five_128[index]. Usually, that's good enough to approximate i * 5^q
// to the desired approximation using one multiplication. Sometimes it does not suffice.
// Then we store the next most significant 64 bits in power_of_five_128[index + 1], and
// then we get a better approximation to i * 5^q. In very rare cases, even that
// will not suffice, though it is seemingly very hard to find such a scenario.
// then we get a better approximation to i * 5^q.
//
// That's for when q>=0. The logic for q<0 is somewhat similar but it is somewhat
// more complicated.
@@ -201,12 +201,9 @@ simdjson_inline bool compute_float_64(int64_t power, uint64_t i, bool negative,
simdjson::internal::value128 secondproduct = full_multiplication(i, simdjson::internal::power_of_five_128[index + 1]);
firstproduct.low += secondproduct.high;
if(secondproduct.high > firstproduct.low) { firstproduct.high++; }
// At this point, we might need to add at most one to firstproduct, but this
// can only change the value of firstproduct.high if firstproduct.low is maximal.
if(simdjson_unlikely(firstproduct.low == 0xFFFFFFFFFFFFFFFF)) {
// This is very unlikely, but if so, we need to do much more work!
return false;
}
// As it has been proven by Noble Mushtak and Daniel Lemire in "Fast Number Parsing Without
// Fallback" (https://arxiv.org/abs/2212.06644), at this point we are sure that the product
// is sufficiently accurate, and more computation is not needed.
}
uint64_t lower = firstproduct.low;
uint64_t upper = firstproduct.high;
@@ -1,4 +1,4 @@
#if defined(SIMDJSON_AMALGAMATED) && !defined(SIMDJSON_GENERIC_ONDEMAND_DEPENDENCIES_H)
#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!
#endif
@@ -1,6 +1,6 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_ARRAY_INL_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/ondemand/array.h"
@@ -8,7 +8,7 @@
#include "simdjson/generic/ondemand/json_iterator.h"
#include "simdjson/generic/ondemand/value.h"
#include "simdjson/generic/ondemand/value_iterator-inl.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
+2 -2
View File
@@ -1,11 +1,11 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_ARRAY_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/implementation_simdjson_result_base.h"
#include "simdjson/generic/ondemand/value_iterator.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -1,12 +1,12 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_INL_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/ondemand/array_iterator.h"
#include "simdjson/generic/ondemand/value-inl.h"
#include "simdjson/generic/ondemand/value_iterator-inl.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -1,11 +1,11 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_ARRAY_ITERATOR_H
#include "simdjson/generic/implementation_simdjson_result_base.h"
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/ondemand/value_iterator.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
+2 -2
View File
@@ -1,9 +1,9 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_BASE_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_BASE_H
#include "simdjson/generic/base.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -1,5 +1,5 @@
#ifdef SIMDJSON_AMALGAMATED
#error simdjson/generic/ondemand/dependencies.h must be included before defining SIMDJSON_AMALGAMATED!
#ifdef SIMDJSON_CONDITIONAL_INCLUDE
#error simdjson/generic/ondemand/dependencies.h must be included before defining SIMDJSON_CONDITIONAL_INCLUDE!
#endif
#ifndef SIMDJSON_GENERIC_ONDEMAND_DEPENDENCIES_H
@@ -1,6 +1,6 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_INL_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/ondemand/array-inl.h"
@@ -12,7 +12,7 @@
#include "simdjson/generic/ondemand/raw_json_string.h"
#include "simdjson/generic/ondemand/value.h"
#include "simdjson/generic/ondemand/value_iterator-inl.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -128,6 +128,9 @@ simdjson_inline simdjson_result<double> document::get_double_in_string() noexcep
simdjson_inline simdjson_result<std::string_view> document::get_string(bool allow_replacement) noexcept {
return get_root_value_iterator().get_root_string(true, allow_replacement);
}
simdjson_inline error_code document::get_string(std::string& receiver, bool allow_replacement) noexcept {
return get_root_value_iterator().get_root_string(receiver, true, allow_replacement);
}
simdjson_inline simdjson_result<std::string_view> document::get_wobbly_string() noexcept {
return get_root_value_iterator().get_root_wobbly_string(true);
}
@@ -397,6 +400,10 @@ simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLE
if (error()) { return error(); }
return first.get_string(allow_replacement);
}
simdjson_inline error_code simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get_string(std::string& receiver, bool allow_replacement) noexcept {
if (error()) { return error(); }
return first.get_string(receiver, allow_replacement);
}
simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document>::get_wobbly_string() noexcept {
if (error()) { return error(); }
return first.get_wobbly_string();
@@ -583,6 +590,7 @@ simdjson_inline simdjson_result<int64_t> document_reference::get_int64_in_string
simdjson_inline simdjson_result<double> document_reference::get_double() noexcept { return doc->get_root_value_iterator().get_root_double(false); }
simdjson_inline simdjson_result<double> document_reference::get_double_in_string() noexcept { return doc->get_root_value_iterator().get_root_double(false); }
simdjson_inline simdjson_result<std::string_view> document_reference::get_string(bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(false, allow_replacement); }
simdjson_inline error_code document_reference::get_string(std::string& receiver, bool allow_replacement) noexcept { return doc->get_root_value_iterator().get_root_string(receiver, false, allow_replacement); }
simdjson_inline simdjson_result<std::string_view> document_reference::get_wobbly_string() noexcept { return doc->get_root_value_iterator().get_root_wobbly_string(false); }
simdjson_inline simdjson_result<raw_json_string> document_reference::get_raw_json_string() noexcept { return doc->get_root_value_iterator().get_root_raw_json_string(false); }
simdjson_inline simdjson_result<bool> document_reference::get_bool() noexcept { return doc->get_root_value_iterator().get_root_bool(false); }
@@ -719,6 +727,10 @@ simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLE
if (error()) { return error(); }
return first.get_string(allow_replacement);
}
simdjson_inline error_code simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::get_string(std::string& receiver, bool allow_replacement) noexcept {
if (error()) { return error(); }
return first.get_string(receiver, allow_replacement);
}
simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::document_reference>::get_wobbly_string() noexcept {
if (error()) { return error(); }
return first.get_wobbly_string();
+27 -4
View File
@@ -1,10 +1,10 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/ondemand/json_iterator.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -100,6 +100,20 @@ public:
* @returns INCORRECT_TYPE if the JSON value is not a string.
*/
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
/**
* Attempts to fill the provided std::string reference with the parsed value of the current string.
*
* The string is guaranteed to be valid UTF-8.
*
* Important: a value should be consumed once. Calling get_string() twice on the same value
* is an error.
*
* Performance: This method may be slower than get_string() or get_string(bool) because it may need to allocate memory.
* We recommend you avoid allocating an std::string unless you need to.
*
* @returns INCORRECT_TYPE if the JSON value is not a string. Otherwise, we return SUCCESS.
*/
simdjson_inline error_code get_string(std::string& receiver, bool allow_replacement = false) noexcept;
/**
* Cast this JSON value to a string.
*
@@ -160,13 +174,19 @@ public:
template<typename T> simdjson_inline simdjson_result<T> get() & noexcept {
// Unless the simdjson library provides an inline implementation, calling this method should
// immediately fail.
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library.");
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. "
"The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, "
"int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), "
" get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template.");
}
/** @overload template<typename T> simdjson_result<T> get() & noexcept */
template<typename T> simdjson_inline simdjson_result<T> get() && noexcept {
// Unless the simdjson library provides an inline implementation, calling this method should
// immediately fail.
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library.");
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. "
"The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, "
"int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), "
" get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template.");
}
/**
@@ -618,6 +638,7 @@ public:
simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
simdjson_inline error_code get_string(std::string& receiver, bool allow_replacement = false) noexcept;
simdjson_inline simdjson_result<std::string_view> get_wobbly_string() noexcept;
simdjson_inline simdjson_result<raw_json_string> get_raw_json_string() noexcept;
simdjson_inline simdjson_result<bool> get_bool() noexcept;
@@ -687,6 +708,7 @@ public:
simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
simdjson_inline error_code get_string(std::string& receiver, bool allow_replacement = false) noexcept;
simdjson_inline simdjson_result<std::string_view> get_wobbly_string() noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
simdjson_inline simdjson_result<bool> get_bool() noexcept;
@@ -759,6 +781,7 @@ public:
simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
simdjson_inline error_code get_string(std::string& receiver, bool allow_replacement = false) noexcept;
simdjson_inline simdjson_result<std::string_view> get_wobbly_string() noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
simdjson_inline simdjson_result<bool> get_bool() noexcept;
@@ -1,12 +1,12 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_INL_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/ondemand/document_stream.h"
#include "simdjson/generic/ondemand/document-inl.h"
#include "simdjson/generic/implementation_simdjson_result_base-inl.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
#include <algorithm>
#include <stdexcept>
@@ -1,12 +1,12 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_DOCUMENT_STREAM_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/implementation_simdjson_result_base.h"
#include "simdjson/generic/ondemand/document.h"
#include "simdjson/generic/ondemand/parser.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
#ifdef SIMDJSON_THREADS_ENABLED
#include <thread>
@@ -1,12 +1,12 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_FIELD_INL_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/ondemand/field.h"
#include "simdjson/generic/ondemand/value-inl.h"
#include "simdjson/generic/ondemand/value_iterator-inl.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
+2 -2
View File
@@ -1,12 +1,12 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_FIELD_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_FIELD_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/implementation_simdjson_result_base.h"
#include "simdjson/generic/ondemand/raw_json_string.h"
#include "simdjson/generic/ondemand/value.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -1,6 +1,6 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_INL_H
#include "simdjson/internal/dom_parser_implementation.h"
#include "simdjson/generic/ondemand/base.h"
@@ -10,7 +10,7 @@
#include "simdjson/generic/ondemand/logger-inl.h"
#include "simdjson/generic/ondemand/parser-inl.h"
#include "simdjson/generic/ondemand/token_iterator-inl.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -254,7 +254,7 @@ simdjson_inline const uint8_t *json_iterator::return_current_and_advance() noexc
simdjson_inline const uint8_t *json_iterator::unsafe_pointer() const noexcept {
// deliberately done without safety guard:
return token.peek(0);
return token.peek();
}
simdjson_inline const uint8_t *json_iterator::peek(int32_t delta) const noexcept {
@@ -1,11 +1,11 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_JSON_ITERATOR_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/implementation_simdjson_result_base.h"
#include "simdjson/generic/ondemand/token_iterator.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -254,6 +254,7 @@ public:
*/
simdjson_inline simdjson_result<std::string_view> unescape(raw_json_string in, bool allow_replacement) noexcept;
simdjson_inline simdjson_result<std::string_view> unescape_wobbly(raw_json_string in) noexcept;
simdjson_inline void reenter_child(token_position position, depth_t child_depth) noexcept;
simdjson_inline error_code consume_character(char c) noexcept;
@@ -1,11 +1,11 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_INL_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/ondemand/json_type.h"
#include "simdjson/generic/implementation_simdjson_result_base-inl.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -1,11 +1,11 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_JSON_TYPE_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/implementation_simdjson_result_base.h"
#include "simdjson/generic/numberparsing.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -1,12 +1,15 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_LOGGER_INL_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/ondemand/logger.h"
#include "simdjson/generic/ondemand/json_iterator.h"
#include "simdjson/generic/ondemand/value_iterator.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
#include <memory>
#include <cstring>
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
+2 -2
View File
@@ -1,9 +1,9 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_LOGGER_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_LOGGER_H
#include "simdjson/generic/ondemand/base.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -1,6 +1,6 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_OBJECT_INL_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/ondemand/field.h"
@@ -9,7 +9,7 @@
#include "simdjson/generic/ondemand/raw_json_string.h"
#include "simdjson/generic/ondemand/json_iterator.h"
#include "simdjson/generic/ondemand/value-inl.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -96,7 +96,7 @@ simdjson_inline simdjson_result<std::string_view> object::raw_json() noexcept {
const uint8_t * starting_point{iter.peek_start()};
auto error = consume();
if(error) { return error; }
const uint8_t * final_point{iter._json_iter->peek(0)};
const uint8_t * final_point{iter._json_iter->peek()};
return std::string_view(reinterpret_cast<const char*>(starting_point), size_t(final_point - starting_point));
}
+2 -2
View File
@@ -1,11 +1,11 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_OBJECT_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/implementation_simdjson_result_base.h"
#include "simdjson/generic/ondemand/value_iterator.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -1,12 +1,12 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_INL_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/ondemand/object_iterator.h"
#include "simdjson/generic/ondemand/field-inl.h"
#include "simdjson/generic/ondemand/value_iterator-inl.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -1,11 +1,11 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_OBJECT_ITERATOR_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/implementation_simdjson_result_base.h"
#include "simdjson/generic/ondemand/value_iterator.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -1,6 +1,6 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_PARSER_INL_H
#include "simdjson/padded_string.h"
#include "simdjson/padded_string_view.h"
@@ -11,7 +11,7 @@
#include "simdjson/generic/ondemand/document_stream.h"
#include "simdjson/generic/ondemand/parser.h"
#include "simdjson/generic/ondemand/raw_json_string.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -68,6 +68,13 @@ simdjson_warn_unused simdjson_inline simdjson_result<document> parser::iterate(s
return iterate(padded_string_view(json, allocated));
}
simdjson_warn_unused simdjson_inline simdjson_result<document> parser::iterate(std::string &json) & noexcept {
if(json.capacity() - json.size() < SIMDJSON_PADDING) {
json.reserve(json.size() + SIMDJSON_PADDING);
}
return iterate(padded_string_view(json));
}
simdjson_warn_unused simdjson_inline simdjson_result<document> parser::iterate(const std::string &json) & noexcept {
return iterate(padded_string_view(json));
}
+6 -2
View File
@@ -1,10 +1,12 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_PARSER_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_PARSER_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/implementation_simdjson_result_base.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
#include <memory>
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -105,6 +107,8 @@ public:
/** @overload simdjson_result<document> iterate(padded_string_view json) & noexcept */
simdjson_warn_unused simdjson_result<document> iterate(const std::string &json) & noexcept;
/** @overload simdjson_result<document> iterate(padded_string_view json) & noexcept */
simdjson_warn_unused simdjson_result<document> iterate(std::string &json) & noexcept;
/** @overload simdjson_result<document> iterate(padded_string_view json) & noexcept */
simdjson_warn_unused simdjson_result<document> iterate(const simdjson_result<padded_string> &json) & noexcept;
/** @overload simdjson_result<document> iterate(padded_string_view json) & noexcept */
simdjson_warn_unused simdjson_result<document> iterate(const simdjson_result<padded_string_view> &json) & noexcept;
@@ -1,12 +1,12 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_INL_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/ondemand/raw_json_string.h"
#include "simdjson/generic/ondemand/json_iterator-inl.h"
#include "simdjson/generic/implementation_simdjson_result_base-inl.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
@@ -1,10 +1,10 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_RAW_JSON_STRING_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/implementation_simdjson_result_base.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -1,6 +1,6 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_INL_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/ondemand/array.h"
@@ -9,7 +9,7 @@
#include "simdjson/generic/ondemand/object.h"
#include "simdjson/generic/ondemand/serialization.h"
#include "simdjson/generic/ondemand/value.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
@@ -1,9 +1,9 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_SERIALIZATION_H
#include "simdjson/generic/ondemand/base.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
/**
@@ -1,11 +1,11 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_INL_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/ondemand/token_iterator.h"
#include "simdjson/generic/implementation_simdjson_result_base-inl.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -1,11 +1,11 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_TOKEN_ITERATOR_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/implementation_simdjson_result_base.h"
#include "simdjson/generic/ondemand/logger.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -1,6 +1,6 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_VALUE_INL_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/ondemand/array.h"
@@ -10,7 +10,7 @@
#include "simdjson/generic/ondemand/object.h"
#include "simdjson/generic/ondemand/raw_json_string.h"
#include "simdjson/generic/ondemand/value.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -47,6 +47,9 @@ simdjson_inline simdjson_result<raw_json_string> value::get_raw_json_string() no
simdjson_inline simdjson_result<std::string_view> value::get_string(bool allow_replacement) noexcept {
return iter.get_string(allow_replacement);
}
simdjson_inline error_code value::get_string(std::string& receiver, bool allow_replacement) noexcept {
return iter.get_string(receiver, allow_replacement);
}
simdjson_inline simdjson_result<std::string_view> value::get_wobbly_string() noexcept {
return iter.get_wobbly_string();
}
@@ -319,6 +322,10 @@ simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLE
if (error()) { return error(); }
return first.get_string(allow_replacement);
}
simdjson_inline error_code simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_string(std::string& receiver, bool allow_replacement) noexcept {
if (error()) { return error(); }
return first.get_string(receiver, allow_replacement);
}
simdjson_inline simdjson_result<std::string_view> simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::value>::get_wobbly_string() noexcept {
if (error()) { return error(); }
return first.get_wobbly_string();
+21 -3
View File
@@ -1,11 +1,11 @@
#ifndef SIMDJSON_GENERIC_ONDEMAND_VALUE_H
#ifndef SIMDJSON_AMALGAMATED
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
#define SIMDJSON_GENERIC_ONDEMAND_VALUE_H
#include "simdjson/generic/ondemand/base.h"
#include "simdjson/generic/implementation_simdjson_result_base.h"
#include "simdjson/generic/ondemand/value_iterator.h"
#endif // SIMDJSON_AMALGAMATED
#endif // SIMDJSON_CONDITIONAL_INCLUDE
namespace simdjson {
namespace SIMDJSON_IMPLEMENTATION {
@@ -38,7 +38,10 @@ public:
template<typename T> simdjson_inline simdjson_result<T> get() noexcept {
// Unless the simdjson library provides an inline implementation, calling this method should
// immediately fail.
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library.");
static_assert(!sizeof(T), "The get method with given type is not implemented by the simdjson library. "
"The supported types are ondemand::object, ondemand::array, raw_json_string, std::string_view, uint64_t, "
"int64_t, double, and bool. We recommend you use get_double(), get_bool(), get_uint64(), get_int64(), "
" get_object(), get_array(), get_raw_json_string(), or get_string() instead of the get template.");
}
/**
@@ -132,6 +135,20 @@ public:
*/
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
/**
* Attempts to fill the provided std::string reference with the parsed value of the current string.
*
* The string is guaranteed to be valid UTF-8.
*
* Important: a value should be consumed once. Calling get_string() twice on the same value
* is an error.
*
* Performance: This method may be slower than get_string() or get_string(bool) because it may need to allocate memory.
* We recommend you avoid allocating an std::string unless you need to.
*
* @returns INCORRECT_TYPE if the JSON value is not a string. Otherwise, we return SUCCESS.
*/
simdjson_inline error_code get_string(std::string& receiver, bool allow_replacement = false) noexcept;
/**
* Cast this JSON value to a "wobbly" string.
@@ -602,6 +619,7 @@ public:
simdjson_inline simdjson_result<double> get_double() noexcept;
simdjson_inline simdjson_result<double> get_double_in_string() noexcept;
simdjson_inline simdjson_result<std::string_view> get_string(bool allow_replacement = false) noexcept;
simdjson_inline error_code get_string(std::string& receiver, bool allow_replacement = false) noexcept;
simdjson_inline simdjson_result<std::string_view> get_wobbly_string() noexcept;
simdjson_inline simdjson_result<SIMDJSON_IMPLEMENTATION::ondemand::raw_json_string> get_raw_json_string() noexcept;
simdjson_inline simdjson_result<bool> get_bool() noexcept;

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