Fix c++11 warnings on clang

- namespace x::y is C++17
- static_assert requires message in C++11
This commit is contained in:
John Keiser 2020-04-10 16:37:00 -07:00
parent 09cf18a646
commit fd418f568c
54 changed files with 319 additions and 205 deletions

View File

@ -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 --verbose --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

1
.gitignore vendored
View File

@ -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

View File

@ -20,8 +20,8 @@ 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
set(SIMDJSON_COMPETITION CACHE STRING "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()
@ -104,6 +104,22 @@ if(${CMAKE_C_COMPILER_ID} MATCHES "Intel") # icc / icpc
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-intel") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-intel")
endif() 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)

View File

@ -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"
}
} }
``` ```

View File

@ -2,51 +2,56 @@
# Quickstart compile tests don't require any flags # Quickstart compile tests don't require any flags
# #
# TODO run amalgamate first! # TODO haven't quite decided the right way to run quickstart on Windows. Needs README update.
if (NOT MSVC)
function(add_quickstart_test TEST_NAME SOURCE_FILE) # TODO run amalgamate first!
# Second argument is C++ standard name function(add_quickstart_test TEST_NAME SOURCE_FILE)
if (${ARGV2}) # Second argument is C++ standard name
if (MSVC) 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() 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() endif()
else()
if(MSVC) # Third argument tells whether to compile with -fno-exceptions
set(QUICKSTART_FLAGS "") if (${ARGV3})
else() if (NOT MSVC)
set(QUICKSTART_FLAGS -Werror) set(QUICKSTART_FLAGS ${QUICKSTART_FLAGS} -fno-exceptions)
endif()
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() endif()
# Third argument tells whether to compile with -fno-exceptions add_quickstart_test(quickstart_noexceptions quickstart_noexceptions.cpp "" true)
if (${ARGV3}) add_quickstart_test(quickstart_noexceptions11 quickstart_noexceptions.cpp c++11 true)
if (NOT MSVC) set_property( TEST quickstart_noexceptions APPEND PROPERTY LABELS quicktests )
set(QUICKSTART_FLAGS "${QUICKSTART_FLAGS} -fno-exceptions") set_property( TEST quickstart_noexceptions11 APPEND PROPERTY LABELS slowtests )
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() 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 )

View File

@ -6,10 +6,7 @@
# #
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 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 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
install(TARGETS simdjson-headers install(TARGETS simdjson-headers
EXPORT simdjson-headers-config EXPORT simdjson-headers-config

View File

@ -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"

View File

@ -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 {

View File

@ -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

View File

@ -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.

View File

@ -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
@ -922,9 +921,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
@ -1104,9 +1102,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
@ -1173,7 +1170,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
@ -1192,7 +1189,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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -6,7 +6,8 @@
# #
add_library(simdjson-include-source INTERFACE) add_library(simdjson-include-source INTERFACE)
target_link_libraries(simdjson-include-source INTERFACE simdjson-headers) target_link_libraries(simdjson-include-source INTERFACE simdjson-headers)
target_include_directories(simdjson-include-source INTERFACE .) 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. # 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. # the .cpp sources. It does not specify any compiler flags.
# #
add_library(simdjson-source INTERFACE) add_library(simdjson-source INTERFACE)
target_sources(simdjson-source INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/simdjson.cpp) target_sources(simdjson-source INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/simdjson.cpp)
target_link_libraries(simdjson-source INTERFACE simdjson-include-source) target_link_libraries(simdjson-source INTERFACE simdjson-include-source)
export_private_library(simdjson-source)
# #
# simdjson is the distributed library compiled with flags. # simdjson is the distributed library compiled with flags.
@ -39,9 +41,11 @@ else()
endif() endif()
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 INTERFACE simdjson-headers) # Only expose the headers, not sources
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
## This is handy but Visual Studio will happily ignore us ## This is handy but Visual Studio will happily ignore us

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
} }

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -93,10 +93,15 @@ if(NOT (MSVC AND MSVC_VERSION LESS 1920))
add_compile_test(readme_examples11 readme_examples.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) 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) 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) 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* # Compile tests that *should fail*
add_compile_test(readme_examples_will_fail_with_exceptions_off readme_examples.cpp quicktests) add_compile_test(readme_examples_will_fail_with_exceptions_off readme_examples.cpp quicktests)
@ -119,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