text: //
  // GTMDefines.h
  //
  //  Copyright 2008 Google Inc.
  //
  //  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  //  use this file except in compliance with the License.  You may obtain a copy
  //  of the License at
  //
  //  http://www.apache.org/licenses/LICENSE-2.0
  //
  //  Unless required by applicable law or agreed to in writing, software
  //  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  //  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
  //  License for the specific language governing permissions and limitations under
  //  the License.
  //
  
  // ============================================================================
  
  #include <AvailabilityMacros.h>
  #include <TargetConditionals.h>
  
  #if TARGET_OS_IPHONE
  #include <Availability.h>
  #endif //  TARGET_OS_IPHONE
  
  // Not all MAC_OS_X_VERSION_10_X macros defined in past SDKs
  #ifndef MAC_OS_X_VERSION_10_5
  #define MAC_OS_X_VERSION_10_5 1050
  #endif
  #ifndef MAC_OS_X_VERSION_10_6
  #define MAC_OS_X_VERSION_10_6 1060
  #endif
  #ifndef MAC_OS_X_VERSION_10_7
  #define MAC_OS_X_VERSION_10_7 1070
  #endif
  
  // Not all __IPHONE_X macros defined in past SDKs
  #ifndef __IPHONE_3_0
  #define __IPHONE_3_0 30000
  #endif
  #ifndef __IPHONE_3_1
  #define __IPHONE_3_1 30100
  #endif
  #ifndef __IPHONE_3_2
  #define __IPHONE_3_2 30200
  #endif
  #ifndef __IPHONE_4_0
  #define __IPHONE_4_0 40000
  #endif
  #ifndef __IPHONE_4_3
  #define __IPHONE_4_3 40300
  #endif
  #ifndef __IPHONE_5_0
  #define __IPHONE_5_0 50000
  #endif
  
  // ----------------------------------------------------------------------------
  // CPP symbols that can be overridden in a prefix to control how the toolbox
  // is compiled.
  // ----------------------------------------------------------------------------
  
  // By setting the GTM_CONTAINERS_VALIDATION_FAILED_LOG and
  // GTM_CONTAINERS_VALIDATION_FAILED_ASSERT macros you can control what happens
  // when a validation fails. If you implement your own validators, you may want
  // to control their internals using the same macros for consistency.
  #ifndef GTM_CONTAINERS_VALIDATION_FAILED_ASSERT
  #define GTM_CONTAINERS_VALIDATION_FAILED_ASSERT 0
  #endif
  
  // Give ourselves a consistent way to do inlines.  Apple's macros even use
  // a few different actual definitions, so we're based off of the foundation
  // one.
  #if !defined(GTM_INLINE)
  #if (defined(__GNUC__) && (__GNUC__ == 4)) || defined(__clang__)
  #define GTM_INLINE static __inline__ __attribute__((always_inline))
  #else
  #define GTM_INLINE static __inline__
  #endif
  #endif
  
  // Give ourselves a consistent way of doing externs that links up nicely
  // when mixing objc and objc++
  #if !defined(GTM_EXTERN)
  #if defined __cplusplus
  #define GTM_EXTERN extern "C"
  #define GTM_EXTERN_C_BEGIN extern "C" {
  #define GTM_EXTERN_C_END }
  #else
  #define GTM_EXTERN extern
  #define GTM_EXTERN_C_BEGIN
  #define GTM_EXTERN_C_END
  #endif
  #endif
  
  // Give ourselves a consistent way of exporting things if we have visibility
  // set to hidden.
  #if !defined(GTM_EXPORT)
  #define GTM_EXPORT __attribute__((visibility("default")))
  #endif
  
  // Give ourselves a consistent way of declaring something as unused. This
  // doesn't use __unused because that is only supported in gcc 4.2 and greater.
  #if !defined(GTM_UNUSED)
  #define GTM_UNUSED(x) ((void)(x))
  #endif
  
  // _GTMDevLog & _GTMDevAssert
  //
  // _GTMDevLog & _GTMDevAssert are meant to be a very lightweight shell for
  // developer level errors.  This implementation simply macros to debugLog/NSAssert.
  // It is not intended to be a general logging/reporting system.
  //
  // Please see http://code.google.com/p/google-toolbox-for-mac/wiki/DevLogNAssert
  // for a little more background on the usage of these macros.
  //
  //    _GTMDevLog           log some error/problem in debug builds
  //    _GTMDevAssert        assert if conditon isn't met w/in a method/function
  //                           in all builds.
  //
  // To replace this system, just provide different macro definitions in your
  // prefix header.  Remember, any implementation you provide *must* be thread
  // safe since this could be called by anything in what ever situtation it has
  // been placed in.
  //
  
  // We only define the simple macros if nothing else has defined this.
  #ifndef _GTMDevLog
  
  #ifdef DEBUG
  #define _GTMDevLog(...) debugLog(__VA_ARGS__)
  #else
  #define _GTMDevLog(...) \
      do {                \
      } while (0)
  #endif
  
  #endif // _GTMDevLog
  
  #ifndef _GTMDevAssert
  // we directly invoke the NSAssert handler so we can pass on the varargs
  // (NSAssert doesn't have a macro we can use that takes varargs)
  #if !defined(NS_BLOCK_ASSERTIONS)
  #define _GTMDevAssert(condition, ...)                                                       \
      do {                                                                                    \
          if (!(condition)) {                                                                 \
              [[NSAssertionHandler currentHandler]                                            \
                  handleFailureInFunction:[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \
                                     file:[NSString stringWithUTF8String:__FILE__]            \
                               lineNumber:__LINE__                                            \
                              description:__VA_ARGS__];                                       \
          }                                                                                   \
      } while (0)
  #else // !defined(NS_BLOCK_ASSERTIONS)
  #define _GTMDevAssert(condition, ...) \
      do {                              \
      } while (0)
  #endif // !defined(NS_BLOCK_ASSERTIONS)
  
  #endif // _GTMDevAssert
  
  // _GTMCompileAssert
  // _GTMCompileAssert is an assert that is meant to fire at compile time if you
  // want to check things at compile instead of runtime. For example if you
  // want to check that a wchar is 4 bytes instead of 2 you would use
  // _GTMCompileAssert(sizeof(wchar_t) == 4, wchar_t_is_4_bytes_on_OS_X)
  // Note that the second "arg" is not in quotes, and must be a valid processor
  // symbol in it's own right (no spaces, punctuation etc).
  
  // Wrapping this in an #ifndef allows external groups to define their own
  // compile time assert scheme.
  #ifndef _GTMCompileAssert
  // We got this technique from here:
  // http://unixjunkie.blogspot.com/2007/10/better-compile-time-asserts_29.html
  
  #define _GTMCompileAssertSymbolInner(line, msg) _GTMCOMPILEASSERT##line##__##msg
  #define _GTMCompileAssertSymbol(line, msg) _GTMCompileAssertSymbolInner(line, msg)
  #define _GTMCompileAssert(test, msg) \
      typedef char _GTMCompileAssertSymbol(__LINE__, msg)[((test) ? 1 : -1)]
  #endif // _GTMCompileAssert
  
  // ----------------------------------------------------------------------------
  // CPP symbols defined based on the project settings so the GTM code has
  // simple things to test against w/o scattering the knowledge of project
  // setting through all the code.
  // ----------------------------------------------------------------------------
  
  // Provide a single constant CPP symbol that all of GTM uses for ifdefing
  // iPhone code.
  #if TARGET_OS_IPHONE // iPhone SDK
  // For iPhone specific stuff
  #define GTM_IPHONE_SDK 1
  #if TARGET_IPHONE_SIMULATOR
  #define GTM_IPHONE_SIMULATOR 1
  #else
  #define GTM_IPHONE_DEVICE 1
  #endif // TARGET_IPHONE_SIMULATOR
  // By default, GTM has provided it's own unittesting support, define this
  // to use the support provided by Xcode, especially for the Xcode4 support
  // for unittesting.
  #ifndef GTM_IPHONE_USE_SENTEST
  #define GTM_IPHONE_USE_SENTEST 0
  #endif
  #else
  // For MacOS specific stuff
  #define GTM_MACOS_SDK 1
  #endif
  
  // Some of our own availability macros
  #if GTM_MACOS_SDK
  #define GTM_AVAILABLE_ONLY_ON_IPHONE UNAVAILABLE_ATTRIBUTE
  #define GTM_AVAILABLE_ONLY_ON_MACOS
  #else
  #define GTM_AVAILABLE_ONLY_ON_IPHONE
  #define GTM_AVAILABLE_ONLY_ON_MACOS UNAVAILABLE_ATTRIBUTE
  #endif
  
  // Provide a symbol to include/exclude extra code for GC support.  (This mainly
  // just controls the inclusion of finalize methods).
  #ifndef GTM_SUPPORT_GC
  #if GTM_IPHONE_SDK
  // iPhone never needs GC
  #define GTM_SUPPORT_GC 0
  #else
  // We can't find a symbol to tell if GC is supported/required, so best we
  // do on Mac targets is include it if we're on 10.5 or later.
  #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
  #define GTM_SUPPORT_GC 0
  #else
  #define GTM_SUPPORT_GC 1
  #endif
  #endif
  #endif
  
  // To simplify support for 64bit (and Leopard in general), we provide the type
  // defines for non Leopard SDKs
  #if !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
  // NSInteger/NSUInteger and Max/Mins
  #ifndef NSINTEGER_DEFINED
  #if __LP64__ || NS_BUILD_32_LIKE_64
  typedef long NSInteger;
  typedef unsigned long NSUInteger;
  #else
  typedef int NSInteger;
  typedef unsigned int NSUInteger;
  #endif
  #define NSIntegerMax LONG_MAX
  #define NSIntegerMin LONG_MIN
  #define NSUIntegerMax ULONG_MAX
  #define NSINTEGER_DEFINED 1
  #endif // NSINTEGER_DEFINED
  // CGFloat
  #ifndef CGFLOAT_DEFINED
  #if defined(__LP64__) && __LP64__
  // This really is an untested path (64bit on Tiger?)
  typedef double CGFloat;
  #define CGFLOAT_MIN DBL_MIN
  #define CGFLOAT_MAX DBL_MAX
  #define CGFLOAT_IS_DOUBLE 1
  #else /* !defined(__LP64__) || !__LP64__ */
  typedef float CGFloat;
  #define CGFLOAT_MIN FLT_MIN
  #define CGFLOAT_MAX FLT_MAX
  #define CGFLOAT_IS_DOUBLE 0
  #endif /* !defined(__LP64__) || !__LP64__ */
  #define CGFLOAT_DEFINED 1
  #endif // CGFLOAT_DEFINED
  #endif // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
  
  // Some support for advanced clang static analysis functionality
  // See http://clang-analyzer.llvm.org/annotations.html
  #ifndef __has_feature      // Optional.
  #define __has_feature(x) 0 // Compatibility with non-clang compilers.
  #endif
  
  #ifndef NS_RETURNS_RETAINED
  #if __has_feature(attribute_ns_returns_retained)
  #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
  #else
  #define NS_RETURNS_RETAINED
  #endif
  #endif
  
  #ifndef NS_RETURNS_NOT_RETAINED
  #if __has_feature(attribute_ns_returns_not_retained)
  #define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
  #else
  #define NS_RETURNS_NOT_RETAINED
  #endif
  #endif
  
  #ifndef CF_RETURNS_RETAINED
  #if __has_feature(attribute_cf_returns_retained)
  #define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
  #else
  #define CF_RETURNS_RETAINED
  #endif
  #endif
  
  #ifndef CF_RETURNS_NOT_RETAINED
  #if __has_feature(attribute_cf_returns_not_retained)
  #define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
  #else
  #define CF_RETURNS_NOT_RETAINED
  #endif
  #endif
  
  #ifndef NS_CONSUMED
  #if __has_feature(attribute_ns_consumed)
  #define NS_CONSUMED __attribute__((ns_consumed))
  #else
  #define NS_CONSUMED
  #endif
  #endif
  
  #ifndef CF_CONSUMED
  #if __has_feature(attribute_cf_consumed)
  #define CF_CONSUMED __attribute__((cf_consumed))
  #else
  #define CF_CONSUMED
  #endif
  #endif
  
  #ifndef NS_CONSUMES_SELF
  #if __has_feature(attribute_ns_consumes_self)
  #define NS_CONSUMES_SELF __attribute__((ns_consumes_self))
  #else
  #define NS_CONSUMES_SELF
  #endif
  #endif
  
  // Defined on 10.6 and above.
  #ifndef NS_FORMAT_ARGUMENT
  #define NS_FORMAT_ARGUMENT(A)
  #endif
  
  // Defined on 10.6 and above.
  #ifndef NS_FORMAT_FUNCTION
  #define NS_FORMAT_FUNCTION(F, A)
  #endif
  
  // Defined on 10.6 and above.
  #ifndef CF_FORMAT_ARGUMENT
  #define CF_FORMAT_ARGUMENT(A)
  #endif
  
  // Defined on 10.6 and above.
  #ifndef CF_FORMAT_FUNCTION
  #define CF_FORMAT_FUNCTION(F, A)
  #endif
  
  #ifndef GTM_NONNULL
  #define GTM_NONNULL(x) __attribute__((nonnull(x)))
  #endif
  
  #ifdef __OBJC__
  
  // Declared here so that it can easily be used for logging tracking if
  // necessary. See GTMUnitTestDevLog.h for details.
  @class NSString;
  GTM_EXTERN void _GTMUnitTestDevLog(NSString *format, ...);
  
  // Macro to allow you to create NSStrings out of other macros.
  // #define FOO foo
  // NSString *fooString = GTM_NSSTRINGIFY(FOO);
  #if !defined(GTM_NSSTRINGIFY)
  #define GTM_NSSTRINGIFY_INNER(x) @ #x
  #define GTM_NSSTRINGIFY(x) GTM_NSSTRINGIFY_INNER(x)
  #endif
  
  // Macro to allow fast enumeration when building for 10.5 or later, and
  // reliance on NSEnumerator for 10.4.  Remember, NSDictionary w/ FastEnumeration
  // does keys, so pick the right thing, nothing is done on the FastEnumeration
  // side to be sure you're getting what you wanted.
  #ifndef GTM_FOREACH_OBJECT
  #if TARGET_OS_IPHONE || !(MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
  #define GTM_FOREACH_ENUMEREE(element, enumeration) \
      for (element in enumeration)
  #define GTM_FOREACH_OBJECT(element, collection) \
      for (element in collection)
  #define GTM_FOREACH_KEY(element, collection) \
      for (element in collection)
  #else
  #define GTM_FOREACH_ENUMEREE(element, enumeration)      \
      for (NSEnumerator *_##element##_enum = enumeration; \
           (element = [_##element##_enum nextObject]) != nil;)
  #define GTM_FOREACH_OBJECT(element, collection) \
      GTM_FOREACH_ENUMEREE(element, [collection objectEnumerator])
  #define GTM_FOREACH_KEY(element, collection) \
      GTM_FOREACH_ENUMEREE(element, [collection keyEnumerator])
  #endif
  #endif
  
  // ============================================================================
  
  // To simplify support for both Leopard and Snow Leopard we declare
  // the Snow Leopard protocols that we need here.
  #if !defined(GTM_10_6_PROTOCOLS_DEFINED) && !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
  #define GTM_10_6_PROTOCOLS_DEFINED 1
  @protocol NSConnectionDelegate
  @end
  @protocol NSAnimationDelegate
  @end
  @protocol NSImageDelegate
  @end
  @protocol NSTabViewDelegate
  @end
  #endif // !defined(GTM_10_6_PROTOCOLS_DEFINED) && !(MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
  
  // GTM_SEL_STRING is for specifying selector (usually property) names to KVC
  // or KVO methods.
  // In debug it will generate warnings for undeclared selectors if
  // -Wunknown-selector is turned on.
  // In release it will have no runtime overhead.
  #ifndef GTM_SEL_STRING
  #ifdef DEBUG
  #define GTM_SEL_STRING(selName) NSStringFromSelector(@selector(selName))
  #else
  #define GTM_SEL_STRING(selName) @ #selName
  #endif // DEBUG
  #endif // GTM_SEL_STRING
  
  #endif // __OBJC__
  