Skip to content

Instantly share code, notes, and snippets.

@insooth
Created January 10, 2020 14:09
Show Gist options
  • Save insooth/97e5b825aa78773983b97ca4053ce8dd to your computer and use it in GitHub Desktop.
Save insooth/97e5b825aa78773983b97ca4053ce8dd to your computer and use it in GitHub Desktop.
Use of prefix tree instead of a unordered map for a given string to enum mapping
// see LICENSE on insooth.github.com
#include <iostream>
#include <cassert>
#include <cstring> // strlen
#include <unordered_map>
// unordered_map<string, enum> -> prefix tree
enum class E { a, b, c, unknown };
// prefix tree
constexpr E match(const char* const s)
{
assert(nullptr != s);
E e = E::unknown;
assert(std::strlen(s) > 0);
switch (s[0])
{
case 'A':
{
assert(std::strlen(s) > 1);
switch (s[1])
{
case '1': { e = E::a; break; }
case '2': { e = E::b; break; }
case '3': { e = E::c; break; }
// or
// [[fallthrough]]
// E abc[] = { E::a, E::b, E::c };
// e = abc[ord(s[1]) - 1);
default: assert( ! "ILLEGAL_PATH");
};
break;
}
default: assert( ! "ILLEGAL_PATH");
};
return e;
}
int main()
{
// memory allocation, hashing performance, can degrade to linear search, runtime
std::unordered_map<std::string, E> m = { { "A1", E::a }, { "A2", E::b }, { "A3", E::c } };
assert(E::a == m.find("A1")->second);
assert(E::b == m.find("A2")->second);
assert(E::c == m.find("A3")->second);
// no allocation, O(1), integral comparison, constexpr
assert(E::a == match("A1"));
assert(E::b == match("A2"));
assert(E::c == match("A3"));
return 0;
}
/*
http://coliru.stacked-crooked.com/a/05c7ba9e2383f519
g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment