mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Merge branch 'master' of github.com:gnustep/libs-base
This commit is contained in:
commit
ab7f39d833
14 changed files with 930 additions and 1039 deletions
29
ChangeLog
29
ChangeLog
|
@ -1,3 +1,32 @@
|
|||
2019-10-28 Wolfgang Lux <wolfgang.lux@gmail.com>
|
||||
|
||||
* Source/GSSocketStream.m:
|
||||
Prevent premature deallocation when a socket is closed while in a
|
||||
TLS handshake.
|
||||
|
||||
2019-10-27 Fred Kiefer <fredkiefer@gmx.de>
|
||||
|
||||
* Headers/Foundation/NSUnit.h,
|
||||
* Source/NSUnit.m: Clean up code and fix bugs.
|
||||
|
||||
2019-10-17 Frederik Seiffert <frederik@algoriddim.com>
|
||||
|
||||
* Source/GSDispatch.h:
|
||||
* Source/NSArray.m:
|
||||
* Source/NSDictionary.m:
|
||||
* Source/NSIndexSet.m:
|
||||
* Source/NSOrderedSet.m:
|
||||
* Source/NSSet.m:
|
||||
Perform non-concurrent block enumeration calls in place instead
|
||||
of using serial queue to match Apple platforms.
|
||||
|
||||
2019-10-25 Frederik Seiffert <frederik@algoriddim.com>
|
||||
|
||||
* Headers/Foundation/NSMapTable.h:
|
||||
* Headers/Foundation/NSHashTable.h:
|
||||
Added generics support to NSMapTable and updated NSMapTable and
|
||||
NSHashTable to use "instancetype".
|
||||
|
||||
2019-10-02 Frederik Seiffert <frederik@algoriddim.com>
|
||||
|
||||
* Source/NSDictionary.m: fixed mutable dictionary keyed subscript
|
||||
|
|
|
@ -62,7 +62,7 @@ GS_EXPORT const NSTimeInterval NSTimeIntervalSince1970;
|
|||
|
||||
/** Returns an autoreleased instance with the current date/time.
|
||||
*/
|
||||
+ (id) date;
|
||||
+ (instancetype) date;
|
||||
|
||||
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
|
||||
/** Returns an autoreleased instance representing the date and time given
|
||||
|
@ -70,7 +70,7 @@ GS_EXPORT const NSTimeInterval NSTimeIntervalSince1970;
|
|||
* specified by the preferences in the user defaults database, allowing
|
||||
* phrases like 'last tuesday'
|
||||
*/
|
||||
+ (id) dateWithNaturalLanguageString: (NSString*)string;
|
||||
+ (instancetype) dateWithNaturalLanguageString: (NSString*)string;
|
||||
|
||||
/**
|
||||
* <p>Returns an autoreleased instance representing the date and time given
|
||||
|
@ -119,47 +119,48 @@ GS_EXPORT const NSTimeInterval NSTimeIntervalSince1970;
|
|||
* </desc>
|
||||
* </deflist>
|
||||
*/
|
||||
+ (id) dateWithNaturalLanguageString: (NSString*)string
|
||||
locale: (NSDictionary*)locale;
|
||||
+ (instancetype) dateWithNaturalLanguageString: (NSString*)string
|
||||
locale: (NSDictionary*)locale;
|
||||
#endif
|
||||
|
||||
/** Returns an autoreleased instance with the date and time value given
|
||||
* by the string using the ISO standard format YYYY-MM-DD HH:MM:SS +/-HHHMM
|
||||
* (all the fields of which must be present).
|
||||
*/
|
||||
+ (id) dateWithString: (NSString*)description;
|
||||
+ (instancetype) dateWithString: (NSString*)description;
|
||||
|
||||
#if OS_API_VERSION(MAC_OS_X_VERSION_10_6,GS_API_LATEST)
|
||||
/** Returns an autoreleased NSDate instance whose value is offset from
|
||||
* that of the given date by the specified interval in seconds.
|
||||
*/
|
||||
+ (id) dateWithTimeInterval: (NSTimeInterval)seconds sinceDate: (NSDate*)date;
|
||||
+ (instancetype) dateWithTimeInterval: (NSTimeInterval)seconds
|
||||
sinceDate: (NSDate*)date;
|
||||
#endif
|
||||
|
||||
/** Returns an autoreleased instance with the offset from the unix system
|
||||
* reference date of 1 January 1970, GMT.
|
||||
*/
|
||||
+ (id) dateWithTimeIntervalSince1970: (NSTimeInterval)seconds;
|
||||
+ (instancetype) dateWithTimeIntervalSince1970: (NSTimeInterval)seconds;
|
||||
|
||||
/** Returns an autoreleased instance with the offset from the current
|
||||
* date/time given by seconds (which may be fractional).
|
||||
*/
|
||||
+ (id) dateWithTimeIntervalSinceNow: (NSTimeInterval)seconds;
|
||||
+ (instancetype) dateWithTimeIntervalSinceNow: (NSTimeInterval)seconds;
|
||||
|
||||
/** Returns an autoreleased instance with the offset from the OpenStep
|
||||
* reference date of 1 January 2001, GMT.
|
||||
*/
|
||||
+ (id) dateWithTimeIntervalSinceReferenceDate: (NSTimeInterval)seconds;
|
||||
+ (instancetype) dateWithTimeIntervalSinceReferenceDate: (NSTimeInterval)seconds;
|
||||
|
||||
/** Returns an autoreleased instance with the date/time set in the far
|
||||
* past.
|
||||
*/
|
||||
+ (id) distantPast;
|
||||
+ (instancetype) distantPast;
|
||||
|
||||
/** Returns an autoreleased instance with the date/time set in the far
|
||||
* future.
|
||||
*/
|
||||
+ (id) distantFuture;
|
||||
+ (instancetype) distantFuture;
|
||||
|
||||
/** Returns the time interval between the reference date and the current
|
||||
* time.
|
||||
|
@ -169,7 +170,7 @@ GS_EXPORT const NSTimeInterval NSTimeIntervalSince1970;
|
|||
/** Returns an autorelease date instance formed by adding the specified
|
||||
* time interval in seconds to the receiver's time interval.
|
||||
*/
|
||||
- (id) addTimeInterval: (NSTimeInterval)seconds;
|
||||
- (instancetype) addTimeInterval: (NSTimeInterval)seconds;
|
||||
|
||||
/** Returns the time interval between the receivers value and the
|
||||
* OpenStep reference date of 1 Jan 2001 GMT.
|
||||
|
@ -180,7 +181,7 @@ GS_EXPORT const NSTimeInterval NSTimeIntervalSince1970;
|
|||
/** Returns an autoreleased NSDate instance whose value is offset from
|
||||
* that of the receiver by the specified interval.
|
||||
*/
|
||||
- (id) dateByAddingTimeInterval: (NSTimeInterval)ti;
|
||||
- (instancetype) dateByAddingTimeInterval: (NSTimeInterval)ti;
|
||||
#endif
|
||||
|
||||
/** Returns an autoreleased instance of the [NSCalendarDate] class whose
|
||||
|
@ -214,35 +215,35 @@ GS_EXPORT const NSTimeInterval NSTimeIntervalSince1970;
|
|||
|
||||
/** Returns an instance initialised with the current date/time.
|
||||
*/
|
||||
- (id) init;
|
||||
- (instancetype) init;
|
||||
|
||||
/** Returns an instance with the date and time value given
|
||||
* by the string using the ISO standard format YYYY-MM-DD HH:MM:SS +/-HHHMM
|
||||
* (all the fields of which must be present).
|
||||
*/
|
||||
- (id) initWithString: (NSString*)description;
|
||||
- (instancetype) initWithString: (NSString*)description;
|
||||
|
||||
/** Returns an instance with the given offset from anotherDate.
|
||||
*/
|
||||
- (id) initWithTimeInterval: (NSTimeInterval)secsToBeAdded
|
||||
sinceDate: (NSDate*)anotherDate;
|
||||
- (instancetype) initWithTimeInterval: (NSTimeInterval)secsToBeAdded
|
||||
sinceDate: (NSDate*)anotherDate;
|
||||
|
||||
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
|
||||
/** Returns an instance with the offset from the unix system
|
||||
* reference date of 1 January 1970, GMT.
|
||||
*/
|
||||
- (id) initWithTimeIntervalSince1970: (NSTimeInterval)seconds;
|
||||
- (instancetype) initWithTimeIntervalSince1970: (NSTimeInterval)seconds;
|
||||
#endif
|
||||
|
||||
/** Returns an instance with the offset from the current date/time.
|
||||
*/
|
||||
- (id) initWithTimeIntervalSinceNow: (NSTimeInterval)secsToBeAdded;
|
||||
- (instancetype) initWithTimeIntervalSinceNow: (NSTimeInterval)secsToBeAdded;
|
||||
|
||||
/** <init />
|
||||
* Returns an instance with the given offset from the OpenStep
|
||||
* reference date of 1 January 2001, GMT.
|
||||
*/
|
||||
- (id) initWithTimeIntervalSinceReferenceDate: (NSTimeInterval)secs;
|
||||
- (instancetype) initWithTimeIntervalSinceReferenceDate: (NSTimeInterval)secs;
|
||||
|
||||
/** Returns NO if other is not a date, otherwise returns the result of
|
||||
* calling the -isEqualtoDate: method.
|
||||
|
|
|
@ -63,23 +63,23 @@ typedef NSUInteger NSHashTableOptions;
|
|||
|
||||
@interface GS_GENERIC_CLASS(NSHashTable, ElementT) : NSObject <NSCopying, NSCoding, NSFastEnumeration>
|
||||
|
||||
+ (id) hashTableWithOptions: (NSPointerFunctionsOptions)options;
|
||||
+ (instancetype) hashTableWithOptions: (NSPointerFunctionsOptions)options;
|
||||
|
||||
+ (id) hashTableWithWeakObjects;
|
||||
+ (instancetype) hashTableWithWeakObjects;
|
||||
/**
|
||||
* Creates a hash table that uses zeroing weak references (either using the
|
||||
* automatic reference counting or garbage collection mechanism, depending on
|
||||
* which mode this framework is compiled in) so that objects are removed when
|
||||
* their last other reference disappears.
|
||||
*/
|
||||
+ (id) weakObjectsHashTable;
|
||||
+ (instancetype) weakObjectsHashTable;
|
||||
|
||||
|
||||
- (id) initWithOptions: (NSPointerFunctionsOptions)options
|
||||
capacity: (NSUInteger)initialCapacity;
|
||||
- (instancetype) initWithOptions: (NSPointerFunctionsOptions)options
|
||||
capacity: (NSUInteger)initialCapacity;
|
||||
|
||||
- (id) initWithPointerFunctions: (NSPointerFunctions*)functions
|
||||
capacity: (NSUInteger)initialCapacity;
|
||||
- (instancetype) initWithPointerFunctions: (NSPointerFunctions*)functions
|
||||
capacity: (NSUInteger)initialCapacity;
|
||||
|
||||
/** Adds the object to the receiver.
|
||||
*/
|
||||
|
|
|
@ -59,67 +59,68 @@ enum {
|
|||
|
||||
typedef NSUInteger NSMapTableOptions;
|
||||
|
||||
@interface NSMapTable : NSObject <NSCopying, NSCoding, NSFastEnumeration>
|
||||
@interface GS_GENERIC_CLASS(NSMapTable, KeyT, ValT)
|
||||
: NSObject <NSCopying, NSCoding, NSFastEnumeration>
|
||||
|
||||
/** Return a map table initialised using the specified options for
|
||||
* keys and values.
|
||||
*/
|
||||
+ (id) mapTableWithKeyOptions: (NSPointerFunctionsOptions)keyOptions
|
||||
valueOptions: (NSPointerFunctionsOptions)valueOptions;
|
||||
+ (instancetype) mapTableWithKeyOptions: (NSPointerFunctionsOptions)keyOptions
|
||||
valueOptions: (NSPointerFunctionsOptions)valueOptions;
|
||||
|
||||
/** Convenience method for creating a map table to store object values
|
||||
* using object keys.
|
||||
*/
|
||||
+ (id) mapTableWithStrongToStrongObjects;
|
||||
+ (instancetype) mapTableWithStrongToStrongObjects;
|
||||
|
||||
/** Convenience method for creating a map table to store non-retained
|
||||
* object values with retained object keys.
|
||||
*/
|
||||
+ (id) mapTableWithStrongToWeakObjects;
|
||||
+ (instancetype) mapTableWithStrongToWeakObjects;
|
||||
|
||||
/** Convenience method for creating a map table to store retained
|
||||
* object values with non-retained object keys.
|
||||
*/
|
||||
+ (id) mapTableWithWeakToStrongObjects;
|
||||
+ (instancetype) mapTableWithWeakToStrongObjects;
|
||||
|
||||
/** Convenience method for creating a map table to store non-retained
|
||||
* object values with non-retained object keys.
|
||||
*/
|
||||
+ (id) mapTableWithWeakToWeakObjects;
|
||||
+ (instancetype) mapTableWithWeakToWeakObjects;
|
||||
|
||||
/** Convenience method for creating a map table to store object values
|
||||
* using object keys. The collection will retain both the key and the value.
|
||||
*/
|
||||
+ (id) strongToStrongObjectsMapTable;
|
||||
+ (instancetype) strongToStrongObjectsMapTable;
|
||||
/** Convenience method for creating a map table to store object values
|
||||
* using object keys. The collection will retain the key, the value will be a
|
||||
* zeroing weak reference.
|
||||
*/
|
||||
+ (id) strongToWeakObjectsMapTable;
|
||||
+ (instancetype) strongToWeakObjectsMapTable;
|
||||
/** Convenience method for creating a map table to store object values
|
||||
* using object keys. The collection will retain the value, the key will be a
|
||||
* zeroing weak reference.
|
||||
*/
|
||||
+ (id) weakToStrongObjectsMapTable;
|
||||
+ (instancetype) weakToStrongObjectsMapTable;
|
||||
/** Convenience method for creating a map table to store object values
|
||||
* using object keys. The collection will use zeroing weak references for both
|
||||
* the key and the value.
|
||||
*/
|
||||
+ (id) weakToWeakObjectsMapTable;
|
||||
+ (instancetype) weakToWeakObjectsMapTable;
|
||||
|
||||
|
||||
/** Initialiser using option bitmasks to describe the keys and values.
|
||||
*/
|
||||
- (id) initWithKeyOptions: (NSPointerFunctionsOptions)keyOptions
|
||||
valueOptions: (NSPointerFunctionsOptions)valueOptions
|
||||
capacity: (NSUInteger)initialCapacity;
|
||||
- (instancetype) initWithKeyOptions: (NSPointerFunctionsOptions)keyOptions
|
||||
valueOptions: (NSPointerFunctionsOptions)valueOptions
|
||||
capacity: (NSUInteger)initialCapacity;
|
||||
|
||||
/** Initialiser using full pointer function information to describe
|
||||
* the keys and values.
|
||||
*/
|
||||
- (id) initWithKeyPointerFunctions: (NSPointerFunctions*)keyFunctions
|
||||
valuePointerFunctions: (NSPointerFunctions*)valueFunctions
|
||||
capacity: (NSUInteger)initialCapacity;
|
||||
- (instancetype) initWithKeyPointerFunctions: (NSPointerFunctions*)keyFunctions
|
||||
valuePointerFunctions: (NSPointerFunctions*)valueFunctions
|
||||
capacity: (NSUInteger)initialCapacity;
|
||||
|
||||
/** Return the number of items stored in the map.
|
||||
*/
|
||||
|
@ -131,7 +132,7 @@ typedef NSUInteger NSMapTableOptions;
|
|||
|
||||
/** Return an enumerator able to enumerate the keys in the receiver.
|
||||
*/
|
||||
- (NSEnumerator*) keyEnumerator;
|
||||
- (GS_GENERIC_CLASS(NSEnumerator, KeyT)*) keyEnumerator;
|
||||
|
||||
/** Return an NSPointerFunctions value describind the functions used by the
|
||||
* receiver to handle keys.
|
||||
|
@ -140,11 +141,11 @@ typedef NSUInteger NSMapTableOptions;
|
|||
|
||||
/** Return an enumerator able to enumerate the values in the receiver.
|
||||
*/
|
||||
- (NSEnumerator*) objectEnumerator;
|
||||
- (GS_GENERIC_CLASS(NSEnumerator, ValT)*) objectEnumerator;
|
||||
|
||||
/** Return the object stored under the specified key.
|
||||
*/
|
||||
- (id) objectForKey: (id)aKey;
|
||||
- (GS_GENERIC_TYPE(ValT)) objectForKey: (GS_GENERIC_TYPE(KeyT))aKey;
|
||||
|
||||
/** Empty the receiver of all stored values.
|
||||
*/
|
||||
|
@ -152,12 +153,12 @@ typedef NSUInteger NSMapTableOptions;
|
|||
|
||||
/** Remove the object stored under the specified key.
|
||||
*/
|
||||
- (void) removeObjectForKey: (id)aKey;
|
||||
- (void) removeObjectForKey: (GS_GENERIC_TYPE(KeyT))aKey;
|
||||
|
||||
/** Store the object under the specified key, replacing any object which
|
||||
* was previously stored under that key.
|
||||
*/
|
||||
- (void) setObject: (id)anObject forKey: (id)aKey;
|
||||
- (void) setObject: (GS_GENERIC_TYPE(ValT))anObject forKey: (GS_GENERIC_TYPE(KeyT))aKey;
|
||||
|
||||
/** Return an NSPointerFunctions value describind the functions used by the
|
||||
* receiver to handle values.
|
||||
|
|
|
@ -72,7 +72,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
- (NSUnitConverter *) converter;
|
||||
- (instancetype) initWithSymbol: (NSString *)symbol converter: (NSUnitConverter *)converter ;
|
||||
- (instancetype) initWithSymbol: (NSString *)symbol converter: (NSUnitConverter *)converter;
|
||||
+ (instancetype) baseUnit;
|
||||
|
||||
@end
|
||||
|
|
|
@ -70,13 +70,21 @@
|
|||
* Release an dispatch object.
|
||||
*/
|
||||
#define GS_DISPATCH_RELEASE(x) dispatch_release(x)
|
||||
|
||||
/**
|
||||
* Allows an arbitrary block to be submitted to the queue. Since dispatch blocks
|
||||
* return nothing and take no arguments, the caller can use the before and after
|
||||
* arguments to set up and tear down the block as required.
|
||||
* Allows an arbitrary block to be submitted to the queue (if available) or run
|
||||
* in place. Since dispatch blocks return nothing and take no arguments, the
|
||||
* caller can use the before and after arguments to guard calling the block as
|
||||
* required.
|
||||
*/
|
||||
#define GS_DISPATCH_SUBMIT_BLOCK(group, queue, before, after, block, args, ...) \
|
||||
dispatch_group_async(group, queue, ^(void){before; block(args, ## __VA_ARGS__); after;})
|
||||
if (queue != NULL) {\
|
||||
dispatch_group_async(group, queue, ^(void){before block(args, ## __VA_ARGS__); after});\
|
||||
} else {\
|
||||
before\
|
||||
block(args, ## __VA_ARGS__);\
|
||||
after\
|
||||
}
|
||||
|
||||
/**
|
||||
* Submits a block without special provisions.
|
||||
|
@ -85,32 +93,30 @@
|
|||
|
||||
|
||||
/**
|
||||
* Convenience macro to create serial or concurrent dispatch queues for the
|
||||
* various -enumerateUsingBlock: methods.
|
||||
* Convenience macro to create concurrent dispatch queues for the various
|
||||
* -enumerateUsingBlock: methods. Non-concurrent will be run in place.
|
||||
*/
|
||||
#define GS_DISPATCH_CREATE_QUEUE_AND_GROUP_FOR_ENUMERATION(queue, opts)\
|
||||
dispatch_queue_t queue;\
|
||||
dispatch_group_t queue ## Group;\
|
||||
dispatch_queue_t queue = NULL;\
|
||||
dispatch_group_t queue ## Group = NULL;\
|
||||
if (opts & NSEnumerationConcurrent)\
|
||||
{\
|
||||
queue = GS_DISPATCH_GET_DEFAULT_CONCURRENT_QUEUE();\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
queue = GS_DISPATCH_QUEUE_CREATE(DISPATCH_QUEUE_SERIAL);\
|
||||
}\
|
||||
queue ## Group = GS_DISPATCH_GROUP_CREATE();
|
||||
queue ## Group = GS_DISPATCH_GROUP_CREATE();\
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience macro to destroy serial or concurrent dispatch queues for the
|
||||
* various -enumerateUsingBlock: methods.
|
||||
* Convenience macro to destroy concurrent dispatch queues for the various
|
||||
* -enumerateUsingBlock: methods.
|
||||
*/
|
||||
#define GS_DISPATCH_TEARDOWN_QUEUE_AND_GROUP_FOR_ENUMERATION(queue, opts)\
|
||||
GS_DISPATCH_GROUP_FINISH(queue ## Group);\
|
||||
GS_DISPATCH_RELEASE(enumQueueGroup);\
|
||||
if (NO == (opts & NSEnumerationConcurrent))\
|
||||
{\
|
||||
GS_DISPATCH_RELEASE(enumQueue);\
|
||||
if (queue != NULL) { \
|
||||
GS_DISPATCH_GROUP_FINISH(queue ## Group);\
|
||||
GS_DISPATCH_RELEASE(queue ## Group);\
|
||||
if (NO == (opts & NSEnumerationConcurrent))\
|
||||
{\
|
||||
GS_DISPATCH_RELEASE(queue);\
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1584,14 +1584,26 @@ setNonBlocking(SOCKET fd)
|
|||
*/
|
||||
if (_handler != nil && [_handler handshake] == YES)
|
||||
{
|
||||
id hdl = _handler;
|
||||
id del = _delegate;
|
||||
BOOL val = _delegateValid;
|
||||
|
||||
_delegate = _handler;
|
||||
/* Retain self to prevent a dangling pointer the handler closes and
|
||||
* releases this socket. Also, do not restore the old delegate if it
|
||||
* was changed directly or indirectly by the handler.
|
||||
* FIXME We leave the socket an inconsistent state if any exception
|
||||
* is raised in _sendEvent:.
|
||||
*/
|
||||
RETAIN(self);
|
||||
_delegate = hdl;
|
||||
_delegateValid = YES;
|
||||
[super _sendEvent: event];
|
||||
_delegate = del;
|
||||
_delegateValid = val;
|
||||
if (_delegate == hdl)
|
||||
{
|
||||
_delegate = del;
|
||||
_delegateValid = val;
|
||||
}
|
||||
RELEASE(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1790,7 +1790,7 @@ compare(id elem1, id elem2, void* context)
|
|||
{
|
||||
GS_DISPATCH_CREATE_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts)
|
||||
FOR_IN (id, obj, enumerator)
|
||||
GS_DISPATCH_SUBMIT_BLOCK(enumQueueGroup, enumQueue, if (YES == shouldStop) {return;}, return, aBlock, obj, count, &shouldStop);
|
||||
GS_DISPATCH_SUBMIT_BLOCK(enumQueueGroup, enumQueue, if (shouldStop == NO) {, }, aBlock, obj, count, &shouldStop);
|
||||
if (isReverse)
|
||||
{
|
||||
count--;
|
||||
|
@ -1841,30 +1841,32 @@ compare(id elem1, id elem2, void* context)
|
|||
GS_DISPATCH_CREATE_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts)
|
||||
FOR_IN (id, obj, enumerator)
|
||||
# if __has_feature(blocks) && (GS_USE_LIBDISPATCH == 1)
|
||||
|
||||
dispatch_group_async(enumQueueGroup, enumQueue, ^(void){
|
||||
if (shouldStop)
|
||||
if (enumQueue != NULL)
|
||||
{
|
||||
return;
|
||||
dispatch_group_async(enumQueueGroup, enumQueue, ^(void){
|
||||
if (shouldStop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (predicate(obj, count, &shouldStop))
|
||||
{
|
||||
[setLock lock];
|
||||
[set addIndex: count];
|
||||
[setLock unlock];
|
||||
}
|
||||
});
|
||||
}
|
||||
if (predicate(obj, count, &shouldStop))
|
||||
{
|
||||
[setLock lock];
|
||||
[set addIndex: count];
|
||||
[setLock unlock];
|
||||
}
|
||||
});
|
||||
# else
|
||||
else // call block directly
|
||||
# endif
|
||||
if (CALL_BLOCK(predicate, obj, count, &shouldStop))
|
||||
{
|
||||
/* TODO: It would be more efficient to collect an NSRange and only
|
||||
* pass it to the index set when CALL_BLOCK returned NO. */
|
||||
[set addIndex: count];
|
||||
/* TODO: It would be more efficient to collect an NSRange and only
|
||||
* pass it to the index set when CALL_BLOCK returned NO. */
|
||||
[set addIndex: count];
|
||||
}
|
||||
# endif
|
||||
if (shouldStop)
|
||||
{
|
||||
break;
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
END_FOR_IN(enumerator)
|
||||
|
@ -1936,33 +1938,35 @@ compare(id elem1, id elem2, void* context)
|
|||
GS_DISPATCH_CREATE_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts)
|
||||
FOR_IN (id, obj, enumerator)
|
||||
# if __has_feature(blocks) && (GS_USE_LIBDISPATCH == 1)
|
||||
dispatch_group_async(enumQueueGroup, enumQueue, ^(void){
|
||||
if (shouldStop)
|
||||
if (enumQueue != NULL)
|
||||
{
|
||||
return;
|
||||
dispatch_group_async(enumQueueGroup, enumQueue, ^(void){
|
||||
if (shouldStop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (predicate(obj, count, &shouldStop))
|
||||
{
|
||||
// FIXME: atomic operation on the shouldStop variable would be nicer,
|
||||
// but we don't expose the GSAtomic* primitives anywhere.
|
||||
[indexLock lock];
|
||||
index = count;
|
||||
// Cancel all other predicate evaluations:
|
||||
shouldStop = YES;
|
||||
[indexLock unlock];
|
||||
}
|
||||
});
|
||||
}
|
||||
if (predicate(obj, count, &shouldStop))
|
||||
{
|
||||
// FIXME: atomic operation on the shouldStop variable would be nicer,
|
||||
// but we don't expose the GSAtomic* primitives anywhere.
|
||||
[indexLock lock];
|
||||
index = count;
|
||||
// Cancel all other predicate evaluations:
|
||||
shouldStop = YES;
|
||||
[indexLock unlock];
|
||||
}
|
||||
});
|
||||
# else
|
||||
else // call block directly
|
||||
# endif
|
||||
if (CALL_BLOCK(predicate, obj, count, &shouldStop))
|
||||
{
|
||||
|
||||
index = count;
|
||||
shouldStop = YES;
|
||||
index = count;
|
||||
shouldStop = YES;
|
||||
}
|
||||
# endif
|
||||
if (shouldStop)
|
||||
{
|
||||
break;
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
END_FOR_IN(enumerator)
|
||||
|
|
|
@ -159,7 +159,7 @@ otherTime(NSDate* other)
|
|||
return NSAllocateObject(self, 0, z);
|
||||
}
|
||||
|
||||
+ (id) date
|
||||
+ (instancetype) date
|
||||
{
|
||||
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
|
||||
initWithTimeIntervalSinceReferenceDate: GSPrivateTimeNow()]);
|
||||
|
@ -171,14 +171,14 @@ otherTime(NSDate* other)
|
|||
* specified by the preferences in the user defaults database, allowing
|
||||
* phrases like 'last tuesday'
|
||||
*/
|
||||
+ (id) dateWithNaturalLanguageString: (NSString*)string
|
||||
+ (instancetype) dateWithNaturalLanguageString: (NSString*)string
|
||||
{
|
||||
return [self dateWithNaturalLanguageString: string
|
||||
locale: nil];
|
||||
}
|
||||
|
||||
+ (id) dateWithNaturalLanguageString: (NSString*)string
|
||||
locale: (NSDictionary*)locale
|
||||
+ (instancetype) dateWithNaturalLanguageString: (NSString*)string
|
||||
locale: (NSDictionary*)locale
|
||||
{
|
||||
NSCharacterSet *ws;
|
||||
NSCharacterSet *digits;
|
||||
|
@ -885,35 +885,36 @@ otherTime(NSDate* other)
|
|||
}
|
||||
}
|
||||
|
||||
+ (id) dateWithString: (NSString*)description
|
||||
+ (instancetype) dateWithString: (NSString*)description
|
||||
{
|
||||
return AUTORELEASE([[self alloc] initWithString: description]);
|
||||
}
|
||||
|
||||
+ (id) dateWithTimeInterval: (NSTimeInterval)seconds sinceDate: (NSDate*)date
|
||||
+ (instancetype) dateWithTimeInterval: (NSTimeInterval)seconds
|
||||
sinceDate: (NSDate*)date
|
||||
{
|
||||
return AUTORELEASE([[self alloc] initWithTimeInterval: seconds
|
||||
sinceDate: date]);
|
||||
}
|
||||
|
||||
+ (id) dateWithTimeIntervalSince1970: (NSTimeInterval)seconds
|
||||
+ (instancetype) dateWithTimeIntervalSince1970: (NSTimeInterval)seconds
|
||||
{
|
||||
return AUTORELEASE([[self alloc] initWithTimeIntervalSinceReferenceDate:
|
||||
seconds - NSTimeIntervalSince1970]);
|
||||
}
|
||||
|
||||
+ (id) dateWithTimeIntervalSinceNow: (NSTimeInterval)seconds
|
||||
+ (instancetype) dateWithTimeIntervalSinceNow: (NSTimeInterval)seconds
|
||||
{
|
||||
return AUTORELEASE([[self alloc] initWithTimeIntervalSinceNow: seconds]);
|
||||
}
|
||||
|
||||
+ (id) dateWithTimeIntervalSinceReferenceDate: (NSTimeInterval)seconds
|
||||
+ (instancetype) dateWithTimeIntervalSinceReferenceDate: (NSTimeInterval)seconds
|
||||
{
|
||||
return AUTORELEASE([[self alloc] initWithTimeIntervalSinceReferenceDate:
|
||||
seconds]);
|
||||
}
|
||||
|
||||
+ (id) distantPast
|
||||
+ (instancetype) distantPast
|
||||
{
|
||||
if (_distantPast == nil)
|
||||
{
|
||||
|
@ -922,7 +923,7 @@ otherTime(NSDate* other)
|
|||
return _distantPast;
|
||||
}
|
||||
|
||||
+ (id) distantFuture
|
||||
+ (instancetype) distantFuture
|
||||
{
|
||||
if (_distantFuture == nil)
|
||||
{
|
||||
|
@ -940,7 +941,7 @@ otherTime(NSDate* other)
|
|||
return GSPrivateTimeNow();
|
||||
}
|
||||
|
||||
- (id) addTimeInterval: (NSTimeInterval)seconds
|
||||
- (instancetype) addTimeInterval: (NSTimeInterval)seconds
|
||||
{
|
||||
return [self dateByAddingTimeInterval: seconds];
|
||||
}
|
||||
|
@ -976,7 +977,7 @@ otherTime(NSDate* other)
|
|||
return abstractClass;
|
||||
}
|
||||
|
||||
- (id) dateByAddingTimeInterval: (NSTimeInterval)ti
|
||||
- (instancetype) dateByAddingTimeInterval: (NSTimeInterval)ti
|
||||
{
|
||||
return [[self class] dateWithTimeIntervalSinceReferenceDate:
|
||||
otherTime(self) + ti];
|
||||
|
@ -1069,7 +1070,7 @@ otherTime(NSDate* other)
|
|||
return (NSUInteger)[self timeIntervalSinceReferenceDate];
|
||||
}
|
||||
|
||||
- (id) initWithCoder: (NSCoder*)coder
|
||||
- (instancetype) initWithCoder: (NSCoder*)coder
|
||||
{
|
||||
NSTimeInterval interval;
|
||||
id o;
|
||||
|
@ -1099,12 +1100,12 @@ otherTime(NSDate* other)
|
|||
return o;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
- (instancetype) init
|
||||
{
|
||||
return [self initWithTimeIntervalSinceReferenceDate: GSPrivateTimeNow()];
|
||||
}
|
||||
|
||||
- (id) initWithString: (NSString*)description
|
||||
- (instancetype) initWithString: (NSString*)description
|
||||
{
|
||||
// Easiest to just have NSCalendarDate do the work for us
|
||||
NSCalendarDate *d = [calendarClass alloc];
|
||||
|
@ -1123,8 +1124,8 @@ otherTime(NSDate* other)
|
|||
}
|
||||
}
|
||||
|
||||
- (id) initWithTimeInterval: (NSTimeInterval)secsToBeAdded
|
||||
sinceDate: (NSDate*)anotherDate
|
||||
- (instancetype) initWithTimeInterval: (NSTimeInterval)secsToBeAdded
|
||||
sinceDate: (NSDate*)anotherDate
|
||||
{
|
||||
if (anotherDate == nil)
|
||||
{
|
||||
|
@ -1137,20 +1138,20 @@ otherTime(NSDate* other)
|
|||
otherTime(anotherDate) + secsToBeAdded];
|
||||
}
|
||||
|
||||
- (id) initWithTimeIntervalSince1970: (NSTimeInterval)seconds
|
||||
- (instancetype) initWithTimeIntervalSince1970: (NSTimeInterval)seconds
|
||||
{
|
||||
return [self initWithTimeIntervalSinceReferenceDate:
|
||||
seconds - NSTimeIntervalSince1970];
|
||||
}
|
||||
|
||||
- (id) initWithTimeIntervalSinceNow: (NSTimeInterval)secsToBeAdded
|
||||
- (instancetype) initWithTimeIntervalSinceNow: (NSTimeInterval)secsToBeAdded
|
||||
{
|
||||
// Get the current time, add the secs and init thyself
|
||||
return [self initWithTimeIntervalSinceReferenceDate:
|
||||
GSPrivateTimeNow() + secsToBeAdded];
|
||||
}
|
||||
|
||||
- (id) initWithTimeIntervalSinceReferenceDate: (NSTimeInterval)secs
|
||||
- (instancetype) initWithTimeIntervalSinceReferenceDate: (NSTimeInterval)secs
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return self;
|
||||
|
|
|
@ -178,7 +178,7 @@ static SEL appSel;
|
|||
FOR_IN(id, key, enumerator)
|
||||
obj = (*objectForKey)(self, objectForKeySelector, key);
|
||||
GS_DISPATCH_SUBMIT_BLOCK(enumQueueGroup, enumQueue,
|
||||
if (shouldStop){return;};, return;, aBlock, key, obj, &shouldStop);
|
||||
if (shouldStop == NO) {, }, aBlock, key, obj, &shouldStop);
|
||||
if (YES == shouldStop)
|
||||
{
|
||||
break;
|
||||
|
@ -1054,28 +1054,30 @@ compareIt(id o1, id o2, void* context)
|
|||
FOR_IN(id, key, enumerator)
|
||||
obj = (*objectForKey)(self, objectForKeySelector, key);
|
||||
#if (__has_feature(blocks) && (GS_USE_LIBDISPATCH == 1))
|
||||
dispatch_group_async(enumQueueGroup, enumQueue, ^(void){
|
||||
if (shouldStop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (aPredicate(key, obj, &shouldStop))
|
||||
{
|
||||
[setLock lock];
|
||||
addObject(buildSet, addObjectSelector, key);
|
||||
[setLock unlock];
|
||||
}
|
||||
});
|
||||
#else
|
||||
if (enumQueue != NULL)
|
||||
{
|
||||
dispatch_group_async(enumQueueGroup, enumQueue, ^(void){
|
||||
if (shouldStop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (aPredicate(key, obj, &shouldStop))
|
||||
{
|
||||
[setLock lock];
|
||||
addObject(buildSet, addObjectSelector, key);
|
||||
[setLock unlock];
|
||||
}
|
||||
});
|
||||
}
|
||||
else // call block directly
|
||||
#endif
|
||||
if (CALL_BLOCK(aPredicate, key, obj, &shouldStop))
|
||||
{
|
||||
addObject(buildSet, addObjectSelector, key);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (YES == shouldStop)
|
||||
if (shouldStop)
|
||||
{
|
||||
break;
|
||||
break;
|
||||
}
|
||||
END_FOR_IN(enumerator)
|
||||
GS_DISPATCH_TEARDOWN_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts)
|
||||
|
|
|
@ -917,7 +917,7 @@ static NSUInteger posForIndex(GSIArray array, NSUInteger index)
|
|||
if ((innerI <= lastInRange) && (innerI >= range.location))
|
||||
{
|
||||
GS_DISPATCH_SUBMIT_BLOCK(enumQueueGroup, enumQueue,
|
||||
if (shouldStop) {return;}, return;,
|
||||
if (shouldStop == NO) {, },
|
||||
aBlock, innerI, &shouldStop);
|
||||
}
|
||||
if (shouldStop)
|
||||
|
|
|
@ -657,7 +657,7 @@ static SEL remSel;
|
|||
{
|
||||
GS_DISPATCH_CREATE_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts)
|
||||
FOR_IN (id, obj, enumerator)
|
||||
GS_DISPATCH_SUBMIT_BLOCK(enumQueueGroup, enumQueue, if (YES == shouldStop) {return;}, return, aBlock, obj, count, &shouldStop);
|
||||
GS_DISPATCH_SUBMIT_BLOCK(enumQueueGroup, enumQueue, if (shouldStop == NO) {, }, aBlock, obj, count, &shouldStop);
|
||||
if (isReverse)
|
||||
{
|
||||
count--;
|
||||
|
@ -865,33 +865,35 @@ static SEL remSel;
|
|||
GS_DISPATCH_CREATE_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts)
|
||||
FOR_IN (id, obj, enumerator)
|
||||
# if __has_feature(blocks) && (GS_USE_LIBDISPATCH == 1)
|
||||
dispatch_group_async(enumQueueGroup, enumQueue, ^(void){
|
||||
if (shouldStop)
|
||||
if (enumQueue != NULL)
|
||||
{
|
||||
return;
|
||||
dispatch_group_async(enumQueueGroup, enumQueue, ^(void){
|
||||
if (shouldStop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (predicate(obj, count, &shouldStop))
|
||||
{
|
||||
// FIXME: atomic operation on the shouldStop variable would be nicer,
|
||||
// but we don't expose the GSAtomic* primitives anywhere.
|
||||
[indexLock lock];
|
||||
index = count;
|
||||
// Cancel all other predicate evaluations:
|
||||
shouldStop = YES;
|
||||
[indexLock unlock];
|
||||
}
|
||||
});
|
||||
}
|
||||
if (predicate(obj, count, &shouldStop))
|
||||
{
|
||||
// FIXME: atomic operation on the shouldStop variable would be nicer,
|
||||
// but we don't expose the GSAtomic* primitives anywhere.
|
||||
[indexLock lock];
|
||||
index = count;
|
||||
// Cancel all other predicate evaluations:
|
||||
shouldStop = YES;
|
||||
[indexLock unlock];
|
||||
}
|
||||
});
|
||||
# else
|
||||
else // call block directly
|
||||
# endif
|
||||
if (CALL_BLOCK(predicate, obj, count, &shouldStop))
|
||||
{
|
||||
|
||||
index = count;
|
||||
shouldStop = YES;
|
||||
index = count;
|
||||
shouldStop = YES;
|
||||
}
|
||||
# endif
|
||||
if (shouldStop)
|
||||
{
|
||||
break;
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
END_FOR_IN(enumerator)
|
||||
|
@ -940,30 +942,32 @@ static SEL remSel;
|
|||
GS_DISPATCH_CREATE_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts)
|
||||
FOR_IN (id, obj, enumerator)
|
||||
# if __has_feature(blocks) && (GS_USE_LIBDISPATCH == 1)
|
||||
|
||||
dispatch_group_async(enumQueueGroup, enumQueue, ^(void){
|
||||
if (shouldStop)
|
||||
if (enumQueue != NULL)
|
||||
{
|
||||
return;
|
||||
dispatch_group_async(enumQueueGroup, enumQueue, ^(void){
|
||||
if (shouldStop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (predicate(obj, count, &shouldStop))
|
||||
{
|
||||
[setLock lock];
|
||||
[set addIndex: count];
|
||||
[setLock unlock];
|
||||
}
|
||||
});
|
||||
}
|
||||
if (predicate(obj, count, &shouldStop))
|
||||
{
|
||||
[setLock lock];
|
||||
[set addIndex: count];
|
||||
[setLock unlock];
|
||||
}
|
||||
});
|
||||
# else
|
||||
else // call block directly
|
||||
# endif
|
||||
if (CALL_BLOCK(predicate, obj, count, &shouldStop))
|
||||
{
|
||||
/* TODO: It would be more efficient to collect an NSRange and only
|
||||
* pass it to the index set when CALL_BLOCK returned NO. */
|
||||
[set addIndex: count];
|
||||
/* TODO: It would be more efficient to collect an NSRange and only
|
||||
* pass it to the index set when CALL_BLOCK returned NO. */
|
||||
[set addIndex: count];
|
||||
}
|
||||
# endif
|
||||
if (shouldStop)
|
||||
{
|
||||
break;
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
END_FOR_IN(enumerator)
|
||||
|
|
|
@ -907,7 +907,7 @@ static Class NSMutableSet_concrete_class;
|
|||
GS_DISPATCH_CREATE_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts)
|
||||
FOR_IN (id, obj, enumerator)
|
||||
{
|
||||
GS_DISPATCH_SUBMIT_BLOCK(enumQueueGroup,enumQueue, if (shouldStop) {return;}, return;, aBlock, obj, &shouldStop);
|
||||
GS_DISPATCH_SUBMIT_BLOCK(enumQueueGroup,enumQueue, if (shouldStop == NO) {, }, aBlock, obj, &shouldStop);
|
||||
if (shouldStop)
|
||||
{
|
||||
break;
|
||||
|
|
1527
Source/NSUnit.m
1527
Source/NSUnit.m
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue