mirror of https://github.com/zeldaret/botw.git
ksys/utils: Add FixedString for light constexpr string manipulation
This commit is contained in:
parent
7828ee535d
commit
af1aacc5bd
|
@ -111,6 +111,7 @@ add_executable(uking
|
||||||
src/KingSystem/Utils/ByamlLocal.h
|
src/KingSystem/Utils/ByamlLocal.h
|
||||||
src/KingSystem/Utils/ByamlUtil.cpp
|
src/KingSystem/Utils/ByamlUtil.cpp
|
||||||
src/KingSystem/Utils/Debug.h
|
src/KingSystem/Utils/Debug.h
|
||||||
|
src/KingSystem/Utils/FixedString.h
|
||||||
src/KingSystem/Utils/HashUtil.h
|
src/KingSystem/Utils/HashUtil.h
|
||||||
src/KingSystem/Utils/HeapUtil.cpp
|
src/KingSystem/Utils/HeapUtil.cpp
|
||||||
src/KingSystem/Utils/HeapUtil.h
|
src/KingSystem/Utils/HeapUtil.h
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace ksys::util {
|
||||||
|
|
||||||
|
// https://stackoverflow.com/a/53190503/1636285
|
||||||
|
|
||||||
|
struct concat_op {};
|
||||||
|
|
||||||
|
template <std::size_t N>
|
||||||
|
struct FixedString {
|
||||||
|
constexpr static std::size_t length() { return N; }
|
||||||
|
constexpr static std::size_t capacity() { return N + 1; }
|
||||||
|
|
||||||
|
template <std::size_t L, std::size_t R>
|
||||||
|
constexpr FixedString(concat_op, FixedString<L> l, FixedString<R> r) : FixedString() {
|
||||||
|
static_assert(L + R == N);
|
||||||
|
overwrite(0, l.data(), L);
|
||||||
|
overwrite(L, r.data(), R);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr FixedString() : buffer_{} {}
|
||||||
|
|
||||||
|
constexpr FixedString(const char (&source)[N + 1]) : FixedString() {
|
||||||
|
do_copy(source, buffer_.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr const char* data() const { return buffer_.data(); }
|
||||||
|
|
||||||
|
constexpr char* data() { return buffer_.data(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr void do_copy(const char (&source)[N + 1], char* dest) {
|
||||||
|
for (std::size_t i = 0; i < capacity(); ++i)
|
||||||
|
dest[i] = source[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void overwrite(std::size_t where, const char* source, std::size_t len) {
|
||||||
|
auto dest = buffer_.data() + where;
|
||||||
|
while (len--)
|
||||||
|
*dest++ = *source++;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<char, capacity()> buffer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <std::size_t N>
|
||||||
|
constexpr FixedString<N - 1> Str(const char (&c)[N]) {
|
||||||
|
return FixedString<N - 1>(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <auto N, int base = 10>
|
||||||
|
constexpr auto Str() {
|
||||||
|
constexpr char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
|
FixedString<([]() constexpr noexcept {
|
||||||
|
unsigned int len = N > 0 ? 0 : 1;
|
||||||
|
for (auto n = N; n; len++, n /= base)
|
||||||
|
continue;
|
||||||
|
return len;
|
||||||
|
}())>
|
||||||
|
buf{};
|
||||||
|
|
||||||
|
auto ptr = buf.data() + buf.length();
|
||||||
|
if (N == 0) {
|
||||||
|
buf.data()[0] = '0';
|
||||||
|
} else {
|
||||||
|
for (auto n = N; n; n /= base)
|
||||||
|
*--ptr = digits[(N < 0 ? -1 : 1) * (n % base)];
|
||||||
|
if (N < 0)
|
||||||
|
*--ptr = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <std::size_t L, std::size_t R>
|
||||||
|
constexpr auto operator+(FixedString<L> l, FixedString<R> r) -> FixedString<L + R> {
|
||||||
|
auto result = FixedString<L + R>(concat_op(), l, r);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Takes any expression that returns a FixedString<N> and returns a const char*.
|
||||||
|
#define KSYS_STR(STR) \
|
||||||
|
([]() -> const char* { \
|
||||||
|
using ksys::util::Str; \
|
||||||
|
static constexpr auto x = STR; \
|
||||||
|
return x.data(); \
|
||||||
|
}())
|
||||||
|
|
||||||
|
} // namespace ksys::util
|
Loading…
Reference in New Issue