From c6dcbed2e5327f0c11962bdbbcd02f1b5c570fea Mon Sep 17 00:00:00 2001 From: Alex Brachet Date: Mon, 9 Jan 2023 20:13:02 +0000 Subject: [PATCH] [libc] Templatize str{,n}cmp This will be used to implement the case insensitive str{,n}casecmp Differential Revision: https://reviews.llvm.org/D141235 --- libc/src/__support/CPP/functional.h | 4 ++ libc/src/string/CMakeLists.txt | 6 +++ libc/src/string/memory_utils/CMakeLists.txt | 6 +++ .../string/memory_utils/strcmp_implementations.h | 44 ++++++++++++++++++++++ libc/src/string/strcmp.cpp | 8 ++-- libc/src/string/strncmp.cpp | 16 ++------ utils/bazel/llvm-project-overlay/libc/BUILD.bazel | 3 ++ 7 files changed, 70 insertions(+), 17 deletions(-) create mode 100644 libc/src/string/memory_utils/strcmp_implementations.h diff --git a/libc/src/__support/CPP/functional.h b/libc/src/__support/CPP/functional.h index 5919306..b77100c 100644 --- a/libc/src/__support/CPP/functional.h +++ b/libc/src/__support/CPP/functional.h @@ -24,6 +24,10 @@ public: constexpr R operator()(Args... params) { return func(params...); } }; +template struct minus { + constexpr T operator()(const T &lhs, const T &rhs) const { return lhs - rhs; } +}; + } // namespace cpp } // namespace __llvm_libc diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt index 0faa1db..93357be 100644 --- a/libc/src/string/CMakeLists.txt +++ b/libc/src/string/CMakeLists.txt @@ -111,6 +111,9 @@ add_entrypoint_object( strcmp.cpp HDRS strcmp.h + DEPENDS + .memory_utils.strcmp_implementation + libc.src.__support.CPP.functional ) add_entrypoint_object( @@ -226,6 +229,9 @@ add_entrypoint_object( strncmp.cpp HDRS strncmp.h + DEPENDS + .memory_utils.strcmp_implementation + libc.src.__support.CPP.functional ) add_entrypoint_object( diff --git a/libc/src/string/memory_utils/CMakeLists.txt b/libc/src/string/memory_utils/CMakeLists.txt index 3bf81e9..10e14e1 100644 --- a/libc/src/string/memory_utils/CMakeLists.txt +++ b/libc/src/string/memory_utils/CMakeLists.txt @@ -60,3 +60,9 @@ add_header_library( DEPS .memset_implementation ) + +add_header_library( + strcmp_implementation + HDRS + strcmp_implementations.h +) diff --git a/libc/src/string/memory_utils/strcmp_implementations.h b/libc/src/string/memory_utils/strcmp_implementations.h new file mode 100644 index 0000000..3a7caee --- /dev/null +++ b/libc/src/string/memory_utils/strcmp_implementations.h @@ -0,0 +1,44 @@ +//===-- str{,case}cmp 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_STRCMP_IMPLEMENTATIONS_H +#define LLVM_LIBC_SRC_STRING_MEMORY_UTILS_STRCMP_IMPLEMENTATIONS_H + +#include + +namespace __llvm_libc { + +template +constexpr static int strcmp_implementation(const char *left, const char *right, + Comp &&comp) { + // TODO: Look at benefits for comparing words at a time. + for (; *left && !comp(*left, *right); ++left, ++right) + ; + return comp(*reinterpret_cast(left), + *reinterpret_cast(right)); +} + +template +constexpr static int strncmp_implementation(const char *left, const char *right, + size_t n, Comp &&comp) { + if (n == 0) + return 0; + + // TODO: Look at benefits for comparing words at a time. + for (; n > 1; --n, ++left, ++right) { + char lc = *left; + if (!comp(lc, '\0') || comp(lc, *right)) + break; + } + return comp(*reinterpret_cast(left), + *reinterpret_cast(right)); +} + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_STRING_MEMORY_UTILS_STRCMP_IMPLEMENTATIONS_H diff --git a/libc/src/string/strcmp.cpp b/libc/src/string/strcmp.cpp index 8468b3c..738b578 100644 --- a/libc/src/string/strcmp.cpp +++ b/libc/src/string/strcmp.cpp @@ -8,16 +8,14 @@ #include "src/string/strcmp.h" +#include "src/__support/CPP/functional.h" #include "src/__support/common.h" +#include "src/string/memory_utils/strcmp_implementations.h" namespace __llvm_libc { -// TODO: Look at benefits for comparing words at a time. LLVM_LIBC_FUNCTION(int, strcmp, (const char *left, const char *right)) { - for (; *left && *left == *right; ++left, ++right) - ; - return *reinterpret_cast(left) - - *reinterpret_cast(right); + return strcmp_implementation(left, right, cpp::minus{}); } } // namespace __llvm_libc diff --git a/libc/src/string/strncmp.cpp b/libc/src/string/strncmp.cpp index 94960e5..f8cf757 100644 --- a/libc/src/string/strncmp.cpp +++ b/libc/src/string/strncmp.cpp @@ -8,25 +8,17 @@ #include "src/string/strncmp.h" +#include "src/__support/CPP/functional.h" #include "src/__support/common.h" +#include "src/string/memory_utils/strcmp_implementations.h" + #include namespace __llvm_libc { -// TODO: Look at benefits for comparing words at a time. LLVM_LIBC_FUNCTION(int, strncmp, (const char *left, const char *right, size_t n)) { - - if (n == 0) - return 0; - - for (; n > 1; --n, ++left, ++right) { - char lc = *left; - if (lc == '\0' || lc != *right) - break; - } - return *reinterpret_cast(left) - - *reinterpret_cast(right); + return strncmp_implementation(left, right, n, cpp::minus{}); } } // namespace __llvm_libc diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index d75e578..a43e1b7 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -1089,6 +1089,7 @@ libc_support_library( "src/string/memory_utils/memcpy_implementations.h", "src/string/memory_utils/memmove_implementations.h", "src/string/memory_utils/memset_implementations.h", + "src/string/memory_utils/strcmp_implementations.h", ], deps = [ ":__support_common", @@ -1270,6 +1271,8 @@ libc_function( hdrs = ["src/string/strcmp.h"], deps = [ ":__support_common", + ":__support_cpp_functional", + ":string_memory_utils", ":string_utils", ], ) -- 2.7.4