// // HOMUtilities.h // HigherOrderMessaging // // Created by Ofri Wolfus on 23/12/05. // Copyright 2005 Ofri Wolfus. All rights reserved. // // This file is released under modified BSD license. // #import #include #include #import /* * A macro for class clusters that needs to implement a method that must be overridden by a concrete subclass. * This macro must be used within the context of a method. It raises an NSInternalInconsistencyException exception when the method is being called. */ #if !defined (DP_SUBCLASS_MUST_IMPLEMENT) #define DP_SUBCLASS_MUST_IMPLEMENT \ do {\ [[NSException exceptionWithName:NSInternalInconsistencyException\ reason:[NSString stringWithFormat:@"%@'s implementation of %@ was not overridden!",\ class_getName(object_isInstance(self) ? (Class)(self->isa) : (Class)self), NSStringFromSelector(_cmd)]\ userInfo:nil] raise];\ } while (0) // An alternative naming to DP_SUBCLASS_MUST_IMPLEMENT #if !defined (DPSubclassMustOverride) #define DPSubclassMustOverride DP_SUBCLASS_MUST_IMPLEMENT #endif #endif @class NSAssertionHandler; /* Asserts for Objective-C that accepts unlimited number of arguments */ #if !defined(NS_BLOCK_ASSERTIONS) && !defined(DPAssert) /* * The usage of this macro is the same as with NSAssert, exept you don't need DPAssert1, DPAssert2, etc. * This macro accepts any number of arguments passed to the description. */ #define DPAssert(condition, desc...)\ do {\ if (!(condition)) {\ [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd\ object:self\ file:[NSString stringWithCString:__FILE__] \ lineNumber:__LINE__\ description:desc];\ }\ } while(0) #endif #if !__OBJC2__ /* Code taken from CocoaDev. See http://www.cocoadev.com/index.pl?ForallMacro for more details. Modified by Ofri Wolfus. */ #define _hom_foreach(element, collection...) for(id __foreach_macro_element = nil, __foreach_macro_enumerator = [collection objectEnumerator]; \ __foreach_macro_element = !__foreach_macro_element ? [__foreach_macro_enumerator nextObject] : nil;) \ for (element = __foreach_macro_element; __foreach_macro_element; __foreach_macro_element = nil) #else // For ObjC 2 we just use the built in for (in) syntax #define _hom_foreach(obj, collection...) for(obj in collection) #endif /* * These two macros enable a foreach (obj In collection) syntax for both * ObjC 1 and 2. The keyword "In" can optionally be replaced by a comma. * In ObjC 1, foreach() sends a -objectEnumerator message to the collection * and uses the returned NSEnumerator to achieve it's goal. * In ObjC 2, foreach() is translated to the built in for(in) syntax in order * to provide better performances. */ #define In , #define foreach(X...) _hom_foreach(X) // A nice name for the always_inline attribute, in the style of the attributes macros from AvailabilityMacros.h #if !defined (ALWAYS_INLINE_ATTRIBUTE) #define ALWAYS_INLINE_ATTRIBUTE __attribute__((always_inline)) #endif // End of supported section #pragma mark - /* * The next section has some stuff that some may find useful, but others will consider as hacks. * Be VERY careful when you use stuff from here, and make sure you know what you're doing! * Also remember that these stuff may stop working at *ANY* later stage or even completely disappear. * * With that being said, most people will find the DPSubclassMustOverride and DPAssert() macros useful. * Other stuff are useful for people that need close interaction with the Objective-C runtime (which most people don't need). */ /* * The following macros are deprecated. * Use the dp_ ones from DPObjCRuntime.h instead. */ // Returns whether the passed object is an instance #define HOMObjectIsInstance(obj) object_isInstance(obj) //Checks if obj is *really* kind of cls. //This is useful if you *need* to know whether a proxy is really a proxy since //it may override -isKindOfClass to its target object. #define hom_isKindOfClass(obj, cls) object_isKindOfClass(obj, cls) //Renames originalSelector instance method of inClass to newSelector. DP_EXTERN BOOL hom_renameInstnaceMethod(Class inClass, SEL originalSelector, SEL newSelector) DEPRECATED_ATTRIBUTE; //Renames originalSelector class method of inClass to newSelector. DP_EXTERN BOOL hom_renameClassMethod(Class inClass, SEL originalSelector, SEL newSelector) DEPRECATED_ATTRIBUTE; //Rplaces the IMP of originalSelector instance method of classOne with the imp of newSelector of classTwo. //Returns the original IMP of originalSelector. DP_EXTERN IMP hom_replaceInstanceIMP(Class classOne, SEL originalSelector, Class classTwo, SEL newSelector) DEPRECATED_ATTRIBUTE; //Rplaces the IMP of originalSelector class method of classOne with the imp of newSelector of classTwo. //Returns the original IMP of originalSelector. DP_EXTERN IMP hom_replaceClassIMP(Class classOne, SEL originalSelector, Class classTwo, SEL newSelector) DEPRECATED_ATTRIBUTE; // Returns the number of arguments the passed selector accepts #define hom_getNumberOfArguments(sel) sel_getNumberOfArguments(sel) // Returnes the type of the argument at a given index. // If index is 0 based, and if it exceeds the number of arguments, the result is undefined. DP_EXTERN const char * hom_getArgumentTypeAtIndex(Method m, unsigned index); DP_EXTERN const char * hom_getArgumentFromTypes(const char *types, unsigned index); // Returnes the type of the argument at a given index. // If index is 0 based, and if it exceeds the number of arguments, the result is undefined. // You are responsible for freeing the returned string. DP_EXTERN char *hom_copyArgumentTypeAtIndex(Method m, unsigned index); // Returnes the offset of the argument at a given index. // If index is 0 based, and if it exceeds the number of arguments, the result is undefined. // Use hom_sizeOfType() if you need to get the size of the argument. DP_EXTERN int hom_getArgumentOffsetAtIndex(Method m, unsigned index); DP_EXTERN int hom_getArgumentOffsetFromTypes(const char *types, unsigned index);