1994-11-04 16:29:24 +00:00
|
|
|
|
/* Implementation for Objective-C Set collection object
|
1996-01-05 04:12:08 +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
|
1999-09-09 02:56:20 +00:00
|
|
|
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
1994-11-04 16:29:24 +00:00
|
|
|
|
*/
|
|
|
|
|
|
1997-11-06 00:51:23 +00:00
|
|
|
|
#include <config.h>
|
1998-12-20 21:27:47 +00:00
|
|
|
|
#include <base/Set.h>
|
|
|
|
|
#include <base/CollectionPrivate.h>
|
|
|
|
|
#include <base/Coder.h>
|
1996-02-22 15:11:43 +00:00
|
|
|
|
#include <Foundation/NSHashTable.h>
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
|
|
|
|
#define DEFAULT_SET_CAPACITY 32
|
|
|
|
|
|
|
|
|
|
@implementation Set
|
|
|
|
|
|
|
|
|
|
// MANAGING CAPACITY;
|
|
|
|
|
|
|
|
|
|
/* Eventually we will want to have better capacity management,
|
|
|
|
|
potentially keep default capacity as a class variable. */
|
|
|
|
|
|
|
|
|
|
+ (unsigned) defaultCapacity
|
|
|
|
|
{
|
|
|
|
|
return DEFAULT_SET_CAPACITY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// INITIALIZING AND FREEING;
|
|
|
|
|
|
|
|
|
|
/* This is the designated initializer of this class */
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- initWithCapacity: (unsigned)cap
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1998-09-10 04:48:50 +00:00
|
|
|
|
_contents_hash = NSCreateHashTable(NSObjectHashCallBacks, cap);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* Override Collection's designated initializer */
|
|
|
|
|
- initWithObjects: (id*)objs count: (unsigned)count
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[self initWithCapacity: count];
|
|
|
|
|
while (count--)
|
|
|
|
|
[self addObject: objs[count]];
|
1995-04-09 01:53:53 +00:00
|
|
|
|
return self;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
/* Archiving must mimic the above designated initializer */
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- _initCollectionWithCoder: aCoder
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[super _initCollectionWithCoder:aCoder];
|
1998-09-10 04:48:50 +00:00
|
|
|
|
_contents_hash = NSCreateHashTable(NSObjectHashCallBacks,
|
1996-02-22 15:11:43 +00:00
|
|
|
|
DEFAULT_SET_CAPACITY);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Empty copy must empty an allocCopy'ed version of self */
|
|
|
|
|
- emptyCopy
|
|
|
|
|
{
|
|
|
|
|
Set *copy = [super emptyCopy];
|
|
|
|
|
copy->_contents_hash =
|
1998-09-10 04:48:50 +00:00
|
|
|
|
NSCreateHashTable (NSObjectHashCallBacks, 0);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return copy;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) dealloc
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1998-08-01 21:30:06 +00:00
|
|
|
|
if (_contents_hash)
|
|
|
|
|
{
|
|
|
|
|
NSFreeHashTable (_contents_hash);
|
|
|
|
|
_contents_hash = 0;
|
|
|
|
|
}
|
1997-09-23 14:03:36 +00:00
|
|
|
|
[super dealloc];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SET OPERATIONS;
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) intersectWithCollection: (id <Collecting>)aCollection
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[self removeContentsNotIn: aCollection];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) unionWithCollection: (id <Collecting>)aCollection
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[self addContentsIfAbsentOf: aCollection];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) differenceWithCollection: (id <Collecting>)aCollection
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[self removeContentsIn: aCollection];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- shallowCopyIntersectWithCollection: (id <Collecting>)aCollection
|
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[self notImplemented: _cmd];
|
|
|
|
|
return nil;
|
|
|
|
|
#if 0
|
1994-11-04 16:29:24 +00:00
|
|
|
|
id newColl = [self emptyCopyAs:[self species]];
|
|
|
|
|
void doIt(elt e)
|
|
|
|
|
{
|
|
|
|
|
if ([aCollection includesElement:e])
|
|
|
|
|
[newColl addElement:e];
|
|
|
|
|
}
|
|
|
|
|
[self withElementsCall:doIt];
|
|
|
|
|
return newColl;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
#endif
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- shallowCopyUnionWithCollection: (id <Collecting>)aCollection
|
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[self notImplemented: _cmd];
|
|
|
|
|
return nil;
|
|
|
|
|
#if 0
|
1994-11-04 16:29:24 +00:00
|
|
|
|
id newColl = [self shallowCopy];
|
|
|
|
|
[newColl addContentsOf:aCollection];
|
|
|
|
|
return newColl;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
#endif
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- shallowCopyDifferenceWithCollection: (id <Collecting>)aCollection
|
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
[self notImplemented: _cmd];
|
|
|
|
|
return nil;
|
|
|
|
|
#if 0
|
1994-11-04 16:29:24 +00:00
|
|
|
|
id newColl = [self emptyCopyAs:[self species]];
|
|
|
|
|
void doIt(elt e)
|
|
|
|
|
{
|
|
|
|
|
if (![aCollection includesElement:e])
|
|
|
|
|
[newColl addElement:e];
|
|
|
|
|
}
|
|
|
|
|
[self withElementsCall:doIt];
|
|
|
|
|
return newColl;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
#endif
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
1994-11-04 16:29:24 +00:00
|
|
|
|
// ADDING;
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) addObject: newObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
NSHashInsert (_contents_hash, newObject);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
1994-11-04 16:29:24 +00:00
|
|
|
|
// REMOVING AND REPLACING;
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) removeObject: oldObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
NSHashRemove (_contents_hash, oldObject);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This must work without sending any messages to content objects */
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) _collectionEmpty
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
NSResetHashTable (_contents_hash);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (void) uniqueContents
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
return;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
1994-11-04 16:29:24 +00:00
|
|
|
|
// TESTING;
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- (BOOL) containsObject: anObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
return (NSHashGet (_contents_hash, anObject) ? 1 : 0);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (unsigned) count
|
|
|
|
|
{
|
1997-09-23 14:03:36 +00:00
|
|
|
|
if (!_contents_hash)
|
|
|
|
|
return 0;
|
1996-02-22 15:11:43 +00:00
|
|
|
|
return NSCountHashTable (_contents_hash);
|
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
|
|
|
|
if ([self containsObject: anObject])
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return 1;
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
1997-11-06 00:51:23 +00:00
|
|
|
|
- member: anObject
|
|
|
|
|
{
|
|
|
|
|
return NSHashGet(_contents_hash, anObject);
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
|
1994-11-04 16:29:24 +00:00
|
|
|
|
// ENUMERATING;
|
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
- nextObjectWithEnumState: (void**)enumState
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-03-22 02:33:33 +00:00
|
|
|
|
return NSNextHashEnumeratorItem ((*(NSHashEnumerator**)enumState));
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void*) newEnumState
|
|
|
|
|
{
|
1996-02-22 15:11:43 +00:00
|
|
|
|
void *es;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:11:43 +00:00
|
|
|
|
OBJC_MALLOC (es, NSMapEnumerator, 1);
|
|
|
|
|
*((NSHashEnumerator*)es) = NSEnumerateHashTable (_contents_hash);
|
|
|
|
|
return es;
|
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
|
|
|
|
OBJC_FREE (*enumState);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|