From 09cf18a64610100f29889fd51469fd5168cc2225 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Thu, 9 Apr 2020 17:31:35 -0700 Subject: [PATCH 1/2] Add C++11 tests to cmake - Add simdjson-flags target so callers don't have flags forced on them --- .appveyor.yml | 2 +- CMakeLists.txt | 105 +++++++++++++++++----- benchmark/CMakeLists.txt | 4 +- examples/quickstart/CMakeLists.txt | 56 ++++++++++-- fuzz/CMakeLists.txt | 2 +- include/CMakeLists.txt | 69 ++------------- include/simdjson/common_defs.h | 3 +- src/CMakeLists.txt | 38 +++++--- tests/CMakeLists.txt | 116 ++++++++++++++----------- tests/readme_examples.cpp | 4 +- tests/readme_examples_noexceptions.cpp | 4 +- tools/CMakeLists.txt | 3 +- 12 files changed, 244 insertions(+), 162 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 59299e7d..a4f30cc5 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -20,7 +20,7 @@ build_script: - mkdir 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 --build . --config %Configuration% + - cmake --verbose --build . --config %Configuration% test_script: - ctest --verbose --output-on-failure -C %Configuration% diff --git a/CMakeLists.txt b/CMakeLists.txt index 256bcf4d..5c292cbc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,20 +12,6 @@ project(simdjson 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_MINOR 3) set(PROJECT_VERSION_PATCH 1) @@ -34,7 +20,7 @@ set(SIMDJSON_LIB_SOVERSION "1" CACHE STRING "simdjson library soversion") if(MSVC) 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) + set(SIMDJSON_COMPETITION CACHE STRING "Compile competitive benchmarks" OFF) else() 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) @@ -43,11 +29,85 @@ option(SIMDJSON_GOOGLE_BENCHMARKS "compile the Google Benchmark benchmarks" OFF) 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() + # # Create the top level simdjson library (must be done at this level to use both src/ and include/ # directories) # -add_subdirectory(windows) add_subdirectory(include) add_subdirectory(src) @@ -60,10 +120,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_BENCHMARK_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/jsonexamples/") +add_subdirectory(windows) add_subdirectory(dependencies) -add_subdirectory(tools) add_subdirectory(tests) add_subdirectory(examples) +add_subdirectory(tools) add_subdirectory(benchmark) # for fuzzing, read the comments in the fuzz/CMakeLists.txt file @@ -72,11 +133,9 @@ if(ENABLE_FUZZING) add_subdirectory(fuzz) endif() -if(${CMAKE_C_COMPILER_ID} MATCHES "Intel") # icc / icpc - # prevent shared libraries from depending on Intel provided libraries - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-intel") -endif() - +# +# CPack +# set(CPACK_PACKAGE_VENDOR "Daniel Lemire") set(CPACK_PACKAGE_CONTACT "lemire@gmail.com") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Parsing gigabytes of JSON per second") @@ -91,5 +150,3 @@ set(CPACK_RPM_PACKAGE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") set(CPACK_SOURCE_GENERATOR "TGZ;ZIP") include(CPack) - - diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 523f0773..93e59484 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -1,6 +1,6 @@ include_directories( . linux ) -link_libraries(simdjson) -# add_executable(benchfeatures benchfeatures.cpp) +link_libraries(simdjson simdjson-flags) +# add_executable(benchfeatures benchfeatures.cpp) # doesn't presently compile at all add_executable(get_corpus_benchmark get_corpus_benchmark.cpp) add_executable(perfdiff perfdiff.cpp) add_executable(parse parse.cpp) diff --git a/examples/quickstart/CMakeLists.txt b/examples/quickstart/CMakeLists.txt index ced2aa31..edf3a054 100644 --- a/examples/quickstart/CMakeLists.txt +++ b/examples/quickstart/CMakeLists.txt @@ -1,6 +1,52 @@ -if(SIMDJSON_EXCEPTIONS) - add_executable(quickstart quickstart.cpp) - target_link_libraries(quickstart PRIVATE simdjson) +# +# Quickstart compile tests don't require any flags +# + +# TODO run amalgamate first! + +function(add_quickstart_test TEST_NAME SOURCE_FILE) + # Second argument is C++ standard name + if (${ARGV2}) + if (MSVC) + set(QUICKSTART_FLAGS /std:${ARGV2}) + else() + set(QUICKSTART_FLAGS -Werror -std=${ARGV2}) + endif() + else() + if(MSVC) + set(QUICKSTART_FLAGS "") + else() + set(QUICKSTART_FLAGS -Werror) + endif() + endif() + + # Third argument tells whether to compile with -fno-exceptions + if (${ARGV3}) + if (NOT MSVC) + set(QUICKSTART_FLAGS "${QUICKSTART_FLAGS} -fno-exceptions") + endif() + endif() + + 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/quickstart.cpp + ) +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_executable(quickstart_noexceptions quickstart_noexceptions.cpp) -target_link_libraries(quickstart_noexceptions PRIVATE simdjson) + +add_quickstart_test(quickstart_noexceptions quickstart_noexceptions.cpp "" true) +add_quickstart_test(quickstart_noexceptions11 quickstart_noexceptions.cpp c++11 true) +set_property( TEST quickstart_noxceptions APPEND PROPERTY LABELS quicktests ) +set_property( TEST quickstart_noexceptions11 APPEND PROPERTY LABELS slowtests ) diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt index c0b36c8a..d0606ec7 100644 --- a/fuzz/CMakeLists.txt +++ b/fuzz/CMakeLists.txt @@ -44,7 +44,7 @@ macro(implement_fuzzer sourcefile) if (SIMDJSON_FUZZ_LINKMAIN) target_sources(${name} PRIVATE main.cpp) endif () - target_link_libraries(${name} PRIVATE simdjson) + target_link_libraries(${name} PRIVATE simdjson simdjson-flags) if (SIMDJSON_FUZZ_LDFLAGS) target_link_libraries(${name} PRIVATE ${SIMDJSON_FUZZ_LDFLAGS}) endif () diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 7c10d422..0b44920b 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,68 +1,15 @@ # -# 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) - -# Include directory +target_compile_features(simdjson-headers INTERFACE cxx_std_11) # headers require at least C++11 target_include_directories(simdjson-headers INTERFACE - $ - $) - -# 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 $<$:-ggdb>) - target_compile_options(simdjson-headers INTERFACE $<$:-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 EXPORT simdjson-headers-config diff --git a/include/simdjson/common_defs.h b/include/simdjson/common_defs.h index 1df0822c..ce82844c 100644 --- a/include/simdjson/common_defs.h +++ b/include/simdjson/common_defs.h @@ -108,7 +108,8 @@ constexpr size_t DEFAULT_MAX_DEPTH = 1024; SIMDJSON_DISABLE_GCC_WARNING(-Wextra) \ SIMDJSON_DISABLE_GCC_WARNING(-Wshadow) \ 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_DISABLE_GCC_WARNING(WARNING) SIMDJSON_PRAGMA(GCC diagnostic ignored #WARNING) #define SIMDJSON_DISABLE_DEPRECATED_WARNING SIMDJSON_DISABLE_GCC_WARNING(-Wdeprecated-declarations) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6bcbccdf..f16f2fc9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,29 @@ # -# 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 .) + +# +# 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 ${CMAKE_CURRENT_SOURCE_DIR}/simdjson.cpp) +target_link_libraries(simdjson-source INTERFACE simdjson-include-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) @@ -15,9 +39,8 @@ else() endif() endif() -target_sources(simdjson PRIVATE simdjson.cpp) -target_link_libraries(simdjson PUBLIC simdjson-headers) -target_include_directories(simdjson PRIVATE .) +target_link_libraries(simdjson PRIVATE simdjson-source simdjson-flags) +target_link_libraries(simdjson INTERFACE simdjson-headers) # Only expose the headers, not sources if(NOT MSVC) ## We output the library at the root of the current directory where cmake is invoked @@ -26,13 +49,6 @@ if(NOT MSVC) MESSAGE( STATUS "Library output directory (does not apply to Visual Studio): " ${CMAKE_BINARY_DIR}) 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 # diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 39276f88..ac67feac 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,42 +1,60 @@ # Helper so we don't have to repeat ourselves so much function(add_cpp_test TEST_NAME TEST_FILE) + # If a source file is passed, add an executable add_executable(${TEST_NAME} ${TEST_FILE}) 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 $ + 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. -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. 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) - target_link_libraries(stringparsingcheck simdjson-source) + target_link_libraries(stringparsingcheck simdjson-include-source) endif() # All remaining tests link with simdjson proper link_libraries(simdjson) - -add_cpp_test(basictests basictests.cpp) -add_cpp_test(errortests errortests.cpp) -add_cpp_test(integer_tests integer_tests.cpp) -add_cpp_test(jsoncheck jsoncheck.cpp) -add_cpp_test(parse_many_test parse_many_test.cpp) +add_cpp_test(basictests basictests.cpp quicktests) +add_cpp_test(errortests errortests.cpp quicktests) +add_cpp_test(integer_tests integer_tests.cpp quicktests) +add_cpp_test(jsoncheck jsoncheck.cpp quicktests) +add_cpp_test(parse_many_test parse_many_test.cpp quicktests) add_cpp_test(pointercheck pointercheck.cpp quicktests) add_cpp_test(extracting_values_example extracting_values_example.cpp quicktests) -set_property( - TEST basictests errortests integer_tests jsoncheck parse_many_test pointercheck - APPEND PROPERTY LABELS quicktests -) - -# -# json2json test -# +# Script tests if (NOT MSVC) # Can't run .sh on windows + # + # json2json test + # add_test( NAME testjson2json COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/testjson2json.sh @@ -44,46 +62,44 @@ if (NOT MSVC) # Can't run .sh on windows ) set_property(TEST testjson2json APPEND PROPERTY DEPENDS minify json2json) 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() # -# 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 $ - 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. if(NOT (MSVC AND MSVC_VERSION LESS 1920)) -if(SIMDJSON_EXCEPTIONS) - add_compile_test(readme_examples readme_examples.cpp quicktests) - set_property( - TEST readme_examples - APPEND PROPERTY LABELS quicktests - ) -endif() + if(SIMDJSON_EXCEPTIONS) + add_compile_test(readme_examples readme_examples.cpp quicktests) + set_property( + TEST readme_examples + APPEND PROPERTY LABELS quicktests + ) + endif() 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) + target_compile_options(readme_examples11 PRIVATE -Werror) + 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) + target_compile_options(readme_examples_noexceptions11 PRIVATE -Werror) + # 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) set_tests_properties(readme_examples_will_fail_with_exceptions_off PROPERTIES WILL_FAIL TRUE) set_property( @@ -112,7 +128,7 @@ endif() ## This causes problems # 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_subdirectory(compilation_failure_tests) diff --git a/tests/readme_examples.cpp b/tests/readme_examples.cpp index 70624de2..88fcc404 100644 --- a/tests/readme_examples.cpp +++ b/tests/readme_examples.cpp @@ -109,7 +109,7 @@ namespace treewalk_1 { } } -#if (SIMDJSON_CPLUSPLUS >= 201703L) +#ifdef SIMDJSON_CPLUSPLUS17 void basics_cpp17_1() { dom::parser parser; padded_string json = R"( { "foo": 1, "bar": 2 } )"_padded; @@ -179,7 +179,7 @@ void performance_1() { 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 void performance_2() { dom::parser parser(1024*1024); // Never grow past documents > 1MB diff --git a/tests/readme_examples_noexceptions.cpp b/tests/readme_examples_noexceptions.cpp index e6c965c8..473cac17 100644 --- a/tests/readme_examples_noexceptions.cpp +++ b/tests/readme_examples_noexceptions.cpp @@ -4,7 +4,7 @@ using namespace std; using namespace simdjson; -#if (SIMDJSON_CPLUSPLUS >= 201703L) +#ifdef SIMDJSON_CPLUSPLUS17 void basics_error_1() { dom::parser parser; auto json = "1"_padded; @@ -76,7 +76,7 @@ void basics_error_3() { } } -#if (SIMDJSON_CPLUSPLUS >= 201703L) +#ifdef SIMDJSON_CPLUSPLUS17 void basics_error_3_cpp17() { auto cars_json = R"( [ { "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] }, diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index b952a7f1..60ab48cf 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1,5 +1,4 @@ -link_libraries(simdjson) -link_libraries(simdjson-windows-headers) +link_libraries(simdjson simdjson-flags simdjson-windows-headers) add_executable(json2json json2json.cpp) add_executable(jsonstats jsonstats.cpp) From fd418f568c1e15f4d09518db1f0c5d5d8af8399a Mon Sep 17 00:00:00 2001 From: John Keiser Date: Fri, 10 Apr 2020 16:37:00 -0700 Subject: [PATCH 2/2] Fix c++11 warnings on clang - namespace x::y is C++17 - static_assert requires message in C++11 --- .appveyor.yml | 5 +- .gitignore | 1 + CMakeLists.txt | 20 ++++- HACKING.md | 6 +- examples/quickstart/CMakeLists.txt | 87 +++++++++++---------- include/CMakeLists.txt | 5 +- include/simdjson.h | 4 +- include/simdjson/document.h | 18 ++--- include/simdjson/document_stream.h | 6 +- include/simdjson/implementation.h | 2 +- include/simdjson/inline/document.h | 15 ++-- include/simdjson/inline/document_stream.h | 13 ++- include/simdjson/inline/error.h | 6 +- include/simdjson/inline/padded_string.h | 6 +- include/simdjson/internal/jsonformatutils.h | 6 +- include/simdjson/padded_string.h | 6 +- src/CMakeLists.txt | 10 ++- src/arm64/bitmanipulation.h | 19 ++--- src/arm64/bitmask.h | 6 +- src/arm64/implementation.h | 6 +- src/arm64/numberparsing.h | 6 +- src/arm64/simd.h | 8 +- src/arm64/stage1_find_marks.h | 6 +- src/arm64/stage2_build_tape.h | 6 +- src/arm64/stringparsing.h | 9 ++- src/document_parser_callbacks.h | 6 +- src/error.cpp | 8 +- src/fallback/bitmanipulation.h | 19 ++--- src/fallback/implementation.h | 7 +- src/fallback/numberparsing.h | 7 +- src/fallback/stage1_find_marks.h | 10 ++- src/fallback/stage2_build_tape.h | 4 +- src/fallback/stringparsing.h | 6 +- src/generic/atomparsing.h | 2 +- src/generic/numberparsing.h | 2 +- src/haswell/bitmanipulation.h | 15 ++-- src/haswell/bitmask.h | 7 +- src/haswell/implementation.h | 6 +- src/haswell/numberparsing.h | 7 +- src/haswell/simd.h | 9 ++- src/haswell/stage1_find_marks.h | 7 +- src/haswell/stage2_build_tape.h | 4 +- src/haswell/stringparsing.h | 8 +- src/implementation.cpp | 21 ++--- src/isadetection.h | 2 +- src/westmere/bitmanipulation.h | 18 ++--- src/westmere/bitmask.h | 7 +- src/westmere/implementation.h | 6 +- src/westmere/numberparsing.h | 7 +- src/westmere/simd.h | 9 ++- src/westmere/stage1_find_marks.h | 7 +- src/westmere/stage2_build_tape.h | 6 +- src/westmere/stringparsing.h | 8 +- tests/CMakeLists.txt | 17 +++- 54 files changed, 319 insertions(+), 205 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index a4f30cc5..c447a9ca 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -20,10 +20,11 @@ build_script: - mkdir 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 --verbose --build . --config %Configuration% + - cmake -LH .. + - cmake --build . --config %Configuration% --verbose test_script: - - ctest --verbose --output-on-failure -C %Configuration% + - ctest --output-on-failure -C %Configuration% --verbose matrix: fast_finish: true diff --git a/.gitignore b/.gitignore index 6fd32b0f..25bf6d4d 100644 --- a/.gitignore +++ b/.gitignore @@ -87,6 +87,7 @@ objs /examples/quickstart/twitter.json /fuzz/fuzz_dump /fuzz/fuzz_dump_raw_tape +/fuzz/fuzz_minify /fuzz/fuzz_parser /fuzz/fuzz_print_json /get_corpus_benchmark diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c292cbc..a5606f2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,8 +20,8 @@ set(SIMDJSON_LIB_SOVERSION "1" CACHE STRING "simdjson library soversion") if(MSVC) option(SIMDJSON_BUILD_STATIC "Build a static library" ON) # turning it on disables the production of a dynamic library - set(SIMDJSON_COMPETITION CACHE STRING "Compile competitive benchmarks" OFF) - else() + option(SIMDJSON_COMPETITION "Compile competitive benchmarks" OFF) +else() 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) endif() @@ -104,6 +104,22 @@ 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/ # directories) diff --git a/HACKING.md b/HACKING.md index a1d9d0a5..b3455a3e 100644 --- a/HACKING.md +++ b/HACKING.md @@ -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 enclosed in a namespace, e.g.: ```c++ - namespace simdjson::haswell { - #include "generic/stage1_find_marks.h" + namespace simdjson { + namespace haswell { + #include "generic/stage1_find_marks.h" + } } ``` diff --git a/examples/quickstart/CMakeLists.txt b/examples/quickstart/CMakeLists.txt index edf3a054..59d89f83 100644 --- a/examples/quickstart/CMakeLists.txt +++ b/examples/quickstart/CMakeLists.txt @@ -2,51 +2,56 @@ # Quickstart compile tests don't require any flags # -# TODO run amalgamate first! - -function(add_quickstart_test TEST_NAME SOURCE_FILE) - # Second argument is C++ standard name - if (${ARGV2}) +# 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) - set(QUICKSTART_FLAGS /std:${ARGV2}) + 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() - set(QUICKSTART_FLAGS -Werror -std=${ARGV2}) + 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() - else() - if(MSVC) - set(QUICKSTART_FLAGS "") - else() - set(QUICKSTART_FLAGS -Werror) + + # 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() - # Third argument tells whether to compile with -fno-exceptions - if (${ARGV3}) - if (NOT MSVC) - set(QUICKSTART_FLAGS "${QUICKSTART_FLAGS} -fno-exceptions") - endif() - endif() - - 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/quickstart.cpp - ) -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 ) + 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() - -add_quickstart_test(quickstart_noexceptions quickstart_noexceptions.cpp "" true) -add_quickstart_test(quickstart_noexceptions11 quickstart_noexceptions.cpp c++11 true) -set_property( TEST quickstart_noxceptions APPEND PROPERTY LABELS quicktests ) -set_property( TEST quickstart_noexceptions11 APPEND PROPERTY LABELS slowtests ) diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 0b44920b..0dc69436 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -6,10 +6,7 @@ # add_library(simdjson-headers INTERFACE) target_compile_features(simdjson-headers INTERFACE cxx_std_11) # headers require at least C++11 -target_include_directories(simdjson-headers INTERFACE - $ - $ -) +target_include_directories(simdjson-headers INTERFACE $) install(TARGETS simdjson-headers EXPORT simdjson-headers-config diff --git a/include/simdjson.h b/include/simdjson.h index 18f7327d..958291de 100644 --- a/include/simdjson.h +++ b/include/simdjson.h @@ -17,12 +17,12 @@ #include "simdjson/document.h" #include "simdjson/document_stream.h" -// Deprecated API +// // Deprecated API #include "simdjson/jsonparser.h" #include "simdjson/parsedjson.h" #include "simdjson/parsedjson_iterator.h" -// Inline functions +// // Inline functions #include "simdjson/inline/document.h" #include "simdjson/inline/document_stream.h" #include "simdjson/inline/error.h" diff --git a/include/simdjson/document.h b/include/simdjson/document.h index 97baeea4..bf7c8310 100644 --- a/include/simdjson/document.h +++ b/include/simdjson/document.h @@ -10,7 +10,8 @@ #include "simdjson/simdjson.h" #include "simdjson/padded_string.h" -namespace simdjson::dom { +namespace simdjson { +namespace dom { class parser; class element; @@ -23,9 +24,7 @@ class document_stream; /** The default batch size for parser.parse_many() and parser.load_many() */ static constexpr size_t DEFAULT_BATCH_SIZE = 1000000; -} // namespace simdjson::dom - -namespace simdjson { +} // namespace dom template<> struct simdjson_result; template<> struct simdjson_result; @@ -34,9 +33,7 @@ template<> struct simdjson_result; template class minify; -} // namespace simdjson - -namespace simdjson::internal { +namespace internal { using namespace simdjson::dom; @@ -90,9 +87,9 @@ public: size_t json_index; }; -} // namespace simdjson::internal +} // namespace internal -namespace simdjson::dom { +namespace dom { /** * The actual concrete type of a JSON element @@ -1087,7 +1084,8 @@ private: friend class document_stream; }; // class parser -} // namespace simdjson::dom +} // namespace dom +} // namespace simdjson namespace simdjson { diff --git a/include/simdjson/document_stream.h b/include/simdjson/document_stream.h index 8d4504aa..b5ebf5fe 100644 --- a/include/simdjson/document_stream.h +++ b/include/simdjson/document_stream.h @@ -4,7 +4,8 @@ #include #include "simdjson/document.h" -namespace simdjson::dom { +namespace simdjson { +namespace dom { /** * A forward-only stream of documents. @@ -140,6 +141,7 @@ private: friend class dom::parser; }; // class document_stream -} // end of namespace simdjson::dom +} // namespace dom +} // namespace simdjson #endif // SIMDJSON_DOCUMENT_STREAM_H diff --git a/include/simdjson/implementation.h b/include/simdjson/implementation.h index 6277e736..60594a4b 100644 --- a/include/simdjson/implementation.h +++ b/include/simdjson/implementation.h @@ -218,7 +218,7 @@ private: std::atomic ptr; }; -} // namespace [simdjson::]internal +} // namespace internal /** * The list of available implementations compiled into simdjson. diff --git a/include/simdjson/inline/document.h b/include/simdjson/inline/document.h index 833e4a28..8b66ff6f 100644 --- a/include/simdjson/inline/document.h +++ b/include/simdjson/inline/document.h @@ -189,9 +189,8 @@ inline size_t simdjson_result::size() const noexcept(false) { #endif // SIMDJSON_EXCEPTIONS -} // namespace simdjson -namespace simdjson::dom { +namespace dom { // // document inline implementation @@ -922,9 +921,8 @@ inline bool element::dump_raw_tape(std::ostream &out) const noexcept { return doc->dump_raw_tape(out); } -} // namespace simdjson::dom +} // namespace dom -namespace simdjson { // // minify inline implementation @@ -1104,9 +1102,8 @@ inline std::ostream& minify>::print(std::ostream& o #endif -} // namespace simdjson -namespace simdjson::internal { +namespace internal { // // tape_ref inline implementation @@ -1173,7 +1170,7 @@ really_inline uint32_t internal::tape_ref::scope_count() const noexcept { template 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... // return *reinterpret_cast(&doc->tape[json_index + 1]); // It is not generally safe. It is safer, and often faster to rely @@ -1192,7 +1189,7 @@ inline std::string_view internal::tape_ref::get_string_view() const noexcept { ); } - -} // namespace simdjson::internal +} // namespace internal +} // namespace simdjson #endif // SIMDJSON_INLINE_DOCUMENT_H diff --git a/include/simdjson/inline/document_stream.h b/include/simdjson/inline/document_stream.h index 93cf5122..8bd75dbe 100644 --- a/include/simdjson/inline/document_stream.h +++ b/include/simdjson/inline/document_stream.h @@ -7,7 +7,8 @@ #include #include -namespace simdjson::internal { +namespace simdjson { +namespace internal { /** * 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; } -} // namespace simdjson::internal +} // namespace internal -namespace simdjson::dom { +} // namespace simdjson + +namespace simdjson { +namespace dom { really_inline document_stream::document_stream( dom::parser &_parser, @@ -272,5 +276,6 @@ inline error_code document_stream::json_parse() noexcept { } #endif // SIMDJSON_THREADS_ENABLED -} // namespace simdjson::dom +} // namespace dom +} // namespace simdjson #endif // SIMDJSON_INLINE_DOCUMENT_STREAM_H diff --git a/include/simdjson/inline/error.h b/include/simdjson/inline/error.h index 5cece7a7..8f961ca1 100644 --- a/include/simdjson/inline/error.h +++ b/include/simdjson/inline/error.h @@ -4,7 +4,8 @@ #include "simdjson/error.h" #include -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 struct error_code_info { error_code code; @@ -12,9 +13,8 @@ namespace simdjson::internal { }; // These MUST match the codes in error_code. We check this constraint in basictests. 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 { // If you're using error_code, we're trusting you got it from the enum. diff --git a/include/simdjson/inline/padded_string.h b/include/simdjson/inline/padded_string.h index 8caed20a..748e2c47 100644 --- a/include/simdjson/inline/padded_string.h +++ b/include/simdjson/inline/padded_string.h @@ -9,7 +9,8 @@ #include #include -namespace simdjson::internal { +namespace simdjson { +namespace internal { // 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 @@ -30,9 +31,8 @@ inline char *allocate_padded_buffer(size_t length) noexcept { return 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(size_t length) noexcept diff --git a/include/simdjson/internal/jsonformatutils.h b/include/simdjson/internal/jsonformatutils.h index f4c585a0..4c16eaab 100644 --- a/include/simdjson/internal/jsonformatutils.h +++ b/include/simdjson/internal/jsonformatutils.h @@ -5,7 +5,8 @@ #include #include -namespace simdjson::internal { +namespace simdjson { +namespace internal { class escape_json_string; @@ -58,6 +59,7 @@ inline std::ostream& operator<<(std::ostream& out, const escape_json_string &une return out; } -} // namespace simdjson::internal +} // namespace internal +} // namespace simdjson #endif // SIMDJSON_INTERNAL_JSONFORMATUTILS_H diff --git a/include/simdjson/padded_string.h b/include/simdjson/padded_string.h index 5f1954ad..2f60131f 100644 --- a/include/simdjson/padded_string.h +++ b/include/simdjson/padded_string.h @@ -127,7 +127,8 @@ inline simdjson::padded_string operator "" _padded(const char *str, size_t 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 // "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(...)) inline char *allocate_padded_buffer(size_t length) noexcept; -} // namespace simdjson::internal; +} // namespace internal +} // namespace simdjson #endif // SIMDJSON_PADDED_STRING_H diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f16f2fc9..8148388f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,7 +6,8 @@ # add_library(simdjson-include-source INTERFACE) target_link_libraries(simdjson-include-source INTERFACE simdjson-headers) -target_include_directories(simdjson-include-source INTERFACE .) +target_include_directories(simdjson-include-source INTERFACE $) +export_private_library(simdjson-include-source) # # For callers who intend to compile simdjson.cpp themselves. @@ -15,8 +16,9 @@ target_include_directories(simdjson-include-source INTERFACE .) # the .cpp sources. It does not specify any compiler flags. # add_library(simdjson-source INTERFACE) -target_sources(simdjson-source INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/simdjson.cpp) +target_sources(simdjson-source INTERFACE $/simdjson.cpp) target_link_libraries(simdjson-source INTERFACE simdjson-include-source) +export_private_library(simdjson-source) # # simdjson is the distributed library compiled with flags. @@ -39,9 +41,11 @@ else() endif() endif() -target_link_libraries(simdjson PRIVATE simdjson-source simdjson-flags) target_link_libraries(simdjson INTERFACE simdjson-headers) # Only expose the headers, not sources +target_link_libraries(simdjson PRIVATE simdjson-source simdjson-flags) + + if(NOT MSVC) ## We output the library at the root of the current directory where cmake is invoked ## This is handy but Visual Studio will happily ignore us diff --git a/src/arm64/bitmanipulation.h b/src/arm64/bitmanipulation.h index d0616065..4c55ef5f 100644 --- a/src/arm64/bitmanipulation.h +++ b/src/arm64/bitmanipulation.h @@ -4,28 +4,24 @@ #include "simdjson.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, // but the algorithms do not end up using the returned value. -// 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 */ +// Sadly, sanitizers are not smart enough to figure it out. really_inline int trailing_zeroes(uint64_t input_num) { - #ifdef _MSC_VER unsigned long ret; // Search the mask data from least significant bit (LSB) // to the most significant bit (MSB) for a set bit (1). _BitScanForward64(&ret, input_num); return (int)ret; -#else +#else // _MSC_VER return __builtin_ctzll(input_num); #endif // _MSC_VER - -} // namespace simdjson::arm64 +} /* result might be undefined when input_num is zero */ 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 } -} // namespace simdjson::arm64 +} // namespace arm64 +} // namespace simdjson #endif // SIMDJSON_ARM64_BITMANIPULATION_H diff --git a/src/arm64/bitmask.h b/src/arm64/bitmask.h index 11f39a4d..3c8ceed9 100644 --- a/src/arm64/bitmask.h +++ b/src/arm64/bitmask.h @@ -5,7 +5,8 @@ #include "arm64/intrinsics.h" -namespace simdjson::arm64 { +namespace simdjson { +namespace arm64 { // // 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; } -} // namespace simdjson::arm64 +} // namespace arm64 +} // namespace simdjson UNTARGET_REGION #endif diff --git a/src/arm64/implementation.h b/src/arm64/implementation.h index 29d42d29..e8da3354 100644 --- a/src/arm64/implementation.h +++ b/src/arm64/implementation.h @@ -4,7 +4,8 @@ #include "simdjson.h" #include "isadetection.h" -namespace simdjson::arm64 { +namespace simdjson { +namespace arm64 { 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; }; -} // namespace simdjson::arm64 +} // namespace arm64 +} // namespace simdjson #endif // SIMDJSON_ARM64_IMPLEMENTATION_H diff --git a/src/arm64/numberparsing.h b/src/arm64/numberparsing.h index 03523a42..b00263f0 100644 --- a/src/arm64/numberparsing.h +++ b/src/arm64/numberparsing.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); #endif -namespace simdjson::arm64 { +namespace simdjson { +namespace arm64 { // we don't have SSE, so let us use a scalar function // 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" -} // namespace simdjson::arm64 +} // namespace arm64 +} // namespace simdjson #endif // SIMDJSON_ARM64_NUMBERPARSING_H diff --git a/src/arm64/simd.h b/src/arm64/simd.h index 404db870..4e02aa9c 100644 --- a/src/arm64/simd.h +++ b/src/arm64/simd.h @@ -6,7 +6,9 @@ #include "arm64/bitmanipulation.h" #include "arm64/intrinsics.h" -namespace simdjson::arm64::simd { +namespace simdjson { +namespace arm64 { +namespace simd { template struct simd8; @@ -387,6 +389,8 @@ namespace simdjson::arm64::simd { } }; // struct simd8x64 -} // namespace simdjson::arm64::simd +} // namespace simd +} // namespace arm64 +} // namespace simdjson #endif // SIMDJSON_ARM64_SIMD_H diff --git a/src/arm64/stage1_find_marks.h b/src/arm64/stage1_find_marks.h index da61fb95..18bb3951 100644 --- a/src/arm64/stage1_find_marks.h +++ b/src/arm64/stage1_find_marks.h @@ -7,7 +7,8 @@ #include "arm64/bitmanipulation.h" #include "arm64/implementation.h" -namespace simdjson::arm64 { +namespace simdjson { +namespace arm64 { 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); } -} // namespace simdjson::arm64 +} // namespace arm64 +} // namespace simdjson #endif // SIMDJSON_ARM64_STAGE1_FIND_MARKS_H diff --git a/src/arm64/stage2_build_tape.h b/src/arm64/stage2_build_tape.h index 2b711157..58804c56 100644 --- a/src/arm64/stage2_build_tape.h +++ b/src/arm64/stage2_build_tape.h @@ -6,12 +6,14 @@ #include "arm64/stringparsing.h" #include "arm64/numberparsing.h" -namespace simdjson::arm64 { +namespace simdjson { +namespace arm64 { #include "generic/atomparsing.h" #include "generic/stage2_build_tape.h" #include "generic/stage2_streaming_build_tape.h" -} // namespace simdjson::arm64 +} // namespace arm64 +} // namespace simdjson #endif // SIMDJSON_ARM64_STAGE2_BUILD_TAPE_H diff --git a/src/arm64/stringparsing.h b/src/arm64/stringparsing.h index 7dd9db68..2069dcff 100644 --- a/src/arm64/stringparsing.h +++ b/src/arm64/stringparsing.h @@ -7,7 +7,8 @@ #include "arm64/intrinsics.h" #include "arm64/bitmanipulation.h" -namespace simdjson::arm64 { +namespace simdjson { +namespace arm64 { 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) { // this can read up to 31 bytes beyond the buffer size, but we require // 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 v0(src); simd8 v1(src + sizeof(v0)); v0.store(dst); @@ -46,7 +47,7 @@ really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8 #include "generic/stringparsing.h" -} -// namespace simdjson::amd64 +} // namespace arm64 +} // namespace simdjson #endif // SIMDJSON_ARM64_STRINGPARSING_H diff --git a/src/document_parser_callbacks.h b/src/document_parser_callbacks.h index 5a54a45f..c2b4b63b 100644 --- a/src/document_parser_callbacks.h +++ b/src/document_parser_callbacks.h @@ -3,7 +3,8 @@ #include "simdjson.h" -namespace simdjson::dom { +namespace simdjson { +namespace dom { // // 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(cntsat) << 32); } -} // namespace simdjson::dom +} // namespace simdjson +} // namespace dom #endif // SIMDJSON_DOCUMENT_PARSER_CALLBACKS_H diff --git a/src/error.cpp b/src/error.cpp index 0fbbff8a..3e9701ca 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -1,6 +1,8 @@ #include "simdjson/error.h" -namespace simdjson::internal { +namespace simdjson { +namespace internal { + SIMDJSON_DLLIMPORTEXPORT const error_code_info error_codes[] { { SUCCESS, "No error" }, { 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." }, { UNEXPECTED_ERROR, "Unexpected error, consider reporting this problem as you may have found a bug in simdjson" } }; // error_messages[] -} \ No newline at end of file + +} // namespace internal +} // namespace simdjson \ No newline at end of file diff --git a/src/fallback/bitmanipulation.h b/src/fallback/bitmanipulation.h index 6d00c80c..96a557fa 100644 --- a/src/fallback/bitmanipulation.h +++ b/src/fallback/bitmanipulation.h @@ -4,28 +4,24 @@ #include "simdjson.h" #include -namespace simdjson::fallback { +namespace simdjson { +namespace fallback { -#ifndef _MSC_VER // We sometimes call trailing_zero on inputs that are zero, // but the algorithms do not end up using the returned value. -// 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 */ +// Sadly, sanitizers are not smart enough to figure it out. +NO_SANITIZE_UNDEFINED really_inline int trailing_zeroes(uint64_t input_num) { - #ifdef _MSC_VER unsigned long ret; // Search the mask data from least significant bit (LSB) // to the most significant bit (MSB) for a set bit (1). _BitScanForward64(&ret, input_num); return (int)ret; -#else +#else // _MSC_VER return __builtin_ctzll(input_num); #endif // _MSC_VER - -} // namespace simdjson::arm64 +} /* result might be undefined when input_num is zero */ 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::max() / value2; } -} // namespace simdjson::fallback +} // namespace fallback +} // namespace simdjson #endif // SIMDJSON_FALLBACK_BITMANIPULATION_H diff --git a/src/fallback/implementation.h b/src/fallback/implementation.h index b184120a..90372b00 100644 --- a/src/fallback/implementation.h +++ b/src/fallback/implementation.h @@ -4,7 +4,8 @@ #include "simdjson.h" #include "isadetection.h" -namespace simdjson::fallback { +namespace simdjson { +namespace fallback { 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; }; -} // namespace simdjson::fallback +} // namespace fallback + +} // namespace simdjson #endif // SIMDJSON_FALLBACK_IMPLEMENTATION_H \ No newline at end of file diff --git a/src/fallback/numberparsing.h b/src/fallback/numberparsing.h index b32e4f05..31d6c95d 100644 --- a/src/fallback/numberparsing.h +++ b/src/fallback/numberparsing.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); #endif -namespace simdjson::fallback { +namespace simdjson { +namespace fallback { static inline uint32_t parse_eight_digits_unrolled(const char *chars) { uint32_t result = 0; 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" -} // namespace simdjson::fallback +} // namespace fallback + +} // namespace simdjson #endif // SIMDJSON_FALLBACK_NUMBERPARSING_H diff --git a/src/fallback/stage1_find_marks.h b/src/fallback/stage1_find_marks.h index d04e4ed5..eaffeba0 100644 --- a/src/fallback/stage1_find_marks.h +++ b/src/fallback/stage1_find_marks.h @@ -4,7 +4,9 @@ #include "simdjson.h" #include "fallback/implementation.h" -namespace simdjson::fallback::stage1 { +namespace simdjson { +namespace fallback { +namespace stage1 { class structural_scanner { public: @@ -139,9 +141,8 @@ private: bool streaming; }; // 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 { 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; } -} // namespace simdjson::fallback +} // namespace fallback +} // namespace simdjson #endif // SIMDJSON_FALLBACK_STAGE1_FIND_MARKS_H diff --git a/src/fallback/stage2_build_tape.h b/src/fallback/stage2_build_tape.h index 41b0c82b..0baed8e1 100644 --- a/src/fallback/stage2_build_tape.h +++ b/src/fallback/stage2_build_tape.h @@ -7,12 +7,14 @@ #include "fallback/stringparsing.h" #include "fallback/numberparsing.h" -namespace simdjson::fallback { +namespace simdjson { +namespace fallback { #include "generic/atomparsing.h" #include "generic/stage2_build_tape.h" #include "generic/stage2_streaming_build_tape.h" +} // namespace fallback } // namespace simdjson #endif // SIMDJSON_FALLBACK_STAGE2_BUILD_TAPE_H diff --git a/src/fallback/stringparsing.h b/src/fallback/stringparsing.h index ac986a79..c3375afe 100644 --- a/src/fallback/stringparsing.h +++ b/src/fallback/stringparsing.h @@ -4,7 +4,8 @@ #include "simdjson.h" #include "jsoncharutils.h" -namespace simdjson::fallback { +namespace simdjson { +namespace fallback { // Holds backslashes and quotes locations. 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" -} // namespace simdjson::fallback +} // namespace fallback +} // namespace simdjson #endif // SIMDJSON_FALLBACK_STRINGPARSING_H diff --git a/src/generic/atomparsing.h b/src/generic/atomparsing.h index 142bef5e..12cfdbbf 100644 --- a/src/generic/atomparsing.h +++ b/src/generic/atomparsing.h @@ -5,7 +5,7 @@ really_inline uint32_t string_to_uint32(const char* str) { return *reinterpret_c WARN_UNUSED 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++) - 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)); return srcval ^ string_to_uint32(atom); } diff --git a/src/generic/numberparsing.h b/src/generic/numberparsing.h index d0d9196f..bea1de10 100644 --- a/src/generic/numberparsing.h +++ b/src/generic/numberparsing.h @@ -242,7 +242,7 @@ really_inline bool is_made_of_eight_digits_fast(const char *chars) { uint64_t val; // this can read up to 7 bytes beyond the buffer size, but we require // 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); // a branchy method might be faster: // return (( val & 0xF0F0F0F0F0F0F0F0 ) == 0x3030303030303030) diff --git a/src/haswell/bitmanipulation.h b/src/haswell/bitmanipulation.h index c46f0733..37385a9b 100644 --- a/src/haswell/bitmanipulation.h +++ b/src/haswell/bitmanipulation.h @@ -6,25 +6,24 @@ #include "haswell/intrinsics.h" TARGET_HASWELL -namespace simdjson::haswell { +namespace simdjson { +namespace haswell { -#ifndef _MSC_VER // We sometimes call trailing_zero on inputs that are zero, // but the algorithms do not end up using the returned value. // Sadly, sanitizers are not smart enough to figure it out. -__attribute__((no_sanitize("undefined"))) // this is deliberate -#endif +NO_SANITIZE_UNDEFINED really_inline int trailing_zeroes(uint64_t input_num) { #ifdef _MSC_VER return (int)_tzcnt_u64(input_num); -#else +#else // _MSC_VER //////// // You might expect the next line to be equivalent to // return (int)_tzcnt_u64(input_num); // but the generated code differs and might be less efficient? //////// return __builtin_ctzll(input_num); -#endif// _MSC_VER +#endif // _MSC_VER } /* 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); #endif } -}// namespace simdjson::haswell + +} // namespace haswell +} // namespace simdjson UNTARGET_REGION #endif // SIMDJSON_HASWELL_BITMANIPULATION_H diff --git a/src/haswell/bitmask.h b/src/haswell/bitmask.h index f97272e6..c9ed2e0e 100644 --- a/src/haswell/bitmask.h +++ b/src/haswell/bitmask.h @@ -6,7 +6,8 @@ #include "haswell/intrinsics.h" TARGET_HASWELL -namespace simdjson::haswell { +namespace simdjson { +namespace haswell { // // 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); } -} // namespace simdjson::haswell +} // namespace haswell + +} // namespace simdjson UNTARGET_REGION #endif // SIMDJSON_HASWELL_BITMASK_H diff --git a/src/haswell/implementation.h b/src/haswell/implementation.h index fa2bda69..12024ec2 100644 --- a/src/haswell/implementation.h +++ b/src/haswell/implementation.h @@ -4,7 +4,8 @@ #include "simdjson.h" #include "isadetection.h" -namespace simdjson::haswell { +namespace simdjson { +namespace haswell { 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; }; -} // namespace simdjson::haswell +} // namespace haswell +} // namespace simdjson #endif // SIMDJSON_HASWELL_IMPLEMENTATION_H \ No newline at end of file diff --git a/src/haswell/numberparsing.h b/src/haswell/numberparsing.h index 41ad4246..e4c7820e 100644 --- a/src/haswell/numberparsing.h +++ b/src/haswell/numberparsing.h @@ -17,7 +17,8 @@ void found_float(double result, const uint8_t *buf); #endif TARGET_HASWELL -namespace simdjson::haswell { +namespace simdjson { +namespace haswell { static inline uint32_t parse_eight_digits_unrolled(const char *chars) { // this actually computes *16* values so we are being wasteful. 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" -} // namespace simdjson::haswell +} // namespace haswell + +} // namespace simdjson UNTARGET_REGION #endif // SIMDJSON_HASWELL_NUMBERPARSING_H diff --git a/src/haswell/simd.h b/src/haswell/simd.h index 2fb9f12c..56acae1c 100644 --- a/src/haswell/simd.h +++ b/src/haswell/simd.h @@ -7,7 +7,9 @@ #include "haswell/intrinsics.h" TARGET_HASWELL -namespace simdjson::haswell::simd { +namespace simdjson { +namespace haswell { +namespace simd { // Forward-declared so they can be used by splat and friends. template @@ -366,7 +368,10 @@ namespace simdjson::haswell::simd { } }; // struct simd8x64 -} // namespace simdjson::haswell::simd +} // namespace simd + +} // namespace haswell +} // namespace simdjson UNTARGET_REGION #endif // SIMDJSON_HASWELL_SIMD_H diff --git a/src/haswell/stage1_find_marks.h b/src/haswell/stage1_find_marks.h index f2f08cb3..16f9f9f1 100644 --- a/src/haswell/stage1_find_marks.h +++ b/src/haswell/stage1_find_marks.h @@ -9,7 +9,8 @@ #include "haswell/implementation.h" TARGET_HASWELL -namespace simdjson::haswell { +namespace simdjson { +namespace haswell { 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); } -} // namespace simdjson::haswell +} // namespace haswell + +} // namespace simdjson UNTARGET_REGION #endif // SIMDJSON_HASWELL_STAGE1_FIND_MARKS_H diff --git a/src/haswell/stage2_build_tape.h b/src/haswell/stage2_build_tape.h index 34560779..9eeedbf8 100644 --- a/src/haswell/stage2_build_tape.h +++ b/src/haswell/stage2_build_tape.h @@ -7,12 +7,14 @@ #include "haswell/numberparsing.h" TARGET_HASWELL -namespace simdjson::haswell { +namespace simdjson { +namespace haswell { #include "generic/atomparsing.h" #include "generic/stage2_build_tape.h" #include "generic/stage2_streaming_build_tape.h" +} // namespace haswell } // namespace simdjson UNTARGET_REGION diff --git a/src/haswell/stringparsing.h b/src/haswell/stringparsing.h index 6e6a633c..67de0ec8 100644 --- a/src/haswell/stringparsing.h +++ b/src/haswell/stringparsing.h @@ -8,7 +8,8 @@ #include "haswell/bitmanipulation.h" TARGET_HASWELL -namespace simdjson::haswell { +namespace simdjson { +namespace haswell { 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) { // this can read up to 15 bytes beyond the buffer size, but we require // 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 v(src); // store to dest unconditionally - we can overwrite the bits we don't like later v.store(dst); @@ -42,7 +43,8 @@ really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8 #include "generic/stringparsing.h" -} // namespace simdjson::haswell +} // namespace haswell +} // namespace simdjson UNTARGET_REGION #endif // SIMDJSON_HASWELL_STRINGPARSING_H diff --git a/src/implementation.cpp b/src/implementation.cpp index 0c0a51b3..c33111a3 100644 --- a/src/implementation.cpp +++ b/src/implementation.cpp @@ -9,25 +9,26 @@ #if SIMDJSON_IMPLEMENTATION_HASWELL #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 #if SIMDJSON_IMPLEMENTATION_WESTMERE #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 #if SIMDJSON_IMPLEMENTATION_ARM64 #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 #if SIMDJSON_IMPLEMENTATION_FALLBACK #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 -namespace simdjson::internal { +namespace simdjson { +namespace internal { /** * @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(); } -} // namespace simdjson::internal +} // namespace internal -namespace simdjson { - SIMDJSON_DLLIMPORTEXPORT const internal::available_implementation_list available_implementations{}; - SIMDJSON_DLLIMPORTEXPORT internal::atomic_ptr active_implementation{&internal::detect_best_supported_implementation_on_first_use_singleton}; -} +SIMDJSON_DLLIMPORTEXPORT const internal::available_implementation_list available_implementations{}; +SIMDJSON_DLLIMPORTEXPORT internal::atomic_ptr active_implementation{&internal::detect_best_supported_implementation_on_first_use_singleton}; + +} // namespace simdjson diff --git a/src/isadetection.h b/src/isadetection.h index 84ab6ffa..8da459c8 100644 --- a/src/isadetection.h +++ b/src/isadetection.h @@ -148,6 +148,6 @@ static inline uint32_t detect_supported_architectures() { #endif // end SIMD extension detection code -} // namespace simdjson::internal +} // namespace simdjson #endif // SIMDJSON_ISADETECTION_H diff --git a/src/westmere/bitmanipulation.h b/src/westmere/bitmanipulation.h index da1b8256..5ebf65ec 100644 --- a/src/westmere/bitmanipulation.h +++ b/src/westmere/bitmanipulation.h @@ -5,15 +5,13 @@ #include "westmere/intrinsics.h" TARGET_WESTMERE -namespace simdjson::westmere { +namespace simdjson { +namespace westmere { -#ifndef _MSC_VER // We sometimes call trailing_zero on inputs that are zero, // but the algorithms do not end up using the returned value. -// Sadly, sanitizers are not smart enough to figure it out. -__attribute__((no_sanitize("undefined"))) // this is deliberate -#endif -/* result might be undefined when input_num is zero */ +// Sadly, sanitizers are not smart enough to figure it out. +NO_SANITIZE_UNDEFINED really_inline int trailing_zeroes(uint64_t input_num) { #ifdef _MSC_VER 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). _BitScanForward64(&ret, input_num); return (int)ret; -#else +#else // _MSC_VER return __builtin_ctzll(input_num); -#endif// _MSC_VER +#endif // _MSC_VER } /* 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 } -} // namespace simdjson::westmere +} // namespace westmere + +} // namespace simdjson UNTARGET_REGION #endif // SIMDJSON_WESTMERE_BITMANIPULATION_H diff --git a/src/westmere/bitmask.h b/src/westmere/bitmask.h index 58eacca3..32bab6da 100644 --- a/src/westmere/bitmask.h +++ b/src/westmere/bitmask.h @@ -5,7 +5,8 @@ #include "westmere/intrinsics.h" TARGET_WESTMERE -namespace simdjson::westmere { +namespace simdjson { +namespace westmere { // // 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); } -} // namespace simdjson::westmere +} // namespace westmere + +} // namespace simdjson UNTARGET_REGION #endif // SIMDJSON_WESTMERE_BITMASK_H diff --git a/src/westmere/implementation.h b/src/westmere/implementation.h index 478782f3..ad4bb599 100644 --- a/src/westmere/implementation.h +++ b/src/westmere/implementation.h @@ -5,7 +5,8 @@ #include "simdjson/implementation.h" #include "isadetection.h" -namespace simdjson::westmere { +namespace simdjson { +namespace westmere { 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; }; -} // namespace simdjson::westmere +} // namespace westmere +} // namespace simdjson #endif // SIMDJSON_WESTMERE_IMPLEMENTATION_H \ No newline at end of file diff --git a/src/westmere/numberparsing.h b/src/westmere/numberparsing.h index cf039498..27f8a773 100644 --- a/src/westmere/numberparsing.h +++ b/src/westmere/numberparsing.h @@ -18,7 +18,8 @@ void found_float(double result, const uint8_t *buf); TARGET_WESTMERE -namespace simdjson::westmere { +namespace simdjson { +namespace westmere { static inline uint32_t parse_eight_digits_unrolled(const char *chars) { // this actually computes *16* values so we are being wasteful. 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" -} // namespace simdjson::westmere +} // namespace westmere + +} // namespace simdjson UNTARGET_REGION #endif // SIMDJSON_WESTMERE_NUMBERPARSING_H diff --git a/src/westmere/simd.h b/src/westmere/simd.h index 3ed56f17..75b2d03f 100644 --- a/src/westmere/simd.h +++ b/src/westmere/simd.h @@ -9,7 +9,9 @@ TARGET_WESTMERE -namespace simdjson::westmere::simd { +namespace simdjson { +namespace westmere { +namespace simd { template struct base { @@ -351,7 +353,10 @@ namespace simdjson::westmere::simd { } }; // struct simd8x64 -} // namespace simdjson::westmere::simd +} // namespace simd + +} // namespace westmere +} // namespace simdjson UNTARGET_REGION #endif // SIMDJSON_WESTMERE_SIMD_INPUT_H diff --git a/src/westmere/stage1_find_marks.h b/src/westmere/stage1_find_marks.h index aef17392..4a1b5e61 100644 --- a/src/westmere/stage1_find_marks.h +++ b/src/westmere/stage1_find_marks.h @@ -8,7 +8,8 @@ #include "westmere/implementation.h" TARGET_WESTMERE -namespace simdjson::westmere { +namespace simdjson { +namespace westmere { 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); } -} // namespace simdjson::westmere +} // namespace westmere + +} // namespace simdjson UNTARGET_REGION #endif // SIMDJSON_WESTMERE_STAGE1_FIND_MARKS_H diff --git a/src/westmere/stage2_build_tape.h b/src/westmere/stage2_build_tape.h index d8c86347..7105c123 100644 --- a/src/westmere/stage2_build_tape.h +++ b/src/westmere/stage2_build_tape.h @@ -7,12 +7,14 @@ #include "westmere/numberparsing.h" TARGET_WESTMERE -namespace simdjson::westmere { +namespace simdjson { +namespace westmere { #include "generic/atomparsing.h" #include "generic/stage2_build_tape.h" #include "generic/stage2_streaming_build_tape.h" -} // namespace simdjson::westmere +} // namespace westmere +} // namespace simdjson UNTARGET_REGION #endif // SIMDJSON_WESTMERE_STAGE2_BUILD_TAPE_H diff --git a/src/westmere/stringparsing.h b/src/westmere/stringparsing.h index 1c3a52a3..e269c982 100644 --- a/src/westmere/stringparsing.h +++ b/src/westmere/stringparsing.h @@ -8,7 +8,8 @@ #include "westmere/bitmanipulation.h" TARGET_WESTMERE -namespace simdjson::westmere { +namespace simdjson { +namespace westmere { 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) { // this can read up to 31 bytes beyond the buffer size, but we require // 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 v0(src); simd8 v1(src + 16); v0.store(dst); @@ -44,7 +45,8 @@ really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8 #include "generic/stringparsing.h" -} // namespace simdjson::westmere +} // namespace westmere +} // namespace simdjson UNTARGET_REGION #endif // SIMDJSON_WESTMERE_STRINGPARSING_H diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ac67feac..b4f39cc8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -93,10 +93,15 @@ if(NOT (MSVC AND MSVC_VERSION LESS 1920)) 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) - target_compile_options(readme_examples11 PRIVATE -Werror) + 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) - target_compile_options(readme_examples_noexceptions11 PRIVATE -Werror) + if (!MSVC) + target_compile_options(readme_examples11 PRIVATE -Werror) + endif() # Compile tests that *should fail* add_compile_test(readme_examples_will_fail_with_exceptions_off readme_examples.cpp quicktests) @@ -119,6 +124,14 @@ if(MSVC) "$") # <--this is out-file path 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..." + "$" # <--this is in-file + "$") # <--this is out-file path +endif() + ## Next bit should not be needed! #if(CMAKE_INTERPROCEDURAL_OPTIMIZATION) # next line is a workaround for an odr-violation in basictests regarding the globals 0x432a40 and 0x52045c under clang