Задача сделать констаный асоциативный массив строка -> число для С++. Т.е. после создания он изменяться не будет.
Далее
using обьект = "констаный асоциативный массив строка -> число";
Условия:
- Обьект создается только один раз
- Можно чтоб обьект был инициализирован до вызова main
- Ключи (строки) и значения (числа) известны уже на этапе компиляции и не изменяются с этого момента.
- Ключи как и значения уникальны (т.е. значения не повторяются, а одному ключу соответствует только одно значение)
- На 90% ключей состоят ровно из 3 символов: большие буквы A-Z и/или цифры 0-9. Остальные 10% ключей не превышают в длинне 15 символов (однако могут иметь также и маленькие буквы a-z).
- Ключи можно вычислять из строки, главное чтоб выполнялось:
f(x) != f(y) для (x != y), (x, y) на всем множестве ключей f(x) == f(x) для x на всем множестве ключей
- Приоритетом является быстрый доступ к значению по точному ключу
- Требуется механизм проверки присутствует ли ключ (т.е. входные данные не всегда валидны)
- Необходима возможность добавления новых пар ключ-значение в последующих компиляциях (ну, чтоб по крайней мере это не было адски сложно)
- Стандарт C++14 (и можно использовать фичи из C++17)
Желательно (но не обязательно):
- Сборка обьекта в compile-time (напр. constexpr)
- Возможность итерации по всем ключам обьекта
- Чтоб значения не были слишком сильно разбросаны
Чем можно пренебречь:
- Размером конечного обьекта (может быть ну очень большим)
- Временем компиляции (т.е. может быть адская шаблоно-лапша, главное чтоб соответствовало условиям выше)
Сейчас, чтоб сильно не заморачиватся, используется
using namespace std::string_view_literals;
const std::unordered_map<std::string_view, int> map{
{ "key"sv, 42 },
// ...
};
Однако появилось время покопаться, по этому прошу подсказать, как можно улучшить?
Т.е. было бы прикольно даже иметь хеш-функцию f(str) -> int
которая бы гарантировала отсутствие коллизий и не слишком разбросанные значения.