mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-12 00:51:08 +00:00
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:
parent
4851131f49
commit
28c824a78a
14 changed files with 541 additions and 273 deletions
25
ChangeLog
25
ChangeLog
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
- (instancetype) initWithObjects: (const GS_GENERIC_TYPE(ElementT)[])objects
|
||||
count: (NSUInteger)count;
|
||||
- (id) lastObject;
|
||||
- (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
|
||||
- (GS_GENERIC_CLASS(NSArray, ElementT)*) 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
|
||||
hint: (NSData*)hint;
|
||||
- (NSArray*) sortedArrayUsingSelector: (SEL)comparator;
|
||||
- (NSArray*) subarrayWithRange: (NSRange)aRange;
|
||||
- (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
|
||||
|
@ -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,7 +276,8 @@ 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
|
||||
- (GS_GENERIC_CLASS(NSArray, ElementT) *)
|
||||
sortedArrayWithOptions: (NSSortOptions)options
|
||||
usingComparator: (NSComparator)comparator;
|
||||
|
||||
/**
|
||||
|
@ -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,34 +351,38 @@ 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
|
||||
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
|
||||
numIndices: (NSUInteger)count;
|
||||
|
||||
- (void) sortUsingFunction: (NSComparisonResult (*)(id,id,void*))compare
|
||||
- (void) sortUsingFunction:
|
||||
(NSComparisonResult (*)(GS_GENERIC_TYPE(ElementT),
|
||||
GS_GENERIC_TYPE(ElementT),void*))compare
|
||||
context: (void*)context;
|
||||
- (void) sortUsingSelector: (SEL)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)
|
||||
|
|
|
@ -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
|
||||
|
@ -76,6 +76,11 @@ extern "C" {
|
|||
*/
|
||||
- (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
|
||||
|
|
|
@ -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
|
||||
+ (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;
|
||||
+ (id) dictionaryWithObjectsAndKeys: (id)firstObject, ...;
|
||||
+ (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
|
||||
|
||||
|
|
|
@ -30,10 +30,13 @@
|
|||
|
||||
#import <Foundation/NSObject.h>
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@class GS_GENERIC_CLASS(NSArray, ElementT);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned long state;
|
||||
|
@ -48,9 +51,9 @@ typedef struct
|
|||
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)
|
||||
|
|
|
@ -162,6 +162,25 @@ extern "C" {
|
|||
# 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)
|
||||
|
|
|
@ -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
|
||||
+ (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
|
||||
- (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;
|
||||
- (id) initWithSet: (NSSet*)other;
|
||||
- (id) initWithSet: (NSSet*)other copyItems: (BOOL)flag;
|
||||
- (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;
|
||||
- (GS_GENERIC_CLASS(NSSet, ElementT) *) objectsPassingTest:
|
||||
(GSSetFilterBlock)aBlock;
|
||||
|
||||
- (NSSet *) objectsWithOptions: (NSEnumerationOptions)opts
|
||||
- (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;
|
||||
- (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
|
||||
|
@ -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
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4044,4 +4047,3 @@ static NSLock *cached_proxies_gate = nil;
|
|||
}
|
||||
}
|
||||
@end
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
@ -4420,4 +4420,3 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos)
|
|||
|
||||
@end
|
||||
#endif /* HAVE_SHMCTL */
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
0
Tests/base/NSCache/TestInfo
Normal file
0
Tests/base/NSCache/TestInfo
Normal file
17
Tests/base/NSCache/basic.m
Normal file
17
Tests/base/NSCache/basic.m
Normal 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
131
Tests/base/NSCache/cache.m
Normal 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;
|
||||
}
|
Loading…
Reference in a new issue