-
-
Save dsaltares/8904478 to your computer and use it in GitHub Desktop.
#ifndef __SMARTENUM_H__ | |
#define __SMARTENUM_H__ | |
#include <cstring> | |
#define SMARTENUM_VALUE(typeName, value) e##typeName##_##value, | |
#define SMARTENUM_STRING(typeName, value) #value, | |
#define SMARTENUM_DEFINE_ENUM(typeName, values) enum typeName { values(SMARTENUM_VALUE) e##typeName##_Count, }; | |
#define SMARTENUM_DEFINE_NAMES(typeName, values) const char* typeName##Array [] = { values(SMARTENUM_STRING) }; | |
#define SMARTENUM_DEFINE_GET_VALUE_FROM_STRING(typeName, name) \ | |
typeName get##typeName##FromString(const char* str) \ | |
{ \ | |
for (int i = 0; i < e##typeName##_Count; ++i) \ | |
if (!strcmp(##typeName##Array[i], str)) \ | |
return (##typeName##)i; \ | |
return e##typeName##_Count; \ | |
} | |
#define getStringFromEnumValue(typeName, value) typeName##Array[##value] | |
#define getEnumValueFromString(typeName, name) get##typeName##FromString(##name) | |
#endif // __SMARTENUM_H__ |
@dsaltares, sorry, what is this supposed to mean: values(SMARTENUM_VALUE)
?
The values
is a macro argument. So, supposedly, you call the macro like this:
SMARTENUM_DEFINE_NAMES(animals, cat dog mouse cow);
Then with g++ -E
you, unsurprisingly, get this:
const char* animalsArray [] = { cat dog mouse cow(SMARTENUM_STRING) };;
which of course doesn't compile because it is syntactically incorrect and contains undefined symbols.
Thank you for sharing this code. Could you help me, I tried to compile this code but I have an error. The error is .
#include
#include
#include
#define SMARTENUM_VALUE(typeName, value) e##typeName##_##value,
#define SMARTENUM_STRING(typeName, value) #value,
#define SMARTENUM_DEFINE_ENUM(typeName, values) enum typeName { values(SMARTENUM_VALUE) e##typeName##_Count };
#define SMARTENUM_DEFINE_NAMES(typeName, values) const char* typeName##Array [] = { values(SMARTENUM_STRING) };
#define SMARTENUM_DEFINE_GET_VALUE_FROM_STRING(typeName, name)
typeName get##typeName##FromString(const char* str)
{
for (int i = 0; i < e##typeName##_Count; ++i) {
if (!strcmp(##typeName##Array[i], str)) {
return (##typeName##)i; }
return e##typeName##_Count; }
}
#define getStringFromEnumValue(typeName, value) typeName##Array[##value]
#define getEnumValueFromString(typeName, name) get##typeName##FromString(##name)
#define ANIMAL_LIST(m)
m(Animal, Dog)
m(Animal, Cat)
m(Animal, Cow)
#define CAR_LIST(m)
m(Car, Fiat)
m(Car, Ford)
m(Car, Audi)
int main()
{
SMARTENUM_DEFINE_ENUM(Animal, ANIMAL_LIST);
SMARTENUM_DEFINE_NAMES(Animal, ANIMAL_LIST);
const char* animalName = getStringFromEnumValue(Animal, eAnimal_Cow);
std::cout << animalName << std::endl;
SMARTENUM_DEFINE_GET_VALUE_FROM_STRING(Animal, animalName);//error here Error (active) ';' waited
Animal animal = getEnumValueFromString(Animal, animalName);
system("pause");
return 0;
}
This is quite clever, but it appears that pasting something which is not a valid preprocessor token results in undefined behavior. In particular, I can't get gcc to compile this.
Here's some discussion:
http://stackoverflow.com/questions/1206624/differences-in-macro-concatenation-operator-between-visual-c-and-gcc