diff --git a/include/stringzilla/stringzilla.hpp b/include/stringzilla/stringzilla.hpp index 49644eca..08b89a7d 100644 --- a/include/stringzilla/stringzilla.hpp +++ b/include/stringzilla/stringzilla.hpp @@ -2656,7 +2656,8 @@ class basic_string_slice { * @return For an @b empty `other`, `min(until, size())`. */ size_type rfind(string_view other, size_type until) const noexcept(false) { - return until + other.size() < length_ ? substr(0, until + other.size()).rfind(other) : rfind(other); + return other.size() < length_ && until < length_ - other.size() ? substr(0, until + other.size()).rfind(other) + : rfind(other); } /** @@ -2775,7 +2776,7 @@ class basic_string_slice { * @param until The offset of the last character to be considered. */ size_type find_last_of(byteset set, size_type until) const noexcept { - auto len = sz_min_of_two(until + 1, length_); + auto len = until < length_ ? until + 1 : length_; auto ptr = sz_rfind_byteset(start_, len, &set.raw()); return ptr ? ptr - start_ : npos; } diff --git a/test/find.cpp b/test/find.cpp index 8ccdcff3..b5eec031 100644 --- a/test/find.cpp +++ b/test/find.cpp @@ -161,15 +161,6 @@ static void check_find_unit_( // void test_find_unit() { std::printf(" - testing search & comparison known-answer vectors...\n"); - // Default views use a null pointer, which must not turn an empty match into npos. - for (sz::string_view empty : {sz::string_view(), sz::string_view("")}) { - verify(empty.find("") == 0); - verify(empty.rfind("") == 0); - verify(empty.rfind("", sz::string_view::npos) == 0); - verify(empty.contains("")); - verify(empty.find("a") == sz::string_view::npos); - } - char const *hello = "hello world"; sz_size_t const hello_length = (sz_size_t)std::strlen(hello); // 11 bytes diff --git a/test/string.cpp b/test/string.cpp index bc839f0c..57e3075e 100644 --- a/test/string.cpp +++ b/test/string.cpp @@ -835,6 +835,8 @@ void test_stl_reads_unit() { verify(str("hello").rfind('l', 1) == str::npos); // Substring search in normal and reverse directions. + verify(str().find("") == 0); + verify(str().rfind("") == 0); verify(str("hello").find("ell") == 1); verify(str("hello").find("ell", 1) == 1); verify(str("hello").find("ell", 2) == str::npos); @@ -938,6 +940,9 @@ void test_stl_reads_unit() { } // Boundary conditions. + auto const max_pos = std::numeric_limits::max(); + verify(str("hello").rfind("ell", max_pos) == 1); + verify(str("hello").find_last_of("le", max_pos) == 3); verify(str("hello").find_first_of("ox", 4) == 4); verify(str("hello").find_first_of("ox", 5) == str::npos); verify(str("hello").find_last_of("ox", 4) == 4);