diff --git a/.github/workflows/vs15-ci.yml b/.github/workflows/vs15-ci.yml index f618c8c62..4736773de 100644 --- a/.github/workflows/vs15-ci.yml +++ b/.github/workflows/vs15-ci.yml @@ -19,17 +19,28 @@ jobs: fail-fast: false matrix: include: - - {gen: Visual Studio 15 2017, arch: Win32} - - {gen: Visual Studio 15 2017, arch: x64} + - {gen: Visual Studio 15 2017, arch: Win32, static: ON} + - {gen: Visual Studio 15 2017, arch: Win32, static: OFF} + - {gen: Visual Studio 15 2017, arch: x64, static: ON} + - {gen: Visual Studio 15 2017, arch: x64, static: OFF} steps: - - uses: actions/checkout@v2 + - name: checkout + uses: actions/checkout@v2 - name: Configure run: | - mkdir build - cd build && cmake -DSIMDJSON_COMPETITION=OFF -G "${{matrix.gen}}" -A ${{matrix.arch}} .. - - name: Build - run: cmake --build build --config Release --parallel - - name: 'Run CTest' + cmake -G "${{matrix.gen}}" -A ${{matrix.arch}} -DSIMDJSON_COMPETITION=OFF -DSIMDJSON_BUILD_STATIC=${{matrix.static}} -B build + - name: Build Debug + run: cmake --build build --config Debug --verbose + - name: Build Release + run: cmake --build build --config Release --verbose + - name: Run tests run: | - cd build - ctest -C Release -LE explicitonly --output-on-failure \ No newline at end of file + cd build + ctest -C Release -LE explicitonly --output-on-failure + - name: Install + run: | + cmake --install build --config Release + - name: Test Installation + run: | + cmake -G "${{matrix.gen}}" -A ${{matrix.arch}} -B build_install_test tests/installation_tests/find + cmake --build build_install_test --config Release \ No newline at end of file diff --git a/.github/workflows/vs16-ci.yml b/.github/workflows/vs16-ci.yml index 2ab58d62a..d116e1342 100644 --- a/.github/workflows/vs16-ci.yml +++ b/.github/workflows/vs16-ci.yml @@ -19,6 +19,8 @@ jobs: fail-fast: false matrix: include: + - {gen: Visual Studio 16 2019, arch: Win32, static: ON} + - {gen: Visual Studio 16 2019, arch: Win32, static: OFF} - {gen: Visual Studio 16 2019, arch: x64, static: ON} - {gen: Visual Studio 16 2019, arch: x64, static: OFF} steps: @@ -27,8 +29,10 @@ jobs: - name: Configure run: | cmake -G "${{matrix.gen}}" -A ${{matrix.arch}} -DSIMDJSON_COMPETITION=OFF -DSIMDJSON_BUILD_STATIC=${{matrix.static}} -B build - - name: Build - run: cmake --build build --config Release + - name: Build Debug + run: cmake --build build --config Debug --verbose + - name: Build Release + run: cmake --build build --config Release --verbose - name: Run tests run: | cd build diff --git a/include/simdjson/arm64/simd.h b/include/simdjson/arm64/simd.h index df4249d00..64a3a7e1e 100644 --- a/include/simdjson/arm64/simd.h +++ b/include/simdjson/arm64/simd.h @@ -421,7 +421,7 @@ simdjson_really_inline int8x16_t make_int8x16_t(int8_t x1, int8_t x2, int8_t x const simd8 chunks[NUM_CHUNKS]; simd8x64(const simd8x64& o) = delete; // no copy allowed - simd8x64& operator=(const simd8 other) = delete; // no assignment allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed simd8x64() = delete; // no default constructor allowed simdjson_really_inline simd8x64(const simd8 chunk0, const simd8 chunk1, const simd8 chunk2, const simd8 chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {} diff --git a/include/simdjson/haswell/simd.h b/include/simdjson/haswell/simd.h index dfb388517..1d325614b 100644 --- a/include/simdjson/haswell/simd.h +++ b/include/simdjson/haswell/simd.h @@ -297,7 +297,7 @@ namespace simd { const simd8 chunks[NUM_CHUNKS]; simd8x64(const simd8x64& o) = delete; // no copy allowed - simd8x64& operator=(const simd8 other) = delete; // no assignment allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed simd8x64() = delete; // no default constructor allowed simdjson_really_inline simd8x64(const simd8 chunk0, const simd8 chunk1) : chunks{chunk0, chunk1} {} diff --git a/include/simdjson/ppc64/simd.h b/include/simdjson/ppc64/simd.h index f8683bc87..6ebecf1e5 100644 --- a/include/simdjson/ppc64/simd.h +++ b/include/simdjson/ppc64/simd.h @@ -400,7 +400,7 @@ template struct simd8x64 { simd8x64(const simd8x64 &o) = delete; // no copy allowed simd8x64 & - operator=(const simd8 other) = delete; // no assignment allowed + operator=(const simd8& other) = delete; // no assignment allowed simd8x64() = delete; // no default constructor allowed simdjson_really_inline simd8x64(const simd8 chunk0, const simd8 chunk1, diff --git a/include/simdjson/westmere/simd.h b/include/simdjson/westmere/simd.h index f997f97da..9d5120ea0 100644 --- a/include/simdjson/westmere/simd.h +++ b/include/simdjson/westmere/simd.h @@ -267,7 +267,7 @@ namespace simd { const simd8 chunks[NUM_CHUNKS]; simd8x64(const simd8x64& o) = delete; // no copy allowed - simd8x64& operator=(const simd8 other) = delete; // no assignment allowed + simd8x64& operator=(const simd8& other) = delete; // no assignment allowed simd8x64() = delete; // no default constructor allowed simdjson_really_inline simd8x64(const simd8 chunk0, const simd8 chunk1, const simd8 chunk2, const simd8 chunk3) : chunks{chunk0, chunk1, chunk2, chunk3} {} diff --git a/src/arm64/dom_parser_implementation.cpp b/src/arm64/dom_parser_implementation.cpp index 0703647c3..b3a7b6e05 100644 --- a/src/arm64/dom_parser_implementation.cpp +++ b/src/arm64/dom_parser_implementation.cpp @@ -12,9 +12,9 @@ using namespace simd; struct json_character_block { static simdjson_really_inline json_character_block classify(const simd::simd8x64& in); - simdjson_really_inline uint64_t whitespace() const { return _whitespace; } - simdjson_really_inline uint64_t op() const { return _op; } - simdjson_really_inline uint64_t scalar() { return ~(op() | whitespace()); } + simdjson_really_inline uint64_t whitespace() const noexcept { return _whitespace; } + simdjson_really_inline uint64_t op() const noexcept { return _op; } + simdjson_really_inline uint64_t scalar() const noexcept { return ~(op() | whitespace()); } uint64_t _whitespace; uint64_t _op; diff --git a/src/generic/stage1/json_minifier.h b/src/generic/stage1/json_minifier.h index 97fb07dea..e3cdd9855 100644 --- a/src/generic/stage1/json_minifier.h +++ b/src/generic/stage1/json_minifier.h @@ -19,13 +19,13 @@ private: {} template simdjson_really_inline void step(const uint8_t *block_buf, buf_block_reader &reader) noexcept; - simdjson_really_inline void next(const simd::simd8x64& in, json_block block); + simdjson_really_inline void next(const simd::simd8x64& in, const json_block& block); simdjson_really_inline error_code finish(uint8_t *dst_start, size_t &dst_len); json_scanner scanner{}; uint8_t *dst; }; -simdjson_really_inline void json_minifier::next(const simd::simd8x64& in, json_block block) { +simdjson_really_inline void json_minifier::next(const simd::simd8x64& in, const json_block& block) { uint64_t mask = block.whitespace(); in.compress(mask, dst); dst += 64 - count_ones(mask); diff --git a/src/generic/stage1/json_scanner.h b/src/generic/stage1/json_scanner.h index 0715f3d3a..6c76b047a 100644 --- a/src/generic/stage1/json_scanner.h +++ b/src/generic/stage1/json_scanner.h @@ -22,20 +22,26 @@ namespace stage1 { */ struct json_block { public: + // We spell out the constructors in the hope of resolving inlining issues with Visual Studio 2017 + simdjson_really_inline json_block(json_string_block&& string, json_character_block characters, uint64_t follows_potential_nonquote_scalar) : + _string(std::move(string)), _characters(characters), _follows_potential_nonquote_scalar(follows_potential_nonquote_scalar) {} + simdjson_really_inline json_block(json_string_block string, json_character_block characters, uint64_t follows_potential_nonquote_scalar) : + _string(string), _characters(characters), _follows_potential_nonquote_scalar(follows_potential_nonquote_scalar) {} + /** * The start of structurals. * In simdjson prior to v0.3, these were called the pseudo-structural characters. **/ - simdjson_really_inline uint64_t structural_start() { return potential_structural_start() & ~_string.string_tail(); } + simdjson_really_inline uint64_t structural_start() const noexcept { return potential_structural_start() & ~_string.string_tail(); } /** All JSON whitespace (i.e. not in a string) */ - simdjson_really_inline uint64_t whitespace() { return non_quote_outside_string(_characters.whitespace()); } + simdjson_really_inline uint64_t whitespace() const noexcept { return non_quote_outside_string(_characters.whitespace()); } // Helpers /** Whether the given characters are inside a string (only works on non-quotes) */ - simdjson_really_inline uint64_t non_quote_inside_string(uint64_t mask) { return _string.non_quote_inside_string(mask); } + simdjson_really_inline uint64_t non_quote_inside_string(uint64_t mask) const noexcept { return _string.non_quote_inside_string(mask); } /** Whether the given characters are outside a string (only works on non-quotes) */ - simdjson_really_inline uint64_t non_quote_outside_string(uint64_t mask) { return _string.non_quote_outside_string(mask); } + simdjson_really_inline uint64_t non_quote_outside_string(uint64_t mask) const noexcept { return _string.non_quote_outside_string(mask); } // string and escape characters json_string_block _string; @@ -50,12 +56,12 @@ private: * structural elements ([,],{,},:, comma) plus scalar starts like 123, true and "abc". * They may reside inside a string. **/ - simdjson_really_inline uint64_t potential_structural_start() { return _characters.op() | potential_scalar_start(); } + simdjson_really_inline uint64_t potential_structural_start() const noexcept { return _characters.op() | potential_scalar_start(); } /** * The start of non-operator runs, like 123, true and "abc". * It main reside inside a string. **/ - simdjson_really_inline uint64_t potential_scalar_start() { + simdjson_really_inline uint64_t potential_scalar_start() const noexcept { // The term "scalar" refers to anything except structural characters and white space // (so letters, numbers, quotes). // Whenever it is preceded by something that is not a structural element ({,},[,],:, ") nor a white-space @@ -66,7 +72,7 @@ private: * Whether the given character is immediately after a non-operator like 123, true. * The characters following a quote are not included. */ - simdjson_really_inline uint64_t follows_potential_scalar() { + simdjson_really_inline uint64_t follows_potential_scalar() const noexcept { // _follows_potential_nonquote_scalar: is defined as marking any character that follows a character // that is not a structural element ({,},[,],:, comma) nor a quote (") and that is not a // white space. @@ -132,11 +138,13 @@ simdjson_really_inline json_block json_scanner::next(const simd::simd8x64(in_string) >> 63); // Use ^ to turn the beginning quote off, and the end quote on. - return { + + // We are returning a function-local object so either we get a move constructor + // or we get copy elision. + return json_string_block( backslash, escaped, quote, in_string - }; + ); } simdjson_really_inline error_code json_string_scanner::finish() { diff --git a/src/generic/stage1/json_structural_indexer.h b/src/generic/stage1/json_structural_indexer.h index 756cbcdcf..a7a0c7535 100644 --- a/src/generic/stage1/json_structural_indexer.h +++ b/src/generic/stage1/json_structural_indexer.h @@ -80,7 +80,7 @@ private: simdjson_really_inline json_structural_indexer(uint32_t *structural_indexes); template simdjson_really_inline void step(const uint8_t *block, buf_block_reader &reader) noexcept; - simdjson_really_inline void next(const simd::simd8x64& in, json_block block, size_t idx); + simdjson_really_inline void next(const simd::simd8x64& in, const json_block& block, size_t idx); simdjson_really_inline error_code finish(dom_parser_implementation &parser, size_t idx, size_t len, bool partial); json_scanner scanner{}; @@ -170,7 +170,7 @@ simdjson_really_inline void json_structural_indexer::step<64>(const uint8_t *blo reader.advance(); } -simdjson_really_inline void json_structural_indexer::next(const simd::simd8x64& in, json_block block, size_t idx) { +simdjson_really_inline void json_structural_indexer::next(const simd::simd8x64& in, const json_block& block, size_t idx) { uint64_t unescaped = in.lteq(0x1F); checker.check_next_input(in); indexer.write(uint32_t(idx-64), prev_structurals); // Output *last* iteration's structurals to the parser diff --git a/src/haswell/dom_parser_implementation.cpp b/src/haswell/dom_parser_implementation.cpp index 4245d03c9..cf9607260 100644 --- a/src/haswell/dom_parser_implementation.cpp +++ b/src/haswell/dom_parser_implementation.cpp @@ -13,19 +13,19 @@ using namespace simd; struct json_character_block { static simdjson_really_inline json_character_block classify(const simd::simd8x64& in); // ASCII white-space ('\r','\n','\t',' ') - simdjson_really_inline uint64_t whitespace() const; + simdjson_really_inline uint64_t whitespace() const noexcept; // non-quote structural characters (comma, colon, braces, brackets) - simdjson_really_inline uint64_t op() const; + simdjson_really_inline uint64_t op() const noexcept; // neither a structural character nor a white-space, so letters, numbers and quotes - simdjson_really_inline uint64_t scalar() const; + simdjson_really_inline uint64_t scalar() const noexcept; uint64_t _whitespace; // ASCII white-space ('\r','\n','\t',' ') uint64_t _op; // structural characters (comma, colon, braces, brackets but not quotes) }; -simdjson_really_inline uint64_t json_character_block::whitespace() const { return _whitespace; } -simdjson_really_inline uint64_t json_character_block::op() const { return _op; } -simdjson_really_inline uint64_t json_character_block::scalar() const { return ~(op() | whitespace()); } +simdjson_really_inline uint64_t json_character_block::whitespace() const noexcept { return _whitespace; } +simdjson_really_inline uint64_t json_character_block::op() const noexcept { return _op; } +simdjson_really_inline uint64_t json_character_block::scalar() const noexcept { return ~(op() | whitespace()); } // This identifies structural characters (comma, colon, braces, brackets), // and ASCII white-space ('\r','\n','\t',' '). diff --git a/src/ppc64/dom_parser_implementation.cpp b/src/ppc64/dom_parser_implementation.cpp index b61187272..802a70d59 100644 --- a/src/ppc64/dom_parser_implementation.cpp +++ b/src/ppc64/dom_parser_implementation.cpp @@ -12,9 +12,9 @@ using namespace simd; struct json_character_block { static simdjson_really_inline json_character_block classify(const simd::simd8x64& in); - simdjson_really_inline uint64_t whitespace() const { return _whitespace; } - simdjson_really_inline uint64_t op() const { return _op; } - simdjson_really_inline uint64_t scalar() { return ~(op() | whitespace()); } + simdjson_really_inline uint64_t whitespace() const noexcept { return _whitespace; } + simdjson_really_inline uint64_t op() const noexcept { return _op; } + simdjson_really_inline uint64_t scalar() const noexcept { return ~(op() | whitespace()); } uint64_t _whitespace; uint64_t _op; diff --git a/src/westmere/dom_parser_implementation.cpp b/src/westmere/dom_parser_implementation.cpp index 67bce00cb..a2d1436a2 100644 --- a/src/westmere/dom_parser_implementation.cpp +++ b/src/westmere/dom_parser_implementation.cpp @@ -13,9 +13,9 @@ using namespace simd; struct json_character_block { static simdjson_really_inline json_character_block classify(const simd::simd8x64& in); - simdjson_really_inline uint64_t whitespace() const { return _whitespace; } - simdjson_really_inline uint64_t op() const { return _op; } - simdjson_really_inline uint64_t scalar() { return ~(op() | whitespace()); } + simdjson_really_inline uint64_t whitespace() const noexcept { return _whitespace; } + simdjson_really_inline uint64_t op() const noexcept { return _op; } + simdjson_really_inline uint64_t scalar() const noexcept { return ~(op() | whitespace()); } uint64_t _whitespace; uint64_t _op;