// *** before: ***
// only a constant could be wrapped shortly; a variable or an expression
// needed the full factory call, and the right method had to be chosen
int width = 320;
NSNumber *boxedWidth = [NSNumber numberWithInt:width];
double area = width * 1.5;
NSNumber *boxedArea = [NSNumber numberWithDouble:area];
const char *cName = "Ann";
NSString *name = [NSString stringWithUTF8String:cName];
// *** in version 2012: ***
// @(...) wraps any expression, and the compiler picks the type itself
int width = 320;
NSNumber *boxedWidth = @(width);
double area = width * 1.5;
NSNumber *boxedArea = @(area);
NSNumber *sum = @(width + 20);
NSNumber *isWide = @(width > 300); // a BOOL comes out
const char *cName = "Ann";
NSString *name = @(cName); // a C string becomes an NSString
// an enum value is wrapped the same way, which is what puts it in a dictionary
typedef enum { StateIdle, StateBusy } State;
NSDictionary *info = @{@"state": @(StateBusy)};
// ⚠️ @(cName) with a NULL pointer throws; a C string must be checked first