1994-11-04 16:29:24 +00:00
|
|
|
|
/* Implementation for Objective-C Collection object
|
1996-04-17 16:58:44 +00:00
|
|
|
|
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-04-17 20:17:45 +00:00
|
|
|
|
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
1994-11-04 16:29:24 +00:00
|
|
|
|
Date: May 1993
|
|
|
|
|
|
1996-05-12 00:56:10 +00:00
|
|
|
|
This file is part of the GNUstep Base Library.
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
|
|
|
License along with this library; if not, write to the Free
|
|
|
|
|
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
*/
|
|
|
|
|
|
1997-11-06 00:51:23 +00:00
|
|
|
|
#include <config.h>
|
1996-04-17 15:23:00 +00:00
|
|
|
|
#include <gnustep/base/Collection.h>
|
|
|
|
|
#include <gnustep/base/CollectionPrivate.h>
|
1994-11-04 16:29:24 +00:00
|
|
|
|
#include <stdarg.h>
|
1996-04-17 15:23:00 +00:00
|
|
|
|
#include <gnustep/base/Bag.h> /* for -contentsEqual: */
|
|
|
|
|
#include <gnustep/base/Array.h> /* for -safeWithElementsCall: */
|
|
|
|
|
#include <gnustep/base/Coder.h>
|
|
|
|
|
#include <gnustep/base/NSString.h>
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
@implementation Enumerator
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- initWithCollection: coll
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1997-11-12 15:37:27 +00:00
|
|
|
|
self = [super init];
|
|
|
|
|
if (self)
|
|
|
|
|
{
|
|
|
|
|
collection = [coll retain];
|
|
|
|
|
enum_state = [coll newEnumState];
|
|
|
|
|
}
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- nextObject
|
1995-04-05 16:02:08 +00:00
|
|
|
|
{
|
1996-03-03 00:33:24 +00:00
|
|
|
|
return [collection nextObjectWithEnumState: &enum_state];
|
1995-04-05 16:02:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-03-12 19:55:07 +00:00
|
|
|
|
- (void) dealloc
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-03-03 00:33:24 +00:00
|
|
|
|
[collection freeEnumState: &enum_state];
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[collection release];
|
1997-11-12 15:37:27 +00:00
|
|
|
|
[super dealloc];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
@end
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
@implementation ConstantCollection
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
|
|
|
|
// INITIALIZING AND RELEASING;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- init
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
return [self initWithObjects: NULL count: 0];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
// This is the designated initializer of this class;
|
|
|
|
|
- initWithObjects: (id*)objc count: (unsigned)c
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[self subclassResponsibility: _cmd];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- initWithObjects: firstObject, ...
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
va_list ap;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
va_start(ap, firstObject);
|
|
|
|
|
self = [self initWithObjects:firstObject rest:ap];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
va_end(ap);
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
#define INITIAL_OBJECTS_SIZE 10
|
|
|
|
|
- initWithObjects: firstObject rest: (va_list)ap
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id *objects;
|
|
|
|
|
int i = 0;
|
|
|
|
|
int s = INITIAL_OBJECTS_SIZE;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
OBJC_MALLOC(objects, id, s);
|
|
|
|
|
if (firstObject != nil)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
objects[i++] = firstObject;
|
|
|
|
|
while ((objects[i++] = va_arg(ap, id)))
|
|
|
|
|
{
|
|
|
|
|
if (i >= s)
|
|
|
|
|
{
|
|
|
|
|
s *= 2;
|
|
|
|
|
OBJC_REALLOC(objects, id, s);
|
|
|
|
|
}
|
|
|
|
|
}
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
self = [self initWithObjects:objects count:i-1];
|
|
|
|
|
OBJC_FREE(objects);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* Subclasses can override this for efficiency. For example, Array can
|
|
|
|
|
init itself with enough capacity to hold aCollection. */
|
|
|
|
|
- initWithContentsOf: (id <Collecting>)aCollection
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
int count = [aCollection count];
|
|
|
|
|
id contents_array[count];
|
|
|
|
|
id o;
|
|
|
|
|
int i = 0;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
FOR_COLLECTION(aCollection, o)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
contents_array[i++] = o;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION(aCollection);
|
|
|
|
|
return [self initWithObjects: contents_array count: count];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) dealloc
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* xxx Get rid of this since Set, Bag, Dictionary, and String
|
|
|
|
|
subclasses don't want to use it? */
|
|
|
|
|
[self _collectionReleaseContents];
|
|
|
|
|
[self _collectionDealloc];
|
|
|
|
|
[super dealloc];
|
|
|
|
|
}
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
|
|
|
|
// QUERYING COUNTS;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (BOOL) isEmpty
|
|
|
|
|
{
|
|
|
|
|
return ([self count] == 0);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
// Inefficient, so should be overridden in subclasses;
|
|
|
|
|
- (unsigned) count
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
unsigned n = 0;
|
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
FOR_COLLECTION(self, o)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
n++;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION(self);
|
|
|
|
|
return n;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
// Potentially inefficient, may be overridden in subclasses;
|
|
|
|
|
- (BOOL) containsObject: anObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id o;
|
|
|
|
|
FOR_COLLECTION (self, o)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if ([anObject isEqual: o])
|
|
|
|
|
return YES;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION(self);
|
|
|
|
|
return NO;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (unsigned) occurrencesOfObject: anObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
unsigned count = 0;
|
|
|
|
|
id o;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
FOR_COLLECTION(self, o)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if ([anObject isEqual: o])
|
|
|
|
|
count++;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION(self);
|
|
|
|
|
return count;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
|
|
|
|
// COMPARISON WITH OTHER COLLECTIONS;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (BOOL) isSubsetOf: (id <Collecting>)aCollection
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id o;
|
|
|
|
|
FOR_COLLECTION (self, o)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if (![aCollection containsObject: o])
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return NO;
|
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION (self);
|
|
|
|
|
return YES;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (BOOL) isDisjointFrom: (id <Collecting>)aCollection
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
// Use objc_msg_lookup here also;
|
|
|
|
|
BOOL flag = YES;
|
|
|
|
|
id o;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
FOR_COLLECTION_WHILE_TRUE(self, o, flag)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if (![aCollection containsObject: o])
|
1994-11-04 16:29:24 +00:00
|
|
|
|
flag = NO;
|
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION_WHILE_TRUE(self);
|
|
|
|
|
return !flag;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
// xxx How do we want to compare unordered contents?? ;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
- (int) compareContentsOf: (id <Collecting>)aCollection
|
|
|
|
|
{
|
|
|
|
|
if ([self contentsEqual:aCollection])
|
|
|
|
|
return 0;
|
|
|
|
|
if (self > aCollection)
|
|
|
|
|
return 1;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (BOOL) isEqual: anObject
|
|
|
|
|
{
|
|
|
|
|
if (self == anObject)
|
|
|
|
|
return YES;
|
1997-10-16 23:56:27 +00:00
|
|
|
|
if ( [self contentsEqual: anObject] )
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return YES;
|
|
|
|
|
else
|
|
|
|
|
return NO;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
// Deal with this in IndexedCollection also ;
|
|
|
|
|
// How do we want to compare collections? ;
|
|
|
|
|
- (int) compare: anObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if ([self isEqual:anObject])
|
|
|
|
|
return 0;
|
|
|
|
|
if (self > anObject)
|
|
|
|
|
return 1;
|
|
|
|
|
return -1;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (BOOL) contentsEqual: (id <Collecting>)aCollection
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id bag, o;
|
|
|
|
|
BOOL flag;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if ([self count] != [aCollection count])
|
|
|
|
|
return NO;
|
|
|
|
|
bag = [[Bag alloc] initWithContentsOf:aCollection];
|
|
|
|
|
flag = YES;
|
|
|
|
|
FOR_COLLECTION_WHILE_TRUE (self, o, flag)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if ([bag containsObject: o])
|
|
|
|
|
[bag removeObject: o];
|
|
|
|
|
else
|
1994-11-04 16:29:24 +00:00
|
|
|
|
flag = NO;
|
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION_WHILE_TRUE(self);
|
|
|
|
|
if ((!flag) || [bag count])
|
|
|
|
|
flag = NO;
|
|
|
|
|
else
|
|
|
|
|
flag = YES;
|
|
|
|
|
[bag release];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return flag;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
|
|
|
|
// PROPERTIES OF CONTENTS;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (BOOL) trueForAllObjectsByInvoking: (id <Invoking>)anInvocation
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
BOOL flag = YES;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id o;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
FOR_COLLECTION_WHILE_TRUE(self, o, flag)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[anInvocation invokeWithObject: o];
|
|
|
|
|
if (![anInvocation returnValueIsTrue])
|
1994-11-04 16:29:24 +00:00
|
|
|
|
flag = NO;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
}
|
|
|
|
|
END_FOR_COLLECTION_WHILE_TRUE(self);
|
|
|
|
|
return flag;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (BOOL) trueForAnyObjectsByInvoking: (id <Invoking>)anInvocation;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
BOOL flag = YES;
|
|
|
|
|
id o;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
FOR_COLLECTION_WHILE_TRUE(self, o, flag)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[anInvocation invokeWithObject: o];
|
|
|
|
|
if ([anInvocation returnValueIsTrue])
|
|
|
|
|
flag = NO;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION_WHILE_TRUE(self);
|
|
|
|
|
return !flag;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- detectObjectByInvoking: (id <Invoking>)anInvocation;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
BOOL flag = YES;
|
1996-03-18 13:44:21 +00:00
|
|
|
|
id detectedObject = nil;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
FOR_COLLECTION_WHILE_TRUE(self, o, flag)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-03-03 00:33:24 +00:00
|
|
|
|
[anInvocation invokeWithObject: o];
|
|
|
|
|
if ([anInvocation returnValueIsTrue])
|
1996-02-22 15:11:43 +00:00
|
|
|
|
{
|
|
|
|
|
flag = NO;
|
|
|
|
|
detectedObject = o;
|
|
|
|
|
}
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION_WHILE_TRUE(self);
|
|
|
|
|
if (flag)
|
|
|
|
|
return NO_OBJECT;
|
|
|
|
|
else
|
|
|
|
|
return detectedObject;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- maxObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-03-18 13:44:21 +00:00
|
|
|
|
id o, max = nil;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
BOOL firstTime = YES;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
|
|
|
|
FOR_COLLECTION(self, o)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
if (firstTime)
|
|
|
|
|
{
|
|
|
|
|
firstTime = NO;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
max = o;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if ([o compare: max] > 0)
|
|
|
|
|
max = o;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION(self);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return max;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- minObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-03-18 13:44:21 +00:00
|
|
|
|
id o, min = nil;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
BOOL firstTime = YES;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
|
|
|
|
FOR_COLLECTION(self, o)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
if (firstTime)
|
|
|
|
|
{
|
|
|
|
|
firstTime = NO;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
min = o;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if ([o compare: min] < 0)
|
|
|
|
|
min = o;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION(self);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return min;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* Consider adding:
|
|
|
|
|
- maxObjectByInvoking: (id <Invoking>)anInvocation;
|
|
|
|
|
- minObjectByInvoking: (id <Invoking>)anInvocation;
|
|
|
|
|
*/
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
|
|
|
|
// ENUMERATING;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (id <Enumerating>) objectEnumerator
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
return [[[Enumerator alloc] initWithCollection: self]
|
|
|
|
|
autorelease];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) withObjectsInvoke: (id <Invoking>)anInvocation
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id o;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
FOR_COLLECTION(self, o)
|
|
|
|
|
{
|
|
|
|
|
[anInvocation invokeWithObject: o];
|
|
|
|
|
}
|
|
|
|
|
END_FOR_COLLECTION(self);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) withObjectsInvoke: (id <Invoking>)anInvocation whileTrue:(BOOL *)flag;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id o;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
FOR_COLLECTION_WHILE_TRUE(self, o, *flag)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[anInvocation invokeWithObject: o];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION_WHILE_TRUE(self);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) makeObjectsPerform: (SEL)aSel
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id o;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
FOR_COLLECTION(self, o)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1998-09-28 20:38:02 +00:00
|
|
|
|
[o performSelector: aSel];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION(self);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) makeObjectsPerform: (SEL)aSel withObject: argObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id o;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
FOR_COLLECTION(self, o)
|
|
|
|
|
{
|
1998-09-28 20:38:02 +00:00
|
|
|
|
[o performSelector: aSel withObject: argObject];
|
1996-02-22 15:11:43 +00:00
|
|
|
|
}
|
|
|
|
|
END_FOR_COLLECTION(self);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
|
|
|
|
// FILTERED ENUMERATING;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) withObjectsTrueByInvoking: (id <Invoking>)testInvocation
|
|
|
|
|
invoke: (id <Invoking>)anInvocation
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id o;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
FOR_COLLECTION(self, o)
|
1996-02-13 01:55:34 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[testInvocation invokeWithObject: o];
|
|
|
|
|
if ([testInvocation returnValueIsTrue])
|
|
|
|
|
[anInvocation invokeWithObject: o];
|
1996-02-13 01:55:34 +00:00
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION(self);
|
1996-02-13 01:55:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) withObjectsFalseByInvoking: (id <Invoking>)testInvocation
|
|
|
|
|
invoke: (id <Invoking>)anInvocation
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id o;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
FOR_COLLECTION(self, o)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[testInvocation invokeWithObject: o];
|
|
|
|
|
if (![testInvocation returnValueIsTrue])
|
|
|
|
|
[anInvocation invokeWithObject: o];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION(self);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) withObjectsTransformedByInvoking: (id <Invoking>)transInvocation
|
|
|
|
|
invoke: (id <Invoking>)anInvocation
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
FOR_COLLECTION(self, o)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[transInvocation invokeWithObject: o];
|
|
|
|
|
[anInvocation invokeWithObject: [transInvocation objectReturnValue]];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION(self);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
|
|
|
|
// LOW-LEVEL ENUMERATING;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void*) newEnumState
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
return (void*)0;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- nextObjectWithEnumState: (void**)enumState;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[self subclassResponsibility: _cmd];
|
|
|
|
|
return NO;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) freeEnumState: (void**)enumState
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
*enumState = (void*)0;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
|
|
|
|
// COPYING;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- allocCopy
|
|
|
|
|
{
|
|
|
|
|
return NSCopyObject (self, 0, [self zone]);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
// the copy to be filled by -shallowCopyAs: etc... ;
|
|
|
|
|
- emptyCopy
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
// This will copy all instance vars;
|
|
|
|
|
// Subclasses will have to change instance vars like Array's _contents_array;
|
|
|
|
|
return [self allocCopy];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
// the copy to be filled by -shallowCopyAs: etc... ;
|
|
|
|
|
- emptyCopyAs: (Class)aCollectionClass
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if (aCollectionClass == [self species])
|
|
|
|
|
return [self emptyCopy];
|
|
|
|
|
else
|
|
|
|
|
return [[(id)aCollectionClass alloc] init];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- shallowCopy
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
return [self shallowCopyAs:[self species]];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- shallowCopyAs: (Class)aCollectionClass
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id newColl = [self emptyCopyAs:aCollectionClass];
|
|
|
|
|
//#warning fix this addContentsOf for ConstantCollection
|
|
|
|
|
[newColl addContentsOf:self];
|
|
|
|
|
return newColl;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* We can avoid the ugly [self safeWithElementsCall:doIt];
|
|
|
|
|
in -deepen with something like this instead.
|
|
|
|
|
This fits with a scheme in which we get rid of the -deepen method, an
|
|
|
|
|
idea that I like since calling deepen on an object that has not just
|
|
|
|
|
been -shallowCopy'ed can cause major memory leakage. */
|
|
|
|
|
- copyAs: (id <Collecting>)aCollectionClass
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id newColl = [self emptyCopyAs:aCollectionClass];
|
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
FOR_COLLECTION(self, o)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
//#warning fix this addObject for ConstantCollection
|
1997-09-01 21:59:51 +00:00
|
|
|
|
id n = [o copy];
|
|
|
|
|
[newColl addObject:n];
|
|
|
|
|
[n release];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION(self);
|
|
|
|
|
return newColl;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- species
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
return [self class];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
|
|
|
|
// EXTRAS;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
|
|
|
|
- (const char *) libobjectsLicense
|
|
|
|
|
{
|
|
|
|
|
const char *licenseString =
|
1996-02-22 15:11:43 +00:00
|
|
|
|
"Copyright (C) 1993,1994,1995,1996 Free Software Foundation, Inc.\n"
|
1994-11-04 16:29:24 +00:00
|
|
|
|
"\n"
|
1996-02-22 15:11:43 +00:00
|
|
|
|
"Chief Maintainer: Andrew McCallum <mccallum@gnu.ai.mit.edu>\n"
|
1994-11-04 16:29:24 +00:00
|
|
|
|
"\n"
|
1996-05-12 00:56:10 +00:00
|
|
|
|
"This object is part of the GNUstep Base Library.\n"
|
1994-11-04 16:29:24 +00:00
|
|
|
|
"\n"
|
|
|
|
|
"This library is free software; you can redistribute it and/or\n"
|
|
|
|
|
"modify it under the terms of the GNU Library General Public\n"
|
|
|
|
|
"License as published by the Free Software Foundation; either\n"
|
|
|
|
|
"version 2 of the License, or (at your option) any later version.\n"
|
|
|
|
|
"\n"
|
|
|
|
|
"This library is distributed in the hope that it will be useful,\n"
|
|
|
|
|
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
|
|
|
|
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
|
|
|
|
|
"Library General Public License for more details.\n"
|
|
|
|
|
"\n"
|
|
|
|
|
"You should have received a copy of the GNU Library General Public\n"
|
|
|
|
|
"License along with this library; if not, write to the Free\n"
|
|
|
|
|
"Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n";
|
|
|
|
|
return licenseString;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- printForDebugger
|
|
|
|
|
{
|
|
|
|
|
id o;
|
|
|
|
|
FOR_COLLECTION(self, o)
|
|
|
|
|
{
|
|
|
|
|
printf("%s ", [[o description] cStringNoCopy]);
|
|
|
|
|
}
|
|
|
|
|
END_FOR_COLLECTION(self);
|
1996-03-03 00:33:24 +00:00
|
|
|
|
printf(": %s\n", object_get_class_name (self));
|
1996-02-22 15:11:43 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
1995-04-12 15:15:53 +00:00
|
|
|
|
|
1995-04-09 01:53:53 +00:00
|
|
|
|
- (void) encodeWithCoder: aCoder
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
[self _encodeCollectionWithCoder:aCoder];
|
|
|
|
|
[self _encodeContentsWithCoder:aCoder];
|
|
|
|
|
}
|
|
|
|
|
|
1995-04-09 01:53:53 +00:00
|
|
|
|
- initWithCoder: aCoder
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1995-04-09 01:53:53 +00:00
|
|
|
|
[self _initCollectionWithCoder:aCoder];
|
|
|
|
|
[self _decodeContentsWithCoder:aCoder];
|
|
|
|
|
return self;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
|
|
|
|
@implementation ConstantCollection (ArchivingHelpers)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1995-04-09 01:53:53 +00:00
|
|
|
|
- (void) _encodeCollectionWithCoder: aCoder
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
[super encodeWithCoder:aCoder];
|
|
|
|
|
// there are no instance vars;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
1995-04-09 01:53:53 +00:00
|
|
|
|
- _initCollectionWithCoder: aCoder
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
// there are no instance vars;
|
1995-04-09 01:53:53 +00:00
|
|
|
|
return [super initWithCoder:aCoder];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) _encodeContentsWithCoder: (id <Encoding>)aCoder
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
unsigned int count = [self count];
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
[aCoder encodeValueOfCType: @encode(unsigned)
|
|
|
|
|
at: &count
|
|
|
|
|
withName: @"Collection content count"];
|
|
|
|
|
FOR_COLLECTION(self, o)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[aCoder encodeObject: o
|
1996-01-24 03:33:21 +00:00
|
|
|
|
withName:@"Collection element"];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION(self);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) _decodeContentsWithCoder: (id <Decoding>)aCoder
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id *content_array;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
unsigned int count, i;
|
|
|
|
|
|
1996-01-23 23:57:17 +00:00
|
|
|
|
[aCoder decodeValueOfCType:@encode(unsigned)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
at:&count
|
|
|
|
|
withName:NULL];
|
1996-04-13 18:37:57 +00:00
|
|
|
|
content_array = alloca (sizeof (id) * count);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
for (i = 0; i < count; i++)
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[aCoder decodeObjectAt: &(content_array[i])
|
|
|
|
|
withName:NULL];
|
|
|
|
|
[self initWithObjects: content_array count: count];
|
1997-09-01 21:59:51 +00:00
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
|
[content_array[i] release];
|
1996-02-22 15:11:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@implementation ConstantCollection (DeallocationHelpers)
|
|
|
|
|
|
|
|
|
|
/* This must work without sending any messages to content objects.
|
|
|
|
|
Content objects already may be dealloc'd when this is executed. */
|
|
|
|
|
- (void) _collectionEmpty
|
|
|
|
|
{
|
|
|
|
|
[self subclassResponsibility:_cmd];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) _collectionReleaseContents
|
|
|
|
|
{
|
|
|
|
|
int c = [self count];
|
1997-09-23 14:03:36 +00:00
|
|
|
|
if (c)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1997-09-23 14:03:36 +00:00
|
|
|
|
id *array = (id*) alloca (c * sizeof(id));
|
|
|
|
|
int i = 0;
|
|
|
|
|
void *es = [self newEnumState];
|
|
|
|
|
id o;
|
|
|
|
|
while ((o = [self nextObjectWithEnumState:&es]))
|
|
|
|
|
{
|
|
|
|
|
array[i++] = o;
|
|
|
|
|
}
|
|
|
|
|
[self freeEnumState: &es];
|
|
|
|
|
assert (c == i);
|
|
|
|
|
for (i = 0; i < c; i++)
|
|
|
|
|
[array[i] release];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) _collectionDealloc
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@implementation Collection
|
|
|
|
|
|
|
|
|
|
// ADDING;
|
|
|
|
|
|
|
|
|
|
- (void) addObject: anObject
|
|
|
|
|
{
|
|
|
|
|
[self subclassResponsibility:_cmd];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) addObjectIfAbsent: newObject;
|
|
|
|
|
{
|
|
|
|
|
if (![self containsObject: newObject])
|
|
|
|
|
[self addObject: newObject];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) addContentsOf: (id <Collecting>)aCollection
|
|
|
|
|
{
|
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
FOR_COLLECTION(aCollection, o)
|
|
|
|
|
{
|
|
|
|
|
[self addObject: o];
|
|
|
|
|
}
|
|
|
|
|
END_FOR_COLLECTION(aCollection);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) addContentsIfAbsentOf: (id <Collecting>)aCollection
|
|
|
|
|
{
|
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
FOR_COLLECTION(aCollection, o)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if (![self containsObject:o])
|
|
|
|
|
[self addObject: o];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION(aCollection);
|
|
|
|
|
}
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) addWithObjects: (id*)objc count: (unsigned)c
|
|
|
|
|
{
|
|
|
|
|
[self notImplemented: _cmd];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) addObjects: firstObject, ...
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[self notImplemented: _cmd];
|
|
|
|
|
}
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) addObjects: firstObject rest: (va_list)ap
|
|
|
|
|
{
|
|
|
|
|
[self notImplemented: _cmd];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// REMOVING AND REPLACING;
|
|
|
|
|
|
|
|
|
|
- (void) removeObject: oldObject
|
|
|
|
|
{
|
|
|
|
|
[self subclassResponsibility: _cmd];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) removeAllOccurrencesOfObject: oldObject
|
|
|
|
|
{
|
|
|
|
|
while ([self containsObject: oldObject])
|
|
|
|
|
[self removeObject: oldObject];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) removeContentsIn: (id <ConstantCollecting>)aCollection
|
|
|
|
|
{
|
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
FOR_COLLECTION(aCollection, o)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[self removeObject: o];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
1996-02-22 15:11:43 +00:00
|
|
|
|
END_FOR_COLLECTION(aCollection);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) removeContentsNotIn: (id <ConstantCollecting>)aCollection
|
|
|
|
|
{
|
|
|
|
|
id o;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
FOR_COLLECTION(self, o)
|
|
|
|
|
{
|
|
|
|
|
if (![aCollection containsObject: o])
|
|
|
|
|
[self removeObject: o];
|
|
|
|
|
}
|
|
|
|
|
END_FOR_COLLECTION(self);
|
|
|
|
|
}
|
1995-03-23 03:37:22 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) uniqueContents
|
1995-03-23 03:37:22 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
id cp = [self shallowCopy];
|
|
|
|
|
int count;
|
|
|
|
|
id o;
|
|
|
|
|
|
1996-03-18 13:44:21 +00:00
|
|
|
|
FOR_COLLECTION(cp, o)
|
1996-02-22 15:11:43 +00:00
|
|
|
|
{
|
|
|
|
|
count = [self occurrencesOfObject: o];
|
|
|
|
|
if (!count)
|
|
|
|
|
continue;
|
|
|
|
|
while (count--)
|
|
|
|
|
[self removeObject: o];
|
|
|
|
|
}
|
1996-03-18 13:44:21 +00:00
|
|
|
|
END_FOR_COLLECTION(cp);
|
1995-03-23 03:37:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* May be inefficient. Could be overridden; */
|
|
|
|
|
- (void) empty
|
1995-03-23 03:37:22 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
if ([self isEmpty])
|
|
|
|
|
return;
|
|
|
|
|
[self _collectionReleaseContents];
|
|
|
|
|
[self _collectionEmpty];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// REPLACING;
|
|
|
|
|
|
|
|
|
|
- (void) replaceObject: oldObject withObject: newObject
|
|
|
|
|
{
|
|
|
|
|
if ([newObject isEqual: newObject])
|
|
|
|
|
return;
|
|
|
|
|
[oldObject retain];
|
|
|
|
|
[self removeObject: oldObject];
|
|
|
|
|
[self addObject: newObject];
|
|
|
|
|
[oldObject release];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) replaceAllOccurrencesOfObject: oldObject withObject: newObject
|
|
|
|
|
{
|
|
|
|
|
if ([oldObject isEqual: newObject])
|
|
|
|
|
return;
|
|
|
|
|
while ([self containsObject: oldObject])
|
|
|
|
|
[self replaceObject: oldObject withObject: newObject];
|
1995-03-23 03:37:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|