Index: src/OFArray.m ================================================================== --- src/OFArray.m +++ src/OFArray.m @@ -243,10 +243,40 @@ if (objs[i] == obj) return i; return SIZE_MAX; } + +- (BOOL)containsObject: (id)obj +{ + id *objs = [array cArray]; + size_t i, count = [array count]; + + if (objs == NULL) + return NO; + + for (i = 0; i < count; i++) + if ([objs[i] isEqual: obj]) + return YES; + + return NO; +} + +- (BOOL)containsObjectIdenticalTo: (id)obj +{ + id *objs = [array cArray]; + size_t i, count = [array count]; + + if (objs == NULL) + return NO; + + for (i = 0; i < count; i++) + if (objs[i] == obj) + return YES; + + return NO; +} - (id)firstObject { id *first = [array firstItem]; Index: src/OFCollection.h ================================================================== --- src/OFCollection.h +++ src/OFCollection.h @@ -31,6 +31,17 @@ /** * \returns An OFEnumerator to enumerate through all objects of the collection */ - (OFEnumerator*)objectEnumerator; + +/** + * \return A boolean whether the collection contains the specified object. + */ +- (BOOL)containsObject: (id)obj; + +/** + * \return A boolean whether the collection contains an object with the + * specified address. + */ +- (BOOL)containsObjectIdenticalTo: (id)obj; @end Index: src/OFDictionary.m ================================================================== --- src/OFDictionary.m +++ src/OFDictionary.m @@ -519,17 +519,47 @@ if ([dict count] != count) return NO; for (i = 0; i < size; i++) - if (data[i] != NULL && data[i]!= DELETED && + if (data[i] != NULL && data[i] != DELETED && ![[dict objectForKey: data[i]->key] isEqual: data[i]->object]) return NO; return YES; } + +- (BOOL)containsObject: (id)obj +{ + uint32_t i; + + if (count == 0) + return NO; + + for (i = 0; i < size; i++) + if (data[i] != NULL && data[i] != DELETED && + [data[i]->object isEqual: obj]) + return YES; + + return NO; +} + +- (BOOL)containsObjectIdenticalTo: (id)obj +{ + uint32_t i; + + if (count == 0) + return NO; + + for (i = 0; i < size; i++) + if (data[i] != NULL && data[i] != DELETED && + data[i]->object == obj) + return YES; + + return NO; +} - (int)countByEnumeratingWithState: (of_fast_enumeration_state_t*)state objects: (id*)objects count: (int)count_ { Index: src/OFList.m ================================================================== --- src/OFList.m +++ src/OFList.m @@ -204,10 +204,38 @@ /* One is bigger than the other although we checked the count */ assert(iter == NULL && iter2 == NULL); return YES; } + +- (BOOL)containsObject: (id)obj +{ + of_list_object_t *iter; + + if (count == 0) + return NO; + + for (iter = firstListObject; iter != NULL; iter = iter->next) + if ([iter->object isEqual: obj]) + return YES; + + return NO; +} + +- (BOOL)containsObjectIdenticalTo: (id)obj +{ + of_list_object_t *iter; + + if (count == 0) + return NO; + + for (iter = firstListObject; iter != NULL; iter = iter->next) + if (iter->object == obj) + return YES; + + return NO; +} - copy { OFList *new = [[OFList alloc] init]; of_list_object_t *iter, *o, *prev; Index: tests/OFArrayTests.m ================================================================== --- tests/OFArrayTests.m +++ tests/OFArrayTests.m @@ -77,10 +77,19 @@ [[a[0] objectAtIndex: 2] isEqual: c_ary[2]] && [[a[1] objectAtIndex: 0] isEqual: c_ary[0]] && [[a[1] objectAtIndex: 1] isEqual: c_ary[1]] && [[a[1] objectAtIndex: 2] isEqual: c_ary[2]]) + TEST(@"-[containsObject:]", + [a[0] containsObject: c_ary[1]] == YES && + [a[0] containsObject: @"nonexistant"] == NO) + + TEST(@"-[containsObject:]", + [a[0] containsObjectIdenticalTo: c_ary[1]] == YES && + [a[0] containsObjectIdenticalTo: + [OFString stringWithString: c_ary[1]]] == NO) + TEST(@"-[indexOfObject:]", [a[0] indexOfObject: c_ary[1]] == 1) TEST(@"-[indexOfObjectIdenticalTo:]", [a[1] indexOfObjectIdenticalTo: c_ary[1]] == 1) Index: tests/OFDictionaryTests.m ================================================================== --- tests/OFDictionaryTests.m +++ tests/OFDictionaryTests.m @@ -50,10 +50,19 @@ TEST(@"-[objectForKey:]", [[dict objectForKey: keys[0]] isEqual: values[0]] && [[dict objectForKey: keys[1]] isEqual: values[1]] && [dict objectForKey: @"key3"] == nil) + TEST(@"-[containsObject:]", + [dict containsObject: values[0]] == YES && + [dict containsObject: @"nonexistant"] == NO) + + TEST(@"-[containsObjectIdenticalTo:]", + [dict containsObjectIdenticalTo: values[0]] == YES && + [dict containsObjectIdenticalTo: + [OFString stringWithString: values[0]]] == NO) + TEST(@"-[description]", [[dict description] isEqual: @"{key1 = value1; key2 = value2}"]) TEST(@"-[keyEnumerator]", (key_enum = [dict keyEnumerator])) TEST(@"-[objectEnumerator]", (obj_enum = [dict objectEnumerator])) Index: tests/OFListTests.m ================================================================== --- tests/OFListTests.m +++ tests/OFListTests.m @@ -75,10 +75,19 @@ afterListObject: [list firstListObject]->next] && [[list lastListObject]->object isEqual: strings[2]]) TEST(@"-[count]", [list count] == 3) + TEST(@"-[containsObject:]", + [list containsObject: strings[1]] == YES && + [list containsObject: @"nonexistant"] == NO) + + TEST(@"-[containsObjectIdenticalTo:]", + [list containsObjectIdenticalTo: strings[1]] == YES && + [list containsObjectIdenticalTo: + [OFString stringWithString: strings[1]]] == NO) + TEST(@"-[copy]", (list = [[list copy] autorelease]) && [[list firstListObject]->object isEqual: strings[0]] && [[list firstListObject]->next->object isEqual: strings[1]] && [[list lastListObject]->object isEqual: strings[2]])