CollectionUtils.m
author Jens Alfke <jens@mooseyard.com>
Tue Apr 15 18:02:40 2008 -0700 (2008-04-15)
changeset 5 c9f2e0c7359a
parent 0 d84d25d6cdbb
child 7 59addced5e2a
permissions -rw-r--r--
Added some set utils.
     1 //
     2 //  CollectionUtils.m
     3 //  MYUtilities
     4 //
     5 //  Created by Jens Alfke on 1/5/08.
     6 //  Copyright 2008 Jens Alfke. All rights reserved.
     7 //
     8 
     9 #import "CollectionUtils.h"
    10 #import "Test.h"
    11 
    12 
    13 NSDictionary* _dictof(const struct _dictpair* pairs, size_t count)
    14 {
    15     CAssert(count<10000);
    16     id objects[count], keys[count];
    17     size_t n = 0;
    18     for( size_t i=0; i<count; i++,pairs++ ) {
    19         if( pairs->value ) {
    20             objects[n] = pairs->value;
    21             keys[n] = pairs->key;
    22             n++;
    23         }
    24     }
    25     return [NSDictionary dictionaryWithObjects: objects forKeys: keys count: n];
    26 }
    27 
    28 
    29 NSMutableDictionary* _mdictof(const struct _dictpair* pairs, size_t count)
    30 {
    31     CAssert(count<10000);
    32     id objects[count], keys[count];
    33     size_t n = 0;
    34     for( size_t i=0; i<count; i++,pairs++ ) {
    35         if( pairs->value ) {
    36             objects[n] = pairs->value;
    37             keys[n] = pairs->key;
    38             n++;
    39         }
    40     }
    41     return [NSMutableDictionary dictionaryWithObjects: objects forKeys: keys count: n];
    42 }
    43 
    44 
    45 BOOL $equal(id obj1, id obj2)      // Like -isEqual: but works even if either/both are nil
    46 {
    47     if( obj1 )
    48         return obj2 && [obj1 isEqual: obj2];
    49     else
    50         return obj2==nil;
    51 }
    52 
    53 
    54 NSValue* _box(const void *value, const char *encoding)
    55 {
    56     // file:///Developer/Documentation/DocSets/com.apple.ADC_Reference_Library.DeveloperTools.docset/Contents/Resources/Documents/documentation/DeveloperTools/gcc-4.0.1/gcc/Type-encoding.html
    57     char e = encoding[0];
    58     if( e=='r' )                // ignore 'const' modifier
    59         e = encoding[1];
    60     switch( e ) {
    61         case 'c':   return [NSNumber numberWithChar: *(char*)value];
    62         case 'C':   return [NSNumber numberWithUnsignedChar: *(char*)value];
    63         case 's':   return [NSNumber numberWithShort: *(short*)value];
    64         case 'S':   return [NSNumber numberWithUnsignedShort: *(unsigned short*)value];
    65         case 'i':   return [NSNumber numberWithInt: *(int*)value];
    66         case 'I':   return [NSNumber numberWithUnsignedInt: *(unsigned int*)value];
    67         case 'l':   return [NSNumber numberWithLong: *(long*)value];
    68         case 'L':   return [NSNumber numberWithUnsignedLong: *(unsigned long*)value];
    69         case 'q':   return [NSNumber numberWithLongLong: *(long long*)value];
    70         case 'Q':   return [NSNumber numberWithUnsignedLongLong: *(unsigned long long*)value];
    71         case 'f':   return [NSNumber numberWithFloat: *(float*)value];
    72         case 'd':   return [NSNumber numberWithDouble: *(double*)value];
    73         case '*':   return [NSString stringWithUTF8String: *(char**)value];
    74         case '@':   return *(id*)value;
    75         default:    return [NSValue value: value withObjCType: encoding];
    76     }
    77 }
    78 
    79 
    80 id _cast( Class requiredClass, id object )
    81 {
    82     if( object && ! [object isKindOfClass: requiredClass] )
    83         [NSException raise: NSInvalidArgumentException format: @"%@ required, but got %@ %p",
    84          requiredClass,[object class],object];
    85     return object;
    86 }
    87 
    88 id _castNotNil( Class requiredClass, id object )
    89 {
    90     if( ! [object isKindOfClass: requiredClass] )
    91         [NSException raise: NSInvalidArgumentException format: @"%@ required, but got %@ %p",
    92          requiredClass,[object class],object];
    93     return object;
    94 }
    95 
    96 id _castIf( Class requiredClass, id object )
    97 {
    98     if( object && ! [object isKindOfClass: requiredClass] )
    99         object = nil;
   100     return object;
   101 }
   102 
   103 NSArray* _castArrayOf(Class itemClass, NSArray *a)
   104 {
   105     id item;
   106     foreach( item, $cast(NSArray,a) )
   107         _cast(itemClass,item);
   108     return a;
   109 }
   110 
   111 
   112 void setObj( id *var, id value )
   113 {
   114     if( value != *var ) {
   115         [*var release];
   116         *var = [value retain];
   117     }
   118 }
   119 
   120 BOOL ifSetObj( id *var, id value )
   121 {
   122     if( value != *var && ![value isEqual: *var] ) {
   123         [*var release];
   124         *var = [value retain];
   125         return YES;
   126     } else {
   127         return NO;
   128     }
   129 }
   130 
   131 
   132 void setString( NSString **var, NSString *value )
   133 {
   134     if( value != *var ) {
   135         [*var release];
   136         *var = [value copy];
   137     }
   138 }
   139 
   140 
   141 BOOL ifSetString( NSString **var, NSString *value )
   142 {
   143     if( value != *var && ![value isEqualToString: *var] ) {
   144         [*var release];
   145         *var = [value copy];
   146         return YES;
   147     } else {
   148         return NO;
   149     }
   150 }
   151 
   152 
   153 @implementation NSArray (MYUtils)
   154 
   155 - (BOOL) my_containsObjectIdenticalTo: (id)object
   156 {
   157     return [self indexOfObjectIdenticalTo: object] != NSNotFound;
   158 }
   159 
   160 @end
   161 
   162 
   163 
   164 @implementation NSSet (MYUtils)
   165 + (NSSet*) my_unionOfSet: (NSSet*)set1 andSet: (NSSet*)set2
   166 {
   167     if( set1 == set2 || set2.count==0 )
   168         return set1;
   169     else if( set1.count==0 )
   170         return set2;
   171     else {
   172         NSMutableSet *result = [set1 mutableCopy];
   173         [result unionSet: set2];
   174         return [result autorelease];
   175     }
   176 }
   177 
   178 + (NSSet*) my_differenceOfSet: (NSSet*)set1 andSet: (NSSet*)set2
   179 {
   180     if( set1.count==0 || set2.count==0 )
   181         return set1;
   182     else if( set1==set2 )
   183         return [NSSet set];
   184     else {
   185         NSMutableSet *result = [set1 mutableCopy];
   186         [result minusSet: set2];
   187         return [result autorelease];
   188     }
   189 }
   190 @end
   191 
   192 
   193 
   194 #import "Test.h"
   195 
   196 TestCase(CollectionUtils) {
   197     NSArray *a = $array(@"foo",@"bar",@"baz");
   198     //Log(@"a = %@",a);
   199     NSArray *aa = [NSArray arrayWithObjects: @"foo",@"bar",@"baz",nil];
   200     CAssertEqual(a,aa);
   201     
   202     const char *cstr = "a C string";
   203     id o = $object(cstr);
   204     //Log(@"o = %@",o);
   205     CAssertEqual(o,@"a C string");
   206     
   207     NSDictionary *d = $dict({@"int",    $object(1)},
   208                             {@"double", $object(-1.1)},
   209                             {@"char",   $object('x')},
   210                             {@"ulong",  $object(1234567UL)},
   211                             {@"longlong",$object(987654321LL)},
   212                             {@"cstr",   $object(cstr)});
   213     //Log(@"d = %@",d);
   214     NSDictionary *dd = [NSDictionary dictionaryWithObjectsAndKeys:
   215                         [NSNumber numberWithInt: 1],                    @"int",
   216                         [NSNumber numberWithDouble: -1.1],              @"double",
   217                         [NSNumber numberWithChar: 'x'],                 @"char",
   218                         [NSNumber numberWithUnsignedLong: 1234567UL],   @"ulong",
   219                         [NSNumber numberWithDouble: 987654321LL],       @"longlong",
   220                         @"a C string",                                  @"cstr",
   221                         nil];
   222     CAssertEqual(d,dd);
   223 }