jens@0: // jens@0: // CollectionUtils.m jens@0: // MYUtilities jens@0: // jens@0: // Created by Jens Alfke on 1/5/08. jens@0: // Copyright 2008 Jens Alfke. All rights reserved. jens@0: // jens@0: jens@0: #import "CollectionUtils.h" jens@0: #import "Test.h" jens@0: jens@0: jens@0: NSDictionary* _dictof(const struct _dictpair* pairs, size_t count) jens@0: { jens@0: CAssert(count<10000); jens@0: id objects[count], keys[count]; jens@0: size_t n = 0; jens@0: for( size_t i=0; ivalue ) { jens@0: objects[n] = pairs->value; jens@0: keys[n] = pairs->key; jens@0: n++; jens@0: } jens@0: } jens@0: return [NSDictionary dictionaryWithObjects: objects forKeys: keys count: n]; jens@0: } jens@0: jens@0: jens@0: NSMutableDictionary* _mdictof(const struct _dictpair* pairs, size_t count) jens@0: { jens@0: CAssert(count<10000); jens@0: id objects[count], keys[count]; jens@0: size_t n = 0; jens@0: for( size_t i=0; ivalue ) { jens@0: objects[n] = pairs->value; jens@0: keys[n] = pairs->key; jens@0: n++; jens@0: } jens@0: } jens@0: return [NSMutableDictionary dictionaryWithObjects: objects forKeys: keys count: n]; jens@0: } jens@0: jens@0: jens@0: BOOL $equal(id obj1, id obj2) // Like -isEqual: but works even if either/both are nil jens@0: { jens@0: if( obj1 ) jens@0: return obj2 && [obj1 isEqual: obj2]; jens@0: else jens@0: return obj2==nil; jens@0: } jens@0: jens@0: jens@0: NSValue* _box(const void *value, const char *encoding) jens@0: { jens@0: // file:///Developer/Documentation/DocSets/com.apple.ADC_Reference_Library.DeveloperTools.docset/Contents/Resources/Documents/documentation/DeveloperTools/gcc-4.0.1/gcc/Type-encoding.html jens@0: char e = encoding[0]; jens@0: if( e=='r' ) // ignore 'const' modifier jens@0: e = encoding[1]; jens@0: switch( e ) { jens@0: case 'c': return [NSNumber numberWithChar: *(char*)value]; jens@0: case 'C': return [NSNumber numberWithUnsignedChar: *(char*)value]; jens@0: case 's': return [NSNumber numberWithShort: *(short*)value]; jens@0: case 'S': return [NSNumber numberWithUnsignedShort: *(unsigned short*)value]; jens@0: case 'i': return [NSNumber numberWithInt: *(int*)value]; jens@0: case 'I': return [NSNumber numberWithUnsignedInt: *(unsigned int*)value]; jens@0: case 'l': return [NSNumber numberWithLong: *(long*)value]; jens@0: case 'L': return [NSNumber numberWithUnsignedLong: *(unsigned long*)value]; jens@0: case 'q': return [NSNumber numberWithLongLong: *(long long*)value]; jens@0: case 'Q': return [NSNumber numberWithUnsignedLongLong: *(unsigned long long*)value]; jens@0: case 'f': return [NSNumber numberWithFloat: *(float*)value]; jens@0: case 'd': return [NSNumber numberWithDouble: *(double*)value]; jens@0: case '*': return [NSString stringWithUTF8String: *(char**)value]; jens@0: case '@': return *(id*)value; jens@0: default: return [NSValue value: value withObjCType: encoding]; jens@0: } jens@0: } jens@0: jens@0: jens@0: id _cast( Class requiredClass, id object ) jens@0: { jens@0: if( object && ! [object isKindOfClass: requiredClass] ) jens@0: [NSException raise: NSInvalidArgumentException format: @"%@ required, but got %@ %p", jens@0: requiredClass,[object class],object]; jens@0: return object; jens@0: } jens@0: jens@0: id _castNotNil( Class requiredClass, id object ) jens@0: { jens@0: if( ! [object isKindOfClass: requiredClass] ) jens@0: [NSException raise: NSInvalidArgumentException format: @"%@ required, but got %@ %p", jens@0: requiredClass,[object class],object]; jens@0: return object; jens@0: } jens@0: jens@0: id _castIf( Class requiredClass, id object ) jens@0: { jens@0: if( object && ! [object isKindOfClass: requiredClass] ) jens@0: object = nil; jens@0: return object; jens@0: } jens@0: jens@0: NSArray* _castArrayOf(Class itemClass, NSArray *a) jens@0: { jens@0: id item; jens@0: foreach( item, $cast(NSArray,a) ) jens@0: _cast(itemClass,item); jens@0: return a; jens@0: } jens@0: jens@0: jens@0: void setObj( id *var, id value ) jens@0: { jens@0: if( value != *var ) { jens@0: [*var release]; jens@0: *var = [value retain]; jens@0: } jens@0: } jens@0: jens@0: BOOL ifSetObj( id *var, id value ) jens@0: { jens@0: if( value != *var && ![value isEqual: *var] ) { jens@0: [*var release]; jens@0: *var = [value retain]; jens@0: return YES; jens@0: } else { jens@0: return NO; jens@0: } jens@0: } jens@0: jens@0: jens@0: void setString( NSString **var, NSString *value ) jens@0: { jens@0: if( value != *var ) { jens@0: [*var release]; jens@0: *var = [value copy]; jens@0: } jens@0: } jens@0: jens@0: jens@0: BOOL ifSetString( NSString **var, NSString *value ) jens@0: { jens@0: if( value != *var && ![value isEqualToString: *var] ) { jens@0: [*var release]; jens@0: *var = [value copy]; jens@0: return YES; jens@0: } else { jens@0: return NO; jens@0: } jens@0: } jens@0: jens@0: jens@0: @implementation NSArray (MYUtils) jens@0: jens@0: - (BOOL) my_containsObjectIdenticalTo: (id)object jens@0: { jens@0: return [self indexOfObjectIdenticalTo: object] != NSNotFound; jens@0: } jens@0: jens@0: @end jens@0: jens@0: jens@0: #import "Test.h" jens@0: jens@0: TestCase(CollectionUtils) { jens@0: NSArray *a = $array(@"foo",@"bar",@"baz"); jens@0: //Log(@"a = %@",a); jens@0: NSArray *aa = [NSArray arrayWithObjects: @"foo",@"bar",@"baz",nil]; jens@0: CAssertEqual(a,aa); jens@0: jens@0: const char *cstr = "a C string"; jens@0: id o = $object(cstr); jens@0: //Log(@"o = %@",o); jens@0: CAssertEqual(o,@"a C string"); jens@0: jens@0: NSDictionary *d = $dict({@"int", $object(1)}, jens@0: {@"double", $object(-1.1)}, jens@0: {@"char", $object('x')}, jens@0: {@"ulong", $object(1234567UL)}, jens@0: {@"longlong",$object(987654321LL)}, jens@0: {@"cstr", $object(cstr)}); jens@0: //Log(@"d = %@",d); jens@0: NSDictionary *dd = [NSDictionary dictionaryWithObjectsAndKeys: jens@0: [NSNumber numberWithInt: 1], @"int", jens@0: [NSNumber numberWithDouble: -1.1], @"double", jens@0: [NSNumber numberWithChar: 'x'], @"char", jens@0: [NSNumber numberWithUnsignedLong: 1234567UL], @"ulong", jens@0: [NSNumber numberWithDouble: 987654321LL], @"longlong", jens@0: @"a C string", @"cstr", jens@0: nil]; jens@0: CAssertEqual(d,dd); jens@0: }