Modify the interfaces of all collection classes to be compatible with the

new lightweight generics implemenation. (Newer MacOS X/iOS code assuming 
the presence of the generics annotations can otherwise not be compiled with
GNUstep). This should be well-behaved under clang and gcc both. 

Fix NSCache which was copying the cache keys when it really shouldn't
have. Added a few test cases for eviction behaviour.

Few smaller tweaks to avoid compiler warnings.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@39406 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
thebeing 2016-02-22 21:04:18 +00:00
parent a01485a16a
commit d50d5dac36
14 changed files with 541 additions and 273 deletions

View file

@ -1,3 +1,28 @@
2016-02-22 Niels Grewe <niels.grewe@halbordnung.de>
* Headers/Foundation/NSObjCRuntime.h: Add macros for backwards-
compatible generics annotations. Also define instancetype if necessary.
* Headers/Foundation/NSArray.h
* Headers/Foundation/NSCache.h
* Headers/Foundation/NSDictionary.h
* Headers/Foundation/NSEnumerator.h
* Headers/Foundation/NSSet.h: Update interfaces for instancetype and
generics.
* Source/NSCache.m: Use NSMapTable instead of NSMutableDictionary.
The API contract for NSCache stipulates that keys are not copied, so
using a dictionary wasn't apropriate.
* Source/NSConnection.m
* Source/NSData.m: Small type safety improvements (mostly to keep the
compiler happy).
* Source/NSDictionary.m: Change id to id<NSCopying> in a few places to
avoid compiler warnings.
* Tests/base/NSCache
* Tests/base/NSCache/TestInfo
* Tests/base/NSCache/basic.m
* Tests/base/NSCache/cache.m:
Test cases eviction from NSCache. Turns out we currently only evict
NSDiscardableContent, while the API documentation seems to suggest that cost
and count based eviction without NSDiscardableContent is also possible.
2016-02-18 Richard Frith-Macdonald <rfm@gnu.org>
* Source/Additions/GSMime.m:
@ -65,7 +90,7 @@
thread object.
Instead, we add it to a map table, keyed under the current thread ID,
and use that in GSCurrentThread() to find the correct NSThread object
if pthread_getspecific wont return it to us.
if pthread_getspecific wont return it to us.
* Tests/base/NSThread/late_unregister.m: Test case for late
unregistration.

View file

