mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
new feature tests, etc.
This commit is contained in:
+10
-4
@@ -54,11 +54,17 @@ 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)
|
||||
|
||||
add_compile_definitions(
|
||||
SIMDJSON_FEATURE_ONDEMAND_API=$<BOOL:${SIMDJSON_FEATURE_ONDEMAND_API}>
|
||||
SIMDJSON_FEATURE_DOM_API=$<BOOL:${SIMDJSON_FEATURE_DOM_API}>
|
||||
)
|
||||
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")
|
||||
option(SIMDJSON_STATIC_REFLECTION "Enables static reflection (experimental), requires C++26" OFF)
|
||||
|
||||
+5
-2
@@ -34,11 +34,13 @@ By default the library is built in Release mode.
|
||||
|
||||
## Optional APIs (Feature Flags)
|
||||
|
||||
simdjson provides two APIs:
|
||||
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
|
||||
|
||||
@@ -46,7 +48,8 @@ Using CMake:
|
||||
|
||||
```bash
|
||||
cmake -DSIMDJSON_FEATURE_DOM_API=OFF \
|
||||
-DSIMDJSON_FEATURE_ONDEMAND_API=ON ..
|
||||
-DSIMDJSON_FEATURE_ONDEMAND_API=ON \
|
||||
-DSIMDJSON_FEATURE_BUILDER_API=OFF ..
|
||||
|
||||
Assertions and development checks
|
||||
------------------------------
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "simdjson/error.h"
|
||||
#include "simdjson/error-inl.h"
|
||||
#include "simdjson/implementation.h"
|
||||
#include "simdjson/builtin.h"
|
||||
#include "simdjson/minify.h"
|
||||
#include "simdjson/padded_string.h"
|
||||
#include "simdjson/padded_string-inl.h"
|
||||
@@ -54,7 +55,9 @@
|
||||
|
||||
#if SIMDJSON_FEATURE_DOM_API
|
||||
#include "simdjson/dom.h"
|
||||
#if SIMDJSON_FEATURE_BUILDER_API
|
||||
#include "simdjson/builder.h"
|
||||
#endif // SIMDJSON_FEATURE_BUILDER_API
|
||||
#endif // SIMDJSON_FEATURE_DOM_API
|
||||
|
||||
#if SIMDJSON_FEATURE_ONDEMAND_API
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
#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,8 +1,10 @@
|
||||
#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_BUILDER_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
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
// Internal headers needed for ondemand generics.
|
||||
// All includes not under simdjson/generic/ondemand must be here!
|
||||
// Otherwise, amalgamation will fail.
|
||||
#include "simdjson/feature_macros.h"
|
||||
#include "simdjson/dom/base.h" // for MINIMAL_DOCUMENT_CAPACITY
|
||||
#include "simdjson/implementation.h"
|
||||
#include "simdjson/padded_string.h"
|
||||
|
||||
@@ -8,12 +8,14 @@ namespace simdjson {
|
||||
* @copydoc simdjson::builtin::ondemand
|
||||
*/
|
||||
namespace ondemand = builtin::ondemand;
|
||||
#if SIMDJSON_FEATURE_BUILDER_API
|
||||
/**
|
||||
* @copydoc simdjson::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.
|
||||
* Only available when SIMDJSON_STATIC_REFLECTION is enabled.
|
||||
|
||||
Executable
+226
@@ -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()
|
||||
@@ -268,7 +268,21 @@ class SimdjsonFile:
|
||||
print(f" Adding include: {self} includes {include}")
|
||||
if self.is_conditional_include:
|
||||
# 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)
|
||||
# if include.amalgamator_file:
|
||||
# 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"
|
||||
|
||||
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:
|
||||
for line in fid2:
|
||||
for line_number, line in enumerate(fid2, 1):
|
||||
line = line.rstrip('\n')
|
||||
|
||||
# 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 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
|
||||
editor_only_start_line = line_number
|
||||
|
||||
# Handle ignored lines (and ending ignore blocks)
|
||||
end_ignore = endif_conditional_re.search(line)
|
||||
@@ -453,6 +470,12 @@ class Amalgamator:
|
||||
file.add_editor_only_include(included_file)
|
||||
if end_ignore:
|
||||
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
|
||||
|
||||
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)
|
||||
|
||||
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)} */")
|
||||
|
||||
|
||||
+2121
-2010
File diff suppressed because it is too large
Load Diff
+8515
-8257
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -2,6 +2,7 @@
|
||||
#define SIMDJSON_SRC_ARM64_CPP
|
||||
|
||||
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||
#include "simdjson/feature_macros.h"
|
||||
#include <base.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
#if SIMDJSON_FEATURE_DOM_API
|
||||
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
|
||||
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 {
|
||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||
}
|
||||
#endif // SIMDJSON_FEATURE_DOM_API
|
||||
|
||||
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 {
|
||||
@@ -159,11 +162,13 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
|
||||
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 {
|
||||
auto error = stage1(_buf, _len, stage1_mode::regular);
|
||||
if (error) { return error; }
|
||||
return stage2(_doc);
|
||||
}
|
||||
#endif // SIMDJSON_FEATURE_DOM_API
|
||||
|
||||
} // namespace arm64
|
||||
} // namespace simdjson
|
||||
|
||||
+1
-2
@@ -1,9 +1,8 @@
|
||||
#ifndef SIMDJSON_SRC_FALLBACK_CPP
|
||||
#define SIMDJSON_SRC_FALLBACK_CPP
|
||||
|
||||
#include "simdjson/feature_macros.h"
|
||||
|
||||
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||
#include "simdjson/feature_macros.h"
|
||||
#include <base.h>
|
||||
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef SIMDJSON_SRC_GENERIC_DEPENDENCIES_H
|
||||
#define SIMDJSON_SRC_GENERIC_DEPENDENCIES_H
|
||||
|
||||
#include "simdjson/feature_macros.h"
|
||||
#include <base.h>
|
||||
|
||||
#endif // SIMDJSON_SRC_GENERIC_DEPENDENCIES_H
|
||||
+1
-2
@@ -1,9 +1,8 @@
|
||||
#ifndef SIMDJSON_SRC_HASWELL_CPP
|
||||
#define SIMDJSON_SRC_HASWELL_CPP
|
||||
|
||||
#include "simdjson/feature_macros.h"
|
||||
|
||||
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||
#include "simdjson/feature_macros.h"
|
||||
#include <base.h>
|
||||
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||
|
||||
|
||||
+1
-2
@@ -1,9 +1,8 @@
|
||||
#ifndef SIMDJSON_SRC_ICELAKE_CPP
|
||||
#define SIMDJSON_SRC_ICELAKE_CPP
|
||||
|
||||
#include "simdjson/feature_macros.h"
|
||||
|
||||
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||
#include "simdjson/feature_macros.h"
|
||||
#include <base.h>
|
||||
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define SIMDJSON_SRC_LASX_CPP
|
||||
|
||||
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||
#include "simdjson/feature_macros.h"
|
||||
#include <base.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
#if SIMDJSON_FEATURE_DOM_API
|
||||
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
|
||||
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 {
|
||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||
}
|
||||
#endif // SIMDJSON_FEATURE_DOM_API
|
||||
|
||||
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 {
|
||||
@@ -119,11 +122,13 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
|
||||
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 {
|
||||
auto error = stage1(_buf, _len, stage1_mode::regular);
|
||||
if (error) { return error; }
|
||||
return stage2(_doc);
|
||||
}
|
||||
#endif // SIMDJSON_FEATURE_DOM_API
|
||||
|
||||
} // namespace lasx
|
||||
} // namespace simdjson
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define SIMDJSON_SRC_LSX_CPP
|
||||
|
||||
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||
#include "simdjson/feature_macros.h"
|
||||
#include <base.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
#if SIMDJSON_FEATURE_DOM_API
|
||||
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
|
||||
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 {
|
||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||
}
|
||||
#endif // SIMDJSON_FEATURE_DOM_API
|
||||
|
||||
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 {
|
||||
@@ -123,11 +126,13 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
|
||||
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 {
|
||||
auto error = stage1(_buf, _len, stage1_mode::regular);
|
||||
if (error) { return error; }
|
||||
return stage2(_doc);
|
||||
}
|
||||
#endif // SIMDJSON_FEATURE_DOM_API
|
||||
|
||||
} // namespace lsx
|
||||
} // namespace simdjson
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define SIMDJSON_SRC_PPC64_CPP
|
||||
|
||||
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||
#include "simdjson/feature_macros.h"
|
||||
#include <base.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
#if SIMDJSON_FEATURE_DOM_API
|
||||
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
|
||||
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 {
|
||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||
}
|
||||
#endif // SIMDJSON_FEATURE_DOM_API
|
||||
|
||||
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 {
|
||||
@@ -129,11 +132,13 @@ simdjson_warn_unused uint8_t *dom_parser_implementation::parse_wobbly_string(con
|
||||
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 {
|
||||
auto error = stage1(_buf, _len, stage1_mode::regular);
|
||||
if (error) { return error; }
|
||||
return stage2(_doc);
|
||||
}
|
||||
#endif // SIMDJSON_FEATURE_DOM_API
|
||||
|
||||
} // namespace ppc64
|
||||
} // namespace simdjson
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define SIMDJSON_SRC_RVV_VLS_CPP
|
||||
|
||||
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||
#include "simdjson/feature_macros.h"
|
||||
#include <base.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
#if SIMDJSON_FEATURE_DOM_API
|
||||
simdjson_warn_unused error_code dom_parser_implementation::stage2(dom::document &_doc) noexcept {
|
||||
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 {
|
||||
return stage2::tape_builder::parse_document<true>(*this, _doc);
|
||||
}
|
||||
#endif // SIMDJSON_FEATURE_DOM_API
|
||||
|
||||
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 {
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
#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 {
|
||||
auto error = stage1(_buf, _len, stage1_mode::regular);
|
||||
if (error) { return error; }
|
||||
return stage2(_doc);
|
||||
}
|
||||
#endif // SIMDJSON_FEATURE_DOM_API
|
||||
|
||||
} // namespace rvv_vls
|
||||
} // namespace simdjson
|
||||
|
||||
+1
-2
@@ -1,9 +1,8 @@
|
||||
#ifndef SIMDJSON_SRC_WESTMERE_CPP
|
||||
#define SIMDJSON_SRC_WESTMERE_CPP
|
||||
|
||||
#include "simdjson/feature_macros.h"
|
||||
|
||||
#ifndef SIMDJSON_CONDITIONAL_INCLUDE
|
||||
#include "simdjson/feature_macros.h"
|
||||
#include <base.h>
|
||||
#endif // SIMDJSON_CONDITIONAL_INCLUDE
|
||||
|
||||
|
||||
@@ -29,4 +29,5 @@ add_cpp_test(checkimplementation LABELS other per_implementation)
|
||||
|
||||
add_subdirectory(compilation_failure_tests)
|
||||
add_subdirectory(builder)
|
||||
add_subdirectory(compile_time)
|
||||
add_subdirectory(compile_time)
|
||||
add_subdirectory(feature_flag_tests)
|
||||
@@ -1,5 +1,8 @@
|
||||
# All remaining tests link with simdjson proper
|
||||
include_directories(..)
|
||||
if(NOT SIMDJSON_FEATURE_BUILDER_API)
|
||||
return()
|
||||
endif()
|
||||
add_cpp_test(builder_string_builder_tests LABELS ondemand acceptance per_implementation)
|
||||
if(SIMDJSON_STATIC_REFLECTION)
|
||||
add_cpp_test(static_reflection_custom_tests LABELS ondemand acceptance per_implementation)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user