macros that automate vending an NSString given an enum value (f.x. MyEnumToString(value))
Objective-C
Latest commit 1d17c69 Mar 25, 2014 @rentzsch [DOC] Typo.
Permalink
Failed to load latest commit information.
JREnumTest
JREnum.h
README.md

README.md

JREnum

Original idea and implementation by Benedict Cohen.

JREnum is a macro that automates creation of functions that blast enums from boring primitive compile-time-land to the fun-filled party environment of runtime.

Let's use a concrete example. Instead of writing:

typedef enum {
    Stream_Disconnected,
    Stream_Connecting,
    Stream_Connected,
    Stream_Disconnecting
}   StreamState;

write:

JREnum(StreamState,
       Stream_Disconnected,
       Stream_Connecting,
       Stream_Connected,
       Stream_Disconnecting);

This will generate the previous typedef enum and will also generate a corresponding suite of functions:

NSString* StreamStateToString(int value)

Given a value, will return the enum's string representation. For example StreamStateToString(2) would return @"Stream_Connected".

When confronted with values not defined in the enumeration, this function will return a placeholder string explaining the situation. For example StreamStateToString(2000) would return @"<unknown StreamState: 2000>".

BOOL StreamStateFromString(NSString *enumLabel, StreamState *enumValue)

Attempts to return the enum's int value given its label. For example StreamStateFromString(@"Stream_Disconnecting", &value) would return YES and set value to 3.

This function returns NO if the label for the enum type is unknown. For example StreamStateFromString(@"lackadaisical", &value) would return NO and leave value untouched.

NSDictionary* StreamStateByValue()

Returns a dictionary whose keys are the enum's values. Used by StreamStateToString().

When enums have multiple overlapping values, the current implementation exhibits last-write-wins behavior.

NSDictionary* StreamStateByLabel()

Returns a dictionary whose keys are the enum's labels. Used by StreamStateFromString(). This is the function you want if you wish to enumerate an enum's labels and values at runtime.

Split Header / Source Files

JREnum() is fine for when you have an enum that lives solely in an .m file. But if you're exposing an enum in a header file, you'll have to use the alternate macros. In your .h, use JREnumDeclare():

JREnumDeclare(StreamState,
              Stream_Disconnected,
              Stream_Connecting,
              Stream_Connected,
              Stream_Disconnecting);

And then use JREnumDefine() in your .m:

JREnumDefine(StreamState);

Explicit Values

You can also explicitly define enum integer values:

JREnum(StreamState,
       Stream_Disconnected = 42,
       Stream_Connecting,
       Stream_Connected,
       Stream_Disconnecting);

In the above scenario, Stream_Disconnected's value will be 42, Stream_Connecting's will be 43 and so on.

You can also use hex values:

JREnum(StreamState,
       Stream_Disconnected = 0x2A,
       Stream_Connecting,
       Stream_Connected,
       Stream_Disconnecting);

That's semantically identical to the above.

New in v1.1 you can use very simple bit-shift masks:

JREnum(Align,
	   AlignLeft         = 1 << 0,
	   AlignRight        = 1 << 1,
	   AlignTop          = 1 << 2,
	   AlignBottom       = 1 << 3,
	   AlignTopLeft      = 0x05,
	   AlignBottomLeft   = 0x09,
	   AlignTopRight     = 0x06,
	   AlignBottomRight  = 0x0A,
	   );

This helps where you want one variable to house a combination of flags:

Align botRight 		  = AlignBottomRight;
Align botRightBitWise = AlignBottom | AlignRight;

NSLog(@"Are They The Same: %@", (botRightBitWise == botRight) ? @"YES" : @"NO");
//=> Are They The Same: YES

But better, because you can go to-and-fro string values:

NSLog(@"How is that combo aligned? %@", AlignToString(botRightBitWise));
//=> How is that combo aligned? AlignBottomRight

TODO

Version History

v1.1: Mar 25 2014

  • [NEW] Add support for hex constants. (Alex Gray)
  • [NEW] Add support for very simple bit-shifting constants. (rentzsch)

v1.0.1: May 28 2013

v1.0: Apr 09 2013

  • Minor bug fix from 0.2.

v0.2: Dec 10 2012

  • [NEW] Generalized to support bidirectional enum label/value lookup and full runtime access to lookup dictionary.
  • [NEW] Add passing tests.
  • [NEW] Write this README.

v0.1: Dec 9 2012

  • [NEW] Devised way to allow split declaration/definition macros to allow use in header/source files.

Prelude: Dec 8 2012