/ CoreFoundation / Base.subproj / CFAvailability.h
CFAvailability.h
  1  /*	CFAvailability.h
  2  	Copyright (c) 2013-2019, Apple Inc. and the Swift project authors
  3   
  4  	Portions Copyright (c) 2014-2019, Apple Inc. and the Swift project authors
  5  	Licensed under Apache License v2.0 with Runtime Library Exception
  6  	See http://swift.org/LICENSE.txt for license information
  7  	See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
  8  */
  9  
 10  #if !defined(__COREFOUNDATION_CFAVAILABILITY__)
 11  #define __COREFOUNDATION_CFAVAILABILITY__ 1
 12  
 13  #if __has_include(<CoreFoundation/TargetConditionals.h>)
 14  #include <CoreFoundation/TargetConditionals.h>
 15  #else
 16  #include <TargetConditionals.h>
 17  #endif
 18  
 19  #if __has_include(<Availability.h>) && __has_include(<os/availability.h>) && __has_include(<AvailabilityMacros.h>)
 20  #include <Availability.h>
 21  #include <os/availability.h>
 22  // Even if unused, these must remain here for compatibility, because projects rely on them being included.
 23  #include <AvailabilityMacros.h>
 24  #else
 25  #define API_AVAILABLE(...)
 26  #define API_DEPRECATED(...)
 27  #define API_UNAVAILABLE(...)
 28  #endif
 29  
 30  #ifndef __has_feature
 31  #define __has_feature(x) 0
 32  #endif
 33  #ifndef __has_attribute
 34  #define __has_attribute(x) 0
 35  #endif
 36  #ifndef __has_extension
 37  #define __has_extension(x) 0
 38  #endif
 39  
 40  // The arguments to these availability macros is a version number, e.g. 10_6, 3_0 or 'NA'
 41  // To use a deprecation message with the macro, add a string as the last argument.
 42  #if __has_feature(attribute_availability_with_version_underscores) || (__has_feature(attribute_availability_with_message) && __clang__ && __clang_major__ >= 7)
 43  #if TARGET_OS_OSX
 44  // This section is for compilers targeting OS X which support attribute_availability_with_message
 45  
 46  #define CF_AVAILABLE(_mac, _ios) __attribute__((availability(macosx,introduced=_mac)))
 47  #define CF_AVAILABLE_MAC(_mac) __attribute__((availability(macosx,introduced=_mac)))
 48  #define CF_AVAILABLE_IOS(_ios) __attribute__((availability(macosx,unavailable)))
 49  #define CF_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, ...) __attribute__((availability(macosx,introduced=_macIntro,deprecated=_macDep,message="" __VA_ARGS__)))
 50  #define CF_DEPRECATED_MAC(_macIntro, _macDep, ...) __attribute__((availability(macosx,introduced=_macIntro,deprecated=_macDep,message="" __VA_ARGS__)))
 51  #define CF_DEPRECATED_IOS(_iosIntro, _iosDep, ...) __attribute__((availability(macosx,unavailable)))
 52  
 53  #elif TARGET_OS_IPHONE
 54  // This section is for compilers targeting iOS which support attribute_availability_with_message
 55  
 56  #define CF_AVAILABLE(_mac, _ios) __attribute__((availability(ios,introduced=_ios)))
 57  #define CF_AVAILABLE_MAC(_mac) __attribute__((availability(ios,unavailable)))
 58  #define CF_AVAILABLE_IOS(_ios) __attribute__((availability(ios,introduced=_ios)))
 59  #define CF_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, ...) __attribute__((availability(ios,introduced=_iosIntro,deprecated=_iosDep,message="" __VA_ARGS__)))
 60  #define CF_DEPRECATED_MAC(_macIntro, _macDep, ...) __attribute__((availability(ios,unavailable)))
 61  #define CF_DEPRECATED_IOS(_iosIntro, _iosDep, ...) __attribute__((availability(ios,introduced=_iosIntro,deprecated=_iosDep,message="" __VA_ARGS__)))
 62  
 63  #endif
 64  
 65  #elif TARGET_OS_OSX || TARGET_OS_IPHONE
 66  // This section is for OS X or iOS, and compilers without support for attribute_availability_with_message. We fall back to Availability.h.
 67  
 68  #ifndef __AVAILABILITY_INTERNAL__MAC_10_0_DEP__MAC_10_0
 69  #define __AVAILABILITY_INTERNAL__MAC_10_0_DEP__MAC_10_0 __AVAILABILITY_INTERNAL_DEPRECATED
 70  #endif
 71  
 72  #define CF_AVAILABLE(_mac, _ios) __OSX_AVAILABLE_STARTING(__MAC_##_mac, __IPHONE_##_ios)
 73  #define CF_AVAILABLE_MAC(_mac) __OSX_AVAILABLE_STARTING(__MAC_##_mac, __IPHONE_NA)
 74  #define CF_AVAILABLE_IOS(_ios) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_##_ios)
 75  #define CF_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, ...) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_##_macIntro, __MAC_##_macDep, __IPHONE_##_iosIntro, __IPHONE_##_iosDep)
 76  #define CF_DEPRECATED_MAC(_macIntro, _macDep, ...) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_##_macIntro, __MAC_##_macDep, __IPHONE_NA, __IPHONE_NA)
 77  #define CF_DEPRECATED_IOS(_iosIntro, _iosDep, ...) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA, __MAC_NA, __IPHONE_##_iosIntro, __IPHONE_##_iosDep)
 78  
 79  #endif // __has_feature(attribute_availability_with_message)
 80  
 81  #ifndef CF_AVAILABLE
 82  // This section is for platforms which do not support availability
 83  #define CF_AVAILABLE(_mac, _ios)
 84  #define CF_AVAILABLE_MAC(_mac)
 85  #define CF_AVAILABLE_IOS(_ios)
 86  #define CF_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, ...)
 87  #define CF_DEPRECATED_MAC(_macIntro, _macDep, ...)
 88  #define CF_DEPRECATED_IOS(_iosIntro, _iosDep, ...)
 89  #endif
 90  
 91  // Older versions of these macros; use iOS versions instead
 92  #define CF_AVAILABLE_IPHONE(_ios) CF_AVAILABLE_IOS(_ios)
 93  #define CF_DEPRECATED_IPHONE(_iosIntro, _iosDep) CF_DEPRECATED_IOS(_iosIntro, _iosDep)
 94  
 95  // Enum availability macros
 96  #if __has_feature(enumerator_attributes) && __has_attribute(availability)
 97  #define CF_ENUM_AVAILABLE(_mac, _ios) CF_AVAILABLE(_mac, _ios)
 98  #define CF_ENUM_AVAILABLE_MAC(_mac) CF_AVAILABLE_MAC(_mac)
 99  #define CF_ENUM_AVAILABLE_IOS(_ios) CF_AVAILABLE_IOS(_ios)
