Skip to content

Instantly share code, notes, and snippets.

@nicerobot
Created January 2, 2012 14:21
Show Gist options
  • Save nicerobot/1550857 to your computer and use it in GitHub Desktop.
Save nicerobot/1550857 to your computer and use it in GitHub Desktop.
Variadic function and NSComparator example
/*
curl -kOs https://raw.github.com/gist/1550857/vac.m && cc -framework Cocoa -o vac vac.m && ./vac
For http://stackoverflow.com/questions/8693810/objective-c-possible-shorter-if-notation
Variadic function and NSComparator example.
*/
#import <Cocoa/Cocoa.h>
#import <stdarg.h>
#import <stdio.h>
// This is just a simple object equality comparator.
static NSComparator compareeq = ^(id obj1, id obj2) {
if (obj1 == obj2) {
return (NSComparisonResult)NSOrderedSame;
}
return (NSComparisonResult)NSOrderedDescending;
};
// This'll execute the above comparator to compare eq to each object in args.
NSComparisonResult comparatorV(NSComparator compare, NSObject *eq, va_list args) {
NSComparisonResult result;
NSObject *value;
do {
if (value = va_arg(args, NSObject*)) {
result = compare(eq,value);
}
} while (value && result == NSOrderedSame);
return (!value?NSOrderedDescending:NSOrderedSame);
}
// This test if eq is == to all the subsequent objects passed.
// The first parameter MUST not be nil and isn't used for comparisons.
// If any object passed is nil it'll end the comparison.
BOOL isEqualTo(NSObject* eq, ...) {
va_list args;
va_start(args, eq);
BOOL result = (NSOrderedSame != comparatorV(compareeq,eq,args));
va_end(args);
return result;
}
// This'll just test if each object passed is == [NSNull null].
// The first parameter MUST not be nil and isn't used for comparisons.
// If any object passed is nil it'll end the comparison.
BOOL isNSNull(NSObject *o, ...) {
NSNull *n = [NSNull null];
if (NSOrderedSame != compareeq(n,o)) return NO;
va_list args;
va_start(args, o);
BOOL result = (NSOrderedSame != comparatorV(compareeq,n,args));
va_end(args);
return result;
}
#define YN(p) (p?"PASS":"FAIL")
#define IS_NSNULL(p) printf("%s\n",YN(p == isNSNull(a,b,c,nil)))
#define ALL_ARE_NSNULL IS_NSNULL(YES)
#define ALL_ARE_NOT_NSNULL IS_NSNULL(NO)
#define IS_EQUAL(p) printf("%s\n",YN(p == isEqualTo(a,b,c,nil)))
#define ALL_ARE_EQUAL IS_EQUAL(YES)
#define ALL_ARE_NOT_EQUAL IS_EQUAL(NO)
int main(int argc, char* argv[]) {
NSObject *a,*b,*c;
{
a =[[NSObject alloc] init];
b =[[NSObject alloc] init];
c =[[NSObject alloc] init];
ALL_ARE_NOT_NSNULL;
} {
a =[NSNull null];
b =[[NSObject alloc] init];
c =[NSNull null];
ALL_ARE_NOT_NSNULL;
} {
a =[NSNull null];
b =[NSNull null];
c =[NSNull null];
ALL_ARE_NSNULL;
} {
a =[NSNull null];
b =[[NSObject alloc] init];
c =[[NSObject alloc] init];
ALL_ARE_NOT_NSNULL;
} {
a =[NSNull null];
b =[NSNull null];
c =[[NSObject alloc] init];
ALL_ARE_NOT_NSNULL;
} {
a =[NSNull null];
b =[[NSObject alloc] init];
c =nil;
ALL_ARE_NOT_NSNULL;
} {
a =[NSNull null];
b =[NSNull null];
c =nil;
ALL_ARE_NSNULL;
} {
a =[NSNull null];
b =nil;
c =[NSNull null]; // This'll never be tested because comparison stops with b.
ALL_ARE_NSNULL;
}
printf("\n");
{
a =[[NSObject alloc] init];
b =[[NSObject alloc] init];
c =[[NSObject alloc] init];
ALL_ARE_NOT_EQUAL;
} {
a =[NSNull null];
b =[[NSObject alloc] init];
c =[NSNull null];
ALL_ARE_NOT_EQUAL;
} {
a =[NSNull null];
b =[NSNull null];
c =[NSNull null];
ALL_ARE_EQUAL;
} {
a =b=c=[[NSObject alloc] init];
ALL_ARE_EQUAL;
} {
a =[NSNull null];
b =[[NSObject alloc] init];
c =[[NSObject alloc] init];
ALL_ARE_NOT_EQUAL;
} {
a =[NSNull null];
b =[NSNull null];
c =[[NSObject alloc] init];
ALL_ARE_NOT_EQUAL;
} {
a =[NSNull null];
b =[[NSObject alloc] init];
c =nil;
ALL_ARE_NOT_EQUAL;
} {
a =[NSNull null];
b =nil;
c =[NSNull null]; // This'll never be tested because comparison stops with b.
ALL_ARE_EQUAL;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment