Created
July 12, 2012 14:06
-
-
Save hezi/3098340 to your computer and use it in GitHub Desktop.
Objective-C Enum-TO-NSString and Vice versa.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Declare enums like so: | |
#define IMAGE_STATUS(XX) \ | |
XX(kDOImageStatusOK, = 0) \ | |
XX(kDOImageStatusCached, )\ | |
XX(kDOImageStatusRetry, ) | |
DECLARE_ENUM(DOImageStatus, IMAGE_STATUS) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Define Enum-To-NSString functions like so: | |
DEFINE_ENUM(DOImageStatus, IMAGE_STATUS) | |
// use them like this: | |
NSString *imageStatus = NSStringFromDOImageStatus(kDOImageStatusOK); | |
DOImageStatus statusFromString = DOImageStatusFromNSString(@"kDOImageStatusCached"); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Based on http://stackoverflow.com/a/202511 | |
// | |
#pragma mark - Enum Factory Macros | |
// expansion macro for enum value definition | |
#define ENUM_VALUE(name,assign) name assign, | |
// expansion macro for enum to string conversion | |
#define ENUM_CASE(name,assign) case name: return @#name; | |
// expansion macro for string to enum conversion | |
#define ENUM_STRCMP(name,assign) if (![string isEqualToString:@#name]) return name; | |
/// declare the access function and define enum values | |
#define DECLARE_ENUM(EnumType,ENUM_DEF) \ | |
typedef enum EnumType { \ | |
ENUM_DEF(ENUM_VALUE) \ | |
}EnumType; \ | |
NSString *NSStringFrom##EnumType(EnumType value); \ | |
EnumType EnumType##FromNSString(NSString *string); \ | |
// Define Functions | |
#define DEFINE_ENUM(EnumType, ENUM_DEF) \ | |
NSString *NSStringFrom##EnumType(EnumType value) \ | |
{ \ | |
switch(value) \ | |
{ \ | |
ENUM_DEF(ENUM_CASE) \ | |
default: return @""; \ | |
} \ | |
} \ | |
EnumType EnumType##FromNSString(NSString *string) \ | |
{ \ | |
ENUM_DEF(ENUM_STRCMP) \ | |
return (EnumType)0; \ | |
} |
hmm.. I was disappointed how github left-justified all my lines of code.
I suggest they improve this as it's common for people to supply code in the replies...
@fredwork you can format your code by putting triple backticks before and after it: https://help.github.com/articles/github-flavored-markdown/#fenced-code-blocks
(The Objective-C language specifier is objc
)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I like the macro approach.
Yet, it can be tricky to debug code generated with macros.
Alternatively, you can generate a table for the conversion.
You can extend the idea of have any arbitrary information per enum.
// enum to string example
define FOR_EACH_GENDER(tbd) \
define ONE_GENDER_ENUM(name) name,
enum
{
FOR_EACH_GENDER(ONE_GENDER_ENUM)
MAX_GENDER
};
define ONE_GENDER(name) #name,
static const char *enumGENDER_TO_STRING[] =
{
FOR_EACH_GENDER(ONE_GENDER)
};
// access string name with enumGENDER_TO_STRING[value]
// or, to be safe converting from a untrustworthy caller
static const char *enumGenderToString(unsigned int value)
{
if (value < MAX_GENDER)
{
return enumGENDER_TO_STRING[value];
}
return NULL;
}
static void printAllGenders(void)
{
for (int ii = 0; ii < MAX_GENDER; ii++)
{
printf("%d) gender %s\n", ii, enumGENDER_TO_STRING[ii]);
}
}
//------------------------------------------------------------------------------
// you can assign an arbitrary value and/or information to each enum,
define FOR_EACH_PERSON(tbd) \
define ONE_PERSON_ENUM(value, ename, first, last, gender, age) ename = value,
enum
{
FOR_EACH_PERSON(ONE_PERSON_ENUM)
};
typedef struct PersonInfoRec
{
int value;
const char *ename;
const char *first;
const char *last;
int gender;
int age;
} PersonInfo;
define ONE_PERSON_INFO(value, ename, first, last, gender, age) \
static const PersonInfo personInfo[] =
{
FOR_EACH_PERSON(ONE_PERSON_INFO)
{ 0, NULL, NULL, NULL, 0, 0 }
};
// note: if the enum values are not sequential, you need another way to lookup
// the information besides personInfo[ENUM_NAME]
static void printAllPersons(void)
{
for (int ii = 0; ; ii++)
{
const PersonInfo *pPI = &personInfo[ii];
if (!pPI->ename)
{
break;
}
printf("%d) enum %-15s %8s %-8s %13s %2d\n",
pPI->value, pPI->ename, pPI->first, pPI->last,
enumGenderToString(pPI->gender), pPI->age);
}
}