I have a list of enums which are defined as follows:
enum PinEnum {
kPinInvalid,
kPinA0,
kPinA1,
kPinB0,
kPinB1,
kPinC0,
kPinC1,
}
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:
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 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).
Is there a way to do this using a compile-time lookup table, constexpr
function, or a template construct so that the statements PinGetPin(kPinA0)
and PinGetPort(kPinA0)
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 const PinEnum
with values known at compile time.
For example, a typical usage scenario is the following:
const PinEnum kPinStatus = kPinB0;
int main(int argc, char ** argv) {
...
PinGetPort(kPinStatus)->BSRRH = PinGetPin(kPinStatus);
// GPIOB->BSRRH = GPIO_Pin_0; <-- should optimize to this during compilation
...
}
C++11 answers are fine.
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).
Aucun commentaire:
Enregistrer un commentaire