1
1
/** NSSet - Set object to store key/value pairs
2
2
Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
4
4
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
7
7
This file is part of the GNUstep Base Library.
9
9
This library is free software; you can redistribute it and/or
10
10
modify it under the terms of the GNU Library General Public
11
11
License as published by the Free Software Foundation; either
12
12
version 2 of the License, or (at your option) any later version.
14
14
This library is distributed in the hope that it will be useful,
15
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
17
Library General Public License for more details.
19
19
You should have received a copy of the GNU Library General Public
20
20
License along with this library; if not, write to the Free
21
21
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
23
23
<title>NSSet class reference</title>
24
$Date: 2001/12/18 16:54:15 $ $Revision: 1.39 $
24
$Date: 2005/02/22 11:22:44 $ $Revision: 1.55 $
28
#include <base/behavior.h>
29
#include <Foundation/NSSet.h>
30
#include <Foundation/NSCoder.h>
31
#include <Foundation/NSArray.h>
32
#include <Foundation/NSUtilities.h>
33
#include <Foundation/NSString.h>
34
#include <Foundation/NSException.h>
35
#include <Foundation/NSObjCRuntime.h>
36
#include <Foundation/NSDebug.h>
28
#include "Foundation/NSSet.h"
29
#include "Foundation/NSCoder.h"
30
#include "Foundation/NSArray.h"
31
#include "Foundation/NSUtilities.h"
32
#include "Foundation/NSString.h"
33
#include "Foundation/NSException.h"
34
#include "Foundation/NSObjCRuntime.h"
35
#include "Foundation/NSDebug.h"
36
// For private method _decodeArrayOfObjectsForKey:
37
#include "Foundation/NSKeyedArchiver.h"
38
#include "GNUstepBase/GSCategories.h"
39
#include "GSPrivate.h"
39
42
@class GSMutableSet;
45
* <code>NSSet</code> maintains an unordered collection of unique objects
46
* (according to [NSObject-isEqual:]). When a duplicate object is added
47
* to the set, it replaces its old copy.
43
51
static Class NSSet_abstract_class;
44
52
static Class NSMutableSet_abstract_class;
80
* New autoreleased empty set.
73
84
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()] init]);
88
* New set containing (unique elements of) objects.
76
90
+ (id) setWithArray: (NSArray*)objects
78
92
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
79
93
initWithArray: objects]);
97
* New set containing single object anObject.
82
99
+ (id) setWithObject: anObject
84
101
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
85
102
initWithObjects: &anObject count: 1]);
88
+ (id) setWithObjects: (id*)objects
106
* New set containing (unique elements of) objects.
108
+ (id) setWithObjects: (id*)objects
89
109
count: (unsigned)count
91
111
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
92
112
initWithObjects: objects count: count]);
116
* New set with objects in given nil-terminated list.
95
118
+ (id) setWithObjects: firstObject, ...
99
va_start(ap, firstObject);
100
set = [[self allocWithZone: NSDefaultMallocZone()]
101
initWithObjects: firstObject rest: ap];
122
GS_USEIDLIST(firstObject,
123
set = [[self allocWithZone: NSDefaultMallocZone()]
124
initWithObjects: __objects count: __count]);
103
125
return AUTORELEASE(set);
106
131
+ (id) setWithSet: (NSSet*)aSet
108
133
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
128
164
- (void) encodeWithCoder: (NSCoder*)aCoder
130
unsigned count = [self count];
131
NSEnumerator *e = [self objectEnumerator];
134
[aCoder encodeValueOfObjCType: @encode(unsigned) at: &count];
135
while ((o = [e nextObject]) != nil)
137
[aCoder encodeValueOfObjCType: @encode(id) at: &o];
166
if ([aCoder allowsKeyedCoding])
168
/* HACK ... MacOS-X seems to code differently if the coder is an
169
* actual instance of NSKeyedArchiver
171
if ([aCoder class] == [NSKeyedArchiver class])
173
[(NSKeyedArchiver*)aCoder _encodeArrayOfObjects: [self allObjects]
174
forKey: @"NS.objects"];
179
NSEnumerator *e = [self objectEnumerator];
182
while ((o = [e nextObject]) != nil)
186
key = [NSString stringWithFormat: @"NS.object.%u", i++];
187
[(NSKeyedArchiver*)aCoder encodeObject: o forKey: key];
193
unsigned count = [self count];
194
NSEnumerator *e = [self objectEnumerator];
197
[aCoder encodeValueOfObjCType: @encode(unsigned) at: &count];
198
while ((o = [e nextObject]) != nil)
200
[aCoder encodeValueOfObjCType: @encode(id) at: &o];
141
205
- (id) initWithCoder: (NSCoder*)aCoder
146
209
c = GSObjCClass(self);
156
219
self = [NSMutableSet_concrete_class allocWithZone: NSDefaultMallocZone()];
157
220
return [self initWithCoder: aCoder];
159
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &count];
164
for (i = 0; i < count; i++)
166
[aCoder decodeValueOfObjCType: @encode(id) at: &objs[i]];
168
return [self initWithObjects: objs count: count];
172
/* This is the designated initializer */
223
if ([aCoder allowsKeyedCoding])
227
array = [(NSKeyedUnarchiver*)aCoder _decodeArrayOfObjectsForKey:
235
array = [NSMutableArray arrayWithCapacity: 2];
236
key = [NSString stringWithFormat: @"NS.object.%u", i];
237
val = [(NSKeyedUnarchiver*)aCoder decodeObjectForKey: key];
241
[array addObject: val];
243
key = [NSString stringWithFormat: @"NS.object.%u", i];
244
val = [(NSKeyedUnarchiver*)aCoder decodeObjectForKey: key];
247
self = [self initWithArray: array];
253
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &count];
257
GS_BEGINIDBUF(objs, count);
259
for (i = 0; i < count; i++)
261
[aCoder decodeValueOfObjCType: @encode(id) at: &objs[i]];
263
self = [self initWithObjects: objs count: count];
267
[objs[count] release];
277
* <p>In MacOS-X class clusters do not have designated initialisers,
278
* and there is a general rule that -init is treated as the designated
279
* initialiser of the class cluster, but that other intitialisers
280
* may not work s expected an would need to be individually overridden
283
* <p>GNUstep tries to make it easier to subclass a class cluster,
284
* by making class clusters follow the same convention as normal
285
* classes, so the designated initialiser is the <em>richest</em>
286
* initialiser. This means that all other initialisers call the
287
* documented designated initialiser (which calls -init only for
288
* MacOS-X compatibility), and anyone writing a subclass only needs
289
* to override that one initialiser in order to have all the other
292
* <p>For MacOS-X compatibility, you may also need to override various
293
* other initialisers. Exactly which ones, you will need to determine
294
* by trial on a MacOS-X system ... and may vary between releases of
295
* MacOS-X. So to be safe, on MacOS-X you probably need to re-implement
296
* <em>all</em> the class cluster initialisers you might use in conjunction
297
* with your subclass.
306
/** <init /> <override-subclass />
307
* Initialize to contain (unique elements of) objects.<br />
308
* Calls -init (which does nothing but maintain MacOS-X compatibility),
309
* and needs to be re-implemented in subclasses in order to have all
310
* other initialisers work.
173
312
- (id) initWithObjects: (id*)objects
174
313
count: (unsigned)count
176
[self subclassResponsibility: _cmd];
320
* If anObject is in set, return it (the copy in the set).
180
322
- (id) member: (id)anObject
182
324
return [self subclassResponsibility: _cmd];
329
* Returns a new instance containing the same objects as
330
* the receiver.<br />
331
* The default implementation does this by calling the
332
* -initWithSet:copyItems: method on a newly created object,
333
* and passing it NO to tell it just to retain the items.
186
335
- (id) mutableCopyWithZone: (NSZone*)z
188
return [[NSMutableSet_concrete_class allocWithZone: z] initWithSet: self];
337
NSMutableSet *copy = [NSMutableSet_concrete_class allocWithZone: z];
339
return [copy initWithSet: self copyItems: NO];
343
* Return enumerator over objects in set. Order is undefined.
191
345
- (NSEnumerator*) objectEnumerator
193
347
return [self subclassResponsibility: _cmd];
196
/* Same as NSArray */
197
- (id) initWithObjects: firstObject rest: (va_list)ap
200
register unsigned curSize;
201
auto unsigned prevSize;
202
auto unsigned newSize;
206
/* Do initial allocation. */
209
objsArray = (id*)NSZoneMalloc(NSDefaultMallocZone(), sizeof(id) * curSize);
212
/* Loop through adding objects to array until a nil is
215
for (i = 0; tmpId != nil; i++)
217
/* Put id into array. */
218
objsArray[i] = tmpId;
220
/* If the index equals the current size, increase size. */
221
if (i == curSize - 1)
223
/* Fibonacci series. Supposedly, for this application,
224
* the fibonacci series will be more memory efficient.
226
newSize = prevSize + curSize;
230
/* Reallocate object array. */
231
objsArray = (id*)NSZoneRealloc(NSDefaultMallocZone(), objsArray,
232
sizeof(id) * curSize);
234
tmpId = va_arg(ap, id);
238
/* Put object ids into NSSet. */
239
self = [self initWithObjects: objsArray count: i];
240
NSZoneFree(NSDefaultMallocZone(), objsArray);
244
/* Same as NSArray */
351
* Initialize with (unique elements of) objects in given nil-terminated list.
245
353
- (id) initWithObjects: firstObject, ...
248
va_start(ap, firstObject);
249
self = [self initWithObjects: firstObject rest: ap];
355
GS_USEIDLIST(firstObject,
356
self = [self initWithObjects: __objects count: __count]);
254
/* Override superclass's designated initializer */
257
return [self initWithObjects: NULL count: 0];
361
* Initialises a newly allocated set by adding all the objects
362
* in the supplied array to the set.
260
364
- (id) initWithArray: (NSArray*)other
262
366
unsigned count = [other count];
482
649
return NSMutableSet_concrete_class;
485
- (id) copyWithZone: (NSZone*)z
487
return [[NSSet_concrete_class allocWithZone: z] initWithSet: self];
490
/* This is the designated initializer */
652
/** <init /> <override-subclass />
653
* Initialises a newly allocated set to contain no objects but
654
* to have space available to hold the specified number of items.<br />
655
* Additions of items to a set initialised
656
* with an appropriate capacity will be more efficient than addition
657
* of items otherwise.<br />
658
* Calls -init (which does nothing but maintain MacOS-X compatibility),
659
* and needs to be re-implemented in subclasses in order to have all
660
* other initialisers work.
491
662
- (id) initWithCapacity: (unsigned)numItems
493
return [self subclassResponsibility: _cmd];
669
* Adds anObject to the set.<br />
670
* The object is retained by the set.
496
672
- (void) addObject: (id)anObject
498
674
[self subclassResponsibility: _cmd];
678
* Removes the anObject from the receiver.
501
680
- (void) removeObject: (id)anObject
503
682
[self subclassResponsibility: _cmd];