Reputation: 666
I have an enum
defined in plain c like so:
typedef enum {
// Determine position of Red and Green color:
// RED[2:0], GREEN[5:3], BLUE implicitly. Thus, [7:6]==!0
LED_BO_RedGreenBlue=0b00010001,
LED_BO_RedBlueGreen=0b00100001,
LED_BO_GreenBlueRed=0b00001100,
LED_BO_GreenRedBlue=0b00001010,
LED_BO_BlueRedGreen=0b00100010,
LED_BO_BlueGreenRed=0b00010100,
} led_byteorder_values_t;
Unfortuantely, the only way I have come up with to check if a given uint8_t
has a value defined explicitly in this enum is this:
uint8_t byteToTest = 0; // has invalid value, so /default/ path will be taken.
switch (byteToTest) {
case: LED_BO_RedGreenBlue: break;
case: LED_BO_RedBlueGreen: break;
case: LED_BO_GreenBlueRed: break;
case: LED_BO_GreenRedBlue: break;
case: LED_BO_BlueRedGreen: break;
case: LED_BO_BlueGreenRed: break;
default: byteToTest = LED_BO_RedGreenBlue; break;
}
Is there a better / shorter way to test a variable against arbitrary values, possibly without having to define an additional const [...]
?
Upvotes: 4
Views: 1005
Reputation: 66234
Though the attractiveness of the following alternative isn't heartwarming, it is none-the-less likely effective for the platform you're currently using.
The language doesn't support enumeration of enum
values as a built-in construct. There are ways to "fake" it though. Once such way is by providing your own table-of-enum, then enumerating that. I will argue, however, whether this is "better". Easier to type, yes. Logical, maybe. but your switch statement is most-assuredly going to compile down to more efficient code. I would be shocked if it didn't.
typedef enum {
// Determine position of Red and Green color:
// RED[2:0], GREEN[5:3], BLUE implicitly. Thus, [7:6]==!0
LED_BO_RedGreenBlue=0b00010001,
LED_BO_RedBlueGreen=0b00100001,
LED_BO_GreenBlueRed=0b00001100,
LED_BO_GreenRedBlue=0b00001010,
LED_BO_BlueRedGreen=0b00100010,
LED_BO_BlueGreenRed=0b00010100,
} led_byteorder_values_t;
static const led_byteorder_values_t led_byteorder_values[] =
{
LED_BO_RedGreenBlue,
LED_BO_RedBlueGreen,
LED_BO_GreenBlueRed,
LED_BO_GreenRedBlue,
LED_BO_BlueRedGreen,
LED_BO_BlueGreenRed
};
static const size_t size_led_byteorder_values =
sizeof(led_byteorder_values)/sizeof(*led_byteorder_values);
With that you can enumerate the values directly via a [0...size_led_byteorder_values)
loop. you can still custom-order the loop by adjusting the table entry order for most-to-least-likely hit for quicker loop-exit. But again, it isn't like that isn't possible with a decently formed switch such as yours.
Anyway, its a thought, and I feel your pain. Its one of the few features that not-just-C++, but most languages don't offer, and it certainly seems to pop up as useful once in awhile.
Best of luck.
Upvotes: 4
Reputation: 17595
You may define enum like below.
typedef enum : uint8_t { // see this type, it's a better defintion
// Determine position of Red and Green color:
// RED[2:0], GREEN[5:3], BLUE implicitly. Thus, [7:6]==!0
LED_BO_RedGreenBlue=0b00010001,
........
} led_byteorder_values_t;
Upvotes: 0