summaryrefslogtreecommitdiff
path: root/absl/strings/string_view.cc
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings/string_view.cc')
-rw-r--r--absl/strings/string_view.cc30
1 files changed, 26 insertions, 4 deletions
diff --git a/absl/strings/string_view.cc b/absl/strings/string_view.cc
index e2261625..f20ff530 100644
--- a/absl/strings/string_view.cc
+++ b/absl/strings/string_view.cc
@@ -21,12 +21,35 @@
#include <cstring>
#include <ostream>
-#include "absl/strings/internal/memutil.h"
-
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace {
+
+// This is significantly faster for case-sensitive matches with very
+// few possible matches.
+const char* memmatch(const char* phaystack, size_t haylen, const char* pneedle,
+ size_t neelen) {
+ if (0 == neelen) {
+ return phaystack; // even if haylen is 0
+ }
+ if (haylen < neelen) return nullptr;
+
+ const char* match;
+ const char* hayend = phaystack + haylen - neelen + 1;
+ // A static cast is used here to work around the fact that memchr returns
+ // a void* on Posix-compliant systems and const void* on Windows.
+ while (
+ (match = static_cast<const char*>(memchr(
+ phaystack, pneedle[0], static_cast<size_t>(hayend - phaystack))))) {
+ if (memcmp(match, pneedle, neelen) == 0)
+ return match;
+ else
+ phaystack = match + 1;
+ }
+ return nullptr;
+}
+
void WritePadding(std::ostream& o, size_t pad) {
char fill_buf[32];
memset(fill_buf, o.fill(), sizeof(fill_buf));
@@ -84,8 +107,7 @@ string_view::size_type string_view::find(string_view s,
if (empty() && pos == 0 && s.empty()) return 0;
return npos;
}
- const char* result =
- strings_internal::memmatch(ptr_ + pos, length_ - pos, s.ptr_, s.length_);
+ const char* result = memmatch(ptr_ + pos, length_ - pos, s.ptr_, s.length_);
return result ? static_cast<size_type>(result - ptr_) : npos;
}