1994-11-04 16:29:24 +00:00
|
|
|
|
/* Implementation for Objective-C IndexedCollection object
|
1996-01-24 03:16:05 +00:00
|
|
|
|
Copyright (C) 1993,1994, 1995, 1996 Free Software Foundation, Inc.
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-04-17 20:17:45 +00:00
|
|
|
|
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
1996-02-22 15:18:57 +00:00
|
|
|
|
Created: May 1993
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-05-12 00:56:10 +00:00
|
|
|
|
This file is part of the GNUstep Base Library.
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
|
|
|
License along with this library; if not, write to the Free
|
|
|
|
|
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
*/
|
|
|
|
|
|
1997-11-06 00:51:23 +00:00
|
|
|
|
#include <config.h>
|
1996-04-17 15:23:00 +00:00
|
|
|
|
#include <gnustep/base/IndexedCollection.h>
|
|
|
|
|
#include <gnustep/base/IndexedCollectionPrivate.h>
|
1994-11-04 16:29:24 +00:00
|
|
|
|
#include <stdio.h>
|
1996-04-17 15:23:00 +00:00
|
|
|
|
#include <gnustep/base/Array.h>
|
|
|
|
|
#include <gnustep/base/NSString.h>
|
|
|
|
|
#include <gnustep/base/behavior.h>
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
@implementation ReverseEnumerator
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- nextObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-03-12 20:39:58 +00:00
|
|
|
|
return [collection prevObjectWithEnumState: &enum_state];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
@end
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
@implementation ConstantIndexedCollection
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
|
1994-11-04 16:29:24 +00:00
|
|
|
|
// GETTING MEMBERS BY INDEX;
|
|
|
|
|
|
|
|
|
|
- objectAtIndex: (unsigned)index
|
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
[self subclassResponsibility: _cmd];
|
1996-03-12 20:39:58 +00:00
|
|
|
|
return nil;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- firstObject
|
|
|
|
|
{
|
1996-03-13 02:34:22 +00:00
|
|
|
|
if ([self isEmpty])
|
|
|
|
|
return nil;
|
1996-02-22 15:18:57 +00:00
|
|
|
|
return [self objectAtIndex: 0];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- lastObject
|
|
|
|
|
{
|
1996-03-13 02:34:22 +00:00
|
|
|
|
if ([self isEmpty])
|
|
|
|
|
return nil;
|
1996-02-22 15:18:57 +00:00
|
|
|
|
return [self objectAtIndex: [self count]-1];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
|
1994-11-04 16:29:24 +00:00
|
|
|
|
// GETTING MEMBERS BY NEIGHBOR;
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
/* Should be overriden by linked-list-type classes */
|
1994-11-04 16:29:24 +00:00
|
|
|
|
- successorOfObject: anObject
|
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
int last = [self count] - 1;
|
|
|
|
|
int index = [self indexOfObject: anObject];
|
|
|
|
|
if (index == last)
|
|
|
|
|
return nil;
|
|
|
|
|
return [self objectAtIndex: index+1];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
/* Should be overriden by linked-list-type classes */
|
1994-11-04 16:29:24 +00:00
|
|
|
|
- predecessorOfObject: anObject
|
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
int index = [self indexOfObject: anObject];
|
|
|
|
|
if (index == 0)
|
|
|
|
|
return nil;
|
|
|
|
|
return [self objectAtIndex: index-1];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
|
|
|
|
|
// GETTING INDICES BY MEMBER;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
|
|
|
|
- (unsigned) indexOfObject: anObject
|
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
int i, count = [self count];
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
|
if ([anObject isEqual: [self objectAtIndex:i]])
|
|
|
|
|
return i;
|
|
|
|
|
return NO_INDEX;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (unsigned) indexOfObject: anObject inRange: (IndexRange)aRange
|
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* xxx check that aRange is within count */
|
|
|
|
|
for (i = aRange.location; i < aRange.location+aRange.length; i++)
|
|
|
|
|
if ([anObject isEqual: [self objectAtIndex:i]])
|
|
|
|
|
return i - aRange.location;
|
|
|
|
|
return NO_INDEX;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
|
|
|
|
|
// TESTING;
|
|
|
|
|
|
|
|
|
|
- (BOOL) contentsEqualInOrder: (id <ConstantIndexedCollecting>)aColl
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
id o1, o2;
|
|
|
|
|
void *s1, *s2;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
if ([self count] != [aColl count])
|
|
|
|
|
return NO;
|
|
|
|
|
s1 = [self newEnumState];
|
|
|
|
|
s2 = [aColl newEnumState];
|
|
|
|
|
while ((o1 = [self nextObjectWithEnumState:&s1])
|
|
|
|
|
&& (o2 = [aColl nextObjectWithEnumState:&s2]))
|
|
|
|
|
{
|
|
|
|
|
if (![o1 isEqual: o2])
|
|
|
|
|
{
|
|
|
|
|
[self freeEnumState:&s1];
|
|
|
|
|
[aColl freeEnumState:&s2];
|
|
|
|
|
return NO;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
[self freeEnumState:&s1];
|
|
|
|
|
[aColl freeEnumState:&s2];
|
|
|
|
|
return YES;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (int) compareInOrderContentsOf: (id <Collecting>)aCollection
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
void *es1 = [self newEnumState];
|
|
|
|
|
void *es2 = [aCollection newEnumState];
|
|
|
|
|
id o1, o2;
|
|
|
|
|
int comparison;
|
|
|
|
|
while ((o1 = [self nextObjectWithEnumState:&es1])
|
|
|
|
|
&& (o2 = [aCollection nextObjectWithEnumState:&es2]))
|
|
|
|
|
{
|
|
|
|
|
if ((comparison = [o1 compare: o2]))
|
|
|
|
|
{
|
|
|
|
|
[self freeEnumState:&es1];
|
|
|
|
|
[aCollection freeEnumState:&es2];
|
|
|
|
|
return comparison;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if ((comparison = ([self count] - [aCollection count])))
|
|
|
|
|
return comparison;
|
|
|
|
|
return 0;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (unsigned) indexOfFirstDifference: (id <ConstantIndexedCollecting>)aColl
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
unsigned i = 0;
|
|
|
|
|
BOOL flag = YES;
|
|
|
|
|
void *enumState = [self newEnumState];
|
1996-02-22 15:18:57 +00:00
|
|
|
|
id o1, o2;
|
|
|
|
|
FOR_INDEXED_COLLECTION_WHILE_TRUE(self, o1, flag)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
if ((!(o2 = [self nextObjectWithEnumState: &enumState]))
|
|
|
|
|
|| [o1 isEqual: o2])
|
1994-11-04 16:29:24 +00:00
|
|
|
|
flag = NO;
|
|
|
|
|
else
|
|
|
|
|
i++;
|
|
|
|
|
}
|
1996-02-22 15:18:57 +00:00
|
|
|
|
END_FOR_INDEXED_COLLECTION_WHILE_TRUE(self);
|
|
|
|
|
[self freeEnumState: &enumState];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Could be more efficient */
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (unsigned) indexOfFirstIn: (id <ConstantCollecting>)aCollection
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
unsigned index = 0;
|
|
|
|
|
BOOL flag = YES;
|
1996-02-22 15:18:57 +00:00
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
FOR_INDEXED_COLLECTION_WHILE_TRUE(self, o, flag)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
if ([aCollection containsObject: o])
|
1994-11-04 16:29:24 +00:00
|
|
|
|
flag = NO;
|
|
|
|
|
else
|
|
|
|
|
index++;
|
|
|
|
|
}
|
1996-02-22 15:18:57 +00:00
|
|
|
|
END_FOR_INDEXED_COLLECTION(self);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Could be more efficient */
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (unsigned) indexOfFirstNotIn: (id <ConstantCollecting>)aCollection
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
|
|
|
|
unsigned index = 0;
|
|
|
|
|
BOOL flag = YES;
|
1996-02-22 15:18:57 +00:00
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
FOR_INDEXED_COLLECTION_WHILE_TRUE(self, o, flag)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
if (![aCollection containsObject: o])
|
1994-11-04 16:29:24 +00:00
|
|
|
|
flag = NO;
|
|
|
|
|
else
|
|
|
|
|
index++;
|
|
|
|
|
}
|
1996-02-22 15:18:57 +00:00
|
|
|
|
END_FOR_INDEXED_COLLECTION(self);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
return index;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
|
|
|
|
|
// ENUMERATING;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (id <Enumerating>) reverseObjectEnumerator
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
return [[[ReverseEnumerator alloc] initWithCollection: self]
|
|
|
|
|
autorelease];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (void) withObjectsInRange: (IndexRange)aRange
|
|
|
|
|
invoke: (id <Invoking>)anInvocation
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
int i;
|
|
|
|
|
for (i = aRange.location; i < aRange.location + aRange.length; i++)
|
|
|
|
|
[anInvocation invokeWithObject: [self objectAtIndex: i]];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (void) withObjectsInReverseInvoke: (id <Invoking>)anInvocation
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
int i, count = [self count];
|
|
|
|
|
for (i = count-1; i >= 0; i--)
|
|
|
|
|
[anInvocation invokeWithObject: [self objectAtIndex: i]];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (void) withObjectsInReverseInvoke: (id <Invoking>)anInvocation
|
|
|
|
|
whileTrue:(BOOL *)flag
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
int i, count = [self count];
|
|
|
|
|
for (i = count-1; *flag && i >= 0; i--)
|
|
|
|
|
[anInvocation invokeWithObject: [self objectAtIndex: i]];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (void) makeObjectsPerformInReverse: (SEL)aSel
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
id o;
|
|
|
|
|
FOR_INDEXED_COLLECTION_REVERSE(self, o)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1998-09-28 20:38:02 +00:00
|
|
|
|
[o performSelector: aSel];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
1996-02-22 15:18:57 +00:00
|
|
|
|
END_FOR_INDEXED_COLLECTION_REVERSE(self);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (void) makeObjectsPerformInReverse: (SEL)aSel withObject: argObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
id o;
|
|
|
|
|
FOR_INDEXED_COLLECTION_REVERSE(self, o)
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1998-09-28 20:38:02 +00:00
|
|
|
|
[o performSelector: aSel withObject: argObject];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
1996-02-22 15:18:57 +00:00
|
|
|
|
END_FOR_INDEXED_COLLECTION_REVERSE(self);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
|
|
|
|
|
// LOW-LEVEL ENUMERATING;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- prevObjectWithEnumState: (void**)enumState
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-03-12 20:39:58 +00:00
|
|
|
|
/* *(int*)enumState is the index of the element that was returned
|
|
|
|
|
last time -prevObjectWithEnumState: or -nextObjectWithEnumState
|
|
|
|
|
was called. In -newEnumState, *(int*)enumState is initialized to
|
|
|
|
|
-2; The implementation of -newEnumState can be found below. */
|
|
|
|
|
|
|
|
|
|
/* If there are not objects in this collection, or we are being
|
|
|
|
|
asked for the object before the first object, return nil. */
|
1996-03-13 02:34:22 +00:00
|
|
|
|
if ([self isEmpty] || ((*(int*)enumState) == 0)
|
|
|
|
|
|| ((*(int*)enumState) == -1))
|
|
|
|
|
{
|
1996-03-18 13:47:14 +00:00
|
|
|
|
(*(int*)enumState) = -1;
|
1996-03-13 02:34:22 +00:00
|
|
|
|
return NO_OBJECT;
|
|
|
|
|
}
|
1996-03-12 20:39:58 +00:00
|
|
|
|
|
|
|
|
|
if (*(int*)enumState == -2)
|
|
|
|
|
/* enumState was just initialized by -newEnumState, start
|
|
|
|
|
at the end of the sequence. */
|
|
|
|
|
*(int*)enumState = [self count]-1;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
else
|
1996-03-13 02:34:22 +00:00
|
|
|
|
/* ...otherwise go the previous index. */
|
1996-03-12 20:39:58 +00:00
|
|
|
|
(*(int*)enumState)--;
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
return [self objectAtIndex:(*(unsigned*)enumState)];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
|
|
|
|
|
// COPYING;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- shallowCopyRange: (IndexRange)aRange
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
[self notImplemented: _cmd];
|
1996-03-12 20:39:58 +00:00
|
|
|
|
return nil;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- shallowCopyInReverse
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
[self notImplemented: _cmd];
|
1996-03-12 20:39:58 +00:00
|
|
|
|
return nil;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- shallowCopyInReverseRange: (IndexRange)aRange
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
[self notImplemented: _cmd];
|
1996-03-12 20:39:58 +00:00
|
|
|
|
return nil;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
|
|
|
|
|
// OVERRIDE SOME COLLECTION METHODS;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-03-12 20:39:58 +00:00
|
|
|
|
- (void*) newEnumState
|
|
|
|
|
{
|
|
|
|
|
return (void*) -2;
|
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- nextObjectWithEnumState: (void**)enumState
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-03-12 20:39:58 +00:00
|
|
|
|
/* *(int*)enumState is the index of the element that was returned
|
|
|
|
|
last time -prevObjectWithEnumState: or -nextObjectWithEnumState
|
|
|
|
|
was called. In -newEnumState, *(int*)enumState is initialized to
|
|
|
|
|
-2. */
|
|
|
|
|
|
|
|
|
|
/* If there are not objects in this collection, or we are being
|
|
|
|
|
asked for the object after the last object, return nil. */
|
1996-03-13 02:34:22 +00:00
|
|
|
|
if ([self isEmpty] || ((*(int*)enumState) >= (int)([self count]-1)))
|
|
|
|
|
{
|
|
|
|
|
(*(int*)enumState) = [self count];
|
|
|
|
|
return NO_OBJECT;
|
|
|
|
|
}
|
1996-03-12 20:39:58 +00:00
|
|
|
|
|
|
|
|
|
if (*(int*)enumState == -2)
|
|
|
|
|
/* enumState was just initialized by -newEnumState, start
|
|
|
|
|
at the beginning of the sequence. */
|
|
|
|
|
*(int*)enumState = 0;
|
|
|
|
|
else
|
|
|
|
|
/* ...otherwise go the next index. */
|
|
|
|
|
(*(int*)enumState)++;
|
|
|
|
|
|
|
|
|
|
return [self objectAtIndex:(*(unsigned*)enumState)];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
/* is this what we want? */
|
|
|
|
|
- (BOOL) isEqual: anObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
if (self == anObject)
|
|
|
|
|
return YES;
|
|
|
|
|
if ([anObject class] == [self class]
|
|
|
|
|
&& [self count] != [anObject count]
|
|
|
|
|
&& [self contentsEqualInOrder: anObject] )
|
|
|
|
|
return YES;
|
|
|
|
|
else
|
|
|
|
|
return NO;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
@end
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
|
|
|
|
|
@implementation IndexedCollection
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
+ (void) initialize
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-03-11 17:02:02 +00:00
|
|
|
|
if (self == [IndexedCollection class])
|
1996-02-22 15:18:57 +00:00
|
|
|
|
class_add_behavior(self, [Collection class]);
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
|
|
|
|
|
// REPLACING;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-03-12 20:39:58 +00:00
|
|
|
|
- (void) replaceObjectAtIndex: (unsigned)index withObject: newObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
[self subclassResponsibility: _cmd];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
|
|
|
|
|
// REMOVING;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (void) removeObjectAtIndex: (unsigned)index
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
[self subclassResponsibility: _cmd];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (void) removeFirstObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
[self removeObjectAtIndex: 0];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (void) removeLastObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
[self removeObjectAtIndex: [self count]-1];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (void) removeRange: (IndexRange)aRange
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-03-12 20:39:58 +00:00
|
|
|
|
int count = aRange.length;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
CHECK_INDEX_RANGE_ERROR(aRange.location, [self count]);
|
|
|
|
|
CHECK_INDEX_RANGE_ERROR(aRange.location+aRange.length-1, [self count]);
|
|
|
|
|
while (count--)
|
|
|
|
|
[self removeObjectAtIndex: aRange.location];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
|
|
|
|
|
// SORTING;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (void) sortContents
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
[self notImplemented: _cmd];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (void) sortAddObject: newObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-02-22 15:18:57 +00:00
|
|
|
|
[self notImplemented: _cmd];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
// OVERRIDE SOME COLLECTION METHODS;
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (void) removeObject: anObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-03-30 22:21:11 +00:00
|
|
|
|
unsigned index;
|
1996-03-30 19:04:35 +00:00
|
|
|
|
|
|
|
|
|
/* Retain the object. Yuck, but necessary in case the array holds
|
|
|
|
|
the last reference to anObject. */
|
|
|
|
|
/* xxx Is there an alternative to this expensive retain/release? */
|
|
|
|
|
[anObject retain];
|
|
|
|
|
|
|
|
|
|
for (index = [self indexOfObject: anObject];
|
|
|
|
|
index != NO_INDEX;
|
|
|
|
|
index = [self indexOfObject: anObject])
|
1996-02-22 15:18:57 +00:00
|
|
|
|
[self removeObjectAtIndex: index];
|
1996-03-30 19:04:35 +00:00
|
|
|
|
|
|
|
|
|
[anObject release];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
- (void) replaceObject: oldObject withObject: newObject
|
1994-11-04 16:29:24 +00:00
|
|
|
|
{
|
1996-03-30 22:21:11 +00:00
|
|
|
|
unsigned index;
|
1996-03-30 19:04:35 +00:00
|
|
|
|
|
|
|
|
|
/* Retain the object. Yuck, but necessary in case the array holds
|
|
|
|
|
the last reference to anObject. */
|
|
|
|
|
/* xxx Is there an alternative to this expensive retain/release? */
|
|
|
|
|
[oldObject retain];
|
|
|
|
|
|
|
|
|
|
for (index = [self indexOfObject: oldObject];
|
|
|
|
|
index != NO_INDEX;
|
|
|
|
|
index = [self indexOfObject: oldObject])
|
|
|
|
|
[self replaceObjectAtIndex: index withObject: newObject];
|
|
|
|
|
|
|
|
|
|
[oldObject release];
|
1994-11-04 16:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-02-22 15:18:57 +00:00
|
|
|
|
@end
|
1994-11-04 16:29:24 +00:00
|
|
|
|
|
|
|
|
|
|