mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-26 02:01:03 +00:00
Fix spelling error in method name.. Implement more methods.
This commit is contained in:
parent
d611743bd2
commit
b248ac8769
2 changed files with 149 additions and 10 deletions
|
@ -115,7 +115,7 @@ extern "C" {
|
||||||
passingTest:(GSPredicateBlock)predicate;
|
passingTest:(GSPredicateBlock)predicate;
|
||||||
|
|
||||||
- (NSIndexSet *)indexesOfObjectsPassingTest:(GSPredicateBlock)predicate;
|
- (NSIndexSet *)indexesOfObjectsPassingTest:(GSPredicateBlock)predicate;
|
||||||
- (NSIndexSet *) indexesOfObjectWithOptions:(NSEnumerationOptions)opts
|
- (NSIndexSet *) indexesOfObjectsWithOptions:(NSEnumerationOptions)opts
|
||||||
passingTest:(GSPredicateBlock)predicate;
|
passingTest:(GSPredicateBlock)predicate;
|
||||||
- (GS_GENERIC_CLASS(NSEnumerator, ElementT)*) objectEnumerator;
|
- (GS_GENERIC_CLASS(NSEnumerator, ElementT)*) objectEnumerator;
|
||||||
- (GS_GENERIC_CLASS(NSEnumerator, ElementT)*) reverseObjectEnumerator;
|
- (GS_GENERIC_CLASS(NSEnumerator, ElementT)*) reverseObjectEnumerator;
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#import "Foundation/NSValue.h"
|
#import "Foundation/NSValue.h"
|
||||||
#import "Foundation/NSException.h"
|
#import "Foundation/NSException.h"
|
||||||
#import "Foundation/NSPredicate.h"
|
#import "Foundation/NSPredicate.h"
|
||||||
|
#import "Foundation/NSLock.h"
|
||||||
|
|
||||||
#import <GNUstepBase/GSBlocks.h>
|
#import <GNUstepBase/GSBlocks.h>
|
||||||
#import "Foundation/NSKeyedArchiver.h"
|
#import "Foundation/NSKeyedArchiver.h"
|
||||||
#import "GSPrivate.h"
|
#import "GSPrivate.h"
|
||||||
|
@ -465,6 +467,8 @@ static SEL rlSel;
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if(self != nil)
|
if(self != nil)
|
||||||
{
|
{
|
||||||
|
// Need proper implementation to happen in subclass since it will define how data
|
||||||
|
// is stored.
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -486,6 +490,10 @@ static SEL rlSel;
|
||||||
count:(NSUInteger)count
|
count:(NSUInteger)count
|
||||||
{
|
{
|
||||||
self = [self init];
|
self = [self init];
|
||||||
|
if(self != nil)
|
||||||
|
{
|
||||||
|
// Need proper implementation in subclass since that is where data will be stored.
|
||||||
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,7 +742,85 @@ static SEL rlSel;
|
||||||
options: (NSBinarySearchingOptions)options
|
options: (NSBinarySearchingOptions)options
|
||||||
usingComparator: (NSComparator)comparator
|
usingComparator: (NSComparator)comparator
|
||||||
{
|
{
|
||||||
return 0;
|
if (range.length == 0)
|
||||||
|
{
|
||||||
|
return options & NSBinarySearchingInsertionIndex
|
||||||
|
? range.location : NSNotFound;
|
||||||
|
}
|
||||||
|
if (range.length == 1)
|
||||||
|
{
|
||||||
|
switch (CALL_BLOCK(comparator, key, [self objectAtIndex: range.location]))
|
||||||
|
{
|
||||||
|
case NSOrderedSame:
|
||||||
|
return range.location;
|
||||||
|
case NSOrderedAscending:
|
||||||
|
return options & NSBinarySearchingInsertionIndex
|
||||||
|
? range.location : NSNotFound;
|
||||||
|
case NSOrderedDescending:
|
||||||
|
return options & NSBinarySearchingInsertionIndex
|
||||||
|
? (range.location + 1) : NSNotFound;
|
||||||
|
default:
|
||||||
|
// Shouldn't happen
|
||||||
|
return NSNotFound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSUInteger index = NSNotFound;
|
||||||
|
NSUInteger count = [self count];
|
||||||
|
NSRange range = NSMakeRange(0, [self count]);
|
||||||
|
GS_BEGINIDBUF(objects, count);
|
||||||
|
|
||||||
|
[self getObjects: objects range: range];
|
||||||
|
// We use the timsort galloping to find the insertion index:
|
||||||
|
if (options & NSBinarySearchingLastEqual)
|
||||||
|
{
|
||||||
|
index = GSRightInsertionPointForKeyInSortedRange(key,
|
||||||
|
objects, range, comparator);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Left insertion is our default
|
||||||
|
index = GSLeftInsertionPointForKeyInSortedRange(key,
|
||||||
|
objects, range, comparator);
|
||||||
|
}
|
||||||
|
GS_ENDIDBUF()
|
||||||
|
|
||||||
|
// If we were looking for the insertion point, we are done here
|
||||||
|
if (options & NSBinarySearchingInsertionIndex)
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, we need need another equality check in order to
|
||||||
|
* know whether we need return NSNotFound.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (options & NSBinarySearchingLastEqual)
|
||||||
|
{
|
||||||
|
/* For search from the right, the equal object would be
|
||||||
|
* the one before the index, but only if it's not at the
|
||||||
|
* very beginning of the range (though that might not
|
||||||
|
* actually be possible, it's better to check nonetheless).
|
||||||
|
*/
|
||||||
|
if (index > range.location)
|
||||||
|
{
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (index >= NSMaxRange(range))
|
||||||
|
{
|
||||||
|
return NSNotFound;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* For a search from the left, we'd have the correct index anyways. Check
|
||||||
|
* whether it's equal to the key and return NSNotFound otherwise
|
||||||
|
*/
|
||||||
|
return (NSOrderedSame == CALL_BLOCK(comparator,
|
||||||
|
key, [self objectAtIndex: index]) ? index : NSNotFound);
|
||||||
|
}
|
||||||
|
// Never reached
|
||||||
|
return NSNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSUInteger) indexOfObjectAtIndexes:(NSIndexSet *)indexSet
|
- (NSUInteger) indexOfObjectAtIndexes:(NSIndexSet *)indexSet
|
||||||
|
@ -742,13 +828,13 @@ static SEL rlSel;
|
||||||
passingTest:(GSPredicateBlock)predicate
|
passingTest:(GSPredicateBlock)predicate
|
||||||
{
|
{
|
||||||
return [[self objectsAtIndexes: indexSet]
|
return [[self objectsAtIndexes: indexSet]
|
||||||
indexesOfObjectsWithOptions: opts
|
indexOfObjectWithOptions: 0
|
||||||
passingTest: predicate];
|
passingTest: predicate];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSUInteger) indexOfObjectPassingTest:(GSPredicateBlock)predicate
|
- (NSUInteger) indexOfObjectPassingTest:(GSPredicateBlock)predicate
|
||||||
{
|
{
|
||||||
return [self indexesOfObjectsWithOptions: 0 passingTest: predicate];
|
return [self indexOfObjectWithOptions: 0 passingTest: predicate];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSUInteger) indexOfObjectWithOptions:(NSEnumerationOptions)opts
|
- (NSUInteger) indexOfObjectWithOptions:(NSEnumerationOptions)opts
|
||||||
|
@ -816,18 +902,71 @@ static SEL rlSel;
|
||||||
options:(NSEnumerationOptions)opts
|
options:(NSEnumerationOptions)opts
|
||||||
passingTest:(GSPredicateBlock)predicate
|
passingTest:(GSPredicateBlock)predicate
|
||||||
{
|
{
|
||||||
return nil;
|
return [[self objectsAtIndexes: indexSet]
|
||||||
|
indexesOfObjectsWithOptions: opts
|
||||||
|
passingTest: predicate];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSIndexSet *)indexesOfObjectsPassingTest:(GSPredicateBlock)predicate
|
- (NSIndexSet *) indexesOfObjectsPassingTest:(GSPredicateBlock)predicate
|
||||||
{
|
{
|
||||||
return nil;
|
return [self indexesOfObjectsWithOptions: 0 passingTest: predicate];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSIndexSet *) indexesOfObjectWithOptions:(NSEnumerationOptions)opts
|
- (NSIndexSet *) indexesOfObjectsWithOptions:(NSEnumerationOptions)opts
|
||||||
passingTest:(GSPredicateBlock)predicate
|
passingTest:(GSPredicateBlock)predicate
|
||||||
{
|
{
|
||||||
return nil;
|
/* TODO: Concurrency. */
|
||||||
|
NSMutableIndexSet *set = [NSMutableIndexSet indexSet];
|
||||||
|
BLOCK_SCOPE BOOL shouldStop = NO;
|
||||||
|
id<NSFastEnumeration> enumerator = self;
|
||||||
|
NSUInteger count = 0;
|
||||||
|
BLOCK_SCOPE NSLock *setLock = nil;
|
||||||
|
|
||||||
|
/* If we are enumerating in reverse, use the reverse enumerator for fast
|
||||||
|
* enumeration. */
|
||||||
|
if (opts & NSEnumerationReverse)
|
||||||
|
{
|
||||||
|
enumerator = [self reverseObjectEnumerator];
|
||||||
|
}
|
||||||
|
if (opts & NSEnumerationConcurrent)
|
||||||
|
{
|
||||||
|
setLock = [NSLock new];
|
||||||
|
}
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (predicate(obj, count, &shouldStop))
|
||||||
|
{
|
||||||
|
[setLock lock];
|
||||||
|
[set addIndex: count];
|
||||||
|
[setLock unlock];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
# else
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
if (shouldStop)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
END_FOR_IN(enumerator)
|
||||||
|
GS_DISPATCH_TEARDOWN_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts);
|
||||||
|
}
|
||||||
|
RELEASE(setLock);
|
||||||
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSEnumerator *) objectEnumerator
|
- (NSEnumerator *) objectEnumerator
|
||||||
|
|
Loading…
Reference in a new issue