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

Popular posts from this blog

javascript - Chart.js (Radar Chart) different scaleLineColor for each scaleLine -

apache - Error with PHP mail(): Multiple or malformed newlines found in additional_header -

java - Android – MapFragment overlay button shadow, just like MyLocation button -