Compare commits

...

2 Commits

Author SHA1 Message Date
Daniel Lemire 9b71acf803 new feature tests, etc. 2026-04-09 14:55:02 -04:00
Raju1173 325db34d41 added build macros to toggle DOM and On-Demand APIs 2026-04-09 14:54:35 -04:00
34 changed files with 11361 additions and 10278 deletions
+14
View File
@@ -52,6 +52,20 @@ if(SIMDJSON_DISABLE_DEPRECATED_API)
) )
endif() endif()
option(SIMDJSON_FEATURE_ONDEMAND_API "Enable ondemand API" ON)
option(SIMDJSON_FEATURE_DOM_API "Enable DOM API" ON)
option(SIMDJSON_FEATURE_BUILDER_API "Enable builder API" ON)
if(NOT SIMDJSON_FEATURE_ONDEMAND_API)
add_compile_definitions(SIMDJSON_FEATURE_ONDEMAND_API=0)
endif()
if(NOT SIMDJSON_FEATURE_DOM_API)
add_compile_definitions(SIMDJSON_FEATURE_DOM_API=0)
endif()
if(NOT SIMDJSON_FEATURE_BUILDER_API)
add_compile_definitions(SIMDJSON_FEATURE_BUILDER_API=0)
endif()
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.25.0") if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.25.0")
option(SIMDJSON_STATIC_REFLECTION "Enables static reflection (experimental), requires C++26" OFF) option(SIMDJSON_STATIC_REFLECTION "Enables static reflection (experimental), requires C++26" OFF)
else() else()
+18
View File
@@ -32,6 +32,24 @@ It is similar for Visual Studio users, please see the CMake or Visual Studio doc
By default the library is built in Release mode. By default the library is built in Release mode.
## Optional APIs (Feature Flags)
simdjson provides three APIs:
- DOM (`simdjson::dom`)
- OnDemand (`simdjson::ondemand`)
- Builder (`simdjson::builder`) — requires DOM
You can enable or disable these APIs at compile time to reduce binary size and compile time.
At least one of DOM or OnDemand must be enabled.
### Configuration
Using CMake:
```bash
cmake -DSIMDJSON_FEATURE_DOM_API=OFF \
-DSIMDJSON_FEATURE_ONDEMAND_API=ON \
-DSIMDJSON_FEATURE_BUILDER_API=OFF ..
Assertions and development checks Assertions and development checks
------------------------------ ------------------------------
+12 -1
View File
@@ -35,6 +35,7 @@
*/ */
#include "simdjson/common_defs.h" #include "simdjson/common_defs.h"
#include "simdjson/feature_macros.h"
// This provides the public API for simdjson. // This provides the public API for simdjson.
// DOM and ondemand are amalgamated separately, in simdjson.h // DOM and ondemand are amalgamated separately, in simdjson.h
@@ -45,19 +46,29 @@
#include "simdjson/error.h" #include "simdjson/error.h"
#include "simdjson/error-inl.h" #include "simdjson/error-inl.h"
#include "simdjson/implementation.h" #include "simdjson/implementation.h"
#include "simdjson/builtin.h"
#include "simdjson/minify.h" #include "simdjson/minify.h"
#include "simdjson/padded_string.h" #include "simdjson/padded_string.h"
#include "simdjson/padded_string-inl.h" #include "simdjson/padded_string-inl.h"
#include "simdjson/padded_string_view.h" #include "simdjson/padded_string_view.h"
#include "simdjson/padded_string_view-inl.h" #include "simdjson/padded_string_view-inl.h"
#if SIMDJSON_FEATURE_DOM_API
#include "simdjson/dom.h" #include "simdjson/dom.h"
#if SIMDJSON_FEATURE_BUILDER_API
#include "simdjson/builder.h" #include "simdjson/builder.h"
#endif // SIMDJSON_FEATURE_BUILDER_API
#endif // SIMDJSON_FEATURE_DOM_API
#if SIMDJSON_FEATURE_ONDEMAND_API
#include "simdjson/ondemand.h" #include "simdjson/ondemand.h"
#endif // SIMDJSON_FEATURE_ONDEMAND_API
#if SIMDJSON_FEATURE_DOM_API && SIMDJSON_FEATURE_ONDEMAND_API
#include "simdjson/convert.h" #include "simdjson/convert.h"
#include "simdjson/convert-inl.h" #include "simdjson/convert-inl.h"
#endif // SIMDJSON_FEATURE_DOM_API && SIMDJSON_FEATURE_ONDEMAND_API
// Compile-time JSON parsing (C++26 P2996 reflection)
#include "simdjson/compile_time_json.h" #include "simdjson/compile_time_json.h"
#include "simdjson/compile_time_json-inl.h" #include "simdjson/compile_time_json-inl.h"
+17
View File
@@ -0,0 +1,17 @@
#pragma once
#if !defined(SIMDJSON_FEATURE_DOM_API)
#define SIMDJSON_FEATURE_DOM_API 1
#endif
#if !defined(SIMDJSON_FEATURE_ONDEMAND_API)
#define SIMDJSON_FEATURE_ONDEMAND_API 1
#endif
#if !defined(SIMDJSON_FEATURE_BUILDER_API)
#define SIMDJSON_FEATURE_BUILDER_API 1
#endif
#if !SIMDJSON_FEATURE_DOM_API && !SIMDJSON_FEATURE_ONDEMAND_API
#error "simdjson: at least one of SIMDJSON_FEATURE_DOM_API or SIMDJSON_FEATURE_ONDEMAND_API must be enabled."
#endif
@@ -1,4 +1,10 @@
#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_BUILDER_DEPENDENCIES_H) #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#endif // SIMDJSON_CONDITIONAL_INCLUDE
#if SIMDJSON_FEATURE_ONDEMAND_API
#if defined(SIMDJSON_CONDITIONAL_INCLUDE) && !defined(SIMDJSON_GENERIC_ONDEMAND_DEPENDENCIES_H)
#error simdjson/generic/ondemand/dependencies.h must be included before simdjson/generic/ondemand/amalgamated.h! #error simdjson/generic/ondemand/dependencies.h must be included before simdjson/generic/ondemand/amalgamated.h!
#endif #endif
@@ -48,3 +54,5 @@
// JSON path accessor (compile-time) - must be after inline definitions // JSON path accessor (compile-time) - must be after inline definitions
#include "simdjson/generic/ondemand/compile_time_accessors.h" #include "simdjson/generic/ondemand/compile_time_accessors.h"
#endif // SIMDJSON_FEATURE_ONDEMAND_API
@@ -8,6 +8,7 @@
// Internal headers needed for ondemand generics. // Internal headers needed for ondemand generics.
// All includes not under simdjson/generic/ondemand must be here! // All includes not under simdjson/generic/ondemand must be here!
// Otherwise, amalgamation will fail. // Otherwise, amalgamation will fail.
#include "simdjson/feature_macros.h"
#include "simdjson/dom/base.h" // for MINIMAL_DOCUMENT_CAPACITY #include "simdjson/dom/base.h" // for MINIMAL_DOCUMENT_CAPACITY
#include "simdjson/implementation.h" #include "simdjson/implementation.h"
#include "simdjson/padded_string.h" #include "simdjson/padded_string.h"
+3 -1
View File
@@ -8,12 +8,14 @@ namespace simdjson {
* @copydoc simdjson::builtin::ondemand * @copydoc simdjson::builtin::ondemand
*/ */
namespace ondemand = builtin::ondemand; namespace ondemand = builtin::ondemand;
#if SIMDJSON_FEATURE_BUILDER_API
/** /**
* @copydoc simdjson::builtin::builder * @copydoc simdjson::builtin::builder
*/ */
namespace builder = builtin::builder; namespace builder = builtin::builder;
#endif // SIMDJSON_FEATURE_BUILDER_API
#if SIMDJSON_STATIC_REFLECTION #if SIMDJSON_STATIC_REFLECTION && SIMDJSON_FEATURE_BUILDER_API
/** /**
* Create a JSON string from any user-defined type using static reflection. * Create a JSON string from any user-defined type using static reflection.
* Only available when SIMDJSON_STATIC_REFLECTION is enabled. * Only available when SIMDJSON_STATIC_REFLECTION is enabled.
+226
View File
@@ -0,0 +1,226 @@
#!/usr/bin/env python3
"""
Amalgamates simdjson into temporary files, then builds and runs 7 feature-flag
test programs. Reports compile time and binary size for each configuration.
"""
import os
import sys
import subprocess
import tempfile
import time
import shutil
SCRIPTPATH = os.path.dirname(os.path.abspath(__file__))
PROJECTPATH = os.path.dirname(SCRIPTPATH)
TESTSRC = os.path.join(PROJECTPATH, "tests", "feature_flag_tests")
# ── feature-flag configurations ──────────────────────────────────────────────
CONFIGS = [
{
"name": "dom_only",
"flags": {"SIMDJSON_FEATURE_DOM_API": 1,
"SIMDJSON_FEATURE_ONDEMAND_API": 0,
"SIMDJSON_FEATURE_BUILDER_API": 0},
},
{
"name": "ondemand_only",
"flags": {"SIMDJSON_FEATURE_DOM_API": 1,
"SIMDJSON_FEATURE_ONDEMAND_API": 1,
"SIMDJSON_FEATURE_BUILDER_API": 0},
},
{
"name": "dom_and_ondemand",
"flags": {"SIMDJSON_FEATURE_DOM_API": 1,
"SIMDJSON_FEATURE_ONDEMAND_API": 1,
"SIMDJSON_FEATURE_BUILDER_API": 0},
},
{
"name": "builder_and_dom",
"flags": {"SIMDJSON_FEATURE_DOM_API": 1,
"SIMDJSON_FEATURE_ONDEMAND_API": 0,
"SIMDJSON_FEATURE_BUILDER_API": 1},
},
{
"name": "builder_and_ondemand",
"flags": {"SIMDJSON_FEATURE_DOM_API": 1,
"SIMDJSON_FEATURE_ONDEMAND_API": 1,
"SIMDJSON_FEATURE_BUILDER_API": 1},
},
{
"name": "builder_dom_and_ondemand",
"flags": {"SIMDJSON_FEATURE_DOM_API": 1,
"SIMDJSON_FEATURE_ONDEMAND_API": 1,
"SIMDJSON_FEATURE_BUILDER_API": 1},
},
{
"name": "builder_only",
"flags": {"SIMDJSON_FEATURE_DOM_API": 1,
"SIMDJSON_FEATURE_ONDEMAND_API": 0,
"SIMDJSON_FEATURE_BUILDER_API": 1},
},
]
CXX = os.environ.get("CXX", "c++")
CXXSTD = os.environ.get("CXXSTD", "-std=c++17")
OPT = os.environ.get("OPT", "-O2")
def amalgamate(output_dir):
"""Run amalgamate.py, writing simdjson.h / simdjson.cpp into *output_dir*."""
env = os.environ.copy()
env["AMALGAMATE_OUTPUT_PATH"] = output_dir
cmd = [sys.executable, os.path.join(SCRIPTPATH, "amalgamate.py")]
result = subprocess.run(cmd, env=env, capture_output=True, text=True)
if result.returncode != 0:
print("amalgamate.py failed:")
print(result.stdout)
print(result.stderr)
sys.exit(1)
header = os.path.join(output_dir, "simdjson.h")
source = os.path.join(output_dir, "simdjson.cpp")
assert os.path.isfile(header), f"missing {header}"
assert os.path.isfile(source), f"missing {source}"
return header, source
def compile_and_run(name, flags, amal_dir, build_dir):
"""
1. Compile simdjson.cpp -> simdjson.o (timed, size reported)
2. Compile test .cpp -> test.o (timed, size reported)
3. Link and run the test program
Returns (lib_time, lib_size, test_time, test_size) or Nones on failure.
"""
src = os.path.join(TESTSRC, f"{name}.cpp")
simdjson_cpp = os.path.join(amal_dir, "simdjson.cpp")
simdjson_o = os.path.join(build_dir, f"{name}_simdjson.o")
test_o = os.path.join(build_dir, f"{name}.o")
binary = os.path.join(build_dir, name)
defs = [f"-D{k}={v}" for k, v in flags.items()]
# ── compile simdjson.o (timed) ────────────────────────────────────────
cmd_lib = [CXX, CXXSTD, OPT, "-c"] + defs + [
f"-I{amal_dir}", "-o", simdjson_o, simdjson_cpp,
]
t0 = time.monotonic()
result = subprocess.run(cmd_lib, capture_output=True, text=True)
lib_time = time.monotonic() - t0
if result.returncode != 0:
print(f" COMPILE FAILED (simdjson.o): {name}")
print(f" command: {' '.join(cmd_lib)}")
print(result.stderr)
return None, None, None, None
lib_size = os.path.getsize(simdjson_o)
# ── compile test source (timed) ───────────────────────────────────────
cmd_test = [CXX, CXXSTD, OPT, "-c"] + defs + [
f"-I{amal_dir}", "-o", test_o, src,
]
t0 = time.monotonic()
result = subprocess.run(cmd_test, capture_output=True, text=True)
test_time = time.monotonic() - t0
if result.returncode != 0:
print(f" COMPILE FAILED (test): {name}")
print(f" command: {' '.join(cmd_test)}")
print(result.stderr)
return None, None, None, None
test_size = os.path.getsize(test_o)
# ── link ──────────────────────────────────────────────────────────────
cmd_link = [CXX, "-o", binary, test_o, simdjson_o]
result = subprocess.run(cmd_link, capture_output=True, text=True)
if result.returncode != 0:
print(f" LINK FAILED: {name}")
print(f" command: {' '.join(cmd_link)}")
print(result.stderr)
return None, None, None, None
# ── run ───────────────────────────────────────────────────────────────
result = subprocess.run([binary], capture_output=True, text=True)
if result.returncode != 0:
print(f" RUN FAILED: {name}")
print(result.stdout)
print(result.stderr)
return lib_time, lib_size, test_time, test_size
print(f" {result.stdout.strip()}")
return lib_time, lib_size, test_time, test_size
def human_size(n):
"""Return e.g. '1.23 MB' or '456 KB'."""
if n is None:
return "N/A"
if n >= 1_000_000:
return f"{n / 1_000_000:.2f} MB"
if n >= 1_000:
return f"{n / 1_000:.1f} KB"
return f"{n} B"
def main():
tmpdir = tempfile.mkdtemp(prefix="simdjson_features_")
amal_dir = os.path.join(tmpdir, "amalgamated")
build_dir = os.path.join(tmpdir, "build")
os.makedirs(amal_dir, exist_ok=True)
os.makedirs(build_dir, exist_ok=True)
print(f"Working directory: {tmpdir}")
print(f"Compiler: {CXX} flags: {CXXSTD} {OPT}")
print()
# ── amalgamate ────────────────────────────────────────────────────────
print("Amalgamating...")
amalgamate(amal_dir)
print("Amalgamation done.\n")
# ── build & run each configuration ────────────────────────────────────
results = []
for cfg in CONFIGS:
name = cfg["name"]
flags = cfg["flags"]
enabled = [k.replace("SIMDJSON_FEATURE_", "").replace("_API", "")
for k, v in flags.items() if v]
label = " + ".join(enabled) if enabled else "none"
print(f"[{name}] ({label})")
lib_time, lib_size, test_time, test_size = \
compile_and_run(name, flags, amal_dir, build_dir)
results.append((name, label, lib_time, lib_size, test_time, test_size))
print()
# ── summary table ─────────────────────────────────────────────────────
name_w = max(len(r[0]) for r in results)
label_w = max(len(r[1]) for r in results)
hdr = (f"{'Test':<{name_w}} {'APIs':<{label_w}}"
f" {'lib time':>9} {'simdjson.o':>11}"
f" {'test time':>10} {'test .o':>11}")
print(hdr)
print("-" * len(hdr))
for name, label, lt, ls, tt, ts in results:
lt_s = f"{lt:.2f} s" if lt is not None else "FAIL"
ls_s = human_size(ls)
tt_s = f"{tt:.2f} s" if tt is not None else "FAIL"
ts_s = human_size(ts)
print(f"{name:<{name_w}} {label:<{label_w}}"
f" {lt_s:>9} {ls_s:>11}"
f" {tt_s:>10} {ts_s:>11}")
# ── cleanup ───────────────────────────────────────────────────────────
shutil.rmtree(tmpdir, ignore_errors=True)
# exit non-zero if anything failed
if any(lt is None for _, _, lt, _, _, _ in results):
print("\nSome tests FAILED.")
sys.exit(1)
print("\nAll tests passed.")
if __name__ == "__main__":
main()
+54 -3
View File
@@ -268,7 +268,21 @@ class SimdjsonFile:
print(f" Adding include: {self} includes {include}") print(f" Adding include: {self} includes {include}")
if self.is_conditional_include: if self.is_conditional_include:
# If I have a dependency file, I can only include something that has a dependency file. # If I have a dependency file, I can only include something that has a dependency file.
assert include.is_conditional_include, f"Error: Amalgamated file '{self}' is trying to include '{include}', but '{include}' is not an amalgamated file. Amalgamated files can only include other amalgamated files to maintain conditional inclusion structure. Check the inclusion rules in the script's 'rules' variable. {rules}" if not include.is_conditional_include:
dep = self.dependency_file
dep_hint = f" and add it to the dependency file '{dep}'" if dep else ""
raise AssertionError(
f"Error: Amalgamated file '{self}' is trying to include '{include}', "
f"but '{include}' is not an amalgamated file.\n\n"
f"FIX: Wrap the #include \"{include}\" in a conditional block:\n\n"
f" #ifndef SIMDJSON_CONDITIONAL_INCLUDE\n"
f" #include \"{include}\"\n"
f" #endif // SIMDJSON_CONDITIONAL_INCLUDE\n\n"
f"This makes the include editor-only (skipped during amalgamation){dep_hint}.\n\n"
f"During amalgamation, '{include}' is already included earlier in the "
f"amalgamated output, so it does not need to be included again.\n\n"
f"{rules}"
)
# TODO make sure we only include amalgamated files that are guaranteed to be included with us (or before us) # TODO make sure we only include amalgamated files that are guaranteed to be included with us (or before us)
# if include.amalgamator_file: # if include.amalgamator_file:
# assert include.amalgamator_file == self, f"{self} cannot include {include}: it should be included from {include.amalgamator_file} instead." # assert include.amalgamator_file == self, f"{self} cannot include {include}: it should be included from {include.amalgamator_file} instead."
@@ -425,8 +439,10 @@ class Amalgamator:
self.implementation = "SIMDJSON_BUILTIN_IMPLEMENTATION" self.implementation = "SIMDJSON_BUILTIN_IMPLEMENTATION"
assert not self.editor_only_region, f"Error: Already in an editor-only region when starting to write '{file}'. Ensure proper nesting of conditional blocks." assert not self.editor_only_region, f"Error: Already in an editor-only region when starting to write '{file}'. Ensure proper nesting of conditional blocks."
editor_only_start_line = None
bare_endif_lines = []
with open(file.absolute_path, 'r') as fid2: with open(file.absolute_path, 'r') as fid2:
for line in fid2: for line_number, line in enumerate(fid2, 1):
line = line.rstrip('\n') line = line.rstrip('\n')
# Ignore #pragma once, it causes warnings if it ends up in a .cpp file # Ignore #pragma once, it causes warnings if it ends up in a .cpp file
@@ -439,6 +455,7 @@ class Amalgamator:
assert self.in_conditional_include_block, f"Error: File '{file}' uses '#ifndef SIMDJSON_CONDITIONAL_INCLUDE' without a prior '#define SIMDJSON_CONDITIONAL_INCLUDE'. Ensure the define comes first. Stack: {self.include_stack}. {rules}" assert self.in_conditional_include_block, f"Error: File '{file}' uses '#ifndef SIMDJSON_CONDITIONAL_INCLUDE' without a prior '#define SIMDJSON_CONDITIONAL_INCLUDE'. Ensure the define comes first. Stack: {self.include_stack}. {rules}"
assert not self.editor_only_region, f"Error: File '{file}' uses '#ifndef SIMDJSON_CONDITIONAL_INCLUDE' twice in a row. Ensure conditional blocks are properly nested and closed. {rules}" assert not self.editor_only_region, f"Error: File '{file}' uses '#ifndef SIMDJSON_CONDITIONAL_INCLUDE' twice in a row. Ensure conditional blocks are properly nested and closed. {rules}"
self.editor_only_region = True self.editor_only_region = True
editor_only_start_line = line_number
# Handle ignored lines (and ending ignore blocks) # Handle ignored lines (and ending ignore blocks)
end_ignore = endif_conditional_re.search(line) end_ignore = endif_conditional_re.search(line)
@@ -453,6 +470,12 @@ class Amalgamator:
file.add_editor_only_include(included_file) file.add_editor_only_include(included_file)
if end_ignore: if end_ignore:
self.editor_only_region = False self.editor_only_region = False
editor_only_start_line = None
else:
# Track bare #endif lines that might be the intended closer
stripped = line.strip()
if stripped == '#endif' or (stripped.startswith('#endif') and 'SIMDJSON_CONDITIONAL_INCLUDE' not in stripped):
bare_endif_lines.append((line_number, line.strip()))
continue continue
assert not end_ignore, f"Error: File '{file}' has '#endif // SIMDJSON_CONDITIONAL_INCLUDE' without a matching '#ifndef'. Ensure proper conditional block structure. {rules}" assert not end_ignore, f"Error: File '{file}' has '#endif // SIMDJSON_CONDITIONAL_INCLUDE' without a matching '#ifndef'. Ensure proper conditional block structure. {rules}"
@@ -501,7 +524,35 @@ class Amalgamator:
self.write(line) self.write(line)
assert not self.editor_only_region, f"Error: File '{file}' ended without closing the '#endif // SIMDJSON_CONDITIONAL_INCLUDE'. Ensure all conditional blocks are properly closed. {rules}" if self.editor_only_region:
msg = (
f"Error: File '{file}' ended without closing the "
f"'#endif // SIMDJSON_CONDITIONAL_INCLUDE' block "
f"(opened at line {editor_only_start_line}).\n\n"
)
if bare_endif_lines:
msg += (
f"HINT: Found #endif line(s) inside the block that are missing "
f"the required comment. The amalgamation script looks for exactly:\n\n"
f" #endif // SIMDJSON_CONDITIONAL_INCLUDE\n\n"
f"but found:\n"
)
for ln, text in bare_endif_lines:
msg += f" line {ln}: {text}\n"
msg += (
f"\nFIX: Change the #endif to:\n\n"
f" #endif // SIMDJSON_CONDITIONAL_INCLUDE\n\n"
f"The '// SIMDJSON_CONDITIONAL_INCLUDE' comment is required "
f"for the amalgamation script to recognize it as the closing "
f"of the conditional block.\n"
)
else:
msg += (
f"FIX: Add '#endif // SIMDJSON_CONDITIONAL_INCLUDE' to close "
f"the '#ifndef SIMDJSON_CONDITIONAL_INCLUDE' block.\n"
)
msg += f"\n{rules}"
raise AssertionError(msg)
self.write(f"/* end file {self.file_to_str(file)} */") self.write(f"/* end file {self.file_to_str(file)} */")
+2121 -2010
View File
File diff suppressed because it is too large Load Diff
+8515 -8257
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.
+5
View File
@@ -2,6 +2,7 @@
#define SIMDJSON_SRC_ARM64_CPP #define SIMDJSON_SRC_ARM64_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -142,6 +143,7 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
return arm64::stage1::generic_validate_utf8(buf,len); return arm64::stage1::generic_validate_utf8(buf,len);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -149,6 +151,7 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
@@ -159,11 +162,13 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return arm64::stringparsing::parse_wobbly_string(src, dst); return arm64::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace arm64 } // namespace arm64
} // namespace simdjson } // namespace simdjson
+8
View File
@@ -2,6 +2,7 @@
#define SIMDJSON_SRC_FALLBACK_CPP #define SIMDJSON_SRC_FALLBACK_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -11,10 +12,13 @@
#include <simdjson/fallback/begin.h> #include <simdjson/fallback/begin.h>
#include <generic/stage1/find_next_document_index.h> #include <generic/stage1/find_next_document_index.h>
#include <generic/stage2/stringparsing.h> #include <generic/stage2/stringparsing.h>
#if SIMDJSON_FEATURE_DOM_API
#include <generic/stage2/logger.h> #include <generic/stage2/logger.h>
#include <generic/stage2/json_iterator.h> #include <generic/stage2/json_iterator.h>
#include <generic/stage2/tape_writer.h> #include <generic/stage2/tape_writer.h>
#include <generic/stage2/tape_builder.h> #include <generic/stage2/tape_builder.h>
#endif // SIMDJSON_FEATURE_DOM_API
// //
// Stage 1 // Stage 1
@@ -436,6 +440,7 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
namespace simdjson { namespace simdjson {
namespace fallback { namespace fallback {
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -443,6 +448,7 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
@@ -453,11 +459,13 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return fallback::stringparsing::parse_wobbly_string(src, dst); return fallback::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace fallback } // namespace fallback
} // namespace simdjson } // namespace simdjson
+1
View File
@@ -5,6 +5,7 @@
#ifndef SIMDJSON_SRC_GENERIC_DEPENDENCIES_H #ifndef SIMDJSON_SRC_GENERIC_DEPENDENCIES_H
#define SIMDJSON_SRC_GENERIC_DEPENDENCIES_H #define SIMDJSON_SRC_GENERIC_DEPENDENCIES_H
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_SRC_GENERIC_DEPENDENCIES_H #endif // SIMDJSON_SRC_GENERIC_DEPENDENCIES_H
+6 -1
View File
@@ -1,3 +1,7 @@
#include <generic/stage2/stringparsing.h>
#if SIMDJSON_FEATURE_DOM_API
// Stuff other things depend on // Stuff other things depend on
#include <generic/stage2/base.h> #include <generic/stage2/base.h>
#include <generic/stage2/tape_writer.h> #include <generic/stage2/tape_writer.h>
@@ -5,6 +9,7 @@
// All other declarations // All other declarations
#include <generic/stage2/json_iterator.h> #include <generic/stage2/json_iterator.h>
#include <generic/stage2/stringparsing.h>
#include <generic/stage2/structural_iterator.h> #include <generic/stage2/structural_iterator.h>
#include <generic/stage2/tape_builder.h> #include <generic/stage2/tape_builder.h>
#endif // SIMDJSON_FEATURE_DOM_API
+6 -1
View File
@@ -2,6 +2,7 @@
#define SIMDJSON_SRC_HASWELL_CPP #define SIMDJSON_SRC_HASWELL_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -139,6 +140,7 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
return haswell::stage1::generic_validate_utf8(buf,len); return haswell::stage1::generic_validate_utf8(buf,len);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -146,6 +148,7 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
@@ -156,15 +159,17 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return haswell::stringparsing::parse_wobbly_string(src, dst); return haswell::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace SIMDJSON_IMPLEMENTATION } // namespace SIMDJSON_IMPLEMENTATION
} // namespace simdjson } // namespace simdjson
#include <simdjson/haswell/end.h> #include <simdjson/haswell/end.h>
#endif // SIMDJSON_SRC_HASWELL_CPP #endif // SIMDJSON_SRC_HASWELL_CPP
+5
View File
@@ -2,6 +2,7 @@
#define SIMDJSON_SRC_ICELAKE_CPP #define SIMDJSON_SRC_ICELAKE_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -185,6 +186,7 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
return icelake::stage1::generic_validate_utf8(buf,len); return icelake::stage1::generic_validate_utf8(buf,len);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -192,6 +194,7 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
@@ -202,11 +205,13 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return icelake::stringparsing::parse_wobbly_string(src, dst); return icelake::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace icelake } // namespace icelake
} // namespace simdjson } // namespace simdjson
+5
View File
@@ -2,6 +2,7 @@
#define SIMDJSON_SRC_LASX_CPP #define SIMDJSON_SRC_LASX_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -102,6 +103,7 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
return lasx::stage1::generic_validate_utf8(buf,len); return lasx::stage1::generic_validate_utf8(buf,len);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -109,6 +111,7 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
@@ -119,11 +122,13 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return lasx::stringparsing::parse_wobbly_string(src, dst); return lasx::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace lasx } // namespace lasx
} // namespace simdjson } // namespace simdjson
+5
View File
@@ -2,6 +2,7 @@
#define SIMDJSON_SRC_LSX_CPP #define SIMDJSON_SRC_LSX_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -106,6 +107,7 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
return lsx::stage1::generic_validate_utf8(buf,len); return lsx::stage1::generic_validate_utf8(buf,len);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -113,6 +115,7 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
@@ -123,11 +126,13 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return lsx::stringparsing::parse_wobbly_string(src, dst); return lsx::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace lsx } // namespace lsx
} // namespace simdjson } // namespace simdjson
+5
View File
@@ -2,6 +2,7 @@
#define SIMDJSON_SRC_PPC64_CPP #define SIMDJSON_SRC_PPC64_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -112,6 +113,7 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
return ppc64::stage1::generic_validate_utf8(buf,len); return ppc64::stage1::generic_validate_utf8(buf,len);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -119,6 +121,7 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
@@ -129,11 +132,13 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return ppc64::stringparsing::parse_wobbly_string(src, dst); return ppc64::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace ppc64 } // namespace ppc64
} // namespace simdjson } // namespace simdjson
+5
View File
@@ -2,6 +2,7 @@
#define SIMDJSON_SRC_RVV_VLS_CPP #define SIMDJSON_SRC_RVV_VLS_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -101,6 +102,7 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
return rvv_vls::stage1::generic_validate_utf8(buf,len); return rvv_vls::stage1::generic_validate_utf8(buf,len);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -108,6 +110,7 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool allow_replacement) const noexcept {
@@ -118,11 +121,13 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return rvv_vls::stringparsing::parse_wobbly_string(src, dst); return rvv_vls::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace rvv_vls } // namespace rvv_vls
} // namespace simdjson } // namespace simdjson
+5 -1
View File
@@ -1,5 +1,7 @@
#define SIMDJSON_SRC_SIMDJSON_CPP #define SIMDJSON_SRC_SIMDJSON_CPP
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS
@@ -13,8 +15,11 @@ SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS
#include <simdjson/generic/dependencies.h> #include <simdjson/generic/dependencies.h>
#include <generic/dependencies.h> #include <generic/dependencies.h>
#if SIMDJSON_FEATURE_DOM_API
#include <generic/stage1/dependencies.h> #include <generic/stage1/dependencies.h>
#include <generic/stage2/dependencies.h> #include <generic/stage2/dependencies.h>
#endif
#include <implementation.cpp> #include <implementation.cpp>
@@ -50,4 +55,3 @@ SIMDJSON_PUSH_DISABLE_UNUSED_WARNINGS
#undef SIMDJSON_CONDITIONAL_INCLUDE #undef SIMDJSON_CONDITIONAL_INCLUDE
SIMDJSON_POP_DISABLE_UNUSED_WARNINGS SIMDJSON_POP_DISABLE_UNUSED_WARNINGS
+6 -1
View File
@@ -2,6 +2,7 @@
#define SIMDJSON_SRC_WESTMERE_CPP #define SIMDJSON_SRC_WESTMERE_CPP
#ifndef SIMDJSON_CONDITIONAL_INCLUDE #ifndef SIMDJSON_CONDITIONAL_INCLUDE
#include "simdjson/feature_macros.h"
#include <base.h> #include <base.h>
#endif // SIMDJSON_CONDITIONAL_INCLUDE #endif // SIMDJSON_CONDITIONAL_INCLUDE
@@ -144,6 +145,7 @@ simdjson_warn_unused bool implementation::validate_utf8(const char *buf, size_t
return westmere::stage1::generic_validate_utf8(buf,len); return westmere::stage1::generic_validate_utf8(buf,len);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<false>(*this, _doc); return stage2::tape_builder::parse_document<false>(*this, _doc);
} }
@@ -151,6 +153,7 @@ simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document
simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::stage2_next(dom::document &_doc) noexcept {
return stage2::tape_builder::parse_document<true>(*this, _doc); return stage2::tape_builder::parse_document<true>(*this, _doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
SIMDJSON_NO_SANITIZE_MEMORY SIMDJSON_NO_SANITIZE_MEMORY
simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept { simdjson_warn_unused uint8_t *dom_parser_implementation::parse_string(const uint8_t *src, uint8_t *dst, bool replacement_char) const noexcept {
@@ -161,14 +164,16 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
return westmere::stringparsing::parse_wobbly_string(src, dst); return westmere::stringparsing::parse_wobbly_string(src, dst);
} }
#if SIMDJSON_FEATURE_DOM_API
simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept { simdjson_warn_unused error_code dom_parser_implementation::parse(const uint8_t *_buf, size_t _len, dom::document &_doc) noexcept {
auto error = stage1(_buf, _len, stage1_mode::regular); auto error = stage1(_buf, _len, stage1_mode::regular);
if (error) { return error; } if (error) { return error; }
return stage2(_doc); return stage2(_doc);
} }
#endif // SIMDJSON_FEATURE_DOM_API
} // namespace westmere } // namespace westmere
} // namespace simdjson } // namespace simdjson
#include <simdjson/westmere/end.h> #include <simdjson/westmere/end.h>
#endif // SIMDJSON_SRC_WESTMERE_CPP #endif // SIMDJSON_SRC_WESTMERE_CPP
+2 -1
View File
@@ -29,4 +29,5 @@ add_cpp_test(checkimplementation LABELS other per_implementation)
add_subdirectory(compilation_failure_tests) add_subdirectory(compilation_failure_tests)
add_subdirectory(builder) add_subdirectory(builder)
add_subdirectory(compile_time) add_subdirectory(compile_time)
add_subdirectory(feature_flag_tests)
+3
View File
@@ -1,5 +1,8 @@
# All remaining tests link with simdjson proper # All remaining tests link with simdjson proper
include_directories(..) include_directories(..)
if(NOT SIMDJSON_FEATURE_BUILDER_API)
return()
endif()
add_cpp_test(builder_string_builder_tests LABELS ondemand acceptance per_implementation) add_cpp_test(builder_string_builder_tests LABELS ondemand acceptance per_implementation)
if(SIMDJSON_STATIC_REFLECTION) if(SIMDJSON_STATIC_REFLECTION)
add_cpp_test(static_reflection_custom_tests LABELS ondemand acceptance per_implementation) add_cpp_test(static_reflection_custom_tests LABELS ondemand acceptance per_implementation)
+36
View File
@@ -0,0 +1,36 @@
# Feature flag tests: compile and run against the amalgamated single-header file.
# Each test uses target_compile_definitions to set its own feature macros,
# independent of the project-wide settings.
set(SINGLEHEADER_DIR ${PROJECT_SOURCE_DIR}/singleheader)
function(add_feature_flag_test TEST_NAME)
cmake_parse_arguments(PARSE_ARGV 1 ARG "" "" "DEFS")
add_executable(${TEST_NAME} ${TEST_NAME}.cpp ${SINGLEHEADER_DIR}/simdjson.cpp)
target_include_directories(${TEST_NAME} PRIVATE ${SINGLEHEADER_DIR})
target_compile_features(${TEST_NAME} PRIVATE cxx_std_17)
# Override any inherited feature flag definitions with our own.
target_compile_definitions(${TEST_NAME} PRIVATE ${ARG_DEFS})
# Remove inherited link libraries (simdjson-internal-flags brings -Werror
# which conflicts with the amalgamated header's warning profile).
set_target_properties(${TEST_NAME} PROPERTIES LINK_LIBRARIES "")
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
set_property(TEST ${TEST_NAME} APPEND PROPERTY LABELS feature_flags acceptance)
endfunction()
add_feature_flag_test(dom_only DEFS
SIMDJSON_FEATURE_DOM_API=1 SIMDJSON_FEATURE_ONDEMAND_API=0 SIMDJSON_FEATURE_BUILDER_API=0)
# Note: OnDemand tests also enable DOM because the builtin infrastructure
# is currently included via the DOM/builtin path in the amalgamated header.
add_feature_flag_test(ondemand_only DEFS
SIMDJSON_FEATURE_DOM_API=1 SIMDJSON_FEATURE_ONDEMAND_API=1 SIMDJSON_FEATURE_BUILDER_API=0)
add_feature_flag_test(dom_and_ondemand DEFS
SIMDJSON_FEATURE_DOM_API=1 SIMDJSON_FEATURE_ONDEMAND_API=1 SIMDJSON_FEATURE_BUILDER_API=0)
add_feature_flag_test(builder_and_dom DEFS
SIMDJSON_FEATURE_DOM_API=1 SIMDJSON_FEATURE_ONDEMAND_API=0 SIMDJSON_FEATURE_BUILDER_API=1)
add_feature_flag_test(builder_and_ondemand DEFS
SIMDJSON_FEATURE_DOM_API=1 SIMDJSON_FEATURE_ONDEMAND_API=1 SIMDJSON_FEATURE_BUILDER_API=1)
add_feature_flag_test(builder_dom_and_ondemand DEFS
SIMDJSON_FEATURE_DOM_API=1 SIMDJSON_FEATURE_ONDEMAND_API=1 SIMDJSON_FEATURE_BUILDER_API=1)
add_feature_flag_test(builder_only DEFS
SIMDJSON_FEATURE_DOM_API=1 SIMDJSON_FEATURE_ONDEMAND_API=0 SIMDJSON_FEATURE_BUILDER_API=1)
@@ -0,0 +1,42 @@
// Test: Builder + DOM APIs (OnDemand disabled)
// Feature flags set via target_compile_definitions in CMakeLists.txt
#include "simdjson.h"
#include <iostream>
int main() {
auto json = R"({"key": "value"})"_padded;
// Use DOM API
simdjson::dom::parser parser;
simdjson::dom::element doc;
auto error = parser.parse(json).get(doc);
if (error) {
std::cerr << "DOM parse error: " << error << std::endl;
return EXIT_FAILURE;
}
std::string_view val;
error = doc["key"].get_string().get(val);
if (error || val != "value") {
std::cerr << "DOM key lookup failed" << std::endl;
return EXIT_FAILURE;
}
// Use Builder API
simdjson::builder::string_builder sb;
sb.start_object();
sb.append_key_value("greeting", "hello");
sb.end_object();
std::string_view result;
error = sb.view().get(result);
if (error) {
std::cerr << "Builder error: " << error << std::endl;
return EXIT_FAILURE;
}
if (result != R"({"greeting":"hello"})") {
std::cerr << "Builder output mismatch: " << result << std::endl;
return EXIT_FAILURE;
}
std::cout << "Builder+DOM test passed." << std::endl;
return EXIT_SUCCESS;
}
@@ -0,0 +1,45 @@
// Test: Builder + OnDemand APIs (DOM also enabled since Builder depends on it)
// Feature flags set via target_compile_definitions in CMakeLists.txt
#include "simdjson.h"
#include <iostream>
int main() {
// Use OnDemand API
auto json = R"({"key": "value"})"_padded;
simdjson::ondemand::parser parser;
simdjson::ondemand::document doc;
auto error = parser.iterate(json).get(doc);
if (error) {
std::cerr << "OnDemand parse error: " << error << std::endl;
return EXIT_FAILURE;
}
std::string_view val;
error = doc["key"].get_string().get(val);
if (error || val != "value") {
std::cerr << "OnDemand key lookup failed" << std::endl;
return EXIT_FAILURE;
}
// Use Builder API
simdjson::builder::string_builder sb;
sb.start_array();
sb.append(1);
sb.append_comma();
sb.append(2);
sb.append_comma();
sb.append(3);
sb.end_array();
std::string_view result;
error = sb.view().get(result);
if (error) {
std::cerr << "Builder error: " << error << std::endl;
return EXIT_FAILURE;
}
if (result != "[1,2,3]") {
std::cerr << "Builder output mismatch: " << result << std::endl;
return EXIT_FAILURE;
}
std::cout << "Builder+OnDemand test passed." << std::endl;
return EXIT_SUCCESS;
}
@@ -0,0 +1,59 @@
// Test: All three APIs enabled (Builder + DOM + OnDemand)
// Feature flags set via target_compile_definitions in CMakeLists.txt
#include "simdjson.h"
#include <iostream>
int main() {
auto json = R"({"name": "simdjson", "version": 5})"_padded;
// Use DOM API
simdjson::dom::parser dom_parser;
simdjson::dom::element dom_doc;
auto error = dom_parser.parse(json).get(dom_doc);
if (error) {
std::cerr << "DOM parse error: " << error << std::endl;
return EXIT_FAILURE;
}
std::string_view name;
error = dom_doc["name"].get_string().get(name);
if (error || name != "simdjson") {
std::cerr << "DOM name lookup failed" << std::endl;
return EXIT_FAILURE;
}
// Use OnDemand API
simdjson::ondemand::parser od_parser;
simdjson::ondemand::document od_doc;
error = od_parser.iterate(json).get(od_doc);
if (error) {
std::cerr << "OnDemand parse error: " << error << std::endl;
return EXIT_FAILURE;
}
std::string_view od_name;
error = od_doc["name"].get_string().get(od_name);
if (error || od_name != "simdjson") {
std::cerr << "OnDemand name lookup failed" << std::endl;
return EXIT_FAILURE;
}
// Use Builder API
simdjson::builder::string_builder sb;
sb.start_object();
sb.append_key_value("name", "simdjson");
sb.append_comma();
sb.append_key_value("version", 5);
sb.end_object();
std::string_view result;
error = sb.view().get(result);
if (error) {
std::cerr << "Builder error: " << error << std::endl;
return EXIT_FAILURE;
}
if (result != R"({"name":"simdjson","version":5})") {
std::cerr << "Builder output mismatch: " << result << std::endl;
return EXIT_FAILURE;
}
std::cout << "Builder+DOM+OnDemand test passed." << std::endl;
return EXIT_SUCCESS;
}
+27
View File
@@ -0,0 +1,27 @@
// Test: Builder API only (OnDemand disabled, DOM enabled since Builder depends on it)
// Feature flags set via target_compile_definitions in CMakeLists.txt
#include "simdjson.h"
#include <iostream>
int main() {
// Use Builder API
simdjson::builder::string_builder sb;
sb.start_object();
sb.append_key_value("count", 2);
sb.append_comma();
sb.append_key_value("name", "test");
sb.end_object();
std::string_view result;
auto error = sb.view().get(result);
if (error) {
std::cerr << "Builder error: " << error << std::endl;
return EXIT_FAILURE;
}
if (result != R"({"count":2,"name":"test"})") {
std::cerr << "Builder output mismatch: " << result << std::endl;
return EXIT_FAILURE;
}
std::cout << "Builder-only test passed." << std::endl;
return EXIT_SUCCESS;
}
@@ -0,0 +1,41 @@
// Test: Both DOM and OnDemand APIs (Builder disabled)
// Feature flags set via target_compile_definitions in CMakeLists.txt
#include "simdjson.h"
#include <iostream>
int main() {
auto json = R"({"key": "value", "number": 42})"_padded;
// Use DOM API
simdjson::dom::parser dom_parser;
simdjson::dom::element dom_doc;
auto error = dom_parser.parse(json).get(dom_doc);
if (error) {
std::cerr << "DOM parse error: " << error << std::endl;
return EXIT_FAILURE;
}
std::string_view dom_val;
error = dom_doc["key"].get_string().get(dom_val);
if (error || dom_val != "value") {
std::cerr << "DOM key lookup failed" << std::endl;
return EXIT_FAILURE;
}
// Use OnDemand API
simdjson::ondemand::parser od_parser;
simdjson::ondemand::document od_doc;
error = od_parser.iterate(json).get(od_doc);
if (error) {
std::cerr << "OnDemand parse error: " << error << std::endl;
return EXIT_FAILURE;
}
std::string_view od_val;
error = od_doc["key"].get_string().get(od_val);
if (error || od_val != "value") {
std::cerr << "OnDemand key lookup failed" << std::endl;
return EXIT_FAILURE;
}
std::cout << "DOM+OnDemand test passed." << std::endl;
return EXIT_SUCCESS;
}
+29
View File
@@ -0,0 +1,29 @@
// Test: DOM API only (OnDemand and Builder disabled)
// Feature flags set via target_compile_definitions in CMakeLists.txt
#include "simdjson.h"
#include <iostream>
int main() {
simdjson::dom::parser parser;
auto json = R"({"key": "value", "number": 42})"_padded;
simdjson::dom::element doc;
auto error = parser.parse(json).get(doc);
if (error) {
std::cerr << "DOM parse error: " << error << std::endl;
return EXIT_FAILURE;
}
std::string_view val;
error = doc["key"].get_string().get(val);
if (error || val != "value") {
std::cerr << "DOM key lookup failed" << std::endl;
return EXIT_FAILURE;
}
int64_t num;
error = doc["number"].get_int64().get(num);
if (error || num != 42) {
std::cerr << "DOM number lookup failed" << std::endl;
return EXIT_FAILURE;
}
std::cout << "DOM-only test passed." << std::endl;
return EXIT_SUCCESS;
}
@@ -0,0 +1,25 @@
// Test: OnDemand API only (Builder disabled)
// Note: DOM must remain enabled because the builtin infrastructure
// (SIMDJSON_BUILTIN_IMPLEMENTATION_IS) is currently included via the DOM path.
// Feature flags set via target_compile_definitions in CMakeLists.txt
#include "simdjson.h"
#include <iostream>
int main() {
simdjson::ondemand::parser parser;
auto json = R"({"key": "value", "number": 42})"_padded;
simdjson::ondemand::document doc;
auto error = parser.iterate(json).get(doc);
if (error) {
std::cerr << "OnDemand parse error: " << error << std::endl;
return EXIT_FAILURE;
}
std::string_view val;
error = doc["key"].get_string().get(val);
if (error || val != "value") {
std::cerr << "OnDemand key lookup failed" << std::endl;
return EXIT_FAILURE;
}
std::cout << "OnDemand-only test passed." << std::endl;
return EXIT_SUCCESS;
}