1 // 2 // GTMDefines.h 3 // 4 // Copyright 2008 Google Inc. 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 7 // use this file except in compliance with the License. You may obtain a copy 8 // of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 // License for the specific language governing permissions and limitations under 16 // the License. 17 // 18 19 // ============================================================================ 20 21 #include <AvailabilityMacros.h> 22 #include <TargetConditionals.h> 23 24 // Not all MAC_OS_X_VERSION_10_X macros defined in past SDKs 25 #ifndef MAC_OS_X_VERSION_10_5 26 #define MAC_OS_X_VERSION_10_5 1050 27 #endif 28 #ifndef MAC_OS_X_VERSION_10_6 29 #define MAC_OS_X_VERSION_10_6 1060 30 #endif 31 32 // ---------------------------------------------------------------------------- 33 // CPP symbols that can be overridden in a prefix to control how the toolbox 34 // is compiled. 35 // ---------------------------------------------------------------------------- 36 37 38 // By setting the GTM_CONTAINERS_VALIDATION_FAILED_LOG and 39 // GTM_CONTAINERS_VALIDATION_FAILED_ASSERT macros you can control what happens 40 // when a validation fails. If you implement your own validators, you may want 41 // to control their internals using the same macros for consistency. 42 #ifndef GTM_CONTAINERS_VALIDATION_FAILED_ASSERT 43 #define GTM_CONTAINERS_VALIDATION_FAILED_ASSERT 0 44 #endif 45 46 // Give ourselves a consistent way to do inlines. Apple's macros even use 47 // a few different actual definitions, so we're based off of the foundation 48 // one. 49 #if !defined(GTM_INLINE) 50 #if defined (__GNUC__) && (__GNUC__ == 4) 51 #define GTM_INLINE static __inline__ __attribute__((always_inline)) 52 #else 53 #define GTM_INLINE static __inline__ 54 #endif 55 #endif 56 57 // Give ourselves a consistent way of doing externs that links up nicely 58 // when mixing objc and objc++ 59 #if !defined (GTM_EXTERN) 60 #if defined __cplusplus 61 #define GTM_EXTERN extern "C" 62 #else 63 #define GTM_EXTERN extern 64 #endif 65 #endif 66 67 // Give ourselves a consistent way of exporting things if we have visibility 68 // set to hidden. 69 #if !defined (GTM_EXPORT) 70 #define GTM_EXPORT __attribute__((visibility("default"))) 71 #endif 72 73 // _GTMDevLog & _GTMDevAssert 74 // 75 // _GTMDevLog & _GTMDevAssert are meant to be a very lightweight shell for 76 // developer level errors. This implementation simply macros to NSLog/NSAssert. 77 // It is not intended to be a general logging/reporting system. 78 // 79 // Please see http://code.google.com/p/google-toolbox-for-mac/wiki/DevLogNAssert 80 // for a little more background on the usage of these macros. 81 // 82 // _GTMDevLog log some error/problem in debug builds 83 // _GTMDevAssert assert if conditon isn't met w/in a method/function 84 // in all builds. 85 // 86 // To replace this system, just provide different macro definitions in your 87 // prefix header. Remember, any implementation you provide *must* be thread 88 // safe since this could be called by anything in what ever situtation it has 89 // been placed in. 90 // 91 92 // We only define the simple macros if nothing else has defined this. 93 #ifndef _GTMDevLog 94 95 #ifdef DEBUG 96 #define _GTMDevLog(...) NSLog(__VA_ARGS__) 97 #else 98 #define _GTMDevLog(...) do { } while (0) 99 #endif 100 101 #endif // _GTMDevLog 102 103 // Declared here so that it can easily be used for logging tracking if 104 // necessary. See GTMUnitTestDevLog.h for details. 105 @class NSString; 106 GTM_EXTERN void _GTMUnitTestDevLog(NSString *format, ...); 107 108 #ifndef _GTMDevAssert 109 // we directly invoke the NSAssert handler so we can pass on the varargs 110 // (NSAssert doesn't have a macro we can use that takes varargs) 111 #if !defined(NS_BLOCK_ASSERTIONS) 112 #define _GTMDevAssert(condition, ...) \ 113 do { \ 114 if (!(condition)) { \ 115 [[NSAssertionHandler currentHandler] \ 116 handleFailureInFunction:[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \ 117 file:[NSString stringWithUTF8String:__FILE__] \ 118 lineNumber:__LINE__ \ 119 description:__VA_ARGS__]; \ 120 } \ 121 } while(0) 122 #else // !defined(NS_BLOCK_ASSERTIONS) 123 #define _GTMDevAssert(condition, ...) do { } while (0) 124 #endif // !defined(NS_BLOCK_ASSERTIONS) 125 126 #endif // _GTMDevAssert 127 128 // _GTMCompileAssert 129 // _GTMCompileAssert is an assert that is meant to fire at compile time if you 130 // want to check things at compile instead of runtime. For example if you 131 // want to check that a wchar is 4 bytes instead of 2 you would use 132 // _GTMCompileAssert(sizeof(wchar_t) == 4, wchar_t_is_4_bytes_on_OS_X) 133 // Note that the second "arg" is not in quotes, and must be a valid processor 134 // symbol in it's own right (no spaces, punctuation etc). 135 136 // Wrapping this in an #ifndef allows external groups to define their own 137 // compile time assert scheme. 138 #ifndef _GTMCompileAssert 139 // We got this technique from here: 140 // http://unixjunkie.blogspot.com/2007/10/better-compile-time-asserts_29.html 141 142 #define _GTMCompileAssertSymbolInner(line, msg) _GTMCOMPILEASSERT ## line ## __ ## msg 143 #define _GTMCompileAssertSymbol(line, msg) _GTMCompileAssertSymbolInner(line, msg) 144 #define _GTMCompileAssert(test, msg) \ 145 typedef char _GTMCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ] 146 #endif // _GTMCompileAssert 147 148 // Macro to allow fast enumeration when building for 10.5 or later, and 149 // reliance on NSEnumerator for 10.4. Remember, NSDictionary w/ FastEnumeration 150 // does keys, so pick the right thing, nothing is done on the FastEnumeration 151 // side to be sure you're getting what you wanted. 152 #ifndef GTM_FOREACH_OBJECT 153 #if TARGET_OS_IPHONE || (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) 154 #define GTM_FOREACH_OBJECT(element, collection) \ 155 for (element in collection) 156 #define GTM_FOREACH_KEY(element, collection) \ 157 for (element in collection) 158 #else 159 #define GTM_FOREACH_OBJECT(element, collection) \ 160 for (NSEnumerator * _ ## element ## _enum = [collection objectEnumerator]; \ 161 (element = [_ ## element ## _enum nextObject]) != nil; ) 162 #define GTM_FOREACH_KEY(element, collection) \ 163 for (NSEnumerator * _ ## element ## _enum = [collection keyEnumerator]; \ 164 (element = [_ ## element ## _enum nextObject]) != nil; ) 165 #endif 166 #endif 167 168 // ============================================================================ 169 170 // ---------------------------------------------------------------------------- 171 // CPP symbols defined based on the project settings so the GTM code has 172 // simple things to test against w/o scattering the knowledge of project 173 // setting through all the code. 174 // ---------------------------------------------------------------------------- 175 176 // Provide a single constant CPP symbol that all of GTM uses for ifdefing 177 // iPhone code. 178 #if TARGET_OS_IPHONE // iPhone SDK 179 // For iPhone specific stuff 180 #define GTM_IPHONE_SDK 1 181 #if TARGET_IPHONE_SIMULATOR 182 #define GTM_IPHONE_SIMULATOR 1 183 #else 184 #define GTM_IPHONE_DEVICE 1 185 #endif // TARGET_IPHONE_SIMULATOR 186 #else 187 // For MacOS specific stuff 188 #define GTM_MACOS_SDK 1 189 #endif 190 191 // Provide a symbol to include/exclude extra code for GC support. (This mainly 192 // just controls the inclusion of finalize methods). 193 #ifndef GTM_SUPPORT_GC 194 #if GTM_IPHONE_SDK 195 // iPhone never needs GC 196 #define GTM_SUPPORT_GC 0 197 #else 198 // We can't find a symbol to tell if GC is supported/required, so best we 199 // do on Mac targets is include it if we're on 10.5 or later. 200 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 201 #define GTM_SUPPORT_GC 0 202 #else 203 #define GTM_SUPPORT_GC 1 204 #endif 205 #endif 206 #endif 207 208 // To simplify support for 64bit (and Leopard in general), we provide the type 209 // defines for non Leopard SDKs 210 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 211 // NSInteger/NSUInteger and Max/Mins 212 #ifndef NSINTEGER_DEFINED 213 #if __LP64__ || NS_BUILD_32_LIKE_64 214 typedef long NSInteger; 215 typedef unsigned long NSUInteger; 216 #else 217 typedef int NSInteger; 218 typedef unsigned int NSUInteger; 219 #endif 220 #define NSIntegerMax LONG_MAX 221 #define NSIntegerMin LONG_MIN 222 #define NSUIntegerMax ULONG_MAX 223 #define NSINTEGER_DEFINED 1 224 #endif // NSINTEGER_DEFINED 225 // CGFloat 226 #ifndef CGFLOAT_DEFINED 227 #if defined(__LP64__) && __LP64__ 228 // This really is an untested path (64bit on Tiger?) 229 typedef double CGFloat; 230 #define CGFLOAT_MIN DBL_MIN 231 #define CGFLOAT_MAX DBL_MAX 232 #define CGFLOAT_IS_DOUBLE 1 233 #else /* !defined(__LP64__) || !__LP64__ */ 234 typedef float CGFloat; 235 #define CGFLOAT_MIN FLT_MIN 236 #define CGFLOAT_MAX FLT_MAX 237 #define CGFLOAT_IS_DOUBLE 0 238 #endif /* !defined(__LP64__) || !__LP64__ */ 239 #define CGFLOAT_DEFINED 1 240 #endif // CGFLOAT_DEFINED 241 #endif // MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 242