From 409948a0f9f93e9268bac5ea7de7b390360824bb Mon Sep 17 00:00:00 2001 From: John Keiser Date: Thu, 23 Apr 2020 09:19:26 -0700 Subject: [PATCH] Update amalgamated headers --- singleheader/amalgamate_demo.cpp | 2 +- singleheader/simdjson.cpp | 385 +++++++++++++++++-------------- singleheader/simdjson.h | 237 ++++++++++++------- 3 files changed, 360 insertions(+), 264 deletions(-) diff --git a/singleheader/amalgamate_demo.cpp b/singleheader/amalgamate_demo.cpp index 3898cdf9d..23395d067 100644 --- a/singleheader/amalgamate_demo.cpp +++ b/singleheader/amalgamate_demo.cpp @@ -1,4 +1,4 @@ -/* auto-generated on Mon Apr 20 11:05:12 PDT 2020. Do not edit! */ +/* auto-generated on Thu Apr 23 09:19:14 PDT 2020. Do not edit! */ #include #include "simdjson.h" diff --git a/singleheader/simdjson.cpp b/singleheader/simdjson.cpp index 852bbb260..a7d6985fc 100644 --- a/singleheader/simdjson.cpp +++ b/singleheader/simdjson.cpp @@ -1,4 +1,4 @@ -/* auto-generated on Mon Apr 20 11:05:12 PDT 2020. Do not edit! */ +/* auto-generated on Thu Apr 23 09:19:14 PDT 2020. Do not edit! */ #include "simdjson.h" /* used for http://dmalloc.com/ Dmalloc - Debug Malloc Library */ @@ -697,9 +697,8 @@ really_inline int count_ones(uint64_t input_num) { really_inline bool add_overflow(uint64_t value1, uint64_t value2, uint64_t *result) { #ifdef _MSC_VER - // todo: this might fail under visual studio for ARM - return _addcarry_u64(0, value1, value2, - reinterpret_cast(result)); + *result = value1 + value2; + return *result < value1; #else return __builtin_uaddll_overflow(value1, value2, (unsigned long long *)result); @@ -766,7 +765,7 @@ namespace simd { typedef uint16_t bitmask_t; typedef uint32_t bitmask2_t; - static really_inline simd8 splat(bool _value) { return vmovq_n_u8(-(!!_value)); } + static really_inline simd8 splat(bool _value) { return vmovq_n_u8(uint8_t(-(!!_value))); } really_inline simd8(const uint8x16_t _value) : base_u8(_value) {} // False constructor @@ -875,8 +874,8 @@ namespace simd { really_inline void compress(uint16_t mask, L * output) const { // this particular implementation was inspired by work done by @animetosho // we do it in two steps, first 8 bytes and then second 8 bytes - uint8_t mask1 = static_cast(mask); // least significant 8 bits - uint8_t mask2 = static_cast(mask >> 8); // most significant 8 bits + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits // next line just loads the 64-bit values thintable_epi8[mask1] and // thintable_epi8[mask2] into a 128-bit register, using only // two instructions on most compilers. @@ -1025,10 +1024,10 @@ namespace simd { } really_inline void compress(uint64_t mask, T * output) const { - this->chunks[0].compress(mask, output); - this->chunks[1].compress(mask >> 16, output + 16 - count_ones(mask & 0xFFFF)); - this->chunks[2].compress(mask >> 32, output + 32 - count_ones(mask & 0xFFFFFFFF)); - this->chunks[3].compress(mask >> 48, output + 48 - count_ones(mask & 0xFFFFFFFFFFFF)); + this->chunks[0].compress(uint16_t(mask), output); + this->chunks[1].compress(uint16_t(mask >> 16), output + 16 - count_ones(mask & 0xFFFF)); + this->chunks[2].compress(uint16_t(mask >> 32), output + 32 - count_ones(mask & 0xFFFFFFFF)); + this->chunks[3].compress(uint16_t(mask >> 48), output + 48 - count_ones(mask & 0xFFFFFFFFFFFF)); } template @@ -1338,7 +1337,7 @@ really_inline json_string_block json_string_scanner::next(const simd::simd8x64(static_cast(in_string) >> 63); + prev_in_string = uint64_t(static_cast(in_string) >> 63); // Use ^ to turn the beginning quote off, and the end quote on. return { backslash, @@ -1408,6 +1407,7 @@ private: */ class json_scanner { public: + json_scanner() {} really_inline json_block next(const simd::simd8x64 in); really_inline error_code finish(bool streaming); @@ -1415,7 +1415,7 @@ private: // Whether the last character of the previous iteration is part of a scalar token // (anything except whitespace or an operator). uint64_t prev_scalar = 0ULL; - json_string_scanner string_scanner; + json_string_scanner string_scanner{}; }; @@ -1434,7 +1434,7 @@ really_inline uint64_t follows(const uint64_t match, uint64_t &overflow) { // // Check if the current character follows a matching character, with possible "filler" between. -// For example, this checks for empty curly braces, e.g. +// For example, this checks for empty curly braces, e.g. // // in.eq('}') & follows(in.eq('['), in.eq(' '), prev_empty_array) // { * } // @@ -1477,12 +1477,14 @@ public: static error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) noexcept; private: - really_inline json_minifier(uint8_t *_dst) : dst{_dst} {} + really_inline json_minifier(uint8_t *_dst) + : dst{_dst} + {} template really_inline void step(const uint8_t *block_buf, buf_block_reader &reader) noexcept; really_inline void next(simd::simd8x64 in, json_block block); really_inline error_code finish(uint8_t *dst_start, size_t &dst_len); - json_scanner scanner; + json_scanner scanner{}; uint8_t *dst; }; @@ -1994,7 +1996,7 @@ public: // it helps tremendously. if (bits == 0) return; - uint32_t cnt = count_ones(bits); + int cnt = static_cast(count_ones(bits)); // Do the first 8 all together for (int i=0; i<8; i++) { @@ -2014,7 +2016,7 @@ public: // branch mispredictions here. 16+ structurals per block means either punctuation ({} [] , :) // or the start of a value ("abc" true 123) every four characters. if (unlikely(cnt > 16)) { - uint32_t i = 16; + int i = 16; do { this->tail[i] = idx + trailing_zeroes(bits); bits = clear_lowest_bit(bits); @@ -2033,13 +2035,14 @@ public: static error_code index(const uint8_t *buf, size_t len, parser &parser, bool streaming) noexcept; private: - really_inline json_structural_indexer(uint32_t *structural_indexes) : indexer{structural_indexes} {} + really_inline json_structural_indexer(uint32_t *structural_indexes) + : indexer{structural_indexes} {} template really_inline void step(const uint8_t *block, buf_block_reader &reader) noexcept; really_inline void next(simd::simd8x64 in, json_block block, size_t idx); really_inline error_code finish(parser &parser, size_t idx, size_t len, bool streaming); - json_scanner scanner; + json_scanner scanner{}; utf8_checker checker{}; bit_indexer indexer; uint64_t prev_structurals = 0; @@ -2049,14 +2052,14 @@ private: really_inline void json_structural_indexer::next(simd::simd8x64 in, json_block block, size_t idx) { uint64_t unescaped = in.lteq(0x1F); checker.check_next_input(in); - indexer.write(idx-64, prev_structurals); // Output *last* iteration's structurals to the parser + indexer.write(uint32_t(idx-64), prev_structurals); // Output *last* iteration's structurals to the parser prev_structurals = block.structural_start(); unescaped_chars_error |= block.non_quote_inside_string(unescaped); } really_inline error_code json_structural_indexer::finish(parser &parser, size_t idx, size_t len, bool streaming) { // Write out the final iteration's structurals - indexer.write(idx-64, prev_structurals); + indexer.write(uint32_t(idx-64), prev_structurals); error_code error = scanner.finish(streaming); if (unlikely(error != SUCCESS)) { return error; } @@ -2065,7 +2068,7 @@ really_inline error_code json_structural_indexer::finish(parser &parser, size_t return UNESCAPED_CHARS; } - parser.n_structural_indexes = indexer.tail - parser.structural_indexes.get(); + parser.n_structural_indexes = uint32_t(indexer.tail - parser.structural_indexes.get()); /* a valid JSON file cannot have zero structural indexes - we should have * found something */ if (unlikely(parser.n_structural_indexes == 0u)) { @@ -2077,7 +2080,7 @@ really_inline error_code json_structural_indexer::finish(parser &parser, size_t if (len != parser.structural_indexes[parser.n_structural_indexes - 1]) { /* the string might not be NULL terminated, but we add a virtual NULL * ending character. */ - parser.structural_indexes[parser.n_structural_indexes++] = len; + parser.structural_indexes[parser.n_structural_indexes++] = uint32_t(len); } /* make it safe to dereference one beyond this array */ parser.structural_indexes[parser.n_structural_indexes] = 0; @@ -2117,7 +2120,7 @@ really_inline void json_structural_indexer::step<64>(const uint8_t *block, buf_b // they can make a lot of progress before they need that information. // 3. Step 1 doesn't use enough capacity, so we run some extra stuff while we're waiting for that // to finish: utf-8 checks and generating the output from the last iteration. -// +// // The reason we run 2 inputs at a time, is steps 2 and 3 are *still* not enough to soak up all // available capacity with just one input. Running 2 at a time seems to give the CPU a good enough // workout. @@ -2286,7 +2289,7 @@ really_inline error_code scan() { } *next_structural_index = len; next_structural_index++; - doc_parser.n_structural_indexes = next_structural_index - doc_parser.structural_indexes.get(); + doc_parser.n_structural_indexes = uint32_t(next_structural_index - doc_parser.structural_indexes.get()); return error; } @@ -2307,7 +2310,7 @@ WARN_UNUSED error_code implementation::stage1(const uint8_t *buf, size_t len, pa if (unlikely(len > parser.capacity())) { return CAPACITY; } - stage1::structural_scanner scanner(buf, len, parser, streaming); + stage1::structural_scanner scanner(buf, uint32_t(len), parser, streaming); return scanner.scan(); } @@ -2360,7 +2363,7 @@ WARN_UNUSED error_code implementation::minify(const uint8_t *buf, size_t len, ui pos += meta[2] | quote; i += 1; - nonescape = (~nonescape) | (meta[1]); + nonescape = uint8_t(~nonescape) | (meta[1]); } dst_len = pos; // we intentionally do not work with a reference // for fear of aliasing @@ -2462,17 +2465,19 @@ really_inline uint64_t clear_lowest_bit(uint64_t input_num) { /* result might be undefined when input_num is zero */ really_inline int leading_zeroes(uint64_t input_num) { - return static_cast(_lzcnt_u64(input_num)); + return int(_lzcnt_u64(input_num)); } -really_inline int count_ones(uint64_t input_num) { #ifdef _MSC_VER +really_inline unsigned __int64 count_ones(uint64_t input_num) { // note: we do not support legacy 32-bit Windows return __popcnt64(input_num);// Visual Studio wants two underscores -#else - return _popcnt64(input_num); -#endif } +#else +really_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif really_inline bool add_overflow(uint64_t value1, uint64_t value2, uint64_t *result) { @@ -2563,7 +2568,7 @@ namespace simd { // SIMD byte mask type (returned by things like eq and gt) template<> struct simd8: base8 { - static really_inline simd8 splat(bool _value) { return _mm256_set1_epi8(-(!!_value)); } + static really_inline simd8 splat(bool _value) { return _mm256_set1_epi8(uint8_t(-(!!_value))); } really_inline simd8() : base8() {} really_inline simd8(const __m256i _value) : base8(_value) {} @@ -2627,10 +2632,10 @@ namespace simd { really_inline void compress(uint32_t mask, L * output) const { // this particular implementation was inspired by work done by @animetosho // we do it in four steps, first 8 bytes and then second 8 bytes... - uint8_t mask1 = static_cast(mask); // least significant 8 bits - uint8_t mask2 = static_cast(mask >> 8); // second least significant 8 bits - uint8_t mask3 = static_cast(mask >> 16); // ... - uint8_t mask4 = static_cast(mask >> 24); // ... + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // second least significant 8 bits + uint8_t mask3 = uint8_t(mask >> 16); // ... + uint8_t mask4 = uint8_t(mask >> 24); // ... // next line just loads the 64-bit values thintable_epi8[mask1] and // thintable_epi8[mask2] into a 128-bit register, using only // two instructions on most compilers. @@ -2807,8 +2812,8 @@ namespace simd { } really_inline void compress(uint64_t mask, T * output) const { - uint32_t mask1 = static_cast(mask); - uint32_t mask2 = static_cast(mask >> 32); + uint32_t mask1 = uint32_t(mask); + uint32_t mask2 = uint32_t(mask >> 32); this->chunks[0].compress(mask1, output); this->chunks[1].compress(mask2, output + 32 - count_ones(mask1)); } @@ -2849,7 +2854,7 @@ namespace simd { } really_inline uint64_t to_bitmask() const { - uint64_t r_lo = static_cast(this->chunks[0].to_bitmask()); + uint64_t r_lo = uint32_t(this->chunks[0].to_bitmask()); uint64_t r_hi = this->chunks[1].to_bitmask(); return r_lo | (r_hi << 32); } @@ -3093,7 +3098,7 @@ really_inline json_string_block json_string_scanner::next(const simd::simd8x64(static_cast(in_string) >> 63); + prev_in_string = uint64_t(static_cast(in_string) >> 63); // Use ^ to turn the beginning quote off, and the end quote on. return { backslash, @@ -3163,6 +3168,7 @@ private: */ class json_scanner { public: + json_scanner() {} really_inline json_block next(const simd::simd8x64 in); really_inline error_code finish(bool streaming); @@ -3170,7 +3176,7 @@ private: // Whether the last character of the previous iteration is part of a scalar token // (anything except whitespace or an operator). uint64_t prev_scalar = 0ULL; - json_string_scanner string_scanner; + json_string_scanner string_scanner{}; }; @@ -3189,7 +3195,7 @@ really_inline uint64_t follows(const uint64_t match, uint64_t &overflow) { // // Check if the current character follows a matching character, with possible "filler" between. -// For example, this checks for empty curly braces, e.g. +// For example, this checks for empty curly braces, e.g. // // in.eq('}') & follows(in.eq('['), in.eq(' '), prev_empty_array) // { * } // @@ -3232,12 +3238,14 @@ public: static error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) noexcept; private: - really_inline json_minifier(uint8_t *_dst) : dst{_dst} {} + really_inline json_minifier(uint8_t *_dst) + : dst{_dst} + {} template really_inline void step(const uint8_t *block_buf, buf_block_reader &reader) noexcept; really_inline void next(simd::simd8x64 in, json_block block); really_inline error_code finish(uint8_t *dst_start, size_t &dst_len); - json_scanner scanner; + json_scanner scanner{}; uint8_t *dst; }; @@ -3749,7 +3757,7 @@ public: // it helps tremendously. if (bits == 0) return; - uint32_t cnt = count_ones(bits); + int cnt = static_cast(count_ones(bits)); // Do the first 8 all together for (int i=0; i<8; i++) { @@ -3769,7 +3777,7 @@ public: // branch mispredictions here. 16+ structurals per block means either punctuation ({} [] , :) // or the start of a value ("abc" true 123) every four characters. if (unlikely(cnt > 16)) { - uint32_t i = 16; + int i = 16; do { this->tail[i] = idx + trailing_zeroes(bits); bits = clear_lowest_bit(bits); @@ -3788,13 +3796,14 @@ public: static error_code index(const uint8_t *buf, size_t len, parser &parser, bool streaming) noexcept; private: - really_inline json_structural_indexer(uint32_t *structural_indexes) : indexer{structural_indexes} {} + really_inline json_structural_indexer(uint32_t *structural_indexes) + : indexer{structural_indexes} {} template really_inline void step(const uint8_t *block, buf_block_reader &reader) noexcept; really_inline void next(simd::simd8x64 in, json_block block, size_t idx); really_inline error_code finish(parser &parser, size_t idx, size_t len, bool streaming); - json_scanner scanner; + json_scanner scanner{}; utf8_checker checker{}; bit_indexer indexer; uint64_t prev_structurals = 0; @@ -3804,14 +3813,14 @@ private: really_inline void json_structural_indexer::next(simd::simd8x64 in, json_block block, size_t idx) { uint64_t unescaped = in.lteq(0x1F); checker.check_next_input(in); - indexer.write(idx-64, prev_structurals); // Output *last* iteration's structurals to the parser + indexer.write(uint32_t(idx-64), prev_structurals); // Output *last* iteration's structurals to the parser prev_structurals = block.structural_start(); unescaped_chars_error |= block.non_quote_inside_string(unescaped); } really_inline error_code json_structural_indexer::finish(parser &parser, size_t idx, size_t len, bool streaming) { // Write out the final iteration's structurals - indexer.write(idx-64, prev_structurals); + indexer.write(uint32_t(idx-64), prev_structurals); error_code error = scanner.finish(streaming); if (unlikely(error != SUCCESS)) { return error; } @@ -3820,7 +3829,7 @@ really_inline error_code json_structural_indexer::finish(parser &parser, size_t return UNESCAPED_CHARS; } - parser.n_structural_indexes = indexer.tail - parser.structural_indexes.get(); + parser.n_structural_indexes = uint32_t(indexer.tail - parser.structural_indexes.get()); /* a valid JSON file cannot have zero structural indexes - we should have * found something */ if (unlikely(parser.n_structural_indexes == 0u)) { @@ -3832,7 +3841,7 @@ really_inline error_code json_structural_indexer::finish(parser &parser, size_t if (len != parser.structural_indexes[parser.n_structural_indexes - 1]) { /* the string might not be NULL terminated, but we add a virtual NULL * ending character. */ - parser.structural_indexes[parser.n_structural_indexes++] = len; + parser.structural_indexes[parser.n_structural_indexes++] = uint32_t(len); } /* make it safe to dereference one beyond this array */ parser.structural_indexes[parser.n_structural_indexes] = 0; @@ -3872,7 +3881,7 @@ really_inline void json_structural_indexer::step<64>(const uint8_t *block, buf_b // they can make a lot of progress before they need that information. // 3. Step 1 doesn't use enough capacity, so we run some extra stuff while we're waiting for that // to finish: utf-8 checks and generating the output from the last iteration. -// +// // The reason we run 2 inputs at a time, is steps 2 and 3 are *still* not enough to soak up all // available capacity with just one input. Running 2 at a time seems to give the CPU a good enough // workout. @@ -4010,14 +4019,16 @@ really_inline int leading_zeroes(uint64_t input_num) { #endif// _MSC_VER } -really_inline int count_ones(uint64_t input_num) { #ifdef _MSC_VER +really_inline unsigned __int64 count_ones(uint64_t input_num) { // note: we do not support legacy 32-bit Windows return __popcnt64(input_num);// Visual Studio wants two underscores -#else - return _popcnt64(input_num); -#endif } +#else +really_inline long long int count_ones(uint64_t input_num) { + return _popcnt64(input_num); +} +#endif really_inline bool add_overflow(uint64_t value1, uint64_t value2, uint64_t *result) { @@ -4110,7 +4121,7 @@ namespace simd { // SIMD byte mask type (returned by things like eq and gt) template<> struct simd8: base8 { - static really_inline simd8 splat(bool _value) { return _mm_set1_epi8(-(!!_value)); } + static really_inline simd8 splat(bool _value) { return _mm_set1_epi8(uint8_t(-(!!_value))); } really_inline simd8() : base8() {} really_inline simd8(const __m128i _value) : base8(_value) {} @@ -4172,8 +4183,8 @@ namespace simd { really_inline void compress(uint16_t mask, L * output) const { // this particular implementation was inspired by work done by @animetosho // we do it in two steps, first 8 bytes and then second 8 bytes - uint8_t mask1 = static_cast(mask); // least significant 8 bits - uint8_t mask2 = static_cast(mask >> 8); // most significant 8 bits + uint8_t mask1 = uint8_t(mask); // least significant 8 bits + uint8_t mask2 = uint8_t(mask >> 8); // most significant 8 bits // next line just loads the 64-bit values thintable_epi8[mask1] and // thintable_epi8[mask2] into a 128-bit register, using only // two instructions on most compilers. @@ -4326,10 +4337,10 @@ namespace simd { } really_inline void compress(uint64_t mask, T * output) const { - this->chunks[0].compress(mask, output); - this->chunks[1].compress(mask >> 16, output + 16 - count_ones(mask & 0xFFFF)); - this->chunks[2].compress(mask >> 32, output + 32 - count_ones(mask & 0xFFFFFFFF)); - this->chunks[3].compress(mask >> 48, output + 48 - count_ones(mask & 0xFFFFFFFFFFFF)); + this->chunks[0].compress(uint16_t(mask), output); + this->chunks[1].compress(uint16_t(mask >> 16), output + 16 - count_ones(mask & 0xFFFF)); + this->chunks[2].compress(uint16_t(mask >> 32), output + 32 - count_ones(mask & 0xFFFFFFFF)); + this->chunks[3].compress(uint16_t(mask >> 48), output + 48 - count_ones(mask & 0xFFFFFFFFFFFF)); } template @@ -4378,7 +4389,7 @@ namespace simd { } really_inline uint64_t to_bitmask() const { - uint64_t r0 = static_cast(this->chunks[0].to_bitmask()); + uint64_t r0 = uint32_t(this->chunks[0].to_bitmask()); uint64_t r1 = this->chunks[1].to_bitmask(); uint64_t r2 = this->chunks[2].to_bitmask(); uint64_t r3 = this->chunks[3].to_bitmask(); @@ -4624,7 +4635,7 @@ really_inline json_string_block json_string_scanner::next(const simd::simd8x64(static_cast(in_string) >> 63); + prev_in_string = uint64_t(static_cast(in_string) >> 63); // Use ^ to turn the beginning quote off, and the end quote on. return { backslash, @@ -4694,6 +4705,7 @@ private: */ class json_scanner { public: + json_scanner() {} really_inline json_block next(const simd::simd8x64 in); really_inline error_code finish(bool streaming); @@ -4701,7 +4713,7 @@ private: // Whether the last character of the previous iteration is part of a scalar token // (anything except whitespace or an operator). uint64_t prev_scalar = 0ULL; - json_string_scanner string_scanner; + json_string_scanner string_scanner{}; }; @@ -4720,7 +4732,7 @@ really_inline uint64_t follows(const uint64_t match, uint64_t &overflow) { // // Check if the current character follows a matching character, with possible "filler" between. -// For example, this checks for empty curly braces, e.g. +// For example, this checks for empty curly braces, e.g. // // in.eq('}') & follows(in.eq('['), in.eq(' '), prev_empty_array) // { * } // @@ -4763,12 +4775,14 @@ public: static error_code minify(const uint8_t *buf, size_t len, uint8_t *dst, size_t &dst_len) noexcept; private: - really_inline json_minifier(uint8_t *_dst) : dst{_dst} {} + really_inline json_minifier(uint8_t *_dst) + : dst{_dst} + {} template really_inline void step(const uint8_t *block_buf, buf_block_reader &reader) noexcept; really_inline void next(simd::simd8x64 in, json_block block); really_inline error_code finish(uint8_t *dst_start, size_t &dst_len); - json_scanner scanner; + json_scanner scanner{}; uint8_t *dst; }; @@ -5280,7 +5294,7 @@ public: // it helps tremendously. if (bits == 0) return; - uint32_t cnt = count_ones(bits); + int cnt = static_cast(count_ones(bits)); // Do the first 8 all together for (int i=0; i<8; i++) { @@ -5300,7 +5314,7 @@ public: // branch mispredictions here. 16+ structurals per block means either punctuation ({} [] , :) // or the start of a value ("abc" true 123) every four characters. if (unlikely(cnt > 16)) { - uint32_t i = 16; + int i = 16; do { this->tail[i] = idx + trailing_zeroes(bits); bits = clear_lowest_bit(bits); @@ -5319,13 +5333,14 @@ public: static error_code index(const uint8_t *buf, size_t len, parser &parser, bool streaming) noexcept; private: - really_inline json_structural_indexer(uint32_t *structural_indexes) : indexer{structural_indexes} {} + really_inline json_structural_indexer(uint32_t *structural_indexes) + : indexer{structural_indexes} {} template really_inline void step(const uint8_t *block, buf_block_reader &reader) noexcept; really_inline void next(simd::simd8x64 in, json_block block, size_t idx); really_inline error_code finish(parser &parser, size_t idx, size_t len, bool streaming); - json_scanner scanner; + json_scanner scanner{}; utf8_checker checker{}; bit_indexer indexer; uint64_t prev_structurals = 0; @@ -5335,14 +5350,14 @@ private: really_inline void json_structural_indexer::next(simd::simd8x64 in, json_block block, size_t idx) { uint64_t unescaped = in.lteq(0x1F); checker.check_next_input(in); - indexer.write(idx-64, prev_structurals); // Output *last* iteration's structurals to the parser + indexer.write(uint32_t(idx-64), prev_structurals); // Output *last* iteration's structurals to the parser prev_structurals = block.structural_start(); unescaped_chars_error |= block.non_quote_inside_string(unescaped); } really_inline error_code json_structural_indexer::finish(parser &parser, size_t idx, size_t len, bool streaming) { // Write out the final iteration's structurals - indexer.write(idx-64, prev_structurals); + indexer.write(uint32_t(idx-64), prev_structurals); error_code error = scanner.finish(streaming); if (unlikely(error != SUCCESS)) { return error; } @@ -5351,7 +5366,7 @@ really_inline error_code json_structural_indexer::finish(parser &parser, size_t return UNESCAPED_CHARS; } - parser.n_structural_indexes = indexer.tail - parser.structural_indexes.get(); + parser.n_structural_indexes = uint32_t(indexer.tail - parser.structural_indexes.get()); /* a valid JSON file cannot have zero structural indexes - we should have * found something */ if (unlikely(parser.n_structural_indexes == 0u)) { @@ -5363,7 +5378,7 @@ really_inline error_code json_structural_indexer::finish(parser &parser, size_t if (len != parser.structural_indexes[parser.n_structural_indexes - 1]) { /* the string might not be NULL terminated, but we add a virtual NULL * ending character. */ - parser.structural_indexes[parser.n_structural_indexes++] = len; + parser.structural_indexes[parser.n_structural_indexes++] = uint32_t(len); } /* make it safe to dereference one beyond this array */ parser.structural_indexes[parser.n_structural_indexes] = 0; @@ -5403,7 +5418,7 @@ really_inline void json_structural_indexer::step<64>(const uint8_t *block, buf_b // they can make a lot of progress before they need that information. // 3. Step 1 doesn't use enough capacity, so we run some extra stuff while we're waiting for that // to finish: utf-8 checks and generating the output from the last iteration. -// +// // The reason we run 2 inputs at a time, is steps 2 and 3 are *still* not enough to soak up all // available capacity with just one input. Running 2 at a time seems to give the CPU a good enough // workout. @@ -5730,27 +5745,27 @@ static inline bool is_utf8_continuing(char c) { // inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) { if (cp <= 0x7F) { - c[0] = cp; + c[0] = uint8_t(cp); return 1; // ascii } if (cp <= 0x7FF) { - c[0] = (cp >> 6) + 192; - c[1] = (cp & 63) + 128; + c[0] = uint8_t((cp >> 6) + 192); + c[1] = uint8_t((cp & 63) + 128); return 2; // universal plane // Surrogates are treated elsewhere... //} //else if (0xd800 <= cp && cp <= 0xdfff) { // return 0; // surrogates // could put assert here } else if (cp <= 0xFFFF) { - c[0] = (cp >> 12) + 224; - c[1] = ((cp >> 6) & 63) + 128; - c[2] = (cp & 63) + 128; + c[0] = uint8_t((cp >> 12) + 224); + c[1] = uint8_t(((cp >> 6) & 63) + 128); + c[2] = uint8_t((cp & 63) + 128); return 3; } else if (cp <= 0x10FFFF) { // if you know you have a valid code point, this // is not needed - c[0] = (cp >> 18) + 240; - c[1] = ((cp >> 12) & 63) + 128; - c[2] = ((cp >> 6) & 63) + 128; - c[3] = (cp & 63) + 128; + c[0] = uint8_t((cp >> 18) + 240); + c[1] = uint8_t(((cp >> 12) & 63) + 128); + c[2] = uint8_t(((cp >> 6) & 63) + 128); + c[3] = uint8_t((cp & 63) + 128); return 4; } // will return 0 when the code point was too large. @@ -5797,8 +5812,8 @@ really_inline value128 full_multiplication(uint64_t value1, uint64_t value2) { answer.low = _umul128(value1, value2, &answer.high); #else __uint128_t r = ((__uint128_t)value1) * value2; - answer.low = r; - answer.high = r >> 64; + answer.low = uint64_t(r); + answer.high = uint64_t(r >> 64); #endif return answer; } @@ -6880,7 +6895,7 @@ really_inline uint8_t *parser::on_start_string() noexcept { } really_inline bool parser::on_end_string(uint8_t *dst) noexcept { - uint32_t str_length = dst - (current_string_buf_loc + sizeof(uint32_t)); + uint32_t str_length = uint32_t(dst - (current_string_buf_loc + sizeof(uint32_t))); // TODO check for overflow in case someone has a crazy string (>=4GB?) // But only add the overflow check when the document itself exceeds 4GB // Currently unneeded because we refuse to parse docs larger or equal to 4GB. @@ -6912,7 +6927,7 @@ really_inline bool parser::on_number_double(double value) noexcept { } really_inline void parser::write_tape(uint64_t val, internal::tape_type t) noexcept { - doc.tape[current_loc++] = val | ((static_cast(static_cast(t))) << 56); + doc.tape[current_loc++] = val | ((uint64_t(char(t))) << 56); } // this function is responsible for annotating the start of the scope @@ -6922,7 +6937,7 @@ really_inline void parser::end_scope(uint32_t depth) noexcept { // the convention being that a cnt of 0xffffff or more is undetermined in value (>= 0xffffff). const uint32_t cntsat = d.count > 0xFFFFFF ? 0xFFFFFF : d.count; // This is a load and an OR. It would be possible to just write once at doc.tape[d.tape_index] - doc.tape[d.tape_index] |= current_loc | (static_cast(cntsat) << 32); + doc.tape[d.tape_index] |= current_loc | (uint64_t(cntsat) << 32); } } // namespace simdjson @@ -6987,8 +7002,8 @@ really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8 // smash them together into a 64-byte mask and get the bitmask from there. uint64_t bs_and_quote = simd8x64(v0 == '\\', v1 == '\\', v0 == '"', v1 == '"').to_bitmask(); return { - static_cast(bs_and_quote), // bs_bits - static_cast(bs_and_quote >> 32) // quote_bits + uint32_t(bs_and_quote), // bs_bits + uint32_t(bs_and_quote >> 32) // quote_bits }; } @@ -7149,7 +7164,7 @@ static inline uint32_t parse_eight_digits_unrolled(const char *chars) { memcpy(&val, chars, sizeof(uint64_t)); val = (val & 0x0F0F0F0F0F0F0F0F) * 2561 >> 8; val = (val & 0x00FF00FF00FF00FF) * 6553601 >> 16; - return (val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32; + return uint32_t((val & 0x0000FFFF0000FFFF) * 42949672960001 >> 32); } #define SWAR_NUMBER_PARSING @@ -7173,7 +7188,7 @@ really_inline double compute_float_64(int64_t power, uint64_t i, bool negative, if (-22 <= power && power <= 22 && i <= 9007199254740991) { // convert the integer into a double. This is lossless since // 0 <= i <= 2^53 - 1. - double d = i; + double d = double(i); // // The general idea is as follows. // If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then @@ -7279,7 +7294,7 @@ really_inline double compute_float_64(int64_t power, uint64_t i, bool negative, /////// uint64_t upperbit = upper >> 63; uint64_t mantissa = upper >> (upperbit + 9); - lz += 1 ^ upperbit; + lz += int(1 ^ upperbit); // Here we have mantissa < (1<<54). @@ -7433,13 +7448,13 @@ never_inline bool parse_large_integer(const uint8_t *const src, ++p; i = 0; } else { - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); i = digit; p++; // the is_made_of_eight_digits_fast routine is unlikely to help here because // we rarely see large integer parts like 123456789 while (is_integer(*p)) { - digit = *p - '0'; + digit = static_cast(*p - '0'); if (mul_overflow(i, 10, &i)) { #ifdef JSON_TEST_NUMBERS // for unit testing found_invalid_number(src); @@ -7561,13 +7576,13 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, #endif return false; } - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); i = digit; p++; // the is_made_of_eight_digits_fast routine is unlikely to help here because // we rarely see large integer parts like 123456789 while (is_integer(*p)) { - digit = *p - '0'; + digit = static_cast(*p - '0'); // a multiplication by 10 is cheaper than an arbitrary integer // multiplication i = 10 * i + digit; // might overflow, we will handle the overflow later @@ -7585,7 +7600,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, ++p; const char *const first_after_period = p; if (is_integer(*p)) { - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); ++p; i = i * 10 + digit; // might overflow + multiplication by 10 is likely // cheaper than arbitrary mult. @@ -7605,7 +7620,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, } #endif while (is_integer(*p)) { - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); ++p; i = i * 10 + digit; // in rare cases, this will overflow, but that's ok // because we have parse_highprecision_float later. @@ -7613,7 +7628,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, exponent = first_after_period - p; } int digit_count = - p - start_digits - 1; // used later to guard against overflows + int(p - start_digits) - 1; // used later to guard against overflows int64_t exp_number = 0; // exponential part if (('e' == *p) || ('E' == *p)) { is_float = true; @@ -7631,16 +7646,16 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, #endif return false; } - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); exp_number = digit; p++; if (is_integer(*p)) { - digit = *p - '0'; + digit = static_cast(*p - '0'); exp_number = 10 * exp_number + digit; ++p; } if (is_integer(*p)) { - digit = *p - '0'; + digit = static_cast(*p - '0'); exp_number = 10 * exp_number + digit; ++p; } @@ -7652,7 +7667,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, #endif return false; } - digit = *p - '0'; + digit = static_cast(*p - '0'); exp_number = 10 * exp_number + digit; ++p; } @@ -7670,7 +7685,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, start++; } // we over-decrement by one when there is a '.' - digit_count -= (start - start_digits); + digit_count -= int(start - start_digits); if (digit_count >= 19) { // Ok, chances are good that we had an overflow! // this is almost never going to get called!!! @@ -7838,7 +7853,11 @@ struct unified_machine_addresses { class structural_iterator { public: really_inline structural_iterator(const uint8_t* _buf, size_t _len, const uint32_t *_structural_indexes, size_t next_structural_index) - : buf{_buf}, len{_len}, structural_indexes{_structural_indexes}, next_structural{next_structural_index} {} + : buf{_buf}, + len{_len}, + structural_indexes{_structural_indexes}, + next_structural{next_structural_index} + {} really_inline char advance_char() { idx = structural_indexes[next_structural]; next_structural++; @@ -7893,8 +7912,8 @@ public: const size_t len; const uint32_t* const structural_indexes; size_t next_structural; // next structural index - size_t idx; // location of the structural character in the input (buf) - uint8_t c; // used to track the (structural) character we are looking at + size_t idx{0}; // location of the structural character in the input (buf) + uint8_t c{0}; // used to track the (structural) character we are looking at }; struct structural_parser { @@ -8240,7 +8259,7 @@ WARN_UNUSED error_code implementation::parse(const uint8_t *buf, size_t len, par namespace stage2 { struct streaming_structural_parser: structural_parser { - really_inline streaming_structural_parser(const uint8_t *_buf, size_t _len, parser &_doc_parser, size_t _i) : structural_parser(_buf, _len, _doc_parser, _i) {} + really_inline streaming_structural_parser(const uint8_t *buf, size_t len, parser &_doc_parser, uint32_t next_structural) : structural_parser(buf, len, _doc_parser, next_structural) {} // override to add streaming WARN_UNUSED really_inline error_code start(UNUSED size_t len, ret_address finish_parser) { @@ -8280,7 +8299,7 @@ struct streaming_structural_parser: structural_parser { ***********/ WARN_UNUSED error_code implementation::stage2(const uint8_t *buf, size_t len, parser &doc_parser, size_t &next_json) const noexcept { static constexpr stage2::unified_machine_addresses addresses = INIT_ADDRESSES(); - stage2::streaming_structural_parser parser(buf, len, doc_parser, next_json); + stage2::streaming_structural_parser parser(buf, len, doc_parser, uint32_t(next_json)); error_code result = parser.start(len, addresses.finish); if (result) { return result; } // @@ -8688,7 +8707,7 @@ really_inline double compute_float_64(int64_t power, uint64_t i, bool negative, if (-22 <= power && power <= 22 && i <= 9007199254740991) { // convert the integer into a double. This is lossless since // 0 <= i <= 2^53 - 1. - double d = i; + double d = double(i); // // The general idea is as follows. // If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then @@ -8794,7 +8813,7 @@ really_inline double compute_float_64(int64_t power, uint64_t i, bool negative, /////// uint64_t upperbit = upper >> 63; uint64_t mantissa = upper >> (upperbit + 9); - lz += 1 ^ upperbit; + lz += int(1 ^ upperbit); // Here we have mantissa < (1<<54). @@ -8948,13 +8967,13 @@ never_inline bool parse_large_integer(const uint8_t *const src, ++p; i = 0; } else { - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); i = digit; p++; // the is_made_of_eight_digits_fast routine is unlikely to help here because // we rarely see large integer parts like 123456789 while (is_integer(*p)) { - digit = *p - '0'; + digit = static_cast(*p - '0'); if (mul_overflow(i, 10, &i)) { #ifdef JSON_TEST_NUMBERS // for unit testing found_invalid_number(src); @@ -9076,13 +9095,13 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, #endif return false; } - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); i = digit; p++; // the is_made_of_eight_digits_fast routine is unlikely to help here because // we rarely see large integer parts like 123456789 while (is_integer(*p)) { - digit = *p - '0'; + digit = static_cast(*p - '0'); // a multiplication by 10 is cheaper than an arbitrary integer // multiplication i = 10 * i + digit; // might overflow, we will handle the overflow later @@ -9100,7 +9119,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, ++p; const char *const first_after_period = p; if (is_integer(*p)) { - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); ++p; i = i * 10 + digit; // might overflow + multiplication by 10 is likely // cheaper than arbitrary mult. @@ -9120,7 +9139,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, } #endif while (is_integer(*p)) { - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); ++p; i = i * 10 + digit; // in rare cases, this will overflow, but that's ok // because we have parse_highprecision_float later. @@ -9128,7 +9147,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, exponent = first_after_period - p; } int digit_count = - p - start_digits - 1; // used later to guard against overflows + int(p - start_digits) - 1; // used later to guard against overflows int64_t exp_number = 0; // exponential part if (('e' == *p) || ('E' == *p)) { is_float = true; @@ -9146,16 +9165,16 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, #endif return false; } - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); exp_number = digit; p++; if (is_integer(*p)) { - digit = *p - '0'; + digit = static_cast(*p - '0'); exp_number = 10 * exp_number + digit; ++p; } if (is_integer(*p)) { - digit = *p - '0'; + digit = static_cast(*p - '0'); exp_number = 10 * exp_number + digit; ++p; } @@ -9167,7 +9186,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, #endif return false; } - digit = *p - '0'; + digit = static_cast(*p - '0'); exp_number = 10 * exp_number + digit; ++p; } @@ -9185,7 +9204,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, start++; } // we over-decrement by one when there is a '.' - digit_count -= (start - start_digits); + digit_count -= int(start - start_digits); if (digit_count >= 19) { // Ok, chances are good that we had an overflow! // this is almost never going to get called!!! @@ -9354,7 +9373,11 @@ struct unified_machine_addresses { class structural_iterator { public: really_inline structural_iterator(const uint8_t* _buf, size_t _len, const uint32_t *_structural_indexes, size_t next_structural_index) - : buf{_buf}, len{_len}, structural_indexes{_structural_indexes}, next_structural{next_structural_index} {} + : buf{_buf}, + len{_len}, + structural_indexes{_structural_indexes}, + next_structural{next_structural_index} + {} really_inline char advance_char() { idx = structural_indexes[next_structural]; next_structural++; @@ -9409,8 +9432,8 @@ public: const size_t len; const uint32_t* const structural_indexes; size_t next_structural; // next structural index - size_t idx; // location of the structural character in the input (buf) - uint8_t c; // used to track the (structural) character we are looking at + size_t idx{0}; // location of the structural character in the input (buf) + uint8_t c{0}; // used to track the (structural) character we are looking at }; struct structural_parser { @@ -9756,7 +9779,7 @@ WARN_UNUSED error_code implementation::parse(const uint8_t *buf, size_t len, par namespace stage2 { struct streaming_structural_parser: structural_parser { - really_inline streaming_structural_parser(const uint8_t *_buf, size_t _len, parser &_doc_parser, size_t _i) : structural_parser(_buf, _len, _doc_parser, _i) {} + really_inline streaming_structural_parser(const uint8_t *buf, size_t len, parser &_doc_parser, uint32_t next_structural) : structural_parser(buf, len, _doc_parser, next_structural) {} // override to add streaming WARN_UNUSED really_inline error_code start(UNUSED size_t len, ret_address finish_parser) { @@ -9796,7 +9819,7 @@ struct streaming_structural_parser: structural_parser { ***********/ WARN_UNUSED error_code implementation::stage2(const uint8_t *buf, size_t len, parser &doc_parser, size_t &next_json) const noexcept { static constexpr stage2::unified_machine_addresses addresses = INIT_ADDRESSES(); - stage2::streaming_structural_parser parser(buf, len, doc_parser, next_json); + stage2::streaming_structural_parser parser(buf, len, doc_parser, uint32_t(next_json)); error_code result = parser.start(len, addresses.finish); if (result) { return result; } // @@ -10154,7 +10177,7 @@ really_inline double compute_float_64(int64_t power, uint64_t i, bool negative, if (-22 <= power && power <= 22 && i <= 9007199254740991) { // convert the integer into a double. This is lossless since // 0 <= i <= 2^53 - 1. - double d = i; + double d = double(i); // // The general idea is as follows. // If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then @@ -10260,7 +10283,7 @@ really_inline double compute_float_64(int64_t power, uint64_t i, bool negative, /////// uint64_t upperbit = upper >> 63; uint64_t mantissa = upper >> (upperbit + 9); - lz += 1 ^ upperbit; + lz += int(1 ^ upperbit); // Here we have mantissa < (1<<54). @@ -10414,13 +10437,13 @@ never_inline bool parse_large_integer(const uint8_t *const src, ++p; i = 0; } else { - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); i = digit; p++; // the is_made_of_eight_digits_fast routine is unlikely to help here because // we rarely see large integer parts like 123456789 while (is_integer(*p)) { - digit = *p - '0'; + digit = static_cast(*p - '0'); if (mul_overflow(i, 10, &i)) { #ifdef JSON_TEST_NUMBERS // for unit testing found_invalid_number(src); @@ -10542,13 +10565,13 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, #endif return false; } - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); i = digit; p++; // the is_made_of_eight_digits_fast routine is unlikely to help here because // we rarely see large integer parts like 123456789 while (is_integer(*p)) { - digit = *p - '0'; + digit = static_cast(*p - '0'); // a multiplication by 10 is cheaper than an arbitrary integer // multiplication i = 10 * i + digit; // might overflow, we will handle the overflow later @@ -10566,7 +10589,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, ++p; const char *const first_after_period = p; if (is_integer(*p)) { - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); ++p; i = i * 10 + digit; // might overflow + multiplication by 10 is likely // cheaper than arbitrary mult. @@ -10586,7 +10609,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, } #endif while (is_integer(*p)) { - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); ++p; i = i * 10 + digit; // in rare cases, this will overflow, but that's ok // because we have parse_highprecision_float later. @@ -10594,7 +10617,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, exponent = first_after_period - p; } int digit_count = - p - start_digits - 1; // used later to guard against overflows + int(p - start_digits) - 1; // used later to guard against overflows int64_t exp_number = 0; // exponential part if (('e' == *p) || ('E' == *p)) { is_float = true; @@ -10612,16 +10635,16 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, #endif return false; } - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); exp_number = digit; p++; if (is_integer(*p)) { - digit = *p - '0'; + digit = static_cast(*p - '0'); exp_number = 10 * exp_number + digit; ++p; } if (is_integer(*p)) { - digit = *p - '0'; + digit = static_cast(*p - '0'); exp_number = 10 * exp_number + digit; ++p; } @@ -10633,7 +10656,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, #endif return false; } - digit = *p - '0'; + digit = static_cast(*p - '0'); exp_number = 10 * exp_number + digit; ++p; } @@ -10651,7 +10674,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, start++; } // we over-decrement by one when there is a '.' - digit_count -= (start - start_digits); + digit_count -= int(start - start_digits); if (digit_count >= 19) { // Ok, chances are good that we had an overflow! // this is almost never going to get called!!! @@ -10822,7 +10845,11 @@ struct unified_machine_addresses { class structural_iterator { public: really_inline structural_iterator(const uint8_t* _buf, size_t _len, const uint32_t *_structural_indexes, size_t next_structural_index) - : buf{_buf}, len{_len}, structural_indexes{_structural_indexes}, next_structural{next_structural_index} {} + : buf{_buf}, + len{_len}, + structural_indexes{_structural_indexes}, + next_structural{next_structural_index} + {} really_inline char advance_char() { idx = structural_indexes[next_structural]; next_structural++; @@ -10877,8 +10904,8 @@ public: const size_t len; const uint32_t* const structural_indexes; size_t next_structural; // next structural index - size_t idx; // location of the structural character in the input (buf) - uint8_t c; // used to track the (structural) character we are looking at + size_t idx{0}; // location of the structural character in the input (buf) + uint8_t c{0}; // used to track the (structural) character we are looking at }; struct structural_parser { @@ -11224,7 +11251,7 @@ WARN_UNUSED error_code implementation::parse(const uint8_t *buf, size_t len, par namespace stage2 { struct streaming_structural_parser: structural_parser { - really_inline streaming_structural_parser(const uint8_t *_buf, size_t _len, parser &_doc_parser, size_t _i) : structural_parser(_buf, _len, _doc_parser, _i) {} + really_inline streaming_structural_parser(const uint8_t *buf, size_t len, parser &_doc_parser, uint32_t next_structural) : structural_parser(buf, len, _doc_parser, next_structural) {} // override to add streaming WARN_UNUSED really_inline error_code start(UNUSED size_t len, ret_address finish_parser) { @@ -11264,7 +11291,7 @@ struct streaming_structural_parser: structural_parser { ***********/ WARN_UNUSED error_code implementation::stage2(const uint8_t *buf, size_t len, parser &doc_parser, size_t &next_json) const noexcept { static constexpr stage2::unified_machine_addresses addresses = INIT_ADDRESSES(); - stage2::streaming_structural_parser parser(buf, len, doc_parser, next_json); + stage2::streaming_structural_parser parser(buf, len, doc_parser, uint32_t(next_json)); error_code result = parser.start(len, addresses.finish); if (result) { return result; } // @@ -11430,8 +11457,8 @@ really_inline backslash_and_quote backslash_and_quote::copy_and_find(const uint8 v1.store(dst + 16); uint64_t bs_and_quote = simd8x64(v0 == '\\', v1 == '\\', v0 == '"', v1 == '"').to_bitmask(); return { - static_cast(bs_and_quote), // bs_bits - static_cast(bs_and_quote >> 32) // quote_bits + uint32_t(bs_and_quote), // bs_bits + uint32_t(bs_and_quote >> 32) // quote_bits }; } @@ -11626,7 +11653,7 @@ really_inline double compute_float_64(int64_t power, uint64_t i, bool negative, if (-22 <= power && power <= 22 && i <= 9007199254740991) { // convert the integer into a double. This is lossless since // 0 <= i <= 2^53 - 1. - double d = i; + double d = double(i); // // The general idea is as follows. // If 0 <= s < 2^53 and if 10^0 <= p <= 10^22 then @@ -11732,7 +11759,7 @@ really_inline double compute_float_64(int64_t power, uint64_t i, bool negative, /////// uint64_t upperbit = upper >> 63; uint64_t mantissa = upper >> (upperbit + 9); - lz += 1 ^ upperbit; + lz += int(1 ^ upperbit); // Here we have mantissa < (1<<54). @@ -11886,13 +11913,13 @@ never_inline bool parse_large_integer(const uint8_t *const src, ++p; i = 0; } else { - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); i = digit; p++; // the is_made_of_eight_digits_fast routine is unlikely to help here because // we rarely see large integer parts like 123456789 while (is_integer(*p)) { - digit = *p - '0'; + digit = static_cast(*p - '0'); if (mul_overflow(i, 10, &i)) { #ifdef JSON_TEST_NUMBERS // for unit testing found_invalid_number(src); @@ -12014,13 +12041,13 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, #endif return false; } - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); i = digit; p++; // the is_made_of_eight_digits_fast routine is unlikely to help here because // we rarely see large integer parts like 123456789 while (is_integer(*p)) { - digit = *p - '0'; + digit = static_cast(*p - '0'); // a multiplication by 10 is cheaper than an arbitrary integer // multiplication i = 10 * i + digit; // might overflow, we will handle the overflow later @@ -12038,7 +12065,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, ++p; const char *const first_after_period = p; if (is_integer(*p)) { - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); ++p; i = i * 10 + digit; // might overflow + multiplication by 10 is likely // cheaper than arbitrary mult. @@ -12058,7 +12085,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, } #endif while (is_integer(*p)) { - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); ++p; i = i * 10 + digit; // in rare cases, this will overflow, but that's ok // because we have parse_highprecision_float later. @@ -12066,7 +12093,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, exponent = first_after_period - p; } int digit_count = - p - start_digits - 1; // used later to guard against overflows + int(p - start_digits) - 1; // used later to guard against overflows int64_t exp_number = 0; // exponential part if (('e' == *p) || ('E' == *p)) { is_float = true; @@ -12084,16 +12111,16 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, #endif return false; } - unsigned char digit = *p - '0'; + unsigned char digit = static_cast(*p - '0'); exp_number = digit; p++; if (is_integer(*p)) { - digit = *p - '0'; + digit = static_cast(*p - '0'); exp_number = 10 * exp_number + digit; ++p; } if (is_integer(*p)) { - digit = *p - '0'; + digit = static_cast(*p - '0'); exp_number = 10 * exp_number + digit; ++p; } @@ -12105,7 +12132,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, #endif return false; } - digit = *p - '0'; + digit = static_cast(*p - '0'); exp_number = 10 * exp_number + digit; ++p; } @@ -12123,7 +12150,7 @@ really_inline bool parse_number(UNUSED const uint8_t *const src, start++; } // we over-decrement by one when there is a '.' - digit_count -= (start - start_digits); + digit_count -= int(start - start_digits); if (digit_count >= 19) { // Ok, chances are good that we had an overflow! // this is almost never going to get called!!! @@ -12294,7 +12321,11 @@ struct unified_machine_addresses { class structural_iterator { public: really_inline structural_iterator(const uint8_t* _buf, size_t _len, const uint32_t *_structural_indexes, size_t next_structural_index) - : buf{_buf}, len{_len}, structural_indexes{_structural_indexes}, next_structural{next_structural_index} {} + : buf{_buf}, + len{_len}, + structural_indexes{_structural_indexes}, + next_structural{next_structural_index} + {} really_inline char advance_char() { idx = structural_indexes[next_structural]; next_structural++; @@ -12349,8 +12380,8 @@ public: const size_t len; const uint32_t* const structural_indexes; size_t next_structural; // next structural index - size_t idx; // location of the structural character in the input (buf) - uint8_t c; // used to track the (structural) character we are looking at + size_t idx{0}; // location of the structural character in the input (buf) + uint8_t c{0}; // used to track the (structural) character we are looking at }; struct structural_parser { @@ -12696,7 +12727,7 @@ WARN_UNUSED error_code implementation::parse(const uint8_t *buf, size_t len, par namespace stage2 { struct streaming_structural_parser: structural_parser { - really_inline streaming_structural_parser(const uint8_t *_buf, size_t _len, parser &_doc_parser, size_t _i) : structural_parser(_buf, _len, _doc_parser, _i) {} + really_inline streaming_structural_parser(const uint8_t *buf, size_t len, parser &_doc_parser, uint32_t next_structural) : structural_parser(buf, len, _doc_parser, next_structural) {} // override to add streaming WARN_UNUSED really_inline error_code start(UNUSED size_t len, ret_address finish_parser) { @@ -12736,7 +12767,7 @@ struct streaming_structural_parser: structural_parser { ***********/ WARN_UNUSED error_code implementation::stage2(const uint8_t *buf, size_t len, parser &doc_parser, size_t &next_json) const noexcept { static constexpr stage2::unified_machine_addresses addresses = INIT_ADDRESSES(); - stage2::streaming_structural_parser parser(buf, len, doc_parser, next_json); + stage2::streaming_structural_parser parser(buf, len, doc_parser, uint32_t(next_json)); error_code result = parser.start(len, addresses.finish); if (result) { return result; } // diff --git a/singleheader/simdjson.h b/singleheader/simdjson.h index 09414b452..ffd1a4334 100644 --- a/singleheader/simdjson.h +++ b/singleheader/simdjson.h @@ -1,4 +1,4 @@ -/* auto-generated on Mon Apr 20 11:05:12 PDT 2020. Do not edit! */ +/* auto-generated on Thu Apr 23 09:19:14 PDT 2020. Do not edit! */ /* begin file simdjson.h */ #ifndef SIMDJSON_H #define SIMDJSON_H @@ -345,6 +345,7 @@ constexpr size_t DEFAULT_MAX_DEPTH = 1024; // gcc doesn't seem to disable all warnings with all and extra, add warnings here as necessary #define SIMDJSON_PUSH_DISABLE_ALL_WARNINGS SIMDJSON_PUSH_DISABLE_WARNINGS \ SIMDJSON_DISABLE_GCC_WARNING(-Wall) \ + SIMDJSON_DISABLE_GCC_WARNING(-Wconversion) \ SIMDJSON_DISABLE_GCC_WARNING(-Wextra) \ SIMDJSON_DISABLE_GCC_WARNING(-Wattributes) \ SIMDJSON_DISABLE_GCC_WARNING(-Wimplicit-fallthrough) \ @@ -361,11 +362,49 @@ constexpr size_t DEFAULT_MAX_DEPTH = 1024; #endif // MSC_VER -// -// Backfill std::string_view using nonstd::string_view on C++11 -// -#if (!SIMDJSON_CPLUSPLUS17) + +// C++17 requires string_view. +#if SIMDJSON_CPLUSPLUS17 +#define SIMDJSON_HAS_STRING_VIEW +#endif + +// This macro (__cpp_lib_string_view) has to be defined +// for C++17 and better, but if it is otherwise defined, +// we are going to assume that string_view is available +// even if we do not have C++17 support. +#ifdef __cpp_lib_string_view +#define SIMDJSON_HAS_STRING_VIEW +#endif + +// Some systems have string_view even if we do not have C++17 support, +// and even if __cpp_lib_string_view is undefined, it is the case +// with Apple clang version 11. +// We must handle it. *This is important.* +#ifndef SIMDJSON_HAS_STRING_VIEW +#if defined __has_include +// do not combine the next #if with the previous one (unsafe) +#if __has_include () +// now it is safe to trigger the include +#include // though the file is there, it does not follow that we got the implementation +#if defined(_LIBCPP_STRING_VIEW) +// Ah! So we under libc++ which under its Library Fundamentals Technical Specification, which preceeded C++17, +// included string_view. +// This means that we have string_view *even though* we may not have C++17. +#define SIMDJSON_HAS_STRING_VIEW +#endif // _LIBCPP_STRING_VIEW +#endif // __has_include () +#endif // defined __has_include +#endif // def SIMDJSON_HAS_STRING_VIEW +// end of complicated but important routine to try to detect string_view. + +// +// Backfill std::string_view using nonstd::string_view on systems where +// we expect that string_view is missing. Important: if we get this wrong, +// we will end up with two string_view definitions and potential trouble. +// That is why we work so hard above to avoid it. +// +#ifndef SIMDJSON_HAS_STRING_VIEW SIMDJSON_PUSH_DISABLE_ALL_WARNINGS /* begin file simdjson/nonstd/string_view.hpp */ // Copyright 2017-2019 by Martin Moene @@ -1903,7 +1942,8 @@ SIMDJSON_POP_DISABLE_WARNINGS namespace std { using string_view = nonstd::string_view; } -#endif // if (SIMDJSON_CPLUSPLUS < 201703L) +#endif // SIMDJSON_HAS_STRING_VIEW +#undef SIMDJSON_HAS_STRING_VIEW // We are not going to need this macro anymore. #endif // SIMDJSON_COMMON_DEFS_H /* end file */ @@ -2421,8 +2461,9 @@ public: * Get the next value. * * Part of the std::iterator interface. + * */ - inline void operator++() noexcept; + inline iterator& operator++() noexcept; /** * Check if these values come from the same place in the JSON. * @@ -2502,8 +2543,9 @@ public: * Get the next key/value pair. * * Part of the std::iterator interface. + * */ - inline void operator++() noexcept; + inline iterator& operator++() noexcept; /** * Check if these key value pairs come from the same place in the JSON. * @@ -2670,13 +2712,13 @@ public: bool dump_raw_tape(std::ostream &os) const noexcept; /** @private Structural values. */ - std::unique_ptr tape; + std::unique_ptr tape{}; /** @private String values. * * Should be at least byte_capacity. */ - std::unique_ptr string_buf; + std::unique_ptr string_buf{}; private: inline error_code allocate(size_t len) noexcept; @@ -2957,8 +2999,7 @@ public: * to allocate an initial capacity, call allocate() after constructing the parser. * Defaults to SIMDJSON_MAXSIZE_BYTES (the largest single document simdjson can process). */ - really_inline parser(size_t max_capacity = SIMDJSON_MAXSIZE_BYTES) noexcept; - + really_inline explicit parser(size_t max_capacity = SIMDJSON_MAXSIZE_BYTES) noexcept; /** * Take another parser's buffers and state. * @@ -3108,7 +3149,7 @@ public: * - CAPACITY if the parser does not have enough capacity and batch_size > max_capacity. * - other json errors if parsing fails. */ - inline document_stream load_many(const std::string &path, size_t batch_size = DEFAULT_BATCH_SIZE) noexcept; + inline document_stream load_many(const std::string &path, size_t batch_size = DEFAULT_BATCH_SIZE) noexcept; /** * Parse a buffer containing many JSON documents. @@ -3250,21 +3291,21 @@ public: /** @private Number of structural indices passed from stage 1 to stage 2 */ uint32_t n_structural_indexes{0}; /** @private Structural indices passed from stage 1 to stage 2 */ - std::unique_ptr structural_indexes; + std::unique_ptr structural_indexes{}; /** @private Tape location of each open { or [ */ - std::unique_ptr containing_scope; + std::unique_ptr containing_scope{}; #ifdef SIMDJSON_USE_COMPUTED_GOTO /** @private Return address of each open { or [ */ - std::unique_ptr ret_address; + std::unique_ptr ret_address{}; #else /** @private Return address of each open { or [ */ - std::unique_ptr ret_address; + std::unique_ptr ret_address{}; #endif /** @private Next write location in the string buf for stage 2 parsing */ - uint8_t *current_string_buf_loc; + uint8_t *current_string_buf_loc{}; /** @private Use `if (parser.parse(...).error())` instead */ bool valid{false}; @@ -3272,7 +3313,7 @@ public: error_code error{UNINITIALIZED}; /** @private Use `parser.parse(...).value()` instead */ - document doc; + document doc{}; /** @private returns true if the document parsed was valid */ [[deprecated("Use the result of parser.parse() instead")]] @@ -3646,6 +3687,7 @@ namespace simdjson { */ class implementation { public: + /** * The name of this implementation. * @@ -3760,6 +3802,7 @@ protected: _required_instruction_sets(required_instruction_sets) { } + virtual ~implementation()=default; private: /** @@ -3841,7 +3884,7 @@ public: operator T*() { return ptr.load(); } T& operator*() { return *ptr; } T* operator->() { return ptr.load(); } - T* operator=(T *_ptr) { return ptr = _ptr; } + atomic_ptr& operator=(T *_ptr) { ptr = _ptr; return *this; } private: std::atomic ptr; @@ -4002,8 +4045,8 @@ private: error_code error{SUCCESS_AND_HAS_MORE}; #ifdef SIMDJSON_THREADS_ENABLED error_code stage1_is_ok_thread{SUCCESS}; - std::thread stage_1_thread; - dom::parser parser_thread; + std::thread stage_1_thread{}; + dom::parser parser_thread{}; #endif friend class dom::parser; }; // class document_stream @@ -4240,7 +4283,7 @@ inline std::ostream& operator<<(std::ostream& out, const escape_json_string &une if ((unsigned char)unescaped.str[i] <= 0x1F) { // TODO can this be done once at the beginning, or will it mess up << char? std::ios::fmtflags f(out.flags()); - out << "\\u" << std::hex << std::setw(4) << std::setfill('0') << static_cast(unescaped.str[i]); + out << "\\u" << std::hex << std::setw(4) << std::setfill('0') << int(unescaped.str[i]); out.flags(f); } else { out << unescaped.str[i]; @@ -4264,6 +4307,8 @@ public: inline Iterator(const Iterator &o) noexcept; inline ~Iterator() noexcept; + inline Iterator& operator=(const Iterator&) = delete; + inline bool is_ok() const; // useful for debugging purposes @@ -4429,7 +4474,7 @@ public: // is referenced is undefined, and evaluation fails". Here we just return // the first corresponding value. inline bool move_to(const std::string &pointer) { - return move_to(pointer.c_str(), pointer.length()); + return move_to(pointer.c_str(), uint32_t(pointer.length())); } private: @@ -4495,13 +4540,13 @@ public: private: const document &doc; - size_t max_depth; - size_t depth; - size_t location; // our current location on a tape - size_t tape_length; - uint8_t current_type; - uint64_t current_val; - scopeindex_t *depth_index; + size_t max_depth{}; + size_t depth{}; + size_t location{}; // our current location on a tape + size_t tape_length{}; + uint8_t current_type{}; + uint64_t current_val{}; + scopeindex_t *depth_index{}; }; } // namespace simdjson @@ -4721,7 +4766,7 @@ inline error_code document::allocate(size_t capacity) noexcept { // a pathological input like "[[[[..." would generate len tape elements, so // need a capacity of at least len + 1, but it is also possible to do - // worse with "[7,7,7,7,6,7,7,7,6,7,7,6,[7,7,7,7,6,7,7,7,6,7,7,6,7,7,7,7,7,7,6" + // worse with "[7,7,7,7,6,7,7,7,6,7,7,6,[7,7,7,7,6,7,7,7,6,7,7,6,7,7,7,7,7,7,6" //where len + 1 tape elements are // generated, see issue https://github.com/lemire/simdjson/issues/345 size_t tape_capacity = ROUNDUP_N(capacity + 2, 64); @@ -4737,12 +4782,12 @@ inline bool document::dump_raw_tape(std::ostream &os) const noexcept { uint32_t string_length; size_t tape_idx = 0; uint64_t tape_val = tape[tape_idx]; - uint8_t type = (tape_val >> 56); + uint8_t type = uint8_t(tape_val >> 56); os << tape_idx << " : " << type; tape_idx++; size_t how_many = 0; if (type == 'r') { - how_many = tape_val & internal::JSON_VALUE_MASK; + how_many = size_t(tape_val & internal::JSON_VALUE_MASK); } else { // Error: no starting root node? return false; @@ -4753,7 +4798,7 @@ inline bool document::dump_raw_tape(std::ostream &os) const noexcept { os << tape_idx << " : "; tape_val = tape[tape_idx]; payload = tape_val & internal::JSON_VALUE_MASK; - type = (tape_val >> 56); + type = uint8_t(tape_val >> 56); switch (type) { case '"': // we have a string os << "string \""; @@ -4820,7 +4865,7 @@ inline bool document::dump_raw_tape(std::ostream &os) const noexcept { } tape_val = tape[tape_idx]; payload = tape_val & internal::JSON_VALUE_MASK; - type = (tape_val >> 56); + type = uint8_t(tape_val >> 56); os << tape_idx << " : " << type << "\t// pointing to " << payload << " (start root)\n"; return true; @@ -4830,7 +4875,9 @@ inline bool document::dump_raw_tape(std::ostream &os) const noexcept { // parser inline implementation // really_inline parser::parser(size_t max_capacity) noexcept - : _max_capacity{max_capacity}, loaded_bytes(nullptr, &aligned_free_char) {} + : _max_capacity{max_capacity}, + loaded_bytes(nullptr, &aligned_free_char) + {} inline bool parser::is_valid() const noexcept { return valid; } inline int parser::get_error_code() const noexcept { return error; } inline std::string parser::get_error_message() const noexcept { return error_message(error); } @@ -4979,7 +5026,7 @@ inline error_code parser::allocate(size_t capacity, size_t max_depth) noexcept { // // Initialize stage 1 output // - uint32_t max_structures = ROUNDUP_N(capacity, 64) + 2 + 7; + size_t max_structures = ROUNDUP_N(capacity, 64) + 2 + 7; structural_indexes.reset( new (std::nothrow) uint32_t[max_structures] ); // TODO realloc if (!structural_indexes) { return MEMALLOC; @@ -5073,7 +5120,7 @@ inline simdjson_result array::at(const std::string_view &json_pointer) size_t array_index = 0; size_t i; for (i = 0; i < json_pointer.length() && json_pointer[i] != '/'; i++) { - uint8_t digit = uint8_t(json_pointer[i]) - '0'; + uint8_t digit = uint8_t(json_pointer[i] - '0'); // Check for non-digit in array index. If it's there, we're trying to get a field in an object if (digit > 9) { return INCORRECT_TYPE; } array_index = array_index*10 + digit; @@ -5112,8 +5159,9 @@ inline element array::iterator::operator*() const noexcept { inline bool array::iterator::operator!=(const array::iterator& other) const noexcept { return json_index != other.json_index; } -inline void array::iterator::operator++() noexcept { +inline array::iterator& array::iterator::operator++() noexcept { json_index = after_element(); + return *this; } // @@ -5211,12 +5259,13 @@ inline const key_value_pair object::iterator::operator*() const noexcept { inline bool object::iterator::operator!=(const object::iterator& other) const noexcept { return json_index != other.json_index; } -inline void object::iterator::operator++() noexcept { +inline object::iterator& object::iterator::operator++() noexcept { json_index++; json_index = after_element(); + return *this; } inline std::string_view object::iterator::key() const noexcept { - size_t string_buf_index = tape_value(); + size_t string_buf_index = size_t(tape_value()); uint32_t len; memcpy(&len, &doc->string_buf[string_buf_index], sizeof(len)); return std::string_view( @@ -5225,7 +5274,7 @@ inline std::string_view object::iterator::key() const noexcept { ); } inline const char* object::iterator::key_c_str() const noexcept { - return reinterpret_cast(&doc->string_buf[tape_value() + sizeof(uint32_t)]); + return reinterpret_cast(&doc->string_buf[size_t(tape_value()) + sizeof(uint32_t)]); } inline element object::iterator::value() const noexcept { return element(doc, json_index + 1); @@ -5265,7 +5314,7 @@ template<> inline simdjson_result element::get() const noexcept { switch (tape_ref_type()) { case internal::tape_type::STRING: { - size_t string_buf_index = tape_value(); + size_t string_buf_index = size_t(tape_value()); return reinterpret_cast(&doc->string_buf[string_buf_index + sizeof(uint32_t)]); } default: @@ -5289,7 +5338,7 @@ inline simdjson_result element::get() const noexcept { if (result < 0) { return NUMBER_OUT_OF_RANGE; } - return static_cast(result); + return uint64_t(result); } return INCORRECT_TYPE; } @@ -5323,9 +5372,9 @@ inline simdjson_result element::get() const noexcept { // information. (This could also be solved with profile-guided optimization.) if(unlikely(!is_double())) { // branch rarely taken if(is_uint64()) { - return next_tape_value(); + return double(next_tape_value()); } else if(is_int64()) { - return next_tape_value(); + return double(next_tape_value()); } return INCORRECT_TYPE; } @@ -5604,27 +5653,27 @@ really_inline tape_ref::tape_ref(const document *_doc, size_t _json_index) noexc // most significant 8 bits. really_inline bool tape_ref::is_double() const noexcept { - constexpr uint64_t tape_double = static_cast(tape_type::DOUBLE)<<56; + constexpr uint64_t tape_double = uint64_t(tape_type::DOUBLE)<<56; return doc->tape[json_index] == tape_double; } really_inline bool tape_ref::is_int64() const noexcept { - constexpr uint64_t tape_int64 = static_cast(tape_type::INT64)<<56; + constexpr uint64_t tape_int64 = uint64_t(tape_type::INT64)<<56; return doc->tape[json_index] == tape_int64; } really_inline bool tape_ref::is_uint64() const noexcept { - constexpr uint64_t tape_uint64 = static_cast(tape_type::UINT64)<<56; + constexpr uint64_t tape_uint64 = uint64_t(tape_type::UINT64)<<56; return doc->tape[json_index] == tape_uint64; } really_inline bool tape_ref::is_false() const noexcept { - constexpr uint64_t tape_false = static_cast(tape_type::FALSE_VALUE)<<56; + constexpr uint64_t tape_false = uint64_t(tape_type::FALSE_VALUE)<<56; return doc->tape[json_index] == tape_false; } really_inline bool tape_ref::is_true() const noexcept { - constexpr uint64_t tape_true = static_cast(tape_type::TRUE_VALUE)<<56; + constexpr uint64_t tape_true = uint64_t(tape_type::TRUE_VALUE)<<56; return doc->tape[json_index] == tape_true; } really_inline bool tape_ref::is_null_on_tape() const noexcept { - constexpr uint64_t tape_null = static_cast(tape_type::NULL_VALUE)<<56; + constexpr uint64_t tape_null = uint64_t(tape_type::NULL_VALUE)<<56; return doc->tape[json_index] == tape_null; } @@ -5648,10 +5697,10 @@ really_inline uint64_t internal::tape_ref::tape_value() const noexcept { return doc->tape[json_index] & internal::JSON_VALUE_MASK; } really_inline uint32_t internal::tape_ref::matching_brace_index() const noexcept { - return static_cast(doc->tape[json_index]); + return uint32_t(doc->tape[json_index]); } really_inline uint32_t internal::tape_ref::scope_count() const noexcept { - return static_cast((doc->tape[json_index] >> 32) & internal::JSON_COUNT_MASK); + return uint32_t((doc->tape[json_index] >> 32) & internal::JSON_COUNT_MASK); } template @@ -5666,7 +5715,7 @@ really_inline T tape_ref::next_tape_value() const noexcept { return x; } inline std::string_view internal::tape_ref::get_string_view() const noexcept { - size_t string_buf_index = tape_value(); + size_t string_buf_index = size_t(tape_value()); uint32_t len; memcpy(&len, &doc->string_buf[string_buf_index], sizeof(len)); return std::string_view( @@ -5715,7 +5764,7 @@ namespace internal { * complete * document, therefore the last json buffer location is the end of the batch * */ -inline size_t find_last_json_buf_idx(const uint8_t *buf, size_t size, const dom::parser &parser) { +inline uint32_t find_last_json_buf_idx(const uint8_t *buf, size_t size, const dom::parser &parser) { // this function can be generally useful if (parser.n_structural_indexes == 0) return 0; @@ -5767,7 +5816,7 @@ static inline bool is_ascii(char c) { return ((unsigned char)c) <= 127; } -// if the string ends with UTF-8 values, backtrack +// if the string ends with UTF-8 values, backtrack // up to the first ASCII character. May return 0. static inline size_t trimmed_length_safe_utf8(const char * c, size_t len) { while ((len > 0) and (not is_ascii(c[len - 1]))) { @@ -5782,14 +5831,19 @@ static inline size_t trimmed_length_safe_utf8(const char * c, size_t len) { namespace simdjson { namespace dom { - really_inline document_stream::document_stream( dom::parser &_parser, const uint8_t *buf, size_t len, size_t batch_size, error_code _error -) noexcept : parser{_parser}, _buf{buf}, _len{len}, _batch_size(batch_size), error{_error} { +) noexcept + : parser{_parser}, + _buf{buf}, + _len{len}, + _batch_size(batch_size), + error(_error) +{ if (!error) { error = json_parse(); } } @@ -5854,7 +5908,7 @@ inline error_code document_stream::json_parse() noexcept { if (stage1_is_ok != simdjson::SUCCESS) { return stage1_is_ok; } - size_t last_index = internal::find_last_json_buf_idx(buf(), _batch_size, parser); + uint32_t last_index = internal::find_last_json_buf_idx(buf(), _batch_size, parser); if (last_index == 0) { if (parser.n_structural_indexes == 0) { return simdjson::EMPTY; @@ -5931,7 +5985,7 @@ inline error_code document_stream::json_parse() noexcept { if (stage1_is_ok != simdjson::SUCCESS) { return stage1_is_ok; } - size_t last_index = internal::find_last_json_buf_idx(buf(), _batch_size, parser); + uint32_t last_index = internal::find_last_json_buf_idx(buf(), _batch_size, parser); if (last_index == 0) { if (parser.n_structural_indexes == 0) { return EMPTY; @@ -6250,6 +6304,10 @@ inline simdjson_result padded_string::load(const std::string &fil namespace simdjson { +// VS2017 reports deprecated warnings when you define a deprecated class's methods. +SIMDJSON_PUSH_DISABLE_WARNINGS +SIMDJSON_DISABLE_DEPRECATED_WARNING + // Because of template weirdness, the actual class definition is inline in the document class WARN_UNUSED bool dom::parser::Iterator::is_ok() const { @@ -6299,7 +6357,7 @@ bool dom::parser::Iterator::move_forward() { location += 1; current_val = doc.tape[location]; - current_type = (current_val >> 56); + current_type = uint8_t(current_val >> 56); return true; } @@ -6307,7 +6365,7 @@ void dom::parser::Iterator::move_to_value() { // assume that we are on a key, so move by 1. location += 1; current_val = doc.tape[location]; - current_type = (current_val >> 56); + current_type = uint8_t(current_val >> 56); } bool dom::parser::Iterator::move_to_key(const char *key) { @@ -6384,14 +6442,14 @@ bool dom::parser::Iterator::prev() { oldnpos = npos; if ((current_type == '[') || (current_type == '{')) { // we need to jump - npos = static_cast(current_val); + npos = uint32_t(current_val); } else { npos = npos + ((current_type == 'd' || current_type == 'l') ? 2 : 1); } } while (npos < target_location); location = oldnpos; current_val = doc.tape[location]; - current_type = current_val >> 56; + current_type = uint8_t(current_val >> 56); return true; } @@ -6404,7 +6462,7 @@ bool dom::parser::Iterator::up() { depth--; location -= 1; current_val = doc.tape[location]; - current_type = (current_val >> 56); + current_type = uint8_t(current_val >> 56); return true; } @@ -6413,7 +6471,7 @@ bool dom::parser::Iterator::down() { return false; } if ((current_type == '[') || (current_type == '{')) { - size_t npos = static_cast(current_val); + size_t npos = uint32_t(current_val); if (npos == location + 2) { return false; // we have an empty scope } @@ -6423,7 +6481,7 @@ bool dom::parser::Iterator::down() { depth_index[depth].start_of_scope = location; depth_index[depth].scope_type = current_type; current_val = doc.tape[location]; - current_type = (current_val >> 56); + current_type = uint8_t(current_val >> 56); return true; } return false; @@ -6432,19 +6490,19 @@ bool dom::parser::Iterator::down() { void dom::parser::Iterator::to_start_scope() { location = depth_index[depth].start_of_scope; current_val = doc.tape[location]; - current_type = (current_val >> 56); + current_type = uint8_t(current_val >> 56); } bool dom::parser::Iterator::next() { size_t npos; if ((current_type == '[') || (current_type == '{')) { // we need to jump - npos = static_cast(current_val); + npos = uint32_t(current_val); } else { npos = location + (is_number() ? 2 : 1); } uint64_t next_val = doc.tape[npos]; - uint8_t next_type = (next_val >> 56); + uint8_t next_type = uint8_t(next_val >> 56); if ((next_type == ']') || (next_type == '}')) { return false; // we reached the end of the scope } @@ -6453,9 +6511,9 @@ bool dom::parser::Iterator::next() { current_type = next_type; return true; } - dom::parser::Iterator::Iterator(const dom::parser &pj) noexcept(false) - : doc(pj.doc), depth(0), location(0), tape_length(0) { + : doc(pj.doc) +{ #if SIMDJSON_EXCEPTIONS if (!pj.valid) { throw simdjson_error(pj.error); } #else @@ -6466,26 +6524,31 @@ dom::parser::Iterator::Iterator(const dom::parser &pj) noexcept(false) depth_index = new scopeindex_t[max_depth + 1]; depth_index[0].start_of_scope = location; current_val = doc.tape[location++]; - current_type = (current_val >> 56); + current_type = uint8_t(current_val >> 56); depth_index[0].scope_type = current_type; - tape_length = current_val & internal::JSON_VALUE_MASK; + tape_length = size_t(current_val & internal::JSON_VALUE_MASK); if (location < tape_length) { // If we make it here, then depth_capacity must >=2, but the compiler // may not know this. current_val = doc.tape[location]; - current_type = (current_val >> 56); + current_type = uint8_t(current_val >> 56); depth++; assert(depth < max_depth); depth_index[depth].start_of_scope = location; depth_index[depth].scope_type = current_type; } } - dom::parser::Iterator::Iterator( const dom::parser::Iterator &o) noexcept - : doc(o.doc), max_depth(o.depth), depth(o.depth), location(o.location), - tape_length(o.tape_length), current_type(o.current_type), - current_val(o.current_val) { + : doc(o.doc), + max_depth(o.depth), + depth(o.depth), + location(o.location), + tape_length(o.tape_length), + current_type(o.current_type), + current_val(o.current_val), + depth_index() +{ depth_index = new scopeindex_t[max_depth+1]; memcpy(depth_index, o.depth_index, (depth + 1) * sizeof(depth_index[0])); } @@ -6532,7 +6595,7 @@ bool dom::parser::Iterator::print(std::ostream &os, bool escape_strings) const { case '}': // we end an object case '[': // we start an array case ']': // we end an array - os << static_cast(current_type); + os << char(current_type); break; default: return false; @@ -6559,7 +6622,7 @@ bool dom::parser::Iterator::move_to(const char *pointer, new_pointer[new_length] = '\\'; new_length++; } - new_pointer[new_length] = fragment; + new_pointer[new_length] = char(fragment); i += 3; #if __cpp_exceptions } catch (std::invalid_argument &) { @@ -6672,7 +6735,7 @@ bool dom::parser::Iterator::relative_move_to(const char *pointer, bool found = false; if (is_object()) { - if (move_to_key(key_or_index.c_str(), key_or_index.length())) { + if (move_to_key(key_or_index.c_str(), uint32_t(key_or_index.length()))) { found = relative_move_to(pointer + offset, length - offset); } } else if (is_array()) { @@ -6684,14 +6747,14 @@ bool dom::parser::Iterator::relative_move_to(const char *pointer, size_t npos; if ((current_type == '[') || (current_type == '{')) { // we need to jump - npos = static_cast(current_val); + npos = uint32_t(current_val); } else { npos = location + ((current_type == 'd' || current_type == 'l') ? 2 : 1); } location = npos; current_val = doc.tape[npos]; - current_type = (current_val >> 56); + current_type = uint8_t(current_val >> 56); return true; // how could it fail ? } } else { // regular numeric index @@ -6714,6 +6777,8 @@ bool dom::parser::Iterator::relative_move_to(const char *pointer, return found; } +SIMDJSON_POP_DISABLE_WARNINGS + } // namespace simdjson #endif // SIMDJSON_INLINE_PARSEDJSON_ITERATOR_H