GeezerVison is showing github.com — Copy the macros from SDWebImage Core repo · YFCasually/SDWebImageWebPCoder@4005a4d
File treeExpand file treeCollapse file tree Open diff view settings SDWebImageWebPCoder.xcodeproj
Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboard +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 1 | | -github "SDWebImage/SDWebImage" "5.18.4" | | 1 | +github "SDWebImage/SDWebImage" "5.18.10" | 2 | 2 | github "SDWebImage/libwebp-Xcode" "1.3.2" |
Collapse file Copy file name to clipboardExpand all lines: Package.resolved +2-2Lines changed: 2 additions & 2 deletions Collapse file Copy file name to clipboardExpand all lines: Package.swift +4-1Lines changed: 4 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -28,7 +28,10 @@ let package = Package( | 28 | 28 | dependencies: ["SDWebImage", "libwebp"], | 29 | 29 | path: ".", | 30 | 30 | sources: ["SDWebImageWebPCoder/Classes"], | 31 | | - publicHeadersPath: "SDWebImageWebPCoder/Classes" | | 31 | + publicHeadersPath: "SDWebImageWebPCoder/Classes", | | 32 | + cSettings: [ | | 33 | + .headerSearchPath("SDWebImageWebPCoder/Private") | | 34 | + ] | 32 | 35 | ) | 33 | 36 | ] | 34 | 37 | ) |
Collapse file Copy file name to clipboardExpand all lines: SDWebImageWebPCoder.podspec +2-1Lines changed: 2 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -18,7 +18,8 @@ This is a SDWebImage coder plugin to support WebP image. | 18 | 18 | s.watchos.deployment_target = '2.0' | 19 | 19 | s.module_map = 'SDWebImageWebPCoder/Module/SDWebImageWebPCoder.modulemap' | 20 | 20 |
| 21 | | - s.source_files = 'SDWebImageWebPCoder/Classes/**/*', 'SDWebImageWebPCoder/Module/SDWebImageWebPCoder.h' | | 21 | + s.source_files = 'SDWebImageWebPCoder/Classes/**/*', 'SDWebImageWebPCoder/Classes/Private/*.h', 'SDWebImageWebPCoder/Module/SDWebImageWebPCoder.h' | | 22 | + s.private_header_files = 'SDWebImageWebPCoder/Classes/Private/*.h' | 22 | 23 | s.xcconfig = { | 23 | 24 | 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) SD_WEBP=1', | 24 | 25 | 'USER_HEADER_SEARCH_PATHS' => '$(inherited) $(SRCROOT)/libwebp/src' | |
Collapse file Copy file name to clipboardExpand all lines: SDWebImageWebPCoder.xcodeproj/project.pbxproj +28Lines changed: 28 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 15 | 15 | 220A623F257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; settings = {ATTRIBUTES = (Public, ); }; }; | 16 | 16 | 220A6240257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */; settings = {ATTRIBUTES = (Public, ); }; }; | 17 | 17 | 228EA36125825A52005903D9 /* SDWebImageWebPCoderDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */; }; | | 18 | + 32A3C1452B7129CB00B611BD /* SDInternalMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A3C1432B7129CB00B611BD /* SDInternalMacros.h */; settings = {ATTRIBUTES = (Private, ); }; }; | | 19 | + 32A3C1462B7129CB00B611BD /* SDInternalMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A3C1432B7129CB00B611BD /* SDInternalMacros.h */; settings = {ATTRIBUTES = (Private, ); }; }; | | 20 | + 32A3C1472B7129CB00B611BD /* SDInternalMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A3C1432B7129CB00B611BD /* SDInternalMacros.h */; settings = {ATTRIBUTES = (Private, ); }; }; | | 21 | + 32A3C1482B7129CB00B611BD /* SDInternalMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A3C1432B7129CB00B611BD /* SDInternalMacros.h */; settings = {ATTRIBUTES = (Private, ); }; }; | | 22 | + 32A3C1492B7129CB00B611BD /* SDmetamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A3C1442B7129CB00B611BD /* SDmetamacros.h */; settings = {ATTRIBUTES = (Private, ); }; }; | | 23 | + 32A3C14A2B7129CB00B611BD /* SDmetamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A3C1442B7129CB00B611BD /* SDmetamacros.h */; }; | | 24 | + 32A3C14B2B7129CB00B611BD /* SDmetamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A3C1442B7129CB00B611BD /* SDmetamacros.h */; settings = {ATTRIBUTES = (Private, ); }; }; | | 25 | + 32A3C14C2B7129CB00B611BD /* SDmetamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 32A3C1442B7129CB00B611BD /* SDmetamacros.h */; settings = {ATTRIBUTES = (Private, ); }; }; | 18 | 26 | 806E77B32136A2E900A316D2 /* UIImage+WebP.m in Sources */ = {isa = PBXBuildFile; fileRef = 806E77AA2136A2E900A316D2 /* UIImage+WebP.m */; }; | 19 | 27 | 806E77B42136A2E900A316D2 /* SDImageWebPCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 806E77AB2136A2E900A316D2 /* SDImageWebPCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; | 20 | 28 | 806E77B62136A2E900A316D2 /* UIImage+WebP.h in Headers */ = {isa = PBXBuildFile; fileRef = 806E77AD2136A2E900A316D2 /* UIImage+WebP.h */; settings = {ATTRIBUTES = (Public, ); }; }; | | 49 | 57 | 220A6237257EAFB300262720 /* SDWebImageWebPCoderDefine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageWebPCoderDefine.m; sourceTree = "<group>"; }; | 50 | 58 | 220A6238257EAFB300262720 /* SDWebImageWebPCoderDefine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImageWebPCoderDefine.h; sourceTree = "<group>"; }; | 51 | 59 | 3217BE7B220547EB003D0310 /* SDWebImageWebPCoder.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = SDWebImageWebPCoder.modulemap; sourceTree = "<group>"; }; | | 60 | + 32A3C1432B7129CB00B611BD /* SDInternalMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDInternalMacros.h; sourceTree = "<group>"; }; | | 61 | + 32A3C1442B7129CB00B611BD /* SDmetamacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDmetamacros.h; sourceTree = "<group>"; }; | 52 | 62 | 46F21AD7D1692EBAC4D0FF33 /* Pods_SDWebImageWebPCoderTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImageWebPCoderTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | 53 | 63 | 806E779D2136A1C000A316D2 /* SDWebImageWebPCoder.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImageWebPCoder.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | 54 | 64 | 806E77AA2136A2E900A316D2 /* UIImage+WebP.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+WebP.m"; sourceTree = "<group>"; }; | | 110 | 120 | /* End PBXFrameworksBuildPhase section */ | 111 | 121 |
| 112 | 122 | /* Begin PBXGroup section */ | | 123 | + 32A3C1422B7129CB00B611BD /* Private */ = { | | 124 | + isa = PBXGroup; | | 125 | + children = ( | | 126 | + 32A3C1432B7129CB00B611BD /* SDInternalMacros.h */, | | 127 | + 32A3C1442B7129CB00B611BD /* SDmetamacros.h */, | | 128 | + ); | | 129 | + path = Private; | | 130 | + sourceTree = "<group>"; | | 131 | + }; | 113 | 132 | 806E77932136A1C000A316D2 = { | 114 | 133 | isa = PBXGroup; | 115 | 134 | children = ( | | 135 | 154 | children = ( | 136 | 155 | 806E77A92136A2E900A316D2 /* Classes */, | 137 | 156 | 806E77AF2136A2E900A316D2 /* Module */, | | 157 | + 32A3C1422B7129CB00B611BD /* Private */, | 138 | 158 | 806E77B12136A2E900A316D2 /* Assets */, | 139 | 159 | ); | 140 | 160 | name = SDImageWebPCoder; | | 229 | 249 | 806E77C72136A7AD00A316D2 /* SDWebImageWebPCoder.h in Headers */, | 230 | 250 | 806E77B62136A2E900A316D2 /* UIImage+WebP.h in Headers */, | 231 | 251 | 220A623D257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */, | | 252 | + 32A3C1452B7129CB00B611BD /* SDInternalMacros.h in Headers */, | 232 | 253 | 806E77B42136A2E900A316D2 /* SDImageWebPCoder.h in Headers */, | | 254 | + 32A3C1492B7129CB00B611BD /* SDmetamacros.h in Headers */, | 233 | 255 | ); | 234 | 256 | runOnlyForDeploymentPostprocessing = 0; | 235 | 257 | }; | | 240 | 262 | 80BFF2502136BC1500B95470 /* UIImage+WebP.h in Headers */, | 241 | 263 | 80BFF24D2136BC0600B95470 /* SDWebImageWebPCoder.h in Headers */, | 242 | 264 | 220A623E257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */, | | 265 | + 32A3C1462B7129CB00B611BD /* SDInternalMacros.h in Headers */, | 243 | 266 | 80BFF24E2136BC1000B95470 /* SDImageWebPCoder.h in Headers */, | | 267 | + 32A3C14A2B7129CB00B611BD /* SDmetamacros.h in Headers */, | 244 | 268 | ); | 245 | 269 | runOnlyForDeploymentPostprocessing = 0; | 246 | 270 | }; | | 251 | 275 | 80BFF2632136BE2200B95470 /* SDWebImageWebPCoder.h in Headers */, | 252 | 276 | 80BFF2612136BE1C00B95470 /* UIImage+WebP.h in Headers */, | 253 | 277 | 220A623F257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */, | | 278 | + 32A3C1472B7129CB00B611BD /* SDInternalMacros.h in Headers */, | 254 | 279 | 80BFF25F2136BE1700B95470 /* SDImageWebPCoder.h in Headers */, | | 280 | + 32A3C14B2B7129CB00B611BD /* SDmetamacros.h in Headers */, | 255 | 281 | ); | 256 | 282 | runOnlyForDeploymentPostprocessing = 0; | 257 | 283 | }; | | 262 | 288 | 80BFF27F2136BEF200B95470 /* SDWebImageWebPCoder.h in Headers */, | 263 | 289 | 80BFF27D2136BEED00B95470 /* UIImage+WebP.h in Headers */, | 264 | 290 | 220A6240257EAFB300262720 /* SDWebImageWebPCoderDefine.h in Headers */, | | 291 | + 32A3C1482B7129CB00B611BD /* SDInternalMacros.h in Headers */, | 265 | 292 | 80BFF27B2136BEE700B95470 /* SDImageWebPCoder.h in Headers */, | | 293 | + 32A3C14C2B7129CB00B611BD /* SDmetamacros.h in Headers */, | 266 | 294 | ); | 267 | 295 | runOnlyForDeploymentPostprocessing = 0; | 268 | 296 | }; | |
Collapse file Copy file name to clipboardExpand all lines: SDWebImageWebPCoder/Classes/SDImageWebPCoder.m -42Lines changed: 0 additions & 42 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 27 | 27 | @import libwebp; | 28 | 28 | #endif | 29 | 29 |
| 30 | | -#define SD_USE_OS_UNFAIR_LOCK TARGET_OS_MACCATALYST ||\ | 31 | | - (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0) ||\ | 32 | | - (__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_12) ||\ | 33 | | - (__TV_OS_VERSION_MIN_REQUIRED >= __TVOS_10_0) ||\ | 34 | | - (__WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_3_0) | 35 | | - | 36 | | -#ifndef SD_LOCK_DECLARE | 37 | | -#if SD_USE_OS_UNFAIR_LOCK | 38 | | -#define SD_LOCK_DECLARE(lock) os_unfair_lock lock | 39 | | -#else | 40 | | -#define SD_LOCK_DECLARE(lock) os_unfair_lock lock API_AVAILABLE(ios(10.0), tvos(10), watchos(3), macos(10.12)); \ | 41 | | -OSSpinLock lock##_deprecated; | 42 | | -#endif | 43 | | -#endif | 44 | | - | 45 | | -#ifndef SD_LOCK_INIT | 46 | | -#if SD_USE_OS_UNFAIR_LOCK | 47 | | -#define SD_LOCK_INIT(lock) lock = OS_UNFAIR_LOCK_INIT | 48 | | -#else | 49 | | -#define SD_LOCK_INIT(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) lock = OS_UNFAIR_LOCK_INIT; \ | 50 | | -else lock##_deprecated = OS_SPINLOCK_INIT; | 51 | | -#endif | 52 | | -#endif | 53 | | - | 54 | | -#ifndef SD_LOCK | 55 | | -#if SD_USE_OS_UNFAIR_LOCK | 56 | | -#define SD_LOCK(lock) os_unfair_lock_lock(&lock) | 57 | | -#else | 58 | | -#define SD_LOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_lock(&lock); \ | 59 | | -else OSSpinLockLock(&lock##_deprecated); | 60 | | -#endif | 61 | | -#endif | 62 | | - | 63 | | -#ifndef SD_UNLOCK | 64 | | -#if SD_USE_OS_UNFAIR_LOCK | 65 | | -#define SD_UNLOCK(lock) os_unfair_lock_unlock(&lock) | 66 | | -#else | 67 | | -#define SD_UNLOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_unlock(&lock); \ | 68 | | -else OSSpinLockUnlock(&lock##_deprecated); | 69 | | -#endif | 70 | | -#endif | 71 | | - | 72 | 30 | /// Used for animated WebP, which need a canvas for decoding (rendering), possible apply a scale transform for thumbnail decoding (avoiding post-rescale using vImage) | 73 | 31 | /// See more in #73 | 74 | 32 | static inline CGContextRef _Nullable CreateWebPCanvas(BOOL hasAlpha, CGSize canvasSize, CGSize thumbnailSize, BOOL preserveAspectRatio) { | |
Collapse file Copy file name to clipboard +187Lines changed: 187 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +/* | | 2 | + * This file is part of the SDWebImage package. | | 3 | + | | 4 | + * | | 5 | + * For the full copyright and license information, please view the LICENSE | | 6 | + * file that was distributed with this source code. | | 7 | + */ | | 8 | + | | 9 | +#import <Foundation/Foundation.h> | | 10 | +#import <os/lock.h> | | 11 | +#import <libkern/OSAtomic.h> | | 12 | +#import "SDmetamacros.h" | | 13 | + | | 14 | +#define SD_USE_OS_UNFAIR_LOCK TARGET_OS_MACCATALYST ||\ | | 15 | + (__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0) ||\ | | 16 | + (__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_12) ||\ | | 17 | + (__TV_OS_VERSION_MIN_REQUIRED >= __TVOS_10_0) ||\ | | 18 | + (__WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_3_0) | | 19 | + | | 20 | +#ifndef SD_LOCK_DECLARE | | 21 | +#if SD_USE_OS_UNFAIR_LOCK | | 22 | +#define SD_LOCK_DECLARE(lock) os_unfair_lock lock | | 23 | +#else | | 24 | +#define SD_LOCK_DECLARE(lock) os_unfair_lock lock API_AVAILABLE(ios(10.0), tvos(10), watchos(3), macos(10.12)); \ | | 25 | +OSSpinLock lock##_deprecated; | | 26 | +#endif | | 27 | +#endif | | 28 | + | | 29 | +#ifndef SD_LOCK_DECLARE_STATIC | | 30 | +#if SD_USE_OS_UNFAIR_LOCK | | 31 | +#define SD_LOCK_DECLARE_STATIC(lock) static os_unfair_lock lock | | 32 | +#else | | 33 | +#define SD_LOCK_DECLARE_STATIC(lock) static os_unfair_lock lock API_AVAILABLE(ios(10.0), tvos(10), watchos(3), macos(10.12)); \ | | 34 | +static OSSpinLock lock##_deprecated; | | 35 | +#endif | | 36 | +#endif | | 37 | + | | 38 | +#ifndef SD_LOCK_INIT | | 39 | +#if SD_USE_OS_UNFAIR_LOCK | | 40 | +#define SD_LOCK_INIT(lock) lock = OS_UNFAIR_LOCK_INIT | | 41 | +#else | | 42 | +#define SD_LOCK_INIT(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) lock = OS_UNFAIR_LOCK_INIT; \ | | 43 | +else lock##_deprecated = OS_SPINLOCK_INIT; | | 44 | +#endif | | 45 | +#endif | | 46 | + | | 47 | +#ifndef SD_LOCK | | 48 | +#if SD_USE_OS_UNFAIR_LOCK | | 49 | +#define SD_LOCK(lock) os_unfair_lock_lock(&lock) | | 50 | +#else | | 51 | +#define SD_LOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_lock(&lock); \ | | 52 | +else OSSpinLockLock(&lock##_deprecated); | | 53 | +#endif | | 54 | +#endif | | 55 | + | | 56 | +#ifndef SD_UNLOCK | | 57 | +#if SD_USE_OS_UNFAIR_LOCK | | 58 | +#define SD_UNLOCK(lock) os_unfair_lock_unlock(&lock) | | 59 | +#else | | 60 | +#define SD_UNLOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_unlock(&lock); \ | | 61 | +else OSSpinLockUnlock(&lock##_deprecated); | | 62 | +#endif | | 63 | +#endif | | 64 | + | | 65 | +#ifndef SD_OPTIONS_CONTAINS | | 66 | +#define SD_OPTIONS_CONTAINS(options, value) (((options) & (value)) == (value)) | | 67 | +#endif | | 68 | + | | 69 | +#ifndef SD_CSTRING | | 70 | +#define SD_CSTRING(str) #str | | 71 | +#endif | | 72 | + | | 73 | +#ifndef SD_NSSTRING | | 74 | +#define SD_NSSTRING(str) @(SD_CSTRING(str)) | | 75 | +#endif | | 76 | + | | 77 | +#ifndef SD_SEL_SPI | | 78 | +#define SD_SEL_SPI(name) NSSelectorFromString([NSString stringWithFormat:@"_%@", SD_NSSTRING(name)]) | | 79 | +#endif | | 80 | + | | 81 | +#ifndef weakify | | 82 | +#define weakify(...) \ | | 83 | +sd_keywordify \ | | 84 | +metamacro_foreach_cxt(sd_weakify_,, __weak, __VA_ARGS__) | | 85 | +#endif | | 86 | + | | 87 | +#ifndef strongify | | 88 | +#define strongify(...) \ | | 89 | +sd_keywordify \ | | 90 | +_Pragma("clang diagnostic push") \ | | 91 | +_Pragma("clang diagnostic ignored \"-Wshadow\"") \ | | 92 | +metamacro_foreach(sd_strongify_,, __VA_ARGS__) \ | | 93 | +_Pragma("clang diagnostic pop") | | 94 | +#endif | | 95 | + | | 96 | +#define sd_weakify_(INDEX, CONTEXT, VAR) \ | | 97 | +CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR); | | 98 | + | | 99 | +#define sd_strongify_(INDEX, VAR) \ | | 100 | +__strong __typeof__(VAR) VAR = metamacro_concat(VAR, _weak_); | | 101 | + | | 102 | +#if DEBUG | | 103 | +#define sd_keywordify autoreleasepool {} | | 104 | +#else | | 105 | +#define sd_keywordify try {} @catch (...) {} | | 106 | +#endif | | 107 | + | | 108 | +#ifndef onExit | | 109 | +#define onExit \ | | 110 | +sd_keywordify \ | | 111 | +__strong sd_cleanupBlock_t metamacro_concat(sd_exitBlock_, __LINE__) __attribute__((cleanup(sd_executeCleanupBlock), unused)) = ^ | | 112 | +#endif | | 113 | + | | 114 | +typedef void (^sd_cleanupBlock_t)(void); | | 115 | + | | 116 | +#if defined(__cplusplus) | | 117 | +extern "C" { | | 118 | +#endif | | 119 | + void sd_executeCleanupBlock (__strong sd_cleanupBlock_t *block); | | 120 | +#if defined(__cplusplus) | | 121 | +} | | 122 | +#endif | | 123 | + | | 124 | +/** | | 125 | + * \@keypath allows compile-time verification of key paths. Given a real object | | 126 | + * receiver and key path: | | 127 | + * | | 128 | + * @code | | 129 | +
| | 130 | +NSString *UTF8StringPath = @keypath(str.lowercaseString.UTF8String); | | 131 | +// => @"lowercaseString.UTF8String" | | 132 | +
| | 133 | +NSString *versionPath = @keypath(NSObject, version); | | 134 | +// => @"version" | | 135 | +
| | 136 | +NSString *lowercaseStringPath = @keypath(NSString.new, lowercaseString); | | 137 | +// => @"lowercaseString" | | 138 | +
| | 139 | + * @endcode | | 140 | + * | | 141 | + * ... the macro returns an \c NSString containing all but the first path | | 142 | + * component or argument (e.g., @"lowercaseString.UTF8String", @"version"). | | 143 | + * | | 144 | + * In addition to simply creating a key path, this macro ensures that the key | | 145 | + * path is valid at compile-time (causing a syntax error if not), and supports | | 146 | + * refactoring, such that changing the name of the property will also update any | | 147 | + * uses of \@keypath. | | 148 | + */ | | 149 | +#define keypath(...) \ | | 150 | + _Pragma("clang diagnostic push") \ | | 151 | + _Pragma("clang diagnostic ignored \"-Warc-repeated-use-of-weak\"") \ | | 152 | + (NO).boolValue ? ((NSString * _Nonnull)nil) : ((NSString * _Nonnull)@(cStringKeypath(__VA_ARGS__))) \ | | 153 | + _Pragma("clang diagnostic pop") \ | | 154 | + | | 155 | +#define cStringKeypath(...) \ | | 156 | + metamacro_if_eq(1, metamacro_argcount(__VA_ARGS__))(keypath1(__VA_ARGS__))(keypath2(__VA_ARGS__)) | | 157 | + | | 158 | +#define keypath1(PATH) \ | | 159 | + (((void)(NO && ((void)PATH, NO)), \ | | 160 | + ({ char *__extobjckeypath__ = strchr(# PATH, '.'); NSCAssert(__extobjckeypath__, @"Provided key path is invalid."); __extobjckeypath__ + 1; }))) | | 161 | + | | 162 | +#define keypath2(OBJ, PATH) \ | | 163 | + (((void)(NO && ((void)OBJ.PATH, NO)), # PATH)) | | 164 | + | | 165 | +/** | | 166 | + * \@collectionKeypath allows compile-time verification of key paths across collections NSArray/NSSet etc. Given a real object | | 167 | + * receiver, collection object receiver and related keypaths: | | 168 | + * | | 169 | + * @code | | 170 | + | | 171 | + NSString *employeesFirstNamePath = @collectionKeypath(department.employees, Employee.new, firstName) | | 172 | + // => @"employees.firstName" | | 173 | + | | 174 | + NSString *employeesFirstNamePath = @collectionKeypath(Department.new, employees, Employee.new, firstName) | | 175 | + // => @"employees.firstName" | | 176 | +
| | 177 | + * @endcode | | 178 | + * | | 179 | + */ | | 180 | +#define collectionKeypath(...) \ | | 181 | + metamacro_if_eq(3, metamacro_argcount(__VA_ARGS__))(collectionKeypath3(__VA_ARGS__))(collectionKeypath4(__VA_ARGS__)) | | 182 | + | | 183 | +#define collectionKeypath3(PATH, COLLECTION_OBJECT, COLLECTION_PATH) \ | | 184 | + (YES).boolValue ? (NSString * _Nonnull)@((const char * _Nonnull)[[NSString stringWithFormat:@"%s.%s", cStringKeypath(PATH), cStringKeypath(COLLECTION_OBJECT, COLLECTION_PATH)] UTF8String]) : (NSString * _Nonnull)nil | | 185 | + | | 186 | +#define collectionKeypath4(OBJ, PATH, COLLECTION_OBJECT, COLLECTION_PATH) \ | | 187 | + (YES).boolValue ? (NSString * _Nonnull)@((const char * _Nonnull)[[NSString stringWithFormat:@"%s.%s", cStringKeypath(OBJ, PATH), cStringKeypath(COLLECTION_OBJECT, COLLECTION_PATH)] UTF8String]) : (NSString * _Nonnull)nil |
|