mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 00:30:53 +00:00
Optimisation
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@4894 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
24886c5b3a
commit
6a01c2a85d
3 changed files with 501 additions and 226 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Tue Sep 14 20:44:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
|
* Source/NSArray.m: Huge amounts of optimisation.
|
||||||
|
Memory leak fixed in ([-initWithFile:]).
|
||||||
|
* Source/NSGArray.m: Optimisations of less-used methods, including
|
||||||
|
implementation of fast enumerators.
|
||||||
|
|
||||||
Tue Sep 14 15:11:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
Tue Sep 14 15:11:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
* Source/NSTimer.m: minor optimisations
|
* Source/NSTimer.m: minor optimisations
|
||||||
|
|
545
Source/NSArray.m
545
Source/NSArray.m
|
@ -50,9 +50,19 @@
|
||||||
@interface NSMutableArrayNonCore : NSMutableArray
|
@interface NSMutableArrayNonCore : NSMutableArray
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
static Class NSArray_abstract_class;
|
||||||
static Class NSArray_concrete_class;
|
static Class NSArray_concrete_class;
|
||||||
|
static Class NSMutableArray_abstract_class;
|
||||||
static Class NSMutableArray_concrete_class;
|
static Class NSMutableArray_concrete_class;
|
||||||
|
|
||||||
|
static SEL addSel = @selector(addObject:);
|
||||||
|
static SEL appSel = @selector(appendString:);
|
||||||
|
static SEL countSel = @selector(count);
|
||||||
|
static SEL eqSel = @selector(isEqual:);
|
||||||
|
static SEL oaiSel = @selector(objectAtIndex:);
|
||||||
|
static SEL remSel = @selector(removeObjectAtIndex:);
|
||||||
|
static SEL rlSel = @selector(removeLastObject);
|
||||||
|
|
||||||
|
|
||||||
@implementation NSArray
|
@implementation NSArray
|
||||||
|
|
||||||
|
@ -60,6 +70,8 @@ static Class NSMutableArray_concrete_class;
|
||||||
{
|
{
|
||||||
if (self == [NSArray class])
|
if (self == [NSArray class])
|
||||||
{
|
{
|
||||||
|
NSArray_abstract_class = [NSArray class];
|
||||||
|
NSMutableArray_abstract_class = [NSMutableArray class];
|
||||||
NSArray_concrete_class = [NSGArray class];
|
NSArray_concrete_class = [NSGArray class];
|
||||||
NSMutableArray_concrete_class = [NSGMutableArray class];
|
NSMutableArray_concrete_class = [NSGMutableArray class];
|
||||||
behavior_class_add_class (self, [NSArrayNonCore class]);
|
behavior_class_add_class (self, [NSArrayNonCore class]);
|
||||||
|
@ -86,31 +98,31 @@ static Class NSMutableArray_concrete_class;
|
||||||
return NSMutableArray_concrete_class;
|
return NSMutableArray_concrete_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ allocWithZone: (NSZone*)z
|
+ (id) allocWithZone: (NSZone*)z
|
||||||
{
|
{
|
||||||
if ([self class] == [NSArray class])
|
if ([self class] == NSArray_abstract_class)
|
||||||
return NSAllocateObject ([self _concreteClass], 0, z);
|
return NSAllocateObject(NSArray_concrete_class, 0, z);
|
||||||
return [super allocWithZone: z];
|
return [super allocWithZone: z];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ array
|
+ (id) array
|
||||||
{
|
{
|
||||||
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()] init]);
|
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()] init]);
|
||||||
}
|
}
|
||||||
|
|
||||||
+ arrayWithArray: (NSArray*)array
|
+ (id) arrayWithArray: (NSArray*)array
|
||||||
{
|
{
|
||||||
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
|
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
|
||||||
initWithArray: array]);
|
initWithArray: array]);
|
||||||
}
|
}
|
||||||
|
|
||||||
+ arrayWithContentsOfFile: (NSString*)file
|
+ (id) arrayWithContentsOfFile: (NSString*)file
|
||||||
{
|
{
|
||||||
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
|
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
|
||||||
initWithContentsOfFile: file]);
|
initWithContentsOfFile: file]);
|
||||||
}
|
}
|
||||||
|
|
||||||
+ arrayWithObject: anObject
|
+ (id) arrayWithObject: anObject
|
||||||
{
|
{
|
||||||
if (anObject == nil)
|
if (anObject == nil)
|
||||||
[NSException raise: NSInvalidArgumentException
|
[NSException raise: NSInvalidArgumentException
|
||||||
|
@ -120,7 +132,7 @@ static Class NSMutableArray_concrete_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the designated initializer for NSArray. */
|
/* This is the designated initializer for NSArray. */
|
||||||
- initWithObjects: (id*)objects count: (unsigned)count
|
- (id) initWithObjects: (id*)objects count: (unsigned)count
|
||||||
{
|
{
|
||||||
[self subclassResponsibility: _cmd];
|
[self subclassResponsibility: _cmd];
|
||||||
return nil;
|
return nil;
|
||||||
|
@ -132,7 +144,7 @@ static Class NSMutableArray_concrete_class;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
- objectAtIndex: (unsigned)index
|
- (id) objectAtIndex: (unsigned)index
|
||||||
{
|
{
|
||||||
[self subclassResponsibility: _cmd];
|
[self subclassResponsibility: _cmd];
|
||||||
return nil;
|
return nil;
|
||||||
|
@ -142,55 +154,54 @@ static Class NSMutableArray_concrete_class;
|
||||||
|
|
||||||
- (void) encodeWithCoder: (NSCoder*)aCoder
|
- (void) encodeWithCoder: (NSCoder*)aCoder
|
||||||
{
|
{
|
||||||
unsigned count = [self count];
|
unsigned count = [self count];
|
||||||
|
|
||||||
[aCoder encodeValueOfObjCType: @encode(unsigned)
|
[aCoder encodeValueOfObjCType: @encode(unsigned)
|
||||||
at: &count];
|
at: &count];
|
||||||
|
|
||||||
if (count > 0) {
|
if (count > 0)
|
||||||
unsigned i;
|
{
|
||||||
|
id a[count];
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
[self getObjects: a];
|
||||||
[aCoder encodeObject: [self objectAtIndex: i]];
|
[aCoder encodeArrayOfObjCType: @encode(id)
|
||||||
}
|
count: count
|
||||||
|
at: a];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithCoder: (NSCoder*)aCoder
|
- (id) initWithCoder: (NSCoder*)aCoder
|
||||||
{
|
{
|
||||||
unsigned count;
|
unsigned count;
|
||||||
|
|
||||||
if ([aCoder systemVersion] == 0) {
|
[aCoder decodeValueOfObjCType: @encode(unsigned)
|
||||||
unsigned dummy;
|
at: &count];
|
||||||
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &dummy];
|
if (count > 0)
|
||||||
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &dummy];
|
{
|
||||||
}
|
id contents[count];
|
||||||
[aCoder decodeValueOfObjCType: @encode(unsigned) at: &count];
|
|
||||||
if (count > 0) {
|
|
||||||
id contents[count];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
[aCoder decodeArrayOfObjCType: @encode(id)
|
||||||
contents[i] = [aCoder decodeObject];
|
count: count
|
||||||
}
|
at: contents];
|
||||||
return [self initWithObjects: contents count: count];
|
return [self initWithObjects: contents count: count];
|
||||||
}
|
}
|
||||||
|
else
|
||||||
return [self initWithObjects: 0 count: 0];
|
return [self initWithObjects: 0 count: 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The NSCopying Protocol */
|
/* The NSCopying Protocol */
|
||||||
|
|
||||||
- copyWithZone: (NSZone*)zone
|
- (id) copyWithZone: (NSZone*)zone
|
||||||
{
|
{
|
||||||
return RETAIN(self);
|
return RETAIN(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The NSMutableCopying Protocol */
|
/* The NSMutableCopying Protocol */
|
||||||
|
|
||||||
- mutableCopyWithZone: (NSZone*)zone
|
- (id) mutableCopyWithZone: (NSZone*)zone
|
||||||
{
|
{
|
||||||
return [[[[self class] _mutableConcreteClass] allocWithZone: zone]
|
return [[NSMutableArray_concrete_class allocWithZone: zone]
|
||||||
initWithArray: self];
|
initWithArray: self];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -198,20 +209,26 @@ static Class NSMutableArray_concrete_class;
|
||||||
|
|
||||||
@implementation NSArrayNonCore
|
@implementation NSArrayNonCore
|
||||||
|
|
||||||
- (NSArray*) arrayByAddingObject: anObject
|
- (NSArray*) arrayByAddingObject: (id)anObject
|
||||||
{
|
{
|
||||||
id na;
|
id na;
|
||||||
unsigned c;
|
unsigned c = [self count];
|
||||||
|
|
||||||
c = [self count];
|
if (anObject == nil)
|
||||||
{
|
[NSException raise: NSInvalidArgumentException
|
||||||
id objects[c+1];
|
format: @"Attempt to add nil to an array"];
|
||||||
|
if (c == 0)
|
||||||
|
na = [[NSArray_concrete_class allocWithZone: NSDefaultMallocZone()]
|
||||||
|
initWithObjects: &anObject count: 1];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
id objects[c+1];
|
||||||
|
|
||||||
[self getObjects: objects];
|
[self getObjects: objects];
|
||||||
objects[c] = anObject;
|
objects[c] = anObject;
|
||||||
na = [[NSArray allocWithZone: NSDefaultMallocZone()]
|
na = [[NSArray_concrete_class allocWithZone: NSDefaultMallocZone()]
|
||||||
initWithObjects: objects count: c+1];
|
initWithObjects: objects count: c+1];
|
||||||
}
|
}
|
||||||
return AUTORELEASE(na);
|
return AUTORELEASE(na);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,12 +244,12 @@ static Class NSMutableArray_concrete_class;
|
||||||
|
|
||||||
[self getObjects: objects];
|
[self getObjects: objects];
|
||||||
[anotherArray getObjects: &objects[c]];
|
[anotherArray getObjects: &objects[c]];
|
||||||
na = [NSArray arrayWithObjects: objects count: c+l];
|
na = [NSArray_abstract_class arrayWithObjects: objects count: c+l];
|
||||||
}
|
}
|
||||||
return na;
|
return na;
|
||||||
}
|
}
|
||||||
|
|
||||||
- initWithObjects: firstObject rest: (va_list) ap
|
- (id) initWithObjects: firstObject rest: (va_list) ap
|
||||||
{
|
{
|
||||||
register unsigned i;
|
register unsigned i;
|
||||||
register unsigned curSize;
|
register unsigned curSize;
|
||||||
|
@ -278,7 +295,7 @@ static Class NSMutableArray_concrete_class;
|
||||||
return( self );
|
return( self );
|
||||||
}
|
}
|
||||||
|
|
||||||
- initWithObjects: firstObject, ...
|
- (id) initWithObjects: firstObject, ...
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, firstObject);
|
va_start(ap, firstObject);
|
||||||
|
@ -287,7 +304,7 @@ static Class NSMutableArray_concrete_class;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- initWithContentsOfFile: (NSString*)file
|
- (id) initWithContentsOfFile: (NSString*)file
|
||||||
{
|
{
|
||||||
NSString *myString;
|
NSString *myString;
|
||||||
|
|
||||||
|
@ -295,7 +312,7 @@ static Class NSMutableArray_concrete_class;
|
||||||
initWithContentsOfFile: file];
|
initWithContentsOfFile: file];
|
||||||
if (myString)
|
if (myString)
|
||||||
{
|
{
|
||||||
id result = [myString propertyList];
|
id result;
|
||||||
|
|
||||||
NS_DURING
|
NS_DURING
|
||||||
{
|
{
|
||||||
|
@ -307,7 +324,7 @@ static Class NSMutableArray_concrete_class;
|
||||||
}
|
}
|
||||||
NS_ENDHANDLER
|
NS_ENDHANDLER
|
||||||
RELEASE(myString);
|
RELEASE(myString);
|
||||||
if ([result isKindOfClass: [NSArray class]])
|
if ([result isKindOfClass: NSArray_abstract_class])
|
||||||
{
|
{
|
||||||
[self initWithArray: result];
|
[self initWithArray: result];
|
||||||
return self;
|
return self;
|
||||||
|
@ -318,7 +335,7 @@ static Class NSMutableArray_concrete_class;
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ arrayWithObjects: firstObject, ...
|
+ (id) arrayWithObjects: firstObject, ...
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, firstObject);
|
va_start(ap, firstObject);
|
||||||
|
@ -328,13 +345,13 @@ static Class NSMutableArray_concrete_class;
|
||||||
return AUTORELEASE(self);
|
return AUTORELEASE(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
+ arrayWithObjects: (id*)objects count: (unsigned)count
|
+ (id) arrayWithObjects: (id*)objects count: (unsigned)count
|
||||||
{
|
{
|
||||||
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
|
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
|
||||||
initWithObjects: objects count: count]);
|
initWithObjects: objects count: count]);
|
||||||
}
|
}
|
||||||
|
|
||||||
- initWithArray: (NSArray*)array
|
- (id) initWithArray: (NSArray*)array
|
||||||
{
|
{
|
||||||
unsigned c;
|
unsigned c;
|
||||||
|
|
||||||
|
@ -351,19 +368,21 @@ static Class NSMutableArray_concrete_class;
|
||||||
- (void) getObjects: (id*)aBuffer
|
- (void) getObjects: (id*)aBuffer
|
||||||
{
|
{
|
||||||
unsigned i, c = [self count];
|
unsigned i, c = [self count];
|
||||||
|
IMP get = [self methodForSelector: oaiSel];
|
||||||
|
|
||||||
for (i = 0; i < c; i++)
|
for (i = 0; i < c; i++)
|
||||||
aBuffer[i] = [self objectAtIndex: i];
|
aBuffer[i] = (*get)(self, oaiSel, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) getObjects: (id*)aBuffer range: (NSRange)aRange
|
- (void) getObjects: (id*)aBuffer range: (NSRange)aRange
|
||||||
{
|
{
|
||||||
unsigned i, j = 0, c = [self count], e = aRange.location + aRange.length;
|
unsigned i, j = 0, c = [self count], e = aRange.location + aRange.length;
|
||||||
|
IMP get = [self methodForSelector: oaiSel];
|
||||||
|
|
||||||
GS_RANGE_CHECK(aRange, c);
|
GS_RANGE_CHECK(aRange, c);
|
||||||
|
|
||||||
for (i = aRange.location; i < e; i++)
|
for (i = aRange.location; i < e; i++)
|
||||||
aBuffer[j++] = [self objectAtIndex: i];
|
aBuffer[j++] = (*get)(self, oaiSel, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (unsigned) hash
|
- (unsigned) hash
|
||||||
|
@ -373,46 +392,65 @@ static Class NSMutableArray_concrete_class;
|
||||||
|
|
||||||
- (unsigned) indexOfObjectIdenticalTo: anObject
|
- (unsigned) indexOfObjectIdenticalTo: anObject
|
||||||
{
|
{
|
||||||
unsigned i, c = [self count];
|
unsigned c = [self count];
|
||||||
for (i = 0; i < c; i++)
|
|
||||||
if (anObject == [self objectAtIndex: i])
|
if (c > 0)
|
||||||
return i;
|
{
|
||||||
|
IMP get = [self methodForSelector: oaiSel];
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < c; i++)
|
||||||
|
if (anObject == (*get)(self, oaiSel, i))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
return NSNotFound;
|
return NSNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (unsigned) indexOfObjectIdenticalTo: anObject inRange: (NSRange)aRange
|
- (unsigned) indexOfObjectIdenticalTo: anObject inRange: (NSRange)aRange
|
||||||
{
|
{
|
||||||
unsigned i, e = aRange.location + aRange.length, c = [self count];
|
unsigned i, e = aRange.location + aRange.length, c = [self count];
|
||||||
|
IMP get = [self methodForSelector: oaiSel];
|
||||||
|
|
||||||
GS_RANGE_CHECK(aRange, c);
|
GS_RANGE_CHECK(aRange, c);
|
||||||
|
|
||||||
for (i = aRange.location; i < e; i++)
|
for (i = aRange.location; i < e; i++)
|
||||||
if (anObject == [self objectAtIndex: i])
|
if (anObject == (*get)(self, oaiSel, i))
|
||||||
return i;
|
return i;
|
||||||
return NSNotFound;
|
return NSNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inefficient, should be overridden. */
|
/* Inefficient, should be overridden. */
|
||||||
- (unsigned) indexOfObject: anObject
|
- (unsigned) indexOfObject: (id)anObject
|
||||||
{
|
{
|
||||||
unsigned i, c = [self count];
|
unsigned c = [self count];
|
||||||
for (i = 0; i < c; i++)
|
|
||||||
if ([[self objectAtIndex: i] isEqual: anObject])
|
if (c > 0 && anObject != nil)
|
||||||
return i;
|
{
|
||||||
|
unsigned i;
|
||||||
|
IMP get = [self methodForSelector: oaiSel];
|
||||||
|
BOOL (*eq)(id, SEL, id)
|
||||||
|
= (BOOL (*)(id, SEL, id))[anObject methodForSelector: eqSel];
|
||||||
|
|
||||||
|
for (i = 0; i < c; i++)
|
||||||
|
if ((*eq)(anObject, eqSel, (*get)(self, oaiSel, i)) == YES)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
return NSNotFound;
|
return NSNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inefficient, should be overridden. */
|
/* Inefficient, should be overridden. */
|
||||||
- (unsigned) indexOfObject: anObject inRange: (NSRange)aRange
|
- (unsigned) indexOfObject: (id)anObject inRange: (NSRange)aRange
|
||||||
{
|
{
|
||||||
unsigned i, e = aRange.location + aRange.length, c = [self count];
|
unsigned i, e = aRange.location + aRange.length, c = [self count];
|
||||||
|
IMP get = [self methodForSelector: oaiSel];
|
||||||
|
BOOL (*eq)(id, SEL, id)
|
||||||
|
= (BOOL (*)(id, SEL, id))[anObject methodForSelector: eqSel];
|
||||||
|
|
||||||
GS_RANGE_CHECK(aRange, c);
|
GS_RANGE_CHECK(aRange, c);
|
||||||
|
|
||||||
for (i = aRange.location; i < e; i++)
|
for (i = aRange.location; i < e; i++)
|
||||||
{
|
{
|
||||||
id o = [self objectAtIndex: i];
|
if ((*eq)(anObject, eqSel, (*get)(self, oaiSel, i)) == YES)
|
||||||
if (anObject == o || [o isEqual: anObject])
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return NSNotFound;
|
return NSNotFound;
|
||||||
|
@ -423,26 +461,37 @@ static Class NSMutableArray_concrete_class;
|
||||||
return ([self indexOfObject: anObject] != NSNotFound);
|
return ([self indexOfObject: anObject] != NSNotFound);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) isEqual: anObject
|
- (BOOL) isEqual: (id)anObject
|
||||||
{
|
{
|
||||||
if ([anObject isKindOf: [NSArray class]])
|
if (self == anObject)
|
||||||
|
return YES;
|
||||||
|
if ([anObject isKindOfClass: NSArray_abstract_class])
|
||||||
return [self isEqualToArray: anObject];
|
return [self isEqualToArray: anObject];
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) isEqualToArray: (NSArray*)otherArray
|
- (BOOL) isEqualToArray: (NSArray*)otherArray
|
||||||
{
|
{
|
||||||
unsigned i, c = [self count];
|
unsigned i, c;
|
||||||
|
|
||||||
|
if (self == (id)otherArray)
|
||||||
|
return YES;
|
||||||
|
c = [self count];
|
||||||
if (c != [otherArray count])
|
if (c != [otherArray count])
|
||||||
return NO;
|
return NO;
|
||||||
for (i = 0; i < c; i++)
|
if (c > 0)
|
||||||
if (![[self objectAtIndex: i] isEqual: [otherArray objectAtIndex: i]])
|
{
|
||||||
return NO;
|
IMP get0 = [self methodForSelector: oaiSel];
|
||||||
|
IMP get1 = [otherArray methodForSelector: oaiSel];
|
||||||
|
|
||||||
|
for (i = 0; i < c; i++)
|
||||||
|
if (![(*get0)(self, oaiSel, i) isEqual: (*get1)(otherArray, oaiSel, i)])
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- lastObject
|
- (id) lastObject
|
||||||
{
|
{
|
||||||
unsigned count = [self count];
|
unsigned count = [self count];
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
|
@ -453,8 +502,14 @@ static Class NSMutableArray_concrete_class;
|
||||||
- (void) makeObjectsPerformSelector: (SEL)aSelector
|
- (void) makeObjectsPerformSelector: (SEL)aSelector
|
||||||
{
|
{
|
||||||
unsigned i = [self count];
|
unsigned i = [self count];
|
||||||
while (i-- > 0)
|
|
||||||
[[self objectAtIndex: i] performSelector: aSelector];
|
if (i > 0)
|
||||||
|
{
|
||||||
|
IMP get = [self methodForSelector: oaiSel];
|
||||||
|
|
||||||
|
while (i-- > 0)
|
||||||
|
[(*get)(self, oaiSel, i) performSelector: aSelector];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) makeObjectsPerform: (SEL)aSelector
|
- (void) makeObjectsPerform: (SEL)aSelector
|
||||||
|
@ -462,14 +517,20 @@ static Class NSMutableArray_concrete_class;
|
||||||
[self makeObjectsPerformSelector: aSelector];
|
[self makeObjectsPerformSelector: aSelector];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) makeObjectsPerformSelector: (SEL)aSelector withObject: argument
|
- (void) makeObjectsPerformSelector: (SEL)aSelector withObject: (id) arg
|
||||||
{
|
{
|
||||||
unsigned i = [self count];
|
unsigned i = [self count];
|
||||||
while (i-- > 0)
|
|
||||||
[[self objectAtIndex: i] performSelector: aSelector withObject: argument];
|
if (i > 0)
|
||||||
|
{
|
||||||
|
IMP get = [self methodForSelector: oaiSel];
|
||||||
|
|
||||||
|
while (i-- > 0)
|
||||||
|
[(*get)(self, oaiSel, i) performSelector: aSelector withObject: arg];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) makeObjectsPerform: (SEL)aSelector withObject: argument
|
- (void) makeObjectsPerform: (SEL)aSelector withObject: (id)argument
|
||||||
{
|
{
|
||||||
[self makeObjectsPerformSelector: aSelector withObject: argument];
|
[self makeObjectsPerformSelector: aSelector withObject: argument];
|
||||||
}
|
}
|
||||||
|
@ -481,7 +542,7 @@ static Class NSMutableArray_concrete_class;
|
||||||
return (int)[elem1 performSelector: comparator withObject: elem2];
|
return (int)[elem1 performSelector: comparator withObject: elem2];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [self sortedArrayUsingFunction: compare context: NULL];
|
return [self sortedArrayUsingFunction: compare context: NULL];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray*) sortedArrayUsingFunction: (int(*)(id,id,void*))comparator
|
- (NSArray*) sortedArrayUsingFunction: (int(*)(id,id,void*))comparator
|
||||||
|
@ -492,7 +553,7 @@ static Class NSMutableArray_concrete_class;
|
||||||
|
|
||||||
- (NSData*) sortedArrayHint
|
- (NSData*) sortedArrayHint
|
||||||
{
|
{
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray*) sortedArrayUsingFunction: (int(*)(id,id,void*))comparator
|
- (NSArray*) sortedArrayUsingFunction: (int(*)(id,id,void*))comparator
|
||||||
|
@ -502,10 +563,10 @@ static Class NSMutableArray_concrete_class;
|
||||||
NSMutableArray *sortedArray;
|
NSMutableArray *sortedArray;
|
||||||
NSArray *result;
|
NSArray *result;
|
||||||
|
|
||||||
sortedArray = [[NSMutableArray allocWithZone: NSDefaultMallocZone()]
|
sortedArray = [[NSMutableArray_abstract_class allocWithZone:
|
||||||
initWithArray: self];
|
NSDefaultMallocZone()] initWithArray: self];
|
||||||
[sortedArray sortUsingFunction: comparator context: context];
|
[sortedArray sortUsingFunction: comparator context: context];
|
||||||
result = [NSArray arrayWithArray: sortedArray];
|
result = [NSArray_abstract_class arrayWithArray: sortedArray];
|
||||||
RELEASE(sortedArray);
|
RELEASE(sortedArray);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -530,17 +591,22 @@ static Class NSMutableArray_concrete_class;
|
||||||
{
|
{
|
||||||
unsigned i, c = [self count];
|
unsigned i, c = [self count];
|
||||||
NSMutableArray *a = [NSMutableArray arrayWithCapacity: 1];
|
NSMutableArray *a = [NSMutableArray arrayWithCapacity: 1];
|
||||||
|
Class cls = [NSString class];
|
||||||
|
IMP get = [self methodForSelector: oaiSel];
|
||||||
|
IMP add = [a methodForSelector: addSel];
|
||||||
|
|
||||||
for (i = 0; i < c; i++)
|
for (i = 0; i < c; i++)
|
||||||
{
|
{
|
||||||
id o = [self objectAtIndex: i];
|
id o = (*get)(self, oaiSel, i);
|
||||||
if ([o isKindOfClass: [NSString class]])
|
|
||||||
|
if ([o isKindOfClass: cls])
|
||||||
if ([extensions containsObject: [o pathExtension]])
|
if ([extensions containsObject: [o pathExtension]])
|
||||||
[a addObject: o];
|
(*add)(a, addSel, o);
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
- firstObjectCommonWithArray: (NSArray*)otherArray
|
- (id) firstObjectCommonWithArray: (NSArray*)otherArray
|
||||||
{
|
{
|
||||||
unsigned i, c = [self count];
|
unsigned i, c = [self count];
|
||||||
id o;
|
id o;
|
||||||
|
@ -627,10 +693,8 @@ static NSString *indentStrings[] = {
|
||||||
unsigned count = [self count];
|
unsigned count = [self count];
|
||||||
NSString *plists[count];
|
NSString *plists[count];
|
||||||
unsigned i;
|
unsigned i;
|
||||||
SEL appSel;
|
|
||||||
IMP appImp;
|
IMP appImp;
|
||||||
|
|
||||||
appSel = @selector(appendString:);
|
|
||||||
appImp = [(NSObject*)result methodForSelector: appSel];
|
appImp = [(NSObject*)result methodForSelector: appSel];
|
||||||
|
|
||||||
if (level < sizeof(indentStrings)/sizeof(NSString*))
|
if (level < sizeof(indentStrings)/sizeof(NSString*))
|
||||||
|
@ -693,16 +757,16 @@ static NSString *indentStrings[] = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+ allocWithZone: (NSZone*)z
|
+ (id) allocWithZone: (NSZone*)z
|
||||||
{
|
{
|
||||||
if ([self class] == [NSMutableArray class])
|
if (self == NSMutableArray_abstract_class)
|
||||||
return NSAllocateObject ([self _mutableConcreteClass], 0, z);
|
return NSAllocateObject(NSMutableArray_concrete_class, 0, z);
|
||||||
return [super allocWithZone: z];
|
return [super allocWithZone: z];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The NSCopying Protocol */
|
/* The NSCopying Protocol */
|
||||||
|
|
||||||
- copyWithZone: (NSZone*)zone
|
- (id) copyWithZone: (NSZone*)zone
|
||||||
{
|
{
|
||||||
/* a deep copy */
|
/* a deep copy */
|
||||||
unsigned count = [self count];
|
unsigned count = [self count];
|
||||||
|
@ -713,15 +777,15 @@ static NSString *indentStrings[] = {
|
||||||
[self getObjects: objects];
|
[self getObjects: objects];
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
objects[i] = [objects[i] copyWithZone: zone];
|
objects[i] = [objects[i] copyWithZone: zone];
|
||||||
newArray = [[[[self class] _concreteClass] allocWithZone: zone]
|
newArray = [[NSArray_concrete_class allocWithZone: zone]
|
||||||
initWithObjects: objects count: count];
|
initWithObjects: objects count: count];
|
||||||
while (i > 0)
|
while (i > 0)
|
||||||
RELEASE(objects[--i]);
|
RELEASE(objects[--i]);
|
||||||
return newArray;
|
return newArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the desgnated initializer for NSMutableArray */
|
/* This is the desgnated initializer for NSMutableArray */
|
||||||
- initWithCapacity: (unsigned)numItems
|
- (id) initWithCapacity: (unsigned)numItems
|
||||||
{
|
{
|
||||||
[self subclassResponsibility: _cmd];
|
[self subclassResponsibility: _cmd];
|
||||||
return nil;
|
return nil;
|
||||||
|
@ -774,127 +838,174 @@ static NSString *indentStrings[] = {
|
||||||
|
|
||||||
@implementation NSMutableArrayNonCore
|
@implementation NSMutableArrayNonCore
|
||||||
|
|
||||||
+ arrayWithCapacity: (unsigned)numItems
|
+ (id) arrayWithCapacity: (unsigned)numItems
|
||||||
{
|
{
|
||||||
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
|
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
|
||||||
initWithCapacity: numItems]);
|
initWithCapacity: numItems]);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)writeToFile: (NSString *)path atomically: (BOOL)useAuxiliaryFile
|
- (BOOL) writeToFile: (NSString *)path atomically: (BOOL)useAuxiliaryFile
|
||||||
{
|
{
|
||||||
return [[self description] writeToFile: path atomically: useAuxiliaryFile];
|
return [[self description] writeToFile: path atomically: useAuxiliaryFile];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Override our superclass's designated initializer to go our's */
|
/* Override our superclass's designated initializer to go our's */
|
||||||
- initWithObjects: (id*)objects count: (unsigned)count
|
- (id) initWithObjects: (id*)objects count: (unsigned)count
|
||||||
{
|
{
|
||||||
unsigned i;
|
|
||||||
self = [self initWithCapacity: count];
|
self = [self initWithCapacity: count];
|
||||||
for (i = 0; i < count; i++)
|
if (count > 0)
|
||||||
[self addObject: objects[i]];
|
{
|
||||||
|
unsigned i;
|
||||||
|
IMP add = [self methodForSelector: addSel];
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
(*add)(self, addSel, objects[i]);
|
||||||
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) removeLastObject
|
- (void) removeLastObject
|
||||||
{
|
{
|
||||||
unsigned count = [self count];
|
unsigned count = [self count];
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
[NSException raise: NSRangeException
|
[NSException raise: NSRangeException
|
||||||
format: @"Trying to remove from an empty array."];
|
format: @"Trying to remove from an empty array."];
|
||||||
[self removeObjectAtIndex: count-1];
|
[self removeObjectAtIndex: count-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) removeObjectIdenticalTo: anObject
|
- (void) removeObjectIdenticalTo: (id)anObject
|
||||||
{
|
{
|
||||||
unsigned pos = NSNotFound;
|
unsigned i = [self count];
|
||||||
unsigned i = [self count];
|
|
||||||
|
|
||||||
while (i-- > 0)
|
if (i > 0)
|
||||||
{
|
{
|
||||||
id o = [self objectAtIndex: i];
|
IMP rem = 0;
|
||||||
if (o == anObject)
|
IMP get = [self methodForSelector: oaiSel];
|
||||||
|
|
||||||
|
while (i-- > 0)
|
||||||
{
|
{
|
||||||
if (pos != NSNotFound)
|
id o = (*get)(self, oaiSel, i);
|
||||||
[self removeObjectAtIndex: pos];
|
|
||||||
pos = i;
|
if (o == anObject)
|
||||||
|
{
|
||||||
|
if (rem == 0)
|
||||||
|
rem = [self methodForSelector: remSel];
|
||||||
|
(*rem)(self, remSel, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pos != NSNotFound)
|
|
||||||
[self removeObjectAtIndex: pos];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) removeObject: anObject inRange: (NSRange)aRange
|
- (void) removeObject: (id)anObject inRange: (NSRange)aRange
|
||||||
{
|
{
|
||||||
unsigned c = [self count], s = aRange.location;
|
unsigned c = [self count];
|
||||||
unsigned i = aRange.location + aRange.length;
|
unsigned s = aRange.location;
|
||||||
unsigned pos = NSNotFound;
|
unsigned i = aRange.location + aRange.length;
|
||||||
|
|
||||||
if (i > c)
|
if (i > c)
|
||||||
i = c;
|
i = c;
|
||||||
while (i-- > s)
|
|
||||||
|
if (i > s)
|
||||||
{
|
{
|
||||||
id o = [self objectAtIndex: i];
|
IMP rem = 0;
|
||||||
if (o == anObject || [o isEqual: anObject])
|
IMP get = [self methodForSelector: oaiSel];
|
||||||
|
BOOL (*eq)(id, SEL, id)
|
||||||
|
= (BOOL (*)(id, SEL, id))[anObject methodForSelector: eqSel];
|
||||||
|
|
||||||
|
while (i-- > s)
|
||||||
{
|
{
|
||||||
if (pos != NSNotFound)
|
id o = (*get)(self, oaiSel, i);
|
||||||
[self removeObjectAtIndex: pos];
|
|
||||||
pos = i;
|
if (o == anObject || (*eq)(anObject, eqSel, o) == YES)
|
||||||
|
{
|
||||||
|
if (rem == 0)
|
||||||
|
rem = [self methodForSelector: remSel];
|
||||||
|
(*rem)(self, remSel, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pos != NSNotFound)
|
|
||||||
[self removeObjectAtIndex: pos];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) removeObjectIdenticalTo: anObject inRange: (NSRange)aRange
|
- (void) removeObjectIdenticalTo: (id)anObject inRange: (NSRange)aRange
|
||||||
{
|
{
|
||||||
unsigned c = [self count], s = aRange.location;
|
unsigned c = [self count];
|
||||||
unsigned i = aRange.location + aRange.length;
|
unsigned s = aRange.location;
|
||||||
unsigned pos = NSNotFound;
|
unsigned i = aRange.location + aRange.length;
|
||||||
|
|
||||||
if (i > c)
|
if (i > c)
|
||||||
i = c;
|
i = c;
|
||||||
while (i-- > s)
|
|
||||||
|
if (i > s)
|
||||||
{
|
{
|
||||||
id o = [self objectAtIndex: i];
|
IMP rem = 0;
|
||||||
if (o == anObject)
|
IMP get = [self methodForSelector: oaiSel];
|
||||||
|
|
||||||
|
while (i-- > s)
|
||||||
{
|
{
|
||||||
if (pos != NSNotFound)
|
id o = (*get)(self, oaiSel, i);
|
||||||
[self removeObjectAtIndex: pos];
|
|
||||||
pos = i;
|
if (o == anObject)
|
||||||
|
{
|
||||||
|
if (rem == 0)
|
||||||
|
rem = [self methodForSelector: remSel];
|
||||||
|
(*rem)(self, remSel, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pos != NSNotFound)
|
|
||||||
[self removeObjectAtIndex: pos];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) removeObject: anObject
|
- (void) removeObject: (id)anObject
|
||||||
{
|
{
|
||||||
unsigned pos = NSNotFound;
|
unsigned i = [self count];
|
||||||
unsigned i = [self count];
|
|
||||||
|
|
||||||
while (i-- > 0)
|
if (i > 0)
|
||||||
{
|
{
|
||||||
id o = [self objectAtIndex: i];
|
IMP rem = 0;
|
||||||
if (o == anObject || [o isEqual: anObject])
|
IMP get = [self methodForSelector: oaiSel];
|
||||||
|
BOOL (*eq)(id, SEL, id)
|
||||||
|
= (BOOL (*)(id, SEL, id))[anObject methodForSelector: eqSel];
|
||||||
|
|
||||||
|
while (i-- > 0)
|
||||||
{
|
{
|
||||||
if (pos != NSNotFound)
|
id o = (*get)(self, oaiSel, i);
|
||||||
[self removeObjectAtIndex: pos];
|
|
||||||
pos = i;
|
if (o == anObject || (*eq)(anObject, eqSel, o) == YES)
|
||||||
|
{
|
||||||
|
if (rem == 0)
|
||||||
|
rem = [self methodForSelector: remSel];
|
||||||
|
(*rem)(self, remSel, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pos != NSNotFound)
|
|
||||||
[self removeObjectAtIndex: pos];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) removeAllObjects
|
- (void) removeAllObjects
|
||||||
{
|
{
|
||||||
while ([self count])
|
unsigned c = [self count];
|
||||||
[self removeLastObject];
|
|
||||||
|
if (c > 0)
|
||||||
|
{
|
||||||
|
IMP remLast = [self methodForSelector: rlSel];
|
||||||
|
|
||||||
|
while (c--)
|
||||||
|
(*remLast)(self, rlSel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) addObjectsFromArray: (NSArray*)otherArray
|
- (void) addObjectsFromArray: (NSArray*)otherArray
|
||||||
{
|
{
|
||||||
unsigned i, c = [otherArray count];
|
unsigned c = [otherArray count];
|
||||||
for (i = 0; i < c; i++)
|
|
||||||
[self addObject: [otherArray objectAtIndex: i]];
|
if (c > 0)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
IMP get = [otherArray methodForSelector: oaiSel];
|
||||||
|
IMP add = [self methodForSelector: addSel];
|
||||||
|
|
||||||
|
for (i = 0; i < c; i++)
|
||||||
|
(*add)(self, addSel, (*get)(otherArray, oaiSel, i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setArray: (NSArray *)otherArray
|
- (void) setArray: (NSArray *)otherArray
|
||||||
|
@ -943,28 +1054,51 @@ static NSString *indentStrings[] = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (to--)
|
if (to > 0)
|
||||||
{
|
{
|
||||||
[self removeObjectAtIndex: sorted[to]];
|
IMP rem = [self methodForSelector: remSel];
|
||||||
|
|
||||||
|
while (to--)
|
||||||
|
{
|
||||||
|
(*rem)(self, remSel, sorted[to]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) removeObjectsInArray: (NSArray*)otherArray
|
- (void) removeObjectsInArray: (NSArray*)otherArray
|
||||||
{
|
{
|
||||||
unsigned i, c = [otherArray count];
|
unsigned c = [otherArray count];
|
||||||
for (i = 0; i < c; i++)
|
|
||||||
[self removeObject: [otherArray objectAtIndex: i]];
|
if (c > 0)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
IMP get = [otherArray methodForSelector: oaiSel];
|
||||||
|
IMP rem = [self methodForSelector: @selector(removeObject:)];
|
||||||
|
|
||||||
|
for (i = 0; i < c; i++)
|
||||||
|
(*rem)(self, @selector(removeObject:), (*get)(otherArray, oaiSel, i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) removeObjectsInRange: (NSRange)aRange
|
- (void) removeObjectsInRange: (NSRange)aRange
|
||||||
{
|
{
|
||||||
unsigned i, s = aRange.location, c = [self count];
|
unsigned i;
|
||||||
|
unsigned s = aRange.location;
|
||||||
|
unsigned c = [self count];
|
||||||
|
|
||||||
i = aRange.location + aRange.length;
|
i = aRange.location + aRange.length;
|
||||||
|
|
||||||
if (c < i)
|
if (c < i)
|
||||||
i = c;
|
i = c;
|
||||||
while (i-- > s)
|
|
||||||
[self removeObjectAtIndex: i];
|
if (i > s)
|
||||||
|
{
|
||||||
|
IMP rem = [self methodForSelector: remSel];
|
||||||
|
|
||||||
|
while (i-- > s)
|
||||||
|
(*rem)(self, remSel, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) sortUsingSelector: (SEL)comparator
|
- (void) sortUsingSelector: (SEL)comparator
|
||||||
|
@ -974,7 +1108,7 @@ static NSString *indentStrings[] = {
|
||||||
return (int)[elem1 performSelector: comparator withObject: elem2];
|
return (int)[elem1 performSelector: comparator withObject: elem2];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self sortUsingFunction: compare context: NULL];
|
[self sortUsingFunction: compare context: NULL];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) sortUsingFunction: (int(*)(id,id,void*))compare
|
- (void) sortUsingFunction: (int(*)(id,id,void*))compare
|
||||||
|
@ -991,58 +1125,67 @@ static NSString *indentStrings[] = {
|
||||||
while (stride <= count)
|
while (stride <= count)
|
||||||
stride = stride * STRIDE_FACTOR + 1;
|
stride = stride * STRIDE_FACTOR + 1;
|
||||||
|
|
||||||
while(stride > (STRIDE_FACTOR - 1)) {
|
while(stride > (STRIDE_FACTOR - 1))
|
||||||
// loop to sort for each value of stride
|
{
|
||||||
stride = stride / STRIDE_FACTOR;
|
// loop to sort for each value of stride
|
||||||
for (c = stride; c < count; c++) {
|
stride = stride / STRIDE_FACTOR;
|
||||||
found = NO;
|
for (c = stride; c < count; c++)
|
||||||
if (stride > c)
|
{
|
||||||
break;
|
found = NO;
|
||||||
d = c - stride;
|
if (stride > c)
|
||||||
while (!found) {
|
|
||||||
// move to left until correct place
|
|
||||||
id a = [self objectAtIndex: d + stride];
|
|
||||||
id b = [self objectAtIndex: d];
|
|
||||||
if ((*compare)(a, b, context) == NSOrderedAscending) {
|
|
||||||
RETAIN(a);
|
|
||||||
[self replaceObjectAtIndex: d + stride withObject: b];
|
|
||||||
[self replaceObjectAtIndex: d withObject: a];
|
|
||||||
RELEASE(a);
|
|
||||||
if (stride > d)
|
|
||||||
break;
|
break;
|
||||||
d -= stride; // jump by stride factor
|
d = c - stride;
|
||||||
|
while (!found)
|
||||||
|
{
|
||||||
|
// move to left until correct place
|
||||||
|
id a = [self objectAtIndex: d + stride];
|
||||||
|
id b = [self objectAtIndex: d];
|
||||||
|
if ((*compare)(a, b, context) == NSOrderedAscending)
|
||||||
|
{
|
||||||
|
RETAIN(a);
|
||||||
|
[self replaceObjectAtIndex: d + stride withObject: b];
|
||||||
|
[self replaceObjectAtIndex: d withObject: a];
|
||||||
|
RELEASE(a);
|
||||||
|
if (stride > d)
|
||||||
|
break;
|
||||||
|
d -= stride; // jump by stride factor
|
||||||
|
}
|
||||||
|
else found = YES;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else found = YES;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface NSArrayEnumerator : NSEnumerator
|
@interface NSArrayEnumerator : NSEnumerator
|
||||||
{
|
{
|
||||||
id array;
|
NSArray *array;
|
||||||
int next_index;
|
unsigned pos;
|
||||||
|
IMP get;
|
||||||
|
unsigned (*cnt)(NSArray*, SEL);
|
||||||
}
|
}
|
||||||
|
- (id) initWithArray: (NSArray*)anArray;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation NSArrayEnumerator
|
@implementation NSArrayEnumerator
|
||||||
|
|
||||||
- initWithArray: (NSArray*)anArray
|
- (id) initWithArray: (NSArray*)anArray
|
||||||
{
|
{
|
||||||
[super init];
|
[super init];
|
||||||
array = anArray;
|
array = anArray;
|
||||||
RETAIN(array);
|
RETAIN(array);
|
||||||
next_index = 0;
|
pos = 0;
|
||||||
|
get = [array methodForSelector: oaiSel];
|
||||||
|
cnt = (unsigned (*)(NSArray*, SEL))[array methodForSelector: countSel];
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) nextObject
|
- (id) nextObject
|
||||||
{
|
{
|
||||||
if (next_index >= [array count])
|
if (pos >= (*cnt)(array, countSel))
|
||||||
return nil;
|
return nil;
|
||||||
return [array objectAtIndex: next_index++];
|
return (*get)(array, oaiSel, pos++);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
|
@ -1058,19 +1201,17 @@ static NSString *indentStrings[] = {
|
||||||
|
|
||||||
@implementation NSArrayEnumeratorReverse
|
@implementation NSArrayEnumeratorReverse
|
||||||
|
|
||||||
- initWithArray: (NSArray*)anArray
|
- (id) initWithArray: (NSArray*)anArray
|
||||||
{
|
{
|
||||||
[super init];
|
[super initWithArray: anArray];
|
||||||
array = anArray;
|
pos = (*cnt)(array, countSel);
|
||||||
RETAIN(array);
|
|
||||||
next_index = [array count]-1;
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) nextObject
|
- (id) nextObject
|
||||||
{
|
{
|
||||||
if (next_index < 0)
|
if (pos == 0)
|
||||||
return nil;
|
return nil;
|
||||||
return [array objectAtIndex: next_index--];
|
return (*get)(array, oaiSel, --pos);
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Concrete implementation of NSArray
|
/* Concrete implementation of NSArray
|
||||||
Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
|
Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
|
||||||
|
|
||||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||||
Date: March 1995
|
Date: March 1995
|
||||||
|
@ -29,8 +29,14 @@
|
||||||
#include <Foundation/NSException.h>
|
#include <Foundation/NSException.h>
|
||||||
#include <Foundation/NSPortCoder.h>
|
#include <Foundation/NSPortCoder.h>
|
||||||
|
|
||||||
|
static SEL eqSel = @selector(isEqual:);
|
||||||
|
|
||||||
|
@class NSGArrayEnumerator;
|
||||||
|
@class NSGArrayEnumeratorReverse;
|
||||||
|
|
||||||
@interface NSGArray : NSArray
|
@interface NSGArray : NSArray
|
||||||
{
|
{
|
||||||
|
@public
|
||||||
id *_contents_array;
|
id *_contents_array;
|
||||||
unsigned _count;
|
unsigned _count;
|
||||||
}
|
}
|
||||||
|
@ -38,6 +44,7 @@
|
||||||
|
|
||||||
@interface NSGMutableArray : NSMutableArray
|
@interface NSGMutableArray : NSMutableArray
|
||||||
{
|
{
|
||||||
|
@public
|
||||||
id *_contents_array;
|
id *_contents_array;
|
||||||
unsigned _count;
|
unsigned _count;
|
||||||
unsigned _capacity;
|
unsigned _capacity;
|
||||||
|
@ -166,15 +173,14 @@
|
||||||
*/
|
*/
|
||||||
if (_count > 1)
|
if (_count > 1)
|
||||||
{
|
{
|
||||||
static SEL sel = @selector(isEqual:);
|
|
||||||
BOOL (*imp)(id,SEL,id);
|
BOOL (*imp)(id,SEL,id);
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
imp = (BOOL (*)(id,SEL,id))[anObject methodForSelector: sel];
|
imp = (BOOL (*)(id,SEL,id))[anObject methodForSelector: eqSel];
|
||||||
|
|
||||||
for (i = 0; i < _count; i++)
|
for (i = 0; i < _count; i++)
|
||||||
{
|
{
|
||||||
if ((*imp)(anObject, sel, _contents_array[i]))
|
if ((*imp)(anObject, eqSel, _contents_array[i]))
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -413,6 +419,33 @@
|
||||||
RELEASE(_contents_array[_count]);
|
RELEASE(_contents_array[_count]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) removeObject: (id)anObject
|
||||||
|
{
|
||||||
|
unsigned index = _count;
|
||||||
|
|
||||||
|
if (index > 0)
|
||||||
|
{
|
||||||
|
BOOL (*imp)(id,SEL,id);
|
||||||
|
|
||||||
|
imp = (BOOL (*)(id,SEL,id))[anObject methodForSelector: eqSel];
|
||||||
|
while (index-- > 0)
|
||||||
|
{
|
||||||
|
if ((*imp)(anObject, eqSel, _contents_array[index]) == YES)
|
||||||
|
{
|
||||||
|
id obj = _contents_array[index];
|
||||||
|
unsigned pos = index;
|
||||||
|
|
||||||
|
while (++pos < _count)
|
||||||
|
{
|
||||||
|
_contents_array[pos-1] = _contents_array[pos];
|
||||||
|
}
|
||||||
|
_count--;
|
||||||
|
RELEASE(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void) removeObjectAtIndex: (unsigned)index
|
- (void) removeObjectAtIndex: (unsigned)index
|
||||||
{
|
{
|
||||||
id obj;
|
id obj;
|
||||||
|
@ -433,6 +466,27 @@
|
||||||
RELEASE(obj); /* Adjust array BEFORE releasing object. */
|
RELEASE(obj); /* Adjust array BEFORE releasing object. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) removeObjectIdenticalTo: (id)anObject
|
||||||
|
{
|
||||||
|
unsigned index = _count;
|
||||||
|
|
||||||
|
while (index-- > 0)
|
||||||
|
{
|
||||||
|
if (_contents_array[index] == anObject)
|
||||||
|
{
|
||||||
|
id obj = _contents_array[index];
|
||||||
|
unsigned pos = index;
|
||||||
|
|
||||||
|
while (++pos < _count)
|
||||||
|
{
|
||||||
|
_contents_array[pos-1] = _contents_array[pos];
|
||||||
|
}
|
||||||
|
_count--;
|
||||||
|
RELEASE(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void) replaceObjectAtIndex: (unsigned)index withObject: (id)anObject
|
- (void) replaceObjectAtIndex: (unsigned)index withObject: (id)anObject
|
||||||
{
|
{
|
||||||
id obj;
|
id obj;
|
||||||
|
@ -467,29 +521,102 @@
|
||||||
while (stride <= count)
|
while (stride <= count)
|
||||||
stride = stride * STRIDE_FACTOR + 1;
|
stride = stride * STRIDE_FACTOR + 1;
|
||||||
|
|
||||||
while(stride > (STRIDE_FACTOR - 1)) {
|
while (stride > (STRIDE_FACTOR - 1))
|
||||||
// loop to sort for each value of stride
|
{
|
||||||
stride = stride / STRIDE_FACTOR;
|
// loop to sort for each value of stride
|
||||||
for (c = stride; c < count; c++) {
|
stride = stride / STRIDE_FACTOR;
|
||||||
found = NO;
|
for (c = stride; c < count; c++)
|
||||||
if (stride > c)
|
{
|
||||||
break;
|
found = NO;
|
||||||
d = c - stride;
|
if (stride > c)
|
||||||
while (!found) {
|
|
||||||
// move to left until correct place
|
|
||||||
id a = _contents_array[d + stride];
|
|
||||||
id b = _contents_array[d];
|
|
||||||
if ((*compare)(a, b, context) == NSOrderedAscending) {
|
|
||||||
_contents_array[d+stride] = b;
|
|
||||||
_contents_array[d] = a;
|
|
||||||
if (stride > d)
|
|
||||||
break;
|
break;
|
||||||
d -= stride; // jump by stride factor
|
d = c - stride;
|
||||||
|
while (!found)
|
||||||
|
{
|
||||||
|
// move to left until correct place
|
||||||
|
id a = _contents_array[d + stride];
|
||||||
|
id b = _contents_array[d];
|
||||||
|
if ((*compare)(a, b, context) == NSOrderedAscending)
|
||||||
|
{
|
||||||
|
_contents_array[d+stride] = b;
|
||||||
|
_contents_array[d] = a;
|
||||||
|
if (stride > d)
|
||||||
|
break;
|
||||||
|
d -= stride; // jump by stride factor
|
||||||
|
}
|
||||||
|
else
|
||||||
|
found = YES;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else found = YES;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSEnumerator*) objectEnumerator
|
||||||
|
{
|
||||||
|
return AUTORELEASE([[NSGArrayEnumerator allocWithZone: NSDefaultMallocZone()]
|
||||||
|
initWithArray: self]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSEnumerator*) reverseObjectEnumerator
|
||||||
|
{
|
||||||
|
return AUTORELEASE([[NSGArrayEnumeratorReverse allocWithZone:
|
||||||
|
NSDefaultMallocZone()] initWithArray: self]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@interface NSGArrayEnumerator : NSEnumerator
|
||||||
|
{
|
||||||
|
NSGArray *array;
|
||||||
|
unsigned pos;
|
||||||
|
}
|
||||||
|
- (id) initWithArray: (NSGArray*)anArray;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation NSGArrayEnumerator
|
||||||
|
|
||||||
|
- (id) initWithArray: (NSGArray*)anArray
|
||||||
|
{
|
||||||
|
[super init];
|
||||||
|
array = anArray;
|
||||||
|
RETAIN(array);
|
||||||
|
pos = 0;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) nextObject
|
||||||
|
{
|
||||||
|
if (pos >= array->_count)
|
||||||
|
return nil;
|
||||||
|
return array->_contents_array[pos++];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) dealloc
|
||||||
|
{
|
||||||
|
RELEASE(array);
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface NSGArrayEnumeratorReverse : NSGArrayEnumerator
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation NSGArrayEnumeratorReverse
|
||||||
|
|
||||||
|
- (id) initWithArray: (NSGArray*)anArray
|
||||||
|
{
|
||||||
|
[super initWithArray: anArray];
|
||||||
|
pos = array->_count;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) nextObject
|
||||||
|
{
|
||||||
|
if (pos == 0)
|
||||||
|
return nil;
|
||||||
|
return array->_contents_array[--pos];
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue