Skip to content

Commit

Permalink
[NEW] Add support for custom scalar types. (Quentin ARNAULT)
Browse files Browse the repository at this point in the history
  • Loading branch information
rentzsch committed Jun 26, 2014
1 parent 67f9860 commit 802305f
Show file tree
Hide file tree
Showing 13 changed files with 723 additions and 3 deletions.
49 changes: 49 additions & 0 deletions test/Gender.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#import <Foundation/Foundation.h>
#import "JREnum/JREnum.h"

// Mostly stolen from http://abcnews.go.com/blogs/headlines/2014/02/heres-a-list-of-58-gender-options-for-facebook-users/

JREnumDeclare(
Gender,
Gender_Undefined,
Gender_Female,
Gender_Male,
Gender_Other,
Gender_Agender,
Gender_Androgyne,
Gender_Androgynous,
Gender_Bigender,
Gender_Cisgender,
Gender_CisgenderFemale,
Gender_CisgenderMale,
Gender_FemaleToMale,
Gender_GenderFluid,
Gender_GenderNonconforming,
Gender_GenderQuestioning,
Gender_GenderVariant,
Gender_Genderqueer,
Gender_Intersex,
Gender_MaleToFemale,
Gender_Neither,
Gender_Neutrois,
Gender_Nonbinary,
Gender_Pangender,
Gender_Trans,
Gender_TransStar,
Gender_TransFemale,
Gender_TransStarFemale,
Gender_TransMale,
Gender_TransStarMale,
Gender_TransPerson,
Gender_TransStarPerson,
Gender_Transfeminine,
Gender_Transgender,
Gender_TransgenderFemale,
Gender_TransgenderMale,
Gender_TransgenderPerson,
Gender_Transmasculine,
Gender_Transsexual,
Gender_TranssexualFemale,
Gender_TranssexualMale,
Gender_TranssexualPerson,
);
3 changes: 3 additions & 0 deletions test/Gender.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#import "Gender.h"

JREnumDefine(Gender);
109 changes: 109 additions & 0 deletions test/JREnum/JREnum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// JREnum.h semver:1.1
// Original implementation by Benedict Cohen: http://benedictcohen.co.uk
// Copyright (c) 2012-2014 Jonathan 'Wolf' Rentzsch: http://rentzsch.com
// Some rights reserved: http://opensource.org/licenses/mit
// https://github.com/rentzsch/JREnum

#define JREnum(ENUM_TYPENAME, ENUM_CONSTANTS...) \
typedef enum { \
ENUM_CONSTANTS \
} ENUM_TYPENAME; \
static NSString *_##ENUM_TYPENAME##_constants_string = @"" #ENUM_CONSTANTS; \
_JREnum_GenerateImplementation(ENUM_TYPENAME)

//--

#define JREnumDeclare(ENUM_TYPENAME, ENUM_CONSTANTS...) \
typedef enum { \
ENUM_CONSTANTS \
} ENUM_TYPENAME; \
extern NSDictionary* ENUM_TYPENAME##ByValue(); \
extern NSDictionary* ENUM_TYPENAME##ByLabel(); \
extern NSString* ENUM_TYPENAME##ToString(int enumValue); \
extern BOOL ENUM_TYPENAME##FromString(NSString *enumLabel, ENUM_TYPENAME *enumValue); \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wunused-variable\"") \
static NSString *_##ENUM_TYPENAME##_constants_string = @"" #ENUM_CONSTANTS; \
_Pragma("clang diagnostic pop")

//--

#define JREnumDefine(ENUM_TYPENAME) \
_JREnum_GenerateImplementation(ENUM_TYPENAME)

//--

#define _JREnum_GenerateImplementation(ENUM_TYPENAME) \
NSArray* _JREnumParse##ENUM_TYPENAME##ConstantsString() { \
NSString *constantsString = _##ENUM_TYPENAME##_constants_string; \
constantsString = [[constantsString componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] componentsJoinedByString:@""]; \
if ([constantsString hasSuffix:@","]) { \
constantsString = [constantsString substringToIndex:[constantsString length]-1]; \
} \
NSArray *stringPairs = [constantsString componentsSeparatedByString:@","]; \
NSMutableArray *labelsAndValues = [NSMutableArray arrayWithCapacity:[stringPairs count]]; \
int nextDefaultValue = 0; \
for (NSString *stringPair in stringPairs) { \
NSArray *labelAndValueString = [stringPair componentsSeparatedByString:@"="]; \
NSString *label = [labelAndValueString objectAtIndex:0]; \
NSString *valueString = [labelAndValueString count] > 1 ? [labelAndValueString objectAtIndex:1] : nil; \
int value; \
if (valueString) { \
NSRange shiftTokenRange = [valueString rangeOfString:@"<<"]; \
if (shiftTokenRange.location != NSNotFound) { \
valueString = [valueString substringFromIndex:shiftTokenRange.location + 2]; \
value = 1 << [valueString intValue]; \
} else if ([valueString hasPrefix:@"0x"]) { \
[[NSScanner scannerWithString:valueString] scanHexInt:(unsigned int*)&value]; \
} else { \
value = [valueString intValue]; \
} \
} else { \
value = nextDefaultValue; \
} \
nextDefaultValue = value + 1; \
[labelsAndValues addObject:label]; \
[labelsAndValues addObject:[NSNumber numberWithInt:value]]; \
} \
return labelsAndValues; \
} \
\
NSDictionary* ENUM_TYPENAME##ByValue() { \
NSArray *constants = _JREnumParse##ENUM_TYPENAME##ConstantsString(); \
NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity:[constants count] / 2]; \
for (NSUInteger i = 0; i < [constants count]; i += 2) { \
NSString *label = [constants objectAtIndex:i]; \
NSNumber *value = [constants objectAtIndex:i+1]; \
[result setObject:label forKey:value]; \
} \
return result; \
} \
\
NSDictionary* ENUM_TYPENAME##ByLabel() { \
NSArray *constants = _JREnumParse##ENUM_TYPENAME##ConstantsString(); \
NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity:[constants count] / 2]; \
for (NSUInteger i = 0; i < [constants count]; i += 2) { \
NSString *label = [constants objectAtIndex:i]; \
NSNumber *value = [constants objectAtIndex:i+1]; \
[result setObject:value forKey:label]; \
} \
return result; \
} \
\
NSString* ENUM_TYPENAME##ToString(int enumValue) { \
NSString *result = [ENUM_TYPENAME##ByValue() objectForKey:[NSNumber numberWithInt:enumValue]]; \
if (!result) { \
result = [NSString stringWithFormat:@"<unknown "#ENUM_TYPENAME": %d>", enumValue]; \
} \
return result; \
} \
\
BOOL ENUM_TYPENAME##FromString(NSString *enumLabel, ENUM_TYPENAME *enumValue) { \
NSNumber *value = [ENUM_TYPENAME##ByLabel() objectForKey:enumLabel]; \
if (value) { \
*enumValue = (ENUM_TYPENAME)[value intValue]; \
return YES; \
} else { \
return NO; \
} \
}
Loading

0 comments on commit 802305f

Please sign in to comment.