[libc] Templatize strstr
authorAlex Brachet <abrachet@google.com>
Wed, 25 Jan 2023 16:42:34 +0000 (16:42 +0000)
committerAlex Brachet <abrachet@google.com>
Wed, 25 Jan 2023 16:42:34 +0000 (16:42 +0000)
Differential Revision: https://reviews.llvm.org/D142517

libc/src/string/CMakeLists.txt
libc/src/string/memory_utils/CMakeLists.txt
libc/src/string/memory_utils/strstr_implementations.h [new file with mode: 0644]
libc/src/string/strstr.cpp
utils/bazel/llvm-project-overlay/libc/BUILD.bazel

index 749cfab8d01f1260443ed4eb280f3fe3c7de7d41..9c580dcaae1aa040c768c9e7ad312b4adb88c6f8 100644 (file)
@@ -330,6 +330,8 @@ add_entrypoint_object(
     strstr.cpp
   HDRS
     strstr.h
+  DEPENDS
+    .memory_utils.strstr_implementation
 )
 
 add_entrypoint_object(
index 10e14e1a40fc33405e0a7016d8bfe4d21425c742..9a4df7c9508374873454b9c2434a5948bc647ca1 100644 (file)
@@ -66,3 +66,9 @@ add_header_library(
   HDRS
     strcmp_implementations.h
 )
+
+add_header_library(
+  strstr_implementation
+  HDRS
+    strstr_implementations.h
+)
diff --git a/libc/src/string/memory_utils/strstr_implementations.h b/libc/src/string/memory_utils/strstr_implementations.h
new file mode 100644 (file)
index 0000000..2c81ca7
--- /dev/null
@@ -0,0 +1,33 @@
+//===-- str{,case}str implementation ----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_STRSTR_IMPLEMENTATIONS_H
+#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_STRSTR_IMPLEMENTATIONS_H
+
+#include <stddef.h>
+
+namespace __llvm_libc {
+
+template <typename Comp>
+constexpr static char *strstr_implementation(const char *haystack,
+                                             const char *needle, Comp &&comp) {
+  // TODO: This is a simple brute force implementation. This can be
+  // improved upon using well known string matching algorithms.
+  for (size_t i = 0; comp(haystack[i], 0); ++i) {
+    size_t j = 0;
+    for (; comp(haystack[i + j], 0) && !comp(haystack[i + j], needle[j]); ++j)
+      ;
+    if (!comp(needle[j], 0))
+      return const_cast<char *>(haystack + i);
+  }
+  return nullptr;
+}
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_STRSTR_IMPLEMENTATIONS_H
index 3ec32fddd942f8d46df30864779c35543b2e6294..643461da5993543b35ccc8124b1a518aed66734e 100644 (file)
@@ -9,21 +9,15 @@
 #include "src/string/strstr.h"
 
 #include "src/__support/common.h"
-#include <stddef.h>
+#include "src/string/memory_utils/strstr_implementations.h"
 
 namespace __llvm_libc {
 
 // TODO: This is a simple brute force implementation. This can be
 // improved upon using well known string matching algorithms.
 LLVM_LIBC_FUNCTION(char *, strstr, (const char *haystack, const char *needle)) {
-  for (size_t i = 0; haystack[i]; ++i) {
-    size_t j;
-    for (j = 0; haystack[i + j] && haystack[i + j] == needle[j]; ++j)
-      ;
-    if (!needle[j])
-      return const_cast<char *>(haystack + i);
-  }
-  return nullptr;
+  auto comp = [](char l, char r) -> int { return l - r; };
+  return strstr_implementation(haystack, needle, comp);
 }
 
 } // namespace __llvm_libc
index ecfdb4f48096a671293339cf71ba0e550e5194c1..e8d7f8b608d3acc5dacca1e5a8b99536c1ab73fb 100644 (file)
@@ -1103,6 +1103,7 @@ libc_support_library(
         "src/string/memory_utils/memmove_implementations.h",
         "src/string/memory_utils/memset_implementations.h",
         "src/string/memory_utils/strcmp_implementations.h",
+        "src/string/memory_utils/strstr_implementations.h",
     ],
     deps = [
         ":__support_common",
@@ -1315,6 +1316,7 @@ libc_function(
     hdrs = ["src/string/strstr.h"],
     deps = [
         ":__support_common",
+        ":string_memory_utils",
         ":string_utils",
     ],
 )