1 /** Interface for NSSet, NSMutableSet, NSCountedSet for GNUStep
2    Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
3 
4    Written by:  Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
5    Created: Sep 1995
6 
7    This file is part of the GNUstep Base Library.
8 
9    This library is free software; you can redistribute it and/or
10    modify it under the terms of the GNU Lesser General Public
11    License as published by the Free Software Foundation; either
12    version 2 of the License, or (at your option) any later version.
13 
14    This library is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    Lesser General Public License for more details.
18 
19    You should have received a copy of the GNU Lesser General Public
20    License along with this library; if not, write to the Free
21    Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22    Boston, MA 02110 USA.
23 
24    AutogsdocSource: NSSet.m
25    AutogsdocSource: NSCountedSet.m
26 
27    */
28 
29 #ifndef _NSSet_h_GNUSTEP_BASE_INCLUDE
30 #define _NSSet_h_GNUSTEP_BASE_INCLUDE
31 #import	<GNUstepBase/GSVersionMacros.h>
32 
33 #import	<Foundation/NSObject.h>
34 #import <Foundation/NSEnumerator.h>
35 #import <GNUstepBase/GSBlocks.h>
36 
37 #if	defined(__cplusplus)
38 extern "C" {
39 #endif
40 
41 @class GS_GENERIC_CLASS(NSArray, ElementT);
42 @class GS_GENERIC_CLASS(NSEnumerator, ElementT);
43 @class GS_GENERIC_CLASS(NSDictionary, KeyT:id<NSCopying>, ValT);
44 @class NSString;
45 
46 @interface GS_GENERIC_CLASS(NSSet, __covariant ElementT) : NSObject <NSCoding,
47                                                              NSCopying,
48                                                              NSMutableCopying,
49                                                              NSFastEnumeration>
50 
51 + (instancetype) set;
52 + (instancetype) setWithArray: (GS_GENERIC_CLASS(NSArray, ElementT)*)objects;
53 + (instancetype) setWithObject: (GS_GENERIC_TYPE(ElementT))anObject;
54 + (instancetype) setWithObjects: (GS_GENERIC_TYPE(ElementT))firstObject, ...;
55 #if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
56 + (instancetype) setWithObjects: (const GS_GENERIC_TYPE(ElementT)[])objects
57 		                  count: (NSUInteger)count;
58 #endif
59 + (instancetype) setWithSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)aSet;
60 
61 - (GS_GENERIC_CLASS(NSArray, ElementT)*) allObjects;
62 - (GS_GENERIC_TYPE(ElementT)) anyObject;
63 - (BOOL) containsObject: (GS_GENERIC_TYPE(ElementT))anObject;
64 - (NSUInteger) count;
65 - (NSString*) description;
66 - (NSString*) descriptionWithLocale: (id)locale;
67 
68 - (instancetype) init;
69 - (instancetype) initWithArray: (GS_GENERIC_CLASS(NSArray, ElementT)*)other;
70 - (instancetype) initWithObjects: (GS_GENERIC_TYPE(ElementT))firstObject, ...;
71 - (instancetype) initWithObjects: (const GS_GENERIC_TYPE(ElementT)[])objects
72 		                   count: (NSUInteger)count;
73 - (instancetype) initWithSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
74 - (instancetype) initWithSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other
75                    copyItems: (BOOL)flag;
76 
77 - (BOOL) intersectsSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)otherSet;
78 - (BOOL) isEqualToSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
79 - (BOOL) isSubsetOfSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)otherSet;
80 
81 - (void) makeObjectsPerform: (SEL)aSelector;
82 - (void) makeObjectsPerform: (SEL)aSelector withObject: (id)argument;
83 #if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
84 - (void) makeObjectsPerformSelector: (SEL)aSelector;
85 - (void) makeObjectsPerformSelector: (SEL)aSelector withObject: (id)argument;
86 #endif
87 - (GS_GENERIC_TYPE(ElementT)) member: (GS_GENERIC_TYPE(ElementT))anObject;
88 - (GS_GENERIC_CLASS(NSEnumerator, ElementT)*) objectEnumerator;
89 
90 #if OS_API_VERSION(MAC_OS_X_VERSION_10_6, GS_API_LATEST)
91 
92 DEFINE_BLOCK_TYPE(GSSetEnumeratorBlock, void, GS_GENERIC_TYPE(ElementT), BOOL*);
93 DEFINE_BLOCK_TYPE(GSSetFilterBlock, BOOL, GS_GENERIC_TYPE(ElementT), BOOL*);
94 
95 /**
96  * Enumerate over the collection using a given block.  The first argument is
97  * the object.  The second argument is a pointer to a BOOL indicating
98  * whether the enumeration should stop.  Setting this to YES will interupt
99  * the enumeration.
100  */
101 - (void) enumerateObjectsUsingBlock:(GSSetEnumeratorBlock)aBlock;
102 
103 /**
104  * Enumerate over the collection using the given block.  The first argument is
105  * the object.  The second argument is a pointer to a BOOL indicating whether
106  * the enumeration should stop.  Setting  this to YES will interrupt the
107  * enumeration.
108  *
109  * The opts argument is a bitfield.  Setting the NSNSEnumerationConcurrent flag
110  * specifies that it is thread-safe.  The NSEnumerationReverse bit specifies
111  * that it should be enumerated in reverse order.
112  */
113 - (void) enumerateObjectsWithOptions: (NSEnumerationOptions)opts
114                           usingBlock: (GSSetEnumeratorBlock)aBlock;
115 
116 - (GS_GENERIC_CLASS(NSSet, ElementT) *) objectsPassingTest:
117     (GSSetFilterBlock)aBlock;
118 
119 - (GS_GENERIC_CLASS(NSSet, ElementT) *) objectsWithOptions:
120     (NSEnumerationOptions)opts
121                                     passingTest: (GSSetFilterBlock)aBlock;
122 #endif
123 
124 #if OS_API_VERSION(MAC_OS_X_VERSION_10_5,GS_API_LATEST)
125 - (GS_GENERIC_CLASS(NSSet, ElementT) *) setByAddingObject:
126     (GS_GENERIC_TYPE(ElementT))anObject;
127 - (GS_GENERIC_CLASS(NSSet, ElementT) *) setByAddingObjectsFromSet:
128     (GS_GENERIC_CLASS(NSSet, ElementT) *)other;
129 - (GS_GENERIC_CLASS(NSSet, ElementT) *) setByAddingObjectsFromArray:
130     (GS_GENERIC_CLASS(NSArray, ElementT) *)other;
131 #endif
132 @end
133 
134 @interface GS_GENERIC_CLASS(NSMutableSet, ElementT):
135   GS_GENERIC_CLASS(NSSet, ElementT)
136 
137 + (instancetype) setWithCapacity: (NSUInteger)numItems;
138 
139 - (void) addObject: (GS_GENERIC_TYPE(ElementT))anObject;
140 - (void) addObjectsFromArray: (GS_GENERIC_CLASS(NSArray, ElementT)*)array;
141 - (instancetype) initWithCapacity: (NSUInteger)numItems;
142 - (void) intersectSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
143 - (void) minusSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
144 - (void) removeAllObjects;
145 - (void) removeObject: (GS_GENERIC_TYPE(ElementT))anObject;
146 #if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
147 - (void) setSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
148 #endif
149 - (void) unionSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
150 @end
151 
152 @interface GS_GENERIC_CLASS(NSCountedSet, ElementT) :
153   GS_GENERIC_CLASS(NSMutableSet, ElementT)
154 
155 - (NSUInteger) countForObject: (GS_GENERIC_TYPE(ElementT))anObject;
156 
157 @end
158 
159 #if OS_API_VERSION(GS_API_NONE, GS_API_NONE)
160 
161 /**
162  * Utility methods for using a counted set to handle uniquing of objects.
163  */
164 @interface GS_GENERIC_CLASS(NSCountedSet, ElementT) (GNU_Uniquing)
165 /**
166  * <p>
167  *   This method removes from the set all objects whose count is
168  *   less than or equal to the specified value.
169  * </p>
170  * <p>
171  *   This is useful where a counted set is used for uniquing objects.
172  *   The set can be periodically purged of objects that have only
173  *   been added once - and are therefore simply wasting space.
174  * </p>
175  */
176 - (void) purge: (NSInteger)level;
177 
178 /**
179  * <p>
180  *   If the supplied object (or one equal to it as determined by
181  *   the [NSObject-isEqual:] method) is already present in the set, the
182  *   count for that object is incremented, the supplied object
183  *   is released, and the object in the set is retained and returned.
184  *   Otherwise, the supplied object is added to the set and returned.
185  * </p>
186  * <p>
187  *   This method is useful for uniquing objects - the init method of
188  *   a class need simply end with -
189  *   <code>
190  *     return [myUniquingSet unique: self];
191  *   </code>
192  * </p>
193  */
194 - (GS_GENERIC_TYPE(ElementT)) unique:
195     (GS_GENERIC_TYPE(ElementT)) NS_CONSUMED anObject NS_RETURNS_RETAINED;
196 @end
197 
198 /*
199  * Functions for managing a global uniquing set.
200  */
201 
202 /*
203  * GSUniquing() turns on/off the action of the GSUnique() function.
204  * if uniquing is turned off, GSUnique() simply returns its argument.
205  *
206  */
207 void	GSUniquing(BOOL flag);
208 
209 /*
210  * GSUnique() returns an object that is equal to the one passed to it.
211  * If the returned object is not the same object as the object passed in,
212  * the original object is released and the returned object is retained.
213  * Thus, an -init method that wants to implement uniquing simply needs
214  * to end with 'return GSUnique(self);'
215  */
216 id	GSUnique(id NS_CONSUMED anObject) NS_RETURNS_RETAINED;
217 
218 /*
219  * Management functions -
220  */
221 
222 /*
223  * GSUPurge() can be used to purge infrequently referenced objects from the
224  * set by removing any objec whose count is less than or equal to that given.
225  *
226  */
227 void	GSUPurge(NSUInteger count);
228 
229 /*
230  * GSUSet() can be used to artificially set the count for a particular object
231  * Setting the count to zero will remove the object from the global set.
232  */
233 id	GSUSet(id anObject, NSUInteger count);
234 
235 #endif	/* GS_API_NONE */
236 
237 #if	defined(__cplusplus)
238 }
239 #endif
240 
241 #endif
242