diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml index 5d9fe720..8f8b7803 100644 --- a/.github/workflows/prerelease.yml +++ b/.github/workflows/prerelease.yml @@ -28,7 +28,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Run TinySemVer - uses: ashvardanian/tinysemver@v2.0.7 + uses: ashvardanian/tinysemver@v2.1.1 with: verbose: "true" version-file: "VERSION" @@ -465,7 +465,7 @@ jobs: if: matrix.os == 'ubuntu-24.04' uses: docker/setup-qemu-action@v3 - name: Install cibuildwheel - run: python -m pip install cibuildwheel + run: python -m pip install cibuildwheel==2.21.3 - name: Build wheels run: cibuildwheel --output-dir wheelhouse env: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 79aa61fe..80a8f989 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Run TinySemVer - uses: ashvardanian/tinysemver@v2.0.7 + uses: ashvardanian/tinysemver@v2.1.1 with: verbose: "true" version-file: "VERSION" @@ -93,7 +93,7 @@ jobs: if: matrix.os == 'ubuntu-24.04' # We only need QEMU for Linux builds uses: docker/setup-qemu-action@v3 - name: Install cibuildwheel - run: python -m pip install cibuildwheel + run: python -m pip install cibuildwheel==2.21.3 - name: Build wheels run: cibuildwheel --output-dir wheelhouse env: diff --git a/include/stringzilla/stringzilla.h b/include/stringzilla/stringzilla.h index 3d43a71c..3721c5b0 100644 --- a/include/stringzilla/stringzilla.h +++ b/include/stringzilla/stringzilla.h @@ -5818,7 +5818,7 @@ SZ_PUBLIC sz_bool_t sz_equal_neon(sz_cptr_t a, sz_cptr_t b, sz_size_t length) { a_vec.u8x16 = vld1q_u8((sz_u8_t const *)a); b_vec.u8x16 = vld1q_u8((sz_u8_t const *)b); uint8x16_t cmp = vceqq_u8(a_vec.u8x16, b_vec.u8x16); - if (vmaxvq_u8(cmp) != 255) { return sz_false_k; } // Check if all bytes match + if (vminvq_u8(cmp) != 255) { return sz_false_k; } // Check if all bytes match } // Handle remaining bytes diff --git a/include/stringzilla/stringzilla.hpp b/include/stringzilla/stringzilla.hpp index 736877df..89620860 100644 --- a/include/stringzilla/stringzilla.hpp +++ b/include/stringzilla/stringzilla.hpp @@ -3681,6 +3681,41 @@ bool basic_string::try_preparing_replacement(size_type o } } +/** + * @brief Helper function-like object to order string-view convertible objects with StringZilla. + * @see Similar to `std::less`: https://en.cppreference.com/w/cpp/utility/functional/less + * + * Unlike the STL analog, doesn't require C++14 or including the heavy `` header. + * Can be used to combine STL classes with StringZilla logic, like: `std::map`. + */ +struct string_view_less { + bool operator()(string_view a, string_view b) const noexcept { return a < b; } +}; + +/** + * @brief Helper function-like object to check equality between string-view convertible objects with StringZilla. + * @see Similar to `std::equal_to`: https://en.cppreference.com/w/cpp/utility/functional/equal_to + * + * Unlike the STL analog, doesn't require C++14 or including the heavy `` header. + * Can be used to combine STL classes with StringZilla logic, like: + * `std::unordered_map`. + */ +struct string_view_equal_to { + bool operator()(string_view a, string_view b) const noexcept { return a == b; } +}; + +/** + * @brief Helper function-like object to hash string-view convertible objects with StringZilla. + * @see Similar to `std::hash`: https://en.cppreference.com/w/cpp/utility/functional/hash + * + * Unlike the STL analog, doesn't require C++14 or including the heavy `` header. + * Can be used to combine STL classes with StringZilla logic, like: + * `std::unordered_map`. + */ +struct string_view_hash { + std::size_t operator()(string_view str) const noexcept { return str.hash(); } +}; + /** @brief SFINAE-type used to infer the resulting type of concatenating multiple string together. */ template struct concatenation_result {}; diff --git a/scripts/test.cpp b/scripts/test.cpp index 8c1186ea..c32cc92d 100644 --- a/scripts/test.cpp +++ b/scripts/test.cpp @@ -24,14 +24,16 @@ #include // ASAN #endif -#include // `std::transform` -#include // `std::printf` -#include // `std::memcpy` -#include // `std::distance` -#include // `std::allocator` -#include // `std::random_device` -#include // `std::ostringstream` -#include // `std::vector` +#include // `std::transform` +#include // `std::printf` +#include // `std::memcpy` +#include // `std::distance` +#include // `std::map` +#include // `std::allocator` +#include // `std::random_device` +#include // `std::ostringstream` +#include // `std::unordered_map` +#include // `std::vector` #include // Baseline #include // Baseline @@ -58,6 +60,14 @@ template class std::basic_string; template class sz::basic_string; template class sz::basic_charset; +template class std::vector; +template class std::map; +template class std::unordered_map; + +template class std::vector; +template class std::map; +template class std::unordered_map; + /** * @brief Several string processing operations rely on computing integer logarithms. * Failures in such operations will result in wrong `resize` outcomes and heap corruption. @@ -394,6 +404,10 @@ static void test_stl_compatibility_for_reads() { assert(str("12341234") <= str("12341234")); assert(str("12341234") > str("12241224")); assert(str("12341234") < str("13241324")); + assert(str("0123456789012345678901234567890123456789012345678901234567890123") == + str("0123456789012345678901234567890123456789012345678901234567890123")); + assert(str("0123456789012345678901234567890123456789012345678901234567890123") != + str("0223456789012345678901234567890123456789012345678901234567890123")); // Comparisons. assert(str("a") != str("b")); @@ -1489,6 +1503,21 @@ static void test_sequence_algorithms() { } } +/** + * @brief Tests constructing STL containers with StringZilla strings. + */ +static void test_stl_containers() { + std::map sorted_words_sz; + std::unordered_map words_sz; + assert(sorted_words_sz.empty()); + assert(words_sz.empty()); + + std::map sorted_words_stl; + std::unordered_map words_stl; + assert(sorted_words_stl.empty()); + assert(words_stl.empty()); +} + int main(int argc, char const **argv) { // Let's greet the user nicely @@ -1539,6 +1568,7 @@ int main(int argc, char const **argv) { // Sequences of strings test_sequence_algorithms(); + test_stl_containers(); std::printf("All tests passed... Unbelievable!\n"); return 0;