100  #define CF_ENUM_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, ...) CF_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, __VA_ARGS__)
101  #define CF_ENUM_DEPRECATED_MAC(_macIntro, _macDep, ...) CF_DEPRECATED_MAC(_macIntro, _macDep, __VA_ARGS__)
102  #define CF_ENUM_DEPRECATED_IOS(_iosIntro, _iosDep, ...) CF_DEPRECATED_IOS(_iosIntro, _iosDep, __VA_ARGS__)
103  #else
104  #define CF_ENUM_AVAILABLE(_mac, _ios)
105  #define CF_ENUM_AVAILABLE_MAC(_mac)
106  #define CF_ENUM_AVAILABLE_IOS(_ios)
107  #define CF_ENUM_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, ...)
108  #define CF_ENUM_DEPRECATED_MAC(_macIntro, _macDep, ...)
109  #define CF_ENUM_DEPRECATED_IOS(_iosIntro, _iosDep, ...)
110  #endif
111  
112  // "Soft" deprecation.
113  #ifndef API_TO_BE_DEPRECATED
114  /// This macro is used as a version number in API that will be deprecated in an upcoming release. We call this API "soft deprecated". Soft deprecation is an intermediate step before formal deprecation, used as a way to give you a heads-up about the API before you start getting a compiler warning.
115  /// You can find all places in your code that use soft deprecated API by redefining the value of this macro to your current minimum deployment target, for example:
116  ///   (macOS)
117  ///    clang -DAPI_TO_BE_DEPRECATED=10.12 other compiler flags
118  ///   (iOS)
119  ///    clang -DAPI_TO_BE_DEPRECATED=11.0 other compiler flags
120  #define API_TO_BE_DEPRECATED 100000
121  #endif
122  
123  // Enums and Options
124  #if __has_attribute(enum_extensibility)
125  #define __CF_ENUM_ATTRIBUTES __attribute__((enum_extensibility(open)))
126  #define __CF_CLOSED_ENUM_ATTRIBUTES __attribute__((enum_extensibility(closed)))
127  #define __CF_OPTIONS_ATTRIBUTES __attribute__((flag_enum,enum_extensibility(open)))
128  #else
129  #define __CF_ENUM_ATTRIBUTES
130  #define __CF_CLOSED_ENUM_ATTRIBUTES
131  #define __CF_OPTIONS_ATTRIBUTES
132  #endif
133  
134  #define __CF_ENUM_GET_MACRO(_1, _2, NAME, ...) NAME
135  #define __CF_ENUM_FIXED_IS_AVAILABLE (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && (__has_feature(objc_fixed_enum) || __has_extension(cxx_fixed_enum)))
136  
137  #if __CF_ENUM_FIXED_IS_AVAILABLE
138  #define __CF_NAMED_ENUM(_type, _name)     int __CF_ENUM_ ## _name; enum __CF_ENUM_ATTRIBUTES _name : _type; typedef enum _name _name; enum _name : _type
139  #define __CF_ANON_ENUM(_type)             enum __CF_ENUM_ATTRIBUTES : _type
140  #define CF_CLOSED_ENUM(_type, _name)      int __CF_ENUM_ ## _name; enum __CF_CLOSED_ENUM_ATTRIBUTES _name : _type; typedef enum _name _name; enum _name : _type
141  #if (__cplusplus)
142  #define CF_OPTIONS(_type, _name) _type _name; enum __CF_OPTIONS_ATTRIBUTES : _type
143  #else
144  #define CF_OPTIONS(_type, _name) int __CF_OPTIONS_ ## _name; enum __CF_OPTIONS_ATTRIBUTES _name : _type; typedef enum _name _name; enum _name : _type
145  #endif
146  #else
147  #define __CF_NAMED_ENUM(_type, _name) _type _name; enum
148  #define __CF_ANON_ENUM(_type) enum
149  #define CF_CLOSED_ENUM(_type, _name) _type _name; enum
150  #define CF_OPTIONS(_type, _name) _type _name; enum
151  #endif
152  
153  /* CF_ENUM supports the use of one or two arguments. The first argument is always the integer type used for the values of the enum. The second argument is an optional type name for the macro. When specifying a type name, you must precede the macro with 'typedef' like so:
154  
155  typedef CF_ENUM(CFIndex, CFComparisonResult) {
156      ...
157  };
158  
159  If you do not specify a type name, do not use 'typdef', like so:
160  
161  CF_ENUM(CFIndex) {
162      ...
163  };
164  */
165  #define CF_ENUM(...) __CF_ENUM_GET_MACRO(__VA_ARGS__, __CF_NAMED_ENUM, __CF_ANON_ENUM, )(__VA_ARGS__)
166  
167  #if __has_attribute(swift_wrapper)
168  #define _CF_TYPED_ENUM __attribute__((swift_wrapper(enum)))
169  #else
170  #define _CF_TYPED_ENUM
171  #endif
172  
173  #if __has_attribute(swift_wrapper)
174  #define _CF_TYPED_EXTENSIBLE_ENUM __attribute__((swift_wrapper(struct)))
175  #else
176  #define _CF_TYPED_EXTENSIBLE_ENUM
177  #endif
178  
179  #if DEPLOYMENT_RUNTIME_SWIFT
180  #define CF_STRING_ENUM
181  #define CF_EXTENSIBLE_STRING_ENUM
182  
183  #define CF_TYPED_ENUM
184  #define CF_TYPED_EXTENSIBLE_ENUM
185  #else
186  #define CF_STRING_ENUM _CF_TYPED_ENUM
187  #define CF_EXTENSIBLE_STRING_ENUM _CF_TYPED_EXTENSIBLE_ENUM
188  
189  #define CF_TYPED_ENUM _CF_TYPED_ENUM
190  #define CF_TYPED_EXTENSIBLE_ENUM _CF_TYPED_EXTENSIBLE_ENUM
191  #endif
192  
193  #define __CF_ERROR_ENUM_GET_MACRO(_1, _2, NAME, ...) NAME
194  #if ((__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum))) && __has_attribute(ns_error_domain)
195  #define __CF_NAMED_ERROR_ENUM(_domain, _name)     enum __attribute__((ns_error_domain(_domain))) _name : CFIndex _name; enum _name : CFIndex
196  #define __CF_ANON_ERROR_ENUM(_domain)             enum __attribute__((ns_error_domain(_domain))) : CFIndex
197  #else
198  #define __CF_NAMED_ERROR_ENUM(_domain, _name) __CF_NAMED_ENUM(CFIndex, _name)
199  #define __CF_ANON_ERROR_ENUM(_domain) __CF_ANON_ENUM(CFIndex)
200  #endif
201  
202  /* CF_ERROR_ENUM supports the use of one or two arguments. The first argument is always the domain specifier for the enum. The second argument is an optional name of the typedef for the macro. When specifying a name for of the typedef, you must precede the macro with 'typedef' like so:
203   
204   typedef CF_ERROR_ENUM(kCFSomeErrorDomain, SomeErrorCodes) {
205   ...
206   };
207   
208   If you do not specify a typedef name, do not use 'typedef', like so:
209   
210   CF_ERROR_ENUM(kCFSomeErrorDomain) {
211   ...
212   };
213   */
214  #define CF_ERROR_ENUM(...) __CF_ERROR_ENUM_GET_MACRO(__VA_ARGS__, __CF_NAMED_ERROR_ENUM, __CF_ANON_ERROR_ENUM)(__VA_ARGS__)
215  
216  #ifndef CF_SWIFT_BRIDGED_TYPEDEF
217  #if __has_attribute(swift_bridged_typedef)
218  #define CF_SWIFT_BRIDGED_TYPEDEF __attribute__((swift_bridged_typedef))
219  #else
220  #define CF_SWIFT_BRIDGED_TYPEDEF
221  #endif
222  #endif
223  
224  // Extension availability macros
225  #define CF_EXTENSION_UNAVAILABLE(_msg)      __OS_EXTENSION_UNAVAILABLE(_msg)
226  #define CF_EXTENSION_UNAVAILABLE_MAC(_msg)  __OSX_EXTENSION_UNAVAILABLE(_msg)
227  #define CF_EXTENSION_UNAVAILABLE_IOS(_msg)  __IOS_EXTENSION_UNAVAILABLE(_msg)
228  
229  // Swift availability macro
230  #if __has_feature(attribute_availability_swift)
231  #define CF_SWIFT_UNAVAILABLE(_msg) __attribute__((availability(swift, unavailable, message=_msg)))
232  #else
233  #define CF_SWIFT_UNAVAILABLE(_msg)
234  #endif
235  
236  #endif // __COREFOUNDATION_CFAVAILABILITY__