|
|
|
@ -4,10 +4,12 @@
|
|
|
|
|
#include "exopt.h"
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
//#include "util.hh"
|
|
|
|
|
|
|
|
|
|
#include <string_view>
|
|
|
|
|
#include <concepts>
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <array>
|
|
|
|
|
#include <span>
|
|
|
|
|
#include <tuple>
|
|
|
|
|
|
|
|
|
@ -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<size_t N =0> // 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<size_t, N+1>{});
|
|
|
|
|
} else if consteval {
|
|
|
|
|
return work_on_d(std::vector<size_t>(n + 1));
|
|
|
|
|
} else {
|
|
|
|
|
thread_local static std::vector<size_t> d;
|
|
|
|
@ -74,6 +79,16 @@ namespace exopt { namespace util [[gnu::visibility("internal")]] {
|
|
|
|
|
return leven_diff(str{sa}, str{sb});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<size_t M, size_t N>
|
|
|
|
|
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<N>(std::string_view{sa}, std::string_view{sb});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} }
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|