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

1
.gitignore vendored
View File

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

View File

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

View File

@ -26,9 +26,11 @@ 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 {
namespace simdjson {
namespace haswell {
#include "generic/stage1_find_marks.h"
}
}
```
Other important files and directories:

View File

@ -2,31 +2,35 @@
# Quickstart compile tests don't require any flags
#
# TODO run amalgamate first!
function(add_quickstart_test TEST_NAME SOURCE_FILE)
# 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 (${ARGV2})
if (MSVC)
if (${ARGV2})
set(QUICKSTART_FLAGS /std:${ARGV2})
else()
set(QUICKSTART_FLAGS -Werror -std=${ARGV2})
set(QUICKSTART_FLAGS /WX)
endif()
set(QUICKSTART_INCLUDE /I${PROJECT_SOURCE_DIR}/include /I${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/src/simdjson.cpp)
else()
if(MSVC)
set(QUICKSTART_FLAGS "")
if (${ARGV2})
set(QUICKSTART_FLAGS -Werror -std=${ARGV2})
else()
set(QUICKSTART_FLAGS -Werror)
endif()
set(QUICKSTART_INCLUDE -I${PROJECT_SOURCE_DIR}/include -I${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/src/simdjson.cpp)
endif()
# Third argument tells whether to compile with -fno-exceptions
if (${ARGV3})
if (NOT MSVC)
set(QUICKSTART_FLAGS "${QUICKSTART_FLAGS} -fno-exceptions")
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}
@ -34,19 +38,20 @@ function(add_quickstart_test TEST_NAME SOURCE_FILE)
)
set_property(
TEST ${TEST_NAME}
APPEND PROPERTY DEPENDS simdjson-source ${PROJECT_SOURCE_DIR}/examples/quickstart/quickstart.cpp
APPEND PROPERTY DEPENDS simdjson-source ${PROJECT_SOURCE_DIR}/examples/quickstart/${SOURCE_FILE}
)
endfunction(add_quickstart_test)
endfunction(add_quickstart_test)
if (SIMDJSON_EXCEPTIONS)
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 )
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()

View File

@ -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
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
target_include_directories(simdjson-headers INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
install(TARGETS simdjson-headers
EXPORT simdjson-headers-config

View File

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

View File

@ -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<dom::element>;
template<> struct simdjson_result<dom::array>;
@ -34,9 +33,7 @@ template<> struct simdjson_result<dom::object>;
template<typename T>
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 {

View File

@ -4,7 +4,8 @@
#include <thread>
#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

View File

@ -218,7 +218,7 @@ private:
std::atomic<T*> ptr;
};
} // namespace [simdjson::]internal
} // namespace internal
/**
* 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
} // 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<simdjson_result<dom::object>>::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<typename T>
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<const T*>(&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

View File

@ -7,7 +7,8 @@
#include <stdexcept>
#include <thread>
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

View File

@ -4,7 +4,8 @@
#include "simdjson/error.h"
#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
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.

View File

@ -9,7 +9,8 @@
#include <memory>
#include <string>
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

View File

@ -5,7 +5,8 @@
#include <iostream>
#include <sstream>
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

View File

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

View File

@ -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 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
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 $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>/simdjson.cpp)
target_link_libraries(simdjson-source INTERFACE simdjson-include-source)
export_private_library(simdjson-source)
#
# simdjson is the distributed library compiled with flags.
@ -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

View File

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

View File

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

View File

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

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);
#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

View File

@ -6,7 +6,9 @@
#include "arm64/bitmanipulation.h"
#include "arm64/intrinsics.h"
namespace simdjson::arm64::simd {
namespace simdjson {
namespace arm64 {
namespace simd {
template<typename T>
struct simd8;
@ -387,6 +389,8 @@ namespace simdjson::arm64::simd {
}
}; // struct simd8x64<T>
} // namespace simdjson::arm64::simd
} // namespace simd
} // namespace arm64
} // namespace simdjson
#endif // SIMDJSON_ARM64_SIMD_H

View File

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

View File

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

View File

@ -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<uint8_t> v0(src);
simd8<uint8_t> 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

View File

@ -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<uint64_t>(cntsat) << 32);
}
} // namespace simdjson::dom
} // namespace simdjson
} // namespace dom
#endif // SIMDJSON_DOCUMENT_PARSER_CALLBACKS_H

View File

@ -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[]
}
} // namespace internal
} // namespace simdjson

View File

@ -4,28 +4,24 @@
#include "simdjson.h"
#include <limits>
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 */
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<uint64_t>::max() / value2;
}
} // namespace simdjson::fallback
} // namespace fallback
} // namespace simdjson
#endif // SIMDJSON_FALLBACK_BITMANIPULATION_H

View File

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

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);
#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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<typename Child>
@ -366,7 +368,10 @@ namespace simdjson::haswell::simd {
}
}; // struct simd8x64<T>
} // namespace simdjson::haswell::simd
} // namespace simd
} // namespace haswell
} // namespace simdjson
UNTARGET_REGION
#endif // SIMDJSON_HASWELL_SIMD_H

View File

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

View File

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

View File

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

View File

@ -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<const implementation> 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<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
} // namespace simdjson::internal
} // namespace simdjson
#endif // SIMDJSON_ISADETECTION_H

View File

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

View File

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

View File

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

View File

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

View File

@ -9,7 +9,9 @@
TARGET_WESTMERE
namespace simdjson::westmere::simd {
namespace simdjson {
namespace westmere {
namespace simd {
template<typename Child>
struct base {
@ -351,7 +353,10 @@ namespace simdjson::westmere::simd {
}
}; // struct simd8x64<T>
} // namespace simdjson::westmere::simd
} // namespace simd
} // namespace westmere
} // namespace simdjson
UNTARGET_REGION
#endif // SIMDJSON_WESTMERE_SIMD_INPUT_H

View File

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

View File

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

View File

@ -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<uint8_t> v0(src);
simd8<uint8_t> 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

View File

@ -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)
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)
"$<TARGET_FILE_DIR:basictests>") # <--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..."
"$<TARGET_FILE:simdjson>" # <--this is in-file
"$<TARGET_FILE_DIR:basictests>") # <--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