@ -3,24 +3,24 @@
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: 1995
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser 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 Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
*/
*/
#ifndef __NSArray_h_GNUSTEP_BASE_INCLUDE
#define __NSArray_h_GNUSTEP_BASE_INCLUDE
@ -57,43 +57,49 @@ enum
typedef NSUInteger NSBinarySearchingOptions;
#endif
@interface NSArray : NSObject
@interface GS_GENERIC_CLASS(NSArray, __covariant ElementT) : NSObject
<NSCoding, NSCopying, NSMutableCopying, NSFastEnumeration>
+ (id) array;
+ (id) arrayWithArray: (NSArray*)array;
+ (id) arrayWithContentsOfFile: (NSString*)file;
+ (instancetype) array;
+ (instancetype) arrayWithArray: (GS_GENERIC_CLASS(NSArray, ElementT) *)array;
+ (instancetype) arrayWithContentsOfFile: (NSString*)file;
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
+ (id) arrayWithContentsOfURL: (NSURL*)aURL;
+ (instancetype) arrayWithContentsOfURL: (NSURL*)aURL;
#endif
+ (id) arrayWithObject: (id)anObject;
+ (id) arrayWithObjects: (id)firstObject, ...;
+ (id) arrayWithObjects: (const id[])objects count: (NSUInteger)count;
+ (instancetype) arrayWithObject: (id)anObject;
+ (instancetype) arrayWithObjects: (id)firstObject, ...;
+ (instancetype) arrayWithObjects: (const id[])objects count: (NSUInteger)count;
- (NSArray*) arrayByAddingObject: (id)anObject;
- (NSArray*) arrayByAddingObjectsFromArray: (NSArray*)anotherArray;
- (BOOL) containsObject: anObject;
- (GS_GENERIC_CLASS(NSArray, ElementT) *) arrayByAddingObject:
(GS_GENERIC_TYPE(ElementT))anObject;
- (GS_GENERIC_CLASS(NSArray, ElementT) *) arrayByAddingObjectsFromArray:
(GS_GENERIC_CLASS(NSArray, ElementT)*)anotherArray;
- (BOOL) containsObject: (GS_GENERIC_TYPE(ElementT))anObject;
/** <override-subclass />
* Returns the number of elements contained in the receiver.
*/
- (NSUInteger) count;
- (void) getObjects: (__unsafe_unretained id[])aBuffer;
- (void) getObjects: (__unsafe_unretained id[])aBuffer range: (NSRange)aRange;
- (NSUInteger) indexOfObject: (id)anObject;
- (NSUInteger) indexOfObject: (id)anObject inRange: (NSRange)aRange;
- (NSUInteger) indexOfObjectIdenticalTo: (id)anObject;
- (NSUInteger) indexOfObjectIdenticalTo: (id)anObject inRange: (NSRange)aRange;
- (id) init;
- (id) initWithArray: (NSArray*)array;
- (void) getObjects: (__unsafe_unretained GS_GENERIC_TYPE(ElementT)[])aBuffer;
- (void) getObjects: (__unsafe_unretained GS_GENERIC_TYPE(ElementT)[])aBuffer
range: (NSRange)aRange;
- (NSUInteger) indexOfObject: (GS_GENERIC_TYPE(ElementT))anObject;
- (NSUInteger) indexOfObject: (GS_GENERIC_TYPE(ElementT))anObject
inRange: (NSRange)aRange;
- (NSUInteger) indexOfObjectIdenticalTo: (GS_GENERIC_TYPE(ElementT))anObject;
- (NSUInteger) indexOfObjectIdenticalTo: (GS_GENERIC_TYPE(ElementT))anObject
inRange: (NSRange)aRange;
- (instancetype) init;
- (instancetype) initWithArray: (GS_GENERIC_CLASS(NSArray, ElementT)*)array;
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
- (id) initWithArray: (NSArray*)array copyItems: (BOOL)shouldCopy;
- (instancetype) initWithArray: (GS_GENERIC_CLASS(NSArray, ElementT)*)array
copyItems: (BOOL)shouldCopy;
#endif
- (id) initWithContentsOfFile: (NSString*)file;
- (instancetype) initWithContentsOfFile: (NSString*)file;
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
- (id) initWithContentsOfURL: (NSURL*)aURL;
- (instancetype) initWithContentsOfURL: (NSURL*)aURL;
#endif
- (id) initWithObjects: firstObject, ...;
- (instancetype) initWithObjects: (GS_GENERIC_TYPE(ElementT)) firstObject, ...;
/** <init /> <override-subclass />
* This should initialize the array with count (may be zero) objects.<br />
@ -102,24 +108,25 @@ typedef NSUInteger NSBinarySearchingOptions;
* and needs to be re-implemented in subclasses in order to have all
* other initialisers work.
*/
- (id) initWithObjects: (const id[])objects
count: (NSUInteger)count;
- (id) lastObject;
- (instancetype) initWithObjects: (const GS_GENERIC_TYPE(ElementT)[])objects
count: (NSUInteger)count;
- (GS_GENERIC_TYPE(ElementT)) lastObject;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_6, GS_API_LATEST)
- (id) firstObject;
- (GS_GENERIC_TYPE(ElementT)) firstObject;
#endif
/** <override-subclass />
* Returns the object at the specified index.
* Raises an exception of the index is beyond the array.
*/
- (id) objectAtIndex: (NSUInteger)index;
- (GS_GENERIC_TYPE(ElementT)) objectAtIndex: (NSUInteger)index;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST)
- (NSArray *) objectsAtIndexes: (NSIndexSet *)indexes;
- (GS_GENERIC_CLASS(NSArray, ElementT) *) objectsAtIndexes: (NSIndexSet *)indexes;
#endif
- (id) firstObjectCommonWithArray: (NSArray*)otherArray;
- (GS_GENERIC_TYPE(ElementT)) firstObjectCommonWithArray:
(GS_GENERIC_CLASS(NSArray, ElementT) *)otherArray;
- (BOOL) isEqualToArray: (NSArray*)otherArray;
#if OS_API_VERSION(GS_API_OPENSTEP, GS_API_MACOSX)
@ -132,19 +139,22 @@ typedef NSUInteger NSBinarySearchingOptions;
#endif
- (NSData*) sortedArrayHint;
- (NSArray*) sortedArrayUsingFunction: (NSComparisonResult (*)(id, id, void*))comparator
context: (void*)context;
- (NSArray*) sortedArrayUsingFunction: (NSComparisonResult (*)(id, id, void*))comparator
- (GS_GENERIC_CLASS(NSArray, ElementT)*) sortedArrayUsingFunction:
(NSComparisonResult (*)(id, id, void*))comparator
context: (void*)context;
- (GS_GENERIC_CLASS(NSArray, ElementT)*) sortedArrayUsingFunction:
(NSComparisonResult (*)(id, id, void*))comparator
context: (void*)context
hint: (NSData*)hint;
- (NSArray*) sortedArrayUsingSelector: (SEL)comparator;
- (NSArray*) subarrayWithRange: (NSRange)aRange;
hint: (NSData*)hint;
- (GS_GENERIC_CLASS(NSArray, ElementT)*) sortedArrayUsingSelector: (SEL)comparator;
- (GS_GENERIC_CLASS(NSArray, ElementT)*) subarrayWithRange: (NSRange)aRange;
- (NSString*) componentsJoinedByString: (NSString*)separator;
- (NSArray*) pathsMatchingExtensions: (NSArray*)extensions;
- (GS_GENERIC_CLASS(NSArray, NSString*)*) pathsMatchingExtensions:
(GS_GENERIC_CLASS(NSArray, NSString*)*)extensions;
- (NSEnumerator*) objectEnumerator;
- (NSEnumerator*) reverseObjectEnumerator;
- (GS_GENERIC_CLASS(NSEnumerator, ElementT)*) objectEnumerator;
- (GS_GENERIC_CLASS(NSEnumerator, ElementT)*) reverseObjectEnumerator;
- (NSString*) description;
- (NSString*) descriptionWithLocale: (id)locale;
@ -154,14 +164,14 @@ typedef NSUInteger NSBinarySearchingOptions;
- (BOOL) writeToFile: (NSString*)path atomically: (BOOL)useAuxiliaryFile;
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
- (BOOL) writeToURL: (NSURL*)url atomically: (BOOL)useAuxiliaryFile;
- (id) valueForKey: (NSString*)key;
- (void) setValue: (id)value forKey: (NSString*)key;
- (GS_GENERIC_TYPE(ElementT)) valueForKey: (NSString*)key;
- (void) setValue: (GS_GENERIC_TYPE(ElementT))value forKey: (NSString*)key;
#endif
#if OS_API_VERSION(MAC_OS_X_VERSION_10_6, GS_API_LATEST)
DEFINE_BLOCK_TYPE(GSEnumeratorBlock, void, id, NSUInteger, BOOL*);
DEFINE_BLOCK_TYPE(GSPredicateBlock, BOOL, id, NSUInteger, BOOL*);
DEFINE_BLOCK_TYPE(GSEnumeratorBlock, void, GS_GENERIC_TYPE(ElementT), NSUInteger, BOOL*);
DEFINE_BLOCK_TYPE(GSPredicateBlock, BOOL, GS_GENERIC_TYPE(ElementT), NSUInteger, BOOL*);
/**
* Enumerate over the collection using the given block. The first argument is
* the object and the second is the index in the array. The final argument is
@ -180,7 +190,7 @@ DEFINE_BLOCK_TYPE(GSPredicateBlock, BOOL, id, NSUInteger, BOOL*);
* specifies that it is thread-safe. The NSEnumerationReverse bit specifies
* that it should be enumerated in reverse order.
*/
- (void) enumerateObjectsWithOptions: (NSEnumerationOptions)opts
- (void) enumerateObjectsWithOptions: (NSEnumerationOptions)opts
usingBlock: (GSEnumeratorBlock)aBlock;
/**
* Enumerate over the specified indexes in the collection using the given
@ -204,7 +214,7 @@ DEFINE_BLOCK_TYPE(GSPredicateBlock, BOOL, id, NSUInteger, BOOL*);
* specifies that it is thread-safe. The NSEnumerationReverse bit specifies
* that it should be enumerated in reverse order.
*/
- (NSIndexSet *) indexesOfObjectsWithOptions: (NSEnumerationOptions)opts
- (NSIndexSet *) indexesOfObjectsWithOptions: (NSEnumerationOptions)opts
passingTest: (GSPredicateBlock)predicate;
/**
@ -233,7 +243,7 @@ DEFINE_BLOCK_TYPE(GSPredicateBlock, BOOL, id, NSUInteger, BOOL*);
* specifies that it is thread-safe. The NSEnumerationReverse bit specifies
* that it should be enumerated in reverse order.
*/
- (NSUInteger) indexOfObjectWithOptions: (NSEnumerationOptions)opts
- (NSUInteger) indexOfObjectWithOptions: (NSEnumerationOptions)opts
passingTest: (GSPredicateBlock)predicate;
/**
@ -257,7 +267,8 @@ DEFINE_BLOCK_TYPE(GSPredicateBlock, BOOL, id, NSUInteger, BOOL*);
/** Returns a sorted array using the comparator to determine the
* order of objects.
*/
- (NSArray *) sortedArrayUsingComparator: (NSComparator)comparator;
- (GS_GENERIC_CLASS(NSArray, ElementT) *) sortedArrayUsingComparator:
(NSComparator)comparator;
/** Returns a sorted array using the block to determine the order of objects.
*
@ -265,8 +276,9 @@ DEFINE_BLOCK_TYPE(GSPredicateBlock, BOOL, id, NSUInteger, BOOL*);
* specifies that it is thread-safe. The NSSortStable bit specifies that
* it should keep equal objects in the same order.
*/
- (NSArray *) sortedArrayWithOptions: (NSSortOptions)options
usingComparator: (NSComparator)comparator;
- (GS_GENERIC_CLASS(NSArray, ElementT) *)
sortedArrayWithOptions: (NSSortOptions)options
usingComparator: (NSComparator)comparator;
/**
* Performs a binary search of the array within the specified range for the
@ -283,20 +295,20 @@ DEFINE_BLOCK_TYPE(GSPredicateBlock, BOOL, id, NSUInteger, BOOL*);
* Accessor for subscripting. This is called by the compiler when you write
* code like anArray[12]. It should not be called directly.
*/
- (id) objectAtIndexedSubscript: (size_t)anIndex;
- (GS_GENERIC_TYPE(ElementT)) objectAtIndexedSubscript: (size_t)anIndex;
@end
@interface NSMutableArray : NSArray
@interface GS_GENERIC_CLASS(NSMutableArray, ElementT) : NSArray
+ (id) arrayWithCapacity: (NSUInteger)numItems;
+ (instancetype) arrayWithCapacity: (NSUInteger)numItems;
/** <override-subclass />
* Adds anObject at the end of the array, thus increasing the size of
* the array. The object is retained upon addition.
*/
- (void) addObject: (id)anObject;
- (void) addObjectsFromArray: (NSArray*)otherArray;
- (void) addObject: (GS_GENERIC_TYPE(ElementT))anObject;
- (void) addObjectsFromArray: (GS_GENERIC_CLASS(NSArray, ElementT)*)otherArray;
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
- (void) exchangeObjectAtIndex: (NSUInteger)i1
withObjectAtIndex: (NSUInteger)i2;
@ -309,7 +321,7 @@ DEFINE_BLOCK_TYPE(GSPredicateBlock, BOOL, id, NSUInteger, BOOL*);
* and needs to be re-implemented in subclasses in order to have all
* other initialisers work.
*/
- (id) initWithCapacity: (NSUInteger)numItems;
- (instancetype) initWithCapacity: (NSUInteger)numItems;
/** <override-subclass />
* Inserts an object into the receiver at the specified location.<br />
@ -317,9 +329,11 @@ DEFINE_BLOCK_TYPE(GSPredicateBlock, BOOL, id, NSUInteger, BOOL*);
* The size of the array increases by one.<br />
* The object is retained by the array.
*/
- (void) insertObject: (id)anObject atIndex: (NSUInteger)index;
- (void) insertObject: (GS_GENERIC_TYPE(ElementT))anObject
atIndex: (NSUInteger)index;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST)
- (void) insertObjects: (NSArray *)objects atIndexes: (NSIndexSet *)indexes;
- (void) insertObjects: (GS_GENERIC_CLASS(NSArray, ElementT) *)objects
atIndexes: (NSIndexSet *)indexes;
#endif
/** <override-subclass />
@ -337,35 +351,39 @@ DEFINE_BLOCK_TYPE(GSPredicateBlock, BOOL, id, NSUInteger, BOOL*);
* The object is retained by the array.
*/
- (void) replaceObjectAtIndex: (NSUInteger)index
withObject: (id)anObject;
withObject: (GS_GENERIC_TYPE(ElementT))anObject;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST)
- (void) replaceObjectsAtIndexes: (NSIndexSet *)indexes
withObjects: (NSArray *)objects;
withObjects: (GS_GENERIC_CLASS(NSArray, ElementT)*)objects;
#endif
- (void) replaceObjectsInRange: (NSRange)aRange
withObjectsFromArray: (NSArray*)anArray;
withObjectsFromArray: (GS_GENERIC_CLASS(NSArray, ElementT)*)anArray;
- (void) replaceObjectsInRange: (NSRange)aRange
withObjectsFromArray: (NSArray*)anArray
range: (NSRange)anotherRange;
withObjectsFromArray: (GS_GENERIC_CLASS(NSArray, ElementT)*)anArray
range: (NSRange)anotherRange;
- (void) setArray: (NSArray *)otherArray;
- (void) setArray: (GS_GENERIC_CLASS(NSArray, ElementT) *)otherArray;
- (void) removeAllObjects;
- (void) removeLastObject;
- (void) removeObject: (id)anObject;
- (void) removeObject: (id)anObject inRange: (NSRange)aRange;
- (void) removeObjectIdenticalTo: (id)anObject;
- (void) removeObjectIdenticalTo: (id)anObject inRange: (NSRange)aRange;
- (void) removeObjectsInArray: (NSArray*)otherArray;
- (void) removeObject: (GS_GENERIC_TYPE(ElementT))anObject;
- (void) removeObject: (GS_GENERIC_TYPE(ElementT))anObject
inRange: (NSRange)aRange;
- (void) removeObjectIdenticalTo: (GS_GENERIC_TYPE(ElementT))anObject;
- (void) removeObjectIdenticalTo: (GS_GENERIC_TYPE(ElementT))anObject
inRange: (NSRange)aRange;
- (void) removeObjectsInArray: (GS_GENERIC_CLASS(NSArray, ElementT)*)otherArray;
- (void) removeObjectsInRange: (NSRange)aRange;
- (void) removeObjectsFromIndices: (NSUInteger*)indices
- (void) removeObjectsFromIndices: (NSUInteger*)indices
numIndices: (NSUInteger)count;
- (void) sortUsingFunction: (NSComparisonResult (*)(id,id,void*))compare
context: (void*)context;
- (void) sortUsingFunction:
(NSComparisonResult (*)(GS_GENERIC_TYPE(ElementT),
GS_GENERIC_TYPE(ElementT),void*))compare
context: (void*)context;
- (void) sortUsingSelector: (SEL)comparator;
@ -376,7 +394,7 @@ DEFINE_BLOCK_TYPE(GSPredicateBlock, BOOL, id, NSUInteger, BOOL*);
- (void) sortUsingComparator: (NSComparator)comparator;
/**
* Sorts the array using the specified comparator block and options.
* Sorts the array using the specified comparator block and options.
*/
- (void) sortWithOptions: (NSSortOptions)options
usingComparator: (NSComparator)comparator;
@ -384,7 +402,8 @@ DEFINE_BLOCK_TYPE(GSPredicateBlock, BOOL, id, NSUInteger, BOOL*);
/**
* Set method called by the compiler with array subscripting.
*/
- (void) setObject: (id)anObject atIndexedSubscript: (size_t)anIndex;
- (void) setObject: (GS_GENERIC_TYPE(ElementT))anObject
atIndexedSubscript: (size_t)anIndex;
@end
#if defined(__cplusplus)

