Major efficieny rewrites.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@3043 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 1998-10-08 13:46:53 +00:00
parent 85c38deb08
commit b25aac96ce
10 changed files with 1047 additions and 409 deletions

View file

@ -1,3 +1,15 @@
The Oct 8 15:15:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* src/FastMap.x: Minor bugfixes and updates.
* src/NSArray.m: Optimisation - don't use malloc unless really needed.
* src/NSCountedSet.m: Tidied
* src/NSSet.m: Tidied - core/non-core separation made.
* src/NSGArray.m: Rewrite - simpler and faster.
* src/NSGCountedSet.m: Rewrite to use FastMap (and work).
* src/NSGDictionary.m: Tidied initialisation.
* src/NSGSet.m: Rewrite to use FastMap - much faster.
* src/include/NSSet.h: tidied - core/non-core stuff.
Tue Oct 6 16:35:48 1998 Adam Fedor <fedor@doc.com>
* aclocal.m4: Add win32 test
@ -5,7 +17,7 @@ Tue Oct 6 16:35:48 1998 Adam Fedor <fedor@doc.com>
* src/GNUmakefile: Add win32-load.h
* src/win32-load.h: New file.
Sat Oct 6 16:45:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
Tue Oct 6 16:45:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* src/FastMap.x: New map table for dictionaries.
* src/include/fast.x: New stuff for avoiding objc message overheads.

View file

@ -1,5 +1,5 @@
/* Interface for NSSet, NSMutableSet, NSCountedSet for GNUStep
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: Sep 1995
@ -30,24 +30,29 @@
@interface NSSet : NSObject <NSCoding, NSCopying, NSMutableCopying>
+ allocWithZone: (NSZone*)zone;
+ set;
+ setWithArray: (NSArray*)array;
+ setWithObject: anObject;
+ setWithObjects: anObject, ...;
- (id) initWithObjects: (id*)objects
count: (unsigned)count;
- (unsigned) count;
- (id) member: (id)anObject;
- (NSEnumerator*) objectEnumerator;
@end
@interface NSSet (NonCore)
- initWithArray: (NSArray*)array;
- initWithObjects: (id)objects, ...;
- initWithObjects: (id*)objects
count: (unsigned)count;
- initWithSet: (NSSet*)otherSet;
- initWithSet: (NSSet*)otherSet copyItems: (BOOL)flags;
- (NSArray*) allObjects;
- anyObject;
- (BOOL) containsObject: anObject;
- (unsigned) count;
- member: anObject;
- (NSEnumerator*) objectEnumerator;
- (void) makeObjectsPerform: (SEL)aSelector;
- (void) makeObjectsPerform: (SEL)aSelector withObject:argument;
@ -56,38 +61,33 @@
- (BOOL) isEqualToSet: (NSSet*)other;
- (BOOL) isSubsetOfSet: (NSSet*)other;
- (NSString*) description;
- (NSString*) descriptionWithLocale: (NSDictionary*)ld;
@end
@interface NSMutableSet: NSSet
+ allocWithZone: (NSZone*)zone;
+ setWithCapacity: (unsigned)numItems;
- initWithCapacity: (unsigned)numItems;
- (void) addObject: anObject;
- initWithCapacity: (unsigned)numItems;
- (void) addObject: (id)anObject;
- (void) removeObject: (id)anObject;
@end
@interface NSMutableSet (NonCore)
- (void) addObjectsFromArray: (NSArray*)array;
- (void) unionSet: (NSSet*)other;
- (void) intersectSet: (NSSet*)other;
- (void) minusSet: (NSSet*)other;
- (void) removeAllObjects;
- (void) removeObject: anObject;
@end
@interface NSCountedSet : NSMutableSet
+ allocWithZone: (NSZone*)zone;
- initWithCapacity: (unsigned)numItems;
- initWithArray: (NSArray*)array;
- initWithSet: (NSSet*)otherSet;
- (void) addObject: anObject;
- (void) removeObject: anObject;
- (unsigned int) countForObject: anObject;
- (NSEnumerator*) objectEnumerator;
@end

View file

@ -95,6 +95,7 @@ typedef union {
NSObject *o;
long int i;
void *p;
unsigned u;
} FastMapItem;
typedef struct _FastMapTable FastMapTable_t;
@ -316,7 +317,7 @@ FastMapNewNode(FastMapTable map, FastMapItem key)
{
FastMapNode node = map->freeNodes;
if (node = 0) {
if (node == 0) {
FastMapMoreNodes(map);
node = map->freeNodes;
if (node == 0) {
@ -524,7 +525,7 @@ FastMapAddKey(FastMapTable map, FastMapItem key)
FastMapNode node;
FAST_MAP_RETAIN_KEY(key);
node = FastMapNewNode(map, key, value);
node = FastMapNewNode(map, key);
if (node != 0) {
FastMapRightSizeMap(map, map->nodeCount);
@ -550,7 +551,7 @@ FastMapRemoveKey(FastMapTable map, FastMapItem key)
}
static INLINE void
FastMapEmptyMap(FastMapTable map)
FastMapCleanMap(FastMapTable map)
{
FastMapBucket bucket = map->buckets;
int i;
@ -564,6 +565,16 @@ FastMapEmptyMap(FastMapTable map)
}
bucket++;
}
map->firstNode = 0;
map->nodeCount = 0;
}
static INLINE void
FastMapEmptyMap(FastMapTable map)
{
int i;
FastMapCleanMap(map);
if (map->buckets != 0) {
NSZoneFree(map->zone, map->buckets);
map->buckets = 0;
@ -577,9 +588,6 @@ FastMapEmptyMap(FastMapTable map)
NSZoneFree(map->zone, map->nodeChunks);
map->nodeChunks = 0;
}
map->firstNode = 0;
map->nodeCount = 0;
map->freeNodes = 0;
map->zone = 0;
}

View file

@ -1,5 +1,5 @@
/* NSArray - Array object to hold other objects.
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
From skeleton by: Adam Fedor <fedor@boulder.colorado.edu>
@ -194,31 +194,31 @@ static Class NSMutableArray_concrete_class;
id *objects;
c = [self count];
OBJC_MALLOC (objects, id, c+1);
for (i = 0; i < c; i++)
objects[i] = [self objectAtIndex: i];
objects[c] = anObject;
na = [[NSArray alloc] initWithObjects: objects count: c+1];
OBJC_FREE (objects);
{
id objects[c+1];
[self getObjects: objects];
objects[c] = anObject;
na = [[NSArray alloc] initWithObjects: objects count: c+1];
}
return [na autorelease];
}
- (NSArray*) arrayByAddingObjectsFromArray: (NSArray*)anotherArray
{
id na;
unsigned i, c, l;
id *objects;
id na;
unsigned c, l;
c = [self count];
l = [anotherArray count];
OBJC_MALLOC (objects, id, c+l);
for (i = 0; i < c; i++)
objects[i] = [self objectAtIndex: i];
for (i = c; i < c+l; i++)
objects[i] = [anotherArray objectAtIndex: i-c];
na = [[NSArray alloc] initWithObjects: objects count: c+l];
OBJC_FREE (objects);
return [na autorelease];
c = [self count];
l = [anotherArray count];
{
id objects[c+l];
[self getObjects: objects];
[anotherArray getObjects: &objects[c]];
na = [NSArray arrayWithObjects: objects count: c+l];
}
return na;
}
- initWithObjects: firstObject rest: (va_list) ap
@ -231,8 +231,8 @@ static Class NSMutableArray_concrete_class;
auto id tmpId;
/* Do initial allocation. */
prevSize = 1;
curSize = 2;
prevSize = 3;
curSize = 5;
OBJC_MALLOC(objsArray, id, curSize);
tmpId = firstObject;
@ -312,16 +312,16 @@ static Class NSMutableArray_concrete_class;
- initWithArray: (NSArray*)array
{
unsigned i, c;
id *objects;
unsigned c;
c = [array count];
OBJC_MALLOC(objects, id, c);
for (i = 0; i < c; i++)
objects[i] = [array objectAtIndex:i];
self = [self initWithObjects:objects count:c];
OBJC_FREE(objects);
return self;
c = [array count];
{
id objects[c];
[array getObjects: objects];
self = [self initWithObjects: objects count: c];
}
return self;
}
- (void) getObjects: (id*)aBuffer
@ -537,16 +537,13 @@ static Class NSMutableArray_concrete_class;
else
j = range.location + range.length - 1;
// Copy the ids from the range into a temporary array
OBJC_MALLOC(objects, id, j-i+1);
for (k = i; k <= j; k++)
objects[k-i] = [self objectAtIndex:k];
// Create the new array
na = [[NSArray alloc] initWithObjects:objects count:j-i+1];
OBJC_FREE(objects);
return [na autorelease];
{
id objects[j-i+1];
[self getObjects: objects range: NSMakeRange(i, j-i+1)];
na = [NSArray arrayWithObjects: objects count: j-i+1];
}
return na;
}
- (NSEnumerator*) objectEnumerator

View file

@ -22,17 +22,30 @@
*/
#include <config.h>
#include <gnustep/base/behavior.h>
#include <Foundation/NSSet.h>
#include <Foundation/NSGSet.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSUtilities.h>
#include <gnustep/base/NSString.h>
#include <Foundation/NSString.h>
#include <assert.h>
@class NSSetNonCore;
@class NSMutableSetNonCore;
@implementation NSCountedSet
static Class NSCountedSet_concrete_class;
+ (void) initialize
{
if (self == [NSCountedSet class]) {
NSCountedSet_concrete_class = [NSGCountedSet class];
behavior_class_add_class(self, [NSMutableSetNonCore class]);
behavior_class_add_class(self, [NSSetNonCore class]);
}
}
+ (void) _CountedSetConcreteClass: (Class)c
{
NSCountedSet_concrete_class = c;
@ -43,58 +56,11 @@ static Class NSCountedSet_concrete_class;
return NSCountedSet_concrete_class;
}
+ (void) initialize
{
NSCountedSet_concrete_class = [NSGCountedSet class];
}
+ allocWithZone: (NSZone*)z
{
return NSAllocateObject([self _concreteClass], 0, z);
}
/* This is the designated initializer */
/* Also, override superclass's designated initializer */
- initWithCapacity: (unsigned)numItems
{
return [self subclassResponsibility:_cmd];
}
- initWithArray: (NSArray*)array
{
int i, c = [array count];
[self initWithCapacity:c];
for (i = 0; i < c; i++)
[self addObject:[array objectAtIndex:i]];
return self;
}
- initWithSet: (NSSet*)other
{
id o, e = [other objectEnumerator];
[self initWithCapacity:[other count]];
while ((o = [e nextObject]))
[self addObject:o];
return self;
}
- (NSEnumerator*) objectEnumerator
{
return [self subclassResponsibility:_cmd];
}
- (void) addObject: anObject
{
[self subclassResponsibility:_cmd];
}
- (void) removeObject: anObject
{
[self subclassResponsibility:_cmd];
}
- (unsigned int) countForObject: anObject
{
[self subclassResponsibility:_cmd];
@ -103,14 +69,51 @@ static Class NSCountedSet_concrete_class;
- copyWithZone: (NSZone*)z
{
id o, e = [self objectEnumerator];
id c = [[[[self class] _concreteClass] alloc]
initWithCapacity:[self count]];
while ((o = [e nextObject]))
[(NSCountedSet*)c addObject:o];
/* Cast to avoid type warning.
I'll fix the type in gnustep/base/Collecting.h eventually. */
return o;
/* a deep copy */
int count = [self count];
id objects[count];
id enumerator = [self objectEnumerator];
id o;
NSSet *newSet;
int i;
BOOL needCopy = [self isKindOfClass: [NSMutableSet class]];
if (NSShouldRetainWithZone(self, z) == NO)
needCopy = YES;
for (i = 0; (o = [enumerator nextObject]); i++)
{
objects[i] = [o copyWithZone:z];
if (objects[i] != o)
needCopy = YES;
}
if (needCopy)
{
int j;
newSet = [[[[self class] _concreteClass] allocWithZone: z]
initWithObjects:objects count:count];
for (j = 0; j < i; j++)
{
unsigned extra = [self countForObject: objects[j]];
if (extra > 1)
while (--extra)
[newSet addObject: objects[j]];
}
}
else
newSet = [self retain];
for (i = 0; i < count; i++)
[objects[i] release];
return newSet;
}
- mutableCopyWithZone: (NSZone*)z
{
/* a shallow copy */
return [[[[self class] _concreteClass] allocWithZone: z] initWithSet: self];
}
- initWithCoder: aCoder
@ -124,4 +127,38 @@ static Class NSCountedSet_concrete_class;
[self subclassResponsibility:_cmd];
}
- initWithSet: (NSSet*)other copyItems: (BOOL)flag
{
int c = [other count];
id os[c], o, e = [other objectEnumerator];
int i = 0;
while ((o = [e nextObject]))
{
if (flag)
os[i] = [o copy];
else
os[i] = o;
i++;
}
self = [self initWithObjects:os count:c];
if ([other isKindOfClass: [NSCountedSet class]])
{
int j;
for (j = 0; j < i; j++)
{
unsigned extra = [(NSCountedSet*)other countForObject: os[j]];
if (extra > 1)
while (--extra)
[self addObject: os[j]];
}
}
if (flag)
while (--i)
[os[i] release];
return self;
}
@end

View file

@ -1,8 +1,9 @@
/* Concrete implementation of NSArray based on GNU Array class
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
/* Concrete implementation of NSArray
Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: March 1995
Rewrite by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
This file is part of the GNUstep Base Library.
@ -23,13 +24,29 @@
#include <config.h>
#include <gnustep/base/preface.h>
#include <Foundation/NSGArray.h>
#include <Foundation/NSArray.h>
#include <gnustep/base/NSArray.h>
#include <gnustep/base/behavior.h>
#include <gnustep/base/Array.h>
#include <gnustep/base/ArrayPrivate.h>
#include <Foundation/NSException.h>
#include <Foundation/NSPortCoder.h>
#include <gnustep/base/Coding.h>
#define BADREALLOC 1
@interface NSGArray : NSArray
{
id *_contents_array;
unsigned _count;
}
@end
@interface NSGMutableArray : NSMutableArray
{
id *_contents_array;
unsigned _count;
unsigned _capacity;
int _grow_factor;
}
@end
@class NSArrayNonCore;
@ -37,61 +54,159 @@
+ (void) initialize
{
if (self == [NSGArray class])
{
behavior_class_add_class (self, [NSArrayNonCore class]);
behavior_class_add_class (self, [Array class]);
if (self == [NSGArray class]) {
behavior_class_add_class(self, [NSArrayNonCore class]);
}
}
/* #define self ((Array*)self) */
#if 0
/* This is the designated initializer for NSArray. */
- initWithObjects: (id*)objects count: (unsigned)count
- (void) dealloc
{
int i;
if (_contents_array) {
unsigned i;
for (i = 0; i < count; i++)
if (objects[i] == nil)
[NSException raise:NSInvalidArgumentException
format:@"Tried to add nil"];
[self initWithCapacity: count];
while (count--)
[self addObject: [objects[count] retain]];
return self;
for (i = 0; i < _count; i++) {
[_contents_array[i] release];
}
NSZoneFree([self zone], _contents_array);
}
[super dealloc];
}
/* This is the designated initializer for NSArray. */
- (id) initWithObjects: (id*)objects count: (unsigned)count
{
if (count > 0) {
unsigned i;
_contents_array = NSZoneMalloc([self zone], sizeof(id)*count);
if (_contents_array == 0) {
[self release];
return nil;
}
for (i = 0; i < count; i++) {
if ((_contents_array[i] = [objects[i] retain]) == nil) {
_count = i;
[self autorelease];
[NSException raise: NSInvalidArgumentException
format: @"Tried to add nil"];
}
}
_count = count;
}
return self;
}
- (void) encodeWithCoder: (NSCoder*)aCoder
{
unsigned i;
[(id<Encoding>)aCoder encodeValueOfCType: @encode(unsigned)
at: &_count
withName: @"Array content count"];
if ([aCoder isKindOfClass: [NSPortCoder class]] &&
[(NSPortCoder*)aCoder isBycopy]) {
for (i = 0; i < _count; i++) {
[(id<Encoding>)aCoder encodeBycopyObject: _contents_array[i]
withName: @"Array content"];
}
}
else {
for (i = 0; i < _count; i++) {
[(id<Encoding>)aCoder encodeObject: _contents_array[i]
withName: @"Array content"];
}
}
}
- (id) initWithCoder: (NSCoder*)aCoder
{
unsigned count;
[(id<Decoding>)aCoder decodeValueOfCType: @encode(unsigned)
at: &count
withName: NULL];
if (count > 0) {
_contents_array = NSZoneMalloc([self zone], sizeof(id)*count);
if (_contents_array == 0) {
[NSException raise: NSMallocException
format: @"Unable to make array"];
}
while (_count < count) {
[(id<Decoding>)aCoder decodeObjectAt: &_contents_array[_count++]
withName: NULL];
}
}
return self;
}
- (id) init
{
return [self initWithObjects: 0 count: 0];
}
- (unsigned) count
{
return _count;
}
/* Force message to go to super class rather than the behavior class */
- (unsigned) indexOfObject: anObject
{
return [super indexOfObject: anObject];
unsigned hash = [anObject hash];
unsigned i;
for (i = 0; i < _count; i++) {
if ([_contents_array[i] hash] == hash) {
if ([_contents_array[i] isEqual: anObject]) {
return i;
}
}
}
return NSNotFound;
}
- objectAtIndex: (unsigned)index
- (unsigned) indexOfObjectIdenticalTo: anObject
{
if (index >= self->_count)
[NSException raise: NSRangeException
format: @"Index out of bounds"];
return self->_contents_array[index];
unsigned i;
for (i = 0; i < _count; i++) {
if (anObject == _contents_array[i]) {
return i;
}
}
return NSNotFound;
}
- (id) objectAtIndex: (unsigned)index
{
if (index >= _count) {
[NSException raise: NSRangeException
format: @"Index out of bounds"];
}
return _contents_array[index];
}
#endif
- (void) getObjects: (id*)aBuffer
{
unsigned i;
for (i = 0; i < _count; i++)
aBuffer[i] = _contents_array[i];
unsigned i;
for (i = 0; i < _count; i++) {
aBuffer[i] = _contents_array[i];
}
}
- (void) getObjects: (id*)aBuffer range: (IndexRange)aRange
{
unsigned i, j = 0, e = aRange.location + aRange.length;
if (_count < e)
e = _count;
for (i = aRange.location; i < _count; i++)
aBuffer[j++] = _contents_array[i];
unsigned i, j = 0, e = aRange.location + aRange.length;
if (_count < e) {
e = _count;
}
for (i = aRange.location; i < _count; i++) {
aBuffer[j++] = _contents_array[i];
}
}
@end
@ -102,16 +217,189 @@
+ (void) initialize
{
if (self == [NSGMutableArray class])
{
behavior_class_add_class (self, [NSMutableArrayNonCore class]);
behavior_class_add_class (self, [NSGArray class]);
behavior_class_add_class (self, [Array class]);
if (self == [NSGMutableArray class]) {
behavior_class_add_class(self, [NSMutableArrayNonCore class]);
behavior_class_add_class(self, [NSGArray class]);
}
}
- (id) initWithCapacity: (unsigned)cap
{
if (cap == 0) {
cap = 1;
}
_contents_array = NSZoneMalloc([self zone], sizeof(id)*cap);
_capacity = cap;
_grow_factor = cap > 1 ? cap/2 : 1;
return self;
}
- (id) initWithCoder: (NSCoder*)aCoder
{
unsigned count;
[(id<Decoding>)aCoder decodeValueOfCType: @encode(unsigned)
at: &count
withName: NULL];
if ([self initWithCapacity: count] == nil) {
[NSException raise: NSMallocException
format: @"Unable to make array"];
}
while (_count < count) {
[(id<Decoding>)aCoder decodeObjectAt: &_contents_array[_count++]
withName: NULL];
}
return self;
}
- (id) initWithObjects: (id*)objects count: (unsigned)count
{
self = [self initWithCapacity: count];
if (self != nil && count > 0) {
unsigned i;
for (i = 0; i < count; i++) {
if ((_contents_array[i] = [objects[i] retain]) == nil) {
_count = i;
[self autorelease];
[NSException raise: NSInvalidArgumentException
format: @"Tried to add nil"];
}
}
_count = count;
}
return self;
}
- (void) insertObject: (id)anObject atIndex: (unsigned)index
{
unsigned i;
if (!anObject) {
[NSException raise: NSInvalidArgumentException
format: @"Tried to insert nil"];
}
if (index > _count) {
[NSException raise: NSRangeException format:
@"in insertObject:atIndex:, index %d is out of range", index];
}
if (_count == _capacity) {
id *ptr;
size_t size = (_capacity + _grow_factor)*sizeof(id);
#if BADREALLOC
ptr = NSZoneMalloc([self zone], size);
#else
ptr = NSZoneRealloc([self zone], _contents_array, size);
#endif
if (ptr == 0) {
[NSException raise: NSMallocException
format: @"Unable to grow"];
}
#if BADREALLOC
if (_contents_array) {
memcpy(ptr, _contents_array, _capacity*sizeof(id));
NSZoneFree([self zone], _contents_array);
}
#endif
_contents_array = ptr;
_capacity += _grow_factor;
_grow_factor = _capacity/2;
}
for (i = _count; i > index; i--) {
_contents_array[i] = _contents_array[i - 1];
}
/*
* Make sure the array is 'sane' so that it can be deallocated
* safely by an autorelease pool if the '[anObject retain]' causes
* an exception.
*/
_contents_array[index] = nil;
_count++;
_contents_array[index] = [anObject retain];
}
- (void) addObject: (id)anObject
{
if (anObject == nil) {
[NSException raise: NSInvalidArgumentException
format: @"Tried to add nil"];
}
if (_count >= _capacity) {
id *ptr;
size_t size = (_capacity + _grow_factor)*sizeof(id);
#if BADREALLOC
ptr = NSZoneMalloc([self zone], size);
#else
ptr = NSZoneRealloc([self zone], _contents_array, size);
#endif
if (ptr == 0) {
[NSException raise: NSMallocException
format: @"Unable to grow"];
}
#if BADREALLOC
if (_contents_array) {
memcpy(ptr, _contents_array, _capacity*sizeof(id));
NSZoneFree([self zone], _contents_array);
}
#endif
_contents_array = ptr;
_capacity += _grow_factor;
_grow_factor = _capacity/2;
}
_contents_array[_count] = [anObject retain];
_count++; /* Do this AFTER we have retained the object. */
}
- (void) removeLastObject
{
if (_count == 0) {
[NSException raise: NSRangeException
format: @"Trying to remove from an empty array."];
}
_count--;
[_contents_array[_count] release];
}
- (void) removeObjectAtIndex: (unsigned)index
{
id obj;
if (index >= _count) {
[NSException raise: NSRangeException format:
@"in removeObjectAtIndex:, index %d is out of range", index];
}
obj = _contents_array[index];
_count--;
while (index < _count) {
_contents_array[index] = _contents_array[index+1];
index++;
}
[obj release]; /* Adjust array BEFORE releasing object. */
}
- (void) replaceObjectAtIndex: (unsigned)index withObject: (id)anObject
{
id obj;
if (index >= _count) {
[NSException raise: NSRangeException format:
@"in replaceObjectAtIndex:withObject:, index %d is out of range",
index];
}
/*
* Swap objects in order so that there is always a valid object in the
* array in case a retain or release causes an exception.
*/
obj = _contents_array[index];
[anObject retain];
_contents_array[index] = anObject;
[obj release];
}
- (void) sortUsingFunction: (int(*)(id,id,void*))compare
context: (void*)context
context: (void*)context
{
/* Shell sort algorithm taken from SortingInAction - a NeXT example */
#define STRIDE_FACTOR 3 // good value for stride factor is not well-understood

View file

@ -1,8 +1,8 @@
/* Concrete implementation of NSCountedSet based on GNU Bag class
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
/* Concrete implementation of NSSet based on GNU Set class
Copyright (C) 1998 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: Sep 1995
Written by: Richard frith-Macdonald <richard@brainstorm.co.uk>
Created: October 1998
This file is part of the GNUstep Base Library.
@ -22,41 +22,62 @@
*/
#include <config.h>
#include <Foundation/NSGSet.h>
#include <gnustep/base/NSSet.h>
#include <Foundation/NSSet.h>
//#include <Foundation/NSGSet.h>
#include <gnustep/base/behavior.h>
#include <gnustep/base/Set.h>
#include <Foundation/NSUtilities.h>
#include <Foundation/NSString.h>
#include <Foundation/NSPortCoder.h>
#include <gnustep/base/Coding.h>
#define FAST_MAP_RETAIN_VAL(X) X
#define FAST_MAP_RELEASE_VAL(X)
#include "FastMap.x"
@class NSSetNonCore;
@class NSMutableSetNonCore;
@interface NSGCountedSet : NSCountedSet
{
@public
FastMapTable_t map;
}
@end
@interface NSGCountedSetEnumerator : NSEnumerator
{
NSCountedSet *bag;
void *enum_state;
NSGCountedSet *set;
FastMapNode node;
}
@end
@implementation NSGCountedSetEnumerator
- initWithCountedSet: (NSCountedSet*)d
- initWithSet: (NSSet*)d
{
[super init];
bag = d;
[bag retain];
enum_state = [bag newEnumState];
return self;
[super init];
set = [(NSGCountedSet*)d retain];
node = set->map.firstNode;
return self;
}
- nextObject
{
return [bag nextObjectWithEnumState: &enum_state];
FastMapNode old = node;
if (node == 0) {
return nil;
}
node = node->nextInMap;
return old->key.o;
}
- (void) dealloc
{
[bag freeEnumState: &enum_state];
[bag release];
[super dealloc];
[set release];
[super dealloc];
}
@end
@ -66,30 +87,162 @@
+ (void) initialize
{
static int done = 0;
if (!done)
{
done = 1;
class_add_behavior([NSGCountedSet class], [Bag class]);
if (self == [NSGCountedSet class]) {
class_add_behavior(self, [NSSetNonCore class]);
class_add_behavior(self, [NSMutableSetNonCore class]);
}
}
- (void) dealloc
{
FastMapEmptyMap(&map);
[super dealloc];
}
- (void) encodeWithCoder: (NSCoder*)aCoder
{
unsigned count = map.nodeCount;
FastMapNode node = map.firstNode;
[(id<Encoding>)aCoder encodeValueOfCType: @encode(unsigned)
at: &count
withName: @"Set content count"];
if ([aCoder isKindOfClass: [NSPortCoder class]] &&
[(NSPortCoder*)aCoder isBycopy]) {
while (node != 0) {
[(id<Encoding>)aCoder encodeBycopyObject: node->key.o
withName: @"Set value"];
[(id<Encoding>)aCoder encodeValueOfCType: @encode(unsigned)
at: &node->value.u
withName: @"Set value count"];
node = node->nextInMap;
}
}
else {
while (node != 0) {
[(id<Encoding>)aCoder encodeObject: node->key.o
withName: @"Set content"];
[(id<Encoding>)aCoder encodeValueOfCType: @encode(unsigned)
at: &node->value.u
withName: @"Set value count"];
node = node->nextInMap;
}
}
}
- (id) initWithCoder: (NSCoder*)aCoder
{
unsigned count;
id value;
unsigned valcnt;
[(id<Decoding>)aCoder decodeValueOfCType: @encode(unsigned)
at: &count
withName: NULL];
FastMapInitWithZoneAndCapacity(&map, [self zone], count);
while (count-- > 0) {
[(id<Decoding>)aCoder decodeObjectAt: &value withName: NULL];
[(id<Decoding>)aCoder decodeValueOfCType: @encode(unsigned)
at: &valcnt
withName: NULL];
FastMapAddPairNoRetain(&map, (FastMapItem)value, (FastMapItem)valcnt);
}
return self;
}
/* Designated initialiser */
- (id) initWithCapacity: (unsigned)cap
{
FastMapInitWithZoneAndCapacity(&map, [self zone], cap);
return self;
}
- (id) initWithObjects: (id*)objs count: (unsigned)c
{
int i;
if ([self initWithCapacity: c] == nil) {
return nil;
}
for (i = 0; i < c; i++) {
FastMapNode node = FastMapNodeForKey(&map, (FastMapItem)objs[i]);
if (node == 0) {
FastMapAddPair(&map,(FastMapItem)objs[i],(FastMapItem)(unsigned)1);
}
else {
node->value.u++;
}
}
return self;
}
- (void) addObject: (NSObject*)anObject
{
FastMapNode node = FastMapNodeForKey(&map, (FastMapItem)anObject);
if (node == 0) {
FastMapAddPair(&map,(FastMapItem)anObject,(FastMapItem)(unsigned)1);
}
else {
node->value.u++;
}
}
- (unsigned) count
{
return map.nodeCount;
}
- (unsigned) countForObject: (id)anObject
{
FastMapNode node = FastMapNodeForKey(&map, (FastMapItem)anObject);
if (node == 0) {
return 0;
}
return node->value.u;
}
- (id) member: (id)anObject
{
FastMapNode node = FastMapNodeForKey(&map, (FastMapItem)anObject);
if (node == 0) {
return nil;
}
return node->key.o;
}
- (NSEnumerator*) objectEnumerator
{
return [[[NSGCountedSetEnumerator alloc] initWithCountedSet:self]
autorelease];
return [[[NSGCountedSetEnumerator alloc] initWithSet: self] autorelease];
}
- (unsigned int) countForObject: anObject
- (void) removeObject: (NSObject*)anObject
{
return [self occurrencesOfObject: anObject];
FastMapBucket bucket;
bucket = FastMapBucketForKey(&map, (FastMapItem)anObject);
if (bucket) {
FastMapNode node;
node = FastMapNodeForKeyInBucket(bucket, (FastMapItem)anObject);
if (node) {
if (--node->value.u == 0) {
FastMapRemoveNodeFromMap(&map, bucket, node);
FastMapFreeNode(&map, node);
}
}
}
}
/* To deal with behavior over-enthusiasm. Will be fixed later. */
- (BOOL) isEqual: other
- (void) removeAllObjects
{
return [super isEqual:other];
FastMapCleanMap(&map);
}
@end

View file

@ -99,18 +99,6 @@ myEqual(NSObject *self, NSObject *other)
@class NSDictionaryNonCore;
@class NSMutableDictionaryNonCore;
@class NSGDictionary;
@class NSGMutableDictionary;
@interface NSGDictionaryKeyEnumerator : NSEnumerator
{
NSGDictionary *dictionary;
FastMapNode node;
}
@end
@interface NSGDictionaryObjectEnumerator : NSGDictionaryKeyEnumerator
@end
@interface NSGDictionary : NSDictionary
{
@ -126,13 +114,22 @@ myEqual(NSObject *self, NSObject *other)
}
@end
@interface NSGDictionaryKeyEnumerator : NSEnumerator
{
NSGDictionary *dictionary;
FastMapNode node;
}
@end
@interface NSGDictionaryObjectEnumerator : NSGDictionaryKeyEnumerator
@end
@implementation NSGDictionary
+ (void) initialize
{
if (self == [NSGDictionary class])
{
behavior_class_add_class (self, [NSDictionaryNonCore class]);
if (self == [NSGDictionary class]) {
behavior_class_add_class(self, [NSDictionaryNonCore class]);
}
}
@ -197,6 +194,7 @@ myEqual(NSObject *self, NSObject *other)
return self;
}
/* Designated initialiser */
- (id) initWithObjects: (id*)objs forKeys: (NSObject**)keys count: (unsigned)c
{
int i;
@ -243,20 +241,20 @@ myEqual(NSObject *self, NSObject *other)
+ (void) initialize
{
if (self == [NSGMutableDictionary class])
{
behavior_class_add_class (self, [NSMutableDictionaryNonCore class]);
behavior_class_add_class (self, [NSGDictionary class]);
if (self == [NSGMutableDictionary class]) {
behavior_class_add_class(self, [NSMutableDictionaryNonCore class]);
behavior_class_add_class(self, [NSGDictionary class]);
}
}
/* Designated initialiser */
- (id) initWithCapacity: (unsigned)cap
{
FastMapInitWithZoneAndCapacity(&map, [self zone], cap);
return self;
}
- (void) setObject:anObject forKey:(NSObject *)aKey
- (void) setObject: (NSObject*)anObject forKey: (NSObject *)aKey
{
FastMapNode node = FastMapNodeForKey(&map, (FastMapItem)aKey);
@ -270,7 +268,12 @@ myEqual(NSObject *self, NSObject *other)
}
}
- (void) removeObjectForKey:(NSObject *)aKey
- (void) removeAllObjects
{
FastMapCleanMap(&map);
}
- (void) removeObjectForKey: (NSObject *)aKey
{
FastMapRemoveKey(&map, (FastMapItem)aKey);
}

View file

@ -1,8 +1,9 @@
/* Concrete implementation of NSSet based on GNU Set class
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: September 1995
Rewrite by: Richard frith-Macdonald <richard@brainstorm.co.uk>
This file is part of the GNUstep Base Library.
@ -22,17 +23,39 @@
*/
#include <config.h>
#include <Foundation/NSGSet.h>
#include <gnustep/base/NSSet.h>
#include <Foundation/NSSet.h>
//#include <Foundation/NSGSet.h>
#include <gnustep/base/behavior.h>
#include <gnustep/base/Set.h>
#include <Foundation/NSUtilities.h>
#include <Foundation/NSString.h>
#include <Foundation/NSPortCoder.h>
#include <gnustep/base/Coding.h>
#define FAST_MAP_HAS_VALUE 0
#include "FastMap.x"
@class NSSetNonCore;
@class NSMutableSetNonCore;
@interface NSGSet : NSSet
{
@public
FastMapTable_t map;
}
@end
@interface NSGMutableSet : NSMutableSet
{
@public
FastMapTable_t map;
}
@end
@interface NSGSetEnumerator : NSEnumerator
{
NSSet *set;
void *enum_state;
NSGSet *set;
FastMapNode node;
}
@end
@ -40,22 +63,27 @@
- initWithSet: (NSSet*)d
{
[super init];
set = d;
[set retain];
enum_state = [set newEnumState];
return self;
[super init];
set = [(NSGSet*)d retain];
node = set->map.firstNode;
return self;
}
- nextObject
{
return [set nextObjectWithEnumState: &enum_state];
FastMapNode old = node;
if (node == 0) {
return nil;
}
node = node->nextInMap;
return old->key.o;
}
- (void) dealloc
{
[set release];
[super dealloc];
[set release];
[super dealloc];
}
@end
@ -65,74 +93,132 @@
+ (void) initialize
{
static int done = 0;
if (!done)
{
done = 1;
class_add_behavior([NSGSet class], [Set class]);
if (self == [NSGSet class]) {
class_add_behavior(self, [NSSetNonCore class]);
}
}
- (unsigned) count
{
return map.nodeCount;
}
/* This is the designated initializer
- initWithObjects: (id*)objects
count: (unsigned)count
Implemented by behavior. */
- (void) dealloc
{
FastMapEmptyMap(&map);
[super dealloc];
}
- (void) encodeWithCoder: (NSCoder*)aCoder
{
unsigned count = map.nodeCount;
FastMapNode node = map.firstNode;
[(id<Encoding>)aCoder encodeValueOfCType: @encode(unsigned)
at: &count
withName: @"Set content count"];
if ([aCoder isKindOfClass: [NSPortCoder class]] &&
[(NSPortCoder*)aCoder isBycopy]) {
while (node != 0) {
[(id<Encoding>)aCoder encodeBycopyObject: node->key.o
withName: @"Set content"];
node = node->nextInMap;
}
}
else {
while (node != 0) {
[(id<Encoding>)aCoder encodeObject: node->key.o
withName: @"Set content"];
node = node->nextInMap;
}
}
}
- (id) initWithCoder: (NSCoder*)aCoder
{
unsigned count;
id value;
[(id<Decoding>)aCoder decodeValueOfCType: @encode(unsigned)
at: &count
withName: NULL];
FastMapInitWithZoneAndCapacity(&map, [self zone], count);
while (count-- > 0) {
[(id<Decoding>)aCoder decodeObjectAt: &value withName: NULL];
FastMapAddKeyNoRetain(&map, (FastMapItem)value);
}
return self;
}
/* Designated initialiser */
- (id) initWithObjects: (id*)objs count: (unsigned)c
{
int i;
FastMapInitWithZoneAndCapacity(&map, [self zone], c);
for (i = 0; i < c; i++) {
FastMapNode node = FastMapNodeForKey(&map, (FastMapItem)objs[i]);
if (node == 0) {
FastMapAddKey(&map, (FastMapItem)objs[i]);
}
}
return self;
}
- (id) member: (id)anObject
{
FastMapNode node = FastMapNodeForKey(&map, (FastMapItem)anObject);
if (node == 0) {
return nil;
}
return node->key.o;
}
- (NSEnumerator*) objectEnumerator
{
return [[[NSGSetEnumerator alloc] initWithSet:self]
autorelease];
return [[[NSGSetEnumerator alloc] initWithSet: self] autorelease];
}
/* To deal with behavior over-enthusiasm. Will be fixed later. */
- (BOOL) isEqual: other
{
#if 1
return [self isEqualToSet: other];
#else
/* xxx What is the correct behavior here?
If we end up calling [NSSet -isEqualToSet:] we end up in
an infinite loop, since that method enumerates the set, and
the set enumerator asks if things are equal...
[Huh? What am I saying here?] */
return (self == other);
#endif
}
@end
@implementation NSGMutableSet
+ (void) initialize
{
static int done = 0;
if (!done)
{
done = 1;
class_add_behavior([NSGMutableSet class], [NSGSet class]);
if (self == [NSGMutableSet class]) {
class_add_behavior(self, [NSMutableSetNonCore class]);
class_add_behavior(self, [NSGSet class]);
}
}
/* This is the designated initializer
- initWithCapacity: (unsigned)numItems
implemented by behavior. */
/* Designated initialiser */
- (id) initWithCapacity: (unsigned)cap
{
FastMapInitWithZoneAndCapacity(&map, [self zone], cap);
return self;
}
/* Implemented by behavior:
- (void) addObject: newObject;
- (void) removeObject: anObject
*/
- (void) addObject: (NSObject*)anObject
{
FastMapNode node = FastMapNodeForKey(&map, (FastMapItem)anObject);
if (node == 0) {
FastMapAddKey(&map, (FastMapItem)anObject);
}
}
- (void) removeObject: (NSObject *)anObject
{
FastMapRemoveKey(&map, (FastMapItem)anObject);
}
- (void) removeAllObjects
{
[self empty];
}
/* To deal with behavior over-enthusiasm. Will be fixed later. */
- (BOOL) isEqual: other
{
return [super isEqual:other];
FastMapCleanMap(&map);
}
@end

View file

@ -1,5 +1,5 @@
/* NSSet - Set object to store key/value pairs
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: Sep 1995
@ -22,18 +22,33 @@
*/
#include <config.h>
#include <gnustep/base/behavior.h>
#include <Foundation/NSSet.h>
#include <Foundation/NSGSet.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSUtilities.h>
#include <gnustep/base/NSString.h>
#include <Foundation/NSString.h>
#include <assert.h>
@interface NSSetNonCore : NSSet
@end
@interface NSMutableSetNonCore: NSMutableSet
@end
@implementation NSSet
static Class NSSet_concrete_class;
static Class NSMutableSet_concrete_class;
+ (void) initialize
{
if (self == [NSSet class]) {
NSSet_concrete_class = [NSGSet class];
NSMutableSet_concrete_class = [NSGMutableSet class];
behavior_class_add_class(self, [NSSetNonCore class]);
}
}
+ (void) _setConcreteClass: (Class)c
{
NSSet_concrete_class = c;
@ -54,17 +69,6 @@ static Class NSMutableSet_concrete_class;
return NSMutableSet_concrete_class;
}
+ (void) initialize
{
NSSet_concrete_class = [NSGSet class];
NSMutableSet_concrete_class = [NSGMutableSet class];
}
+ allocWithZone: (NSZone*)z
{
return NSAllocateObject([self _concreteClass], 0, z);
}
+ set
{
return [[[self alloc] init]
@ -81,9 +85,7 @@ static Class NSMutableSet_concrete_class;
+ setWithArray: (NSArray*)objects
{
/* xxx Only works because NSArray also responds to objectEnumerator
and nextObject. */
return [[[self alloc] initWithSet:(NSSet*)objects]
return [[[self alloc] initWithArray: objects]
autorelease];
}
@ -94,34 +96,6 @@ static Class NSMutableSet_concrete_class;
autorelease];
}
/* Same as NSArray */
/* Not very pretty... */
#define INITIAL_OBJECTS_SIZE 10
- initWithObjects: firstObject rest: (va_list)ap
{
id *objects;
int i = 0;
int s = INITIAL_OBJECTS_SIZE;
OBJC_MALLOC(objects, id, s);
if (firstObject != nil)
{
objects[i++] = firstObject;
while ((objects[i++] = va_arg(ap, id)))
{
if (i >= s)
{
s *= 2;
OBJC_REALLOC(objects, id, s);
}
}
}
self = [self initWithObjects:objects count:i-1];
OBJC_FREE(objects);
return self;
}
/* Same as NSArray */
+ setWithObjects: firstObject, ...
{
va_list ap;
@ -131,6 +105,11 @@ static Class NSMutableSet_concrete_class;
return [self autorelease];
}
+ allocWithZone: (NSZone*)z
{
return NSAllocateObject([self _concreteClass], 0, z);
}
/* This is the designated initializer */
- initWithObjects: (id*)objects
count: (unsigned)count
@ -139,11 +118,121 @@ static Class NSMutableSet_concrete_class;
return 0;
}
- initWithArray: (NSArray*)array
- initWithCoder: aCoder
{
/* xxx Only works because NSArray also responds to objectEnumerator
and nextObject. */
return [self initWithSet:(NSSet*)array];
[self subclassResponsibility:_cmd];
return nil;
}
- (void) encodeWithCoder: aCoder
{
[self subclassResponsibility:_cmd];
}
- (unsigned) count
{
[self subclassResponsibility:_cmd];
return 0;
}
- member: anObject
{
return [self subclassResponsibility:_cmd];
return 0;
}
- (NSEnumerator*) objectEnumerator
{
return [self subclassResponsibility:_cmd];
}
- copyWithZone: (NSZone*)z
{
/* a deep copy */
int count = [self count];
id objects[count];
id enumerator = [self objectEnumerator];
id o;
NSSet *newSet;
int i;
BOOL needCopy = [self isKindOfClass: [NSMutableSet class]];
if (NSShouldRetainWithZone(self, z) == NO)
needCopy = YES;
for (i = 0; (o = [enumerator nextObject]); i++)
{
objects[i] = [o copyWithZone:z];
if (objects[i] != o)
needCopy = YES;
}
if (needCopy)
newSet = [[[[self class] _concreteClass] allocWithZone: z]
initWithObjects:objects
count:count];
else
newSet = [self retain];
for (i = 0; i < count; i++)
[objects[i] release];
return newSet;
}
- mutableCopyWithZone: (NSZone*)z
{
/* a shallow copy */
return [[[[self class] _mutableConcreteClass] allocWithZone: z]
initWithSet: self];
}
@end
@implementation NSSetNonCore
/* Same as NSArray */
- initWithObjects: firstObject rest: (va_list)ap
{
register unsigned i;
register unsigned curSize;
auto unsigned prevSize;
auto unsigned newSize;
auto id *objsArray;
auto id tmpId;
/* Do initial allocation. */
prevSize = 3;
curSize = 5;
OBJC_MALLOC(objsArray, id, curSize);
tmpId = firstObject;
/* Loop through adding objects to array until a nil is
* found.
*/
for (i = 0; tmpId != nil; i++)
{
/* Put id into array. */
objsArray[i] = tmpId;
/* If the index equals the current size, increase size. */
if (i == curSize - 1)
{
/* Fibonacci series. Supposedly, for this application,
* the fibonacci series will be more memory efficient.
*/
newSize = prevSize + curSize;
prevSize = curSize;
curSize = newSize;
/* Reallocate object array. */
OBJC_REALLOC(objsArray, id, curSize);
}
tmpId = va_arg(ap, id);
}
va_end( ap );
/* Put object ids into NSSet. */
self = [self initWithObjects: objsArray count: i];
OBJC_FREE( objsArray );
return( self );
}
/* Same as NSArray */
@ -162,6 +251,21 @@ static Class NSMutableSet_concrete_class;
return [self initWithObjects:NULL count:0];
}
- initWithArray: (NSArray*)other
{
unsigned count = [other count];
if (count == 0) {
return [self init];
}
else {
id objs[count];
[other getObjects: objs];
return [self initWithObjects: objs count: count];
}
}
- initWithSet: (NSSet*)other copyItems: (BOOL)flag
{
int c = [other count];
@ -176,7 +280,11 @@ static Class NSMutableSet_concrete_class;
os[i] = o;
i++;
}
return [self initWithObjects:os count:c];
self = [self initWithObjects:os count:c];
if (flag)
while (--i)
[os[i] release];
return self;
}
- initWithSet: (NSSet*)other
@ -216,23 +324,6 @@ static Class NSMutableSet_concrete_class;
return (([self member:anObject]) ? YES : NO);
}
- (unsigned) count
{
[self subclassResponsibility:_cmd];
return 0;
}
- member: anObject
{
return [self subclassResponsibility:_cmd];
return 0;
}
- (NSEnumerator*) objectEnumerator
{
return [self subclassResponsibility:_cmd];
}
- (void) makeObjectsPerform: (SEL)aSelector
{
id o, e = [self objectEnumerator];
@ -322,62 +413,16 @@ static Class NSMutableSet_concrete_class;
return [[self allObjects] descriptionWithLocale: locale];
}
- copyWithZone: (NSZone*)z
{
/* a deep copy */
int count = [self count];
id objects[count];
id enumerator = [self objectEnumerator];
id o;
NSSet *newSet;
int i;
BOOL needCopy = [self isKindOfClass: [NSMutableSet class]];
if (NSShouldRetainWithZone(self, z) == NO)
needCopy = YES;
for (i = 0; (o = [enumerator nextObject]); i++)
{
objects[i] = [o copyWithZone:z];
if (objects[i] != o)
needCopy = YES;
}
if (needCopy)
newSet = [[[[self class] _concreteClass] alloc]
initWithObjects:objects
count:count];
else
newSet = [self retain];
for (i = 0; i < count; i++)
[objects[i] release];
return newSet;
}
- mutableCopyWithZone: (NSZone*)z
{
/* a shallow copy */
return [[[[[self class] _mutableConcreteClass] _mutableConcreteClass] alloc]
initWithSet:self];
}
- initWithCoder: aCoder
{
[self subclassResponsibility:_cmd];
return nil;
}
- (void) encodeWithCoder: aCoder
{
[self subclassResponsibility:_cmd];
}
@end
@implementation NSMutableSet
+ allocWithZone: (NSZone*)z
+ (void) initialize
{
return NSAllocateObject([self _mutableConcreteClass], 0, z);
if (self == [NSMutableSet class]) {
behavior_class_add_class(self, [NSMutableSetNonCore class]);
behavior_class_add_class(self, [NSSetNonCore class]);
}
}
+ setWithCapacity: (unsigned)numItems
@ -386,12 +431,31 @@ static Class NSMutableSet_concrete_class;
autorelease];
}
+ allocWithZone: (NSZone*)z
{
return NSAllocateObject([self _mutableConcreteClass], 0, z);
}
/* This is the designated initializer */
- initWithCapacity: (unsigned)numItems
{
return [self subclassResponsibility:_cmd];
}
- (void) addObject: anObject
{
[self subclassResponsibility:_cmd];
}
- (void) removeObject: anObject
{
[self subclassResponsibility:_cmd];
}
@end
@implementation NSMutableSetNonCore
/* Override superclass's designated initializer */
- initWithObjects: (id*)objects
count: (unsigned)count
@ -402,11 +466,6 @@ static Class NSMutableSet_concrete_class;
return self;
}
- (void) addObject: anObject
{
[self subclassResponsibility:_cmd];
}
- (void) addObjectsFromArray: (NSArray*)array
{
int i, c = [array count];
@ -448,9 +507,4 @@ static Class NSMutableSet_concrete_class;
[self subclassResponsibility:_cmd];
}
- (void) removeObject: anObject
{
[self subclassResponsibility:_cmd];
}
@end