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

Reply via email to