Skip to content

Instantly share code, notes, and snippets.

@apaszke
Last active September 8, 2017 17:42
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 apaszke/8015289f5da222c76ebd9d6ba79f34de to your computer and use it in GitHub Desktop.
Save apaszke/8015289f5da222c76ebd9d6ba79f34de to your computer and use it in GitHub Desktop.
////////////////////////////////////////////////////////////////////////////////
// Writing a string comparison that would consistently work as a compile time
// function, even in older compilers (think GCC 4.8) is not that easy...
////////////////////////////////////////////////////////////////////////////////
template<std::size_t N>
constexpr bool fixed_equal(char const * a, char const * b) {
return *a == *b && fixed_equal<N-1>(a + 1, b + 1);
}
template<>
constexpr bool fixed_equal<0>(char const * a, char const * b) {
return true;
}
template<std::size_t N, std::size_t M>
constexpr bool strings_equal(const char(&a)[N], const char(&b)[M]) {
return N == M && fixed_equal<N>(a, b);
}
////////////////////////////////////////////////////////////////////////////////
// This is the important part
////////////////////////////////////////////////////////////////////////////////
int strToSymbol(const char * a);
// List all builtin symbols here
#define FORALL_BUILTIN_SYMBOLS(_) \
_(A) \
_(B)
// NOTE: BuiltinSymbols::fistFreeId can be used to get the lowest ID
// which can be assigned to a string interned at run time.
#define DEFINE_SYMBOL(s) s,
enum class BuiltinSymbols : int {
FORALL_BUILTIN_SYMBOLS(DEFINE_SYMBOL)
firstFreeId
};
#undef DEFINE_SYMBOL
template<std::size_t N>
constexpr int _(const char (&a)[N]) {
#define DEFINE_CASE(s) strings_equal(a, #s) ? static_cast<int>(BuiltinSymbols::s) :
return FORALL_BUILTIN_SYMBOLS(DEFINE_CASE) (strToSymbol(a));
#undef DEFINE_CASE
}
int main() {
return _("A");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment