Skip to content

Instantly share code, notes, and snippets.

@HookedBehemoth
Created July 16, 2023 20:52
Show Gist options
  • Save HookedBehemoth/8b3946c8198c2b226a9df49a06cc4ae0 to your computer and use it in GitHub Desktop.
Save HookedBehemoth/8b3946c8198c2b226a9df49a06cc4ae0 to your computer and use it in GitHub Desktop.
constexpr translations
{"playlist", "Playlist"},
{"music_browser", "Music browser"},
{"close", "Close sys-tune"}
#include <cstddef>
#include <string_view>
#include <array>
#include <tuple>
using RawTranslation = std::array<std::tuple<std::string_view, std::string_view>, 3>;
using TranslationArray = std::array<std::string_view, 3>;
consteval
TranslationArray build_translation_indices(const RawTranslation &raw) {
TranslationArray out;
size_t idx = 0;
for (auto &[key, value] : raw) {
out[idx++] = key;
}
return out;
}
constexpr
TranslationArray TranslationLookupStrings = build_translation_indices({{
#include "english.hpp"
}});
static const TranslationArray *s_translation = &TranslationLookupStrings;
struct Lang {
unsigned int index;
std::string_view operator()() {
return (*s_translation)[index];
}
};
consteval
int translation_index_of(std::string_view str) {
int idx = 0;
while (str != TranslationLookupStrings[idx]) {
++idx;
if (idx == TranslationLookupStrings.size()) {
throw;
}
}
return idx;
}
consteval
Lang operator ""_lang(const char* str, size_t len) {
return Lang {
(unsigned)translation_index_of({ str, len })
};
}
consteval
TranslationArray build_translation(const RawTranslation &raw) {
TranslationArray out;
for (auto &[key, value] : raw) {
auto idx = translation_index_of(key);
out[idx] = value;
}
return out;
}
constexpr TranslationArray German = build_translation({{
#include "german.hpp"
}});
constexpr TranslationArray English = build_translation({{
#include "english.hpp"
}});
std::string_view return_translated() {
return "playlist"_lang();
}
#include <iostream>
void init_translation(int idx) {
switch (idx) {
case 1:
s_translation = &German;
break;
default:
s_translation = &English;
break;
}
}
int main(int argc, char *argv[]) {
init_translation(argc);
std::cout << return_translated() << std::endl;
// Fails to compile
// std::cout << "hex.builtin.command.web.desc"_lang() << std::endl;
}
#include <cstddef>
#include <string>
#include <vector>
static std::vector<std::string> s_translation;
struct Lang {
unsigned int index;
std::string &operator()() {
return s_translation[index];
}
};
#include <array>
constexpr
std::array lookup_strings {
"hex.builtin.command.calc.desc",
"hex.builtin.command.cmd.desc",
"hex.builtin.command.cmd.result",
};
#include <cstring>
constexpr
int lang_index_of(const char* str) {
int idx = 0;
while (std::strcmp(str, lookup_strings[idx]) != 0) {
++idx;
if (idx == lookup_strings.size()) {
return -1;
}
}
return idx;
}
consteval
Lang operator ""_lang(const char* str, size_t) {
auto idx = lang_index_of(str);
if (idx < 0) {
throw;
}
return Lang {
(unsigned)idx
};
}
const char* English = R"foo(
{
"code": "en-US",
"language": "English",
"country": "United States",
"fallback": true,
"translations": {
"hex.builtin.command.calc.desc": "Calculator",
"hex.builtin.command.cmd.desc": "Command",
"hex.builtin.command.cmd.result": "Run command '{0}'",
"hex.builtin.command.web.desc": "Website lookup"
}
}
)foo";
#include <nlohmann/json.hpp>
void init_translation() {
s_translation = std::vector<std::string>(lookup_strings.size());
auto json = nlohmann::json::parse(English);
auto translations = json["translations"];
for (auto &[key, value] : translations.items()) {
if (!value.is_string()) {
throw;
}
auto idx = lang_index_of(key.c_str());
if (idx < 0) {
continue;
}
s_translation[idx] = value.get<std::string>();
}
}
std::string &return_translated() {
return "hex.builtin.command.calc.desc"_lang();
}
#include <iostream>
int main() {
std::cout << English;
init_translation();
std::cout << return_translated() << std::endl;
// Fails to compile
// std::cout << "hex.builtin.command.web.desc"_lang() << std::endl;
}
{"playlist", "Wiedergabeliste"},
{"music_browser", "Dateisuche"},
{"close", "Beenden"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment