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"); } }