Skip to content

Commit

Permalink
Merge pull request #198 from ashvardanian/main-dev
Browse files Browse the repository at this point in the history
Equality Checks & C++ Function Objects
  • Loading branch information
ashvardanian authored Nov 30, 2024
2 parents 30d3e21 + 592034c commit c280645
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 13 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/prerelease.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion include/stringzilla/stringzilla.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
35 changes: 35 additions & 0 deletions include/stringzilla/stringzilla.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3681,6 +3681,41 @@ bool basic_string<char_type_, allocator_>::try_preparing_replacement(size_type o
}
}

/**
* @brief Helper function-like object to order string-view convertible objects with StringZilla.
* @see Similar to `std::less<std::string_view>`: https://en.cppreference.com/w/cpp/utility/functional/less
*
* Unlike the STL analog, doesn't require C++14 or including the heavy `<functional>` header.
* Can be used to combine STL classes with StringZilla logic, like: `std::map<std::string, int, sz::string_view_less>`.
*/
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<std::string_view>`: https://en.cppreference.com/w/cpp/utility/functional/equal_to
*
* Unlike the STL analog, doesn't require C++14 or including the heavy `<functional>` header.
* Can be used to combine STL classes with StringZilla logic, like:
* `std::unordered_map<std::string, int, sz::string_view_hash, sz::string_view_equal_to>`.
*/
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<std::string_view>`: https://en.cppreference.com/w/cpp/utility/functional/hash
*
* Unlike the STL analog, doesn't require C++14 or including the heavy `<functional>` header.
* Can be used to combine STL classes with StringZilla logic, like:
* `std::unordered_map<std::string, int, sz::string_view_hash, sz::string_view_equal_to>`.
*/
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 <typename... args_types>
struct concatenation_result {};
Expand Down
46 changes: 38 additions & 8 deletions scripts/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@
#include <sanitizer/asan_interface.h> // ASAN
#endif

#include <algorithm> // `std::transform`
#include <cstdio> // `std::printf`
#include <cstring> // `std::memcpy`
#include <iterator> // `std::distance`
#include <memory> // `std::allocator`
#include <random> // `std::random_device`
#include <sstream> // `std::ostringstream`
#include <vector> // `std::vector`
#include <algorithm> // `std::transform`
#include <cstdio> // `std::printf`
#include <cstring> // `std::memcpy`
#include <iterator> // `std::distance`
#include <map> // `std::map`
#include <memory> // `std::allocator`
#include <random> // `std::random_device`
#include <sstream> // `std::ostringstream`
#include <unordered_map> // `std::unordered_map`
#include <vector> // `std::vector`

#include <string> // Baseline
#include <string_view> // Baseline
Expand All @@ -58,6 +60,14 @@ template class std::basic_string<char>;
template class sz::basic_string<char>;
template class sz::basic_charset<char>;

template class std::vector<sz::string>;
template class std::map<sz::string, int>;
template class std::unordered_map<sz::string, int>;

template class std::vector<sz::string_view>;
template class std::map<sz::string_view, int>;
template class std::unordered_map<sz::string_view, int>;

/**
* @brief Several string processing operations rely on computing integer logarithms.
* Failures in such operations will result in wrong `resize` outcomes and heap corruption.
Expand Down Expand Up @@ -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"));
Expand Down Expand Up @@ -1489,6 +1503,21 @@ static void test_sequence_algorithms() {
}
}

/**
* @brief Tests constructing STL containers with StringZilla strings.
*/
static void test_stl_containers() {
std::map<sz::string, int> sorted_words_sz;
std::unordered_map<sz::string, int> words_sz;
assert(sorted_words_sz.empty());
assert(words_sz.empty());

std::map<std::string, int, sz::string_view_less> sorted_words_stl;
std::unordered_map<std::string, int, sz::string_view_hash, sz::string_view_equal_to> words_stl;
assert(sorted_words_stl.empty());
assert(words_stl.empty());
}

int main(int argc, char const **argv) {

// Let's greet the user nicely
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit c280645

Please sign in to comment.