mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 00:41:02 +00:00
Implement [NSPredicate predicateWithBlock:].
Fixes https://savannah.gnu.org/bugs/?46418 git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@39493 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
62d2bcbabc
commit
6e6ee05a80
4 changed files with 147 additions and 5 deletions
|
@ -1,3 +1,10 @@
|
|||
2016-03-09 Niels Grewe <niels.grewe@halbordnung.de>
|
||||
|
||||
* Headers/Foundation/NSPredicate.h
|
||||
* Source/NSPredicate.m
|
||||
* Tests/base/NSPredicate/basic.m:
|
||||
Implementation and tests for +predicateWithBlock:
|
||||
|
||||
2016-03-09 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source\NSSocketPortNameServer.m:
|
||||
|
|
|
@ -30,12 +30,17 @@
|
|||
|
||||
#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>
|
||||
|
||||
+ (NSPredicate *) predicateWithFormat: (NSString *)format, ...;
|
||||
|
@ -44,10 +49,13 @@ extern "C" {
|
|||
+ (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 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#endif /* 100400 */
|
||||
#endif /* __NSPredicate_h_GNUSTEP_BASE_INCLUDE */
|
||||
#endif /* __NSPredicate_h_GNUSTEP_BASE_INCLUDE */
|
||||
|
|
|
@ -141,7 +141,24 @@ extern void GSPropertyListMake(id,NSDictionary*,BOOL,BOOL,unsigned,id*);
|
|||
}
|
||||
@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
|
||||
|
||||
|
@ -361,6 +378,11 @@ extern void GSPropertyListMake(id,NSDictionary*,BOOL,BOOL,unsigned,id*);
|
|||
return self;
|
||||
}
|
||||
|
||||
+ (NSPredicate*)predicateWithBlock: (GSBlockPredicateBlock)block
|
||||
{
|
||||
return [[[GSBlockPredicate alloc] initWithBlock: block] autorelease];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation GSTruePredicate
|
||||
|
@ -2591,5 +2613,82 @@ GSICUStringMatchesRegex(NSString *string, NSString *regex, NSStringCompareOption
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@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
|
||||
|
|
|
@ -101,6 +101,33 @@ testAttregate(NSDictionary *dict)
|
|||
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 @@ int main()
|
|||
testInteger(dict);
|
||||
testFloat(dict);
|
||||
testAttregate(dict);
|
||||
testBlock(dict);
|
||||
[dict release];
|
||||
|
||||
pitches = [NSArray arrayWithObjects:
|
||||
|
|
Loading…
Reference in a new issue