From 1752c8905693d10bf91aecf8855c3e7bdc041da5 Mon Sep 17 00:00:00 2001 From: Avril Date: Mon, 17 Apr 2023 03:36:34 +0100 Subject: [PATCH] `leven_diff()`: Added string literal overloads for comptime string comparison load and allocation reductions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fortune for libexopt's current commit: Blessing − 吉 --- include/leven.h | 17 ++++++++++++++++- include/util.hh | 5 +++-- src/leven.cpp | 4 ++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/include/leven.h b/include/leven.h index 3067af7..c9ee7cc 100644 --- a/include/leven.h +++ b/include/leven.h @@ -4,10 +4,12 @@ #include "exopt.h" #ifdef __cplusplus +//#include "util.hh" #include #include #include +#include #include #include @@ -24,6 +26,7 @@ size_t _EO(leven_diff)(const char* _EO(restrict), const char* _EO(restrict), siz } namespace exopt { namespace util [[gnu::visibility("internal")]] { + template // NOTE: Do not change this manually // constexpr auto leven_diff(std::string_view s1, std::string_view s2) noexcept { const size_t m(s1.size()), @@ -58,7 +61,9 @@ namespace exopt { namespace util [[gnu::visibility("internal")]] { return costs[n]; }; - if consteval { + if constexpr(N > 0) { + return work_on_d(std::array{}); + } else if consteval { return work_on_d(std::vector(n + 1)); } else { thread_local static std::vector d; @@ -74,6 +79,16 @@ namespace exopt { namespace util [[gnu::visibility("internal")]] { return leven_diff(str{sa}, str{sb}); } + template + constexpr decltype(auto) leven_diff(const char (&sa)[M], const char (&sb)[N]) noexcept { + if constexpr(!N) return M; + else if constexpr(!M) return N; + + else if constexpr(M < N) return N - M; //XXX: Are these lines correct? + else if constexpr(N < M) return M - N; // ^ + else return leven_diff(std::string_view{sa}, std::string_view{sb}); + } + } } #endif diff --git a/include/util.hh b/include/util.hh index 762517f..c97122e 100644 --- a/include/util.hh +++ b/include/util.hh @@ -1,16 +1,17 @@ #pragma once +#include #include #include "exopt.h" -#define _EO_CONSTANT_VALUE(X) ([] { \ +#define _EO_CONSTANT_VALUE(X) ([]() { \ struct { \ typedef decltype(X) comptime_constant_t; \ consteval operator comptime_constant_t() const noexcept { return (X); } \ } inner; \ return inner; \ -}()) +})() namespace exopt { namespace util [[gnu::visibility("internal")]] { template diff --git a/src/leven.cpp b/src/leven.cpp index 6feb917..a4fad89 100644 --- a/src/leven.cpp +++ b/src/leven.cpp @@ -1,4 +1,6 @@ +#include + #include #include @@ -18,5 +20,7 @@ namespace exopt { namespace util [[gnu::visibility("internal")]] { static_assert(leven_diff("hello world", "Hello World") == 2, "Levelshtein distance incorrect for non-matching strings"); static_assert(leven_diff("hello world", "hello world") == 0, "Levelshtein distance incorrect for matching strings"); + static_assert(leven_diff("hello world", std::string_view{"hello world"}) == 0, "Levelshtein distance incorrect for matching string container type 1"); + static_assert(leven_diff(std::string{"llo world"}, std::string_view{"hello world"}) == 2, "Levelshtein distance incorrect for matching string container type 2"); } }