Author: thebeing Date: Wed Mar 9 14:19:35 2016 New Revision: 39493 URL: http://svn.gna.org/viewcvs/gnustep?rev=39493&view=rev Log: Implement [NSPredicate predicateWithBlock:].
Fixes https://savannah.gnu.org/bugs/?46418 Modified: libs/base/trunk/ChangeLog libs/base/trunk/Headers/Foundation/NSPredicate.h libs/base/trunk/Source/NSPredicate.m libs/base/trunk/Tests/base/NSPredicate/basic.m Modified: libs/base/trunk/ChangeLog URL: http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/ChangeLog?rev=39493&r1=39492&r2=39493&view=diff ============================================================================== --- libs/base/trunk/ChangeLog (original) +++ libs/base/trunk/ChangeLog Wed Mar 9 14:19:35 2016 @@ -1,3 +1,10 @@ +2016-03-09 Niels Grewe <[email protected]> + + * Headers/Foundation/NSPredicate.h + * Source/NSPredicate.m + * Tests/base/NSPredicate/basic.m: + Implementation and tests for +predicateWithBlock: + 2016-03-09 Richard Frith-Macdonald <[email protected]> * Source\NSSocketPortNameServer.m: Modified: libs/base/trunk/Headers/Foundation/NSPredicate.h URL: http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Headers/Foundation/NSPredicate.h?rev=39493&r1=39492&r2=39493&view=diff ============================================================================== --- libs/base/trunk/Headers/Foundation/NSPredicate.h (original) +++ libs/base/trunk/Headers/Foundation/NSPredicate.h Wed Mar 9 14:19:35 2016 @@ -30,10 +30,15 @@ #import <Foundation/NSObject.h> #import <Foundation/NSArray.h> +#import <Foundation/NSDictionary.h> #import <Foundation/NSSet.h> #if defined(__cplusplus) extern "C" { +#endif + +#if OS_API_VERSION(MAC_OS_X_VERSION_10_6, GS_API_LATEST) +DEFINE_BLOCK_TYPE(GSBlockPredicateBlock, BOOL, id, GS_GENERIC_CLASS(NSDictionary,NSString*,id)*); #endif @interface NSPredicate : NSObject <NSCoding, NSCopying> @@ -44,10 +49,13 @@ + (NSPredicate *) predicateWithFormat: (NSString *)format arguments: (va_list)args; + (NSPredicate *) predicateWithValue: (BOOL)value; - +#if OS_API_VERSION(MAC_OS_X_VERSION_10_6, GS_API_LATEST) ++ (NSPredicate *) predicateWithBlock: (GSBlockPredicateBlock)block; +#endif - (BOOL) evaluateWithObject: (id)object; - (NSString *) predicateFormat; -- (NSPredicate *) predicateWithSubstitutionVariables: (NSDictionary *)variables; +- (NSPredicate *) predicateWithSubstitutionVariables: + (GS_GENERIC_CLASS(NSDictionary,NSString*,id)*)variables; @end @@ -84,4 +92,4 @@ #endif #endif /* 100400 */ -#endif /* __NSPredicate_h_GNUSTEP_BASE_INCLUDE */ +#endif /* __NSPredicate_h_GNUSTEP_BASE_INCLUDE */ Modified: libs/base/trunk/Source/NSPredicate.m URL: http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Source/NSPredicate.m?rev=39493&r1=39492&r2=39493&view=diff ============================================================================== --- libs/base/trunk/Source/NSPredicate.m (original) +++ libs/base/trunk/Source/NSPredicate.m Wed Mar 9 14:19:35 2016 @@ -141,7 +141,24 @@ } @end - +#if OS_API_VERSION(MAC_OS_X_VERSION_10_6, GS_API_LATEST) +@interface GSBlockPredicate : NSPredicate +{ + GSBlockPredicateBlock _block; +} + +- (instancetype) initWithBlock: (GSBlockPredicateBlock)block; +@end + + +@interface GSBoundBlockPredicate : GSBlockPredicate +{ + GS_GENERIC_CLASS(NSDictionary,NSString*,id)* _bindings; +} +- (instancetype) initWithBlock: (GSBlockPredicateBlock)block + bindings: (GS_GENERIC_CLASS(NSDictionary,NSString*,id)*)bindings; +@end +#endif @implementation NSPredicate @@ -359,6 +376,11 @@ // FIXME [self subclassResponsibility: _cmd]; return self; +} + ++ (NSPredicate*)predicateWithBlock: (GSBlockPredicateBlock)block +{ + return [[[GSBlockPredicate alloc] initWithBlock: block] autorelease]; } @end @@ -2591,5 +2613,82 @@ } } } - -@end +@end + + +#if OS_API_VERSION(MAC_OS_X_VERSION_10_6, GS_API_LATEST) + + +@implementation GSBlockPredicate + +- (instancetype) initWithBlock: (GSBlockPredicateBlock)block +{ + if (nil == (self = [super init])) + { + return nil; + } + _block = (GSBlockPredicateBlock)[(id)block retain]; + return self; +} + +- (instancetype) predicateWithSubstitutionVariables: + (GS_GENERIC_CLASS(NSDictionary,NSString*,id)*)variables +{ + return [[[GSBoundBlockPredicate alloc] initWithBlock: _block + bindings: variables] autorelease]; +} + +- (BOOL) evaluateWithObject: (id)object + substitutionVariables: (GS_GENERIC_CLASS(NSDictionary, + NSString*,id)*)variables +{ + return CALL_BLOCK(_block, object, variables); +} + +- (BOOL) evaluateWithObject: (id)object +{ + return [self evaluateWithObject: object + substitutionVariables: nil]; +} + +- (void) dealloc +{ + [(id)_block release]; + _block = NULL; + [super dealloc]; +} + +- (NSString*) predicateFormat +{ + return [NSString stringWithFormat: @"BLOCKPREDICATE(%p)", (void*)_block]; +} +@end + +@implementation GSBoundBlockPredicate + +- (instancetype) initWithBlock: (GSBlockPredicateBlock)block + bindings: (GS_GENERIC_CLASS(NSDictionary, + NSString*,id)*)bindings +{ + if (nil == (self = [super initWithBlock: block])) + { + return nil; + } + ASSIGN(_bindings, bindings); + return self; +} + +- (BOOL) evaluateWithObject: (id)object +{ + return [self evaluateWithObject: object + substitutionVariables: _bindings]; +} + +- (void) dealloc +{ + DESTROY(_bindings); + [super dealloc]; +} +@end + +#endif Modified: libs/base/trunk/Tests/base/NSPredicate/basic.m URL: http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Tests/base/NSPredicate/basic.m?rev=39493&r1=39492&r2=39493&view=diff ============================================================================== --- libs/base/trunk/Tests/base/NSPredicate/basic.m (original) +++ libs/base/trunk/Tests/base/NSPredicate/basic.m Wed Mar 9 14:19:35 2016 @@ -101,6 +101,33 @@ PASS([p evaluateWithObject: dict], "Any %%K == %%@"); } + +void +testBlock(NSDictionary* dict) +{ + START_SET("Block predicates"); + NSPredicate *p = nil; + NSPredicate *p2 = nil; +# if __has_feature(blocks) + p = [NSPredicate predicateWithBlock: ^BOOL(id obj, + GS_GENERIC_CLASS(NSDictionary,NSString*,id)* bindings){ + NSString *key = [bindings objectForKey: @"Key"]; + if (nil == key) + { + key = @"Record1"; + } + NSString *value = [[obj objectForKey: key] objectForKey: @"Name"]; + return [value isEqualToString: @"John"]; + }]; + PASS([p evaluateWithObject: dict], "BLOCKPREDICATE() without bindings"); + p2 = [p predicateWithSubstitutionVariables: + [NSDictionary dictionaryWithObjectsAndKeys: @"Record2", @"Key", nil]]; + PASS(![p2 evaluateWithObject: dict], "BLOCKPREDICATE() with bound variables"); +# else + SKIP("No blocks support in the compiler."); +# endif + END_SET("Block predicates"); +} int main() { NSArray *filtered; @@ -134,6 +161,7 @@ testInteger(dict); testFloat(dict); testAttregate(dict); + testBlock(dict); [dict release]; pitches = [NSArray arrayWithObjects: _______________________________________________ Gnustep-cvs mailing list [email protected] https://mail.gna.org/listinfo/gnustep-cvs
