Skip to content

Instantly share code, notes, and snippets.

@joshuashaffer
Created October 1, 2023 19:08
Show Gist options
  • Save joshuashaffer/9402d63e7e74642e963a1e1c2dfbaca5 to your computer and use it in GitHub Desktop.
Save joshuashaffer/9402d63e7e74642e963a1e1c2dfbaca5 to your computer and use it in GitHub Desktop.
constexpr enum constants from string constants at compile time
/***
* @brief Convert a string literal to a compile-time integer constant.
* @tparam IntT The integer type to return.
* @tparam CharT The character type of the string literal.
* @tparam NameLength The length of the string literal.
* @tparam NameIndex The current index of the string literal.
* @tparam TBytes The number of bytes in the integer type.
* @param name The string literal to convert.
* @return The integer constant.
*/
template<typename IntT, typename CharT, int NameLength, int NameIndex = 0>
requires std::integral<IntT>
constexpr IntT to_int_constant(const CharT(&name)[NameLength]) noexcept {
constexpr int n_bytes = sizeof(IntT);
if constexpr (NameIndex >= NameLength || NameIndex >= n_bytes) {
return 0;
} else {
auto c = static_cast<IntT>(static_cast<unsigned char>(name[NameIndex]));
return (c << (8 * sizeof(CharT) * (std::min(NameLength,n_bytes) - NameIndex - 1))) |
to_int_constant<IntT, CharT, NameLength, NameIndex + 1>(name);
}
}
/**
* @brief Convert a string literal to a compile-time uint64_t constant.
* @tparam NameLength the length of the string literal.
* @tparam CharT the character type of the string literal.
* @param s the string literal to convert.
* @return the integer constant.
*/
template<int NameLength, typename CharT>
constexpr uint64_t to_uint64(const CharT (&s)[NameLength]) noexcept {
return to_int_constant<uint64_t>(s);
}
enum class Ok : uint64_t {
ABCD = to_uint64("ABCD"),
DEADBEEF = to_uint64("DEADBEEF"),
VERY_LONG_CONSTANT_FOR_INFORMATION = to_uint64("very long constant for information")
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment