mirror of
https://github.com/gnustep/libs-base.git
synced 2025-06-02 17:41:05 +00:00
Add more fast enumeration code
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@27712 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
afb0f171c7
commit
f2a92b88ec
4 changed files with 60 additions and 6 deletions
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
* Headers/Foundation/NSEnumerator.h:
|
* Headers/Foundation/NSEnumerator.h:
|
||||||
* Source/NSEnumerator.m:
|
* Source/NSEnumerator.m:
|
||||||
|
* Source/GSArray.m:
|
||||||
|
* Source/GSprivate.h:
|
||||||
Add Apple's fast enumeration protocol.
|
Add Apple's fast enumeration protocol.
|
||||||
|
|
||||||
2009-01-28 Richard Frith-Macdonald <rfm@gnu.org>
|
2009-01-28 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
|
@ -367,6 +367,15 @@ static Class GSInlineArrayClass;
|
||||||
aBuffer[j++] = _contents_array[i];
|
aBuffer[j++] = _contents_array[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state
|
||||||
|
objects: (id*)stackbuf
|
||||||
|
count: (NSUInteger)len
|
||||||
|
{
|
||||||
|
/* For immutable arrays we can return the contents pointer directly. */
|
||||||
|
state->itemsPtr = _contents_array;
|
||||||
|
return _count;
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#if !GS_WITH_GC
|
#if !GS_WITH_GC
|
||||||
|
@ -437,6 +446,7 @@ static Class GSInlineArrayClass;
|
||||||
|
|
||||||
- (void) addObject: (id)anObject
|
- (void) addObject: (id)anObject
|
||||||
{
|
{
|
||||||
|
_version++;
|
||||||
if (anObject == nil)
|
if (anObject == nil)
|
||||||
{
|
{
|
||||||
[NSException raise: NSInvalidArgumentException
|
[NSException raise: NSInvalidArgumentException
|
||||||
|
@ -459,6 +469,7 @@ static Class GSInlineArrayClass;
|
||||||
}
|
}
|
||||||
_contents_array[_count] = RETAIN(anObject);
|
_contents_array[_count] = RETAIN(anObject);
|
||||||
_count++; /* Do this AFTER we have retained the object. */
|
_count++; /* Do this AFTER we have retained the object. */
|
||||||
|
_version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -479,6 +490,7 @@ static Class GSInlineArrayClass;
|
||||||
- (void) exchangeObjectAtIndex: (unsigned int)i1
|
- (void) exchangeObjectAtIndex: (unsigned int)i1
|
||||||
withObjectAtIndex: (unsigned int)i2
|
withObjectAtIndex: (unsigned int)i2
|
||||||
{
|
{
|
||||||
|
_version++;
|
||||||
if (i1 >= _count)
|
if (i1 >= _count)
|
||||||
{
|
{
|
||||||
[self _raiseRangeExceptionWithIndex: i1 from: _cmd];
|
[self _raiseRangeExceptionWithIndex: i1 from: _cmd];
|
||||||
|
@ -494,6 +506,7 @@ static Class GSInlineArrayClass;
|
||||||
_contents_array[i1] = _contents_array[i2];
|
_contents_array[i1] = _contents_array[i2];
|
||||||
_contents_array[i2] = tmp;
|
_contents_array[i2] = tmp;
|
||||||
}
|
}
|
||||||
|
_version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) init
|
- (id) init
|
||||||
|
@ -572,8 +585,7 @@ static Class GSInlineArrayClass;
|
||||||
|
|
||||||
- (void) insertObject: (id)anObject atIndex: (unsigned)index
|
- (void) insertObject: (id)anObject atIndex: (unsigned)index
|
||||||
{
|
{
|
||||||
unsigned i;
|
_version++;
|
||||||
|
|
||||||
if (!anObject)
|
if (!anObject)
|
||||||
{
|
{
|
||||||
NSException *exception;
|
NSException *exception;
|
||||||
|
@ -607,10 +619,7 @@ static Class GSInlineArrayClass;
|
||||||
_capacity += _grow_factor;
|
_capacity += _grow_factor;
|
||||||
_grow_factor = _capacity/2;
|
_grow_factor = _capacity/2;
|
||||||
}
|
}
|
||||||
for (i = _count; i > index; i--)
|
memmove(&_contents_array[index], &_contents_array[index+1], _count - index);
|
||||||
{
|
|
||||||
_contents_array[i] = _contents_array[i - 1];
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* Make sure the array is 'sane' so that it can be deallocated
|
* Make sure the array is 'sane' so that it can be deallocated
|
||||||
* safely by an autorelease pool if the '[anObject retain]' causes
|
* safely by an autorelease pool if the '[anObject retain]' causes
|
||||||
|
@ -619,6 +628,7 @@ static Class GSInlineArrayClass;
|
||||||
_contents_array[index] = nil;
|
_contents_array[index] = nil;
|
||||||
_count++;
|
_count++;
|
||||||
_contents_array[index] = RETAIN(anObject);
|
_contents_array[index] = RETAIN(anObject);
|
||||||
|
_version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) makeImmutableCopyOnFail: (BOOL)force
|
- (id) makeImmutableCopyOnFail: (BOOL)force
|
||||||
|
@ -635,6 +645,7 @@ static Class GSInlineArrayClass;
|
||||||
|
|
||||||
- (void) removeLastObject
|
- (void) removeLastObject
|
||||||
{
|
{
|
||||||
|
_version++;
|
||||||
if (_count == 0)
|
if (_count == 0)
|
||||||
{
|
{
|
||||||
[NSException raise: NSRangeException
|
[NSException raise: NSRangeException
|
||||||
|
@ -643,12 +654,14 @@ static Class GSInlineArrayClass;
|
||||||
_count--;
|
_count--;
|
||||||
RELEASE(_contents_array[_count]);
|
RELEASE(_contents_array[_count]);
|
||||||
_contents_array[_count] = 0;
|
_contents_array[_count] = 0;
|
||||||
|
_version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) removeObject: (id)anObject
|
- (void) removeObject: (id)anObject
|
||||||
{
|
{
|
||||||
unsigned index;
|
unsigned index;
|
||||||
|
|
||||||
|
_version++;
|
||||||
if (anObject == nil)
|
if (anObject == nil)
|
||||||
{
|
{
|
||||||
NSWarnMLog(@"attempt to remove nil object");
|
NSWarnMLog(@"attempt to remove nil object");
|
||||||
|
@ -694,12 +707,14 @@ static Class GSInlineArrayClass;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
_version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) removeObjectAtIndex: (unsigned)index
|
- (void) removeObjectAtIndex: (unsigned)index
|
||||||
{
|
{
|
||||||
id obj;
|
id obj;
|
||||||
|
|
||||||
|
_version++;
|
||||||
if (index >= _count)
|
if (index >= _count)
|
||||||
{
|
{
|
||||||
[self _raiseRangeExceptionWithIndex: index from: _cmd];
|
[self _raiseRangeExceptionWithIndex: index from: _cmd];
|
||||||
|
@ -713,12 +728,14 @@ static Class GSInlineArrayClass;
|
||||||
}
|
}
|
||||||
_contents_array[_count] = 0;
|
_contents_array[_count] = 0;
|
||||||
RELEASE(obj); /* Adjust array BEFORE releasing object. */
|
RELEASE(obj); /* Adjust array BEFORE releasing object. */
|
||||||
|
_version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) removeObjectIdenticalTo: (id)anObject
|
- (void) removeObjectIdenticalTo: (id)anObject
|
||||||
{
|
{
|
||||||
unsigned index;
|
unsigned index;
|
||||||
|
|
||||||
|
_version++;
|
||||||
if (anObject == nil)
|
if (anObject == nil)
|
||||||
{
|
{
|
||||||
NSWarnMLog(@"attempt to remove nil object");
|
NSWarnMLog(@"attempt to remove nil object");
|
||||||
|
@ -743,12 +760,14 @@ static Class GSInlineArrayClass;
|
||||||
RELEASE(obj);
|
RELEASE(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) replaceObjectAtIndex: (unsigned)index withObject: (id)anObject
|
- (void) replaceObjectAtIndex: (unsigned)index withObject: (id)anObject
|
||||||
{
|
{
|
||||||
id obj;
|
id obj;
|
||||||
|
|
||||||
|
_version++;
|
||||||
if (index >= _count)
|
if (index >= _count)
|
||||||
{
|
{
|
||||||
[self _raiseRangeExceptionWithIndex: index from: _cmd];
|
[self _raiseRangeExceptionWithIndex: index from: _cmd];
|
||||||
|
@ -776,6 +795,7 @@ static Class GSInlineArrayClass;
|
||||||
IF_NO_GC(RETAIN(anObject));
|
IF_NO_GC(RETAIN(anObject));
|
||||||
_contents_array[index] = anObject;
|
_contents_array[index] = anObject;
|
||||||
RELEASE(obj);
|
RELEASE(obj);
|
||||||
|
_version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) sortUsingFunction: (NSComparisonResult(*)(id,id,void*))compare
|
- (void) sortUsingFunction: (NSComparisonResult(*)(id,id,void*))compare
|
||||||
|
@ -793,6 +813,7 @@ static Class GSInlineArrayClass;
|
||||||
BOOL badComparison = NO;
|
BOOL badComparison = NO;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
_version++;
|
||||||
while (stride <= count)
|
while (stride <= count)
|
||||||
{
|
{
|
||||||
stride = stride * STRIDE_FACTOR + 1;
|
stride = stride * STRIDE_FACTOR + 1;
|
||||||
|
@ -852,6 +873,7 @@ static Class GSInlineArrayClass;
|
||||||
NSWarnMLog(@"Detected bad return value from comparison");
|
NSWarnMLog(@"Detected bad return value from comparison");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
_version++;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSEnumerator*) objectEnumerator
|
- (NSEnumerator*) objectEnumerator
|
||||||
|
@ -870,6 +892,34 @@ static Class GSInlineArrayClass;
|
||||||
return AUTORELEASE([enumerator initWithArray: (GSArray*)self]);
|
return AUTORELEASE([enumerator initWithArray: (GSArray*)self]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state
|
||||||
|
objects: (id*)stackbuf
|
||||||
|
count: (NSUInteger)len
|
||||||
|
{
|
||||||
|
NSInteger count;
|
||||||
|
|
||||||
|
/* This is cached in the caller at the start and compared at each
|
||||||
|
* iteration. If it changes during the iteration then
|
||||||
|
* objc_enumerationMutation() will be called, throwing an exception.
|
||||||
|
*/
|
||||||
|
state->mutationsPtr = (unsigned long*)_version;
|
||||||
|
count = MIN(len, _count - state->state);
|
||||||
|
/* If a mutation has occurred then it's possible that we are being asked to
|
||||||
|
* get objects from after the end of the array. Don't pass negative values
|
||||||
|
* to memcpy.
|
||||||
|
*/
|
||||||
|
if (count <= 0)
|
||||||
|
{
|
||||||
|
memcpy(stackbuf, _contents_array, count);
|
||||||
|
state->state += count;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
state->itemsPtr = stackbuf;
|
||||||
|
return count;
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
unsigned _count;
|
unsigned _count;
|
||||||
unsigned _capacity;
|
unsigned _capacity;
|
||||||
int _grow_factor;
|
int _grow_factor;
|
||||||
|
int _version;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,7 @@
|
||||||
}
|
}
|
||||||
*(stackbuf+i) = next;
|
*(stackbuf+i) = next;
|
||||||
}
|
}
|
||||||
|
state->itemsPtr;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue