From 63cfcc91a8a0f3da0b3d6121b5ec35e43d68b574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bromo=CC=88?= Date: Wed, 20 Apr 2016 15:51:35 +0200 Subject: [PATCH 1/5] Renamed method argument class to aClass as class is a reserved keyword when compiling for Objective-C++ --- MTLManagedObjectAdapter/MTLManagedObjectAdapter.h | 2 +- MTLManagedObjectAdapter/MTLManagedObjectAdapter.m | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/MTLManagedObjectAdapter/MTLManagedObjectAdapter.h b/MTLManagedObjectAdapter/MTLManagedObjectAdapter.h index dfefb20..ef2a337 100644 --- a/MTLManagedObjectAdapter/MTLManagedObjectAdapter.h +++ b/MTLManagedObjectAdapter/MTLManagedObjectAdapter.h @@ -231,7 +231,7 @@ extern const NSInteger MTLManagedObjectAdapterErrorInvalidManagedObjectMapping; // nil. // // Returns a value transformer or nil if no transformation should be used. -+ (NSValueTransformer *)transformerForModelPropertiesOfClass:(Class)class; ++ (NSValueTransformer *)transformerForModelPropertiesOfClass:(Class)aClass; // A value transformer that should be used for a properties of the given // primitive type. diff --git a/MTLManagedObjectAdapter/MTLManagedObjectAdapter.m b/MTLManagedObjectAdapter/MTLManagedObjectAdapter.m index 3a3189f..7dcdc22 100644 --- a/MTLManagedObjectAdapter/MTLManagedObjectAdapter.m +++ b/MTLManagedObjectAdapter/MTLManagedObjectAdapter.m @@ -75,7 +75,7 @@ @interface MTLManagedObjectAdapter () // // Returns a dictionary with the properties of modelClass that need // transformation as keys and the value transformers as values. -- (NSDictionary *)valueTransformersForModelClass:(Class)class; +- (NSDictionary *)valueTransformersForModelClass:(Class)aClass; // Initializes the receiver to serialize or deserialize a MTLModel of the given // class. @@ -761,10 +761,10 @@ - (NSDictionary *)valueTransformersForModelClass:(Class)modelClass { return result; } -+ (NSValueTransformer *)transformerForModelPropertiesOfClass:(Class)class { - NSParameterAssert(class != nil); ++ (NSValueTransformer *)transformerForModelPropertiesOfClass:(Class)aClass { + NSParameterAssert(aClass != nil); - SEL selector = MTLSelectorWithKeyPattern(NSStringFromClass(class), "EntityAttributeTransformer"); + SEL selector = MTLSelectorWithKeyPattern(NSStringFromClass(aClass), "EntityAttributeTransformer"); if (![self respondsToSelector:selector]) return nil; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:selector]]; From 3b31a1c87dea853336363e5a6646f50a2aaf7ab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bromo=CC=88?= Date: Wed, 28 Nov 2018 10:28:14 +0100 Subject: [PATCH 2/5] Fixed a crash when setting the success/error (in Swift) of an MTLValueTransformer, caused by capturing the autoreleased error reference in the blocks and the error reference being deallocated prematurely. Passing a local tmpError that is then assigned to the error reference avoids this. --- .../MTLManagedObjectAdapter.m | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/MTLManagedObjectAdapter/MTLManagedObjectAdapter.m b/MTLManagedObjectAdapter/MTLManagedObjectAdapter.m index 7dcdc22..b19ffcc 100644 --- a/MTLManagedObjectAdapter/MTLManagedObjectAdapter.m +++ b/MTLManagedObjectAdapter/MTLManagedObjectAdapter.m @@ -166,12 +166,14 @@ - (id)modelFromManagedObject:(NSManagedObject *)managedObject processedObjects:( // any cycles when processing its relationships. CFDictionaryAddValue(processedObjects, (__bridge void *)managedObject, (__bridge void *)model); + __block NSError *tmpError; + BOOL (^setValueForKey)(NSString *, id) = ^(NSString *key, id value) { // Mark this as being autoreleased, because validateValue may return // a new object to be stored in this variable (and we don't want ARC to // double-free or leak the old or new values). __autoreleasing id replaceableValue = value; - if (![model validateValue:&replaceableValue forKey:key error:error]) return NO; + if (![model validateValue:&replaceableValue forKey:key error:&tmpError]) return NO; [model setValue:replaceableValue forKey:key]; return YES; @@ -191,7 +193,7 @@ - (id)modelFromManagedObject:(NSManagedObject *)managedObject processedObjects:( id errorHandlingTransformer = (id)transformer; BOOL success = YES; - value = [errorHandlingTransformer transformedValue:value success:&success error:error]; + value = [errorHandlingTransformer transformedValue:value success:&success error:&tmpError]; if (!success) return NO; } else if (transformer != nil) { @@ -213,7 +215,7 @@ - (id)modelFromManagedObject:(NSManagedObject *)managedObject processedObjects:( NSMutableArray *models = [NSMutableArray arrayWithCapacity:[relationshipCollection count]]; for (NSManagedObject *nestedObject in relationshipCollection) { - id model = [self.class modelOfClass:nestedClass fromManagedObject:nestedObject processedObjects:processedObjects error:error]; + id model = [self.class modelOfClass:nestedClass fromManagedObject:nestedObject processedObjects:processedObjects error:&tmpError]; if (model == nil) return nil; [models addObject:model]; @@ -233,7 +235,7 @@ - (id)modelFromManagedObject:(NSManagedObject *)managedObject processedObjects:( if (nestedObject == nil) return YES; - id model = [self.class modelOfClass:nestedClass fromManagedObject:nestedObject processedObjects:processedObjects error:error]; + id model = [self.class modelOfClass:nestedClass fromManagedObject:nestedObject processedObjects:processedObjects error:&tmpError]; if (model == nil) return NO; return setValueForKey(propertyKey, model); @@ -242,17 +244,14 @@ - (id)modelFromManagedObject:(NSManagedObject *)managedObject processedObjects:( BOOL (^deserializeProperty)(NSPropertyDescription *) = ^(NSPropertyDescription *propertyDescription) { if (propertyDescription == nil) { - if (error != NULL) { - NSString *failureReason = [NSString stringWithFormat:NSLocalizedString(@"No property by name \"%@\" exists on the entity.", @""), managedObjectKey]; - - NSDictionary *userInfo = @{ - NSLocalizedDescriptionKey: NSLocalizedString(@"Could not deserialize managed object", @""), - NSLocalizedFailureReasonErrorKey: failureReason, - }; + NSString *failureReason = [NSString stringWithFormat:NSLocalizedString(@"No property by name \"%@\" exists on the entity.", @""), managedObjectKey]; - *error = [NSError errorWithDomain:MTLManagedObjectAdapterErrorDomain code:MTLManagedObjectAdapterErrorInvalidManagedObjectKey userInfo:userInfo]; - } + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not deserialize managed object", @""), + NSLocalizedFailureReasonErrorKey: failureReason, + }; + tmpError = [NSError errorWithDomain:MTLManagedObjectAdapterErrorDomain code:MTLManagedObjectAdapterErrorInvalidManagedObjectKey userInfo:userInfo]; return NO; } @@ -263,22 +262,24 @@ - (id)modelFromManagedObject:(NSManagedObject *)managedObject processedObjects:( } else if ([propertyClassName isEqual:@"NSRelationshipDescription"]) { return deserializeRelationship((id)propertyDescription); } else { - if (error != NULL) { - NSString *failureReason = [NSString stringWithFormat:NSLocalizedString(@"Property descriptions of class %@ are unsupported.", @""), propertyClassName]; - - NSDictionary *userInfo = @{ - NSLocalizedDescriptionKey: NSLocalizedString(@"Could not deserialize managed object", @""), - NSLocalizedFailureReasonErrorKey: failureReason, - }; + NSString *failureReason = [NSString stringWithFormat:NSLocalizedString(@"Property descriptions of class %@ are unsupported.", @""), propertyClassName]; - *error = [NSError errorWithDomain:MTLManagedObjectAdapterErrorDomain code:MTLManagedObjectAdapterErrorUnsupportedManagedObjectPropertyType userInfo:userInfo]; - } + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not deserialize managed object", @""), + NSLocalizedFailureReasonErrorKey: failureReason, + }; + tmpError = [NSError errorWithDomain:MTLManagedObjectAdapterErrorDomain code:MTLManagedObjectAdapterErrorUnsupportedManagedObjectPropertyType userInfo:userInfo]; return NO; } }; - if (!deserializeProperty(managedObjectProperties[managedObjectKey])) return nil; + if (!deserializeProperty(managedObjectProperties[managedObjectKey])) { + if (tmpError && error) { + *error = tmpError; + } + return nil; + } } return model; @@ -452,7 +453,7 @@ - (id)managedObjectFromModel:(id)model insertingInt id errorHandlingTransformer = (id)transformer; BOOL success = YES; - transformedValue = [errorHandlingTransformer reverseTransformedValue:value success:&success error:error]; + transformedValue = [errorHandlingTransformer reverseTransformedValue:value success:&success error:&tmpError]; if (!success) return NO; } else { From eae60888fe179c52b6f9b7ddde107e2a53f275b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bromo=CC=88?= Date: Wed, 28 Nov 2018 10:37:43 +0100 Subject: [PATCH 3/5] Ensure property attributes don't leak (https://github.com/jspahrsummers/libextobjc/commit/31927ddccd68564addcf310741b0c252225ddcea) --- MTLManagedObjectAdapter/extobjc/EXTRuntimeExtensions.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MTLManagedObjectAdapter/extobjc/EXTRuntimeExtensions.m b/MTLManagedObjectAdapter/extobjc/EXTRuntimeExtensions.m index 7b8804e..3eb6e5f 100644 --- a/MTLManagedObjectAdapter/extobjc/EXTRuntimeExtensions.m +++ b/MTLManagedObjectAdapter/extobjc/EXTRuntimeExtensions.m @@ -53,7 +53,7 @@ if (!next) { fprintf(stderr, "ERROR: Could not read class name in attribute string \"%s\" for property %s\n", attrString, property_getName(property)); - return NULL; + goto errorOut; } if (className != next) { From 390e564defe3bc4fc49a324ea385936ab5f211d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bromo=CC=88?= Date: Wed, 28 Nov 2018 10:40:05 +0100 Subject: [PATCH 4/5] Added a podspec and increased the version to 1.0.4. --- MTLManagedObjectAdapter.podspec | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 MTLManagedObjectAdapter.podspec diff --git a/MTLManagedObjectAdapter.podspec b/MTLManagedObjectAdapter.podspec new file mode 100644 index 0000000..25ea72a --- /dev/null +++ b/MTLManagedObjectAdapter.podspec @@ -0,0 +1,25 @@ +Pod::Spec.new do |s| + s.name = "MTLManagedObjectAdapter" + s.version = "1.0.4" + s.license = "MIT" + s.summary = "Model framework for Cocoa and Cocoa Touch." + s.homepage = "https://github.com/Mantle/Mantle" + s.authors = { "GitHub" => "support@github.com" } + s.source = { :git => "https://github.com/peroper/MTLManagedObjectAdapter.git", :tag => s.version } + s.requires_arc = true + s.platforms = { + :ios => "5.0", + :osx => "10.7", + :watchos => "2.0", + :tvos => "9.0" + } + s.source_files = "MTLManagedObjectAdapter" + s.dependency "Mantle", "~> 2.0" + s.frameworks = "Foundation", "CoreData" + s.prepare_command = "PREFIX=\"mtl_moa_\"\n# Add prefix to header imports\next_header_prefix_src() {\n SOURCE_FILE=$1\n EXT_HEADER_NAME=$2\n sed -i.bak \"s/\"${EXT_HEADER_NAME}\"/\"${PREFIX}${EXT_HEADER_NAME}\"/g\" ${SOURCE_FILE} && rm ${SOURCE_FILE}.bak\n}\next_header_prefix_src MTLManagedObjectAdapter/MTLManagedObjectAdapter.m EXTRuntimeExtensions.h\next_header_prefix_src MTLManagedObjectAdapter/MTLManagedObjectAdapter.m EXTScope.h\next_header_prefix_src MTLManagedObjectAdapter/extobjc/EXTRuntimeExtensions.m EXTRuntimeExtensions.h\next_header_prefix_src MTLManagedObjectAdapter/extobjc/EXTScope.m EXTScope.h\n# Change header name\next_header_prefix_mv() {\n SOURCE_FILE=$1\n FILE_NAME=`basename ${SOURCE_FILE}`\n DIR_NAME=`dirname ${SOURCE_FILE}`\n mv ${SOURCE_FILE} `dirname ${SOURCE_FILE}`/${PREFIX}`basename ${SOURCE_FILE}`\n}\nexport -f ext_header_prefix_mv\nexport PREFIX=${PREFIX}\nfind MTLManagedObjectAdapter/extobjc -name \"*.h\" -exec bash -c 'ext_header_prefix_mv \"$0\"' {} \\;\nunset ext_header_prefix_mv\nunset PREFIX" + s.default_subspec = 'extobjc' + s.subspec 'extobjc' do |s| + s.source_files = "MTLManagedObjectAdapter/extobjc" + s.private_header_files = "MTLManagedObjectAdapter/extobjc/*.h" + end +end From 860410bcfe7c7ac36eb22c4d4fd99e4192b9c382 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Thu, 19 Nov 2020 15:16:00 +0100 Subject: [PATCH 5/5] Update Mantle dependency. Removed unecessary extobjc, as it is included in Mantle dependency. --- MTLManagedObjectAdapter.podspec | 10 +- .../project.pbxproj | 30 +- .../MTLManagedObjectAdapter.m | 6 +- .../extobjc/EXTKeyPathCoding.h | 68 -- .../extobjc/EXTRuntimeExtensions.h | 114 --- .../extobjc/EXTRuntimeExtensions.m | 209 ------ MTLManagedObjectAdapter/extobjc/EXTScope.h | 99 --- MTLManagedObjectAdapter/extobjc/EXTScope.m | 15 - MTLManagedObjectAdapter/extobjc/metamacros.h | 666 ------------------ README.md | 3 + 10 files changed, 9 insertions(+), 1211 deletions(-) delete mode 100644 MTLManagedObjectAdapter/extobjc/EXTKeyPathCoding.h delete mode 100644 MTLManagedObjectAdapter/extobjc/EXTRuntimeExtensions.h delete mode 100644 MTLManagedObjectAdapter/extobjc/EXTRuntimeExtensions.m delete mode 100644 MTLManagedObjectAdapter/extobjc/EXTScope.h delete mode 100644 MTLManagedObjectAdapter/extobjc/EXTScope.m delete mode 100644 MTLManagedObjectAdapter/extobjc/metamacros.h diff --git a/MTLManagedObjectAdapter.podspec b/MTLManagedObjectAdapter.podspec index 25ea72a..2303e91 100644 --- a/MTLManagedObjectAdapter.podspec +++ b/MTLManagedObjectAdapter.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "MTLManagedObjectAdapter" - s.version = "1.0.4" + s.version = "1.0.5" s.license = "MIT" s.summary = "Model framework for Cocoa and Cocoa Touch." s.homepage = "https://github.com/Mantle/Mantle" @@ -14,12 +14,6 @@ Pod::Spec.new do |s| :tvos => "9.0" } s.source_files = "MTLManagedObjectAdapter" - s.dependency "Mantle", "~> 2.0" + s.dependency "Mantle/extobjc", "~> 2.1.6" s.frameworks = "Foundation", "CoreData" - s.prepare_command = "PREFIX=\"mtl_moa_\"\n# Add prefix to header imports\next_header_prefix_src() {\n SOURCE_FILE=$1\n EXT_HEADER_NAME=$2\n sed -i.bak \"s/\"${EXT_HEADER_NAME}\"/\"${PREFIX}${EXT_HEADER_NAME}\"/g\" ${SOURCE_FILE} && rm ${SOURCE_FILE}.bak\n}\next_header_prefix_src MTLManagedObjectAdapter/MTLManagedObjectAdapter.m EXTRuntimeExtensions.h\next_header_prefix_src MTLManagedObjectAdapter/MTLManagedObjectAdapter.m EXTScope.h\next_header_prefix_src MTLManagedObjectAdapter/extobjc/EXTRuntimeExtensions.m EXTRuntimeExtensions.h\next_header_prefix_src MTLManagedObjectAdapter/extobjc/EXTScope.m EXTScope.h\n# Change header name\next_header_prefix_mv() {\n SOURCE_FILE=$1\n FILE_NAME=`basename ${SOURCE_FILE}`\n DIR_NAME=`dirname ${SOURCE_FILE}`\n mv ${SOURCE_FILE} `dirname ${SOURCE_FILE}`/${PREFIX}`basename ${SOURCE_FILE}`\n}\nexport -f ext_header_prefix_mv\nexport PREFIX=${PREFIX}\nfind MTLManagedObjectAdapter/extobjc -name \"*.h\" -exec bash -c 'ext_header_prefix_mv \"$0\"' {} \\;\nunset ext_header_prefix_mv\nunset PREFIX" - s.default_subspec = 'extobjc' - s.subspec 'extobjc' do |s| - s.source_files = "MTLManagedObjectAdapter/extobjc" - s.private_header_files = "MTLManagedObjectAdapter/extobjc/*.h" - end end diff --git a/MTLManagedObjectAdapter.xcodeproj/project.pbxproj b/MTLManagedObjectAdapter.xcodeproj/project.pbxproj index 654892e..fc6816b 100644 --- a/MTLManagedObjectAdapter.xcodeproj/project.pbxproj +++ b/MTLManagedObjectAdapter.xcodeproj/project.pbxproj @@ -12,8 +12,6 @@ 5470B5241985122200E4D941 /* MTLManagedObjectAdapter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5470B5071985122200E4D941 /* MTLManagedObjectAdapter.framework */; }; 5470B52C1985122300E4D941 /* MTLManagedObjectAdapterSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5470B52B1985122300E4D941 /* MTLManagedObjectAdapterSpec.m */; }; 5470B583198512AE00E4D941 /* MTLManagedObjectAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 5470B5171985122200E4D941 /* MTLManagedObjectAdapter.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 5470B5C819851F3900E4D941 /* EXTRuntimeExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 5470B5C219851F3900E4D941 /* EXTRuntimeExtensions.m */; }; - 5470B5CC19851F3900E4D941 /* EXTScope.m in Sources */ = {isa = PBXBuildFile; fileRef = 5470B5C419851F3900E4D941 /* EXTScope.m */; }; 5470B5D51985208C00E4D941 /* MTLCoreDataObjects.m in Sources */ = {isa = PBXBuildFile; fileRef = 5470B5D21985208C00E4D941 /* MTLCoreDataObjects.m */; }; 5470B5D71985208C00E4D941 /* MTLCoreDataTestModels.m in Sources */ = {isa = PBXBuildFile; fileRef = 5470B5D41985208C00E4D941 /* MTLCoreDataTestModels.m */; }; 5470B5DB1985209E00E4D941 /* TestModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 5470B5D91985209E00E4D941 /* TestModel.xcdatamodeld */; }; @@ -29,8 +27,6 @@ D0EB705C1AB747F000BBB455 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0EB70591AB747E300BBB455 /* CoreData.framework */; }; D0EB705E1AB7487D00BBB455 /* Mantle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0EB705D1AB7487D00BBB455 /* Mantle.framework */; }; D0EB705F1AB748C900BBB455 /* Mantle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0EB705D1AB7487D00BBB455 /* Mantle.framework */; }; - D0EB70601AB748E700BBB455 /* EXTRuntimeExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 5470B5C219851F3900E4D941 /* EXTRuntimeExtensions.m */; }; - D0EB70611AB748E700BBB455 /* EXTScope.m in Sources */ = {isa = PBXBuildFile; fileRef = 5470B5C419851F3900E4D941 /* EXTScope.m */; }; D0EB70651AB74A0A00BBB455 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0EB70631AB74A0A00BBB455 /* Quick.framework */; }; D0EB70671AB74A2200BBB455 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0EB70661AB74A2200BBB455 /* Nimble.framework */; }; D0EB70681AB74A2200BBB455 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0EB70661AB74A2200BBB455 /* Nimble.framework */; }; @@ -84,12 +80,6 @@ 5470B599198514F700E4D941 /* Mac-Framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-Framework.xcconfig"; sourceTree = ""; }; 5470B59A198514F700E4D941 /* Mac-StaticLibrary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-StaticLibrary.xcconfig"; sourceTree = ""; }; 5470B59B198514F700E4D941 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.md; sourceTree = ""; }; - 5470B5C019851F3900E4D941 /* EXTKeyPathCoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXTKeyPathCoding.h; sourceTree = ""; }; - 5470B5C119851F3900E4D941 /* EXTRuntimeExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXTRuntimeExtensions.h; sourceTree = ""; }; - 5470B5C219851F3900E4D941 /* EXTRuntimeExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EXTRuntimeExtensions.m; sourceTree = ""; }; - 5470B5C319851F3900E4D941 /* EXTScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXTScope.h; sourceTree = ""; }; - 5470B5C419851F3900E4D941 /* EXTScope.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EXTScope.m; sourceTree = ""; }; - 5470B5C519851F3900E4D941 /* metamacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = metamacros.h; sourceTree = ""; }; 5470B5D11985208C00E4D941 /* MTLCoreDataObjects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTLCoreDataObjects.h; sourceTree = ""; }; 5470B5D21985208C00E4D941 /* MTLCoreDataObjects.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTLCoreDataObjects.m; sourceTree = ""; }; 5470B5D31985208C00E4D941 /* MTLCoreDataTestModels.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTLCoreDataTestModels.h; sourceTree = ""; }; @@ -212,7 +202,6 @@ 5470B5111985122200E4D941 /* Supporting Files */ = { isa = PBXGroup; children = ( - 5470B5BF19851F3900E4D941 /* libextobjc */, D0EB70581AB747C300BBB455 /* Info.plist */, ); name = "Supporting Files"; @@ -306,20 +295,6 @@ path = "Mac OS X"; sourceTree = ""; }; - 5470B5BF19851F3900E4D941 /* libextobjc */ = { - isa = PBXGroup; - children = ( - 5470B5C019851F3900E4D941 /* EXTKeyPathCoding.h */, - 5470B5C119851F3900E4D941 /* EXTRuntimeExtensions.h */, - 5470B5C219851F3900E4D941 /* EXTRuntimeExtensions.m */, - 5470B5C319851F3900E4D941 /* EXTScope.h */, - 5470B5C419851F3900E4D941 /* EXTScope.m */, - 5470B5C519851F3900E4D941 /* metamacros.h */, - ); - name = libextobjc; - path = extobjc; - sourceTree = ""; - }; 5470B5D01985202F00E4D941 /* Specs */ = { isa = PBXGroup; children = ( @@ -447,6 +422,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ); mainGroup = 5470B4FD1985122200E4D941; @@ -498,8 +474,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5470B5CC19851F3900E4D941 /* EXTScope.m in Sources */, - 5470B5C819851F3900E4D941 /* EXTRuntimeExtensions.m in Sources */, 5470B5191985122200E4D941 /* MTLManagedObjectAdapter.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -520,8 +494,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D0EB70611AB748E700BBB455 /* EXTScope.m in Sources */, - D0EB70601AB748E700BBB455 /* EXTRuntimeExtensions.m in Sources */, D0EB70531AB7479700BBB455 /* MTLManagedObjectAdapter.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/MTLManagedObjectAdapter/MTLManagedObjectAdapter.m b/MTLManagedObjectAdapter/MTLManagedObjectAdapter.m index b19ffcc..57153f7 100644 --- a/MTLManagedObjectAdapter/MTLManagedObjectAdapter.m +++ b/MTLManagedObjectAdapter/MTLManagedObjectAdapter.m @@ -10,8 +10,8 @@ #import -#import "EXTScope.h" -#import "EXTRuntimeExtensions.h" +#import +#import #import "MTLManagedObjectAdapter.h" @@ -741,7 +741,7 @@ - (NSDictionary *)valueTransformersForModelClass:(Class)modelClass { if (property == NULL) continue; - mtl_moa_propertyAttributes *attributes = mtl_moa_copyPropertyAttributes(property); + mtl_propertyAttributes *attributes = mtl_copyPropertyAttributes(property); @onExit { free(attributes); }; diff --git a/MTLManagedObjectAdapter/extobjc/EXTKeyPathCoding.h b/MTLManagedObjectAdapter/extobjc/EXTKeyPathCoding.h deleted file mode 100644 index f34dc4a..0000000 --- a/MTLManagedObjectAdapter/extobjc/EXTKeyPathCoding.h +++ /dev/null @@ -1,68 +0,0 @@ -// -// EXTKeyPathCoding.h -// extobjc -// -// Created by Justin Spahr-Summers on 19.06.12. -// Copyright (C) 2012 Justin Spahr-Summers. -// Released under the MIT license. -// - -#import -#import "metamacros.h" - -/** - * \@keypath allows compile-time verification of key paths. Given a real object - * receiver and key path: - * - * @code - -NSString *UTF8StringPath = @keypath(str.lowercaseString.UTF8String); -// => @"lowercaseString.UTF8String" - -NSString *versionPath = @keypath(NSObject, version); -// => @"version" - -NSString *lowercaseStringPath = @keypath(NSString.new, lowercaseString); -// => @"lowercaseString" - - * @endcode - * - * ... the macro returns an \c NSString containing all but the first path - * component or argument (e.g., @"lowercaseString.UTF8String", @"version"). - * - * In addition to simply creating a key path, this macro ensures that the key - * path is valid at compile-time (causing a syntax error if not), and supports - * refactoring, such that changing the name of the property will also update any - * uses of \@keypath. - */ -#define keypath(...) \ - metamacro_if_eq(1, metamacro_argcount(__VA_ARGS__))(keypath1(__VA_ARGS__))(keypath2(__VA_ARGS__)) - -#define keypath1(PATH) \ - (((void)(NO && ((void)PATH, NO)), strchr(# PATH, '.') + 1)) - -#define keypath2(OBJ, PATH) \ - (((void)(NO && ((void)OBJ.PATH, NO)), # PATH)) - -/** - * \@collectionKeypath allows compile-time verification of key paths across collections NSArray/NSSet etc. Given a real object - * receiver, collection object receiver and related keypaths: - * - * @code - - NSString *employessFirstNamePath = @collectionKeypath(department.employees, Employee.new, firstName) - // => @"employees.firstName" - - NSString *employessFirstNamePath = @collectionKeypath(Department.new, employees, Employee.new, firstName) - // => @"employees.firstName" - - * @endcode - * - */ -#define collectionKeypath(...) \ - metamacro_if_eq(3, metamacro_argcount(__VA_ARGS__))(collectionKeypath3(__VA_ARGS__))(collectionKeypath4(__VA_ARGS__)) - -#define collectionKeypath3(PATH, COLLECTION_OBJECT, COLLECTION_PATH) ([[NSString stringWithFormat:@"%s.%s",keypath(PATH), keypath(COLLECTION_OBJECT, COLLECTION_PATH)] UTF8String]) - -#define collectionKeypath4(OBJ, PATH, COLLECTION_OBJECT, COLLECTION_PATH) ([[NSString stringWithFormat:@"%s.%s",keypath(OBJ, PATH), keypath(COLLECTION_OBJECT, COLLECTION_PATH)] UTF8String]) - diff --git a/MTLManagedObjectAdapter/extobjc/EXTRuntimeExtensions.h b/MTLManagedObjectAdapter/extobjc/EXTRuntimeExtensions.h deleted file mode 100644 index 1f16c53..0000000 --- a/MTLManagedObjectAdapter/extobjc/EXTRuntimeExtensions.h +++ /dev/null @@ -1,114 +0,0 @@ -// -// EXTRuntimeExtensions.h -// extobjc -// -// Created by Justin Spahr-Summers on 2011-03-05. -// Copyright (C) 2012 Justin Spahr-Summers. -// Released under the MIT license. -// - -#import -#import - -/** - * Describes the memory management policy of a property. - */ -typedef enum { - /** - * The value is assigned. - */ - mtl_moa_propertyMemoryManagementPolicyAssign = 0, - - /** - * The value is retained. - */ - mtl_moa_propertyMemoryManagementPolicyRetain, - - /** - * The value is copied. - */ - mtl_moa_propertyMemoryManagementPolicyCopy -} mtl_moa_propertyMemoryManagementPolicy; - -/** - * Describes the attributes and type information of a property. - */ -typedef struct { - /** - * Whether this property was declared with the \c readonly attribute. - */ - BOOL readonly; - - /** - * Whether this property was declared with the \c nonatomic attribute. - */ - BOOL nonatomic; - - /** - * Whether the property is a weak reference. - */ - BOOL weak; - - /** - * Whether the property is eligible for garbage collection. - */ - BOOL canBeCollected; - - /** - * Whether this property is defined with \c \@dynamic. - */ - BOOL dynamic; - - /** - * The memory management policy for this property. This will always be - * #mtl_moa_propertyMemoryManagementPolicyAssign if #readonly is \c YES. - */ - mtl_moa_propertyMemoryManagementPolicy memoryManagementPolicy; - - /** - * The selector for the getter of this property. This will reflect any - * custom \c getter= attribute provided in the property declaration, or the - * inferred getter name otherwise. - */ - SEL getter; - - /** - * The selector for the setter of this property. This will reflect any - * custom \c setter= attribute provided in the property declaration, or the - * inferred setter name otherwise. - * - * @note If #readonly is \c YES, this value will represent what the setter - * \e would be, if the property were writable. - */ - SEL setter; - - /** - * The backing instance variable for this property, or \c NULL if \c - * \c @synthesize was not used, and therefore no instance variable exists. This - * would also be the case if the property is implemented dynamically. - */ - const char *ivar; - - /** - * If this property is defined as being an instance of a specific class, - * this will be the class object representing it. - * - * This will be \c nil if the property was defined as type \c id, if the - * property is not of an object type, or if the class could not be found at - * runtime. - */ - Class objectClass; - - /** - * The type encoding for the value of this property. This is the type as it - * would be returned by the \c \@encode() directive. - */ - char type[]; -} mtl_moa_propertyAttributes; - -/** - * Returns a pointer to a structure containing information about \a property. - * You must \c free() the returned pointer. Returns \c NULL if there is an error - * obtaining information from \a property. - */ -mtl_moa_propertyAttributes *mtl_moa_copyPropertyAttributes (objc_property_t property); diff --git a/MTLManagedObjectAdapter/extobjc/EXTRuntimeExtensions.m b/MTLManagedObjectAdapter/extobjc/EXTRuntimeExtensions.m deleted file mode 100644 index 3eb6e5f..0000000 --- a/MTLManagedObjectAdapter/extobjc/EXTRuntimeExtensions.m +++ /dev/null @@ -1,209 +0,0 @@ -// -// EXTRuntimeExtensions.m -// extobjc -// -// Created by Justin Spahr-Summers on 2011-03-05. -// Copyright (C) 2012 Justin Spahr-Summers. -// Released under the MIT license. -// - -#import "EXTRuntimeExtensions.h" - -mtl_moa_propertyAttributes *mtl_moa_copyPropertyAttributes (objc_property_t property) { - const char * const attrString = property_getAttributes(property); - if (!attrString) { - fprintf(stderr, "ERROR: Could not get attribute string from property %s\n", property_getName(property)); - return NULL; - } - - if (attrString[0] != 'T') { - fprintf(stderr, "ERROR: Expected attribute string \"%s\" for property %s to start with 'T'\n", attrString, property_getName(property)); - return NULL; - } - - const char *typeString = attrString + 1; - const char *next = NSGetSizeAndAlignment(typeString, NULL, NULL); - if (!next) { - fprintf(stderr, "ERROR: Could not read past type in attribute string \"%s\" for property %s\n", attrString, property_getName(property)); - return NULL; - } - - size_t typeLength = next - typeString; - if (!typeLength) { - fprintf(stderr, "ERROR: Invalid type in attribute string \"%s\" for property %s\n", attrString, property_getName(property)); - return NULL; - } - - // allocate enough space for the structure and the type string (plus a NUL) - mtl_moa_propertyAttributes *attributes = calloc(1, sizeof(mtl_moa_propertyAttributes) + typeLength + 1); - if (!attributes) { - fprintf(stderr, "ERROR: Could not allocate mtl_moa_propertyAttributes structure for attribute string \"%s\" for property %s\n", attrString, property_getName(property)); - return NULL; - } - - // copy the type string - strncpy(attributes->type, typeString, typeLength); - attributes->type[typeLength] = '\0'; - - // if this is an object type, and immediately followed by a quoted string... - if (typeString[0] == *(@encode(id)) && typeString[1] == '"') { - // we should be able to extract a class name - const char *className = typeString + 2; - next = strchr(className, '"'); - - if (!next) { - fprintf(stderr, "ERROR: Could not read class name in attribute string \"%s\" for property %s\n", attrString, property_getName(property)); - goto errorOut; - } - - if (className != next) { - size_t classNameLength = next - className; - char trimmedName[classNameLength + 1]; - - strncpy(trimmedName, className, classNameLength); - trimmedName[classNameLength] = '\0'; - - // attempt to look up the class in the runtime - attributes->objectClass = objc_getClass(trimmedName); - } - } - - if (*next != '\0') { - // skip past any junk before the first flag - next = strchr(next, ','); - } - - while (next && *next == ',') { - char flag = next[1]; - next += 2; - - switch (flag) { - case '\0': - break; - - case 'R': - attributes->readonly = YES; - break; - - case 'C': - attributes->memoryManagementPolicy = mtl_moa_propertyMemoryManagementPolicyCopy; - break; - - case '&': - attributes->memoryManagementPolicy = mtl_moa_propertyMemoryManagementPolicyRetain; - break; - - case 'N': - attributes->nonatomic = YES; - break; - - case 'G': - case 'S': - { - const char *nextFlag = strchr(next, ','); - SEL name = NULL; - - if (!nextFlag) { - // assume that the rest of the string is the selector - const char *selectorString = next; - next = ""; - - name = sel_registerName(selectorString); - } else { - size_t selectorLength = nextFlag - next; - if (!selectorLength) { - fprintf(stderr, "ERROR: Found zero length selector name in attribute string \"%s\" for property %s\n", attrString, property_getName(property)); - goto errorOut; - } - - char selectorString[selectorLength + 1]; - - strncpy(selectorString, next, selectorLength); - selectorString[selectorLength] = '\0'; - - name = sel_registerName(selectorString); - next = nextFlag; - } - - if (flag == 'G') - attributes->getter = name; - else - attributes->setter = name; - } - - break; - - case 'D': - attributes->dynamic = YES; - attributes->ivar = NULL; - break; - - case 'V': - // assume that the rest of the string (if present) is the ivar name - if (*next == '\0') { - // if there's nothing there, let's assume this is dynamic - attributes->ivar = NULL; - } else { - attributes->ivar = next; - next = ""; - } - - break; - - case 'W': - attributes->weak = YES; - break; - - case 'P': - attributes->canBeCollected = YES; - break; - - case 't': - fprintf(stderr, "ERROR: Old-style type encoding is unsupported in attribute string \"%s\" for property %s\n", attrString, property_getName(property)); - - // skip over this type encoding - while (*next != ',' && *next != '\0') - ++next; - - break; - - default: - fprintf(stderr, "ERROR: Unrecognized attribute string flag '%c' in attribute string \"%s\" for property %s\n", flag, attrString, property_getName(property)); - } - } - - if (next && *next != '\0') { - fprintf(stderr, "Warning: Unparsed data \"%s\" in attribute string \"%s\" for property %s\n", next, attrString, property_getName(property)); - } - - if (!attributes->getter) { - // use the property name as the getter by default - attributes->getter = sel_registerName(property_getName(property)); - } - - if (!attributes->setter) { - const char *propertyName = property_getName(property); - size_t propertyNameLength = strlen(propertyName); - - // we want to transform the name to setProperty: style - size_t setterLength = propertyNameLength + 4; - - char setterName[setterLength + 1]; - strncpy(setterName, "set", 3); - strncpy(setterName + 3, propertyName, propertyNameLength); - - // capitalize property name for the setter - setterName[3] = (char)toupper(setterName[3]); - - setterName[setterLength - 1] = ':'; - setterName[setterLength] = '\0'; - - attributes->setter = sel_registerName(setterName); - } - - return attributes; - -errorOut: - free(attributes); - return NULL; -} diff --git a/MTLManagedObjectAdapter/extobjc/EXTScope.h b/MTLManagedObjectAdapter/extobjc/EXTScope.h deleted file mode 100644 index b66b13c..0000000 --- a/MTLManagedObjectAdapter/extobjc/EXTScope.h +++ /dev/null @@ -1,99 +0,0 @@ -// -// EXTScope.h -// extobjc -// -// Created by Justin Spahr-Summers on 2011-05-04. -// Copyright (C) 2012 Justin Spahr-Summers. -// Released under the MIT license. -// - -#import "metamacros.h" - -/** - * \@onExit defines some code to be executed when the current scope exits. The - * code must be enclosed in braces and terminated with a semicolon, and will be - * executed regardless of how the scope is exited, including from exceptions, - * \c goto, \c return, \c break, and \c continue. - * - * Provided code will go into a block to be executed later. Keep this in mind as - * it pertains to memory management, restrictions on assignment, etc. Because - * the code is used within a block, \c return is a legal (though perhaps - * confusing) way to exit the cleanup block early. - * - * Multiple \@onExit statements in the same scope are executed in reverse - * lexical order. This helps when pairing resource acquisition with \@onExit - * statements, as it guarantees teardown in the opposite order of acquisition. - * - * @note This statement cannot be used within scopes defined without braces - * (like a one line \c if). In practice, this is not an issue, since \@onExit is - * a useless construct in such a case anyways. - */ -#define onExit \ - try {} @finally {} \ - __strong mtl_moa_cleanupBlock_t metamacro_concat(mtl_moa_exitBlock_, __LINE__) __attribute__((cleanup(mtl_moa_executeCleanupBlock), unused)) = ^ - -/** - * Creates \c __weak shadow variables for each of the variables provided as - * arguments, which can later be made strong again with #strongify. - * - * This is typically used to weakly reference variables in a block, but then - * ensure that the variables stay alive during the actual execution of the block - * (if they were live upon entry). - * - * See #strongify for an example of usage. - */ -#define weakify(...) \ - try {} @finally {} \ - metamacro_foreach_cxt(mtl_moa_weakify_,, __weak, __VA_ARGS__) - -/** - * Like #weakify, but uses \c __unsafe_unretained instead, for targets or - * classes that do not support weak references. - */ -#define unsafeify(...) \ - try {} @finally {} \ - metamacro_foreach_cxt(mtl_moa_weakify_,, __unsafe_unretained, __VA_ARGS__) - -/** - * Strongly references each of the variables provided as arguments, which must - * have previously been passed to #weakify. - * - * The strong references created will shadow the original variable names, such - * that the original names can be used without issue (and a significantly - * reduced risk of retain cycles) in the current scope. - * - * @code - - id foo = [[NSObject alloc] init]; - id bar = [[NSObject alloc] init]; - - @weakify(foo, bar); - - // this block will not keep 'foo' or 'bar' alive - BOOL (^matchesFooOrBar)(id) = ^ BOOL (id obj){ - // but now, upon entry, 'foo' and 'bar' will stay alive until the block has - // finished executing - @strongify(foo, bar); - - return [foo isEqual:obj] || [bar isEqual:obj]; - }; - - * @endcode - */ -#define strongify(...) \ - try {} @finally {} \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Wshadow\"") \ - metamacro_foreach(mtl_moa_strongify_,, __VA_ARGS__) \ - _Pragma("clang diagnostic pop") - -/*** implementation details follow ***/ -typedef void (^mtl_moa_cleanupBlock_t)(); - -void mtl_moa_executeCleanupBlock (__strong mtl_moa_cleanupBlock_t *block); - -#define mtl_moa_weakify_(INDEX, CONTEXT, VAR) \ - CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR); - -#define mtl_moa_strongify_(INDEX, VAR) \ - __strong __typeof__(VAR) VAR = metamacro_concat(VAR, _weak_); diff --git a/MTLManagedObjectAdapter/extobjc/EXTScope.m b/MTLManagedObjectAdapter/extobjc/EXTScope.m deleted file mode 100644 index 82899ca..0000000 --- a/MTLManagedObjectAdapter/extobjc/EXTScope.m +++ /dev/null @@ -1,15 +0,0 @@ -// -// EXTScope.m -// extobjc -// -// Created by Justin Spahr-Summers on 2011-05-04. -// Copyright (C) 2012 Justin Spahr-Summers. -// Released under the MIT license. -// - -#import "EXTScope.h" - -void mtl_moa_executeCleanupBlock (__strong mtl_moa_cleanupBlock_t *block) { - (*block)(); -} - diff --git a/MTLManagedObjectAdapter/extobjc/metamacros.h b/MTLManagedObjectAdapter/extobjc/metamacros.h deleted file mode 100644 index 77a77b5..0000000 --- a/MTLManagedObjectAdapter/extobjc/metamacros.h +++ /dev/null @@ -1,666 +0,0 @@ -/** - * Macros for metaprogramming - * ExtendedC - * - * Copyright (C) 2012 Justin Spahr-Summers - * Released under the MIT license - */ - -#ifndef EXTC_METAMACROS_H -#define EXTC_METAMACROS_H - -/** - * Executes one or more expressions (which may have a void type, such as a call - * to a function that returns no value) and always returns true. - */ -#define metamacro_exprify(...) \ - ((__VA_ARGS__), true) - -/** - * Returns a string representation of VALUE after full macro expansion. - */ -#define metamacro_stringify(VALUE) \ - metamacro_stringify_(VALUE) - -/** - * Returns A and B concatenated after full macro expansion. - */ -#define metamacro_concat(A, B) \ - metamacro_concat_(A, B) - -/** - * Returns the Nth variadic argument (starting from zero). At least - * N + 1 variadic arguments must be given. N must be between zero and twenty, - * inclusive. - */ -#define metamacro_at(N, ...) \ - metamacro_concat(metamacro_at, N)(__VA_ARGS__) - -/** - * Returns the number of arguments (up to twenty) provided to the macro. At - * least one argument must be provided. - * - * Inspired by P99: http://p99.gforge.inria.fr - */ -#define metamacro_argcount(...) \ - metamacro_at(20, __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) - -/** - * Identical to #metamacro_foreach_cxt, except that no CONTEXT argument is - * given. Only the index and current argument will thus be passed to MACRO. - */ -#define metamacro_foreach(MACRO, SEP, ...) \ - metamacro_foreach_cxt(metamacro_foreach_iter, SEP, MACRO, __VA_ARGS__) - -/** - * For each consecutive variadic argument (up to twenty), MACRO is passed the - * zero-based index of the current argument, CONTEXT, and then the argument - * itself. The results of adjoining invocations of MACRO are then separated by - * SEP. - * - * Inspired by P99: http://p99.gforge.inria.fr - */ -#define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \ - metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__) - -/** - * Identical to #metamacro_foreach_cxt. This can be used when the former would - * fail due to recursive macro expansion. - */ -#define metamacro_foreach_cxt_recursive(MACRO, SEP, CONTEXT, ...) \ - metamacro_concat(metamacro_foreach_cxt_recursive, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__) - -/** - * In consecutive order, appends each variadic argument (up to twenty) onto - * BASE. The resulting concatenations are then separated by SEP. - * - * This is primarily useful to manipulate a list of macro invocations into instead - * invoking a different, possibly related macro. - */ -#define metamacro_foreach_concat(BASE, SEP, ...) \ - metamacro_foreach_cxt(metamacro_foreach_concat_iter, SEP, BASE, __VA_ARGS__) - -/** - * Iterates COUNT times, each time invoking MACRO with the current index - * (starting at zero) and CONTEXT. The results of adjoining invocations of MACRO - * are then separated by SEP. - * - * COUNT must be an integer between zero and twenty, inclusive. - */ -#define metamacro_for_cxt(COUNT, MACRO, SEP, CONTEXT) \ - metamacro_concat(metamacro_for_cxt, COUNT)(MACRO, SEP, CONTEXT) - -/** - * Returns the first argument given. At least one argument must be provided. - * - * This is useful when implementing a variadic macro, where you may have only - * one variadic argument, but no way to retrieve it (for example, because \c ... - * always needs to match at least one argument). - * - * @code - -#define varmacro(...) \ - metamacro_head(__VA_ARGS__) - - * @endcode - */ -#define metamacro_head(...) \ - metamacro_head_(__VA_ARGS__, 0) - -/** - * Returns every argument except the first. At least two arguments must be - * provided. - */ -#define metamacro_tail(...) \ - metamacro_tail_(__VA_ARGS__) - -/** - * Returns the first N (up to twenty) variadic arguments as a new argument list. - * At least N variadic arguments must be provided. - */ -#define metamacro_take(N, ...) \ - metamacro_concat(metamacro_take, N)(__VA_ARGS__) - -/** - * Removes the first N (up to twenty) variadic arguments from the given argument - * list. At least N variadic arguments must be provided. - */ -#define metamacro_drop(N, ...) \ - metamacro_concat(metamacro_drop, N)(__VA_ARGS__) - -/** - * Decrements VAL, which must be a number between zero and twenty, inclusive. - * - * This is primarily useful when dealing with indexes and counts in - * metaprogramming. - */ -#define metamacro_dec(VAL) \ - metamacro_at(VAL, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) - -/** - * Increments VAL, which must be a number between zero and twenty, inclusive. - * - * This is primarily useful when dealing with indexes and counts in - * metaprogramming. - */ -#define metamacro_inc(VAL) \ - metamacro_at(VAL, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) - -/** - * If A is equal to B, the next argument list is expanded; otherwise, the - * argument list after that is expanded. A and B must be numbers between zero - * and twenty, inclusive. Additionally, B must be greater than or equal to A. - * - * @code - -// expands to true -metamacro_if_eq(0, 0)(true)(false) - -// expands to false -metamacro_if_eq(0, 1)(true)(false) - - * @endcode - * - * This is primarily useful when dealing with indexes and counts in - * metaprogramming. - */ -#define metamacro_if_eq(A, B) \ - metamacro_concat(metamacro_if_eq, A)(B) - -/** - * Identical to #metamacro_if_eq. This can be used when the former would fail - * due to recursive macro expansion. - */ -#define metamacro_if_eq_recursive(A, B) \ - metamacro_concat(metamacro_if_eq_recursive, A)(B) - -/** - * Returns 1 if N is an even number, or 0 otherwise. N must be between zero and - * twenty, inclusive. - * - * For the purposes of this test, zero is considered even. - */ -#define metamacro_is_even(N) \ - metamacro_at(N, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1) - -/** - * Returns the logical NOT of B, which must be the number zero or one. - */ -#define metamacro_not(B) \ - metamacro_at(B, 1, 0) - -// IMPLEMENTATION DETAILS FOLLOW! -// Do not write code that depends on anything below this line. -#define metamacro_stringify_(VALUE) # VALUE -#define metamacro_concat_(A, B) A ## B -#define metamacro_foreach_iter(INDEX, MACRO, ARG) MACRO(INDEX, ARG) -#define metamacro_head_(FIRST, ...) FIRST -#define metamacro_tail_(FIRST, ...) __VA_ARGS__ -#define metamacro_consume_(...) -#define metamacro_expand_(...) __VA_ARGS__ - -// implemented from scratch so that metamacro_concat() doesn't end up nesting -#define metamacro_foreach_concat_iter(INDEX, BASE, ARG) metamacro_foreach_concat_iter_(BASE, ARG) -#define metamacro_foreach_concat_iter_(BASE, ARG) BASE ## ARG - -// metamacro_at expansions -#define metamacro_at0(...) metamacro_head(__VA_ARGS__) -#define metamacro_at1(_0, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at2(_0, _1, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at3(_0, _1, _2, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at4(_0, _1, _2, _3, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at5(_0, _1, _2, _3, _4, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at6(_0, _1, _2, _3, _4, _5, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at7(_0, _1, _2, _3, _4, _5, _6, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at8(_0, _1, _2, _3, _4, _5, _6, _7, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at9(_0, _1, _2, _3, _4, _5, _6, _7, _8, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at10(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at11(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at12(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at13(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at14(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at15(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at17(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at18(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at19(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, ...) metamacro_head(__VA_ARGS__) -#define metamacro_at20(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, ...) metamacro_head(__VA_ARGS__) - -// metamacro_foreach_cxt expansions -#define metamacro_foreach_cxt0(MACRO, SEP, CONTEXT) -#define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0) - -#define metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \ - metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) \ - SEP \ - MACRO(1, CONTEXT, _1) - -#define metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \ - metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \ - SEP \ - MACRO(2, CONTEXT, _2) - -#define metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ - metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \ - SEP \ - MACRO(3, CONTEXT, _3) - -#define metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ - metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ - SEP \ - MACRO(4, CONTEXT, _4) - -#define metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ - metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ - SEP \ - MACRO(5, CONTEXT, _5) - -#define metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ - metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ - SEP \ - MACRO(6, CONTEXT, _6) - -#define metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ - metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ - SEP \ - MACRO(7, CONTEXT, _7) - -#define metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ - metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ - SEP \ - MACRO(8, CONTEXT, _8) - -#define metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ - metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ - SEP \ - MACRO(9, CONTEXT, _9) - -#define metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ - metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ - SEP \ - MACRO(10, CONTEXT, _10) - -#define metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ - metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ - SEP \ - MACRO(11, CONTEXT, _11) - -#define metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ - metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ - SEP \ - MACRO(12, CONTEXT, _12) - -#define metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ - metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ - SEP \ - MACRO(13, CONTEXT, _13) - -#define metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ - metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ - SEP \ - MACRO(14, CONTEXT, _14) - -#define metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ - metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ - SEP \ - MACRO(15, CONTEXT, _15) - -#define metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ - metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ - SEP \ - MACRO(16, CONTEXT, _16) - -#define metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ - metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ - SEP \ - MACRO(17, CONTEXT, _17) - -#define metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ - metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ - SEP \ - MACRO(18, CONTEXT, _18) - -#define metamacro_foreach_cxt20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \ - metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ - SEP \ - MACRO(19, CONTEXT, _19) - -// metamacro_foreach_cxt_recursive expansions -#define metamacro_foreach_cxt_recursive0(MACRO, SEP, CONTEXT) -#define metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0) - -#define metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \ - metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) \ - SEP \ - MACRO(1, CONTEXT, _1) - -#define metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \ - metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \ - SEP \ - MACRO(2, CONTEXT, _2) - -#define metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ - metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \ - SEP \ - MACRO(3, CONTEXT, _3) - -#define metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ - metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ - SEP \ - MACRO(4, CONTEXT, _4) - -#define metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ - metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ - SEP \ - MACRO(5, CONTEXT, _5) - -#define metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ - metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ - SEP \ - MACRO(6, CONTEXT, _6) - -#define metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ - metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ - SEP \ - MACRO(7, CONTEXT, _7) - -#define metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ - metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ - SEP \ - MACRO(8, CONTEXT, _8) - -#define metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ - metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ - SEP \ - MACRO(9, CONTEXT, _9) - -#define metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ - metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ - SEP \ - MACRO(10, CONTEXT, _10) - -#define metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ - metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ - SEP \ - MACRO(11, CONTEXT, _11) - -#define metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ - metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ - SEP \ - MACRO(12, CONTEXT, _12) - -#define metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ - metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ - SEP \ - MACRO(13, CONTEXT, _13) - -#define metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ - metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ - SEP \ - MACRO(14, CONTEXT, _14) - -#define metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ - metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ - SEP \ - MACRO(15, CONTEXT, _15) - -#define metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ - metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ - SEP \ - MACRO(16, CONTEXT, _16) - -#define metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ - metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ - SEP \ - MACRO(17, CONTEXT, _17) - -#define metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ - metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ - SEP \ - MACRO(18, CONTEXT, _18) - -#define metamacro_foreach_cxt_recursive20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \ - metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ - SEP \ - MACRO(19, CONTEXT, _19) - -// metamacro_for_cxt expansions -#define metamacro_for_cxt0(MACRO, SEP, CONTEXT) -#define metamacro_for_cxt1(MACRO, SEP, CONTEXT) MACRO(0, CONTEXT) - -#define metamacro_for_cxt2(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt1(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(1, CONTEXT) - -#define metamacro_for_cxt3(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt2(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(2, CONTEXT) - -#define metamacro_for_cxt4(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt3(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(3, CONTEXT) - -#define metamacro_for_cxt5(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt4(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(4, CONTEXT) - -#define metamacro_for_cxt6(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt5(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(5, CONTEXT) - -#define metamacro_for_cxt7(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt6(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(6, CONTEXT) - -#define metamacro_for_cxt8(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt7(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(7, CONTEXT) - -#define metamacro_for_cxt9(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt8(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(8, CONTEXT) - -#define metamacro_for_cxt10(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt9(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(9, CONTEXT) - -#define metamacro_for_cxt11(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt10(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(10, CONTEXT) - -#define metamacro_for_cxt12(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt11(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(11, CONTEXT) - -#define metamacro_for_cxt13(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt12(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(12, CONTEXT) - -#define metamacro_for_cxt14(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt13(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(13, CONTEXT) - -#define metamacro_for_cxt15(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt14(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(14, CONTEXT) - -#define metamacro_for_cxt16(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt15(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(15, CONTEXT) - -#define metamacro_for_cxt17(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt16(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(16, CONTEXT) - -#define metamacro_for_cxt18(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt17(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(17, CONTEXT) - -#define metamacro_for_cxt19(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt18(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(18, CONTEXT) - -#define metamacro_for_cxt20(MACRO, SEP, CONTEXT) \ - metamacro_for_cxt19(MACRO, SEP, CONTEXT) \ - SEP \ - MACRO(19, CONTEXT) - -// metamacro_if_eq expansions -#define metamacro_if_eq0(VALUE) \ - metamacro_concat(metamacro_if_eq0_, VALUE) - -#define metamacro_if_eq0_0(...) __VA_ARGS__ metamacro_consume_ -#define metamacro_if_eq0_1(...) metamacro_expand_ -#define metamacro_if_eq0_2(...) metamacro_expand_ -#define metamacro_if_eq0_3(...) metamacro_expand_ -#define metamacro_if_eq0_4(...) metamacro_expand_ -#define metamacro_if_eq0_5(...) metamacro_expand_ -#define metamacro_if_eq0_6(...) metamacro_expand_ -#define metamacro_if_eq0_7(...) metamacro_expand_ -#define metamacro_if_eq0_8(...) metamacro_expand_ -#define metamacro_if_eq0_9(...) metamacro_expand_ -#define metamacro_if_eq0_10(...) metamacro_expand_ -#define metamacro_if_eq0_11(...) metamacro_expand_ -#define metamacro_if_eq0_12(...) metamacro_expand_ -#define metamacro_if_eq0_13(...) metamacro_expand_ -#define metamacro_if_eq0_14(...) metamacro_expand_ -#define metamacro_if_eq0_15(...) metamacro_expand_ -#define metamacro_if_eq0_16(...) metamacro_expand_ -#define metamacro_if_eq0_17(...) metamacro_expand_ -#define metamacro_if_eq0_18(...) metamacro_expand_ -#define metamacro_if_eq0_19(...) metamacro_expand_ -#define metamacro_if_eq0_20(...) metamacro_expand_ - -#define metamacro_if_eq1(VALUE) metamacro_if_eq0(metamacro_dec(VALUE)) -#define metamacro_if_eq2(VALUE) metamacro_if_eq1(metamacro_dec(VALUE)) -#define metamacro_if_eq3(VALUE) metamacro_if_eq2(metamacro_dec(VALUE)) -#define metamacro_if_eq4(VALUE) metamacro_if_eq3(metamacro_dec(VALUE)) -#define metamacro_if_eq5(VALUE) metamacro_if_eq4(metamacro_dec(VALUE)) -#define metamacro_if_eq6(VALUE) metamacro_if_eq5(metamacro_dec(VALUE)) -#define metamacro_if_eq7(VALUE) metamacro_if_eq6(metamacro_dec(VALUE)) -#define metamacro_if_eq8(VALUE) metamacro_if_eq7(metamacro_dec(VALUE)) -#define metamacro_if_eq9(VALUE) metamacro_if_eq8(metamacro_dec(VALUE)) -#define metamacro_if_eq10(VALUE) metamacro_if_eq9(metamacro_dec(VALUE)) -#define metamacro_if_eq11(VALUE) metamacro_if_eq10(metamacro_dec(VALUE)) -#define metamacro_if_eq12(VALUE) metamacro_if_eq11(metamacro_dec(VALUE)) -#define metamacro_if_eq13(VALUE) metamacro_if_eq12(metamacro_dec(VALUE)) -#define metamacro_if_eq14(VALUE) metamacro_if_eq13(metamacro_dec(VALUE)) -#define metamacro_if_eq15(VALUE) metamacro_if_eq14(metamacro_dec(VALUE)) -#define metamacro_if_eq16(VALUE) metamacro_if_eq15(metamacro_dec(VALUE)) -#define metamacro_if_eq17(VALUE) metamacro_if_eq16(metamacro_dec(VALUE)) -#define metamacro_if_eq18(VALUE) metamacro_if_eq17(metamacro_dec(VALUE)) -#define metamacro_if_eq19(VALUE) metamacro_if_eq18(metamacro_dec(VALUE)) -#define metamacro_if_eq20(VALUE) metamacro_if_eq19(metamacro_dec(VALUE)) - -// metamacro_if_eq_recursive expansions -#define metamacro_if_eq_recursive0(VALUE) \ - metamacro_concat(metamacro_if_eq_recursive0_, VALUE) - -#define metamacro_if_eq_recursive0_0(...) __VA_ARGS__ metamacro_consume_ -#define metamacro_if_eq_recursive0_1(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_2(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_3(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_4(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_5(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_6(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_7(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_8(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_9(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_10(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_11(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_12(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_13(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_14(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_15(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_16(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_17(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_18(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_19(...) metamacro_expand_ -#define metamacro_if_eq_recursive0_20(...) metamacro_expand_ - -#define metamacro_if_eq_recursive1(VALUE) metamacro_if_eq_recursive0(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive2(VALUE) metamacro_if_eq_recursive1(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive3(VALUE) metamacro_if_eq_recursive2(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive4(VALUE) metamacro_if_eq_recursive3(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive5(VALUE) metamacro_if_eq_recursive4(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive6(VALUE) metamacro_if_eq_recursive5(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive7(VALUE) metamacro_if_eq_recursive6(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive8(VALUE) metamacro_if_eq_recursive7(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive9(VALUE) metamacro_if_eq_recursive8(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive10(VALUE) metamacro_if_eq_recursive9(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive11(VALUE) metamacro_if_eq_recursive10(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive12(VALUE) metamacro_if_eq_recursive11(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive13(VALUE) metamacro_if_eq_recursive12(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive14(VALUE) metamacro_if_eq_recursive13(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive15(VALUE) metamacro_if_eq_recursive14(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive16(VALUE) metamacro_if_eq_recursive15(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive17(VALUE) metamacro_if_eq_recursive16(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive18(VALUE) metamacro_if_eq_recursive17(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive19(VALUE) metamacro_if_eq_recursive18(metamacro_dec(VALUE)) -#define metamacro_if_eq_recursive20(VALUE) metamacro_if_eq_recursive19(metamacro_dec(VALUE)) - -// metamacro_take expansions -#define metamacro_take0(...) -#define metamacro_take1(...) metamacro_head(__VA_ARGS__) -#define metamacro_take2(...) metamacro_head(__VA_ARGS__), metamacro_take1(metamacro_tail(__VA_ARGS__)) -#define metamacro_take3(...) metamacro_head(__VA_ARGS__), metamacro_take2(metamacro_tail(__VA_ARGS__)) -#define metamacro_take4(...) metamacro_head(__VA_ARGS__), metamacro_take3(metamacro_tail(__VA_ARGS__)) -#define metamacro_take5(...) metamacro_head(__VA_ARGS__), metamacro_take4(metamacro_tail(__VA_ARGS__)) -#define metamacro_take6(...) metamacro_head(__VA_ARGS__), metamacro_take5(metamacro_tail(__VA_ARGS__)) -#define metamacro_take7(...) metamacro_head(__VA_ARGS__), metamacro_take6(metamacro_tail(__VA_ARGS__)) -#define metamacro_take8(...) metamacro_head(__VA_ARGS__), metamacro_take7(metamacro_tail(__VA_ARGS__)) -#define metamacro_take9(...) metamacro_head(__VA_ARGS__), metamacro_take8(metamacro_tail(__VA_ARGS__)) -#define metamacro_take10(...) metamacro_head(__VA_ARGS__), metamacro_take9(metamacro_tail(__VA_ARGS__)) -#define metamacro_take11(...) metamacro_head(__VA_ARGS__), metamacro_take10(metamacro_tail(__VA_ARGS__)) -#define metamacro_take12(...) metamacro_head(__VA_ARGS__), metamacro_take11(metamacro_tail(__VA_ARGS__)) -#define metamacro_take13(...) metamacro_head(__VA_ARGS__), metamacro_take12(metamacro_tail(__VA_ARGS__)) -#define metamacro_take14(...) metamacro_head(__VA_ARGS__), metamacro_take13(metamacro_tail(__VA_ARGS__)) -#define metamacro_take15(...) metamacro_head(__VA_ARGS__), metamacro_take14(metamacro_tail(__VA_ARGS__)) -#define metamacro_take16(...) metamacro_head(__VA_ARGS__), metamacro_take15(metamacro_tail(__VA_ARGS__)) -#define metamacro_take17(...) metamacro_head(__VA_ARGS__), metamacro_take16(metamacro_tail(__VA_ARGS__)) -#define metamacro_take18(...) metamacro_head(__VA_ARGS__), metamacro_take17(metamacro_tail(__VA_ARGS__)) -#define metamacro_take19(...) metamacro_head(__VA_ARGS__), metamacro_take18(metamacro_tail(__VA_ARGS__)) -#define metamacro_take20(...) metamacro_head(__VA_ARGS__), metamacro_take19(metamacro_tail(__VA_ARGS__)) - -// metamacro_drop expansions -#define metamacro_drop0(...) __VA_ARGS__ -#define metamacro_drop1(...) metamacro_tail(__VA_ARGS__) -#define metamacro_drop2(...) metamacro_drop1(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop3(...) metamacro_drop2(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop4(...) metamacro_drop3(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop5(...) metamacro_drop4(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop6(...) metamacro_drop5(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop7(...) metamacro_drop6(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop8(...) metamacro_drop7(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop9(...) metamacro_drop8(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop10(...) metamacro_drop9(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop11(...) metamacro_drop10(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop12(...) metamacro_drop11(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop13(...) metamacro_drop12(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop14(...) metamacro_drop13(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop15(...) metamacro_drop14(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop16(...) metamacro_drop15(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop17(...) metamacro_drop16(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop18(...) metamacro_drop17(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop19(...) metamacro_drop18(metamacro_tail(__VA_ARGS__)) -#define metamacro_drop20(...) metamacro_drop19(metamacro_tail(__VA_ARGS__)) - -#endif diff --git a/README.md b/README.md index 65cef34..e75cdf4 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,6 @@ `MTLManagedObjectAdapter` is released under the MIT license. See [LICENSE.md](LICENSE.md). + +## 2xPer Note: +Did not figure out how to use "extobjc" subspec with Carthage, so this workspace does not build on its own. It works fine using as a Pod, as we define the Mantle/extobjc pod as dependency.