GTMDefines.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  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. #include <AvailabilityMacros.h>
  20. #include <TargetConditionals.h>
  21. #ifdef __OBJC__
  22. #include <Foundation/NSObjCRuntime.h>
  23. #endif // __OBJC__
  24. #if TARGET_OS_IPHONE
  25. #include <Availability.h>
  26. #endif // TARGET_OS_IPHONE
  27. // ----------------------------------------------------------------------------
  28. // CPP symbols that can be overridden in a prefix to control how the toolbox
  29. // is compiled.
  30. // ----------------------------------------------------------------------------
  31. // By setting the GTM_CONTAINERS_VALIDATION_FAILED_LOG and
  32. // GTM_CONTAINERS_VALIDATION_FAILED_ASSERT macros you can control what happens
  33. // when a validation fails. If you implement your own validators, you may want
  34. // to control their internals using the same macros for consistency.
  35. #ifndef GTM_CONTAINERS_VALIDATION_FAILED_ASSERT
  36. #define GTM_CONTAINERS_VALIDATION_FAILED_ASSERT 0
  37. #endif
  38. // Ensure __has_feature and __has_extension are safe to use.
  39. // See http://clang-analyzer.llvm.org/annotations.html
  40. #ifndef __has_feature // Optional.
  41. #define __has_feature(x) 0 // Compatibility with non-clang compilers.
  42. #endif
  43. #ifndef __has_extension
  44. #define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
  45. #endif
  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)) || defined (__clang__)
  51. #define GTM_INLINE static __inline__ __attribute__((always_inline))
  52. #else
  53. #define GTM_INLINE static __inline__
  54. #endif
  55. #endif
  56. // Give ourselves a consistent way of doing externs that links up nicely
  57. // when mixing objc and objc++
  58. #if !defined (GTM_EXTERN)
  59. #if defined __cplusplus
  60. #define GTM_EXTERN extern "C"
  61. #define GTM_EXTERN_C_BEGIN extern "C" {
  62. #define GTM_EXTERN_C_END }
  63. #else
  64. #define GTM_EXTERN extern
  65. #define GTM_EXTERN_C_BEGIN
  66. #define GTM_EXTERN_C_END
  67. #endif
  68. #endif
  69. // Give ourselves a consistent way of exporting things if we have visibility
  70. // set to hidden.
  71. #if !defined (GTM_EXPORT)
  72. #define GTM_EXPORT __attribute__((visibility("default")))
  73. #endif
  74. // Give ourselves a consistent way of declaring something as unused. This
  75. // doesn't use __unused because that is only supported in gcc 4.2 and greater.
  76. #if !defined (GTM_UNUSED)
  77. #define GTM_UNUSED(x) ((void)(x))
  78. #endif
  79. // _GTMDevLog & _GTMDevAssert
  80. //
  81. // _GTMDevLog & _GTMDevAssert are meant to be a very lightweight shell for
  82. // developer level errors. This implementation simply macros to NSLog/NSAssert.
  83. // It is not intended to be a general logging/reporting system.
  84. //
  85. // Please see http://code.google.com/p/google-toolbox-for-mac/wiki/DevLogNAssert
  86. // for a little more background on the usage of these macros.
  87. //
  88. // _GTMDevLog log some error/problem in debug builds
  89. // _GTMDevAssert assert if condition isn't met w/in a method/function
  90. // in all builds.
  91. //
  92. // To replace this system, just provide different macro definitions in your
  93. // prefix header. Remember, any implementation you provide *must* be thread
  94. // safe since this could be called by anything in what ever situtation it has
  95. // been placed in.
  96. //
  97. // We only define the simple macros if nothing else has defined this.
  98. #ifndef _GTMDevLog
  99. #ifdef DEBUG
  100. #define _GTMDevLog(...) NSLog(__VA_ARGS__)
  101. #else
  102. #define _GTMDevLog(...) do { } while (0)
  103. #endif
  104. #endif // _GTMDevLog
  105. #ifndef _GTMDevAssert
  106. // we directly invoke the NSAssert handler so we can pass on the varargs
  107. // (NSAssert doesn't have a macro we can use that takes varargs)
  108. #if !defined(NS_BLOCK_ASSERTIONS)
  109. #define _GTMDevAssert(condition, ...) \
  110. do { \
  111. if (!(condition)) { \
  112. [[NSAssertionHandler currentHandler] \
  113. handleFailureInFunction:(NSString *) \
  114. [NSString stringWithUTF8String:__PRETTY_FUNCTION__] \
  115. file:(NSString *)[NSString stringWithUTF8String:__FILE__] \
  116. lineNumber:__LINE__ \
  117. description:__VA_ARGS__]; \
  118. } \
  119. } while(0)
  120. #else // !defined(NS_BLOCK_ASSERTIONS)
  121. #define _GTMDevAssert(condition, ...) do { } while (0)
  122. #endif // !defined(NS_BLOCK_ASSERTIONS)
  123. #endif // _GTMDevAssert
  124. // _GTMCompileAssert
  125. //
  126. // Note: Software for current compilers should just use _Static_assert directly
  127. // instead of this macro.
  128. //
  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. // Wrapping this in an #ifndef allows external groups to define their own
  136. // compile time assert scheme.
  137. #ifndef _GTMCompileAssert
  138. #if __has_feature(c_static_assert) || __has_extension(c_static_assert)
  139. #define _GTMCompileAssert(test, msg) _Static_assert((test), #msg)
  140. #else
  141. // Pre-Xcode 7 support.
  142. //
  143. // We got this technique from here:
  144. // http://unixjunkie.blogspot.com/2007/10/better-compile-time-asserts_29.html
  145. #define _GTMCompileAssertSymbolInner(line, msg) _GTMCOMPILEASSERT ## line ## __ ## msg
  146. #define _GTMCompileAssertSymbol(line, msg) _GTMCompileAssertSymbolInner(line, msg)
  147. #define _GTMCompileAssert(test, msg) \
  148. typedef char _GTMCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ]
  149. #endif // __has_feature(c_static_assert) || __has_extension(c_static_assert)
  150. #endif // _GTMCompileAssert
  151. // ----------------------------------------------------------------------------
  152. // CPP symbols defined based on the project settings so the GTM code has
  153. // simple things to test against w/o scattering the knowledge of project
  154. // setting through all the code.
  155. // ----------------------------------------------------------------------------
  156. // Provide a single constant CPP symbol that all of GTM uses for ifdefing
  157. // iPhone code.
  158. #if TARGET_OS_IPHONE // iPhone SDK
  159. // For iPhone specific stuff
  160. #define GTM_IPHONE_SDK 1
  161. #if TARGET_IPHONE_SIMULATOR
  162. #define GTM_IPHONE_DEVICE 0
  163. #define GTM_IPHONE_SIMULATOR 1
  164. #else
  165. #define GTM_IPHONE_DEVICE 1
  166. #define GTM_IPHONE_SIMULATOR 0
  167. #endif // TARGET_IPHONE_SIMULATOR
  168. // By default, GTM has provided it's own unittesting support, define this
  169. // to use the support provided by Xcode, especially for the Xcode4 support
  170. // for unittesting.
  171. #ifndef GTM_USING_XCTEST
  172. #define GTM_USING_XCTEST 0
  173. #endif
  174. #define GTM_MACOS_SDK 0
  175. #else
  176. // For MacOS specific stuff
  177. #define GTM_MACOS_SDK 1
  178. #define GTM_IPHONE_SDK 0
  179. #define GTM_IPHONE_SIMULATOR 0
  180. #define GTM_IPHONE_DEVICE 0
  181. #ifndef GTM_USING_XCTEST
  182. #define GTM_USING_XCTEST 0
  183. #endif
  184. #endif
  185. // Some of our own availability macros
  186. #if GTM_MACOS_SDK
  187. #define GTM_AVAILABLE_ONLY_ON_IPHONE UNAVAILABLE_ATTRIBUTE
  188. #define GTM_AVAILABLE_ONLY_ON_MACOS
  189. #else
  190. #define GTM_AVAILABLE_ONLY_ON_IPHONE
  191. #define GTM_AVAILABLE_ONLY_ON_MACOS UNAVAILABLE_ATTRIBUTE
  192. #endif
  193. // GC was dropped by Apple, define the old constant incase anyone still keys
  194. // off of it.
  195. #ifndef GTM_SUPPORT_GC
  196. #define GTM_SUPPORT_GC 0
  197. #endif
  198. // Some support for advanced clang static analysis functionality
  199. #ifndef NS_RETURNS_RETAINED
  200. #if __has_feature(attribute_ns_returns_retained)
  201. #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
  202. #else
  203. #define NS_RETURNS_RETAINED
  204. #endif
  205. #endif
  206. #ifndef NS_RETURNS_NOT_RETAINED
  207. #if __has_feature(attribute_ns_returns_not_retained)
  208. #define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
  209. #else
  210. #define NS_RETURNS_NOT_RETAINED
  211. #endif
  212. #endif
  213. #ifndef CF_RETURNS_RETAINED
  214. #if __has_feature(attribute_cf_returns_retained)
  215. #define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
  216. #else
  217. #define CF_RETURNS_RETAINED
  218. #endif
  219. #endif
  220. #ifndef CF_RETURNS_NOT_RETAINED
  221. #if __has_feature(attribute_cf_returns_not_retained)
  222. #define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
  223. #else
  224. #define CF_RETURNS_NOT_RETAINED
  225. #endif
  226. #endif
  227. #ifndef NS_CONSUMED
  228. #if __has_feature(attribute_ns_consumed)
  229. #define NS_CONSUMED __attribute__((ns_consumed))
  230. #else
  231. #define NS_CONSUMED
  232. #endif
  233. #endif
  234. #ifndef CF_CONSUMED
  235. #if __has_feature(attribute_cf_consumed)
  236. #define CF_CONSUMED __attribute__((cf_consumed))
  237. #else
  238. #define CF_CONSUMED
  239. #endif
  240. #endif
  241. #ifndef NS_CONSUMES_SELF
  242. #if __has_feature(attribute_ns_consumes_self)
  243. #define NS_CONSUMES_SELF __attribute__((ns_consumes_self))
  244. #else
  245. #define NS_CONSUMES_SELF
  246. #endif
  247. #endif
  248. #ifndef GTM_NONNULL
  249. #if defined(__has_attribute)
  250. #if __has_attribute(nonnull)
  251. #define GTM_NONNULL(x) __attribute__((nonnull x))
  252. #else
  253. #define GTM_NONNULL(x)
  254. #endif
  255. #else
  256. #define GTM_NONNULL(x)
  257. #endif
  258. #endif
  259. // Invalidates the initializer from which it's called.
  260. #ifndef GTMInvalidateInitializer
  261. #if __has_feature(objc_arc)
  262. #define GTMInvalidateInitializer() \
  263. do { \
  264. [self class]; /* Avoid warning of dead store to |self|. */ \
  265. _GTMDevAssert(NO, @"Invalid initializer."); \
  266. return nil; \
  267. } while (0)
  268. #else
  269. #define GTMInvalidateInitializer() \
  270. do { \
  271. [self release]; \
  272. _GTMDevAssert(NO, @"Invalid initializer."); \
  273. return nil; \
  274. } while (0)
  275. #endif
  276. #endif
  277. #ifndef GTMCFAutorelease
  278. // GTMCFAutorelease returns an id. In contrast, Apple's CFAutorelease returns
  279. // a CFTypeRef.
  280. #if __has_feature(objc_arc)
  281. #define GTMCFAutorelease(x) CFBridgingRelease(x)
  282. #else
  283. #define GTMCFAutorelease(x) ([(id)x autorelease])
  284. #endif
  285. #endif
  286. #ifdef __OBJC__
  287. // Macro to allow you to create NSStrings out of other macros.
  288. // #define FOO foo
  289. // NSString *fooString = GTM_NSSTRINGIFY(FOO);
  290. #if !defined (GTM_NSSTRINGIFY)
  291. #define GTM_NSSTRINGIFY_INNER(x) @#x
  292. #define GTM_NSSTRINGIFY(x) GTM_NSSTRINGIFY_INNER(x)
  293. #endif
  294. // Macro to allow fast enumeration when building for 10.5 or later, and
  295. // reliance on NSEnumerator for 10.4. Remember, NSDictionary w/ FastEnumeration
  296. // does keys, so pick the right thing, nothing is done on the FastEnumeration
  297. // side to be sure you're getting what you wanted.
  298. #ifndef GTM_FOREACH_OBJECT
  299. #if TARGET_OS_IPHONE || !(MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
  300. #define GTM_FOREACH_ENUMEREE(element, enumeration) \
  301. for (element in enumeration)
  302. #define GTM_FOREACH_OBJECT(element, collection) \
  303. for (element in collection)
  304. #define GTM_FOREACH_KEY(element, collection) \
  305. for (element in collection)
  306. #else
  307. #define GTM_FOREACH_ENUMEREE(element, enumeration) \
  308. for (NSEnumerator *_ ## element ## _enum = enumeration; \
  309. (element = [_ ## element ## _enum nextObject]) != nil; )
  310. #define GTM_FOREACH_OBJECT(element, collection) \
  311. GTM_FOREACH_ENUMEREE(element, [collection objectEnumerator])
  312. #define GTM_FOREACH_KEY(element, collection) \
  313. GTM_FOREACH_ENUMEREE(element, [collection keyEnumerator])
  314. #endif
  315. #endif
  316. // ============================================================================
  317. // GTM_SEL_STRING is for specifying selector (usually property) names to KVC
  318. // or KVO methods.
  319. // In debug it will generate warnings for undeclared selectors if
  320. // -Wunknown-selector is turned on.
  321. // In release it will have no runtime overhead.
  322. #ifndef GTM_SEL_STRING
  323. #ifdef DEBUG
  324. #define GTM_SEL_STRING(selName) NSStringFromSelector(@selector(selName))
  325. #else
  326. #define GTM_SEL_STRING(selName) @#selName
  327. #endif // DEBUG
  328. #endif // GTM_SEL_STRING
  329. #ifndef GTM_WEAK
  330. #if __has_feature(objc_arc_weak)
  331. // With ARC enabled, __weak means a reference that isn't implicitly
  332. // retained. __weak objects are accessed through runtime functions, so
  333. // they are zeroed out, but this requires OS X 10.7+.
  334. // At clang r251041+, ARC-style zeroing weak references even work in
  335. // non-ARC mode.
  336. #define GTM_WEAK __weak
  337. #elif __has_feature(objc_arc)
  338. // ARC, but targeting 10.6 or older, where zeroing weak references don't
  339. // exist.
  340. #define GTM_WEAK __unsafe_unretained
  341. #else
  342. // With manual reference counting, __weak used to be silently ignored.
  343. // clang r251041 gives it the ARC semantics instead. This means they
  344. // now require a deployment target of 10.7, while some clients of GTM
  345. // still target 10.6. In these cases, expand to __unsafe_unretained instead
  346. #define GTM_WEAK
  347. #endif
  348. #endif
  349. #endif // __OBJC__