Merge pull request #693 from simdjson/jkeiser/cmake-quickstartcpp
Add C++11 tests to cmake
This commit is contained in:
commit
7480b87e07
|
@ -20,10 +20,11 @@ build_script:
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- cmake -DSIMDJSON_BUILD_STATIC=%SIMDJSON_BUILD_STATIC% -DSIMDJSON_ENABLE_THREADS=%SIMDJSON_ENABLE_THREADS% -DCMAKE_BUILD_TYPE=%Configuration% -DCMAKE_GENERATOR_PLATFORM=x64 -DSIMDJSON_GOOGLE_BENCHMARKS=OFF ..
|
- cmake -DSIMDJSON_BUILD_STATIC=%SIMDJSON_BUILD_STATIC% -DSIMDJSON_ENABLE_THREADS=%SIMDJSON_ENABLE_THREADS% -DCMAKE_BUILD_TYPE=%Configuration% -DCMAKE_GENERATOR_PLATFORM=x64 -DSIMDJSON_GOOGLE_BENCHMARKS=OFF ..
|
||||||
- cmake --build . --config %Configuration%
|
- cmake -LH ..
|
||||||
|
- cmake --build . --config %Configuration% --verbose
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
- ctest --verbose --output-on-failure -C %Configuration%
|
- ctest --output-on-failure -C %Configuration% --verbose
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
|
|
@ -87,6 +87,7 @@ objs
|
||||||
/examples/quickstart/twitter.json
|
/examples/quickstart/twitter.json
|
||||||
/fuzz/fuzz_dump
|
/fuzz/fuzz_dump
|
||||||
/fuzz/fuzz_dump_raw_tape
|
/fuzz/fuzz_dump_raw_tape
|
||||||
|
/fuzz/fuzz_minify
|
||||||
/fuzz/fuzz_parser
|
/fuzz/fuzz_parser
|
||||||
/fuzz/fuzz_print_json
|
/fuzz/fuzz_print_json
|
||||||
/get_corpus_benchmark
|
/get_corpus_benchmark
|
||||||
|
|
121
CMakeLists.txt
121
CMakeLists.txt
|
@ -12,20 +12,6 @@ project(simdjson
|
||||||
LANGUAGES CXX C
|
LANGUAGES CXX C
|
||||||
)
|
)
|
||||||
|
|
||||||
# LTO seems to create all sorts of fun problems. Let us
|
|
||||||
# disable temporarily.
|
|
||||||
#include(CheckIPOSupported)
|
|
||||||
#check_ipo_supported(RESULT ltoresult)
|
|
||||||
#if(ltoresult)
|
|
||||||
# set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
|
||||||
#endif()
|
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
||||||
set(CMAKE_MACOSX_RPATH OFF)
|
|
||||||
set(CMAKE_THREAD_PREFER_PTHREAD ON)
|
|
||||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
|
||||||
|
|
||||||
set(PROJECT_VERSION_MAJOR 0)
|
set(PROJECT_VERSION_MAJOR 0)
|
||||||
set(PROJECT_VERSION_MINOR 3)
|
set(PROJECT_VERSION_MINOR 3)
|
||||||
set(PROJECT_VERSION_PATCH 1)
|
set(PROJECT_VERSION_PATCH 1)
|
||||||
|
@ -35,7 +21,7 @@ set(SIMDJSON_LIB_SOVERSION "1" CACHE STRING "simdjson library soversion")
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
option(SIMDJSON_BUILD_STATIC "Build a static library" ON) # turning it on disables the production of a dynamic library
|
option(SIMDJSON_BUILD_STATIC "Build a static library" ON) # turning it on disables the production of a dynamic library
|
||||||
option(SIMDJSON_COMPETITION "Compile competitive benchmarks" OFF)
|
option(SIMDJSON_COMPETITION "Compile competitive benchmarks" OFF)
|
||||||
else()
|
else()
|
||||||
option(SIMDJSON_BUILD_STATIC "Build a static library" OFF) # turning it on disables the production of a dynamic library
|
option(SIMDJSON_BUILD_STATIC "Build a static library" OFF) # turning it on disables the production of a dynamic library
|
||||||
option(SIMDJSON_COMPETITION "Compile competitive benchmarks" ON)
|
option(SIMDJSON_COMPETITION "Compile competitive benchmarks" ON)
|
||||||
endif()
|
endif()
|
||||||
|
@ -43,11 +29,101 @@ option(SIMDJSON_GOOGLE_BENCHMARKS "compile the Google Benchmark benchmarks" OFF)
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake")
|
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake")
|
||||||
|
|
||||||
|
# We compile tools, tests, etc. with C++ 17. Override yourself if you need on a target.
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
set(CMAKE_MACOSX_RPATH OFF)
|
||||||
|
set(CMAKE_THREAD_PREFER_PTHREAD ON)
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
|
|
||||||
|
# LTO seems to create all sorts of fun problems. Let us
|
||||||
|
# disable temporarily.
|
||||||
|
#include(CheckIPOSupported)
|
||||||
|
#check_ipo_supported(RESULT ltoresult)
|
||||||
|
#if(ltoresult)
|
||||||
|
# set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||||
|
#endif()
|
||||||
|
|
||||||
|
#
|
||||||
|
# Flags used by exes and by the simdjson library (project-wide flags)
|
||||||
|
#
|
||||||
|
add_library(simdjson-flags INTERFACE)
|
||||||
|
if(MSVC)
|
||||||
|
target_compile_options(simdjson-flags INTERFACE /nologo /D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
target_compile_options(simdjson-flags INTERFACE /W3 /wd4005 /wd4996 /wd4267 /wd4244 /wd4113)
|
||||||
|
else()
|
||||||
|
target_compile_options(simdjson-flags INTERFACE -fPIC)
|
||||||
|
target_compile_options(simdjson-flags INTERFACE -Wall -Wextra -Wsign-compare -Wshadow -Wwrite-strings -Wpointer-arith -Winit-self)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Optional flags
|
||||||
|
option(SIMDJSON_IMPLEMENTATION_HASWELL "Include the haswell implementation" ON)
|
||||||
|
if(NOT SIMDJSON_IMPLEMENTATION_HASWELL)
|
||||||
|
target_compile_definitions(simdjson-flags INTERFACE SIMDJSON_IMPLEMENTATION_HASWELL=0)
|
||||||
|
endif()
|
||||||
|
option(SIMDJSON_IMPLEMENTATION_WESTMERE "Include the westmere implementation" ON)
|
||||||
|
if(NOT SIMDJSON_IMPLEMENTATION_WESTMERE)
|
||||||
|
target_compile_definitions(simdjson-flags INTERFACE SIMDJSON_IMPLEMENTATION_WESTMERE=0)
|
||||||
|
endif()
|
||||||
|
option(SIMDJSON_IMPLEMENTATION_ARM64 "Include the arm64 implementation" ON)
|
||||||
|
if(NOT SIMDJSON_IMPLEMENTATION_ARM64)
|
||||||
|
target_compile_definitions(simdjson-flags INTERFACE SIMDJSON_IMPLEMENTATION_ARM64=0)
|
||||||
|
endif()
|
||||||
|
option(SIMDJSON_IMPLEMENTATION_FALLBACK "Include the fallback implementation" ON)
|
||||||
|
if(NOT SIMDJSON_IMPLEMENTATION_FALLBACK)
|
||||||
|
target_compile_definitions(simdjson-flags INTERFACE SIMDJSON_IMPLEMENTATION_FALLBACK=0)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(SIMDJSON_EXCEPTIONS "Enable simdjson's exception-throwing interface" ON)
|
||||||
|
if(NOT SIMDJSON_EXCEPTIONS)
|
||||||
|
message(STATUS "simdjson exception interface turned off. Code that does not check error codes will not compile.")
|
||||||
|
target_compile_definitions(simdjson-flags INTERFACE SIMDJSON_EXCEPTIONS=0)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(SIMDJSON_ENABLE_THREADS "Enable threaded operation" ON)
|
||||||
|
if(SIMDJSON_ENABLE_THREADS)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
target_link_libraries(simdjson-flags INTERFACE Threads::Threads)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
option(SIMDJSON_SANITIZE "Sanitize addresses" OFF)
|
||||||
|
if(SIMDJSON_SANITIZE)
|
||||||
|
# Not sure which
|
||||||
|
target_compile_options(simdjson-flags INTERFACE -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all)
|
||||||
|
target_link_libraries(simdjson-flags INTERFACE -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all)
|
||||||
|
|
||||||
|
# Ubuntu bug for GCC 5.0+ (safe for all versions)
|
||||||
|
if (CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
target_link_libraries(simdjson-flags INTERFACE -fuse-ld=gold)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# prevent shared libraries from depending on Intel provided libraries
|
||||||
|
if(${CMAKE_C_COMPILER_ID} MATCHES "Intel") # icc / icpc
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-intel")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Workaround for https://gitlab.kitware.com/cmake/cmake/issues/15415#note_633938:
|
||||||
|
function(export_private_library NAME)
|
||||||
|
install(TARGETS ${NAME}
|
||||||
|
EXPORT ${NAME}-config
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
)
|
||||||
|
install(EXPORT ${NAME}-config
|
||||||
|
FILE ${NAME}-config.cmake
|
||||||
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/simdjson-private
|
||||||
|
)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
export_private_library(simdjson-flags)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Create the top level simdjson library (must be done at this level to use both src/ and include/
|
# Create the top level simdjson library (must be done at this level to use both src/ and include/
|
||||||
# directories)
|
# directories)
|
||||||
#
|
#
|
||||||
add_subdirectory(windows)
|
|
||||||
add_subdirectory(include)
|
add_subdirectory(include)
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
||||||
|
@ -60,10 +136,11 @@ add_library(test-data INTERFACE)
|
||||||
target_compile_definitions(test-data INTERFACE SIMDJSON_TEST_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/jsonchecker/")
|
target_compile_definitions(test-data INTERFACE SIMDJSON_TEST_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/jsonchecker/")
|
||||||
target_compile_definitions(test-data INTERFACE SIMDJSON_BENCHMARK_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/jsonexamples/")
|
target_compile_definitions(test-data INTERFACE SIMDJSON_BENCHMARK_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/jsonexamples/")
|
||||||
|
|
||||||
|
add_subdirectory(windows)
|
||||||
add_subdirectory(dependencies)
|
add_subdirectory(dependencies)
|
||||||
add_subdirectory(tools)
|
|
||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
add_subdirectory(examples)
|
add_subdirectory(examples)
|
||||||
|
add_subdirectory(tools)
|
||||||
add_subdirectory(benchmark)
|
add_subdirectory(benchmark)
|
||||||
|
|
||||||
# for fuzzing, read the comments in the fuzz/CMakeLists.txt file
|
# for fuzzing, read the comments in the fuzz/CMakeLists.txt file
|
||||||
|
@ -72,11 +149,9 @@ if(ENABLE_FUZZING)
|
||||||
add_subdirectory(fuzz)
|
add_subdirectory(fuzz)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(${CMAKE_C_COMPILER_ID} MATCHES "Intel") # icc / icpc
|
#
|
||||||
# prevent shared libraries from depending on Intel provided libraries
|
# CPack
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-intel")
|
#
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CPACK_PACKAGE_VENDOR "Daniel Lemire")
|
set(CPACK_PACKAGE_VENDOR "Daniel Lemire")
|
||||||
set(CPACK_PACKAGE_CONTACT "lemire@gmail.com")
|
set(CPACK_PACKAGE_CONTACT "lemire@gmail.com")
|
||||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Parsing gigabytes of JSON per second")
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Parsing gigabytes of JSON per second")
|
||||||
|
@ -91,5 +166,3 @@ set(CPACK_RPM_PACKAGE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
||||||
set(CPACK_SOURCE_GENERATOR "TGZ;ZIP")
|
set(CPACK_SOURCE_GENERATOR "TGZ;ZIP")
|
||||||
|
|
||||||
include(CPack)
|
include(CPack)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,10 @@ simdjson's source structure, from the top level, looks like this:
|
||||||
compiled multiple times, from whichever architectures use them. They assume they are already
|
compiled multiple times, from whichever architectures use them. They assume they are already
|
||||||
enclosed in a namespace, e.g.:
|
enclosed in a namespace, e.g.:
|
||||||
```c++
|
```c++
|
||||||
namespace simdjson::haswell {
|
namespace simdjson {
|
||||||
#include "generic/stage1_find_marks.h"
|
namespace haswell {
|
||||||
|
#include "generic/stage1_find_marks.h"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
include_directories( . linux )
|
include_directories( . linux )
|
||||||
link_libraries(simdjson)
|
link_libraries(simdjson simdjson-flags)
|
||||||
# add_executable(benchfeatures benchfeatures.cpp)
|
# add_executable(benchfeatures benchfeatures.cpp) # doesn't presently compile at all
|
||||||
add_executable(get_corpus_benchmark get_corpus_benchmark.cpp)
|
add_executable(get_corpus_benchmark get_corpus_benchmark.cpp)
|
||||||
add_executable(perfdiff perfdiff.cpp)
|
add_executable(perfdiff perfdiff.cpp)
|
||||||
add_executable(parse parse.cpp)
|
add_executable(parse parse.cpp)
|
||||||
|
|
|
@ -1,6 +1,57 @@
|
||||||
if(SIMDJSON_EXCEPTIONS)
|
#
|
||||||
add_executable(quickstart quickstart.cpp)
|
# Quickstart compile tests don't require any flags
|
||||||
target_link_libraries(quickstart PRIVATE simdjson)
|
#
|
||||||
|
|
||||||
|
# TODO haven't quite decided the right way to run quickstart on Windows. Needs README update.
|
||||||
|
if (NOT MSVC)
|
||||||
|
# TODO run amalgamate first!
|
||||||
|
function(add_quickstart_test TEST_NAME SOURCE_FILE)
|
||||||
|
# Second argument is C++ standard name
|
||||||
|
if (MSVC)
|
||||||
|
if (${ARGV2})
|
||||||
|
set(QUICKSTART_FLAGS /std:${ARGV2})
|
||||||
|
else()
|
||||||
|
set(QUICKSTART_FLAGS /WX)
|
||||||
|
endif()
|
||||||
|
set(QUICKSTART_INCLUDE /I${PROJECT_SOURCE_DIR}/include /I${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/src/simdjson.cpp)
|
||||||
|
else()
|
||||||
|
if (${ARGV2})
|
||||||
|
set(QUICKSTART_FLAGS -Werror -std=${ARGV2})
|
||||||
|
else()
|
||||||
|
set(QUICKSTART_FLAGS -Werror)
|
||||||
|
endif()
|
||||||
|
set(QUICKSTART_INCLUDE -I${PROJECT_SOURCE_DIR}/include -I${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/src/simdjson.cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Third argument tells whether to compile with -fno-exceptions
|
||||||
|
if (${ARGV3})
|
||||||
|
if (NOT MSVC)
|
||||||
|
set(QUICKSTART_FLAGS ${QUICKSTART_FLAGS} -fno-exceptions)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS ${TEST_NAME})
|
||||||
|
add_test(
|
||||||
|
NAME ${TEST_NAME}
|
||||||
|
COMMAND ${CMAKE_CXX_COMPILER} ${QUICKSTART_FLAGS} -I${PROJECT_SOURCE_DIR}/include -I${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/src/simdjson.cpp ${SOURCE_FILE}
|
||||||
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/examples/quickstart
|
||||||
|
)
|
||||||
|
set_property(
|
||||||
|
TEST ${TEST_NAME}
|
||||||
|
APPEND PROPERTY DEPENDS simdjson-source ${PROJECT_SOURCE_DIR}/examples/quickstart/${SOURCE_FILE}
|
||||||
|
)
|
||||||
|
endfunction(add_quickstart_test)
|
||||||
|
|
||||||
|
if (SIMDJSON_EXCEPTIONS)
|
||||||
|
add_quickstart_test(quickstart quickstart.cpp)
|
||||||
|
add_quickstart_test(quickstart11 quickstart.cpp c++11)
|
||||||
|
add_quickstart_test(quickstart14 quickstart.cpp c++14)
|
||||||
|
set_property( TEST quickstart quickstart11 APPEND PROPERTY LABELS quicktests )
|
||||||
|
set_property( TEST quickstart14 APPEND PROPERTY LABELS slowtests )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_quickstart_test(quickstart_noexceptions quickstart_noexceptions.cpp "" true)
|
||||||
|
add_quickstart_test(quickstart_noexceptions11 quickstart_noexceptions.cpp c++11 true)
|
||||||
|
set_property( TEST quickstart_noexceptions APPEND PROPERTY LABELS quicktests )
|
||||||
|
set_property( TEST quickstart_noexceptions11 APPEND PROPERTY LABELS slowtests )
|
||||||
endif()
|
endif()
|
||||||
add_executable(quickstart_noexceptions quickstart_noexceptions.cpp)
|
|
||||||
target_link_libraries(quickstart_noexceptions PRIVATE simdjson)
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ macro(implement_fuzzer sourcefile)
|
||||||
if (SIMDJSON_FUZZ_LINKMAIN)
|
if (SIMDJSON_FUZZ_LINKMAIN)
|
||||||
target_sources(${name} PRIVATE main.cpp)
|
target_sources(${name} PRIVATE main.cpp)
|
||||||
endif ()
|
endif ()
|
||||||
target_link_libraries(${name} PRIVATE simdjson)
|
target_link_libraries(${name} PRIVATE simdjson simdjson-flags)
|
||||||
if (SIMDJSON_FUZZ_LDFLAGS)
|
if (SIMDJSON_FUZZ_LDFLAGS)
|
||||||
target_link_libraries(${name} PRIVATE ${SIMDJSON_FUZZ_LDFLAGS})
|
target_link_libraries(${name} PRIVATE ${SIMDJSON_FUZZ_LDFLAGS})
|
||||||
endif ()
|
endif ()
|
||||||
|
|
|
@ -1,68 +1,12 @@
|
||||||
#
|
#
|
||||||
# simdjson headers and flags required to compile them
|
# Provides the simdjson headers.
|
||||||
|
#
|
||||||
|
# target_link_libraries(my-project simdjson-headers) grants the headers. It does not provide the
|
||||||
|
# source, libraries or any compiler flags.
|
||||||
#
|
#
|
||||||
|
|
||||||
add_library(simdjson-headers INTERFACE)
|
add_library(simdjson-headers INTERFACE)
|
||||||
|
target_compile_features(simdjson-headers INTERFACE cxx_std_11) # headers require at least C++11
|
||||||
# Include directory
|
target_include_directories(simdjson-headers INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
|
||||||
target_include_directories(simdjson-headers INTERFACE
|
|
||||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
|
|
||||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
|
||||||
|
|
||||||
# Flags absolutely needed to compile simdjson at all
|
|
||||||
target_compile_features(simdjson-headers INTERFACE cxx_std_17)
|
|
||||||
if(MSVC) # Windows
|
|
||||||
# C++ standard flags
|
|
||||||
target_compile_options(simdjson-headers INTERFACE /std:c++17)
|
|
||||||
# Base flags
|
|
||||||
target_compile_options(simdjson-headers INTERFACE /nologo)
|
|
||||||
# Warning flags
|
|
||||||
target_compile_options(simdjson-headers INTERFACE /W3 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /wd4267 /wd4244 /wd4113)
|
|
||||||
else() # Linux
|
|
||||||
# Base flags
|
|
||||||
target_compile_options(simdjson-headers INTERFACE -fPIC)
|
|
||||||
# C++ standard flags
|
|
||||||
target_compile_options(simdjson-headers INTERFACE -std=c++17)
|
|
||||||
# Warning flags
|
|
||||||
target_compile_options(simdjson-headers INTERFACE -Wall -Wextra -Wsign-compare -Wshadow -Wwrite-strings -Wpointer-arith -Winit-self)
|
|
||||||
# Debug and release specific flags
|
|
||||||
target_compile_options(simdjson-headers INTERFACE $<$<CONFIG:DEBUG>:-ggdb>)
|
|
||||||
target_compile_options(simdjson-headers INTERFACE $<$<CONFIG:RELEASE>:-O3 -DNDEBUG>)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
# Optional flags
|
|
||||||
option(SIMDJSON_IMPLEMENTATION_HASWELL "Include the haswell implementation" ON)
|
|
||||||
option(SIMDJSON_IMPLEMENTATION_WESTMERE "Include the westmere implementation" ON)
|
|
||||||
option(SIMDJSON_IMPLEMENTATION_ARM64 "Include the arm64 implementation" ON)
|
|
||||||
option(SIMDJSON_IMPLEMENTATION_FALLBACK "Include the fallback implementation" ON)
|
|
||||||
|
|
||||||
option(SIMDJSON_EXCEPTIONS "Enable simdjson's exception-throwing interface" ON)
|
|
||||||
if(NOT SIMDJSON_EXCEPTIONS)
|
|
||||||
message(STATUS "simdjson exception interface turned off. Code that does not check error codes will not compile.")
|
|
||||||
target_compile_definitions(simdjson-headers INTERFACE SIMDJSON_EXCEPTIONS=0)
|
|
||||||
if(UNIX)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions")
|
|
||||||
endif(UNIX)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(SIMDJSON_ENABLE_THREADS "Enable threaded operation" ON)
|
|
||||||
if(SIMDJSON_ENABLE_THREADS)
|
|
||||||
find_package(Threads REQUIRED)
|
|
||||||
target_link_libraries(simdjson-headers INTERFACE Threads::Threads)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(SIMDJSON_SANITIZE "Sanitize addresses" OFF)
|
|
||||||
if(SIMDJSON_SANITIZE)
|
|
||||||
# Not sure which
|
|
||||||
target_compile_options(simdjson-headers INTERFACE -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all)
|
|
||||||
target_link_libraries(simdjson-headers INTERFACE -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined -fno-sanitize-recover=all)
|
|
||||||
|
|
||||||
# Ubuntu bug for GCC 5.0+ (safe for all versions)
|
|
||||||
if (CMAKE_COMPILER_IS_GNUCC)
|
|
||||||
target_link_libraries(simdjson-headers INTERFACE -fuse-ld=gold)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
install(TARGETS simdjson-headers
|
install(TARGETS simdjson-headers
|
||||||
EXPORT simdjson-headers-config
|
EXPORT simdjson-headers-config
|
||||||
|
|
|
@ -17,12 +17,12 @@
|
||||||
#include "simdjson/document.h"
|
#include "simdjson/document.h"
|
||||||
#include "simdjson/document_stream.h"
|
#include "simdjson/document_stream.h"
|
||||||
|
|
||||||
// Deprecated API
|
// // Deprecated API
|
||||||
#include "simdjson/jsonparser.h"
|
#include "simdjson/jsonparser.h"
|
||||||
#include "simdjson/parsedjson.h"
|
#include "simdjson/parsedjson.h"
|
||||||
#include "simdjson/parsedjson_iterator.h"
|
#include "simdjson/parsedjson_iterator.h"
|
||||||
|
|
||||||
// Inline functions
|
// // Inline functions
|
||||||
#include "simdjson/inline/document.h"
|
#include "simdjson/inline/document.h"
|
||||||
#include "simdjson/inline/document_stream.h"
|
#include "simdjson/inline/document_stream.h"
|
||||||
#include "simdjson/inline/error.h"
|
#include "simdjson/inline/error.h"
|
||||||
|
|
|
@ -108,7 +108,8 @@ constexpr size_t DEFAULT_MAX_DEPTH = 1024;
|
||||||
SIMDJSON_DISABLE_GCC_WARNING(-Wextra) \
|
SIMDJSON_DISABLE_GCC_WARNING(-Wextra) \
|
||||||
SIMDJSON_DISABLE_GCC_WARNING(-Wshadow) \
|
SIMDJSON_DISABLE_GCC_WARNING(-Wshadow) \
|
||||||
SIMDJSON_DISABLE_GCC_WARNING(-Wunused-parameter) \
|
SIMDJSON_DISABLE_GCC_WARNING(-Wunused-parameter) \
|
||||||
SIMDJSON_DISABLE_GCC_WARNING(-Wimplicit-fallthrough)
|
SIMDJSON_DISABLE_GCC_WARNING(-Wimplicit-fallthrough) \
|
||||||
|
SIMDJSON_DISABLE_GCC_WARNING(-Wreturn-type)
|
||||||
#define SIMDJSON_PRAGMA(P) _Pragma(#P)
|
#define SIMDJSON_PRAGMA(P) _Pragma(#P)
|
||||||
#define SIMDJSON_DISABLE_GCC_WARNING(WARNING) SIMDJSON_PRAGMA(GCC diagnostic ignored #WARNING)
|
#define SIMDJSON_DISABLE_GCC_WARNING(WARNING) SIMDJSON_PRAGMA(GCC diagnostic ignored #WARNING)
|
||||||
#define SIMDJSON_DISABLE_DEPRECATED_WARNING SIMDJSON_DISABLE_GCC_WARNING(-Wdeprecated-declarations)
|
#define SIMDJSON_DISABLE_DEPRECATED_WARNING SIMDJSON_DISABLE_GCC_WARNING(-Wdeprecated-declarations)
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
#include "simdjson/simdjson.h"
|
#include "simdjson/simdjson.h"
|
||||||
#include "simdjson/padded_string.h"
|
#include "simdjson/padded_string.h"
|
||||||
|
|
||||||
namespace simdjson::dom {
|
namespace simdjson {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
class parser;
|
class parser;
|
||||||
class element;
|
class element;
|
||||||
|
@ -23,9 +24,7 @@ class document_stream;
|
||||||
/** The default batch size for parser.parse_many() and parser.load_many() */
|
/** The default batch size for parser.parse_many() and parser.load_many() */
|
||||||
static constexpr size_t DEFAULT_BATCH_SIZE = 1000000;
|
static constexpr size_t DEFAULT_BATCH_SIZE = 1000000;
|
||||||
|
|
||||||
} // namespace simdjson::dom
|
} // namespace dom
|
||||||
|
|
||||||
namespace simdjson {
|
|
||||||
|
|
||||||
template<> struct simdjson_result<dom::element>;
|
template<> struct simdjson_result<dom::element>;
|
||||||
template<> struct simdjson_result<dom::array>;
|
template<> struct simdjson_result<dom::array>;
|
||||||
|
@ -34,9 +33,7 @@ template<> struct simdjson_result<dom::object>;
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class minify;
|
class minify;
|
||||||
|
|
||||||
} // namespace simdjson
|
namespace internal {
|
||||||
|
|
||||||
namespace simdjson::internal {
|
|
||||||
|
|
||||||
using namespace simdjson::dom;
|
using namespace simdjson::dom;
|
||||||
|
|
||||||
|
@ -90,9 +87,9 @@ public:
|
||||||
size_t json_index;
|
size_t json_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace simdjson::internal
|
} // namespace internal
|
||||||
|
|
||||||
namespace simdjson::dom {
|
namespace dom {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The actual concrete type of a JSON element
|
* The actual concrete type of a JSON element
|
||||||
|
@ -1087,7 +1084,8 @@ private:
|
||||||
friend class document_stream;
|
friend class document_stream;
|
||||||
}; // class parser
|
}; // class parser
|
||||||
|
|
||||||
} // namespace simdjson::dom
|
} // namespace dom
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include "simdjson/document.h"
|
#include "simdjson/document.h"
|
||||||
|
|
||||||
namespace simdjson::dom {
|
namespace simdjson {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A forward-only stream of documents.
|
* A forward-only stream of documents.
|
||||||
|
@ -140,6 +141,7 @@ private:
|
||||||
friend class dom::parser;
|
friend class dom::parser;
|
||||||
}; // class document_stream
|
}; // class document_stream
|
||||||
|
|
||||||
} // end of namespace simdjson::dom
|
} // namespace dom
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_DOCUMENT_STREAM_H
|
#endif // SIMDJSON_DOCUMENT_STREAM_H
|
||||||
|
|
|
@ -218,7 +218,7 @@ private:
|
||||||
std::atomic<T*> ptr;
|
std::atomic<T*> ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace [simdjson::]internal
|
} // namespace internal
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of available implementations compiled into simdjson.
|
* The list of available implementations compiled into simdjson.
|
||||||
|
|
|
@ -189,9 +189,8 @@ inline size_t simdjson_result<dom::object>::size() const noexcept(false) {
|
||||||
|
|
||||||
#endif // SIMDJSON_EXCEPTIONS
|
#endif // SIMDJSON_EXCEPTIONS
|
||||||
|
|
||||||
} // namespace simdjson
|
|
||||||
|
|
||||||
namespace simdjson::dom {
|
namespace dom {
|
||||||
|
|
||||||
//
|
//
|
||||||
// document inline implementation
|
// document inline implementation
|
||||||
|
@ -900,9 +899,8 @@ inline bool element::dump_raw_tape(std::ostream &out) const noexcept {
|
||||||
return doc->dump_raw_tape(out);
|
return doc->dump_raw_tape(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace simdjson::dom
|
} // namespace dom
|
||||||
|
|
||||||
namespace simdjson {
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// minify inline implementation
|
// minify inline implementation
|
||||||
|
@ -1082,9 +1080,8 @@ inline std::ostream& minify<simdjson_result<dom::object>>::print(std::ostream& o
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace simdjson
|
|
||||||
|
|
||||||
namespace simdjson::internal {
|
namespace internal {
|
||||||
|
|
||||||
//
|
//
|
||||||
// tape_ref inline implementation
|
// tape_ref inline implementation
|
||||||
|
@ -1151,7 +1148,7 @@ really_inline uint32_t internal::tape_ref::scope_count() const noexcept {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
really_inline T tape_ref::next_tape_value() const noexcept {
|
really_inline T tape_ref::next_tape_value() const noexcept {
|
||||||
static_assert(sizeof(T) == sizeof(uint64_t));
|
static_assert(sizeof(T) == sizeof(uint64_t), "next_tape_value() template parameter must be 64-bit");
|
||||||
// Though the following is tempting...
|
// Though the following is tempting...
|
||||||
// return *reinterpret_cast<const T*>(&doc->tape[json_index + 1]);
|
// return *reinterpret_cast<const T*>(&doc->tape[json_index + 1]);
|
||||||
// It is not generally safe. It is safer, and often faster to rely
|
// It is not generally safe. It is safer, and often faster to rely
|
||||||
|
@ -1170,7 +1167,7 @@ inline std::string_view internal::tape_ref::get_string_view() const noexcept {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
} // namespace simdjson::internal
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_INLINE_DOCUMENT_H
|
#endif // SIMDJSON_INLINE_DOCUMENT_H
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
namespace simdjson::internal {
|
namespace simdjson {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This algorithm is used to quickly identify the buffer position of
|
* This algorithm is used to quickly identify the buffer position of
|
||||||
|
@ -93,9 +94,12 @@ static inline size_t trimmed_length_safe_utf8(const char * c, size_t len) {
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace simdjson::internal
|
} // namespace internal
|
||||||
|
|
||||||
namespace simdjson::dom {
|
} // namespace simdjson
|
||||||
|
|
||||||
|
namespace simdjson {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
really_inline document_stream::document_stream(
|
really_inline document_stream::document_stream(
|
||||||
dom::parser &_parser,
|
dom::parser &_parser,
|
||||||
|
@ -272,5 +276,6 @@ inline error_code document_stream::json_parse() noexcept {
|
||||||
}
|
}
|
||||||
#endif // SIMDJSON_THREADS_ENABLED
|
#endif // SIMDJSON_THREADS_ENABLED
|
||||||
|
|
||||||
} // namespace simdjson::dom
|
} // namespace dom
|
||||||
|
} // namespace simdjson
|
||||||
#endif // SIMDJSON_INLINE_DOCUMENT_STREAM_H
|
#endif // SIMDJSON_INLINE_DOCUMENT_STREAM_H
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
#include "simdjson/error.h"
|
#include "simdjson/error.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace simdjson::internal {
|
namespace simdjson {
|
||||||
|
namespace internal {
|
||||||
// We store the error code so we can validate the error message is associated with the right code
|
// We store the error code so we can validate the error message is associated with the right code
|
||||||
struct error_code_info {
|
struct error_code_info {
|
||||||
error_code code;
|
error_code code;
|
||||||
|
@ -12,9 +13,8 @@ namespace simdjson::internal {
|
||||||
};
|
};
|
||||||
// These MUST match the codes in error_code. We check this constraint in basictests.
|
// These MUST match the codes in error_code. We check this constraint in basictests.
|
||||||
extern SIMDJSON_DLLIMPORTEXPORT const error_code_info error_codes[];
|
extern SIMDJSON_DLLIMPORTEXPORT const error_code_info error_codes[];
|
||||||
} // namespace simdjson::internal
|
} // namespace internal
|
||||||
|
|
||||||
namespace simdjson {
|
|
||||||
|
|
||||||
inline const char *error_message(error_code error) noexcept {
|
inline const char *error_message(error_code error) noexcept {
|
||||||
// If you're using error_code, we're trusting you got it from the enum.
|
// If you're using error_code, we're trusting you got it from the enum.
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace simdjson::internal {
|
namespace simdjson {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
// low-level function to allocate memory with padding so we can read past the
|
// low-level function to allocate memory with padding so we can read past the
|
||||||
// "length" bytes safely. if you must provide a pointer to some data, create it
|
// "length" bytes safely. if you must provide a pointer to some data, create it
|
||||||
|
@ -30,9 +31,8 @@ inline char *allocate_padded_buffer(size_t length) noexcept {
|
||||||
return padded_buffer;
|
return padded_buffer;
|
||||||
} // allocate_padded_buffer()
|
} // allocate_padded_buffer()
|
||||||
|
|
||||||
} // namespace simdjson::internal
|
} // namespace internal
|
||||||
|
|
||||||
namespace simdjson {
|
|
||||||
|
|
||||||
inline padded_string::padded_string() noexcept : viable_size(0), data_ptr(nullptr) {}
|
inline padded_string::padded_string() noexcept : viable_size(0), data_ptr(nullptr) {}
|
||||||
inline padded_string::padded_string(size_t length) noexcept
|
inline padded_string::padded_string(size_t length) noexcept
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace simdjson::internal {
|
namespace simdjson {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
class escape_json_string;
|
class escape_json_string;
|
||||||
|
|
||||||
|
@ -58,6 +59,7 @@ inline std::ostream& operator<<(std::ostream& out, const escape_json_string &une
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace simdjson::internal
|
} // namespace internal
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_INTERNAL_JSONFORMATUTILS_H
|
#endif // SIMDJSON_INTERNAL_JSONFORMATUTILS_H
|
||||||
|
|
|
@ -127,7 +127,8 @@ inline simdjson::padded_string operator "" _padded(const char *str, size_t len)
|
||||||
return simdjson::padded_string(str, len);
|
return simdjson::padded_string(str, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace simdjson::internal {
|
namespace simdjson {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
// low-level function to allocate memory with padding so we can read past the
|
// low-level function to allocate memory with padding so we can read past the
|
||||||
// "length" bytes safely. if you must provide a pointer to some data, create it
|
// "length" bytes safely. if you must provide a pointer to some data, create it
|
||||||
|
@ -135,6 +136,7 @@ namespace simdjson::internal {
|
||||||
// responsible to free the memory (free(...))
|
// responsible to free the memory (free(...))
|
||||||
inline char *allocate_padded_buffer(size_t length) noexcept;
|
inline char *allocate_padded_buffer(size_t length) noexcept;
|
||||||
|
|
||||||
} // namespace simdjson::internal;
|
} // namespace internal
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_PADDED_STRING_H
|
#endif // SIMDJSON_PADDED_STRING_H
|
||||||
|
|
|
@ -1,5 +1,31 @@
|
||||||
#
|
#
|
||||||
# simdjson as a library
|
# For callers who intend to #include simdjson.cpp.
|
||||||
|
#
|
||||||
|
# target_link_libraries(my-program simdjson-include-source) gives you the header and source
|
||||||
|
# directories. It does not specify any compiler flags.
|
||||||
|
#
|
||||||
|
add_library(simdjson-include-source INTERFACE)
|
||||||
|
target_link_libraries(simdjson-include-source INTERFACE simdjson-headers)
|
||||||
|
target_include_directories(simdjson-include-source INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
|
||||||
|
export_private_library(simdjson-include-source)
|
||||||
|
|
||||||
|
#
|
||||||
|
# For callers who intend to compile simdjson.cpp themselves.
|
||||||
|
#
|
||||||
|
# target_link_libraries(my-object simdjson-source) gives you the header and source directories, plus
|
||||||
|
# the .cpp sources. It does not specify any compiler flags.
|
||||||
|
#
|
||||||
|
add_library(simdjson-source INTERFACE)
|
||||||
|
target_sources(simdjson-source INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/simdjson.cpp)
|
||||||
|
target_link_libraries(simdjson-source INTERFACE simdjson-include-source)
|
||||||
|
export_private_library(simdjson-source)
|
||||||
|
|
||||||
|
#
|
||||||
|
# simdjson is the distributed library compiled with flags.
|
||||||
|
#
|
||||||
|
# target_link_libraries(my-object simdjson) gives you the .so or .a to link against, plus the header
|
||||||
|
# directory. It does not specify any compiler flags, even though simdjson.so/a was compiled with
|
||||||
|
# target_link_libraries(simdjson PRIVATE simdjson-flags).
|
||||||
#
|
#
|
||||||
|
|
||||||
if(SIMDJSON_BUILD_STATIC)
|
if(SIMDJSON_BUILD_STATIC)
|
||||||
|
@ -15,9 +41,10 @@ else()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_sources(simdjson PRIVATE simdjson.cpp)
|
target_link_libraries(simdjson INTERFACE simdjson-headers) # Only expose the headers, not sources
|
||||||
target_link_libraries(simdjson PUBLIC simdjson-headers)
|
|
||||||
target_include_directories(simdjson PRIVATE .)
|
target_link_libraries(simdjson PRIVATE simdjson-source simdjson-flags)
|
||||||
|
|
||||||
|
|
||||||
if(NOT MSVC)
|
if(NOT MSVC)
|
||||||
## We output the library at the root of the current directory where cmake is invoked
|
## We output the library at the root of the current directory where cmake is invoked
|
||||||
|
@ -26,13 +53,6 @@ if(NOT MSVC)
|
||||||
MESSAGE( STATUS "Library output directory (does not apply to Visual Studio): " ${CMAKE_BINARY_DIR})
|
MESSAGE( STATUS "Library output directory (does not apply to Visual Studio): " ${CMAKE_BINARY_DIR})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#
|
|
||||||
# simdjson to be compiled into your exe as source (you must #include simdjson.cpp)
|
|
||||||
#
|
|
||||||
add_library(simdjson-source INTERFACE)
|
|
||||||
target_link_libraries(simdjson-source INTERFACE simdjson-headers)
|
|
||||||
target_include_directories(simdjson-source INTERFACE .)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Installation
|
# Installation
|
||||||
#
|
#
|
||||||
|
|
|
@ -4,28 +4,24 @@
|
||||||
#include "simdjson.h"
|
#include "simdjson.h"
|
||||||
#include "arm64/intrinsics.h"
|
#include "arm64/intrinsics.h"
|
||||||
|
|
||||||
namespace simdjson::arm64 {
|
namespace simdjson {
|
||||||
|
namespace arm64 {
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
NO_SANITIZE_UNDEFINED
|
||||||
// We sometimes call trailing_zero on inputs that are zero,
|
// We sometimes call trailing_zero on inputs that are zero,
|
||||||
// but the algorithms do not end up using the returned value.
|
// but the algorithms do not end up using the returned value.
|
||||||
// Sadly, sanitizers are not smart enough to figure it out.
|
// Sadly, sanitizers are not smart enough to figure it out.
|
||||||
__attribute__((no_sanitize("undefined"))) // this is deliberate
|
|
||||||
#endif // _MSC_VER
|
|
||||||
/* result might be undefined when input_num is zero */
|
|
||||||
really_inline int trailing_zeroes(uint64_t input_num) {
|
really_inline int trailing_zeroes(uint64_t input_num) {
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
// Search the mask data from least significant bit (LSB)
|
// Search the mask data from least significant bit (LSB)
|
||||||
// to the most significant bit (MSB) for a set bit (1).
|
// to the most significant bit (MSB) for a set bit (1).
|
||||||
_BitScanForward64(&ret, input_num);
|
_BitScanForward64(&ret, input_num);
|
||||||
return (int)ret;
|
return (int)ret;
|
||||||
#else
|
#else // _MSC_VER
|
||||||
return __builtin_ctzll(input_num);
|
return __builtin_ctzll(input_num);
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
}
|
||||||
} // namespace simdjson::arm64
|
|
||||||
|
|
||||||
/* result might be undefined when input_num is zero */
|
/* result might be undefined when input_num is zero */
|
||||||
really_inline uint64_t clear_lowest_bit(uint64_t input_num) {
|
really_inline uint64_t clear_lowest_bit(uint64_t input_num) {
|
||||||
|
@ -78,6 +74,7 @@ really_inline bool mul_overflow(uint64_t value1, uint64_t value2, uint64_t *resu
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace simdjson::arm64
|
} // namespace arm64
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_ARM64_BITMANIPULATION_H
|
#endif // SIMDJSON_ARM64_BITMANIPULATION_H
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
|
|
||||||
#include "arm64/intrinsics.h"
|
#include "arm64/intrinsics.h"
|
||||||
|
|
||||||
namespace simdjson::arm64 {
|
namespace simdjson {
|
||||||
|
namespace arm64 {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered.
|
// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered.
|
||||||
|
@ -35,7 +36,8 @@ really_inline uint64_t prefix_xor(uint64_t bitmask) {
|
||||||
return bitmask;
|
return bitmask;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace simdjson::arm64
|
} // namespace arm64
|
||||||
|
} // namespace simdjson
|
||||||
UNTARGET_REGION
|
UNTARGET_REGION
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
#include "simdjson.h"
|
#include "simdjson.h"
|
||||||
#include "isadetection.h"
|
#include "isadetection.h"
|
||||||
|
|
||||||
namespace simdjson::arm64 {
|
namespace simdjson {
|
||||||
|
namespace arm64 {
|
||||||
|
|
||||||
using namespace simdjson::dom;
|
using namespace simdjson::dom;
|
||||||
|
|
||||||
|
@ -18,6 +19,7 @@ public:
|
||||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, parser &parser, size_t &next_json) const noexcept final;
|
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, parser &parser, size_t &next_json) const noexcept final;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace simdjson::arm64
|
} // namespace arm64
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_ARM64_IMPLEMENTATION_H
|
#endif // SIMDJSON_ARM64_IMPLEMENTATION_H
|
||||||
|
|
|
@ -16,7 +16,8 @@ void found_unsigned_integer(uint64_t result, const uint8_t *buf);
|
||||||
void found_float(double result, const uint8_t *buf);
|
void found_float(double result, const uint8_t *buf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace simdjson::arm64 {
|
namespace simdjson {
|
||||||
|
namespace arm64 {
|
||||||
|
|
||||||
// we don't have SSE, so let us use a scalar function
|
// we don't have SSE, so let us use a scalar function
|
||||||
// credit: https://johnnylee-sde.github.io/Fast-numeric-string-to-int/
|
// credit: https://johnnylee-sde.github.io/Fast-numeric-string-to-int/
|
||||||
|
@ -32,6 +33,7 @@ static inline uint32_t parse_eight_digits_unrolled(const char *chars) {
|
||||||
|
|
||||||
#include "generic/numberparsing.h"
|
#include "generic/numberparsing.h"
|
||||||
|
|
||||||
} // namespace simdjson::arm64
|
} // namespace arm64
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_ARM64_NUMBERPARSING_H
|
#endif // SIMDJSON_ARM64_NUMBERPARSING_H
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
#include "arm64/bitmanipulation.h"
|
#include "arm64/bitmanipulation.h"
|
||||||
#include "arm64/intrinsics.h"
|
#include "arm64/intrinsics.h"
|
||||||
|
|
||||||
namespace simdjson::arm64::simd {
|
namespace simdjson {
|
||||||
|
namespace arm64 {
|
||||||
|
namespace simd {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct simd8;
|
struct simd8;
|
||||||
|
@ -387,6 +389,8 @@ namespace simdjson::arm64::simd {
|
||||||
}
|
}
|
||||||
}; // struct simd8x64<T>
|
}; // struct simd8x64<T>
|
||||||
|
|
||||||
} // namespace simdjson::arm64::simd
|
} // namespace simd
|
||||||
|
} // namespace arm64
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_ARM64_SIMD_H
|
#endif // SIMDJSON_ARM64_SIMD_H
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
#include "arm64/bitmanipulation.h"
|
#include "arm64/bitmanipulation.h"
|
||||||
#include "arm64/implementation.h"
|
#include "arm64/implementation.h"
|
||||||
|
|
||||||
namespace simdjson::arm64 {
|
namespace simdjson {
|
||||||
|
namespace arm64 {
|
||||||
|
|
||||||
using namespace simd;
|
using namespace simd;
|
||||||
|
|
||||||
|
@ -85,6 +86,7 @@ WARN_UNUSED error_code implementation::stage1(const uint8_t *buf, size_t len, pa
|
||||||
return arm64::stage1::json_structural_indexer::index<64>(buf, len, parser, streaming);
|
return arm64::stage1::json_structural_indexer::index<64>(buf, len, parser, streaming);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace simdjson::arm64
|
} // namespace arm64
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_ARM64_STAGE1_FIND_MARKS_H
|
#endif // SIMDJSON_ARM64_STAGE1_FIND_MARKS_H
|
||||||
|
|
|
@ -6,12 +6,14 @@
|
||||||
#include "arm64/stringparsing.h"
|
#include "arm64/stringparsing.h"
|
||||||
#include "arm64/numberparsing.h"
|
#include "arm64/numberparsing.h"
|
||||||
|
|
||||||
namespace simdjson::arm64 {
|
namespace simdjson {
|
||||||
|
namespace arm64 {
|
||||||
|
|
||||||
#include "generic/atomparsing.h"
|
#include "generic/atomparsing.h"
|
||||||
#include "generic/stage2_build_tape.h"
|
#include "generic/stage2_build_tape.h"
|
||||||
#include "generic/stage2_streaming_build_tape.h"
|
#include "generic/stage2_streaming_build_tape.h"
|
||||||
|
|
||||||
} // namespace simdjson::arm64
|
} // namespace arm64
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_ARM64_STAGE2_BUILD_TAPE_H
|
#endif // SIMDJSON_ARM64_STAGE2_BUILD_TAPE_H
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
#include "arm64/intrinsics.h"
|
#include "arm64/intrinsics.h"
|
||||||
#include "arm64/bitmanipulation.h"
|
#include "arm64/bitmanipulation.h"
|
||||||
|
|
||||||
namespace simdjson::arm64 {
|
namespace simdjson {
|
||||||
|
namespace arm64 {
|
||||||
|
|
||||||
using namespace simd;
|
using namespace simd;
|
||||||
|
|
||||||
|
@ -29,7 +30,7 @@ public:
|
||||||
really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) {
|
really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) {
|
||||||
// this can read up to 31 bytes beyond the buffer size, but we require
|
// this can read up to 31 bytes beyond the buffer size, but we require
|
||||||
// SIMDJSON_PADDING of padding
|
// SIMDJSON_PADDING of padding
|
||||||
static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1));
|
static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes");
|
||||||
simd8<uint8_t> v0(src);
|
simd8<uint8_t> v0(src);
|
||||||
simd8<uint8_t> v1(src + sizeof(v0));
|
simd8<uint8_t> v1(src + sizeof(v0));
|
||||||
v0.store(dst);
|
v0.store(dst);
|
||||||
|
@ -46,7 +47,7 @@ really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8
|
||||||
|
|
||||||
#include "generic/stringparsing.h"
|
#include "generic/stringparsing.h"
|
||||||
|
|
||||||
}
|
} // namespace arm64
|
||||||
// namespace simdjson::amd64
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_ARM64_STRINGPARSING_H
|
#endif // SIMDJSON_ARM64_STRINGPARSING_H
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
|
|
||||||
#include "simdjson.h"
|
#include "simdjson.h"
|
||||||
|
|
||||||
namespace simdjson::dom {
|
namespace simdjson {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Parser callbacks
|
// Parser callbacks
|
||||||
|
@ -138,6 +139,7 @@ really_inline void parser::end_scope(uint32_t depth) noexcept {
|
||||||
doc.tape[d.tape_index] |= current_loc | (static_cast<uint64_t>(cntsat) << 32);
|
doc.tape[d.tape_index] |= current_loc | (static_cast<uint64_t>(cntsat) << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace simdjson::dom
|
} // namespace simdjson
|
||||||
|
} // namespace dom
|
||||||
|
|
||||||
#endif // SIMDJSON_DOCUMENT_PARSER_CALLBACKS_H
|
#endif // SIMDJSON_DOCUMENT_PARSER_CALLBACKS_H
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "simdjson/error.h"
|
#include "simdjson/error.h"
|
||||||
|
|
||||||
namespace simdjson::internal {
|
namespace simdjson {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
SIMDJSON_DLLIMPORTEXPORT const error_code_info error_codes[] {
|
SIMDJSON_DLLIMPORTEXPORT const error_code_info error_codes[] {
|
||||||
{ SUCCESS, "No error" },
|
{ SUCCESS, "No error" },
|
||||||
{ SUCCESS_AND_HAS_MORE, "No error and buffer still has more data" },
|
{ SUCCESS_AND_HAS_MORE, "No error and buffer still has more data" },
|
||||||
|
@ -28,4 +30,6 @@ namespace simdjson::internal {
|
||||||
{ INVALID_URI_FRAGMENT, "Invalid URI fragment syntax." },
|
{ INVALID_URI_FRAGMENT, "Invalid URI fragment syntax." },
|
||||||
{ UNEXPECTED_ERROR, "Unexpected error, consider reporting this problem as you may have found a bug in simdjson" }
|
{ UNEXPECTED_ERROR, "Unexpected error, consider reporting this problem as you may have found a bug in simdjson" }
|
||||||
}; // error_messages[]
|
}; // error_messages[]
|
||||||
}
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace simdjson
|
|
@ -4,28 +4,24 @@
|
||||||
#include "simdjson.h"
|
#include "simdjson.h"
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
namespace simdjson::fallback {
|
namespace simdjson {
|
||||||
|
namespace fallback {
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
|
||||||
// We sometimes call trailing_zero on inputs that are zero,
|
// We sometimes call trailing_zero on inputs that are zero,
|
||||||
// but the algorithms do not end up using the returned value.
|
// but the algorithms do not end up using the returned value.
|
||||||
// Sadly, sanitizers are not smart enough to figure it out.
|
// Sadly, sanitizers are not smart enough to figure it out.
|
||||||
__attribute__((no_sanitize("undefined"))) // this is deliberate
|
NO_SANITIZE_UNDEFINED
|
||||||
#endif // _MSC_VER
|
|
||||||
/* result might be undefined when input_num is zero */
|
|
||||||
really_inline int trailing_zeroes(uint64_t input_num) {
|
really_inline int trailing_zeroes(uint64_t input_num) {
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
// Search the mask data from least significant bit (LSB)
|
// Search the mask data from least significant bit (LSB)
|
||||||
// to the most significant bit (MSB) for a set bit (1).
|
// to the most significant bit (MSB) for a set bit (1).
|
||||||
_BitScanForward64(&ret, input_num);
|
_BitScanForward64(&ret, input_num);
|
||||||
return (int)ret;
|
return (int)ret;
|
||||||
#else
|
#else // _MSC_VER
|
||||||
return __builtin_ctzll(input_num);
|
return __builtin_ctzll(input_num);
|
||||||
#endif // _MSC_VER
|
#endif // _MSC_VER
|
||||||
|
}
|
||||||
} // namespace simdjson::arm64
|
|
||||||
|
|
||||||
/* result might be undefined when input_num is zero */
|
/* result might be undefined when input_num is zero */
|
||||||
really_inline uint64_t clear_lowest_bit(uint64_t input_num) {
|
really_inline uint64_t clear_lowest_bit(uint64_t input_num) {
|
||||||
|
@ -58,6 +54,7 @@ really_inline bool mul_overflow(uint64_t value1, uint64_t value2, uint64_t *resu
|
||||||
return value2 > 0 && value1 > std::numeric_limits<uint64_t>::max() / value2;
|
return value2 > 0 && value1 > std::numeric_limits<uint64_t>::max() / value2;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace simdjson::fallback
|
} // namespace fallback
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_FALLBACK_BITMANIPULATION_H
|
#endif // SIMDJSON_FALLBACK_BITMANIPULATION_H
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
#include "simdjson.h"
|
#include "simdjson.h"
|
||||||
#include "isadetection.h"
|
#include "isadetection.h"
|
||||||
|
|
||||||
namespace simdjson::fallback {
|
namespace simdjson {
|
||||||
|
namespace fallback {
|
||||||
|
|
||||||
using namespace simdjson::dom;
|
using namespace simdjson::dom;
|
||||||
|
|
||||||
|
@ -22,6 +23,8 @@ public:
|
||||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, parser &parser, size_t &next_json) const noexcept final;
|
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, parser &parser, size_t &next_json) const noexcept final;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace simdjson::fallback
|
} // namespace fallback
|
||||||
|
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_FALLBACK_IMPLEMENTATION_H
|
#endif // SIMDJSON_FALLBACK_IMPLEMENTATION_H
|
|
@ -14,7 +14,8 @@ void found_unsigned_integer(uint64_t result, const uint8_t *buf);
|
||||||
void found_float(double result, const uint8_t *buf);
|
void found_float(double result, const uint8_t *buf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace simdjson::fallback {
|
namespace simdjson {
|
||||||
|
namespace fallback {
|
||||||
static inline uint32_t parse_eight_digits_unrolled(const char *chars) {
|
static inline uint32_t parse_eight_digits_unrolled(const char *chars) {
|
||||||
uint32_t result = 0;
|
uint32_t result = 0;
|
||||||
for (int i=0;i<8;i++) {
|
for (int i=0;i<8;i++) {
|
||||||
|
@ -27,6 +28,8 @@ static inline uint32_t parse_eight_digits_unrolled(const char *chars) {
|
||||||
|
|
||||||
#include "generic/numberparsing.h"
|
#include "generic/numberparsing.h"
|
||||||
|
|
||||||
} // namespace simdjson::fallback
|
} // namespace fallback
|
||||||
|
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_FALLBACK_NUMBERPARSING_H
|
#endif // SIMDJSON_FALLBACK_NUMBERPARSING_H
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
#include "simdjson.h"
|
#include "simdjson.h"
|
||||||
#include "fallback/implementation.h"
|
#include "fallback/implementation.h"
|
||||||
|
|
||||||
namespace simdjson::fallback::stage1 {
|
namespace simdjson {
|
||||||
|
namespace fallback {
|
||||||
|
namespace stage1 {
|
||||||
|
|
||||||
class structural_scanner {
|
class structural_scanner {
|
||||||
public:
|
public:
|
||||||
|
@ -139,9 +141,8 @@ private:
|
||||||
bool streaming;
|
bool streaming;
|
||||||
}; // structural_scanner
|
}; // structural_scanner
|
||||||
|
|
||||||
} // simdjson::fallback::stage1
|
} // namespace stage1
|
||||||
|
|
||||||
namespace simdjson::fallback {
|
|
||||||
|
|
||||||
WARN_UNUSED error_code implementation::stage1(const uint8_t *buf, size_t len, parser &parser, bool streaming) const noexcept {
|
WARN_UNUSED error_code implementation::stage1(const uint8_t *buf, size_t len, parser &parser, bool streaming) const noexcept {
|
||||||
if (unlikely(len > parser.capacity())) {
|
if (unlikely(len > parser.capacity())) {
|
||||||
|
@ -207,6 +208,7 @@ WARN_UNUSED error_code implementation::minify(const uint8_t *buf, size_t len, ui
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace simdjson::fallback
|
} // namespace fallback
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_FALLBACK_STAGE1_FIND_MARKS_H
|
#endif // SIMDJSON_FALLBACK_STAGE1_FIND_MARKS_H
|
||||||
|
|
|
@ -7,12 +7,14 @@
|
||||||
#include "fallback/stringparsing.h"
|
#include "fallback/stringparsing.h"
|
||||||
#include "fallback/numberparsing.h"
|
#include "fallback/numberparsing.h"
|
||||||
|
|
||||||
namespace simdjson::fallback {
|
namespace simdjson {
|
||||||
|
namespace fallback {
|
||||||
|
|
||||||
#include "generic/atomparsing.h"
|
#include "generic/atomparsing.h"
|
||||||
#include "generic/stage2_build_tape.h"
|
#include "generic/stage2_build_tape.h"
|
||||||
#include "generic/stage2_streaming_build_tape.h"
|
#include "generic/stage2_streaming_build_tape.h"
|
||||||
|
|
||||||
|
} // namespace fallback
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_FALLBACK_STAGE2_BUILD_TAPE_H
|
#endif // SIMDJSON_FALLBACK_STAGE2_BUILD_TAPE_H
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
#include "simdjson.h"
|
#include "simdjson.h"
|
||||||
#include "jsoncharutils.h"
|
#include "jsoncharutils.h"
|
||||||
|
|
||||||
namespace simdjson::fallback {
|
namespace simdjson {
|
||||||
|
namespace fallback {
|
||||||
|
|
||||||
// Holds backslashes and quotes locations.
|
// Holds backslashes and quotes locations.
|
||||||
struct backslash_and_quote {
|
struct backslash_and_quote {
|
||||||
|
@ -28,6 +29,7 @@ really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8
|
||||||
|
|
||||||
#include "generic/stringparsing.h"
|
#include "generic/stringparsing.h"
|
||||||
|
|
||||||
} // namespace simdjson::fallback
|
} // namespace fallback
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_FALLBACK_STRINGPARSING_H
|
#endif // SIMDJSON_FALLBACK_STRINGPARSING_H
|
||||||
|
|
|
@ -5,7 +5,7 @@ really_inline uint32_t string_to_uint32(const char* str) { return *reinterpret_c
|
||||||
WARN_UNUSED
|
WARN_UNUSED
|
||||||
really_inline bool str4ncmp(const uint8_t *src, const char* atom) {
|
really_inline bool str4ncmp(const uint8_t *src, const char* atom) {
|
||||||
uint32_t srcval; // we want to avoid unaligned 64-bit loads (undefined in C/C++)
|
uint32_t srcval; // we want to avoid unaligned 64-bit loads (undefined in C/C++)
|
||||||
static_assert(sizeof(uint32_t) <= SIMDJSON_PADDING);
|
static_assert(sizeof(uint32_t) <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be larger than 4 bytes");
|
||||||
std::memcpy(&srcval, src, sizeof(uint32_t));
|
std::memcpy(&srcval, src, sizeof(uint32_t));
|
||||||
return srcval ^ string_to_uint32(atom);
|
return srcval ^ string_to_uint32(atom);
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,7 +242,7 @@ really_inline bool is_made_of_eight_digits_fast(const char *chars) {
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
// this can read up to 7 bytes beyond the buffer size, but we require
|
// this can read up to 7 bytes beyond the buffer size, but we require
|
||||||
// SIMDJSON_PADDING of padding
|
// SIMDJSON_PADDING of padding
|
||||||
static_assert(7 <= SIMDJSON_PADDING);
|
static_assert(7 <= SIMDJSON_PADDING, "SIMDJSON_PADDING must be bigger than 7");
|
||||||
memcpy(&val, chars, 8);
|
memcpy(&val, chars, 8);
|
||||||
// a branchy method might be faster:
|
// a branchy method might be faster:
|
||||||
// return (( val & 0xF0F0F0F0F0F0F0F0 ) == 0x3030303030303030)
|
// return (( val & 0xF0F0F0F0F0F0F0F0 ) == 0x3030303030303030)
|
||||||
|
|
|
@ -6,25 +6,24 @@
|
||||||
#include "haswell/intrinsics.h"
|
#include "haswell/intrinsics.h"
|
||||||
|
|
||||||
TARGET_HASWELL
|
TARGET_HASWELL
|
||||||
namespace simdjson::haswell {
|
namespace simdjson {
|
||||||
|
namespace haswell {
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
|
||||||
// We sometimes call trailing_zero on inputs that are zero,
|
// We sometimes call trailing_zero on inputs that are zero,
|
||||||
// but the algorithms do not end up using the returned value.
|
// but the algorithms do not end up using the returned value.
|
||||||
// Sadly, sanitizers are not smart enough to figure it out.
|
// Sadly, sanitizers are not smart enough to figure it out.
|
||||||
__attribute__((no_sanitize("undefined"))) // this is deliberate
|
NO_SANITIZE_UNDEFINED
|
||||||
#endif
|
|
||||||
really_inline int trailing_zeroes(uint64_t input_num) {
|
really_inline int trailing_zeroes(uint64_t input_num) {
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
return (int)_tzcnt_u64(input_num);
|
return (int)_tzcnt_u64(input_num);
|
||||||
#else
|
#else // _MSC_VER
|
||||||
////////
|
////////
|
||||||
// You might expect the next line to be equivalent to
|
// You might expect the next line to be equivalent to
|
||||||
// return (int)_tzcnt_u64(input_num);
|
// return (int)_tzcnt_u64(input_num);
|
||||||
// but the generated code differs and might be less efficient?
|
// but the generated code differs and might be less efficient?
|
||||||
////////
|
////////
|
||||||
return __builtin_ctzll(input_num);
|
return __builtin_ctzll(input_num);
|
||||||
#endif// _MSC_VER
|
#endif // _MSC_VER
|
||||||
}
|
}
|
||||||
|
|
||||||
/* result might be undefined when input_num is zero */
|
/* result might be undefined when input_num is zero */
|
||||||
|
@ -71,7 +70,9 @@ really_inline bool mul_overflow(uint64_t value1, uint64_t value2,
|
||||||
(unsigned long long *)result);
|
(unsigned long long *)result);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}// namespace simdjson::haswell
|
|
||||||
|
} // namespace haswell
|
||||||
|
} // namespace simdjson
|
||||||
UNTARGET_REGION
|
UNTARGET_REGION
|
||||||
|
|
||||||
#endif // SIMDJSON_HASWELL_BITMANIPULATION_H
|
#endif // SIMDJSON_HASWELL_BITMANIPULATION_H
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
#include "haswell/intrinsics.h"
|
#include "haswell/intrinsics.h"
|
||||||
|
|
||||||
TARGET_HASWELL
|
TARGET_HASWELL
|
||||||
namespace simdjson::haswell {
|
namespace simdjson {
|
||||||
|
namespace haswell {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered.
|
// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered.
|
||||||
|
@ -21,7 +22,9 @@ really_inline uint64_t prefix_xor(const uint64_t bitmask) {
|
||||||
return _mm_cvtsi128_si64(result);
|
return _mm_cvtsi128_si64(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace simdjson::haswell
|
} // namespace haswell
|
||||||
|
|
||||||
|
} // namespace simdjson
|
||||||
UNTARGET_REGION
|
UNTARGET_REGION
|
||||||
|
|
||||||
#endif // SIMDJSON_HASWELL_BITMASK_H
|
#endif // SIMDJSON_HASWELL_BITMASK_H
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
#include "simdjson.h"
|
#include "simdjson.h"
|
||||||
#include "isadetection.h"
|
#include "isadetection.h"
|
||||||
|
|
||||||
namespace simdjson::haswell {
|
namespace simdjson {
|
||||||
|
namespace haswell {
|
||||||
|
|
||||||
using namespace simdjson::dom;
|
using namespace simdjson::dom;
|
||||||
|
|
||||||
|
@ -22,6 +23,7 @@ public:
|
||||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, parser &parser, size_t &next_json) const noexcept final;
|
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, parser &parser, size_t &next_json) const noexcept final;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace simdjson::haswell
|
} // namespace haswell
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_HASWELL_IMPLEMENTATION_H
|
#endif // SIMDJSON_HASWELL_IMPLEMENTATION_H
|
|
@ -17,7 +17,8 @@ void found_float(double result, const uint8_t *buf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TARGET_HASWELL
|
TARGET_HASWELL
|
||||||
namespace simdjson::haswell {
|
namespace simdjson {
|
||||||
|
namespace haswell {
|
||||||
static inline uint32_t parse_eight_digits_unrolled(const char *chars) {
|
static inline uint32_t parse_eight_digits_unrolled(const char *chars) {
|
||||||
// this actually computes *16* values so we are being wasteful.
|
// this actually computes *16* values so we are being wasteful.
|
||||||
const __m128i ascii0 = _mm_set1_epi8('0');
|
const __m128i ascii0 = _mm_set1_epi8('0');
|
||||||
|
@ -40,7 +41,9 @@ static inline uint32_t parse_eight_digits_unrolled(const char *chars) {
|
||||||
|
|
||||||
#include "generic/numberparsing.h"
|
#include "generic/numberparsing.h"
|
||||||
|
|
||||||
} // namespace simdjson::haswell
|
} // namespace haswell
|
||||||
|
|
||||||
|
} // namespace simdjson
|
||||||
UNTARGET_REGION
|
UNTARGET_REGION
|
||||||
|
|
||||||
#endif // SIMDJSON_HASWELL_NUMBERPARSING_H
|
#endif // SIMDJSON_HASWELL_NUMBERPARSING_H
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
#include "haswell/intrinsics.h"
|
#include "haswell/intrinsics.h"
|
||||||
|
|
||||||
TARGET_HASWELL
|
TARGET_HASWELL
|
||||||
namespace simdjson::haswell::simd {
|
namespace simdjson {
|
||||||
|
namespace haswell {
|
||||||
|
namespace simd {
|
||||||
|
|
||||||
// Forward-declared so they can be used by splat and friends.
|
// Forward-declared so they can be used by splat and friends.
|
||||||
template<typename Child>
|
template<typename Child>
|
||||||
|
@ -366,7 +368,10 @@ namespace simdjson::haswell::simd {
|
||||||
}
|
}
|
||||||
}; // struct simd8x64<T>
|
}; // struct simd8x64<T>
|
||||||
|
|
||||||
} // namespace simdjson::haswell::simd
|
} // namespace simd
|
||||||
|
|
||||||
|
} // namespace haswell
|
||||||
|
} // namespace simdjson
|
||||||
UNTARGET_REGION
|
UNTARGET_REGION
|
||||||
|
|
||||||
#endif // SIMDJSON_HASWELL_SIMD_H
|
#endif // SIMDJSON_HASWELL_SIMD_H
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
#include "haswell/implementation.h"
|
#include "haswell/implementation.h"
|
||||||
|
|
||||||
TARGET_HASWELL
|
TARGET_HASWELL
|
||||||
namespace simdjson::haswell {
|
namespace simdjson {
|
||||||
|
namespace haswell {
|
||||||
|
|
||||||
using namespace simd;
|
using namespace simd;
|
||||||
|
|
||||||
|
@ -74,7 +75,9 @@ WARN_UNUSED error_code implementation::stage1(const uint8_t *buf, size_t len, pa
|
||||||
return haswell::stage1::json_structural_indexer::index<128>(buf, len, parser, streaming);
|
return haswell::stage1::json_structural_indexer::index<128>(buf, len, parser, streaming);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace simdjson::haswell
|
} // namespace haswell
|
||||||
|
|
||||||
|
} // namespace simdjson
|
||||||
UNTARGET_REGION
|
UNTARGET_REGION
|
||||||
|
|
||||||
#endif // SIMDJSON_HASWELL_STAGE1_FIND_MARKS_H
|
#endif // SIMDJSON_HASWELL_STAGE1_FIND_MARKS_H
|
||||||
|
|
|
@ -7,12 +7,14 @@
|
||||||
#include "haswell/numberparsing.h"
|
#include "haswell/numberparsing.h"
|
||||||
|
|
||||||
TARGET_HASWELL
|
TARGET_HASWELL
|
||||||
namespace simdjson::haswell {
|
namespace simdjson {
|
||||||
|
namespace haswell {
|
||||||
|
|
||||||
#include "generic/atomparsing.h"
|
#include "generic/atomparsing.h"
|
||||||
#include "generic/stage2_build_tape.h"
|
#include "generic/stage2_build_tape.h"
|
||||||
#include "generic/stage2_streaming_build_tape.h"
|
#include "generic/stage2_streaming_build_tape.h"
|
||||||
|
|
||||||
|
} // namespace haswell
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
UNTARGET_REGION
|
UNTARGET_REGION
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
#include "haswell/bitmanipulation.h"
|
#include "haswell/bitmanipulation.h"
|
||||||
|
|
||||||
TARGET_HASWELL
|
TARGET_HASWELL
|
||||||
namespace simdjson::haswell {
|
namespace simdjson {
|
||||||
|
namespace haswell {
|
||||||
|
|
||||||
using namespace simd;
|
using namespace simd;
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ public:
|
||||||
really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) {
|
really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) {
|
||||||
// this can read up to 15 bytes beyond the buffer size, but we require
|
// this can read up to 15 bytes beyond the buffer size, but we require
|
||||||
// SIMDJSON_PADDING of padding
|
// SIMDJSON_PADDING of padding
|
||||||
static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1));
|
static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes");
|
||||||
simd8<uint8_t> v(src);
|
simd8<uint8_t> v(src);
|
||||||
// store to dest unconditionally - we can overwrite the bits we don't like later
|
// store to dest unconditionally - we can overwrite the bits we don't like later
|
||||||
v.store(dst);
|
v.store(dst);
|
||||||
|
@ -42,7 +43,8 @@ really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8
|
||||||
|
|
||||||
#include "generic/stringparsing.h"
|
#include "generic/stringparsing.h"
|
||||||
|
|
||||||
} // namespace simdjson::haswell
|
} // namespace haswell
|
||||||
|
} // namespace simdjson
|
||||||
UNTARGET_REGION
|
UNTARGET_REGION
|
||||||
|
|
||||||
#endif // SIMDJSON_HASWELL_STRINGPARSING_H
|
#endif // SIMDJSON_HASWELL_STRINGPARSING_H
|
||||||
|
|
|
@ -9,25 +9,26 @@
|
||||||
|
|
||||||
#if SIMDJSON_IMPLEMENTATION_HASWELL
|
#if SIMDJSON_IMPLEMENTATION_HASWELL
|
||||||
#include "haswell/implementation.h"
|
#include "haswell/implementation.h"
|
||||||
namespace simdjson::internal { const haswell::implementation haswell_singleton{}; }
|
namespace simdjson { namespace internal { const haswell::implementation haswell_singleton{}; } }
|
||||||
#endif // SIMDJSON_IMPLEMENTATION_HASWELL
|
#endif // SIMDJSON_IMPLEMENTATION_HASWELL
|
||||||
|
|
||||||
#if SIMDJSON_IMPLEMENTATION_WESTMERE
|
#if SIMDJSON_IMPLEMENTATION_WESTMERE
|
||||||
#include "westmere/implementation.h"
|
#include "westmere/implementation.h"
|
||||||
namespace simdjson::internal { const westmere::implementation westmere_singleton{}; }
|
namespace simdjson { namespace internal { const westmere::implementation westmere_singleton{}; } }
|
||||||
#endif // SIMDJSON_IMPLEMENTATION_WESTMERE
|
#endif // SIMDJSON_IMPLEMENTATION_WESTMERE
|
||||||
|
|
||||||
#if SIMDJSON_IMPLEMENTATION_ARM64
|
#if SIMDJSON_IMPLEMENTATION_ARM64
|
||||||
#include "arm64/implementation.h"
|
#include "arm64/implementation.h"
|
||||||
namespace simdjson::internal { const arm64::implementation arm64_singleton{}; }
|
namespace simdjson { namespace internal { const arm64::implementation arm64_singleton{}; } }
|
||||||
#endif // SIMDJSON_IMPLEMENTATION_ARM64
|
#endif // SIMDJSON_IMPLEMENTATION_ARM64
|
||||||
|
|
||||||
#if SIMDJSON_IMPLEMENTATION_FALLBACK
|
#if SIMDJSON_IMPLEMENTATION_FALLBACK
|
||||||
#include "fallback/implementation.h"
|
#include "fallback/implementation.h"
|
||||||
namespace simdjson::internal { const fallback::implementation fallback_singleton{}; }
|
namespace simdjson { namespace internal { const fallback::implementation fallback_singleton{}; } }
|
||||||
#endif // SIMDJSON_IMPLEMENTATION_FALLBACK
|
#endif // SIMDJSON_IMPLEMENTATION_FALLBACK
|
||||||
|
|
||||||
namespace simdjson::internal {
|
namespace simdjson {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private Detects best supported implementation on first use, and sets it
|
* @private Detects best supported implementation on first use, and sets it
|
||||||
|
@ -124,9 +125,9 @@ const implementation *detect_best_supported_implementation_on_first_use::set_bes
|
||||||
return active_implementation = available_implementations.detect_best_supported();
|
return active_implementation = available_implementations.detect_best_supported();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace simdjson::internal
|
} // namespace internal
|
||||||
|
|
||||||
namespace simdjson {
|
SIMDJSON_DLLIMPORTEXPORT const internal::available_implementation_list available_implementations{};
|
||||||
SIMDJSON_DLLIMPORTEXPORT const internal::available_implementation_list available_implementations{};
|
SIMDJSON_DLLIMPORTEXPORT internal::atomic_ptr<const implementation> active_implementation{&internal::detect_best_supported_implementation_on_first_use_singleton};
|
||||||
SIMDJSON_DLLIMPORTEXPORT internal::atomic_ptr<const implementation> active_implementation{&internal::detect_best_supported_implementation_on_first_use_singleton};
|
|
||||||
}
|
} // namespace simdjson
|
||||||
|
|
|
@ -148,6 +148,6 @@ static inline uint32_t detect_supported_architectures() {
|
||||||
|
|
||||||
#endif // end SIMD extension detection code
|
#endif // end SIMD extension detection code
|
||||||
|
|
||||||
} // namespace simdjson::internal
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_ISADETECTION_H
|
#endif // SIMDJSON_ISADETECTION_H
|
||||||
|
|
|
@ -5,15 +5,13 @@
|
||||||
#include "westmere/intrinsics.h"
|
#include "westmere/intrinsics.h"
|
||||||
|
|
||||||
TARGET_WESTMERE
|
TARGET_WESTMERE
|
||||||
namespace simdjson::westmere {
|
namespace simdjson {
|
||||||
|
namespace westmere {
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
|
||||||
// We sometimes call trailing_zero on inputs that are zero,
|
// We sometimes call trailing_zero on inputs that are zero,
|
||||||
// but the algorithms do not end up using the returned value.
|
// but the algorithms do not end up using the returned value.
|
||||||
// Sadly, sanitizers are not smart enough to figure it out.
|
// Sadly, sanitizers are not smart enough to figure it out.
|
||||||
__attribute__((no_sanitize("undefined"))) // this is deliberate
|
NO_SANITIZE_UNDEFINED
|
||||||
#endif
|
|
||||||
/* result might be undefined when input_num is zero */
|
|
||||||
really_inline int trailing_zeroes(uint64_t input_num) {
|
really_inline int trailing_zeroes(uint64_t input_num) {
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
|
@ -21,9 +19,9 @@ really_inline int trailing_zeroes(uint64_t input_num) {
|
||||||
// to the most significant bit (MSB) for a set bit (1).
|
// to the most significant bit (MSB) for a set bit (1).
|
||||||
_BitScanForward64(&ret, input_num);
|
_BitScanForward64(&ret, input_num);
|
||||||
return (int)ret;
|
return (int)ret;
|
||||||
#else
|
#else // _MSC_VER
|
||||||
return __builtin_ctzll(input_num);
|
return __builtin_ctzll(input_num);
|
||||||
#endif// _MSC_VER
|
#endif // _MSC_VER
|
||||||
}
|
}
|
||||||
|
|
||||||
/* result might be undefined when input_num is zero */
|
/* result might be undefined when input_num is zero */
|
||||||
|
@ -81,7 +79,9 @@ really_inline bool mul_overflow(uint64_t value1, uint64_t value2,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace simdjson::westmere
|
} // namespace westmere
|
||||||
|
|
||||||
|
} // namespace simdjson
|
||||||
UNTARGET_REGION
|
UNTARGET_REGION
|
||||||
|
|
||||||
#endif // SIMDJSON_WESTMERE_BITMANIPULATION_H
|
#endif // SIMDJSON_WESTMERE_BITMANIPULATION_H
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
#include "westmere/intrinsics.h"
|
#include "westmere/intrinsics.h"
|
||||||
|
|
||||||
TARGET_WESTMERE
|
TARGET_WESTMERE
|
||||||
namespace simdjson::westmere {
|
namespace simdjson {
|
||||||
|
namespace westmere {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered.
|
// Perform a "cumulative bitwise xor," flipping bits each time a 1 is encountered.
|
||||||
|
@ -20,7 +21,9 @@ really_inline uint64_t prefix_xor(const uint64_t bitmask) {
|
||||||
return _mm_cvtsi128_si64(result);
|
return _mm_cvtsi128_si64(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace simdjson::westmere
|
} // namespace westmere
|
||||||
|
|
||||||
|
} // namespace simdjson
|
||||||
UNTARGET_REGION
|
UNTARGET_REGION
|
||||||
|
|
||||||
#endif // SIMDJSON_WESTMERE_BITMASK_H
|
#endif // SIMDJSON_WESTMERE_BITMASK_H
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
#include "simdjson/implementation.h"
|
#include "simdjson/implementation.h"
|
||||||
#include "isadetection.h"
|
#include "isadetection.h"
|
||||||
|
|
||||||
namespace simdjson::westmere {
|
namespace simdjson {
|
||||||
|
namespace westmere {
|
||||||
|
|
||||||
using namespace simdjson::dom;
|
using namespace simdjson::dom;
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@ public:
|
||||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, parser &parser, size_t &next_json) const noexcept final;
|
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, parser &parser, size_t &next_json) const noexcept final;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace simdjson::westmere
|
} // namespace westmere
|
||||||
|
} // namespace simdjson
|
||||||
|
|
||||||
#endif // SIMDJSON_WESTMERE_IMPLEMENTATION_H
|
#endif // SIMDJSON_WESTMERE_IMPLEMENTATION_H
|
|
@ -18,7 +18,8 @@ void found_float(double result, const uint8_t *buf);
|
||||||
|
|
||||||
|
|
||||||
TARGET_WESTMERE
|
TARGET_WESTMERE
|
||||||
namespace simdjson::westmere {
|
namespace simdjson {
|
||||||
|
namespace westmere {
|
||||||
static inline uint32_t parse_eight_digits_unrolled(const char *chars) {
|
static inline uint32_t parse_eight_digits_unrolled(const char *chars) {
|
||||||
// this actually computes *16* values so we are being wasteful.
|
// this actually computes *16* values so we are being wasteful.
|
||||||
const __m128i ascii0 = _mm_set1_epi8('0');
|
const __m128i ascii0 = _mm_set1_epi8('0');
|
||||||
|
@ -41,7 +42,9 @@ static inline uint32_t parse_eight_digits_unrolled(const char *chars) {
|
||||||
|
|
||||||
#include "generic/numberparsing.h"
|
#include "generic/numberparsing.h"
|
||||||
|
|
||||||
} // namespace simdjson::westmere
|
} // namespace westmere
|
||||||
|
|
||||||
|
} // namespace simdjson
|
||||||
UNTARGET_REGION
|
UNTARGET_REGION
|
||||||
|
|
||||||
#endif // SIMDJSON_WESTMERE_NUMBERPARSING_H
|
#endif // SIMDJSON_WESTMERE_NUMBERPARSING_H
|
||||||
|
|
|
@ -9,7 +9,9 @@
|
||||||
|
|
||||||
|
|
||||||
TARGET_WESTMERE
|
TARGET_WESTMERE
|
||||||
namespace simdjson::westmere::simd {
|
namespace simdjson {
|
||||||
|
namespace westmere {
|
||||||
|
namespace simd {
|
||||||
|
|
||||||
template<typename Child>
|
template<typename Child>
|
||||||
struct base {
|
struct base {
|
||||||
|
@ -351,7 +353,10 @@ namespace simdjson::westmere::simd {
|
||||||
}
|
}
|
||||||
}; // struct simd8x64<T>
|
}; // struct simd8x64<T>
|
||||||
|
|
||||||
} // namespace simdjson::westmere::simd
|
} // namespace simd
|
||||||
|
|
||||||
|
} // namespace westmere
|
||||||
|
} // namespace simdjson
|
||||||
UNTARGET_REGION
|
UNTARGET_REGION
|
||||||
|
|
||||||
#endif // SIMDJSON_WESTMERE_SIMD_INPUT_H
|
#endif // SIMDJSON_WESTMERE_SIMD_INPUT_H
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
#include "westmere/implementation.h"
|
#include "westmere/implementation.h"
|
||||||
|
|
||||||
TARGET_WESTMERE
|
TARGET_WESTMERE
|
||||||
namespace simdjson::westmere {
|
namespace simdjson {
|
||||||
|
namespace westmere {
|
||||||
|
|
||||||
using namespace simd;
|
using namespace simd;
|
||||||
|
|
||||||
|
@ -73,7 +74,9 @@ WARN_UNUSED error_code implementation::stage1(const uint8_t *buf, size_t len, pa
|
||||||
return westmere::stage1::json_structural_indexer::index<64>(buf, len, parser, streaming);
|
return westmere::stage1::json_structural_indexer::index<64>(buf, len, parser, streaming);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace simdjson::westmere
|
} // namespace westmere
|
||||||
|
|
||||||
|
} // namespace simdjson
|
||||||
UNTARGET_REGION
|
UNTARGET_REGION
|
||||||
|
|
||||||
#endif // SIMDJSON_WESTMERE_STAGE1_FIND_MARKS_H
|
#endif // SIMDJSON_WESTMERE_STAGE1_FIND_MARKS_H
|
||||||
|
|
|
@ -7,12 +7,14 @@
|
||||||
#include "westmere/numberparsing.h"
|
#include "westmere/numberparsing.h"
|
||||||
|
|
||||||
TARGET_WESTMERE
|
TARGET_WESTMERE
|
||||||
namespace simdjson::westmere {
|
namespace simdjson {
|
||||||
|
namespace westmere {
|
||||||
|
|
||||||
#include "generic/atomparsing.h"
|
#include "generic/atomparsing.h"
|
||||||
#include "generic/stage2_build_tape.h"
|
#include "generic/stage2_build_tape.h"
|
||||||
#include "generic/stage2_streaming_build_tape.h"
|
#include "generic/stage2_streaming_build_tape.h"
|
||||||
|
|
||||||
} // namespace simdjson::westmere
|
} // namespace westmere
|
||||||
|
} // namespace simdjson
|
||||||
UNTARGET_REGION
|
UNTARGET_REGION
|
||||||
#endif // SIMDJSON_WESTMERE_STAGE2_BUILD_TAPE_H
|
#endif // SIMDJSON_WESTMERE_STAGE2_BUILD_TAPE_H
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
#include "westmere/bitmanipulation.h"
|
#include "westmere/bitmanipulation.h"
|
||||||
|
|
||||||
TARGET_WESTMERE
|
TARGET_WESTMERE
|
||||||
namespace simdjson::westmere {
|
namespace simdjson {
|
||||||
|
namespace westmere {
|
||||||
|
|
||||||
using namespace simd;
|
using namespace simd;
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ public:
|
||||||
really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) {
|
really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8_t *src, uint8_t *dst) {
|
||||||
// this can read up to 31 bytes beyond the buffer size, but we require
|
// this can read up to 31 bytes beyond the buffer size, but we require
|
||||||
// SIMDJSON_PADDING of padding
|
// SIMDJSON_PADDING of padding
|
||||||
static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1));
|
static_assert(SIMDJSON_PADDING >= (BYTES_PROCESSED - 1), "backslash and quote finder must process fewer than SIMDJSON_PADDING bytes");
|
||||||
simd8<uint8_t> v0(src);
|
simd8<uint8_t> v0(src);
|
||||||
simd8<uint8_t> v1(src + 16);
|
simd8<uint8_t> v1(src + 16);
|
||||||
v0.store(dst);
|
v0.store(dst);
|
||||||
|
@ -44,7 +45,8 @@ really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8
|
||||||
|
|
||||||
#include "generic/stringparsing.h"
|
#include "generic/stringparsing.h"
|
||||||
|
|
||||||
} // namespace simdjson::westmere
|
} // namespace westmere
|
||||||
|
} // namespace simdjson
|
||||||
UNTARGET_REGION
|
UNTARGET_REGION
|
||||||
|
|
||||||
#endif // SIMDJSON_WESTMERE_STRINGPARSING_H
|
#endif // SIMDJSON_WESTMERE_STRINGPARSING_H
|
||||||
|
|
|
@ -1,42 +1,60 @@
|
||||||
# Helper so we don't have to repeat ourselves so much
|
# Helper so we don't have to repeat ourselves so much
|
||||||
function(add_cpp_test TEST_NAME TEST_FILE)
|
function(add_cpp_test TEST_NAME TEST_FILE)
|
||||||
|
# If a source file is passed, add an executable
|
||||||
add_executable(${TEST_NAME} ${TEST_FILE})
|
add_executable(${TEST_NAME} ${TEST_FILE})
|
||||||
add_test(${TEST_NAME} ${TEST_NAME})
|
add_test(${TEST_NAME} ${TEST_NAME})
|
||||||
endfunction(add_cpp_test)
|
if ($ARGN)
|
||||||
|
set_property(TEST ${TEST_NAME} APPEND PROPERTY LABELS ${ARGN})
|
||||||
|
else()
|
||||||
|
set_property(TEST ${TEST_NAME} APPEND PROPERTY LABELS slowtests)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(add_compile_test TEST_NAME TEST_FILE)
|
||||||
|
add_executable(${TEST_NAME} ${TEST_FILE})
|
||||||
|
set_target_properties(${TEST_NAME} PROPERTIES
|
||||||
|
EXCLUDE_FROM_ALL TRUE
|
||||||
|
EXCLUDE_FROM_DEFAULT_BUILD TRUE)
|
||||||
|
add_test(
|
||||||
|
NAME ${TEST_NAME}
|
||||||
|
COMMAND ${CMAKE_COMMAND} --build . --target ${TEST_NAME} --config $<CONFIGURATION>
|
||||||
|
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||||
|
)
|
||||||
|
if (${ARGN}) # Labels
|
||||||
|
set_property(TEST ${TEST_NAME} APPEND PROPERTY LABELS ${ARGN})
|
||||||
|
else()
|
||||||
|
set_property(TEST ${TEST_NAME} APPEND PROPERTY LABELS slowtests)
|
||||||
|
endif()
|
||||||
|
endfunction(add_compile_test)
|
||||||
|
|
||||||
# Most tests need test data, and many need windows headers.
|
# Most tests need test data, and many need windows headers.
|
||||||
link_libraries(test-data simdjson-windows-headers)
|
link_libraries(simdjson-flags test-data simdjson-windows-headers)
|
||||||
|
|
||||||
#
|
#
|
||||||
# These test explicitly do #include "simdjson.cpp" so they can override stuff
|
# These tests explicitly do #include "simdjson.cpp" so they can override stuff
|
||||||
#
|
#
|
||||||
if (NOT MSVC) # Can't get simdjson-source to compile on Windows for some reason.
|
if (NOT MSVC) # Can't get simdjson-source to compile on Windows for some reason.
|
||||||
add_cpp_test(numberparsingcheck numberparsingcheck.cpp quicktests)
|
add_cpp_test(numberparsingcheck numberparsingcheck.cpp quicktests)
|
||||||
target_link_libraries(numberparsingcheck simdjson-source)
|
target_link_libraries(numberparsingcheck simdjson-include-source)
|
||||||
add_cpp_test(stringparsingcheck stringparsingcheck.cpp quicktests)
|
add_cpp_test(stringparsingcheck stringparsingcheck.cpp quicktests)
|
||||||
target_link_libraries(stringparsingcheck simdjson-source)
|
target_link_libraries(stringparsingcheck simdjson-include-source)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# All remaining tests link with simdjson proper
|
# All remaining tests link with simdjson proper
|
||||||
link_libraries(simdjson)
|
link_libraries(simdjson)
|
||||||
|
add_cpp_test(basictests basictests.cpp quicktests)
|
||||||
add_cpp_test(basictests basictests.cpp)
|
add_cpp_test(errortests errortests.cpp quicktests)
|
||||||
add_cpp_test(errortests errortests.cpp)
|
add_cpp_test(integer_tests integer_tests.cpp quicktests)
|
||||||
add_cpp_test(integer_tests integer_tests.cpp)
|
add_cpp_test(jsoncheck jsoncheck.cpp quicktests)
|
||||||
add_cpp_test(jsoncheck jsoncheck.cpp)
|
add_cpp_test(parse_many_test parse_many_test.cpp quicktests)
|
||||||
add_cpp_test(parse_many_test parse_many_test.cpp)
|
|
||||||
add_cpp_test(pointercheck pointercheck.cpp quicktests)
|
add_cpp_test(pointercheck pointercheck.cpp quicktests)
|
||||||
add_cpp_test(extracting_values_example extracting_values_example.cpp quicktests)
|
add_cpp_test(extracting_values_example extracting_values_example.cpp quicktests)
|
||||||
|
|
||||||
set_property(
|
# Script tests
|
||||||
TEST basictests errortests integer_tests jsoncheck parse_many_test pointercheck
|
|
||||||
APPEND PROPERTY LABELS quicktests
|
|
||||||
)
|
|
||||||
|
|
||||||
#
|
|
||||||
# json2json test
|
|
||||||
#
|
|
||||||
if (NOT MSVC) # Can't run .sh on windows
|
if (NOT MSVC) # Can't run .sh on windows
|
||||||
|
#
|
||||||
|
# json2json test
|
||||||
|
#
|
||||||
add_test(
|
add_test(
|
||||||
NAME testjson2json
|
NAME testjson2json
|
||||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/testjson2json.sh
|
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/testjson2json.sh
|
||||||
|
@ -44,46 +62,49 @@ if (NOT MSVC) # Can't run .sh on windows
|
||||||
)
|
)
|
||||||
set_property(TEST testjson2json APPEND PROPERTY DEPENDS minify json2json)
|
set_property(TEST testjson2json APPEND PROPERTY DEPENDS minify json2json)
|
||||||
set_property(TEST testjson2json APPEND PROPERTY LABELS slowtests)
|
set_property(TEST testjson2json APPEND PROPERTY LABELS slowtests)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Competition parse test
|
||||||
|
#
|
||||||
|
if (SIMDJSON_COMPETITION)
|
||||||
|
add_executable(allparserscheckfile allparserscheckfile.cpp)
|
||||||
|
target_link_libraries(allparserscheckfile competition-all)
|
||||||
|
|
||||||
|
add_test(issue150 ${CMAKE_CURRENT_SOURCE_DIR}/issue150.sh)
|
||||||
|
set_property(TEST issue150 APPEND PROPERTY DEPENDS allparserscheckfile)
|
||||||
|
set_property(TEST issue150 APPEND PROPERTY LABELS slowtests)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#
|
#
|
||||||
# Competition parse test
|
# Compile-only tests with simdjson flags on
|
||||||
#
|
#
|
||||||
if (SIMDJSON_COMPETITION)
|
|
||||||
add_executable(allparserscheckfile allparserscheckfile.cpp)
|
|
||||||
target_link_libraries(allparserscheckfile competition-all)
|
|
||||||
|
|
||||||
add_test(issue150 ${CMAKE_CURRENT_SOURCE_DIR}/issue150.sh)
|
|
||||||
set_property(TEST issue150 APPEND PROPERTY DEPENDS allparserscheckfile)
|
|
||||||
set_property(TEST issue150 APPEND PROPERTY LABELS slowtests)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#
|
|
||||||
# Compile-only tests
|
|
||||||
#
|
|
||||||
function(add_compile_test TEST_NAME TEST_FILE)
|
|
||||||
add_executable(${TEST_NAME} ${TEST_FILE})
|
|
||||||
set_target_properties(${TEST_NAME} PROPERTIES
|
|
||||||
EXCLUDE_FROM_ALL TRUE
|
|
||||||
EXCLUDE_FROM_DEFAULT_BUILD TRUE)
|
|
||||||
add_test(NAME ${TEST_NAME}
|
|
||||||
COMMAND ${CMAKE_COMMAND} --build . --target ${TEST_NAME} --config $<CONFIGURATION>
|
|
||||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
|
|
||||||
endfunction(add_compile_test)
|
|
||||||
|
|
||||||
# Don't add the tests if we're on VS2017 or older; they don't succeed.
|
# Don't add the tests if we're on VS2017 or older; they don't succeed.
|
||||||
if(NOT (MSVC AND MSVC_VERSION LESS 1920))
|
if(NOT (MSVC AND MSVC_VERSION LESS 1920))
|
||||||
if(SIMDJSON_EXCEPTIONS)
|
if(SIMDJSON_EXCEPTIONS)
|
||||||
add_compile_test(readme_examples readme_examples.cpp quicktests)
|
add_compile_test(readme_examples readme_examples.cpp quicktests)
|
||||||
set_property(
|
set_property(
|
||||||
TEST readme_examples
|
TEST readme_examples
|
||||||
APPEND PROPERTY LABELS quicktests
|
APPEND PROPERTY LABELS quicktests
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
add_compile_test(readme_examples_noexceptions readme_examples_noexceptions.cpp quicktests)
|
add_compile_test(readme_examples_noexceptions readme_examples_noexceptions.cpp quicktests)
|
||||||
|
|
||||||
|
add_compile_test(readme_examples11 readme_examples.cpp quicktests)
|
||||||
|
set_target_properties(readme_examples11 PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF)
|
||||||
|
if (!MSVC)
|
||||||
|
target_compile_options(readme_examples11 PRIVATE -Werror)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_compile_test(readme_examples_noexceptions11 readme_examples_noexceptions.cpp quicktests)
|
||||||
|
set_target_properties(readme_examples_noexceptions11 PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF)
|
||||||
|
if (!MSVC)
|
||||||
|
target_compile_options(readme_examples11 PRIVATE -Werror)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Compile tests that *should fail*
|
# Compile tests that *should fail*
|
||||||
add_compile_test(readme_examples_will_fail_with_exceptions_off readme_examples.cpp)
|
add_compile_test(readme_examples_will_fail_with_exceptions_off readme_examples.cpp quicktests)
|
||||||
target_compile_definitions(readme_examples_will_fail_with_exceptions_off PRIVATE SIMDJSON_EXCEPTIONS=0)
|
target_compile_definitions(readme_examples_will_fail_with_exceptions_off PRIVATE SIMDJSON_EXCEPTIONS=0)
|
||||||
set_tests_properties(readme_examples_will_fail_with_exceptions_off PROPERTIES WILL_FAIL TRUE)
|
set_tests_properties(readme_examples_will_fail_with_exceptions_off PROPERTIES WILL_FAIL TRUE)
|
||||||
set_property(
|
set_property(
|
||||||
|
@ -103,6 +124,14 @@ if(MSVC)
|
||||||
"$<TARGET_FILE_DIR:basictests>") # <--this is out-file path
|
"$<TARGET_FILE_DIR:basictests>") # <--this is out-file path
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Copy the simdjson dll into the tests directory
|
||||||
|
if(MSVC)
|
||||||
|
add_custom_command(TARGET basictests POST_BUILD # Adds a post-build event
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different # which executes "cmake -E copy_if_different..."
|
||||||
|
"$<TARGET_FILE:simdjson>" # <--this is in-file
|
||||||
|
"$<TARGET_FILE_DIR:basictests>") # <--this is out-file path
|
||||||
|
endif()
|
||||||
|
|
||||||
## Next bit should not be needed!
|
## Next bit should not be needed!
|
||||||
#if(CMAKE_INTERPROCEDURAL_OPTIMIZATION)
|
#if(CMAKE_INTERPROCEDURAL_OPTIMIZATION)
|
||||||
# next line is a workaround for an odr-violation in basictests regarding the globals 0x432a40 and 0x52045c under clang
|
# next line is a workaround for an odr-violation in basictests regarding the globals 0x432a40 and 0x52045c under clang
|
||||||
|
@ -112,7 +141,7 @@ endif()
|
||||||
|
|
||||||
## This causes problems
|
## This causes problems
|
||||||
# add_executable(singleheader ./singleheadertest.cpp ${PROJECT_SOURCE_DIR}/singleheader/simdjson.cpp)
|
# add_executable(singleheader ./singleheadertest.cpp ${PROJECT_SOURCE_DIR}/singleheader/simdjson.cpp)
|
||||||
# target_link_libraries(singleheader simdjson)
|
# target_link_libraries(singleheader simdjson simdjson-flags)
|
||||||
# add_test(singleheader singleheader)
|
# add_test(singleheader singleheader)
|
||||||
|
|
||||||
add_subdirectory(compilation_failure_tests)
|
add_subdirectory(compilation_failure_tests)
|
||||||
|
|
|
@ -109,7 +109,7 @@ namespace treewalk_1 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (SIMDJSON_CPLUSPLUS >= 201703L)
|
#ifdef SIMDJSON_CPLUSPLUS17
|
||||||
void basics_cpp17_1() {
|
void basics_cpp17_1() {
|
||||||
dom::parser parser;
|
dom::parser parser;
|
||||||
padded_string json = R"( { "foo": 1, "bar": 2 } )"_padded;
|
padded_string json = R"( { "foo": 1, "bar": 2 } )"_padded;
|
||||||
|
@ -179,7 +179,7 @@ void performance_1() {
|
||||||
cout << doc2 << endl;
|
cout << doc2 << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (SIMDJSON_CPLUSPLUS >= 201703L)
|
#ifdef SIMDJSON_CPLUSPLUS17
|
||||||
// The web_request part of this is aspirational, so we compile as much as we can here
|
// The web_request part of this is aspirational, so we compile as much as we can here
|
||||||
void performance_2() {
|
void performance_2() {
|
||||||
dom::parser parser(1024*1024); // Never grow past documents > 1MB
|
dom::parser parser(1024*1024); // Never grow past documents > 1MB
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace simdjson;
|
using namespace simdjson;
|
||||||
|
|
||||||
#if (SIMDJSON_CPLUSPLUS >= 201703L)
|
#ifdef SIMDJSON_CPLUSPLUS17
|
||||||
void basics_error_1() {
|
void basics_error_1() {
|
||||||
dom::parser parser;
|
dom::parser parser;
|
||||||
auto json = "1"_padded;
|
auto json = "1"_padded;
|
||||||
|
@ -76,7 +76,7 @@ void basics_error_3() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (SIMDJSON_CPLUSPLUS >= 201703L)
|
#ifdef SIMDJSON_CPLUSPLUS17
|
||||||
void basics_error_3_cpp17() {
|
void basics_error_3_cpp17() {
|
||||||
auto cars_json = R"( [
|
auto cars_json = R"( [
|
||||||
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
|
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
link_libraries(simdjson)
|
link_libraries(simdjson simdjson-flags simdjson-windows-headers)
|
||||||
link_libraries(simdjson-windows-headers)
|
|
||||||
|
|
||||||
add_executable(json2json json2json.cpp)
|
add_executable(json2json json2json.cpp)
|
||||||
add_executable(jsonstats jsonstats.cpp)
|
add_executable(jsonstats jsonstats.cpp)
|
||||||
|
|
Loading…
Reference in New Issue