title: Compile-time lookup table for enum
body: <p>I have a list of enums which are defined as follows:</p>
  
  <pre><code>enum PinEnum {
      kPinInvalid,
      kPinA0,
      kPinA1,
      kPinB0,
      kPinB1,
      kPinC0,
      kPinC1,
  }
  </code></pre>
  
  <p>Each of these enums needs to be associated with two other values, the port and the pin number.  Currently, I'm accessing these through run-time functions:</p>
  
  <pre><code>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;
      }
  }
  </code></pre>
  
  <p>In particular, I'm doing this because I do not want a large lookup table to be taking up RAM at runtime (code size is much less of an issue).</p>
  
  <p><strong>Is there a way to do this using a compile-time lookup table, <code>constexpr</code> function, or a template construct so that the statements <code>PinGetPin(kPinA0)</code> and <code>PinGetPort(kPinA0)</code> each get optimized to a single value instead of having to go through a lengthy function call and case statement?  The arguments to these functions will always be of type <code>const PinEnum</code> with values known at compile time.</strong></p>
  
  <p>For example, a typical usage scenario is the following:</p>
  
  <pre><code>const PinEnum kPinStatus = kPinB0;
  
  int main(int argc, char ** argv) {
      ...
      PinGetPort(kPinStatus)-&gt;BSRRH = PinGetPin(kPinStatus);
      // GPIOB-&gt;BSRRH = GPIO_Pin_0; &lt;-- should optimize to this during compilation
      ...
  }
  </code></pre>
  
  <p>C++11 answers are fine.</p>
  
  <p>While there are other answers out there for compile-time lookup tables, I do not see one which would directly apply to this case.  They either require string recursion, or actually calculate and store a lookup table (which this may end up coming to if there's no other way).</p>