Skip to content

Instantly share code, notes, and snippets.

@derrickturk
Last active February 6, 2024 22:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save derrickturk/51c68fb15cbf82211dc4c812832487b3 to your computer and use it in GitHub Desktop.
Save derrickturk/51c68fb15cbf82211dc4c812832487b3 to your computer and use it in GitHub Desktop.
In his house at R'lyeh, dead Cthulhu waits dreaming
#include <cstddef>
#include <cstdio>
#include <utility>
constexpr std::size_t num_digits(unsigned char n) noexcept
{
if (n < 10)
return 1;
if (n < 100)
return 2;
return 3;
}
template<std::size_t N>
struct symbol {
char Name[N];
constexpr symbol() = default;
constexpr symbol(const char (&str) [N]) noexcept
{
for (std::size_t i = 0; i < N; ++i)
Name[i] = str[i];
}
constexpr symbol(unsigned char value) noexcept
{
std::size_t i;
auto ndigits = num_digits(value);
for (i = 0; i < ndigits && i < N - 1; ++i) {
unsigned char digit;
if ((digit = value / 100)) {
Name[i] = digit + '0';
value %= 100;
} else if ((digit = value / 10)) {
Name[i] = digit + '0';
value %= 10;
} else {
Name[i] = value + '0';
}
}
Name[i] = '\0';
}
template<std::size_t M>
constexpr symbol<N + M - 1> operator+(const symbol<M>& other) const noexcept
{
symbol<N + M - 1> concat;
for (std::size_t i = 0; i < N - 1; ++i)
concat.Name[i] = Name[i];
for (std::size_t i = 0; i < M; ++i)
concat.Name[N + i - 1] = other.Name[i];
return concat;
}
static const size_t Length;
};
template<std::size_t N>
const size_t symbol<N>::Length = N;
template<auto Sym>
struct StaticSymbol {
static constexpr decltype(Sym) Symbol = Sym;
};
template<symbol... Syms>
const char* symbols[sizeof...(Syms)] = {
StaticSymbol<Syms>::Symbol.Name...,
};
template<unsigned char N>
using NumSymbolType = symbol<num_digits(N) + 1>;
template<unsigned char N>
constexpr NumSymbolType<N> NumSymbol = N;
template<typename T, auto Prefix, auto... Rest>
const char* symbols_for_seq[T::size() + sizeof...(Rest)];
template<unsigned char... Ns, auto Prefix, auto... Rest>
const char* symbols_for_seq<
std::integer_sequence<unsigned char, Ns...>,
Prefix,
Rest...
>[sizeof...(Ns) + sizeof...(Rest)] = {
StaticSymbol<Prefix + NumSymbol<Ns + 1>>::Symbol.Name...,
StaticSymbol<Rest>::Symbol.Name...,
};
template<unsigned char N, auto Prefix, auto... Rest>
const char* (&symbols_up_to)[N + sizeof...(Rest)] =
symbols_for_seq<std::make_integer_sequence<unsigned char, N>, Prefix, Rest...>;
const std::size_t num_buttons = 128;
const std::size_t total_buttons = num_buttons + 4;
const char* (&english)[total_buttons] = symbols_up_to<
num_buttons,
symbol("Button "),
symbol("Hat Up"),
symbol("Hat Down"),
symbol("Hat Left"),
symbol("Hat Right")
>;
const char* (&german)[total_buttons] = symbols_up_to<
num_buttons,
symbol("Knopf "),
symbol("Hut Hinten"),
symbol("Hut Vorne"),
symbol("Hut Links"),
symbol("Hut Rechts")
>;
int main()
{
for (const auto& e: english)
puts(e);
for (const auto& g: german)
puts(g);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment