xref: /llvm-project/libc/src/string/memory_utils/inline_memmem.h (revision 5ff3ff33ff930e4ec49da7910612d8a41eb068cb)
11f578347SGuillaume Chatelet //===-- memmem implementation -----------------------------------*- C++ -*-===//
21f578347SGuillaume Chatelet //
31f578347SGuillaume Chatelet // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41f578347SGuillaume Chatelet // See https://llvm.org/LICENSE.txt for license information.
51f578347SGuillaume Chatelet // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61f578347SGuillaume Chatelet //
71f578347SGuillaume Chatelet //===----------------------------------------------------------------------===//
81f578347SGuillaume Chatelet 
91f578347SGuillaume Chatelet #ifndef LLVM_LIBC_SRC_STRING_MEMORY_UTILS_INLINE_MEMMEM_H
101f578347SGuillaume Chatelet #define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_INLINE_MEMMEM_H
111f578347SGuillaume Chatelet 
12019a477cSRoland McGrath #include "src/__support/macros/attributes.h"
13*5ff3ff33SPetr Hosek #include "src/__support/macros/config.h"
14019a477cSRoland McGrath 
151f578347SGuillaume Chatelet #include <stddef.h>
161f578347SGuillaume Chatelet 
17*5ff3ff33SPetr Hosek namespace LIBC_NAMESPACE_DECL {
181f578347SGuillaume Chatelet 
191f578347SGuillaume Chatelet template <typename Comp>
20019a477cSRoland McGrath LIBC_INLINE constexpr static void *
21019a477cSRoland McGrath inline_memmem(const void *haystack, size_t haystack_len, const void *needle,
22019a477cSRoland McGrath               size_t needle_len, Comp &&comp) {
231f578347SGuillaume Chatelet   // TODO: simple brute force implementation. This can be
241f578347SGuillaume Chatelet   // improved upon using well known string matching algorithms.
251f578347SGuillaume Chatelet   if (!needle_len)
261f578347SGuillaume Chatelet     return const_cast<void *>(haystack);
271f578347SGuillaume Chatelet 
281f578347SGuillaume Chatelet   if (needle_len > haystack_len)
291f578347SGuillaume Chatelet     return nullptr;
301f578347SGuillaume Chatelet 
311f578347SGuillaume Chatelet   const unsigned char *h = static_cast<const unsigned char *>(haystack);
321f578347SGuillaume Chatelet   const unsigned char *n = static_cast<const unsigned char *>(needle);
331f578347SGuillaume Chatelet   for (size_t i = 0; i <= (haystack_len - needle_len); ++i) {
341f578347SGuillaume Chatelet     size_t j = 0;
351f578347SGuillaume Chatelet     for (; j < needle_len && !comp(h[i + j], n[j]); ++j)
361f578347SGuillaume Chatelet       ;
371f578347SGuillaume Chatelet     if (j == needle_len)
381f578347SGuillaume Chatelet       return const_cast<unsigned char *>(h + i);
391f578347SGuillaume Chatelet   }
401f578347SGuillaume Chatelet   return nullptr;
411f578347SGuillaume Chatelet }
421f578347SGuillaume Chatelet 
43*5ff3ff33SPetr Hosek } // namespace LIBC_NAMESPACE_DECL
441f578347SGuillaume Chatelet 
451f578347SGuillaume Chatelet #endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_INLINE_MEMMEM_H
46