View file

@ -3,24 +3,24 @@
Written by: David Chisnall <csdavec@swan.ac.uk>
Created: 2009
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser 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 Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
*/
*/
#ifndef __NSCache_h_GNUSTEP_BASE_INCLUDE
#define __NSCache_h_GNUSTEP_BASE_INCLUDE
@ -35,10 +35,10 @@ extern "C" {
#endif
@class NSString;
@class NSMutableDictionary;
@class NSMutableArray;
@class NSMapTable;
@class GS_GENERIC_CLASS(NSMutableArray, ElementT);
@interface NSCache : NSObject
@interface GS_GENERIC_CLASS(NSCache, KeyT, ValT) : NSObject
{
#if GS_EXPOSE(NSCache)
@private
@ -55,9 +55,9 @@ extern "C" {
/** Name of this cache. */
NSString *_name;
/** The mapping from names to objects in this cache. */
NSMutableDictionary *_objects;
NSMapTable *_objects;
/** LRU ordering of all potentially-evictable objects in this cache. */
NSMutableArray *_accesses;
GS_GENERIC_CLASS(NSMutableArray, ValT) *_accesses;
/** Total number of accesses to objects */
int64_t _totalAccesses;
#endif
@ -71,11 +71,16 @@ extern "C" {
@private id _internal GS_UNUSED_IVAR;
#endif
}
/**
/**
* Returns the maximum number of objects that are supported by this cache.
*/
- (NSUInteger) countLimit;
/**
* Returns the total cost of all objects held in the cache.
*/
- (NSUInteger) totalCostLimit;
/**
* Returns the cache's delegate.
*/
@ -96,7 +101,8 @@ extern "C" {
/**
* Returns an object associated with the specified key in this cache.
*/
- (id) objectForKey: (id)key;
- (GS_GENERIC_TYPE(ValT)) objectForKey:
(GS_GENERIC_TYPE(KeyT))key;
/**
* Removes all objects from this cache.
@ -106,7 +112,7 @@ extern "C" {
/**
* Removes the object associated with the given key.
*/
- (void) removeObjectForKey: (id)key;
- (void) removeObjectForKey: (GS_GENERIC_TYPE(KeyT))key;
/**
* Sets the maximum number of objects permitted in this cache. This limit is
@ -137,12 +143,15 @@ extern "C" {
* total cost below the value set with -setTotalCostLimit: by discarding the
* contents of objects which implement the NSDiscardableContent protocol.
*/
- (void) setObject: (id)obj forKey: (id)key cost: (NSUInteger)num;
- (void) setObject: (GS_GENERIC_TYPE(ValT))obj
forKey: (GS_GENERIC_TYPE(KeyT))key
cost: (NSUInteger)num;
/**
* Adds an object to the cache without associating a cost with it.
*/
- (void) setObject: (id)obj forKey: (id)key;
- (void) setObject: (GS_GENERIC_TYPE(ValT))obj
forKey: (GS_GENERIC_TYPE(KeyT))key;
/**
* Sets the maximum total cost for objects stored in this cache. This limit is

View file

@ -33,25 +33,34 @@
extern "C" {
#endif
@class NSArray, NSSet, NSString, NSURL;
@class GS_GENERIC_CLASS(NSArray, ElementT);
@class GS_GENERIC_CLASS(NSSet, ElementT);
@class NSString, NSURL;
@interface NSDictionary : NSObject <NSCoding, NSCopying, NSMutableCopying, NSFastEnumeration>
+ (id) dictionary;
+ (id) dictionaryWithContentsOfFile: (NSString*)path;
@interface GS_GENERIC_CLASS(NSDictionary,
__covariant KeyT:id<NSCopying>, __covariant ValT)
: NSObject <NSCoding, NSCopying, NSMutableCopying, NSFastEnumeration>
+ (instancetype) dictionary;
+ (instancetype) dictionaryWithContentsOfFile: (NSString*)path;
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
+ (id) dictionaryWithContentsOfURL: (NSURL*)aURL;
+ (instancetype) dictionaryWithContentsOfURL: (NSURL*)aURL;
#endif
+ (id) dictionaryWithDictionary: (NSDictionary*)otherDictionary;
+ (id) dictionaryWithObject: (id)object forKey: (id)key;
+ (id) dictionaryWithObjects: (NSArray*)objects forKeys: (NSArray*)keys;
+ (id) dictionaryWithObjects: (const id[])objects
forKeys: (const id <NSCopying>[])keys
count: (NSUInteger)count;
+ (id) dictionaryWithObjectsAndKeys: (id)firstObject, ...;
+ (instancetype) dictionaryWithDictionary: (NSDictionary*)otherDictionary;
+ (instancetype) dictionaryWithObject: (GS_GENERIC_TYPE(ValT))object
forKey:
(GS_GENERIC_TYPE(KeyT))key;
+ (instancetype) dictionaryWithObjects: (GS_GENERIC_CLASS(NSArray,ValT)*)objects
forKeys: (GS_GENERIC_CLASS(NSArray,KeyT)*)keys;
+ (instancetype) dictionaryWithObjects: (const GS_GENERIC_TYPE(ValT)[])objects
forKeys:
(const GS_GENERIC_TYPE_F(KeyT,id<NSCopying>)[])keys
count: (NSUInteger)count;
+ (instancetype) dictionaryWithObjectsAndKeys: (id)firstObject, ...;
- (NSArray*) allKeys;
- (NSArray*) allKeysForObject: (id)anObject;
- (NSArray*) allValues;
- (GS_GENERIC_CLASS(NSArray,KeyT)*) allKeys;
- (GS_GENERIC_CLASS(NSArray,KeyT)*) allKeysForObject:
(GS_GENERIC_TYPE(ValT))anObject;
- (GS_GENERIC_CLASS(NSArray,ValT)*) allValues;
- (NSUInteger) count; // Primitive
- (NSString*) description;
- (NSString*) descriptionInStringsFileFormat;
@ -60,47 +69,58 @@ extern "C" {
indent: (NSUInteger)level;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_6, GS_API_LATEST)
DEFINE_BLOCK_TYPE(GSKeysAndObjectsEnumeratorBlock, void, id, id, BOOL*);
DEFINE_BLOCK_TYPE(GSKeysAndObjectsEnumeratorBlock, void,
GS_GENERIC_TYPE_F(KeyT,id<NSCopying>), GS_GENERIC_TYPE(ValT), BOOL*);
- (void) enumerateKeysAndObjectsUsingBlock:
(GSKeysAndObjectsEnumeratorBlock)aBlock;
- (void) enumerateKeysAndObjectsWithOptions: (NSEnumerationOptions)opts
usingBlock: (GSKeysAndObjectsEnumeratorBlock)aBlock;
#endif
- (void) getObjects: (__unsafe_unretained id[])objects
andKeys: (__unsafe_unretained id[])keys;
- (id) init;
- (id) initWithContentsOfFile: (NSString*)path;
- (void) getObjects: (__unsafe_unretained GS_GENERIC_TYPE(ValT)[])objects
andKeys:
(__unsafe_unretained GS_GENERIC_TYPE_F(KeyT,id<NSCopying>)[])keys;
- (instancetype) init;
- (instancetype) initWithContentsOfFile: (NSString*)path;
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
- (id) initWithContentsOfURL: (NSURL*)aURL;
- (instancetype) initWithContentsOfURL: (NSURL*)aURL;
#endif
- (id) initWithDictionary: (NSDictionary*)otherDictionary;
- (id) initWithDictionary: (NSDictionary*)other copyItems: (BOOL)shouldCopy;
- (id) initWithObjects: (NSArray*)objects forKeys: (NSArray*)keys;
- (id) initWithObjectsAndKeys: (id)firstObject, ...;
- (id) initWithObjects: (const id[])objects
forKeys: (const id <NSCopying>[])keys
- (instancetype) initWithDictionary:
(GS_GENERIC_CLASS(NSDictionary,KeyT, ValT)*)otherDictionary;
- (id) initWithDictionary: (GS_GENERIC_CLASS(NSDictionary,KeyT, ValT)*)other
copyItems: (BOOL)shouldCopy;
- (id) initWithObjects: (GS_GENERIC_CLASS(NSArray,KeyT)*)objects
forKeys: (GS_GENERIC_CLASS(NSArray,ValT)*)keys;
- (id) initWithObjectsAndKeys: (GS_GENERIC_TYPE(ValT))firstObject, ...;
- (id) initWithObjects: (const GS_GENERIC_TYPE(ValT)[])objects
forKeys: (const GS_GENERIC_TYPE_F(KeyT,id<NSCopying>)[])keys
count: (NSUInteger)count; // Primitive
- (BOOL) isEqualToDictionary: (NSDictionary*)other;
- (BOOL) isEqualToDictionary: (GS_GENERIC_CLASS(NSDictionary,KeyT, ValT)*)other;
- (NSEnumerator*) keyEnumerator; // Primitive
- (GS_GENERIC_CLASS(NSEnumerator,KeyT)*) keyEnumerator; // Primitive
#if OS_API_VERSION(MAC_OS_X_VERSION_10_6, GS_API_LATEST)
DEFINE_BLOCK_TYPE(GSKeysAndObjectsPredicateBlock, BOOL, id, id, BOOL*);
- (NSSet*) keysOfEntriesPassingTest: (GSKeysAndObjectsPredicateBlock)aPredicate;
- (NSSet*) keysOfEntriesWithOptions: (NSEnumerationOptions)opts
DEFINE_BLOCK_TYPE(GSKeysAndObjectsPredicateBlock, BOOL,
GS_GENERIC_TYPE_F(KeyT,id<NSCopying>), GS_GENERIC_TYPE(ValT), BOOL*);
- (GS_GENERIC_CLASS(NSSet,KeyT)*) keysOfEntriesPassingTest:
(GSKeysAndObjectsPredicateBlock)aPredicate;
- (GS_GENERIC_CLASS(NSSet,KeyT)*) keysOfEntriesWithOptions:
(NSEnumerationOptions)opts
passingTest: (GSKeysAndObjectsPredicateBlock)aPredicate;
#endif
- (NSArray*) keysSortedByValueUsingSelector: (SEL)comp;
- (NSEnumerator*) objectEnumerator; // Primitive
- (id) objectForKey: (id)aKey; // Primitive
- (NSArray*) objectsForKeys: (NSArray*)keys notFoundMarker: (id)marker;
- (GS_GENERIC_CLASS(NSArray,ValT)*) keysSortedByValueUsingSelector: (SEL)comp;
- (GS_GENERIC_CLASS(NSEnumerator,ValT)*) objectEnumerator; // Primitive
- (GS_GENERIC_TYPE(ValT)) objectForKey:
(GS_GENERIC_TYPE(KeyT))aKey; // Primitive
- (GS_GENERIC_CLASS(NSArray,ValT)*) objectsForKeys:
(GS_GENERIC_CLASS(NSArray,KeyT)*)keys
notFoundMarker: (GS_GENERIC_TYPE(ValT))marker;
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
- (id) valueForKey: (NSString*)key;
- (GS_GENERIC_TYPE(ValT)) valueForKey: (NSString*)key;
#endif
- (BOOL) writeToFile: (NSString*)path atomically: (BOOL)useAuxiliaryFile;
@ -111,29 +131,39 @@ DEFINE_BLOCK_TYPE(GSKeysAndObjectsPredicateBlock, BOOL, id, id, BOOL*);
/**
* Method called by array subscripting.
*/
- (id) objectForKeyedSubscript: (id)aKey;
- (GS_GENERIC_TYPE(ValT)) objectForKeyedSubscript:
(GS_GENERIC_TYPE(KeyT))aKey;
@end
@interface NSMutableDictionary: NSDictionary
@interface GS_GENERIC_CLASS(NSMutableDictionary, KeyT:id<NSCopying>, ValT) :
GS_GENERIC_CLASS(NSDictionary, KeyT, ValT)
+ (id) dictionaryWithCapacity: (NSUInteger)numItems;
+ (instancetype) dictionaryWithCapacity: (NSUInteger)numItems;
- (void) addEntriesFromDictionary: (NSDictionary*)otherDictionary;
- (id) initWithCapacity: (NSUInteger)numItems; // Primitive
- (void) addEntriesFromDictionary:
(GS_GENERIC_CLASS(NSDictionary, KeyT, ValT)*)otherDictionary;
- (instancetype) initWithCapacity: (NSUInteger)numItems; // Primitive
- (void) removeAllObjects;
- (void) removeObjectForKey: (id)aKey; // Primitive
- (void) removeObjectsForKeys: (NSArray*)keyArray;
- (void) setObject: (id)anObject forKey: (id)aKey; // Primitive
- (void) setDictionary: (NSDictionary*)otherDictionary;
/**
* Removes the object with the specified key from the receiver. This method
* is primitive.
*/
- (void) removeObjectForKey: (GS_GENERIC_TYPE(KeyT))aKey;
- (void) removeObjectsForKeys: (GS_GENERIC_CLASS(NSArray, KeyT) *)keyArray;
- (void) setObject: (GS_GENERIC_TYPE(ValT))anObject
forKey: (GS_GENERIC_TYPE(KeyT))aKey; // Primitive
- (void) setDictionary:
(GS_GENERIC_CLASS(NSDictionary, KeyT, ValT)*)otherDictionary;
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
- (void) setValue: (id)value forKey: (NSString*)key;
- (void) takeStoredValue: (id)value forKey: (NSString*)key;
- (void) takeValue: (id)value forKey: (NSString*)key;
- (void) setValue: (GS_GENERIC_TYPE(ValT))value forKey: (NSString*)key;
- (void) takeStoredValue: (GS_GENERIC_TYPE(ValT))value forKey: (NSString*)key;
- (void) takeValue: (GS_GENERIC_TYPE(ValT))value forKey: (NSString*)key;
#endif
/**
* Method called by array subscripting.
*/
- (void) setObject: (id)anObject forKeyedSubscript: (id)aKey;
- (void) setObject: (GS_GENERIC_TYPE(ValT))anObject
forKeyedSubscript: (GS_GENERIC_TYPE(KeyT))aKey;
@end

View file

@ -1,4 +1,4 @@
/*
/*
NSEnumerator.h
Copyright (C) 1998 Free Software Foundation, Inc.
@ -12,7 +12,7 @@
modify it under the terms of the GNU Lesser 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
@ -30,11 +30,14 @@
#import <Foundation/NSObject.h>
#if defined(__cplusplus)
extern "C" {
#endif
typedef struct
@class GS_GENERIC_CLASS(NSArray, ElementT);
typedef struct
{
unsigned long state;
__unsafe_unretained id *itemsPtr;
@ -43,14 +46,14 @@ typedef struct
} NSFastEnumerationState;
@protocol NSFastEnumeration
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState *)state
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState *)state
objects: (__unsafe_unretained id[])stackbuf
count: (NSUInteger)len;
@end
@interface NSEnumerator : NSObject <NSFastEnumeration>
- (NSArray *) allObjects;
- (id) nextObject;
@interface GS_GENERIC_CLASS(NSEnumerator, IterT) : NSObject <NSFastEnumeration>
- (GS_GENERIC_CLASS(NSArray, IterT) *) allObjects;
- (GS_GENERIC_TYPE(IterT)) nextObject;
@end
#if defined(__cplusplus)

View file

@ -48,7 +48,7 @@
#if defined(__hppa__) && defined(__hpux__) && !defined(PRIuPTR)
#define PRIuPTR "lu"
#endif
/* IRIX kludge. */
#if defined(__sgi)
/* IRIX 6.5 <inttypes.h> provides all definitions, but only for C99
@ -70,7 +70,7 @@
are uintptr_t, which is always unsigned long. */
#define PRIuPTR "lu"
#endif
/* Solaris < 10 kludge. */
#if defined(__sun__) && defined(__svr4__) && !defined(PRIuPTR)
#if defined(__arch64__) || defined (__x86_64__)
@ -157,11 +157,30 @@ extern "C" {
#if __has_feature(nullability)
# define NS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
# define NS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
#else
#else
# define NS_ASSUME_NONNULL_BEGIN
# define NS_ASSUME_NONNULL_END
#endif
/*
* Backwards compatibility macro for instance type.
*/
#if !__has_feature(objc_instancetype)
# define instancetype id
#endif
/*
* Backwards compatibility macros for Objective-C lightweight generics.
*/
#if __has_feature(objc_generics)
# define GS_GENERIC_CLASS(clz, ...) clz<__VA_ARGS__>
# define GS_GENERIC_TYPE_F(typeRef, fallback) typeRef
#else
# define GS_GENERIC_CLASS(clz, ...) clz
# define GS_GENERIC_TYPE_F(typeRef, fallback) fallback
#endif
#define GS_GENERIC_TYPE(typeRef) GS_GENERIC_TYPE_F(typeRef, id)
/** Bitfield used to specify options to control enumeration over collections.
*/
typedef NS_OPTIONS(NSUInteger, NSEnumerationOptions)

View file

@ -3,19 +3,19 @@
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: Sep 1995
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser 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 Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
@ -24,7 +24,7 @@
AutogsdocSource: NSSet.m
AutogsdocSource: NSCountedSet.m
*/
*/
#ifndef _NSSet_h_GNUSTEP_BASE_INCLUDE
#define _NSSet_h_GNUSTEP_BASE_INCLUDE
@ -38,38 +38,45 @@
extern "C" {
#endif
@class NSArray, NSString, NSEnumerator, NSDictionary;
@class GS_GENERIC_CLASS(NSArray, ElementT);
@class GS_GENERIC_CLASS(NSEnumerator, ElementT);
@class GS_GENERIC_CLASS(NSDictionary, KeyT:id<NSCopying>, ValT);
@class NSString;
@interface NSSet : NSObject <NSCoding, NSCopying, NSMutableCopying, NSFastEnumeration>
@interface GS_GENERIC_CLASS(NSSet, __covariant ElementT) : NSObject <NSCoding,
NSCopying,
NSMutableCopying,
NSFastEnumeration>
+ (id) set;
+ (id) setWithArray: (NSArray*)objects;
+ (id) setWithObject: (id)anObject;
+ (id) setWithObjects: (id)firstObject, ...;
+ (instancetype) set;
+ (instancetype) setWithArray: (GS_GENERIC_CLASS(NSArray, ElementT)*)objects;
+ (instancetype) setWithObject: (GS_GENERIC_TYPE(ElementT))anObject;
+ (instancetype) setWithObjects: (GS_GENERIC_TYPE(ElementT))firstObject, ...;
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
+ (id) setWithObjects: (const id[])objects
count: (NSUInteger)count;
+ (instancetype) setWithObjects: (const GS_GENERIC_TYPE(ElementT)[])objects
count: (NSUInteger)count;
#endif
+ (id) setWithSet: (NSSet*)aSet;
+ (instancetype) setWithSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)aSet;
- (NSArray*) allObjects;
- (id) anyObject;
- (BOOL) containsObject: (id)anObject;
- (GS_GENERIC_CLASS(NSArray, ElementT)*) allObjects;
- (GS_GENERIC_TYPE(ElementT)) anyObject;
- (BOOL) containsObject: (GS_GENERIC_TYPE(ElementT))anObject;
- (NSUInteger) count;
- (NSString*) description;
- (NSString*) descriptionWithLocale: (id)locale;
- (id) init;
- (id) initWithArray: (NSArray*)other;
- (id) initWithObjects: (id)firstObject, ...;
- (id) initWithObjects: (const id[])objects
count: (NSUInteger)count;
- (id) initWithSet: (NSSet*)other;
- (id) initWithSet: (NSSet*)other copyItems: (BOOL)flag;
- (instancetype) init;
- (instancetype) initWithArray: (GS_GENERIC_CLASS(NSArray, ElementT)*)other;
- (instancetype) initWithObjects: (GS_GENERIC_TYPE(ElementT))firstObject, ...;
- (instancetype) initWithObjects: (const GS_GENERIC_TYPE(ElementT)[])objects
count: (NSUInteger)count;
- (instancetype) initWithSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
- (instancetype) initWithSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other
copyItems: (BOOL)flag;
- (BOOL) intersectsSet: (NSSet*)otherSet;
- (BOOL) isEqualToSet: (NSSet*)other;
- (BOOL) isSubsetOfSet: (NSSet*)otherSet;
- (BOOL) intersectsSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)otherSet;
- (BOOL) isEqualToSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
- (BOOL) isSubsetOfSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)otherSet;
- (void) makeObjectsPerform: (SEL)aSelector;
- (void) makeObjectsPerform: (SEL)aSelector withObject: (id)argument;
@ -77,13 +84,13 @@ extern "C" {
- (void) makeObjectsPerformSelector: (SEL)aSelector;
- (void) makeObjectsPerformSelector: (SEL)aSelector withObject: (id)argument;
#endif
- (id) member: (id)anObject;
- (NSEnumerator*) objectEnumerator;
- (GS_GENERIC_TYPE(ElementT)) member: (GS_GENERIC_TYPE(ElementT))anObject;
- (GS_GENERIC_CLASS(NSEnumerator, ElementT)*) objectEnumerator;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_6, GS_API_LATEST)
DEFINE_BLOCK_TYPE(GSSetEnumeratorBlock, void, id, BOOL*);
DEFINE_BLOCK_TYPE(GSSetFilterBlock, BOOL, id, BOOL*);
DEFINE_BLOCK_TYPE(GSSetEnumeratorBlock, void, GS_GENERIC_TYPE(ElementT), BOOL*);
DEFINE_BLOCK_TYPE(GSSetFilterBlock, BOOL, GS_GENERIC_TYPE(ElementT), BOOL*);
/**
* Enumerate over the collection using a given block. The first argument is
@ -106,40 +113,46 @@ DEFINE_BLOCK_TYPE(GSSetFilterBlock, BOOL, id, BOOL*);
- (void) enumerateObjectsWithOptions: (NSEnumerationOptions)opts
usingBlock: (GSSetEnumeratorBlock)aBlock;
- (NSSet *) objectsPassingTest: (GSSetFilterBlock)aBlock;
- (NSSet *) objectsWithOptions: (NSEnumerationOptions)opts
passingTest: (GSSetFilterBlock)aBlock;
- (GS_GENERIC_CLASS(NSSet, ElementT) *) objectsPassingTest:
(GSSetFilterBlock)aBlock;
- (GS_GENERIC_CLASS(NSSet, ElementT) *) objectsWithOptions:
(NSEnumerationOptions)opts
passingTest: (GSSetFilterBlock)aBlock;
#endif
#if OS_API_VERSION(MAC_OS_X_VERSION_10_5,GS_API_LATEST)
- (NSSet *) setByAddingObject: (id)anObject;
- (NSSet *) setByAddingObjectsFromSet: (NSSet *)other;
- (NSSet *) setByAddingObjectsFromArray: (NSArray *)other;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_5,GS_API_LATEST)
- (GS_GENERIC_CLASS(NSSet, ElementT) *) setByAddingObject:
(GS_GENERIC_TYPE(ElementT))anObject;
- (GS_GENERIC_CLASS(NSSet, ElementT) *) setByAddingObjectsFromSet:
(GS_GENERIC_CLASS(NSSet, ElementT) *)other;
- (GS_GENERIC_CLASS(NSSet, ElementT) *) setByAddingObjectsFromArray:
(GS_GENERIC_CLASS(NSArray, ElementT) *)other;
#endif
@end
@interface NSMutableSet: NSSet
@interface GS_GENERIC_CLASS(NSMutableSet, ElementT):
GS_GENERIC_CLASS(NSSet, ElementT)
+ (id) setWithCapacity: (NSUInteger)numItems;
+ (instancetype) setWithCapacity: (NSUInteger)numItems;
- (void) addObject: (id)anObject;
- (void) addObjectsFromArray: (NSArray*)array;
- (id) initWithCapacity: (NSUInteger)numItems;
- (void) intersectSet: (NSSet*)other;
- (void) minusSet: (NSSet*)other;
- (void) addObject: (GS_GENERIC_TYPE(ElementT))anObject;
- (void) addObjectsFromArray: (GS_GENERIC_CLASS(NSArray, ElementT)*)array;
- (instancetype) initWithCapacity: (NSUInteger)numItems;
- (void) intersectSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
- (void) minusSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
- (void) removeAllObjects;
- (void) removeObject: (id)anObject;
- (void) removeObject: (GS_GENERIC_TYPE(ElementT))anObject;
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
- (void) setSet: (NSSet*)other;
- (void) setSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
#endif
- (void) unionSet: (NSSet*)other;
- (void) unionSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
@end
@interface NSCountedSet : NSMutableSet
@interface GS_GENERIC_CLASS(NSCountedSet, ElementT) :
GS_GENERIC_CLASS(NSMutableSet, ElementT)
- (NSUInteger) countForObject: (id)anObject;
- (NSUInteger) countForObject: (GS_GENERIC_TYPE(ElementT))anObject;
@end
@ -148,7 +161,7 @@ DEFINE_BLOCK_TYPE(GSSetFilterBlock, BOOL, id, BOOL*);
/**
* Utility methods for using a counted set to handle uniquing of objects.
*/
@interface NSCountedSet (GNU_Uniquing)
@interface GS_GENERIC_CLASS(NSCountedSet, ElementT) (GNU_Uniquing)
/**
* <p>
* This method removes from the set all objects whose count is
@ -170,7 +183,7 @@ DEFINE_BLOCK_TYPE(GSSetFilterBlock, BOOL, id, BOOL*);
* is released, and the object in the set is retained and returned.
* Otherwise, the supplied object is added to the set and returned.
* </p>
* <p>
* <p>
* This method is useful for uniquing objects - the init method of
* a class need simply end with -
* <code>
@ -178,7 +191,8 @@ DEFINE_BLOCK_TYPE(GSSetFilterBlock, BOOL, id, BOOL*);
* </code>
* </p>
*/
- (id) unique: (id) NS_CONSUMED anObject NS_RETURNS_RETAINED;
- (GS_GENERIC_TYPE(ElementT)) unique:
(GS_GENERIC_TYPE(ElementT)) NS_CONSUMED anObject NS_RETURNS_RETAINED;
@end
/*
@ -190,7 +204,7 @@ DEFINE_BLOCK_TYPE(GSSetFilterBlock, BOOL, id, BOOL*);
* if uniquing is turned off, GSUnique() simply returns its argument.
*
*/
void GSUniquing(BOOL flag);
void GSUniquing(BOOL flag);
/*
* GSUnique() returns an object that is equal to the one passed to it.

View file

@ -3,24 +3,24 @@
Written by: David Chisnall <csdavec@swan.ac.uk>
Created: 2009
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser 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 Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
*/
*/
#import "common.h"
@ -28,7 +28,7 @@
#import "Foundation/NSArray.h"
#import "Foundation/NSCache.h"
#import "Foundation/NSDictionary.h"
#import "Foundation/NSMapTable.h"
#import "Foundation/NSEnumerator.h"
/**
@ -60,7 +60,7 @@
{
return nil;
}
_objects = [NSMutableDictionary new];
ASSIGN(_objects,[NSMapTable strongToStrongObjectsMapTable]);
_accesses = [NSMutableArray new];
return self;
}

View file

@ -103,15 +103,15 @@ skip_argspec(const char *ptr)
*/
#define GSI_MAP_KTYPES GSUNION_PTR | GSUNION_OBJ | GSUNION_NSINT
#define GSI_MAP_VTYPES GSUNION_PTR | GSUNION_OBJ
#define GSI_MAP_RETAIN_KEY(M, X)
#define GSI_MAP_RELEASE_KEY(M, X)
#define GSI_MAP_RETAIN_VAL(M, X)
#define GSI_MAP_RELEASE_VAL(M, X)
#define GSI_MAP_RETAIN_KEY(M, X)
#define GSI_MAP_RELEASE_KEY(M, X)
#define GSI_MAP_RETAIN_VAL(M, X)
#define GSI_MAP_RELEASE_VAL(M, X)
#define GSI_MAP_HASH(M, X) ((X).nsu ^ ((X).nsu >> 3))
#define GSI_MAP_EQUAL(M, X,Y) ((X).ptr == (Y).ptr)
#define GSI_MAP_NOCLEAN 1
#if GS_WITH_GC
// FIXME ...
// FIXME ...
#include <gc/gc_typed.h>
static GC_descr nodeDesc; // Type descriptor for map node.
#define GSI_MAP_NODES(M, X) \
@ -174,7 +174,7 @@ GSRunLoopForThread(NSThread *aThread)
@interface NSConnection (GNUstepExtensions)
- (void) finalize;
- (void) forwardInvocation: (NSInvocation *)inv
- (void) forwardInvocation: (NSInvocation *)inv
forProxy: (NSDistantObject*)object;
- (const char *) typeForSelector: (SEL)sel remoteTarget: (unsigned)target;
@end
@ -765,7 +765,7 @@ static NSLock *cached_proxies_gate = nil;
return AUTORELEASE(proxy);
}
+ (id) serviceConnectionWithName: (NSString *)name
+ (id) serviceConnectionWithName: (NSString *)name
rootObject: (id)root
{
return [self serviceConnectionWithName: name
@ -773,7 +773,7 @@ static NSLock *cached_proxies_gate = nil;
usingNameServer: [NSPortNameServer systemDefaultPortNameServer]];
}
+ (id) serviceConnectionWithName: (NSString *)name
+ (id) serviceConnectionWithName: (NSString *)name
rootObject: (id)root
usingNameServer: (NSPortNameServer *)server
{
@ -1421,31 +1421,34 @@ static NSLock *cached_proxies_gate = nil;
*/
- (NSArray*) localObjects
{
NSMutableArray *c;
NSArray *a;
/* Don't assert (IisValid); */
GS_M_LOCK(IrefGate);
if (IlocalObjects != 0)
{
GSIMapEnumerator_t enumerator;
GSIMapNode node;
enumerator = GSIMapEnumeratorForMap(IlocalObjects);
node = GSIMapEnumeratorNextNode(&enumerator);
c = [NSMutableArray arrayWithCapacity: IlocalObjects->nodeCount];
NSMutableArray *c =
[NSMutableArray arrayWithCapacity: IlocalObjects->nodeCount];
while (node != 0)
{
[c addObject: node->key.obj];
node = GSIMapEnumeratorNextNode(&enumerator);
}
a = c;
}
else
{
c = [NSArray array];
a = [NSArray array];
}
GSM_UNLOCK(IrefGate);
return c;
return a;
}
/**
@ -2105,7 +2108,7 @@ static NSLock *cached_proxies_gate = nil;
format: @"connection waiting for request was shut down"];
}
aRmc = [self _getReplyRmc: seq];
/*
* Find out if the server is returning an exception instead
* of the return values.
@ -2136,7 +2139,7 @@ static NSLock *cached_proxies_gate = nil;
/* If there is a return value, decode it, and put it in datum. */
if (*tmptype != _C_VOID || (flags & _F_ONEWAY) == 0)
{
{
switch (*tmptype)
{
case _C_ID:
@ -2586,7 +2589,7 @@ static NSLock *cached_proxies_gate = nil;
*/
object = [decoder decodeObject];
/* Decode the selector, (which is the second argument to a method). */
/* Decode the selector, (which is the second argument to a method). */
/* xxx @encode(SEL) produces "^v" in gcc 2.5.8. It should be ":" */
[decoder decodeValueOfObjCType: @encode(SEL) at: &selector];
@ -2606,14 +2609,14 @@ static NSLock *cached_proxies_gate = nil;
object, sel_getName(selector)];
}
type = [sig methodType];
/* Make sure we successfully got the method type, and that its
types match the ENCODED_TYPES. */
NSCParameterAssert (type);
if (GSSelectorTypesMatch(encoded_types, type) == NO)
{
[NSException raise: NSInvalidArgumentException
format: @"NSConection types (%s / %s) missmatch for %s",
format: @"NSConection types (%s / %s) missmatch for %s",
encoded_types, type, sel_getName(selector)];
}
@ -3394,7 +3397,7 @@ static NSLock *cached_proxies_gate = nil;
sendPort:IsendPort
components: nil];
[coder encodeValueOfObjCType: @encode(int) at: &sno];
NSDebugMLLog(@"NSConnection",
NSDebugMLLog(@"NSConnection",
@"Make out RMC %u on %@", sno, self);
return coder;
}
@ -3441,7 +3444,7 @@ static NSLock *cached_proxies_gate = nil;
break;
}
NSDebugMLLog(@"NSConnection",
NSDebugMLLog(@"NSConnection",
@"Sending %@ on %@", stringFromMsgType(msgid), self);
limit = [dateClass dateWithTimeIntervalSinceNow: IrequestTimeout];
@ -4035,7 +4038,7 @@ static NSLock *cached_proxies_gate = nil;
* We enumerate an array copy of the contents of the hash table
* as we know we can do that safely outside the locked region.
* The temporary array and the enumerator are autoreleased and
* will be deallocated with the threads autorelease pool.
* will be deallocated with the threads autorelease pool.
*/
while ((c = [enumerator nextObject]) != nil)
{
@ -4044,4 +4047,3 @@ static NSLock *cached_proxies_gate = nil;
}
}
@end

View file

@ -64,7 +64,7 @@
* Since all the other subclasses are based on NSDataMalloc or
* NSMutableDataMalloc, we can put most methods in here and not
* bother with duplicating them in the other classes.
*
*
*/
#import "common.h"
@ -166,7 +166,7 @@ encodebase64(unsigned char **dstRef,
NSUInteger lineLength;
NSUInteger destLen;
lineLength = 0;
lineLength = 0;
if (options & NSDataBase64Encoding64CharacterLineLength)
lineLength = 64;
else if (options & NSDataBase64Encoding76CharacterLineLength)
@ -243,28 +243,28 @@ readContentsOfFile(NSString* path, void** buf, off_t* len, NSZone* zone)
const unichar *thePath = 0;
#else
const char *thePath = 0;
#endif
#endif
FILE *theFile = 0;
void *tmp = 0;
int c;
off_t fileLength;
#if defined(__MINGW__)
thePath = (const unichar*)[path fileSystemRepresentation];
#else
thePath = [path fileSystemRepresentation];
#endif
#endif
if (thePath == 0)
{
NSWarnFLog(@"Open (%@) attempt failed - bad path", path);
return NO;
}
#if defined(__MINGW__)
theFile = _wfopen(thePath, L"rb");
#else
theFile = fopen(thePath, "rb");
#endif
#endif
if (theFile == 0) /* We failed to open the file. */
{
@ -282,7 +282,7 @@ readContentsOfFile(NSString* path, void** buf, off_t* len, NSZone* zone)
[NSError _last]);
goto failure;
}
/*
* Determine the length of the file (having seeked to the end of the
* file) by calling ftello().
@ -293,7 +293,7 @@ readContentsOfFile(NSString* path, void** buf, off_t* len, NSZone* zone)
NSWarnFLog(@"Ftell on %@ failed - %@", path, [NSError _last]);
goto failure;
}
/*
* Rewind the file pointer to the beginning, preparing to read in
* the file.
@ -310,7 +310,7 @@ readContentsOfFile(NSString* path, void** buf, off_t* len, NSZone* zone)
if (fileLength == 0)
{
unsigned char buf[BUFSIZ];
/*
* Special case ... a file of length zero may be a named pipe or some
* file in the /proc filesystem, which will return us data if we read
@ -362,7 +362,7 @@ readContentsOfFile(NSString* path, void** buf, off_t* len, NSZone* zone)
(intmax_t)fileLength, [NSError _last]);
goto failure;
}
while (offset < fileLength
&& (c = fread(tmp + offset, 1, fileLength - offset, theFile)) != 0)
{
@ -389,7 +389,7 @@ readContentsOfFile(NSString* path, void** buf, off_t* len, NSZone* zone)
*len = fileLength;
fclose(theFile);
return YES;
/*
* Just in case the failure action needs to be changed.
*/
@ -1736,7 +1736,7 @@ failure:
{
c = 0;
// Delete the old file if possible
DeleteFileW(secondaryFile);
DeleteFileW(secondaryFile);
}
else
{
@ -1814,15 +1814,15 @@ failure:
useAuxiliaryFile = YES;
}
if ([path canBeConvertedToEncoding: [NSString defaultCStringEncoding]])
{
{
const char *local_c_path = [path cString];
if (local_c_path != 0 && strlen(local_c_path) < (BUFSIZ*2))
{
{
strncpy(theRealPath, local_c_path, sizeof(theRealPath) - 1);
theRealPath[sizeof(theRealPath) - 1] = '\0';
error_BadPath = NO;
}
}
}
if (error_BadPath)
{
@ -1918,13 +1918,11 @@ failure:
if (useAuxiliaryFile)
{
NSFileManager *mgr = [NSFileManager defaultManager];
NSMutableDictionary *att = nil;
NSDictionary *att = nil;
if ([mgr fileExistsAtPath: path])
{
att = [[mgr fileAttributesAtPath: path
traverseLink: YES] mutableCopy];
IF_NO_GC(AUTORELEASE(att));
att = [mgr fileAttributesAtPath: path traverseLink: YES];
}
c = rename(thePath, theRealPath);
@ -1937,18 +1935,20 @@ failure:
if (att != nil)
{
NSMutableDictionary *mAtt = [att mutableCopy];
IF_NO_GC(AUTORELEASE(mAtt));
/*
* We have created a new file - so we attempt to make it's
* attributes match that of the original.
*/
[att removeObjectForKey: NSFileSize];
[att removeObjectForKey: NSFileModificationDate];
[att removeObjectForKey: NSFileReferenceCount];
[att removeObjectForKey: NSFileSystemNumber];
[att removeObjectForKey: NSFileSystemFileNumber];
[att removeObjectForKey: NSFileDeviceIdentifier];
[att removeObjectForKey: NSFileType];
if ([mgr changeFileAttributes: att atPath: path] == NO)
[mAtt removeObjectForKey: NSFileSize];
[mAtt removeObjectForKey: NSFileModificationDate];
[mAtt removeObjectForKey: NSFileReferenceCount];
[mAtt removeObjectForKey: NSFileSystemNumber];
[mAtt removeObjectForKey: NSFileSystemFileNumber];
[mAtt removeObjectForKey: NSFileDeviceIdentifier];
[mAtt removeObjectForKey: NSFileType];
if ([mgr changeFileAttributes: mAtt atPath: path] == NO)
{
NSWarnMLog(@"Unable to correctly set all attributes for '%@'",
path);
@ -2250,10 +2250,10 @@ failure:
{
[aCoder encodeBytes: bytes
length: length
forKey: @"NS.data"];
forKey: @"NS.data"];
}
else
{
{
[aCoder encodeValueOfObjCType: @encode(NSUInteger)
at: &length];
if (length)
@ -2285,18 +2285,18 @@ failure:
data = [aCoder decodeBytesForKey: @"NS.data"
returnedLength: &l];
returnedLength: &l];
self = [self initWithBytes: data length: l];
}
else
{
{
NSUInteger l;
[aCoder decodeValueOfObjCType: @encode(NSUInteger) at: &l];
if (l)
{
void *b;
#if GS_WITH_GC
b = NSAllocateCollectable(l, 0);
#else
@ -3409,7 +3409,7 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
}
@end
#endif
#ifdef HAVE_MMAP
@implementation NSDataMappedFile
@ -3443,14 +3443,14 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
{
off_t off;
int fd;
#if defined(__MINGW__)
const unichar *thePath = (const unichar*)[path fileSystemRepresentation];
#else
const char *thePath = [path fileSystemRepresentation];
#endif
if (thePath == 0)
if (thePath == 0)
{
NSWarnMLog(@"Open (%@) attempt failed - bad path", path);
DESTROY(self);
@ -4249,7 +4249,7 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
}
@end
#endif
#ifdef HAVE_SHMCTL
@implementation NSMutableDataShared
@ -4420,4 +4420,3 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
@end
#endif /* HAVE_SHMCTL */

View file

@ -863,7 +863,7 @@ static SEL appSel;
}
- (void)getObjects: (__unsafe_unretained id[])objects
andKeys: (__unsafe_unretained id[])keys
andKeys: (__unsafe_unretained id<NSCopying>[])keys
{
int i=0;
FOR_IN(id, key, self)
@ -1242,7 +1242,7 @@ compareIt(id o1, id o2, void* context)
if (count > 0)
{
NSEnumerator *enumerator = [self keyEnumerator];
NSObject *k;
NSObject<NSCopying> *k = nil;
while ((k = [enumerator nextObject]) != nil)
{

View file

View file

@ -0,0 +1,17 @@
#import "ObjectTesting.h"
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSCache.h>
int main()
{
NSAutoreleasePool *arp = [NSAutoreleasePool new];
NSCache *testObj;
testObj = [[NSCache new] autorelease];
[testObj setObject: @"hello" forKey: @"there"];
test_alloc(@"NSCache");
test_NSObject(@"NSCache", [NSArray arrayWithObject: testObj]);
[arp release]; arp = nil;
return 0;
}

131
Tests/base/NSCache/cache.m Normal file
View file

@ -0,0 +1,131 @@
#import "ObjectTesting.h"
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSCache.h>
@interface TestObject : NSObject <NSDiscardableContent>
{
BOOL _discarded;
}
@end
@implementation TestObject
- (BOOL)beginContentAccess
{
return YES;
}
- (void)endContentAccess
{
}
- (void)discardContentIfPossible
{
_discarded = YES;
}
- (BOOL)isContentDiscarded
{
return _discarded;
}
@end
int main()
{
NSAutoreleasePool *arp = [NSAutoreleasePool new];
NSCache *cache = [[NSCache new] autorelease];
[cache setName: @"Foo"];
PASS_EQUAL(@"Foo", [cache name], "Name can be set an accessed");
[cache setCountLimit: 2];
PASS(2 == [cache countLimit], "Count limit can be set and accessed");
[cache setTotalCostLimit: 3];
PASS(3 == [cache totalCostLimit], "Total cost limit can be set and accessed");
[cache setObject: @"bar" forKey: @"foo"];
PASS_EQUAL(@"bar", [cache objectForKey: @"foo"],
"Cached object can be returned");
/*
* NOTE: The following to test sets currently won't work. The only available
* eviction strategy is to evict under the following conditions:
*
* - evictsObjectsWithDiscardedContent is set on the receiver
* - the cached object implements NSDiscardableContent
* - the content is actually discarded
*/
START_SET("count-based eviction")
testHopeful = YES;
/* Let's test count based eviction: We add two more items and expect the
* first one (foo) to be removed because the count limit is two
*/
[cache setObject: @"baz" forKey: @"bar"];
NSUInteger i = 0;
for (i = 0; i < 50; i++)
{
/* We need to heat this object in the cache so that the first one
* becomes elligible for eviction
*/
[cache objectForKey: @"bar"];
}
[cache setObject: @"frubble" forKey: @"baz"];
PASS_EQUAL(@"frubble", [cache objectForKey: @"baz"],
"LRU object retained on count overflow");
PASS_EQUAL(@"baz", [cache objectForKey: @"bar"],
"second object retained on count overflow");
PASS(nil == [cache objectForKey: @"foo"], "Oldest object evicted");
END_SET("count-based eviction")
[cache removeAllObjects];
START_SET("cost-based eviction")
testHopeful = YES;
[cache setObject: @"bar" forKey: @"foo" cost: 2];
// This should push out the previous object because the cumulative cost (4)
// exceeds the limit (3)
[cache setObject: @"baz" forKey: @"bar" cost: 2];
PASS_EQUAL(@"baz", [cache objectForKey: @"bar"],
"LRU object retained on cost overflow");
PASS(nil == [cache objectForKey: @"foo"], "Overflowing object evicted");
END_SET("cost-based eviction")
[cache removeAllObjects];
START_SET("eviction of discardable content")
cache = [[NSCache new] autorelease];
[cache setCountLimit: 1];
[cache setEvictsObjectsWithDiscardedContent: YES];
TestObject *a = [[TestObject new] autorelease];
TestObject *b = [[TestObject new] autorelease];
[cache setObject: a forKey: @"foo"];
[cache setObject: b forKey: @"bar"];
PASS_EQUAL(b, [cache objectForKey: @"bar"],
"LRU object retained on count overflow");
PASS(nil == [cache objectForKey: @"foo"],
"Overflowing object evicted on count overflow");
PASS([a isContentDiscarded],
"Cache did call -discardContentIfPossible on cached object");
[cache removeAllObjects];
[cache setCountLimit: 0];
[cache setTotalCostLimit: 3];
a = [[TestObject new] autorelease];
b = [[TestObject new] autorelease];
[cache setObject: a forKey: @"foo" cost: 2];
[cache setObject: b forKey: @"bar" cost: 2];
PASS_EQUAL(b, [cache objectForKey: @"bar"],
"LRU object retained on cost overflow");
PASS(nil == [cache objectForKey: @"foo"],
"Overflowing object evicted on cost overflow");
PASS([a isContentDiscarded],
"Cache did call -discardContentIfPossible on cached object");
END_SET("eviction of discardable content")
[arp release]; arp = nil;
return 0;
}