Created
August 20, 2010 06:37
-
-
Save jonsterling/539747 to your computer and use it in GitHub Desktop.
Objectify
This file contains 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
#import <Foundation/Foundation.h> | |
#import <CoreGraphics/CoreGraphics.h> | |
#import <objc/message.h> | |
#import <string> | |
#import <map> | |
#import <typeinfo> | |
#define $(value) box<typeof(value)>(value) | |
using namespace std; | |
template <typename T> id box(T v) { | |
typedef pair<Class,SEL> m; | |
map<const char *,m> ops; | |
ops[@encode(int)] = m([NSNumber class], @selector(numberWithInt:)); | |
ops[@encode(float)] = m([NSNumber class], @selector(numberWithFloat:)); | |
ops[@encode(double)] = m([NSNumber class], @selector(numberWithDouble:)); | |
ops[@encode(BOOL)] = m([NSNumber class], @selector(numberWithBool:)); | |
ops[@encode(const char *)] = m([NSString class], @selector(stringWithUTF8String:)); | |
ops[@encode(SEL)] = m([NSString class], @selector(objectify_stringFromSelector:)); | |
ops[@encode(Class)] = m([NSString class], @selector(objectify_stringFromClass:)); | |
ops[@encode(CGPoint)] = m([NSValue class], @selector(valueWithCGPoint:)); | |
ops[@encode(CGRect)] = m([NSValue class], @selector(valueWithCGRect:)); | |
ops[@encode(CGSize)] = m([NSValue class], @selector(valueWithCGSize:)); | |
ops[@encode(NSRange)] = m([NSString class], @selector(objectify_stringFromRange:)); | |
ops[@encode(void *)] = m([NSValue class], @selector(valueWithPointer:)); | |
m method = ops[@encode(T)]; | |
Class klass = method.first ? method.first : [NSObject class]; | |
SEL s = method.second ? method.second : @selector(objectify_identity:); | |
id result = objc_msgSend(klass, s, v); | |
return result; | |
} | |
template <typename T> T unbox(id v) { | |
map<const char *,SEL> ops; | |
ops[@encode(int)] = @selector(intValue); | |
ops[@encode(float)] = @selector(floatValue); | |
ops[@encode(double)] = @selector(doubleValue); | |
ops[@encode(BOOL)] = @selector(boolValue); | |
ops[@encode(const char *)] = @selector(UTF8String); | |
ops[@encode(SEL)] = @selector(objectify_selectorValue); | |
ops[@encode(Class)] = @selector(objectify_classValue); | |
ops[@encode(CGPoint)] = @selector(CGPointValue); | |
ops[@encode(CGRect)] = @selector(CGRectValue); | |
ops[@encode(CGSize)] = @selector(CGSizeValue); | |
ops[@encode(NSRange)] = @selector(objectify_rangeValue); | |
ops[@encode(void *)] = @selector(pointerValue); | |
SEL method = ops[@encode(T)] ? ops[@encode(T)] : @selector(objectify_identity); | |
typedef T (*SendFunctionType)(id, SEL); | |
return ((SendFunctionType)objc_msgSend)(v, method); | |
} |
This file contains 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
#import "Objectify.h" | |
@implementation NSString (Objectify) | |
+ (id)objectify_stringFromSelector:(SEL)aSelector { | |
return NSStringFromSelector(aSelector); | |
} | |
- (SEL)objectify_selectorValue { | |
return NSSelectorFromString(self); | |
} | |
+ (id)objectify_stringFromClass:(Class)aClass { | |
return NSStringFromClass(aClass); | |
} | |
- (Class)objectify_classValue { | |
return NSClassFromString(self); | |
} | |
+ (id)objectify_stringFromRange:(NSRange)aRange{ | |
return NSStringFromRange(aRange); | |
} | |
- (NSRange)objectify_rangeValue { | |
return NSRangeFromString(self); | |
} | |
@end | |
@implementation NSObject (Objectify) | |
+ (id)objectify_identity:(id)object { return object; } | |
- (id)objectify_identity { return self; } | |
@end |
This file contains 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
#import <Foundation/Foundation.h> | |
#import "Objectify.h" | |
int main (int argc, const char * argv[]) { | |
NSAutoreleasePool *pool = [NSAutoreleasePool new]; | |
const char *str = "wut"; | |
id o = $<const char *>(str); | |
NSLog(@"char: %s, string: %@, of class: %@", str, o, [o class]); | |
// => char: wut, string: wut, of class: NSCFString | |
[pool drain]; | |
} |
not really following along completely, but are you calling the objc version that gave warnings like so?
id to_object( void * x )
{
return [NSNumber numberWithInt: (int)x];
}
int a = 42;
id foo = to_object( a );
???
If you do it this way it doesn't give a warning:
id to_object( void * x )
{
return [NSNumber numberWithInt: *(int*)x];
}
int a = 42;
id foo = to_object( &a );
requires sending in the address of the thing you want converted though...
Wow, Tyler, you're totally right. Should have thought of that. :)
maybe it prevents detecting the type though... didn't try to actually do what you were trying to do so not sure. Another other option would be to use C's var-args as the parameter because you can get their types moderately easily. I'm almost motivated enough to have a non-C++ version to sit down and write it, but a little pressed for time at the moment.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
As for resource-intensive checking, just try compiling any Haskell program. Seems to work quickly enough for me… :)