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:
Niels Grewe 2016-02-22 21:04:18 +00:00
parent 4851131f49
commit 28c824a78a
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> 2016-02-18 Richard Frith-Macdonald <rfm@gnu.org>
* Source/Additions/GSMime.m: * Source/Additions/GSMime.m:
@ -65,7 +90,7 @@
thread object. thread object.
Instead, we add it to a map table, keyed under the current thread ID, 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 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 * Tests/base/NSThread/late_unregister.m: Test case for late
unregistration. unregistration.

View file

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

View file

@ -3,24 +3,24 @@
Written by: David Chisnall <csdavec@swan.ac.uk> Written by: David Chisnall <csdavec@swan.ac.uk>
Created: 2009 Created: 2009
This file is part of the GNUstep Base Library. This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version. version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details. Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA. Boston, MA 02111 USA.
*/ */
#ifndef __NSCache_h_GNUSTEP_BASE_INCLUDE #ifndef __NSCache_h_GNUSTEP_BASE_INCLUDE
#define __NSCache_h_GNUSTEP_BASE_INCLUDE #define __NSCache_h_GNUSTEP_BASE_INCLUDE
@ -35,10 +35,10 @@ extern "C" {
#endif #endif
@class NSString; @class NSString;
@class NSMutableDictionary; @class NSMapTable;
@class NSMutableArray; @class GS_GENERIC_CLASS(NSMutableArray, ElementT);
@interface NSCache : NSObject @interface GS_GENERIC_CLASS(NSCache, KeyT, ValT) : NSObject
{ {
#if GS_EXPOSE(NSCache) #if GS_EXPOSE(NSCache)
@private @private
@ -55,9 +55,9 @@ extern "C" {
/** Name of this cache. */ /** Name of this cache. */
NSString *_name; NSString *_name;
/** The mapping from names to objects in this cache. */ /** The mapping from names to objects in this cache. */
NSMutableDictionary *_objects; NSMapTable *_objects;
/** LRU ordering of all potentially-evictable objects in this cache. */ /** LRU ordering of all potentially-evictable objects in this cache. */
NSMutableArray *_accesses; GS_GENERIC_CLASS(NSMutableArray, ValT) *_accesses;
/** Total number of accesses to objects */ /** Total number of accesses to objects */
int64_t _totalAccesses; int64_t _totalAccesses;
#endif #endif
@ -71,11 +71,16 @@ extern "C" {
@private id _internal GS_UNUSED_IVAR; @private id _internal GS_UNUSED_IVAR;
#endif #endif
} }
/** /**
* Returns the maximum number of objects that are supported by this cache. * Returns the maximum number of objects that are supported by this cache.
*/ */
- (NSUInteger) countLimit; - (NSUInteger) countLimit;
/**
* Returns the total cost of all objects held in the cache.
*/
- (NSUInteger) totalCostLimit;
/** /**
* Returns the cache's delegate. * Returns the cache's delegate.
*/ */
@ -96,7 +101,8 @@ extern "C" {
/** /**
* Returns an object associated with the specified key in this cache. * 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. * Removes all objects from this cache.
@ -106,7 +112,7 @@ extern "C" {
/** /**
* Removes the object associated with the given key. * 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 * 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 * total cost below the value set with -setTotalCostLimit: by discarding the
* contents of objects which implement the NSDiscardableContent protocol. * 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. * 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 * Sets the maximum total cost for objects stored in this cache. This limit is

View file

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

View file

@ -1,4 +1,4 @@
/* /*
NSEnumerator.h NSEnumerator.h
Copyright (C) 1998 Free Software Foundation, Inc. Copyright (C) 1998 Free Software Foundation, Inc.
@ -12,7 +12,7 @@
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version. version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
@ -30,11 +30,14 @@
#import <Foundation/NSObject.h> #import <Foundation/NSObject.h>
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
#endif #endif
typedef struct @class GS_GENERIC_CLASS(NSArray, ElementT);
typedef struct
{ {
unsigned long state; unsigned long state;
__unsafe_unretained id *itemsPtr; __unsafe_unretained id *itemsPtr;
@ -43,14 +46,14 @@ typedef struct
} NSFastEnumerationState; } NSFastEnumerationState;
@protocol NSFastEnumeration @protocol NSFastEnumeration
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState *)state - (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState *)state
objects: (__unsafe_unretained id[])stackbuf objects: (__unsafe_unretained id[])stackbuf
count: (NSUInteger)len; count: (NSUInteger)len;
@end @end
@interface NSEnumerator : NSObject <NSFastEnumeration> @interface GS_GENERIC_CLASS(NSEnumerator, IterT) : NSObject <NSFastEnumeration>
- (NSArray *) allObjects; - (GS_GENERIC_CLASS(NSArray, IterT) *) allObjects;
- (id) nextObject; - (GS_GENERIC_TYPE(IterT)) nextObject;
@end @end
#if defined(__cplusplus) #if defined(__cplusplus)

View file

@ -48,7 +48,7 @@
#if defined(__hppa__) && defined(__hpux__) && !defined(PRIuPTR) #if defined(__hppa__) && defined(__hpux__) && !defined(PRIuPTR)
#define PRIuPTR "lu" #define PRIuPTR "lu"
#endif #endif
/* IRIX kludge. */ /* IRIX kludge. */
#if defined(__sgi) #if defined(__sgi)
/* IRIX 6.5 <inttypes.h> provides all definitions, but only for C99 /* IRIX 6.5 <inttypes.h> provides all definitions, but only for C99
@ -70,7 +70,7 @@
are uintptr_t, which is always unsigned long. */ are uintptr_t, which is always unsigned long. */
#define PRIuPTR "lu" #define PRIuPTR "lu"
#endif #endif
/* Solaris < 10 kludge. */ /* Solaris < 10 kludge. */
#if defined(__sun__) && defined(__svr4__) && !defined(PRIuPTR) #if defined(__sun__) && defined(__svr4__) && !defined(PRIuPTR)
#if defined(__arch64__) || defined (__x86_64__) #if defined(__arch64__) || defined (__x86_64__)
@ -157,11 +157,30 @@ extern "C" {
#if __has_feature(nullability) #if __has_feature(nullability)
# define NS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") # define NS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
# define NS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") # define NS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
#else #else
# define NS_ASSUME_NONNULL_BEGIN # define NS_ASSUME_NONNULL_BEGIN
# define NS_ASSUME_NONNULL_END # define NS_ASSUME_NONNULL_END
#endif #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. /** Bitfield used to specify options to control enumeration over collections.
*/ */
typedef NS_OPTIONS(NSUInteger, NSEnumerationOptions) typedef NS_OPTIONS(NSUInteger, NSEnumerationOptions)

View file

@ -3,19 +3,19 @@
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu> Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: Sep 1995 Created: Sep 1995
This file is part of the GNUstep Base Library. This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version. version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details. Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
@ -24,7 +24,7 @@
AutogsdocSource: NSSet.m AutogsdocSource: NSSet.m
AutogsdocSource: NSCountedSet.m AutogsdocSource: NSCountedSet.m
*/ */
#ifndef _NSSet_h_GNUSTEP_BASE_INCLUDE #ifndef _NSSet_h_GNUSTEP_BASE_INCLUDE
#define _NSSet_h_GNUSTEP_BASE_INCLUDE #define _NSSet_h_GNUSTEP_BASE_INCLUDE
@ -38,38 +38,45 @@
extern "C" { extern "C" {
#endif #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; + (instancetype) set;
+ (id) setWithArray: (NSArray*)objects; + (instancetype) setWithArray: (GS_GENERIC_CLASS(NSArray, ElementT)*)objects;
+ (id) setWithObject: (id)anObject; + (instancetype) setWithObject: (GS_GENERIC_TYPE(ElementT))anObject;
+ (id) setWithObjects: (id)firstObject, ...; + (instancetype) setWithObjects: (GS_GENERIC_TYPE(ElementT))firstObject, ...;
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) #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; count: (NSUInteger)count;
#endif #endif
+ (id) setWithSet: (NSSet*)aSet; + (instancetype) setWithSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)aSet;
- (NSArray*) allObjects; - (GS_GENERIC_CLASS(NSArray, ElementT)*) allObjects;
- (id) anyObject; - (GS_GENERIC_TYPE(ElementT)) anyObject;
- (BOOL) containsObject: (id)anObject; - (BOOL) containsObject: (GS_GENERIC_TYPE(ElementT))anObject;
- (NSUInteger) count; - (NSUInteger) count;
- (NSString*) description; - (NSString*) description;
- (NSString*) descriptionWithLocale: (id)locale; - (NSString*) descriptionWithLocale: (id)locale;
- (id) init; - (instancetype) init;
- (id) initWithArray: (NSArray*)other; - (instancetype) initWithArray: (GS_GENERIC_CLASS(NSArray, ElementT)*)other;
- (id) initWithObjects: (id)firstObject, ...; - (instancetype) initWithObjects: (GS_GENERIC_TYPE(ElementT))firstObject, ...;
- (id) initWithObjects: (const id[])objects - (instancetype) initWithObjects: (const GS_GENERIC_TYPE(ElementT)[])objects
count: (NSUInteger)count; count: (NSUInteger)count;
- (id) initWithSet: (NSSet*)other; - (instancetype) initWithSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
- (id) initWithSet: (NSSet*)other copyItems: (BOOL)flag; - (instancetype) initWithSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other
copyItems: (BOOL)flag;
- (BOOL) intersectsSet: (NSSet*)otherSet; - (BOOL) intersectsSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)otherSet;
- (BOOL) isEqualToSet: (NSSet*)other; - (BOOL) isEqualToSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
- (BOOL) isSubsetOfSet: (NSSet*)otherSet; - (BOOL) isSubsetOfSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)otherSet;
- (void) makeObjectsPerform: (SEL)aSelector; - (void) makeObjectsPerform: (SEL)aSelector;
- (void) makeObjectsPerform: (SEL)aSelector withObject: (id)argument; - (void) makeObjectsPerform: (SEL)aSelector withObject: (id)argument;
@ -77,13 +84,13 @@ extern "C" {
- (void) makeObjectsPerformSelector: (SEL)aSelector; - (void) makeObjectsPerformSelector: (SEL)aSelector;
- (void) makeObjectsPerformSelector: (SEL)aSelector withObject: (id)argument; - (void) makeObjectsPerformSelector: (SEL)aSelector withObject: (id)argument;
#endif #endif
- (id) member: (id)anObject; - (GS_GENERIC_TYPE(ElementT)) member: (GS_GENERIC_TYPE(ElementT))anObject;
- (NSEnumerator*) objectEnumerator; - (GS_GENERIC_CLASS(NSEnumerator, ElementT)*) objectEnumerator;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_6, GS_API_LATEST) #if OS_API_VERSION(MAC_OS_X_VERSION_10_6, GS_API_LATEST)
DEFINE_BLOCK_TYPE(GSSetEnumeratorBlock, void, id, BOOL*); DEFINE_BLOCK_TYPE(GSSetEnumeratorBlock, void, GS_GENERIC_TYPE(ElementT), BOOL*);
DEFINE_BLOCK_TYPE(GSSetFilterBlock, BOOL, id, BOOL*); DEFINE_BLOCK_TYPE(GSSetFilterBlock, BOOL, GS_GENERIC_TYPE(ElementT), BOOL*);
/** /**
* Enumerate over the collection using a given block. The first argument is * 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 - (void) enumerateObjectsWithOptions: (NSEnumerationOptions)opts
usingBlock: (GSSetEnumeratorBlock)aBlock; usingBlock: (GSSetEnumeratorBlock)aBlock;
- (NSSet *) objectsPassingTest: (GSSetFilterBlock)aBlock; - (GS_GENERIC_CLASS(NSSet, ElementT) *) objectsPassingTest:
(GSSetFilterBlock)aBlock;
- (NSSet *) objectsWithOptions: (NSEnumerationOptions)opts
passingTest: (GSSetFilterBlock)aBlock;
- (GS_GENERIC_CLASS(NSSet, ElementT) *) objectsWithOptions:
(NSEnumerationOptions)opts
passingTest: (GSSetFilterBlock)aBlock;
#endif #endif
#if OS_API_VERSION(MAC_OS_X_VERSION_10_5,GS_API_LATEST) #if OS_API_VERSION(MAC_OS_X_VERSION_10_5,GS_API_LATEST)
- (NSSet *) setByAddingObject: (id)anObject; - (GS_GENERIC_CLASS(NSSet, ElementT) *) setByAddingObject:
- (NSSet *) setByAddingObjectsFromSet: (NSSet *)other; (GS_GENERIC_TYPE(ElementT))anObject;
- (NSSet *) setByAddingObjectsFromArray: (NSArray *)other; - (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 #endif
@end @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) addObject: (GS_GENERIC_TYPE(ElementT))anObject;
- (void) addObjectsFromArray: (NSArray*)array; - (void) addObjectsFromArray: (GS_GENERIC_CLASS(NSArray, ElementT)*)array;
- (id) initWithCapacity: (NSUInteger)numItems; - (instancetype) initWithCapacity: (NSUInteger)numItems;
- (void) intersectSet: (NSSet*)other; - (void) intersectSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
- (void) minusSet: (NSSet*)other; - (void) minusSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
- (void) removeAllObjects; - (void) removeAllObjects;
- (void) removeObject: (id)anObject; - (void) removeObject: (GS_GENERIC_TYPE(ElementT))anObject;
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) #if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
- (void) setSet: (NSSet*)other; - (void) setSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
#endif #endif
- (void) unionSet: (NSSet*)other; - (void) unionSet: (GS_GENERIC_CLASS(NSSet, ElementT)*)other;
@end @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 @end
@ -148,7 +161,7 @@ DEFINE_BLOCK_TYPE(GSSetFilterBlock, BOOL, id, BOOL*);
/** /**
* Utility methods for using a counted set to handle uniquing of objects. * 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> * <p>
* This method removes from the set all objects whose count is * 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. * is released, and the object in the set is retained and returned.
* Otherwise, the supplied object is added to the set and returned. * Otherwise, the supplied object is added to the set and returned.
* </p> * </p>
* <p> * <p>
* This method is useful for uniquing objects - the init method of * This method is useful for uniquing objects - the init method of
* a class need simply end with - * a class need simply end with -
* <code> * <code>
@ -178,7 +191,8 @@ DEFINE_BLOCK_TYPE(GSSetFilterBlock, BOOL, id, BOOL*);
* </code> * </code>
* </p> * </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 @end
/* /*
@ -190,7 +204,7 @@ DEFINE_BLOCK_TYPE(GSSetFilterBlock, BOOL, id, BOOL*);
* if uniquing is turned off, GSUnique() simply returns its argument. * 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. * 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> Written by: David Chisnall <csdavec@swan.ac.uk>
Created: 2009 Created: 2009
This file is part of the GNUstep Base Library. This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version. version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details. Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA. Boston, MA 02111 USA.
*/ */
#import "common.h" #import "common.h"
@ -28,7 +28,7 @@
#import "Foundation/NSArray.h" #import "Foundation/NSArray.h"
#import "Foundation/NSCache.h" #import "Foundation/NSCache.h"
#import "Foundation/NSDictionary.h" #import "Foundation/NSMapTable.h"
#import "Foundation/NSEnumerator.h" #import "Foundation/NSEnumerator.h"
/** /**
@ -60,7 +60,7 @@
{ {
return nil; return nil;
} }
_objects = [NSMutableDictionary new]; ASSIGN(_objects,[NSMapTable strongToStrongObjectsMapTable]);
_accesses = [NSMutableArray new]; _accesses = [NSMutableArray new];
return self; 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_KTYPES GSUNION_PTR | GSUNION_OBJ | GSUNION_NSINT
#define GSI_MAP_VTYPES GSUNION_PTR | GSUNION_OBJ #define GSI_MAP_VTYPES GSUNION_PTR | GSUNION_OBJ
#define GSI_MAP_RETAIN_KEY(M, X) #define GSI_MAP_RETAIN_KEY(M, X)
#define GSI_MAP_RELEASE_KEY(M, X) #define GSI_MAP_RELEASE_KEY(M, X)
#define GSI_MAP_RETAIN_VAL(M, X) #define GSI_MAP_RETAIN_VAL(M, X)
#define GSI_MAP_RELEASE_VAL(M, X) #define GSI_MAP_RELEASE_VAL(M, X)
#define GSI_MAP_HASH(M, X) ((X).nsu ^ ((X).nsu >> 3)) #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_EQUAL(M, X,Y) ((X).ptr == (Y).ptr)
#define GSI_MAP_NOCLEAN 1 #define GSI_MAP_NOCLEAN 1
#if GS_WITH_GC #if GS_WITH_GC
// FIXME ... // FIXME ...
#include <gc/gc_typed.h> #include <gc/gc_typed.h>
static GC_descr nodeDesc; // Type descriptor for map node. static GC_descr nodeDesc; // Type descriptor for map node.
#define GSI_MAP_NODES(M, X) \ #define GSI_MAP_NODES(M, X) \
@ -174,7 +174,7 @@ GSRunLoopForThread(NSThread *aThread)
@interface NSConnection (GNUstepExtensions) @interface NSConnection (GNUstepExtensions)
- (void) finalize; - (void) finalize;
- (void) forwardInvocation: (NSInvocation *)inv - (void) forwardInvocation: (NSInvocation *)inv
forProxy: (NSDistantObject*)object; forProxy: (NSDistantObject*)object;
- (const char *) typeForSelector: (SEL)sel remoteTarget: (unsigned)target; - (const char *) typeForSelector: (SEL)sel remoteTarget: (unsigned)target;
@end @end
@ -765,7 +765,7 @@ static NSLock *cached_proxies_gate = nil;
return AUTORELEASE(proxy); return AUTORELEASE(proxy);
} }
+ (id) serviceConnectionWithName: (NSString *)name + (id) serviceConnectionWithName: (NSString *)name
rootObject: (id)root rootObject: (id)root
{ {
return [self serviceConnectionWithName: name return [self serviceConnectionWithName: name
@ -773,7 +773,7 @@ static NSLock *cached_proxies_gate = nil;
usingNameServer: [NSPortNameServer systemDefaultPortNameServer]]; usingNameServer: [NSPortNameServer systemDefaultPortNameServer]];
} }
+ (id) serviceConnectionWithName: (NSString *)name + (id) serviceConnectionWithName: (NSString *)name
rootObject: (id)root rootObject: (id)root
usingNameServer: (NSPortNameServer *)server usingNameServer: (NSPortNameServer *)server
{ {
@ -1421,31 +1421,34 @@ static NSLock *cached_proxies_gate = nil;
*/ */
- (NSArray*) localObjects - (NSArray*) localObjects
{ {
NSMutableArray *c; NSArray *a;
/* Don't assert (IisValid); */ /* Don't assert (IisValid); */
GS_M_LOCK(IrefGate); GS_M_LOCK(IrefGate);
if (IlocalObjects != 0) if (IlocalObjects != 0)
{ {
GSIMapEnumerator_t enumerator; GSIMapEnumerator_t enumerator;
GSIMapNode node; GSIMapNode node;
enumerator = GSIMapEnumeratorForMap(IlocalObjects); enumerator = GSIMapEnumeratorForMap(IlocalObjects);
node = GSIMapEnumeratorNextNode(&enumerator); node = GSIMapEnumeratorNextNode(&enumerator);
c = [NSMutableArray arrayWithCapacity: IlocalObjects->nodeCount]; NSMutableArray *c =
[NSMutableArray arrayWithCapacity: IlocalObjects->nodeCount];
while (node != 0) while (node != 0)
{ {
[c addObject: node->key.obj]; [c addObject: node->key.obj];
node = GSIMapEnumeratorNextNode(&enumerator); node = GSIMapEnumeratorNextNode(&enumerator);
} }
a = c;
} }
else else
{ {
c = [NSArray array]; a = [NSArray array];
} }
GSM_UNLOCK(IrefGate); 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"]; format: @"connection waiting for request was shut down"];
} }
aRmc = [self _getReplyRmc: seq]; aRmc = [self _getReplyRmc: seq];
/* /*
* Find out if the server is returning an exception instead * Find out if the server is returning an exception instead
* of the return values. * 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 there is a return value, decode it, and put it in datum. */
if (*tmptype != _C_VOID || (flags & _F_ONEWAY) == 0) if (*tmptype != _C_VOID || (flags & _F_ONEWAY) == 0)
{ {
switch (*tmptype) switch (*tmptype)
{ {
case _C_ID: case _C_ID:
@ -2586,7 +2589,7 @@ static NSLock *cached_proxies_gate = nil;
*/ */
object = [decoder decodeObject]; 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 ":" */ /* xxx @encode(SEL) produces "^v" in gcc 2.5.8. It should be ":" */
[decoder decodeValueOfObjCType: @encode(SEL) at: &selector]; [decoder decodeValueOfObjCType: @encode(SEL) at: &selector];
@ -2606,14 +2609,14 @@ static NSLock *cached_proxies_gate = nil;
object, sel_getName(selector)]; object, sel_getName(selector)];
} }
type = [sig methodType]; type = [sig methodType];
/* Make sure we successfully got the method type, and that its /* Make sure we successfully got the method type, and that its
types match the ENCODED_TYPES. */ types match the ENCODED_TYPES. */
NSCParameterAssert (type); NSCParameterAssert (type);
if (GSSelectorTypesMatch(encoded_types, type) == NO) if (GSSelectorTypesMatch(encoded_types, type) == NO)
{ {
[NSException raise: NSInvalidArgumentException [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)]; encoded_types, type, sel_getName(selector)];
} }
@ -3394,7 +3397,7 @@ static NSLock *cached_proxies_gate = nil;
sendPort:IsendPort sendPort:IsendPort
components: nil]; components: nil];
[coder encodeValueOfObjCType: @encode(int) at: &sno]; [coder encodeValueOfObjCType: @encode(int) at: &sno];
NSDebugMLLog(@"NSConnection", NSDebugMLLog(@"NSConnection",
@"Make out RMC %u on %@", sno, self); @"Make out RMC %u on %@", sno, self);
return coder; return coder;
} }
@ -3441,7 +3444,7 @@ static NSLock *cached_proxies_gate = nil;
break; break;
} }
NSDebugMLLog(@"NSConnection", NSDebugMLLog(@"NSConnection",
@"Sending %@ on %@", stringFromMsgType(msgid), self); @"Sending %@ on %@", stringFromMsgType(msgid), self);
limit = [dateClass dateWithTimeIntervalSinceNow: IrequestTimeout]; 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 * We enumerate an array copy of the contents of the hash table
* as we know we can do that safely outside the locked region. * as we know we can do that safely outside the locked region.
* The temporary array and the enumerator are autoreleased and * 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) while ((c = [enumerator nextObject]) != nil)
{ {
@ -4044,4 +4047,3 @@ static NSLock *cached_proxies_gate = nil;
} }
} }
@end @end

View file

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

View file

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