c++ - Compile-time lookup table for enum -
i have list of enums defined follows:
enum pinenum { kpininvalid, kpina0, kpina1, kpinb0, kpinb1, kpinc0, kpinc1, }
each of these enums needs associated 2 other values, port , pin number. currently, i'm accessing these through run-time functions:
gpio_typedef * pingetport(const pinenum pin) { switch (pin) { case kpina0: case kpina1: return gpioa; case kpinb0: case kpinb1: return gpiob; case kpinc0: case kpinc1: return gpioc; default: return null; } } uint16_t pingetpin(const pinenum pin) { switch (pin) { case kpina0: case kpinb0: case kpinc0: return gpio_pin_0; case kpina1: case kpinb1: case kpinc1: return gpio_pin_1; default: return 0; } }
in particular, i'm doing because not want large lookup table taking ram @ runtime (code size less of issue).
is there way using compile-time lookup table, constexpr
function, or template construct statements pingetpin(kpina0)
, pingetport(kpina0)
each optimized single value instead of having go through lengthy function call , case statement? arguments these functions of type const pinenum
values known @ compile time.
for example, typical usage scenario following:
const pinenum kpinstatus = kpinb0; int main(int argc, char ** argv) { ... pingetport(kpinstatus)->bsrrh = pingetpin(kpinstatus); // gpiob->bsrrh = gpio_pin_0; <-- should optimize during compilation ... }
c++11 answers fine.
while there other answers out there compile-time lookup tables, not see 1 directly apply case. either require string recursion, or calculate , store lookup table (which may end coming if there's no other way).
use template structs taking enum parameter, template specialization, , std::integral_constant
.
#include <type_traits> enum class pin { pin0, pin1 }; template<pin> struct lookup_port; template<pin> struct lookup_num; template<> struct lookup_port<pin::pin0> : std::integral_constant<int, 0> { }; template<> struct lookup_num<pin::pin0> : std::integral_constant<int, 520> { }; template<> struct lookup_port<pin::pin1> : std::integral_constant<int, 22> { }; template<> struct lookup_num<pin::pin1> : std::integral_constant<int, 5440> { }; int main() { static_assert(lookup_port<pin::pin0>::value == 0, ""); static_assert(lookup_port<pin::pin1>::value == 22, ""); static_assert(lookup_num<pin::pin0>::value == 520, ""); static_assert(lookup_num<pin::pin1>::value == 5440, ""); }
in c++14, switch
function constexpr, relaxed constexpr restrictions.
Comments
Post a Comment