2001-12-17 14:31:42 +00:00
|
|
|
|
/** NSArray - Array object to hold other objects.
|
2015-06-01 17:43:37 +00:00
|
|
|
|
Copyright (C) 1995-2015 Free Software Foundation, Inc.
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
1996-04-17 20:17:45 +00:00
|
|
|
|
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
From skeleton by: Adam Fedor <fedor@boulder.colorado.edu>
|
1996-04-16 23:22:08 +00:00
|
|
|
|
Created: March 1995
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
1998-02-03 14:20:00 +00:00
|
|
|
|
Rewrite by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
2005-02-22 11:22:44 +00:00
|
|
|
|
January 1998 - new methods and changes as documented for Rhapsody plus
|
1998-02-03 14:20:00 +00:00
|
|
|
|
changes of array indices to type unsigned, plus major efficiency hacks.
|
|
|
|
|
|
1996-05-12 00:56:10 +00:00
|
|
|
|
This file is part of the GNUstep Base Library.
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
1995-04-03 22:59:20 +00:00
|
|
|
|
This library is free software; you can redistribute it and/or
|
2007-09-14 11:36:11 +00:00
|
|
|
|
modify it under the terms of the GNU Lesser General Public
|
1995-04-03 22:59:20 +00:00
|
|
|
|
License as published by the Free Software Foundation; either
|
2008-06-08 10:38:33 +00:00
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
1995-04-03 22:59:20 +00:00
|
|
|
|
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
|
2019-12-09 23:36:00 +00:00
|
|
|
|
Lesser General Public License for more details.
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2007-09-14 11:36:11 +00:00
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
1995-04-03 22:59:20 +00:00
|
|
|
|
License along with this library; if not, write to the Free
|
2024-11-07 13:37:59 +00:00
|
|
|
|
Software Foundation, Inc., 31 Milk Street #960789 Boston, MA 02196 USA.
|
2001-12-18 16:54:15 +00:00
|
|
|
|
|
|
|
|
|
<title>NSArray class reference</title>
|
|
|
|
|
$Date$ $Revision$
|
1995-04-04 16:01:04 +00:00
|
|
|
|
*/
|
1995-04-03 22:59:20 +00:00
|
|
|
|
|
2010-02-19 08:12:46 +00:00
|
|
|
|
#import "common.h"
|
2007-11-29 20:53:26 +00:00
|
|
|
|
#import "Foundation/NSArray.h"
|
|
|
|
|
#import "Foundation/NSEnumerator.h"
|
|
|
|
|
#import "Foundation/NSCoder.h"
|
|
|
|
|
#import "Foundation/NSData.h"
|
|
|
|
|
#import "Foundation/NSRange.h"
|
|
|
|
|
#import "Foundation/NSException.h"
|
|
|
|
|
#import "Foundation/NSAutoreleasePool.h"
|
|
|
|
|
#import "Foundation/NSThread.h"
|
|
|
|
|
#import "Foundation/NSMapTable.h"
|
|
|
|
|
#import "Foundation/NSLock.h"
|
|
|
|
|
#import "Foundation/NSValue.h"
|
|
|
|
|
#import "Foundation/NSNull.h"
|
2008-03-16 06:56:52 +00:00
|
|
|
|
#import "Foundation/NSKeyValueCoding.h"
|
|
|
|
|
#import "Foundation/NSSet.h"
|
2007-11-29 20:53:26 +00:00
|
|
|
|
#import "Foundation/NSUserDefaults.h"
|
|
|
|
|
#import "Foundation/NSIndexSet.h"
|
2004-01-27 21:51:33 +00:00
|
|
|
|
// For private method _decodeArrayOfObjectsForKey:
|
2007-11-29 20:53:26 +00:00
|
|
|
|
#import "Foundation/NSKeyedArchiver.h"
|
|
|
|
|
#import "GSPrivate.h"
|
2018-04-12 17:21:19 +00:00
|
|
|
|
#import "GSPThread.h"
|
2009-12-27 15:25:12 +00:00
|
|
|
|
#import "GSFastEnumeration.h"
|
2012-03-27 17:05:19 +00:00
|
|
|
|
#import "GSDispatch.h"
|
2012-09-19 13:31:09 +00:00
|
|
|
|
#import "GSSorting.h"
|
2012-09-19 14:20:01 +00:00
|
|
|
|
|
2006-10-09 17:21:51 +00:00
|
|
|
|
static BOOL GSMacOSXCompatiblePropertyLists(void)
|
|
|
|
|
{
|
2006-10-20 10:56:27 +00:00
|
|
|
|
if (GSPrivateDefaultsFlag(NSWriteOldStylePropertyLists) == YES)
|
2006-10-09 17:21:51 +00:00
|
|
|
|
return NO;
|
2006-10-20 10:56:27 +00:00
|
|
|
|
return GSPrivateDefaultsFlag(GSMacOSXCompatible);
|
2006-10-09 17:21:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-27 13:56:00 +00:00
|
|
|
|
extern void GSPropertyListMake(id,NSDictionary*,BOOL,BOOL,unsigned,id*);
|
2002-11-09 06:45:31 +00:00
|
|
|
|
|
2005-07-08 11:48:37 +00:00
|
|
|
|
@interface NSArrayEnumerator : NSEnumerator
|
|
|
|
|
{
|
|
|
|
|
NSArray *array;
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger pos;
|
2005-07-08 11:48:37 +00:00
|
|
|
|
IMP get;
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger (*cnt)(NSArray*, SEL);
|
2005-07-08 11:48:37 +00:00
|
|
|
|
}
|
|
|
|
|
- (id) initWithArray: (NSArray*)anArray;
|
|
|
|
|
@end
|
|
|
|
|
@interface NSArrayEnumeratorReverse : NSArrayEnumerator
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
1995-07-01 18:38:03 +00:00
|
|
|
|
|
2001-01-08 16:45:36 +00:00
|
|
|
|
static Class NSArrayClass;
|
|
|
|
|
static Class GSArrayClass;
|
|
|
|
|
static Class NSMutableArrayClass;
|
|
|
|
|
static Class GSMutableArrayClass;
|
|
|
|
|
static Class GSPlaceholderArrayClass;
|
1995-07-01 18:38:03 +00:00
|
|
|
|
|
2001-01-08 16:45:36 +00:00
|
|
|
|
static GSPlaceholderArray *defaultPlaceholderArray;
|
|
|
|
|
static NSMapTable *placeholderMap;
|
2021-07-28 14:17:47 +00:00
|
|
|
|
static gs_mutex_t placeholderLock = GS_MUTEX_INIT_STATIC;
|
2018-04-12 17:21:19 +00:00
|
|
|
|
|
2000-10-30 18:00:27 +00:00
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
2003-04-06 17:20:04 +00:00
|
|
|
|
* A simple, low overhead, ordered container for objects. All the objects
|
|
|
|
|
* in the container are retained by it. The container may not contain nil
|
|
|
|
|
* (though it may contain [NSNull+null]).
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
1996-03-31 22:23:37 +00:00
|
|
|
|
@implementation NSArray
|
1995-07-01 18:38:03 +00:00
|
|
|
|
|
2000-10-30 18:00:27 +00:00
|
|
|
|
static SEL addSel;
|
|
|
|
|
static SEL appSel;
|
|
|
|
|
static SEL countSel;
|
|
|
|
|
static SEL eqSel;
|
|
|
|
|
static SEL oaiSel;
|
|
|
|
|
static SEL remSel;
|
|
|
|
|
static SEL rlSel;
|
|
|
|
|
|
2011-06-19 13:34:17 +00:00
|
|
|
|
+ (void) atExit
|
|
|
|
|
{
|
2024-11-19 18:10:07 +00:00
|
|
|
|
if ([NSObject shouldCleanUp])
|
2024-11-14 18:57:05 +00:00
|
|
|
|
{
|
2024-11-19 18:10:07 +00:00
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
/* The default placeholder array overrides -dealloc so we must get rid of
|
|
|
|
|
* it directly.
|
|
|
|
|
*/
|
|
|
|
|
o = defaultPlaceholderArray;
|
|
|
|
|
defaultPlaceholderArray = nil;
|
|
|
|
|
NSDeallocateObject(o);
|
|
|
|
|
|
|
|
|
|
/* Deallocate all the placeholders in the map before destroying it.
|
|
|
|
|
*/
|
|
|
|
|
GS_MUTEX_LOCK(placeholderLock);
|
|
|
|
|
if (placeholderMap)
|
|
|
|
|
{
|
|
|
|
|
NSMapEnumerator mEnum = NSEnumerateMapTable(placeholderMap);
|
|
|
|
|
Class c;
|
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
while (NSNextMapEnumeratorPair(&mEnum, (void *)&c, (void *)&o))
|
|
|
|
|
{
|
|
|
|
|
NSDeallocateObject(o);
|
|
|
|
|
}
|
|
|
|
|
NSEndMapTableEnumeration(&mEnum);
|
|
|
|
|
DESTROY(placeholderMap);
|
|
|
|
|
}
|
|
|
|
|
GS_MUTEX_UNLOCK(placeholderLock);
|
2024-11-14 18:57:05 +00:00
|
|
|
|
}
|
2011-06-19 13:34:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-03-31 22:23:37 +00:00
|
|
|
|
+ (void) initialize
|
1995-07-01 18:38:03 +00:00
|
|
|
|
{
|
1996-03-31 22:23:37 +00:00
|
|
|
|
if (self == [NSArray class])
|
|
|
|
|
{
|
2000-10-30 18:00:27 +00:00
|
|
|
|
[self setVersion: 1];
|
|
|
|
|
|
|
|
|
|
addSel = @selector(addObject:);
|
|
|
|
|
appSel = @selector(appendString:);
|
|
|
|
|
countSel = @selector(count);
|
|
|
|
|
eqSel = @selector(isEqual:);
|
|
|
|
|
oaiSel = @selector(objectAtIndex:);
|
|
|
|
|
remSel = @selector(removeObjectAtIndex:);
|
|
|
|
|
rlSel = @selector(removeLastObject);
|
|
|
|
|
|
2001-01-08 16:45:36 +00:00
|
|
|
|
NSArrayClass = [NSArray class];
|
|
|
|
|
NSMutableArrayClass = [NSMutableArray class];
|
|
|
|
|
GSArrayClass = [GSArray class];
|
|
|
|
|
GSMutableArrayClass = [GSMutableArray class];
|
|
|
|
|
GSPlaceholderArrayClass = [GSPlaceholderArray class];
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Set up infrastructure for placeholder arrays.
|
|
|
|
|
*/
|
|
|
|
|
defaultPlaceholderArray = (GSPlaceholderArray*)
|
|
|
|
|
NSAllocateObject(GSPlaceholderArrayClass, 0, NSDefaultMallocZone());
|
|
|
|
|
placeholderMap = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
|
|
|
|
|
NSNonRetainedObjectMapValueCallBacks, 0);
|
2011-06-19 13:34:17 +00:00
|
|
|
|
[self registerAtExit];
|
1996-03-31 22:23:37 +00:00
|
|
|
|
}
|
1995-07-01 18:38:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
+ (id) allocWithZone: (NSZone*)z
|
1995-06-30 13:45:13 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
if (self == NSArrayClass)
|
2000-08-07 22:00:31 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
/*
|
|
|
|
|
* For a constant array, we return a placeholder object that can
|
|
|
|
|
* be converted to a real object when its initialisation method
|
|
|
|
|
* is called.
|
|
|
|
|
*/
|
|
|
|
|
if (z == NSDefaultMallocZone() || z == 0)
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* As a special case, we can return a placeholder for an array
|
|
|
|
|
* in the default malloc zone extremely efficiently.
|
|
|
|
|
*/
|
|
|
|
|
return defaultPlaceholderArray;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
id obj;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* For anything other than the default zone, we need to
|
|
|
|
|
* locate the correct placeholder in the (lock protected)
|
|
|
|
|
* table of placeholders.
|
|
|
|
|
*/
|
2021-07-28 14:17:47 +00:00
|
|
|
|
GS_MUTEX_LOCK(placeholderLock);
|
2001-01-08 16:45:36 +00:00
|
|
|
|
obj = (id)NSMapGet(placeholderMap, (void*)z);
|
2024-11-14 18:57:05 +00:00
|
|
|
|
if (obj == nil && NO == [NSObject isExiting])
|
2001-01-08 16:45:36 +00:00
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* There is no placeholder object for this zone, so we
|
|
|
|
|
* create a new one and use that.
|
|
|
|
|
*/
|
|
|
|
|
obj = (id)NSAllocateObject(GSPlaceholderArrayClass, 0, z);
|
|
|
|
|
NSMapInsert(placeholderMap, (void*)z, (void*)obj);
|
|
|
|
|
}
|
2021-07-28 14:17:47 +00:00
|
|
|
|
GS_MUTEX_UNLOCK(placeholderLock);
|
2001-01-08 16:45:36 +00:00
|
|
|
|
return obj;
|
|
|
|
|
}
|
2000-08-07 22:00:31 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return NSAllocateObject(self, 0, z);
|
|
|
|
|
}
|
1995-06-30 13:45:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an empty autoreleased array.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
+ (id) array
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
o = [self allocWithZone: NSDefaultMallocZone()];
|
|
|
|
|
o = [o initWithObjects: (id*)0 count: 0];
|
|
|
|
|
return AUTORELEASE(o);
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a new autoreleased NSArray instance containing all the objects from
|
|
|
|
|
* array, in the same order as the original.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
+ (id) arrayWithArray: (NSArray*)array
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
o = [self allocWithZone: NSDefaultMallocZone()];
|
|
|
|
|
o = [o initWithArray: array];
|
|
|
|
|
return AUTORELEASE(o);
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* Returns an autoreleased array based upon the file. The new array is
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* created using [NSObject+allocWithZone:] and initialised using the
|
|
|
|
|
* [NSArray-initWithContentsOfFile:] method. See the documentation for those
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* methods for more detail.
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
+ (id) arrayWithContentsOfFile: (NSString*)file
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
o = [self allocWithZone: NSDefaultMallocZone()];
|
|
|
|
|
o = [o initWithContentsOfFile: file];
|
|
|
|
|
return AUTORELEASE(o);
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-15 16:35:11 +00:00
|
|
|
|
/**
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* Returns an autoreleased array from the contents of aURL. The new array is
|
2005-11-28 15:41:35 +00:00
|
|
|
|
* created using [NSObject+allocWithZone:] and initialised using the
|
2003-07-15 16:35:11 +00:00
|
|
|
|
* -initWithContentsOfURL: method. See the documentation for those
|
|
|
|
|
* methods for more detail.
|
|
|
|
|
*/
|
|
|
|
|
+ (id) arrayWithContentsOfURL: (NSURL*)aURL
|
|
|
|
|
{
|
|
|
|
|
id o;
|
|
|
|
|
|
|
|
|
|
o = [self allocWithZone: NSDefaultMallocZone()];
|
|
|
|
|
o = [o initWithContentsOfURL: aURL];
|
|
|
|
|
return AUTORELEASE(o);
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an autoreleased array containing anObject.
|
|
|
|
|
*/
|
2000-10-30 18:00:27 +00:00
|
|
|
|
+ (id) arrayWithObject: (id)anObject
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2000-10-30 18:00:27 +00:00
|
|
|
|
id o;
|
|
|
|
|
|
2001-01-08 16:45:36 +00:00
|
|
|
|
o = [self allocWithZone: NSDefaultMallocZone()];
|
2000-10-30 18:00:27 +00:00
|
|
|
|
o = [o initWithObjects: &anObject count: 1];
|
|
|
|
|
return AUTORELEASE(o);
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an autoreleased array containing the list
|
|
|
|
|
* of objects, preserving order.
|
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
+ (id) arrayWithObjects: firstObject, ...
|
1998-08-01 21:34:58 +00:00
|
|
|
|
{
|
2003-04-06 17:20:04 +00:00
|
|
|
|
id a = [self allocWithZone: NSDefaultMallocZone()];
|
|
|
|
|
|
|
|
|
|
GS_USEIDLIST(firstObject,
|
2005-02-22 11:22:44 +00:00
|
|
|
|
a = [a initWithObjects: __objects count: __count]);
|
2003-04-06 17:20:04 +00:00
|
|
|
|
return AUTORELEASE(a);
|
1998-08-01 21:34:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an autoreleased array containing the specified
|
|
|
|
|
* objects, preserving order.
|
|
|
|
|
*/
|
2011-07-22 16:07:23 +00:00
|
|
|
|
+ (id) arrayWithObjects: (const id[])objects count: (NSUInteger)count
|
1998-08-01 21:34:58 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
|
initWithObjects: objects count: count]);
|
1998-08-01 21:34:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an autoreleased array formed from the contents of
|
|
|
|
|
* the receiver and adding anObject as the last item.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (NSArray*) arrayByAddingObject: (id)anObject
|
1996-03-30 19:14:43 +00:00
|
|
|
|
{
|
|
|
|
|
id na;
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger c = [self count];
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (anObject == nil)
|
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
|
format: @"Attempt to add nil to an array"];
|
|
|
|
|
if (c == 0)
|
2003-10-14 09:00:42 +00:00
|
|
|
|
{
|
|
|
|
|
na = [[GSArrayClass allocWithZone: NSDefaultMallocZone()]
|
|
|
|
|
initWithObjects: &anObject count: 1];
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_BEGINIDBUF(objects, c+1);
|
1998-10-08 13:46:53 +00:00
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
[self getObjects: objects];
|
|
|
|
|
objects[c] = anObject;
|
2001-01-08 16:45:36 +00:00
|
|
|
|
na = [[GSArrayClass allocWithZone: NSDefaultMallocZone()]
|
1999-09-14 19:24:58 +00:00
|
|
|
|
initWithObjects: objects count: c+1];
|
2003-10-14 09:00:42 +00:00
|
|
|
|
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_ENDIDBUF();
|
1999-09-14 19:24:58 +00:00
|
|
|
|
}
|
1999-06-30 21:13:19 +00:00
|
|
|
|
return AUTORELEASE(na);
|
1996-03-30 19:14:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a new array which is the concatenation of self and
|
|
|
|
|
* otherArray (in this precise order).
|
|
|
|
|
*/
|
1996-03-30 19:14:43 +00:00
|
|
|
|
- (NSArray*) arrayByAddingObjectsFromArray: (NSArray*)anotherArray
|
|
|
|
|
{
|
1999-06-04 16:05:45 +00:00
|
|
|
|
id na;
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger c;
|
|
|
|
|
NSUInteger l;
|
|
|
|
|
NSUInteger e;
|
1998-10-08 13:46:53 +00:00
|
|
|
|
|
1999-06-04 16:05:45 +00:00
|
|
|
|
c = [self count];
|
|
|
|
|
l = [anotherArray count];
|
2008-07-06 09:18:30 +00:00
|
|
|
|
e = c + l;
|
1999-06-04 16:05:45 +00:00
|
|
|
|
|
2004-09-10 15:10:54 +00:00
|
|
|
|
{
|
2008-07-06 09:18:30 +00:00
|
|
|
|
GS_BEGINIDBUF(objects, e);
|
2003-10-14 09:00:42 +00:00
|
|
|
|
|
2004-09-10 15:10:54 +00:00
|
|
|
|
[self getObjects: objects];
|
2008-07-06 09:18:30 +00:00
|
|
|
|
if ([anotherArray isProxy])
|
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i = c;
|
|
|
|
|
NSUInteger j = 0;
|
2008-07-06 09:18:30 +00:00
|
|
|
|
|
|
|
|
|
while (i < e)
|
|
|
|
|
{
|
|
|
|
|
objects[i++] = [anotherArray objectAtIndex: j++];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
[anotherArray getObjects: &objects[c]];
|
|
|
|
|
}
|
|
|
|
|
na = [NSArrayClass arrayWithObjects: objects count: e];
|
2003-10-14 09:00:42 +00:00
|
|
|
|
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_ENDIDBUF();
|
|
|
|
|
}
|
2003-10-14 09:00:42 +00:00
|
|
|
|
|
1999-06-04 16:05:45 +00:00
|
|
|
|
return na;
|
1996-03-30 19:14:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* Returns the abstract class ... arrays are coded as abstract arrays.
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (Class) classForCoder
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
return NSArrayClass;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns YES if anObject belongs to self. No otherwise.<br />
|
2005-11-28 15:41:35 +00:00
|
|
|
|
* The [NSObject-isEqual:] method of anObject is used to test for equality.
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
|
|
|
|
- (BOOL) containsObject: (id)anObject
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
return ([self indexOfObject: anObject] != NSNotFound);
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
2003-01-20 17:18:06 +00:00
|
|
|
|
* Returns a new copy of the receiver.<br />
|
|
|
|
|
* The default abstract implementation of a copy is to use the
|
|
|
|
|
* -initWithArray:copyItems: method with the flag set to YES.<br />
|
|
|
|
|
* Immutable subclasses generally simply retain and return the receiver.
|
2002-11-04 08:06:48 +00:00
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (id) copyWithZone: (NSZone*)zone
|
1998-05-13 19:25:38 +00:00
|
|
|
|
{
|
2003-01-20 17:18:06 +00:00
|
|
|
|
NSArray *copy = [NSArrayClass allocWithZone: zone];
|
|
|
|
|
|
|
|
|
|
return [copy initWithArray: self copyItems: YES];
|
1998-05-13 19:25:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
2009-02-23 20:42:32 +00:00
|
|
|
|
- (NSUInteger) count
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
[self subclassResponsibility: _cmd];
|
|
|
|
|
return 0;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-03-27 17:05:19 +00:00
|
|
|
|
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state
|
2011-07-24 13:09:22 +00:00
|
|
|
|
objects: (__unsafe_unretained id[])stackbuf
|
2009-04-19 10:03:18 +00:00
|
|
|
|
count: (NSUInteger)len
|
|
|
|
|
{
|
|
|
|
|
NSInteger count;
|
|
|
|
|
|
2014-01-09 09:00:24 +00:00
|
|
|
|
/* In a mutable subclass, the mutationsPtr should be set to point to a
|
|
|
|
|
* value (unsigned long) which will be changed (incremented) whenever
|
|
|
|
|
* the container is mutated (content added, removed, re-ordered).
|
|
|
|
|
* This is cached in the caller at the start and compared at each
|
2009-04-19 10:03:18 +00:00
|
|
|
|
* iteration. If it changes during the iteration then
|
|
|
|
|
* objc_enumerationMutation() will be called, throwing an exception.
|
2014-01-09 09:00:24 +00:00
|
|
|
|
* The abstract base class implementation points to a fixed value
|
2014-01-09 09:55:36 +00:00
|
|
|
|
* (the enumeration state pointer should exist and be unchanged for as
|
|
|
|
|
* long as the enumeration process runs), which is fine for enumerating
|
|
|
|
|
* an immutable array.
|
2009-04-19 10:03:18 +00:00
|
|
|
|
*/
|
2014-01-09 09:55:36 +00:00
|
|
|
|
state->mutationsPtr = (unsigned long *)&state->mutationsPtr;
|
2014-01-09 09:00:24 +00:00
|
|
|
|
count = MIN(len, [self count] - state->state);
|
2009-04-19 10:03:18 +00:00
|
|
|
|
/* 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)
|
|
|
|
|
{
|
|
|
|
|
IMP imp = [self methodForSelector: @selector(objectAtIndex:)];
|
|
|
|
|
int p = state->state;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++, p++)
|
|
|
|
|
{
|
|
|
|
|
stackbuf[i] = (*imp)(self, @selector(objectAtIndex:), p);
|
|
|
|
|
}
|
|
|
|
|
state->state += count;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
count = 0;
|
|
|
|
|
}
|
|
|
|
|
state->itemsPtr = stackbuf;
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Encodes the receiver for storing to archive or sending over an
|
|
|
|
|
* [NSConnection].
|
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (void) encodeWithCoder: (NSCoder*)aCoder
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger count = [self count];
|
1998-01-19 15:20:15 +00:00
|
|
|
|
|
2004-01-28 07:33:20 +00:00
|
|
|
|
if ([aCoder allowsKeyedCoding])
|
|
|
|
|
{
|
|
|
|
|
/* HACK ... MacOS-X seems to code differently if the coder is an
|
|
|
|
|
* actual instance of NSKeyedArchiver
|
|
|
|
|
*/
|
|
|
|
|
if ([aCoder class] == [NSKeyedArchiver class])
|
|
|
|
|
{
|
|
|
|
|
[(NSKeyedArchiver*)aCoder _encodeArrayOfObjects: self
|
|
|
|
|
forKey: @"NS.objects"];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i;
|
1998-10-08 13:46:53 +00:00
|
|
|
|
|
2004-01-28 07:33:20 +00:00
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
|
{
|
|
|
|
|
NSString *key;
|
|
|
|
|
|
2015-08-05 08:34:49 +00:00
|
|
|
|
key = [NSString stringWithFormat: @"NS.object.%lu", (unsigned long)i];
|
2004-01-28 07:33:20 +00:00
|
|
|
|
[(NSKeyedArchiver*)aCoder encodeObject: [self objectAtIndex: i]
|
|
|
|
|
forKey: key];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
2001-01-08 16:45:36 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
unsigned items = (unsigned)count;
|
1999-06-04 16:05:45 +00:00
|
|
|
|
|
2015-06-04 09:18:52 +00:00
|
|
|
|
[aCoder encodeValueOfObjCType: @encode(unsigned)
|
|
|
|
|
at: &items];
|
2004-01-28 07:33:20 +00:00
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_BEGINIDBUF(a, count);
|
2004-01-28 07:33:20 +00:00
|
|
|
|
|
|
|
|
|
[self getObjects: a];
|
|
|
|
|
[aCoder encodeArrayOfObjCType: @encode(id)
|
|
|
|
|
count: count
|
|
|
|
|
at: a];
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_ENDIDBUF();
|
2004-01-28 07:33:20 +00:00
|
|
|
|
}
|
2001-01-08 16:45:36 +00:00
|
|
|
|
}
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Copies the objects from the receiver to aBuffer, which must be
|
|
|
|
|
* an area of memory large enough to hold them.
|
|
|
|
|
*/
|
2011-07-24 13:09:22 +00:00
|
|
|
|
- (void) getObjects: (__unsafe_unretained id[])aBuffer
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i, c = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
1999-06-04 16:05:45 +00:00
|
|
|
|
|
1998-01-19 15:20:15 +00:00
|
|
|
|
for (i = 0; i < c; i++)
|
1999-09-14 19:24:58 +00:00
|
|
|
|
aBuffer[i] = (*get)(self, oaiSel, i);
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Copies the objects from the range aRange of the receiver to aBuffer,
|
|
|
|
|
* which must be an area of memory large enough to hold them.
|
|
|
|
|
*/
|
2011-07-24 13:09:22 +00:00
|
|
|
|
- (void) getObjects: (__unsafe_unretained id[])aBuffer range: (NSRange)aRange
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i, j = 0, c = [self count], e = aRange.location + aRange.length;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
1999-06-04 16:05:45 +00:00
|
|
|
|
|
1999-06-21 08:30:26 +00:00
|
|
|
|
GS_RANGE_CHECK(aRange, c);
|
1999-06-04 16:05:45 +00:00
|
|
|
|
|
1999-05-11 13:05:24 +00:00
|
|
|
|
for (i = aRange.location; i < e; i++)
|
1999-09-14 19:24:58 +00:00
|
|
|
|
aBuffer[j++] = (*get)(self, oaiSel, i);
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
1995-04-03 22:59:20 +00:00
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* Returns the same value as -count
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
|
- (NSUInteger) hash
|
1998-10-27 08:12:49 +00:00
|
|
|
|
{
|
1999-06-04 16:05:45 +00:00
|
|
|
|
return [self count];
|
1998-10-27 08:12:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the index of the specified object in the receiver, or
|
|
|
|
|
* NSNotFound if the object is not present.
|
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
|
- (NSUInteger) indexOfObjectIdenticalTo: (id)anObject
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger c = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
|
|
|
|
if (c > 0)
|
|
|
|
|
{
|
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
|
|
|
|
for (i = 0; i < c; i++)
|
|
|
|
|
if (anObject == (*get)(self, oaiSel, i))
|
|
|
|
|
return i;
|
|
|
|
|
}
|
1995-09-21 17:42:46 +00:00
|
|
|
|
return NSNotFound;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the index of the specified object in the range of the receiver,
|
|
|
|
|
* or NSNotFound if the object is not present.
|
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
|
- (NSUInteger) indexOfObjectIdenticalTo: anObject inRange: (NSRange)aRange
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i, e = aRange.location + aRange.length, c = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
1999-06-04 16:05:45 +00:00
|
|
|
|
|
1999-06-21 08:30:26 +00:00
|
|
|
|
GS_RANGE_CHECK(aRange, c);
|
1999-06-04 16:05:45 +00:00
|
|
|
|
|
1998-01-19 15:20:15 +00:00
|
|
|
|
for (i = aRange.location; i < e; i++)
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (anObject == (*get)(self, oaiSel, i))
|
1998-01-19 15:20:15 +00:00
|
|
|
|
return i;
|
|
|
|
|
return NSNotFound;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the index of the first object found in the receiver
|
2005-11-28 15:41:35 +00:00
|
|
|
|
* which is equal to anObject (using anObject's [NSObject-isEqual:] method).
|
2002-06-06 14:02:59 +00:00
|
|
|
|
* Returns NSNotFound on failure.
|
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
|
- (NSUInteger) indexOfObject: (id)anObject
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger c = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
|
|
|
|
if (c > 0 && anObject != nil)
|
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
1995-09-21 17:42:46 +00:00
|
|
|
|
return NSNotFound;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the index of the first object found in aRange of receiver
|
2005-11-28 15:41:35 +00:00
|
|
|
|
* which is equal to anObject (using anObject's [NSObject-isEqual:] method).
|
2002-06-06 14:02:59 +00:00
|
|
|
|
* Returns NSNotFound on failure.
|
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
|
- (NSUInteger) indexOfObject: (id)anObject inRange: (NSRange)aRange
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i, e = aRange.location + aRange.length, c = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
|
|
|
|
BOOL (*eq)(id, SEL, id)
|
|
|
|
|
= (BOOL (*)(id, SEL, id))[anObject methodForSelector: eqSel];
|
1999-06-04 16:05:45 +00:00
|
|
|
|
|
1999-06-21 08:30:26 +00:00
|
|
|
|
GS_RANGE_CHECK(aRange, c);
|
1999-06-04 16:05:45 +00:00
|
|
|
|
|
1998-01-19 15:20:15 +00:00
|
|
|
|
for (i = aRange.location; i < e; i++)
|
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if ((*eq)(anObject, eqSel, (*get)(self, oaiSel, i)) == YES)
|
1998-01-19 15:20:15 +00:00
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
return NSNotFound;
|
|
|
|
|
}
|
|
|
|
|
|
2004-09-07 05:43:20 +00:00
|
|
|
|
/**
|
|
|
|
|
* <p>In MacOS-X class clusters do not have designated initialisers,
|
|
|
|
|
* and there is a general rule that -init is treated as the designated
|
|
|
|
|
* initialiser of the class cluster, but that other intitialisers
|
|
|
|
|
* may not work s expected an would need to be individually overridden
|
|
|
|
|
* in any subclass.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>GNUstep tries to make it easier to subclass a class cluster,
|
|
|
|
|
* by making class clusters follow the same convention as normal
|
|
|
|
|
* classes, so the designated initialiser is the <em>richest</em>
|
|
|
|
|
* initialiser. This means that all other initialisers call the
|
|
|
|
|
* documented designated initialiser (which calls -init only for
|
|
|
|
|
* MacOS-X compatibility), and anyone writing a subclass only needs
|
|
|
|
|
* to override that one initialiser in order to have all the other
|
|
|
|
|
* ones work.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>For MacOS-X compatibility, you may also need to override various
|
|
|
|
|
* other initialisers. Exactly which ones, you will need to determine
|
|
|
|
|
* by trial on a MacOS-X system ... and may vary between releases of
|
|
|
|
|
* MacOS-X. So to be safe, on MacOS-X you probably need to re-implement
|
|
|
|
|
* <em>all</em> the class cluster initialisers you might use in conjunction
|
|
|
|
|
* with your subclass.
|
|
|
|
|
* </p>
|
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (id) init
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2004-09-07 05:43:20 +00:00
|
|
|
|
self = [super init];
|
|
|
|
|
return self;
|
2001-01-08 16:45:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
2002-08-27 09:37:58 +00:00
|
|
|
|
* Initialize the receiver with the contents of array.
|
|
|
|
|
* The order of array is preserved.<br />
|
|
|
|
|
* If shouldCopy is YES then the objects are copied
|
|
|
|
|
* rather than simply retained.<br />
|
|
|
|
|
* Invokes -initWithObjects:count:
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
2002-08-27 09:37:58 +00:00
|
|
|
|
- (id) initWithArray: (NSArray*)array copyItems: (BOOL)shouldCopy
|
2001-01-08 16:45:36 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger c = [array count];
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_BEGINIDBUF(objects, c);
|
2001-01-08 16:45:36 +00:00
|
|
|
|
|
2008-07-06 09:18:30 +00:00
|
|
|
|
if ([array isProxy])
|
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i;
|
2008-07-06 09:18:30 +00:00
|
|
|
|
|
|
|
|
|
for (i = 0; i < c; i++)
|
|
|
|
|
{
|
|
|
|
|
objects[i] = [array objectAtIndex: i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
[array getObjects: objects];
|
|
|
|
|
}
|
2002-08-27 09:37:58 +00:00
|
|
|
|
if (shouldCopy == YES)
|
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i;
|
2001-01-08 16:45:36 +00:00
|
|
|
|
|
2002-08-27 09:37:58 +00:00
|
|
|
|
for (i = 0; i < c; i++)
|
|
|
|
|
{
|
|
|
|
|
objects[i] = [objects[i] copy];
|
|
|
|
|
}
|
|
|
|
|
self = [self initWithObjects: objects count: c];
|
|
|
|
|
while (i > 0)
|
|
|
|
|
{
|
|
|
|
|
[objects[--i] release];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
self = [self initWithObjects: objects count: c];
|
|
|
|
|
}
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_ENDIDBUF();
|
2002-08-27 09:37:58 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initialize the receiver with the contents of array.
|
|
|
|
|
* The order of array is preserved.<br />
|
|
|
|
|
* Invokes -initWithObjects:count:
|
|
|
|
|
*/
|
|
|
|
|
- (id) initWithArray: (NSArray*)array
|
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger c = [array count];
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_BEGINIDBUF(objects, c);
|
2002-08-27 09:37:58 +00:00
|
|
|
|
|
2008-07-06 09:18:30 +00:00
|
|
|
|
if ([array isProxy])
|
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i;
|
2008-07-06 09:18:30 +00:00
|
|
|
|
|
|
|
|
|
for (i = 0; i < c; i++)
|
|
|
|
|
{
|
|
|
|
|
objects[i] = [array objectAtIndex: i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
[array getObjects: objects];
|
|
|
|
|
}
|
2002-08-27 09:37:58 +00:00
|
|
|
|
self = [self initWithObjects: objects count: c];
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_ENDIDBUF();
|
2001-01-08 16:45:36 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
2002-08-27 09:37:58 +00:00
|
|
|
|
* Initialize the array by decoding from an archive.<br />
|
|
|
|
|
* Invokes -initWithObjects:count:
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (id) initWithCoder: (NSCoder*)aCoder
|
|
|
|
|
{
|
2004-01-27 21:51:33 +00:00
|
|
|
|
if ([aCoder allowsKeyedCoding])
|
2001-01-08 16:45:36 +00:00
|
|
|
|
{
|
2004-01-28 07:33:20 +00:00
|
|
|
|
id array;
|
|
|
|
|
|
2005-02-22 11:22:44 +00:00
|
|
|
|
array = [(NSKeyedUnarchiver*)aCoder _decodeArrayOfObjectsForKey:
|
2004-01-27 21:51:33 +00:00
|
|
|
|
@"NS.objects"];
|
2004-01-28 07:33:20 +00:00
|
|
|
|
if (array == nil)
|
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i = 0;
|
2004-01-28 07:33:20 +00:00
|
|
|
|
NSString *key;
|
|
|
|
|
id val;
|
|
|
|
|
|
|
|
|
|
array = [NSMutableArray arrayWithCapacity: 2];
|
2015-08-05 08:34:49 +00:00
|
|
|
|
key = [NSString stringWithFormat: @"NS.object.%lu", (unsigned long)i];
|
2004-01-28 07:33:20 +00:00
|
|
|
|
val = [(NSKeyedUnarchiver*)aCoder decodeObjectForKey: key];
|
|
|
|
|
|
|
|
|
|
while (val != nil)
|
|
|
|
|
{
|
|
|
|
|
[array addObject: val];
|
|
|
|
|
i++;
|
2015-08-05 08:34:49 +00:00
|
|
|
|
key = [NSString stringWithFormat: @"NS.object.%lu", (unsigned long)i];
|
2004-01-28 07:33:20 +00:00
|
|
|
|
val = [(NSKeyedUnarchiver*)aCoder decodeObjectForKey: key];
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-08 16:45:36 +00:00
|
|
|
|
|
2004-01-28 07:33:20 +00:00
|
|
|
|
self = [self initWithArray: array];
|
2001-01-08 16:45:36 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2002-08-27 09:37:58 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
unsigned items;
|
2004-01-27 21:51:33 +00:00
|
|
|
|
|
|
|
|
|
[aCoder decodeValueOfObjCType: @encode(unsigned)
|
2015-06-04 09:18:52 +00:00
|
|
|
|
at: &items];
|
|
|
|
|
if (items > 0)
|
2004-01-27 21:51:33 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
GS_BEGINIDBUF(contents, items);
|
2004-01-27 21:51:33 +00:00
|
|
|
|
|
2004-09-10 15:10:54 +00:00
|
|
|
|
[aCoder decodeArrayOfObjCType: @encode(id)
|
2015-06-04 09:18:52 +00:00
|
|
|
|
count: items
|
2004-09-10 15:10:54 +00:00
|
|
|
|
at: contents];
|
2015-06-04 09:18:52 +00:00
|
|
|
|
self = [self initWithObjects: contents count: items];
|
|
|
|
|
while (items-- > 0)
|
2004-01-27 21:51:33 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
[contents[items] release];
|
2004-01-27 21:51:33 +00:00
|
|
|
|
}
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_ENDIDBUF();
|
2004-01-27 21:51:33 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
self = [self initWithObjects: 0 count: 0];
|
|
|
|
|
}
|
2002-08-27 09:37:58 +00:00
|
|
|
|
}
|
2003-10-08 15:03:58 +00:00
|
|
|
|
return self;
|
2001-01-08 16:45:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-03-21 09:45:30 +00:00
|
|
|
|
/**
|
|
|
|
|
* <p>Initialises the array with the contents of the specified file,
|
|
|
|
|
* which must contain an array in property-list format.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>In GNUstep, the property-list format may be either the OpenStep
|
2004-06-22 22:40:40 +00:00
|
|
|
|
* format (ASCII data), or the MacOS-X format (UTF-8 XML data) ... this
|
2002-03-21 09:45:30 +00:00
|
|
|
|
* method will recognise which it is.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>If there is a failure to load the file for any reason, the receiver
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* will be released, the method will return nil, and a warning may be logged.
|
2002-03-21 09:45:30 +00:00
|
|
|
|
* </p>
|
2002-10-04 09:08:09 +00:00
|
|
|
|
* <p>Works by invoking [NSString-initWithContentsOfFile:] and
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* [NSString-propertyList] then checking that the result is an array.
|
2002-10-04 09:08:09 +00:00
|
|
|
|
* </p>
|
2002-03-21 09:45:30 +00:00
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (id) initWithContentsOfFile: (NSString*)file
|
|
|
|
|
{
|
|
|
|
|
NSString *myString;
|
|
|
|
|
|
2002-03-21 09:45:30 +00:00
|
|
|
|
myString = [[NSString allocWithZone: NSDefaultMallocZone()]
|
2002-10-04 09:08:09 +00:00
|
|
|
|
initWithContentsOfFile: file];
|
|
|
|
|
if (myString == nil)
|
|
|
|
|
{
|
|
|
|
|
DESTROY(self);
|
|
|
|
|
}
|
|
|
|
|
else
|
2001-01-08 16:45:36 +00:00
|
|
|
|
{
|
|
|
|
|
id result;
|
|
|
|
|
|
|
|
|
|
NS_DURING
|
|
|
|
|
{
|
|
|
|
|
result = [myString propertyList];
|
|
|
|
|
}
|
|
|
|
|
NS_HANDLER
|
|
|
|
|
{
|
|
|
|
|
result = nil;
|
|
|
|
|
}
|
|
|
|
|
NS_ENDHANDLER
|
|
|
|
|
RELEASE(myString);
|
|
|
|
|
if ([result isKindOfClass: NSArrayClass])
|
|
|
|
|
{
|
2010-04-14 10:39:05 +00:00
|
|
|
|
//self = [self initWithArray: result];
|
2010-04-13 18:37:09 +00:00
|
|
|
|
/* OSX appears to always return a mutable array rather than
|
|
|
|
|
* the class of the receiver.
|
|
|
|
|
*/
|
2010-04-14 10:39:05 +00:00
|
|
|
|
RELEASE(self);
|
|
|
|
|
self = RETAIN(result);
|
2002-10-04 09:08:09 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
NSWarnMLog(@"Contents of file '%@' does not contain an array", file);
|
|
|
|
|
DESTROY(self);
|
2001-01-08 16:45:36 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2002-10-04 09:08:09 +00:00
|
|
|
|
return self;
|
2001-01-08 16:45:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-15 16:35:11 +00:00
|
|
|
|
/**
|
|
|
|
|
* <p>Initialises the array with the contents of the specified URL,
|
|
|
|
|
* which must contain an array in property-list format.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>In GNUstep, the property-list format may be either the OpenStep
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* format (ASCII data), or the MacOS-X format (UTF8 XML data) ... this
|
2003-07-15 16:35:11 +00:00
|
|
|
|
* method will recognise which it is.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>If there is a failure to load the URL for any reason, the receiver
|
|
|
|
|
* will be released, the method will return nil, and a warning may be logged.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>Works by invoking [NSString-initWithContentsOfURL:] and
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* [NSString-propertyList] then checking that the result is an array.
|
2003-07-15 16:35:11 +00:00
|
|
|
|
* </p>
|
|
|
|
|
*/
|
|
|
|
|
- (id) initWithContentsOfURL: (NSURL*)aURL
|
|
|
|
|
{
|
|
|
|
|
NSString *myString;
|
|
|
|
|
|
|
|
|
|
myString = [[NSString allocWithZone: NSDefaultMallocZone()]
|
|
|
|
|
initWithContentsOfURL: aURL];
|
|
|
|
|
if (myString == nil)
|
|
|
|
|
{
|
|
|
|
|
DESTROY(self);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
id result;
|
|
|
|
|
|
|
|
|
|
NS_DURING
|
|
|
|
|
{
|
|
|
|
|
result = [myString propertyList];
|
|
|
|
|
}
|
|
|
|
|
NS_HANDLER
|
|
|
|
|
{
|
|
|
|
|
result = nil;
|
|
|
|
|
}
|
|
|
|
|
NS_ENDHANDLER
|
|
|
|
|
RELEASE(myString);
|
|
|
|
|
if ([result isKindOfClass: NSArrayClass])
|
|
|
|
|
{
|
|
|
|
|
self = [self initWithArray: result];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
NSWarnMLog(@"Contents of URL '%@' does not contain an array", aURL);
|
|
|
|
|
DESTROY(self);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2011-07-22 16:07:23 +00:00
|
|
|
|
- (id) initWithObjects: (const id[])objects count: (NSUInteger)count
|
2001-01-08 16:45:36 +00:00
|
|
|
|
{
|
2004-09-07 05:43:20 +00:00
|
|
|
|
self = [self init];
|
|
|
|
|
return self;
|
2001-01-08 16:45:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Initialize the array the list of objects.
|
|
|
|
|
* <br />May change the value of self before returning it.
|
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (id) initWithObjects: firstObject, ...
|
|
|
|
|
{
|
2003-04-06 17:20:04 +00:00
|
|
|
|
GS_USEIDLIST(firstObject,
|
2005-02-22 11:22:44 +00:00
|
|
|
|
self = [self initWithObjects: __objects count: __count]);
|
2001-01-08 16:45:36 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an NSMutableArray instance containing the same objects as
|
2003-01-20 17:18:06 +00:00
|
|
|
|
* the receiver.<br />
|
|
|
|
|
* The default implementation does this by calling the
|
|
|
|
|
* -initWithArray:copyItems: method on a newly created object,
|
|
|
|
|
* and passing it NO to tell it just to retain the items.
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
2001-01-08 16:45:36 +00:00
|
|
|
|
- (id) mutableCopyWithZone: (NSZone*)zone
|
|
|
|
|
{
|
2003-01-20 17:18:06 +00:00
|
|
|
|
NSMutableArray *copy = [NSMutableArrayClass allocWithZone: zone];
|
|
|
|
|
|
|
|
|
|
return [copy initWithArray: self copyItems: NO];
|
2001-01-08 16:45:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2009-02-23 20:42:32 +00:00
|
|
|
|
- (id) objectAtIndex: (NSUInteger)index
|
2001-01-08 16:45:36 +00:00
|
|
|
|
{
|
|
|
|
|
[self subclassResponsibility: _cmd];
|
|
|
|
|
return nil;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-02-24 07:41:20 +00:00
|
|
|
|
- (id) objectAtIndexedSubscript: (NSUInteger)anIndex
|
2012-04-06 12:23:10 +00:00
|
|
|
|
{
|
2016-02-24 07:41:20 +00:00
|
|
|
|
return [self objectAtIndex: anIndex];
|
2012-04-06 12:23:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-07-10 17:16:31 +00:00
|
|
|
|
- (NSArray *) objectsAtIndexes: (NSIndexSet *)indexes
|
|
|
|
|
{
|
|
|
|
|
//FIXME: probably slow!
|
2007-07-14 04:34:00 +00:00
|
|
|
|
NSMutableArray *group = [NSMutableArray arrayWithCapacity: [indexes count]];
|
2007-07-10 17:16:31 +00:00
|
|
|
|
|
2012-01-02 15:07:32 +00:00
|
|
|
|
NSUInteger i = [indexes firstIndex];
|
2007-07-10 17:16:31 +00:00
|
|
|
|
while (i != NSNotFound)
|
|
|
|
|
{
|
|
|
|
|
[group addObject: [self objectAtIndex: i]];
|
|
|
|
|
i = [indexes indexGreaterThanIndex: i];
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-10 16:50:41 +00:00
|
|
|
|
return GS_IMMUTABLE(group);
|
2007-07-10 17:16:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (BOOL) isEqual: (id)anObject
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (self == anObject)
|
|
|
|
|
return YES;
|
2001-01-08 16:45:36 +00:00
|
|
|
|
if ([anObject isKindOfClass: NSArrayClass])
|
1999-04-08 12:17:15 +00:00
|
|
|
|
return [self isEqualToArray: anObject];
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
return NO;
|
|
|
|
|
}
|
|
|
|
|
|
2007-07-10 17:16:31 +00:00
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns YES if the receiver is equal to otherArray, NO otherwise.
|
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (BOOL) isEqualToArray: (NSArray*)otherArray
|
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i, c;
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (self == (id)otherArray)
|
|
|
|
|
return YES;
|
|
|
|
|
c = [self count];
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
if (c != [otherArray count])
|
1995-04-04 16:01:04 +00:00
|
|
|
|
return NO;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (c > 0)
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
1995-04-04 16:01:04 +00:00
|
|
|
|
return YES;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the last object in the receiver, or nil if the receiver is empty.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (id) lastObject
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger count = [self count];
|
1996-03-30 23:00:27 +00:00
|
|
|
|
if (count == 0)
|
|
|
|
|
return nil;
|
|
|
|
|
return [self objectAtIndex: count-1];
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-06-01 17:43:37 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the first object in the receiver, or nil if the receiver is empty.
|
|
|
|
|
*/
|
|
|
|
|
- (id) firstObject
|
|
|
|
|
{
|
|
|
|
|
NSUInteger count = [self count];
|
|
|
|
|
if (count == 0)
|
|
|
|
|
return nil;
|
|
|
|
|
return [self objectAtIndex: 0];
|
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Makes each object in the array perform aSelector.<br />
|
2004-09-16 14:33:54 +00:00
|
|
|
|
* This is done sequentially from the first to the last object.
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
1998-11-14 03:48:55 +00:00
|
|
|
|
- (void) makeObjectsPerformSelector: (SEL)aSelector
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger c = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
2004-09-16 14:33:54 +00:00
|
|
|
|
if (c > 0)
|
1999-09-14 19:24:58 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
|
|
|
|
NSUInteger i = 0;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
2004-09-16 14:33:54 +00:00
|
|
|
|
while (i < c)
|
|
|
|
|
{
|
|
|
|
|
[(*get)(self, oaiSel, i++) performSelector: aSelector];
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
}
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Obsolete version of -makeObjectsPerformSelector:
|
|
|
|
|
*/
|
1998-11-14 03:48:55 +00:00
|
|
|
|
- (void) makeObjectsPerform: (SEL)aSelector
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
1998-11-14 03:48:55 +00:00
|
|
|
|
[self makeObjectsPerformSelector: aSelector];
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Makes each object in the array perform aSelector with arg.<br />
|
2004-09-16 14:33:54 +00:00
|
|
|
|
* This is done sequentially from the first to the last object.
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
|
|
|
|
- (void) makeObjectsPerformSelector: (SEL)aSelector withObject: (id)arg
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger c = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
2004-09-16 14:33:54 +00:00
|
|
|
|
if (c > 0)
|
1999-09-14 19:24:58 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
|
|
|
|
NSUInteger i = 0;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
2004-09-16 14:33:54 +00:00
|
|
|
|
while (i < c)
|
|
|
|
|
{
|
|
|
|
|
[(*get)(self, oaiSel, i++) performSelector: aSelector
|
|
|
|
|
withObject: arg];
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
}
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Obsolete version of -makeObjectsPerformSelector:withObject:
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (void) makeObjectsPerform: (SEL)aSelector withObject: (id)argument
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
1999-04-08 12:17:15 +00:00
|
|
|
|
[self makeObjectsPerformSelector: aSelector withObject: argument];
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-02-19 17:48:54 +00:00
|
|
|
|
static NSComparisonResult
|
|
|
|
|
compare(id elem1, id elem2, void* context)
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2003-02-19 17:48:54 +00:00
|
|
|
|
NSComparisonResult (*imp)(id, SEL, id);
|
|
|
|
|
|
2003-02-19 20:48:03 +00:00
|
|
|
|
if (context == 0)
|
2003-02-19 21:09:00 +00:00
|
|
|
|
{
|
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
|
format: @"compare null selector given"];
|
|
|
|
|
}
|
2003-02-19 20:48:03 +00:00
|
|
|
|
|
2003-02-19 17:48:54 +00:00
|
|
|
|
imp = (NSComparisonResult (*)(id, SEL, id))
|
|
|
|
|
[elem1 methodForSelector: context];
|
|
|
|
|
|
2003-02-19 20:48:03 +00:00
|
|
|
|
if (imp == NULL)
|
|
|
|
|
{
|
|
|
|
|
[NSException raise: NSGenericException
|
|
|
|
|
format: @"invalid selector passed to compare"];
|
|
|
|
|
}
|
|
|
|
|
|
2003-02-19 17:48:54 +00:00
|
|
|
|
return (*imp)(elem1, context, elem2);
|
2001-09-05 21:31:42 +00:00
|
|
|
|
}
|
1997-01-09 16:24:07 +00:00
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an autoreleased array in which the objects are ordered
|
|
|
|
|
* according to a sort with comparator.
|
|
|
|
|
*/
|
2001-09-05 21:31:42 +00:00
|
|
|
|
- (NSArray*) sortedArrayUsingSelector: (SEL)comparator
|
|
|
|
|
{
|
|
|
|
|
return [self sortedArrayUsingFunction: compare context: (void *)comparator];
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an autoreleased array in which the objects are ordered
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* according to a sort with comparator. This invokes
|
|
|
|
|
* -sortedArrayUsingFunction:context:hint: with a nil hint.
|
2002-06-06 14:02:59 +00:00
|
|
|
|
*/
|
2012-09-19 14:20:01 +00:00
|
|
|
|
- (NSArray*) sortedArrayUsingFunction:
|
|
|
|
|
(NSComparisonResult(*)(id,id,void*))comparator
|
|
|
|
|
context: (void*)context
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1998-01-19 15:20:15 +00:00
|
|
|
|
return [self sortedArrayUsingFunction: comparator context: context hint: nil];
|
|
|
|
|
}
|
1997-01-09 16:24:07 +00:00
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Subclasses may provide a hint for sorting ... The default GNUstep
|
|
|
|
|
* implementation just returns nil.
|
|
|
|
|
*/
|
1998-01-19 15:20:15 +00:00
|
|
|
|
- (NSData*) sortedArrayHint
|
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
return nil;
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns an autoreleased array in which the objects are ordered
|
|
|
|
|
* according to a sort with comparator, where the comparator function
|
2004-06-22 22:40:40 +00:00
|
|
|
|
* is passed two objects to compare, and the context as the third
|
|
|
|
|
* argument. The hint argument is currently ignored, and may be nil.
|
2002-11-04 08:06:48 +00:00
|
|
|
|
*/
|
2012-09-19 14:20:01 +00:00
|
|
|
|
- (NSArray*) sortedArrayUsingFunction:
|
|
|
|
|
(NSComparisonResult(*)(id,id,void*))comparator
|
|
|
|
|
context: (void*)context
|
|
|
|
|
hint: (NSData*)hint
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
|
|
|
|
NSMutableArray *sortedArray;
|
|
|
|
|
|
2015-06-04 09:18:52 +00:00
|
|
|
|
sortedArray = AUTORELEASE([[NSMutableArrayClass allocWithZone:
|
|
|
|
|
NSDefaultMallocZone()] initWithArray: self copyItems: NO]);
|
1999-04-08 12:17:15 +00:00
|
|
|
|
[sortedArray sortUsingFunction: comparator context: context];
|
2002-11-04 08:06:48 +00:00
|
|
|
|
|
2016-03-10 16:50:41 +00:00
|
|
|
|
return GS_IMMUTABLE(sortedArray);
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 13:31:09 +00:00
|
|
|
|
|
|
|
|
|
- (NSArray*) sortedArrayWithOptions: (NSSortOptions)options
|
2012-09-19 14:20:01 +00:00
|
|
|
|
usingComparator: (NSComparator)comparator
|
2012-09-19 13:31:09 +00:00
|
|
|
|
{
|
|
|
|
|
NSMutableArray *sortedArray;
|
|
|
|
|
|
2015-06-04 09:18:52 +00:00
|
|
|
|
sortedArray = AUTORELEASE([[NSMutableArrayClass allocWithZone:
|
|
|
|
|
NSDefaultMallocZone()] initWithArray: self copyItems: NO]);
|
2012-09-19 13:31:09 +00:00
|
|
|
|
[sortedArray sortWithOptions: options usingComparator: comparator];
|
|
|
|
|
|
2016-03-10 16:50:41 +00:00
|
|
|
|
return GS_IMMUTABLE(sortedArray);
|
2012-09-19 13:31:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (NSArray*) sortedArrayUsingComparator: (NSComparator)comparator
|
|
|
|
|
{
|
|
|
|
|
return [self sortedArrayWithOptions: 0 usingComparator: comparator];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (NSUInteger) indexOfObject: (id)key
|
|
|
|
|
inSortedRange: (NSRange)range
|
|
|
|
|
options: (NSBinarySearchingOptions)options
|
|
|
|
|
usingComparator: (NSComparator)comparator
|
|
|
|
|
{
|
|
|
|
|
if (range.length == 0)
|
|
|
|
|
{
|
2012-09-19 14:20:01 +00:00
|
|
|
|
return options & NSBinarySearchingInsertionIndex
|
|
|
|
|
? range.location : NSNotFound;
|
2012-09-19 13:31:09 +00:00
|
|
|
|
}
|
2012-09-19 14:20:01 +00:00
|
|
|
|
if (range.length == 1)
|
2012-09-19 13:31:09 +00:00
|
|
|
|
{
|
2021-11-17 13:35:49 +00:00
|
|
|
|
switch (CALL_NON_NULL_BLOCK(comparator, key, [self objectAtIndex: range.location]))
|
2012-09-19 14:20:01 +00:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
2012-09-19 13:31:09 +00:00
|
|
|
|
}
|
2012-09-19 14:20:01 +00:00
|
|
|
|
else
|
2012-09-19 13:31:09 +00:00
|
|
|
|
{
|
2012-09-19 14:20:01 +00:00
|
|
|
|
NSUInteger index = NSNotFound;
|
|
|
|
|
NSUInteger count = [self count];
|
|
|
|
|
GS_BEGINIDBUF(objects, count);
|
2012-09-19 13:31:09 +00:00
|
|
|
|
|
2012-09-19 14:20:01 +00:00
|
|
|
|
[self getObjects: objects];
|
|
|
|
|
// 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()
|
2012-09-19 13:31:09 +00:00
|
|
|
|
|
2012-09-19 14:20:01 +00:00
|
|
|
|
// 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--;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-11-16 14:56:20 +00:00
|
|
|
|
if (index >= NSMaxRange(range))
|
|
|
|
|
{
|
|
|
|
|
return NSNotFound;
|
|
|
|
|
}
|
2012-09-19 14:20:01 +00:00
|
|
|
|
/*
|
|
|
|
|
* 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
|
|
|
|
|
*/
|
2021-11-17 13:35:49 +00:00
|
|
|
|
return (NSOrderedSame == CALL_NON_NULL_BLOCK(comparator,
|
2012-09-19 14:20:01 +00:00
|
|
|
|
key, [self objectAtIndex: index]) ? index : NSNotFound);
|
2012-09-19 13:31:09 +00:00
|
|
|
|
}
|
|
|
|
|
// Never reached
|
|
|
|
|
return NSNotFound;
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a string formed by concatenating the objects in the receiver,
|
|
|
|
|
* with the specified separator string inserted between each part.
|
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (NSString*) componentsJoinedByString: (NSString*)separator
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger c = [self count];
|
2011-02-11 09:02:33 +00:00
|
|
|
|
NSMutableString *s;
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2015-06-04 09:18:52 +00:00
|
|
|
|
s = [NSMutableString stringWithCapacity: c];
|
2002-11-04 08:06:48 +00:00
|
|
|
|
if (c > 0)
|
1995-04-07 21:01:59 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger l = [separator length];
|
|
|
|
|
NSUInteger i;
|
2002-11-04 08:06:48 +00:00
|
|
|
|
|
|
|
|
|
[s appendString: [[self objectAtIndex: 0] description]];
|
|
|
|
|
for (i = 1; i < c; i++)
|
|
|
|
|
{
|
|
|
|
|
if (l > 0)
|
|
|
|
|
{
|
|
|
|
|
[s appendString: separator];
|
|
|
|
|
}
|
|
|
|
|
[s appendString: [[self objectAtIndex: i] description]];
|
|
|
|
|
}
|
1995-04-07 21:01:59 +00:00
|
|
|
|
}
|
2016-03-10 16:50:41 +00:00
|
|
|
|
return GS_IMMUTABLE(s);
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Assumes that the receiver is an array of paths, and returns an
|
|
|
|
|
* array formed by selecting the subset of those patch matching
|
|
|
|
|
* the specified array of extensions.
|
|
|
|
|
*/
|
1998-01-19 15:20:15 +00:00
|
|
|
|
- (NSArray*) pathsMatchingExtensions: (NSArray*)extensions
|
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i, c = [self count];
|
|
|
|
|
NSMutableArray *a = AUTORELEASE([[NSMutableArray alloc] initWithCapacity: 1]);
|
1999-09-14 19:24:58 +00:00
|
|
|
|
Class cls = [NSString class];
|
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
|
|
|
|
IMP add = [a methodForSelector: addSel];
|
|
|
|
|
|
1998-01-19 15:20:15 +00:00
|
|
|
|
for (i = 0; i < c; i++)
|
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
id o = (*get)(self, oaiSel, i);
|
|
|
|
|
|
|
|
|
|
if ([o isKindOfClass: cls])
|
2002-11-04 08:06:48 +00:00
|
|
|
|
{
|
|
|
|
|
if ([extensions containsObject: [o pathExtension]])
|
|
|
|
|
{
|
|
|
|
|
(*add)(a, addSel, o);
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
2016-03-10 16:50:41 +00:00
|
|
|
|
return GS_IMMUTABLE(a);
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
1995-04-03 22:59:20 +00:00
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the first object found in the receiver (starting at index 0)
|
|
|
|
|
* which is present in the otherArray as determined by using the
|
|
|
|
|
* -containsObject: method.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (id) firstObjectCommonWithArray: (NSArray*)otherArray
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i, c = [self count];
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
id o;
|
2002-11-04 08:06:48 +00:00
|
|
|
|
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
for (i = 0; i < c; i++)
|
2002-11-04 08:06:48 +00:00
|
|
|
|
{
|
|
|
|
|
if ([otherArray containsObject: (o = [self objectAtIndex: i])])
|
|
|
|
|
{
|
|
|
|
|
return o;
|
|
|
|
|
}
|
|
|
|
|
}
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
return nil;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns a subarray of the receiver containing the objects found in
|
|
|
|
|
* the specified range aRange.
|
|
|
|
|
*/
|
1999-06-04 16:05:45 +00:00
|
|
|
|
- (NSArray*) subarrayWithRange: (NSRange)aRange
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1996-03-30 19:14:43 +00:00
|
|
|
|
id na;
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger c = [self count];
|
1996-03-30 19:14:43 +00:00
|
|
|
|
|
1999-06-21 08:30:26 +00:00
|
|
|
|
GS_RANGE_CHECK(aRange, c);
|
1996-03-30 19:14:43 +00:00
|
|
|
|
|
1999-06-04 16:05:45 +00:00
|
|
|
|
if (aRange.length == 0)
|
2000-03-17 13:13:08 +00:00
|
|
|
|
{
|
|
|
|
|
na = [NSArray array];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_BEGINIDBUF(objects, aRange.length);
|
1996-03-30 19:14:43 +00:00
|
|
|
|
|
2000-03-17 13:13:08 +00:00
|
|
|
|
[self getObjects: objects range: aRange];
|
|
|
|
|
na = [NSArray arrayWithObjects: objects count: aRange.length];
|
2004-09-10 15:10:54 +00:00
|
|
|
|
GS_ENDIDBUF();
|
2000-03-17 13:13:08 +00:00
|
|
|
|
}
|
1998-10-08 13:46:53 +00:00
|
|
|
|
return na;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* Returns an enumerator describing the array sequentially
|
2002-06-06 14:02:59 +00:00
|
|
|
|
* from the first to the last element.<br/>
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* If you use a mutable subclass of NSArray,
|
2002-06-06 14:02:59 +00:00
|
|
|
|
* you should not modify the array during enumeration.
|
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (NSEnumerator*) objectEnumerator
|
|
|
|
|
{
|
2000-03-17 13:13:08 +00:00
|
|
|
|
id e;
|
|
|
|
|
|
|
|
|
|
e = [NSArrayEnumerator allocWithZone: NSDefaultMallocZone()];
|
|
|
|
|
e = [e initWithArray: self];
|
|
|
|
|
return AUTORELEASE(e);
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
}
|
1995-04-03 22:59:20 +00:00
|
|
|
|
|
2002-06-06 14:02:59 +00:00
|
|
|
|
/**
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* Returns an enumerator describing the array sequentially
|
2002-06-06 14:02:59 +00:00
|
|
|
|
* from the last to the first element.<br/>
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* If you use a mutable subclass of NSArray,
|
2002-06-06 14:02:59 +00:00
|
|
|
|
* you should not modify the array during enumeration.
|
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (NSEnumerator*) reverseObjectEnumerator
|
|
|
|
|
{
|
2000-03-17 13:13:08 +00:00
|
|
|
|
id e;
|
|
|
|
|
|
|
|
|
|
e = [NSArrayEnumeratorReverse allocWithZone: NSDefaultMallocZone()];
|
|
|
|
|
e = [e initWithArray: self];
|
|
|
|
|
return AUTORELEASE(e);
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
}
|
1995-04-03 22:59:20 +00:00
|
|
|
|
|
2002-11-11 11:34:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the result of invoking -descriptionWithLocale:indent: with a nil
|
|
|
|
|
* locale and zero indent.
|
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (NSString*) description
|
1997-11-07 18:46:30 +00:00
|
|
|
|
{
|
1998-01-19 15:20:15 +00:00
|
|
|
|
return [self descriptionWithLocale: nil];
|
1997-11-07 18:46:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-11 11:34:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the result of invoking -descriptionWithLocale:indent:
|
|
|
|
|
* with a zero indent.
|
|
|
|
|
*/
|
2011-02-23 11:52:17 +00:00
|
|
|
|
- (NSString*) descriptionWithLocale: (id)locale
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1998-01-19 15:20:15 +00:00
|
|
|
|
return [self descriptionWithLocale: locale indent: 0];
|
|
|
|
|
}
|
1998-01-21 14:56:24 +00:00
|
|
|
|
|
2002-11-11 11:34:21 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the receiver as a text property list in the traditional format.<br />
|
|
|
|
|
* See [NSString-propertyList] for details.<br />
|
|
|
|
|
* If locale is nil, no formatting is done, otherwise entries are formatted
|
|
|
|
|
* according to the locale, and indented according to level.<br />
|
|
|
|
|
* Unless locale is nil, a level of zero indents items by four spaces,
|
|
|
|
|
* while a level of one indents them by a tab.<br />
|
|
|
|
|
* The items in the property list string appear in the same order as
|
|
|
|
|
* they appear in the receiver.
|
|
|
|
|
*/
|
2011-02-23 11:52:17 +00:00
|
|
|
|
- (NSString*) descriptionWithLocale: (id)locale
|
2009-02-23 20:42:32 +00:00
|
|
|
|
indent: (NSUInteger)level
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
2002-11-10 09:29:45 +00:00
|
|
|
|
NSString *result = nil;
|
1997-10-31 16:26:44 +00:00
|
|
|
|
|
2002-11-27 13:56:00 +00:00
|
|
|
|
GSPropertyListMake(self, locale, NO, YES, level == 1 ? 3 : 2, &result);
|
2000-03-17 13:13:08 +00:00
|
|
|
|
|
2002-11-10 09:29:45 +00:00
|
|
|
|
return result;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-03-21 09:45:30 +00:00
|
|
|
|
/**
|
|
|
|
|
* <p>Writes the contents of the array to the file specified by path.
|
|
|
|
|
* The file contents will be in property-list format ... under GNUstep
|
|
|
|
|
* this is either OpenStep style (ASCII characters using \U hexadecimal
|
|
|
|
|
* escape sequences for unicode), or MacOS-X style (XML in the UTF8
|
|
|
|
|
* character set).
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>If the useAuxiliaryFile flag is YES, the file write operation is
|
|
|
|
|
* atomic ... the data is written to a temporary file, which is then
|
|
|
|
|
* renamed to the actual file name.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>If the conversion of data into the correct property-list format fails
|
|
|
|
|
* or the write operation fails, the method returns NO, otherwise it
|
|
|
|
|
* returns YES.
|
|
|
|
|
* </p>
|
|
|
|
|
* <p>NB. The fact that the file is in property-list format does not
|
|
|
|
|
* necessarily mean that it can be used to reconstruct the array using
|
|
|
|
|
* the -initWithContentsOfFile: method. If the original array contains
|
|
|
|
|
* non-property-list objects, the descriptions of those objects will
|
|
|
|
|
* have been written, and reading in the file as a property-list will
|
|
|
|
|
* result in a new array containing the string descriptions.
|
|
|
|
|
* </p>
|
|
|
|
|
*/
|
|
|
|
|
- (BOOL) writeToFile: (NSString *)path atomically: (BOOL)useAuxiliaryFile
|
2000-02-19 00:40:47 +00:00
|
|
|
|
{
|
2006-10-18 15:36:52 +00:00
|
|
|
|
NSDictionary *loc;
|
2002-11-10 09:29:45 +00:00
|
|
|
|
NSString *desc = nil;
|
2002-11-27 16:39:17 +00:00
|
|
|
|
NSData *data;
|
2001-09-08 05:11:58 +00:00
|
|
|
|
|
2006-10-18 15:36:52 +00:00
|
|
|
|
loc = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
|
2001-09-08 05:11:58 +00:00
|
|
|
|
if (GSMacOSXCompatiblePropertyLists() == YES)
|
|
|
|
|
{
|
2002-11-27 13:56:00 +00:00
|
|
|
|
GSPropertyListMake(self, loc, YES, NO, 2, &desc);
|
2002-11-27 16:39:17 +00:00
|
|
|
|
data = [desc dataUsingEncoding: NSUTF8StringEncoding];
|
2001-09-08 05:11:58 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2002-11-27 13:56:00 +00:00
|
|
|
|
GSPropertyListMake(self, loc, NO, NO, 2, &desc);
|
2002-11-27 16:39:17 +00:00
|
|
|
|
data = [desc dataUsingEncoding: NSASCIIStringEncoding];
|
2001-09-08 05:11:58 +00:00
|
|
|
|
}
|
2000-03-17 13:13:08 +00:00
|
|
|
|
|
2002-11-27 16:39:17 +00:00
|
|
|
|
return [data writeToFile: path atomically: useAuxiliaryFile];
|
2000-02-19 00:40:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-03-21 09:45:30 +00:00
|
|
|
|
/**
|
|
|
|
|
* <p>Writes the contents of the array to the specified url.
|
|
|
|
|
* This functions just like -writeToFile:atomically: except that the
|
|
|
|
|
* output may be written to any URL, not just a local file.
|
|
|
|
|
* </p>
|
|
|
|
|
*/
|
|
|
|
|
- (BOOL) writeToURL: (NSURL *)url atomically: (BOOL)useAuxiliaryFile
|
2001-07-16 07:08:47 +00:00
|
|
|
|
{
|
2006-10-18 15:36:52 +00:00
|
|
|
|
NSDictionary *loc;
|
2002-11-10 09:29:45 +00:00
|
|
|
|
NSString *desc = nil;
|
2002-11-27 16:39:17 +00:00
|
|
|
|
NSData *data;
|
2001-09-08 05:15:19 +00:00
|
|
|
|
|
2006-10-18 15:36:52 +00:00
|
|
|
|
loc = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
|
2001-09-08 05:15:19 +00:00
|
|
|
|
if (GSMacOSXCompatiblePropertyLists() == YES)
|
|
|
|
|
{
|
2002-11-27 13:56:00 +00:00
|
|
|
|
GSPropertyListMake(self, loc, YES, NO, 2, &desc);
|
2002-11-27 16:39:17 +00:00
|
|
|
|
data = [desc dataUsingEncoding: NSUTF8StringEncoding];
|
2001-09-08 05:15:19 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2002-11-27 13:56:00 +00:00
|
|
|
|
GSPropertyListMake(self, loc, NO, NO, 2, &desc);
|
2002-11-27 16:39:17 +00:00
|
|
|
|
data = [desc dataUsingEncoding: NSASCIIStringEncoding];
|
2001-09-08 05:15:19 +00:00
|
|
|
|
}
|
2001-07-16 07:08:47 +00:00
|
|
|
|
|
2002-11-27 16:39:17 +00:00
|
|
|
|
return [data writeToURL: url atomically: useAuxiliaryFile];
|
2001-07-16 07:08:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-01-06 19:43:29 +00:00
|
|
|
|
/**
|
|
|
|
|
* This overrides NSObjects implementation of this method.
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* This method returns an array of objects returned by
|
|
|
|
|
* invoking -valueForKey: for each item in the receiver,
|
2004-01-06 19:43:29 +00:00
|
|
|
|
* substituting NSNull for nil.
|
|
|
|
|
* A special case: the key "count" is not forwarded to each object
|
|
|
|
|
* of the receiver but returns the number of objects of the receiver.<br/>
|
|
|
|
|
*/
|
|
|
|
|
- (id) valueForKey: (NSString*)key
|
|
|
|
|
{
|
2004-01-08 08:07:29 +00:00
|
|
|
|
id result = nil;
|
2004-01-06 19:43:29 +00:00
|
|
|
|
|
2010-06-15 11:26:00 +00:00
|
|
|
|
if ([key isEqualToString: @"@count"] == YES)
|
2004-01-06 19:43:29 +00:00
|
|
|
|
{
|
2015-01-16 15:25:50 +00:00
|
|
|
|
result = [NSNumber numberWithUnsignedInteger: [self count]];
|
2004-01-06 19:43:29 +00:00
|
|
|
|
}
|
2010-06-15 11:26:00 +00:00
|
|
|
|
else if ([key isEqualToString: @"count"] == YES)
|
|
|
|
|
{
|
|
|
|
|
GSOnceMLog(
|
2016-05-19 07:21:36 +00:00
|
|
|
|
@"[NSArray-valueForKey:] called with 'count' is deprecated .. use '@count'");
|
2015-01-16 15:25:50 +00:00
|
|
|
|
result = [NSNumber numberWithUnsignedInteger: [self count]];
|
2010-06-15 11:26:00 +00:00
|
|
|
|
}
|
2004-01-06 19:43:29 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
2004-01-08 08:07:29 +00:00
|
|
|
|
NSMutableArray *results = nil;
|
|
|
|
|
static NSNull *null = nil;
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i;
|
|
|
|
|
NSUInteger count = [self count];
|
2004-01-08 08:07:29 +00:00
|
|
|
|
volatile id object = nil;
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2005-03-02 11:46:21 +00:00
|
|
|
|
results = [NSMutableArray arrayWithCapacity: count];
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2004-01-08 08:07:29 +00:00
|
|
|
|
for (i = 0; i < count; i++)
|
2004-01-06 19:43:29 +00:00
|
|
|
|
{
|
2004-01-08 08:07:29 +00:00
|
|
|
|
id result;
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2004-01-06 19:43:29 +00:00
|
|
|
|
object = [self objectAtIndex: i];
|
|
|
|
|
result = [object valueForKey: key];
|
2004-01-08 08:07:29 +00:00
|
|
|
|
if (result == nil)
|
2004-01-06 19:43:29 +00:00
|
|
|
|
{
|
2004-01-08 08:07:29 +00:00
|
|
|
|
if (null == nil)
|
|
|
|
|
{
|
|
|
|
|
null = RETAIN([NSNull null]);
|
|
|
|
|
}
|
2004-01-06 19:43:29 +00:00
|
|
|
|
result = null;
|
|
|
|
|
}
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2004-01-06 19:43:29 +00:00
|
|
|
|
[results addObject: result];
|
|
|
|
|
}
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2004-01-08 08:07:29 +00:00
|
|
|
|
result = results;
|
2004-01-06 19:43:29 +00:00
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2008-03-16 06:56:52 +00:00
|
|
|
|
- (id) valueForKeyPath: (NSString*)path
|
|
|
|
|
{
|
2009-03-18 10:02:49 +00:00
|
|
|
|
id result = nil;
|
2008-03-16 06:56:52 +00:00
|
|
|
|
|
|
|
|
|
if ([path hasPrefix: @"@"])
|
|
|
|
|
{
|
|
|
|
|
NSRange r;
|
|
|
|
|
|
|
|
|
|
r = [path rangeOfString: @"."];
|
|
|
|
|
if (r.length == 0)
|
|
|
|
|
{
|
2008-03-16 07:22:08 +00:00
|
|
|
|
if ([path isEqualToString: @"@count"] == YES)
|
|
|
|
|
{
|
2015-01-16 15:25:50 +00:00
|
|
|
|
result = [NSNumber numberWithUnsignedInteger: [self count]];
|
2008-03-16 07:22:08 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = [self valueForKey: path];
|
|
|
|
|
}
|
2008-03-16 06:56:52 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
NSString *op = [path substringToIndex: r.location];
|
|
|
|
|
NSString *rem = [path substringFromIndex: NSMaxRange(r)];
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger count = [self count];
|
2008-03-16 06:56:52 +00:00
|
|
|
|
|
2008-03-16 07:22:08 +00:00
|
|
|
|
if ([op isEqualToString: @"@count"] == YES)
|
|
|
|
|
{
|
2015-01-16 15:25:50 +00:00
|
|
|
|
result = [NSNumber numberWithUnsignedInteger: count];
|
2008-03-16 07:22:08 +00:00
|
|
|
|
}
|
|
|
|
|
else if ([op isEqualToString: @"@avg"] == YES)
|
2008-03-16 06:56:52 +00:00
|
|
|
|
{
|
|
|
|
|
double d = 0;
|
|
|
|
|
|
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
|
|
|
|
NSEnumerator *e = [self objectEnumerator];
|
|
|
|
|
id o;
|
2012-03-27 17:05:19 +00:00
|
|
|
|
|
2008-03-16 06:56:52 +00:00
|
|
|
|
while ((o = [e nextObject]) != nil)
|
|
|
|
|
{
|
|
|
|
|
d += [[o valueForKeyPath: rem] doubleValue];
|
|
|
|
|
}
|
|
|
|
|
d /= count;
|
|
|
|
|
}
|
|
|
|
|
result = [NSNumber numberWithDouble: d];
|
|
|
|
|
}
|
|
|
|
|
else if ([op isEqualToString: @"@max"] == YES)
|
|
|
|
|
{
|
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
|
|
|
|
NSEnumerator *e = [self objectEnumerator];
|
|
|
|
|
id o;
|
2012-03-27 17:05:19 +00:00
|
|
|
|
|
2008-03-16 06:56:52 +00:00
|
|
|
|
while ((o = [e nextObject]) != nil)
|
|
|
|
|
{
|
|
|
|
|
o = [o valueForKeyPath: rem];
|
|
|
|
|
if (result == nil
|
|
|
|
|
|| [result compare: o] == NSOrderedAscending)
|
|
|
|
|
{
|
|
|
|
|
result = o;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ([op isEqualToString: @"@min"] == YES)
|
|
|
|
|
{
|
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
|
|
|
|
NSEnumerator *e = [self objectEnumerator];
|
|
|
|
|
id o;
|
2012-03-27 17:05:19 +00:00
|
|
|
|
|
2008-03-16 06:56:52 +00:00
|
|
|
|
while ((o = [e nextObject]) != nil)
|
|
|
|
|
{
|
|
|
|
|
o = [o valueForKeyPath: rem];
|
|
|
|
|
if (result == nil
|
|
|
|
|
|| [result compare: o] == NSOrderedDescending)
|
|
|
|
|
{
|
|
|
|
|
result = o;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ([op isEqualToString: @"@sum"] == YES)
|
|
|
|
|
{
|
|
|
|
|
double d = 0;
|
|
|
|
|
|
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
|
|
|
|
NSEnumerator *e = [self objectEnumerator];
|
|
|
|
|
id o;
|
2012-03-27 17:05:19 +00:00
|
|
|
|
|
2008-03-16 06:56:52 +00:00
|
|
|
|
while ((o = [e nextObject]) != nil)
|
|
|
|
|
{
|
|
|
|
|
d += [[o valueForKeyPath: rem] doubleValue];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
result = [NSNumber numberWithDouble: d];
|
|
|
|
|
}
|
|
|
|
|
else if ([op isEqualToString: @"@distinctUnionOfArrays"] == YES)
|
|
|
|
|
{
|
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
|
|
|
|
NSEnumerator *e = [self objectEnumerator];
|
|
|
|
|
id o;
|
2012-03-27 17:05:19 +00:00
|
|
|
|
|
2008-03-16 06:56:52 +00:00
|
|
|
|
result = [NSMutableSet set];
|
|
|
|
|
while ((o = [e nextObject]) != nil)
|
|
|
|
|
{
|
|
|
|
|
o = [o valueForKeyPath: rem];
|
|
|
|
|
[result addObjectsFromArray: o];
|
|
|
|
|
}
|
|
|
|
|
result = [result allObjects];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = [NSArray array];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ([op isEqualToString: @"@distinctUnionOfObjects"] == YES)
|
|
|
|
|
{
|
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
|
|
|
|
NSEnumerator *e = [self objectEnumerator];
|
|
|
|
|
id o;
|
2012-03-27 17:05:19 +00:00
|
|
|
|
|
2008-03-16 06:56:52 +00:00
|
|
|
|
result = [NSMutableSet set];
|
|
|
|
|
while ((o = [e nextObject]) != nil)
|
|
|
|
|
{
|
|
|
|
|
o = [o valueForKeyPath: rem];
|
|
|
|
|
[result addObject: o];
|
|
|
|
|
}
|
|
|
|
|
result = [result allObjects];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = [NSArray array];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ([op isEqualToString: @"@distinctUnionOfSets"] == YES)
|
|
|
|
|
{
|
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
|
|
|
|
NSEnumerator *e = [self objectEnumerator];
|
|
|
|
|
id o;
|
2012-03-27 17:05:19 +00:00
|
|
|
|
|
2008-03-16 06:56:52 +00:00
|
|
|
|
result = [NSMutableSet set];
|
|
|
|
|
while ((o = [e nextObject]) != nil)
|
|
|
|
|
{
|
|
|
|
|
o = [o valueForKeyPath: rem];
|
|
|
|
|
[result addObjectsFromArray: [o allObjects]];
|
|
|
|
|
}
|
|
|
|
|
result = [result allObjects];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = [NSArray array];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ([op isEqualToString: @"@unionOfArrays"] == YES)
|
|
|
|
|
{
|
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
|
|
|
|
NSEnumerator *e = [self objectEnumerator];
|
|
|
|
|
id o;
|
2012-03-27 17:05:19 +00:00
|
|
|
|
|
2008-03-16 06:56:52 +00:00
|
|
|
|
result = [GSMutableArray array];
|
|
|
|
|
while ((o = [e nextObject]) != nil)
|
|
|
|
|
{
|
|
|
|
|
o = [o valueForKeyPath: rem];
|
|
|
|
|
[result addObjectsFromArray: o];
|
|
|
|
|
}
|
2016-03-10 16:50:41 +00:00
|
|
|
|
result = GS_IMMUTABLE(result);
|
2008-03-16 06:56:52 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = [NSArray array];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ([op isEqualToString: @"@unionOfObjects"] == YES)
|
|
|
|
|
{
|
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
|
|
|
|
NSEnumerator *e = [self objectEnumerator];
|
|
|
|
|
id o;
|
2012-03-27 17:05:19 +00:00
|
|
|
|
|
2008-03-16 06:56:52 +00:00
|
|
|
|
result = [GSMutableArray array];
|
|
|
|
|
while ((o = [e nextObject]) != nil)
|
|
|
|
|
{
|
|
|
|
|
o = [o valueForKeyPath: rem];
|
|
|
|
|
[result addObject: o];
|
|
|
|
|
}
|
2016-03-10 16:50:41 +00:00
|
|
|
|
result = GS_IMMUTABLE(result);
|
2008-03-16 06:56:52 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = [NSArray array];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ([op isEqualToString: @"@unionOfSets"] == YES)
|
|
|
|
|
{
|
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
|
|
|
|
NSEnumerator *e = [self objectEnumerator];
|
|
|
|
|
id o;
|
2012-03-27 17:05:19 +00:00
|
|
|
|
|
2008-03-16 06:56:52 +00:00
|
|
|
|
result = [GSMutableArray array];
|
|
|
|
|
while ((o = [e nextObject]) != nil)
|
|
|
|
|
{
|
|
|
|
|
o = [o valueForKeyPath: rem];
|
|
|
|
|
[result addObjectsFromArray: [o allObjects]];
|
|
|
|
|
}
|
2016-03-10 16:50:41 +00:00
|
|
|
|
result = GS_IMMUTABLE(result);
|
2008-03-16 06:56:52 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = [NSArray array];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2008-03-16 07:06:15 +00:00
|
|
|
|
result = [super valueForKeyPath: path];
|
2008-03-16 06:56:52 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
result = [super valueForKeyPath: path];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2009-12-27 16:49:52 +00:00
|
|
|
|
|
2013-12-13 21:01:22 +00:00
|
|
|
|
/**
|
|
|
|
|
* Call setValue:forKey: on each of the receiver's items
|
|
|
|
|
* with the value and key.
|
|
|
|
|
*/
|
|
|
|
|
- (void) setValue: (id)value forKey: (NSString*)key
|
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i;
|
|
|
|
|
NSUInteger count = [self count];
|
2013-12-13 21:01:22 +00:00
|
|
|
|
volatile id object = nil;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
|
{
|
|
|
|
|
object = [self objectAtIndex: i];
|
|
|
|
|
[object setValue: value
|
|
|
|
|
forKey: key];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-06-15 11:26:00 +00:00
|
|
|
|
- (void) enumerateObjectsUsingBlock: (GSEnumeratorBlock)aBlock
|
2009-12-27 16:49:52 +00:00
|
|
|
|
{
|
2010-06-15 11:26:00 +00:00
|
|
|
|
[self enumerateObjectsWithOptions: 0 usingBlock: aBlock];
|
2009-12-27 16:49:52 +00:00
|
|
|
|
}
|
2015-07-15 14:14:21 +00:00
|
|
|
|
|
2012-03-27 17:05:19 +00:00
|
|
|
|
- (void) enumerateObjectsWithOptions: (NSEnumerationOptions)opts
|
2010-06-15 11:26:00 +00:00
|
|
|
|
usingBlock: (GSEnumeratorBlock)aBlock
|
2009-12-27 15:25:12 +00:00
|
|
|
|
{
|
2010-06-15 11:26:00 +00:00
|
|
|
|
NSUInteger count = 0;
|
2012-03-27 17:05:19 +00:00
|
|
|
|
BLOCK_SCOPE BOOL shouldStop = NO;
|
|
|
|
|
BOOL isReverse = (opts & NSEnumerationReverse);
|
2010-06-15 11:26:00 +00:00
|
|
|
|
id<NSFastEnumeration> enumerator = self;
|
2009-12-27 16:49:52 +00:00
|
|
|
|
|
2010-06-15 11:26:00 +00:00
|
|
|
|
/* If we are enumerating in reverse, use the reverse enumerator for fast
|
|
|
|
|
* enumeration. */
|
2012-03-27 17:05:19 +00:00
|
|
|
|
if (isReverse)
|
2010-06-15 11:26:00 +00:00
|
|
|
|
{
|
|
|
|
|
enumerator = [self reverseObjectEnumerator];
|
2012-03-27 17:05:19 +00:00
|
|
|
|
count = ([self count] - 1);
|
2010-06-15 11:26:00 +00:00
|
|
|
|
}
|
2009-12-27 16:49:52 +00:00
|
|
|
|
|
2012-03-27 17:05:19 +00:00
|
|
|
|
{
|
|
|
|
|
GS_DISPATCH_CREATE_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts)
|
2010-06-15 11:26:00 +00:00
|
|
|
|
FOR_IN (id, obj, enumerator)
|
2019-09-25 09:14:43 +00:00
|
|
|
|
GS_DISPATCH_SUBMIT_BLOCK(enumQueueGroup, enumQueue, if (shouldStop == NO) {, }, aBlock, obj, count, &shouldStop);
|
2012-03-27 17:05:19 +00:00
|
|
|
|
if (isReverse)
|
2015-07-15 14:14:21 +00:00
|
|
|
|
{
|
|
|
|
|
count--;
|
|
|
|
|
}
|
2012-03-27 17:05:19 +00:00
|
|
|
|
else
|
2015-07-15 14:14:21 +00:00
|
|
|
|
{
|
|
|
|
|
count++;
|
|
|
|
|
}
|
2012-03-27 17:05:19 +00:00
|
|
|
|
|
|
|
|
|
if (shouldStop)
|
2015-07-15 14:14:21 +00:00
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
2012-03-27 17:05:19 +00:00
|
|
|
|
END_FOR_IN(enumerator)
|
|
|
|
|
GS_DISPATCH_TEARDOWN_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts)
|
|
|
|
|
}
|
2009-12-27 16:49:52 +00:00
|
|
|
|
}
|
2010-06-15 11:26:00 +00:00
|
|
|
|
|
|
|
|
|
- (void) enumerateObjectsAtIndexes: (NSIndexSet*)indexSet
|
|
|
|
|
options: (NSEnumerationOptions)opts
|
|
|
|
|
usingBlock: (GSEnumeratorBlock)block
|
2009-12-27 16:49:52 +00:00
|
|
|
|
{
|
2012-03-27 17:05:19 +00:00
|
|
|
|
[[self objectsAtIndexes: indexSet] enumerateObjectsWithOptions: opts
|
2010-06-15 11:26:00 +00:00
|
|
|
|
usingBlock: block];
|
2009-12-27 16:49:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-03-27 17:05:19 +00:00
|
|
|
|
- (NSIndexSet *) indexesOfObjectsWithOptions: (NSEnumerationOptions)opts
|
2010-06-15 11:26:00 +00:00
|
|
|
|
passingTest: (GSPredicateBlock)predicate
|
2009-12-27 16:49:52 +00:00
|
|
|
|
{
|
2010-06-15 11:26:00 +00:00
|
|
|
|
/* TODO: Concurrency. */
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSMutableIndexSet *set = [NSMutableIndexSet indexSet];
|
|
|
|
|
BLOCK_SCOPE BOOL shouldStop = NO;
|
2010-06-15 11:26:00 +00:00
|
|
|
|
id<NSFastEnumeration> enumerator = self;
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger count = 0;
|
|
|
|
|
BLOCK_SCOPE NSLock *setLock = nil;
|
2009-12-27 16:49:52 +00:00
|
|
|
|
|
2010-06-15 11:26:00 +00:00
|
|
|
|
/* If we are enumerating in reverse, use the reverse enumerator for fast
|
|
|
|
|
* enumeration. */
|
|
|
|
|
if (opts & NSEnumerationReverse)
|
|
|
|
|
{
|
|
|
|
|
enumerator = [self reverseObjectEnumerator];
|
|
|
|
|
}
|
2012-03-27 17:05:19 +00:00
|
|
|
|
if (opts & NSEnumerationConcurrent)
|
2015-06-04 09:18:52 +00:00
|
|
|
|
{
|
|
|
|
|
setLock = [NSLock new];
|
|
|
|
|
}
|
2012-03-27 17:05:19 +00:00
|
|
|
|
{
|
|
|
|
|
GS_DISPATCH_CREATE_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts)
|
|
|
|
|
FOR_IN (id, obj, enumerator)
|
|
|
|
|
# if __has_feature(blocks) && (GS_USE_LIBDISPATCH == 1)
|
2019-09-25 09:14:43 +00:00
|
|
|
|
if (enumQueue != NULL)
|
2012-03-27 17:05:19 +00:00
|
|
|
|
{
|
2019-09-25 09:14:43 +00:00
|
|
|
|
dispatch_group_async(enumQueueGroup, enumQueue, ^(void){
|
|
|
|
|
if (shouldStop)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (predicate(obj, count, &shouldStop))
|
|
|
|
|
{
|
|
|
|
|
[setLock lock];
|
|
|
|
|
[set addIndex: count];
|
|
|
|
|
[setLock unlock];
|
|
|
|
|
}
|
|
|
|
|
});
|
2012-03-27 17:05:19 +00:00
|
|
|
|
}
|
2019-09-25 09:14:43 +00:00
|
|
|
|
else // call block directly
|
|
|
|
|
# endif
|
2021-11-17 13:35:49 +00:00
|
|
|
|
if (CALL_NON_NULL_BLOCK(predicate, obj, count, &shouldStop))
|
2012-03-27 17:05:19 +00:00
|
|
|
|
{
|
2019-09-25 09:14:43 +00:00
|
|
|
|
/* TODO: It would be more efficient to collect an NSRange and only
|
2021-11-17 13:35:49 +00:00
|
|
|
|
* pass it to the index set when CALL_NON_NULL_BLOCK returned NO. */
|
2019-09-25 09:14:43 +00:00
|
|
|
|
[set addIndex: count];
|
2012-03-27 17:05:19 +00:00
|
|
|
|
}
|
|
|
|
|
if (shouldStop)
|
|
|
|
|
{
|
2019-09-25 09:14:43 +00:00
|
|
|
|
break;
|
2012-03-27 17:05:19 +00:00
|
|
|
|
}
|
|
|
|
|
count++;
|
|
|
|
|
END_FOR_IN(enumerator)
|
|
|
|
|
GS_DISPATCH_TEARDOWN_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts);
|
|
|
|
|
}
|
2015-06-04 09:18:52 +00:00
|
|
|
|
RELEASE(setLock);
|
2010-06-15 11:26:00 +00:00
|
|
|
|
return set;
|
2009-12-27 16:49:52 +00:00
|
|
|
|
}
|
2010-06-15 11:26:00 +00:00
|
|
|
|
|
|
|
|
|
- (NSIndexSet*) indexesOfObjectsPassingTest: (GSPredicateBlock)predicate
|
2009-12-27 16:49:52 +00:00
|
|
|
|
{
|
2010-06-15 11:26:00 +00:00
|
|
|
|
return [self indexesOfObjectsWithOptions: 0 passingTest: predicate];
|
2009-12-27 15:25:12 +00:00
|
|
|
|
}
|
2010-06-15 11:26:00 +00:00
|
|
|
|
|
|
|
|
|
- (NSIndexSet*) indexesOfObjectsAtIndexes: (NSIndexSet*)indexSet
|
|
|
|
|
options: (NSEnumerationOptions)opts
|
|
|
|
|
passingTest: (GSPredicateBlock)predicate
|
2009-12-27 16:49:52 +00:00
|
|
|
|
{
|
2019-07-02 05:00:41 +00:00
|
|
|
|
NSIndexSet *rindexes =[[self objectsAtIndexes: indexSet]
|
|
|
|
|
indexesOfObjectsWithOptions: opts
|
|
|
|
|
passingTest: predicate];
|
|
|
|
|
NSUInteger count = [indexSet count];
|
|
|
|
|
NSUInteger resultCount = [rindexes count];
|
|
|
|
|
NSUInteger indexArray[count], resultIndexArray[resultCount];
|
|
|
|
|
NSMutableIndexSet *resultSet = [NSMutableIndexSet indexSet];
|
|
|
|
|
NSUInteger i = 0;
|
|
|
|
|
|
|
|
|
|
[indexSet getIndexes: indexArray
|
|
|
|
|
maxCount: count
|
|
|
|
|
inIndexRange: NULL];
|
|
|
|
|
|
|
|
|
|
[rindexes getIndexes: resultIndexArray
|
|
|
|
|
maxCount: resultCount
|
|
|
|
|
inIndexRange: NULL];
|
|
|
|
|
|
|
|
|
|
// interate over indexes and collect the matching ones..
|
|
|
|
|
for(i = 0; i < resultCount; i++)
|
|
|
|
|
{
|
|
|
|
|
NSUInteger rindx = resultIndexArray[i];
|
|
|
|
|
NSUInteger indx = indexArray[rindx];
|
|
|
|
|
[resultSet addIndex: indx];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return resultSet;
|
2009-12-27 16:49:52 +00:00
|
|
|
|
}
|
2010-06-15 11:26:00 +00:00
|
|
|
|
|
2015-07-15 14:14:21 +00:00
|
|
|
|
- (NSUInteger) indexOfObjectWithOptions: (NSEnumerationOptions)opts
|
|
|
|
|
passingTest: (GSPredicateBlock)predicate
|
2009-12-27 16:49:52 +00:00
|
|
|
|
{
|
2010-06-15 11:26:00 +00:00
|
|
|
|
/* TODO: Concurrency. */
|
|
|
|
|
id<NSFastEnumeration> enumerator = self;
|
2015-06-04 09:18:52 +00:00
|
|
|
|
BLOCK_SCOPE BOOL shouldStop = NO;
|
|
|
|
|
NSUInteger count = 0;
|
2012-03-27 17:05:19 +00:00
|
|
|
|
BLOCK_SCOPE NSUInteger index = NSNotFound;
|
2015-06-04 09:18:52 +00:00
|
|
|
|
BLOCK_SCOPE NSLock *indexLock = nil;
|
|
|
|
|
|
2010-06-15 11:26:00 +00:00
|
|
|
|
/* If we are enumerating in reverse, use the reverse enumerator for fast
|
|
|
|
|
* enumeration. */
|
|
|
|
|
if (opts & NSEnumerationReverse)
|
|
|
|
|
{
|
|
|
|
|
enumerator = [self reverseObjectEnumerator];
|
|
|
|
|
}
|
2009-12-27 15:25:12 +00:00
|
|
|
|
|
2012-03-27 17:05:19 +00:00
|
|
|
|
if (opts & NSEnumerationConcurrent)
|
2015-06-04 09:18:52 +00:00
|
|
|
|
{
|
|
|
|
|
indexLock = [NSLock new];
|
|
|
|
|
}
|
2012-03-27 17:05:19 +00:00
|
|
|
|
{
|
|
|
|
|
GS_DISPATCH_CREATE_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts)
|
|
|
|
|
FOR_IN (id, obj, enumerator)
|
|
|
|
|
# if __has_feature(blocks) && (GS_USE_LIBDISPATCH == 1)
|
2019-09-25 09:14:43 +00:00
|
|
|
|
if (enumQueue != NULL)
|
2012-03-27 17:05:19 +00:00
|
|
|
|
{
|
2019-09-25 09:14:43 +00:00
|
|
|
|
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];
|
|
|
|
|
}
|
|
|
|
|
});
|
2012-03-27 17:05:19 +00:00
|
|
|
|
}
|
2019-09-25 09:14:43 +00:00
|
|
|
|
else // call block directly
|
|
|
|
|
# endif
|
2021-11-17 13:35:49 +00:00
|
|
|
|
if (CALL_NON_NULL_BLOCK(predicate, obj, count, &shouldStop))
|
2012-03-27 17:05:19 +00:00
|
|
|
|
{
|
2019-09-25 09:14:43 +00:00
|
|
|
|
index = count;
|
|
|
|
|
shouldStop = YES;
|
2012-03-27 17:05:19 +00:00
|
|
|
|
}
|
|
|
|
|
if (shouldStop)
|
|
|
|
|
{
|
2019-09-25 09:14:43 +00:00
|
|
|
|
break;
|
2012-03-27 17:05:19 +00:00
|
|
|
|
}
|
|
|
|
|
count++;
|
|
|
|
|
END_FOR_IN(enumerator)
|
|
|
|
|
GS_DISPATCH_TEARDOWN_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts);
|
|
|
|
|
}
|
2015-06-04 09:18:52 +00:00
|
|
|
|
RELEASE(indexLock);
|
2012-03-27 17:05:19 +00:00
|
|
|
|
return index;
|
2009-12-27 16:49:52 +00:00
|
|
|
|
}
|
2010-06-15 11:26:00 +00:00
|
|
|
|
|
|
|
|
|
- (NSUInteger) indexOfObjectPassingTest: (GSPredicateBlock)predicate
|
2009-12-27 16:49:52 +00:00
|
|
|
|
{
|
2010-06-15 11:26:00 +00:00
|
|
|
|
return [self indexOfObjectWithOptions: 0 passingTest: predicate];
|
2009-12-27 16:49:52 +00:00
|
|
|
|
}
|
2010-06-15 11:26:00 +00:00
|
|
|
|
|
2015-07-15 14:14:21 +00:00
|
|
|
|
- (NSUInteger) indexOfObjectAtIndexes: (NSIndexSet*)indexSet
|
|
|
|
|
options: (NSEnumerationOptions)opts
|
|
|
|
|
passingTest: (GSPredicateBlock)predicate
|
2009-12-27 16:49:52 +00:00
|
|
|
|
{
|
2019-07-02 05:00:41 +00:00
|
|
|
|
NSUInteger index = [[self objectsAtIndexes: indexSet]
|
|
|
|
|
indexOfObjectWithOptions: 0
|
|
|
|
|
passingTest: predicate];
|
|
|
|
|
NSUInteger count = [indexSet count];
|
|
|
|
|
NSUInteger indexArray[count];
|
|
|
|
|
|
|
|
|
|
[indexSet getIndexes: indexArray
|
|
|
|
|
maxCount: count
|
|
|
|
|
inIndexRange: NULL];
|
|
|
|
|
|
|
|
|
|
return indexArray[index];
|
2015-07-15 14:14:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
1995-04-03 22:59:20 +00:00
|
|
|
|
@end
|
|
|
|
|
|
1996-03-31 22:23:37 +00:00
|
|
|
|
|
2004-06-22 22:40:40 +00:00
|
|
|
|
/**
|
|
|
|
|
* <code>NSMutableArray</code> is the mutable version of [NSArray]. It
|
|
|
|
|
* provides methods for altering the contents of the array.
|
|
|
|
|
*/
|
1996-03-31 22:23:37 +00:00
|
|
|
|
@implementation NSMutableArray
|
1995-04-03 22:59:20 +00:00
|
|
|
|
|
1996-03-31 22:23:37 +00:00
|
|
|
|
+ (void) initialize
|
1995-05-05 15:50:26 +00:00
|
|
|
|
{
|
1996-03-31 22:23:37 +00:00
|
|
|
|
if (self == [NSMutableArray class])
|
1996-05-06 19:57:29 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
1995-05-05 15:50:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
+ (id) allocWithZone: (NSZone*)z
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
if (self == NSMutableArrayClass)
|
2000-08-07 22:00:31 +00:00
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
return NSAllocateObject(GSMutableArrayClass, 0, z);
|
2000-08-07 22:00:31 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return NSAllocateObject(self, 0, z);
|
|
|
|
|
}
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-10-30 18:00:27 +00:00
|
|
|
|
+ (id) arrayWithObject: (id)anObject
|
|
|
|
|
{
|
|
|
|
|
NSMutableArray *obj = [self allocWithZone: NSDefaultMallocZone()];
|
|
|
|
|
|
|
|
|
|
obj = [obj initWithObjects: &anObject count: 1];
|
2000-11-12 13:58:52 +00:00
|
|
|
|
return AUTORELEASE(obj);
|
2000-10-30 18:00:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-10-16 12:35:42 +00:00
|
|
|
|
- (Class) classForCoder
|
|
|
|
|
{
|
2001-01-08 16:45:36 +00:00
|
|
|
|
return NSMutableArrayClass;
|
2000-10-16 12:35:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2009-02-23 20:42:32 +00:00
|
|
|
|
- (id) initWithCapacity: (NSUInteger)numItems
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
2004-09-07 05:43:20 +00:00
|
|
|
|
self = [self init];
|
|
|
|
|
return self;
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-08-27 11:09:12 +00:00
|
|
|
|
- (void) addObject: (id)anObject
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1997-09-01 21:59:51 +00:00
|
|
|
|
[self subclassResponsibility: _cmd];
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-08-27 11:09:12 +00:00
|
|
|
|
/**
|
|
|
|
|
* Swaps the positions of two objects in the array. Raises an exception
|
|
|
|
|
* if either array index is out of bounds.
|
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
|
- (void) exchangeObjectAtIndex: (NSUInteger)i1
|
|
|
|
|
withObjectAtIndex: (NSUInteger)i2
|
2002-08-27 11:09:12 +00:00
|
|
|
|
{
|
|
|
|
|
id tmp = [self objectAtIndex: i1];
|
|
|
|
|
|
2015-06-04 09:18:52 +00:00
|
|
|
|
RETAIN(tmp);
|
2002-08-27 11:09:12 +00:00
|
|
|
|
[self replaceObjectAtIndex: i1 withObject: [self objectAtIndex: i2]];
|
|
|
|
|
[self replaceObjectAtIndex: i2 withObject: tmp];
|
|
|
|
|
RELEASE(tmp);
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-23 20:42:32 +00:00
|
|
|
|
- (void) replaceObjectAtIndex: (NSUInteger)index withObject: (id)anObject
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1999-04-08 12:17:15 +00:00
|
|
|
|
[self subclassResponsibility: _cmd];
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-02-24 07:41:20 +00:00
|
|
|
|
- (void) setObject: (id)anObject atIndexedSubscript: (NSUInteger)anIndex
|
2012-04-06 12:23:10 +00:00
|
|
|
|
{
|
2016-02-24 07:41:20 +00:00
|
|
|
|
if ([self count] == anIndex)
|
|
|
|
|
{
|
|
|
|
|
[self addObject: anObject];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
[self replaceObjectAtIndex: anIndex withObject: anObject];
|
|
|
|
|
}
|
2012-04-06 12:23:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
2009-02-09 16:16:11 +00:00
|
|
|
|
/** Replaces the values in the receiver at the locations given by the
|
|
|
|
|
* indexes set with values from the objects array.
|
2008-06-06 13:57:06 +00:00
|
|
|
|
*/
|
|
|
|
|
- (void) replaceObjectsAtIndexes: (NSIndexSet *)indexes
|
|
|
|
|
withObjects: (NSArray *)objects
|
|
|
|
|
{
|
2009-02-09 16:16:11 +00:00
|
|
|
|
NSUInteger index = [indexes firstIndex];
|
|
|
|
|
NSEnumerator *enumerator = [objects objectEnumerator];
|
|
|
|
|
id object = [enumerator nextObject];
|
|
|
|
|
|
|
|
|
|
while (object != nil && index != NSNotFound)
|
|
|
|
|
{
|
|
|
|
|
[self replaceObjectAtIndex: index withObject: object];
|
|
|
|
|
object = [enumerator nextObject];
|
|
|
|
|
index = [indexes indexGreaterThanIndex: index];
|
|
|
|
|
}
|
2008-06-06 13:57:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-08-27 11:09:12 +00:00
|
|
|
|
/**
|
|
|
|
|
* Replaces objects in the receiver with those from anArray.<br />
|
|
|
|
|
* Raises an exception if given a range extending beyond the array.<br />
|
|
|
|
|
*/
|
1998-01-19 15:20:15 +00:00
|
|
|
|
- (void) replaceObjectsInRange: (NSRange)aRange
|
|
|
|
|
withObjectsFromArray: (NSArray*)anArray
|
|
|
|
|
{
|
1998-04-06 02:09:44 +00:00
|
|
|
|
id e, o;
|
1998-01-19 15:20:15 +00:00
|
|
|
|
|
1998-04-06 02:09:44 +00:00
|
|
|
|
if ([self count] < (aRange.location + aRange.length))
|
1998-01-19 15:20:15 +00:00
|
|
|
|
[NSException raise: NSRangeException
|
|
|
|
|
format: @"Replacing objects beyond end of array."];
|
|
|
|
|
[self removeObjectsInRange: aRange];
|
1998-04-06 02:09:44 +00:00
|
|
|
|
e = [anArray reverseObjectEnumerator];
|
|
|
|
|
while ((o = [e nextObject]))
|
|
|
|
|
[self insertObject: o atIndex: aRange.location];
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-08-27 11:09:12 +00:00
|
|
|
|
/**
|
|
|
|
|
* Replaces objects in the receiver with some of those from anArray.<br />
|
|
|
|
|
* Raises an exception if given a range extending beyond the array.<br />
|
|
|
|
|
*/
|
1998-01-19 15:20:15 +00:00
|
|
|
|
- (void) replaceObjectsInRange: (NSRange)aRange
|
|
|
|
|
withObjectsFromArray: (NSArray*)anArray
|
|
|
|
|
range: (NSRange)anotherRange
|
|
|
|
|
{
|
|
|
|
|
[self replaceObjectsInRange: aRange
|
|
|
|
|
withObjectsFromArray: [anArray subarrayWithRange: anotherRange]];
|
|
|
|
|
}
|
|
|
|
|
|
2009-02-23 20:42:32 +00:00
|
|
|
|
- (void) insertObject: anObject atIndex: (NSUInteger)index
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1999-04-08 12:17:15 +00:00
|
|
|
|
[self subclassResponsibility: _cmd];
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2009-02-09 16:16:11 +00:00
|
|
|
|
/** Inserts the values from the objects array into the receiver at the
|
|
|
|
|
* locations given by the indexes set.<br />
|
|
|
|
|
* The values are inserted in the same order that they appear in the
|
|
|
|
|
* array.
|
2008-06-06 13:57:06 +00:00
|
|
|
|
*/
|
|
|
|
|
- (void) insertObjects: (NSArray *)objects atIndexes: (NSIndexSet *)indexes
|
|
|
|
|
{
|
2009-02-09 16:16:11 +00:00
|
|
|
|
NSUInteger index = [indexes firstIndex];
|
|
|
|
|
NSEnumerator *enumerator = [objects objectEnumerator];
|
|
|
|
|
id object = [enumerator nextObject];
|
|
|
|
|
|
|
|
|
|
while (object != nil && index != NSNotFound)
|
|
|
|
|
{
|
|
|
|
|
[self insertObject: object atIndex: index];
|
|
|
|
|
object = [enumerator nextObject];
|
|
|
|
|
index = [indexes indexGreaterThanIndex: index];
|
|
|
|
|
}
|
2008-06-06 13:57:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2009-02-23 20:42:32 +00:00
|
|
|
|
- (void) removeObjectAtIndex: (NSUInteger)index
|
1995-04-03 22:59:20 +00:00
|
|
|
|
{
|
1999-04-08 12:17:15 +00:00
|
|
|
|
[self subclassResponsibility: _cmd];
|
1995-04-03 22:59:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* Creates an autoreleased mutable array able to store at least numItems.
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* See the -initWithCapacity: method.
|
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
|
+ (id) arrayWithCapacity: (NSUInteger)numItems
|
1996-03-31 22:23:37 +00:00
|
|
|
|
{
|
1999-06-30 21:13:19 +00:00
|
|
|
|
return AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()]
|
|
|
|
|
initWithCapacity: numItems]);
|
1996-03-31 22:23:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-09-07 05:43:20 +00:00
|
|
|
|
/**
|
|
|
|
|
* Override our superclass's designated initializer to go our's
|
|
|
|
|
*/
|
2011-07-22 16:07:23 +00:00
|
|
|
|
- (id) initWithObjects: (const id[])objects count: (NSUInteger)count
|
1996-03-31 22:23:37 +00:00
|
|
|
|
{
|
|
|
|
|
self = [self initWithCapacity: count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP add = [self methodForSelector: addSel];
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
|
(*add)(self, addSel, objects[i]);
|
|
|
|
|
}
|
1996-03-31 22:23:37 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
2024-08-10 21:44:02 +00:00
|
|
|
|
* Removes the last object in the array if one exists (otherwise it just returns).
|
2002-11-04 08:06:48 +00:00
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (void) removeLastObject
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger count = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
1996-03-30 23:00:27 +00:00
|
|
|
|
if (count == 0)
|
2024-08-10 21:44:02 +00:00
|
|
|
|
return;
|
1999-04-08 12:17:15 +00:00
|
|
|
|
[self removeObjectAtIndex: count-1];
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
2004-06-22 22:40:40 +00:00
|
|
|
|
* Removes all occurrences of anObject (found by pointer equality)
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* from the receiver.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (void) removeObjectIdenticalTo: (id)anObject
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i;
|
1996-04-30 14:25:22 +00:00
|
|
|
|
|
1999-11-04 10:42:20 +00:00
|
|
|
|
if (anObject == nil)
|
|
|
|
|
{
|
2001-05-22 09:30:07 +00:00
|
|
|
|
NSWarnMLog(@"attempt to remove nil object");
|
1999-11-04 10:42:20 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
i = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (i > 0)
|
1998-02-03 14:20:00 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP rem = 0;
|
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
|
|
|
|
|
|
|
|
|
while (i-- > 0)
|
1998-02-03 14:20:00 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
id o = (*get)(self, oaiSel, i);
|
|
|
|
|
|
|
|
|
|
if (o == anObject)
|
|
|
|
|
{
|
|
|
|
|
if (rem == 0)
|
1999-12-13 12:14:01 +00:00
|
|
|
|
{
|
|
|
|
|
rem = [self methodForSelector: remSel];
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
(*rem)(self, remSel, i);
|
|
|
|
|
}
|
1998-02-03 14:20:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
2005-11-28 15:41:35 +00:00
|
|
|
|
* Removes all occurrences of anObject (found by the [NSObject-isEqual:] method
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* of anObject) aRange in the receiver.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (void) removeObject: (id)anObject inRange: (NSRange)aRange
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger c;
|
|
|
|
|
NSUInteger s;
|
|
|
|
|
NSUInteger i;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
1999-11-04 10:42:20 +00:00
|
|
|
|
if (anObject == nil)
|
|
|
|
|
{
|
2001-05-22 09:30:07 +00:00
|
|
|
|
NSWarnMLog(@"attempt to remove nil object");
|
1999-11-04 10:42:20 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
c = [self count];
|
|
|
|
|
s = aRange.location;
|
|
|
|
|
i = aRange.location + aRange.length;
|
1998-01-19 15:20:15 +00:00
|
|
|
|
if (i > c)
|
1999-11-04 10:42:20 +00:00
|
|
|
|
{
|
|
|
|
|
i = c;
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (i > s)
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP rem = 0;
|
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
|
|
|
|
BOOL (*eq)(id, SEL, id)
|
|
|
|
|
= (BOOL (*)(id, SEL, id))[anObject methodForSelector: eqSel];
|
|
|
|
|
|
|
|
|
|
while (i-- > s)
|
1998-02-03 14:20:00 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
id o = (*get)(self, oaiSel, i);
|
|
|
|
|
|
|
|
|
|
if (o == anObject || (*eq)(anObject, eqSel, o) == YES)
|
|
|
|
|
{
|
|
|
|
|
if (rem == 0)
|
1999-12-13 12:14:01 +00:00
|
|
|
|
{
|
|
|
|
|
rem = [self methodForSelector: remSel];
|
|
|
|
|
/*
|
|
|
|
|
* We need to retain the object so that when we remove the
|
|
|
|
|
* first equal object we don't get left with a bad object
|
|
|
|
|
* pointer for later comparisons.
|
|
|
|
|
*/
|
2015-06-04 09:18:52 +00:00
|
|
|
|
RETAIN(anObject);
|
1999-12-13 12:14:01 +00:00
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
(*rem)(self, remSel, i);
|
|
|
|
|
}
|
1998-02-03 14:20:00 +00:00
|
|
|
|
}
|
1999-12-13 12:14:01 +00:00
|
|
|
|
if (rem != 0)
|
|
|
|
|
{
|
|
|
|
|
RELEASE(anObject);
|
|
|
|
|
}
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* Removes all occurrences of anObject (found by pointer equality)
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* from aRange in the receiver.
|
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (void) removeObjectIdenticalTo: (id)anObject inRange: (NSRange)aRange
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger c;
|
|
|
|
|
NSUInteger s;
|
|
|
|
|
NSUInteger i;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
1999-11-04 10:42:20 +00:00
|
|
|
|
if (anObject == nil)
|
|
|
|
|
{
|
2001-05-22 09:30:07 +00:00
|
|
|
|
NSWarnMLog(@"attempt to remove nil object");
|
1999-11-04 10:42:20 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
c = [self count];
|
|
|
|
|
s = aRange.location;
|
|
|
|
|
i = aRange.location + aRange.length;
|
1998-01-19 15:20:15 +00:00
|
|
|
|
if (i > c)
|
1999-11-04 10:42:20 +00:00
|
|
|
|
{
|
|
|
|
|
i = c;
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (i > s)
|
1998-01-19 15:20:15 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP rem = 0;
|
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
|
|
|
|
|
|
|
|
|
while (i-- > s)
|
1998-02-03 14:20:00 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
id o = (*get)(self, oaiSel, i);
|
|
|
|
|
|
|
|
|
|
if (o == anObject)
|
|
|
|
|
{
|
|
|
|
|
if (rem == 0)
|
1999-12-13 12:14:01 +00:00
|
|
|
|
{
|
|
|
|
|
rem = [self methodForSelector: remSel];
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
(*rem)(self, remSel, i);
|
|
|
|
|
}
|
1998-02-03 14:20:00 +00:00
|
|
|
|
}
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
2005-11-28 15:41:35 +00:00
|
|
|
|
* Removes all occurrences of anObject (found by anObject's
|
|
|
|
|
* [NSObject-isEqual:] method) from the receiver.
|
2002-11-04 08:06:48 +00:00
|
|
|
|
*/
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (void) removeObject: (id)anObject
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i;
|
1996-04-30 14:25:22 +00:00
|
|
|
|
|
1999-11-04 10:42:20 +00:00
|
|
|
|
if (anObject == nil)
|
|
|
|
|
{
|
2001-05-22 09:30:07 +00:00
|
|
|
|
NSWarnMLog(@"attempt to remove nil object");
|
1999-11-04 10:42:20 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
i = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (i > 0)
|
1998-02-03 14:20:00 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP rem = 0;
|
|
|
|
|
IMP get = [self methodForSelector: oaiSel];
|
|
|
|
|
BOOL (*eq)(id, SEL, id)
|
|
|
|
|
= (BOOL (*)(id, SEL, id))[anObject methodForSelector: eqSel];
|
|
|
|
|
|
|
|
|
|
while (i-- > 0)
|
1998-02-03 14:20:00 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
id o = (*get)(self, oaiSel, i);
|
|
|
|
|
|
|
|
|
|
if (o == anObject || (*eq)(anObject, eqSel, o) == YES)
|
|
|
|
|
{
|
|
|
|
|
if (rem == 0)
|
1999-12-13 12:14:01 +00:00
|
|
|
|
{
|
|
|
|
|
rem = [self methodForSelector: remSel];
|
|
|
|
|
/*
|
|
|
|
|
* We need to retain the object so that when we remove the
|
|
|
|
|
* first equal object we don't get left with a bad object
|
|
|
|
|
* pointer for later comparisons.
|
|
|
|
|
*/
|
2015-06-04 09:18:52 +00:00
|
|
|
|
RETAIN(anObject);
|
1999-12-13 12:14:01 +00:00
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
(*rem)(self, remSel, i);
|
|
|
|
|
}
|
1998-02-03 14:20:00 +00:00
|
|
|
|
}
|
1999-12-13 12:14:01 +00:00
|
|
|
|
if (rem != 0)
|
|
|
|
|
{
|
|
|
|
|
RELEASE(anObject);
|
|
|
|
|
}
|
1998-02-03 14:20:00 +00:00
|
|
|
|
}
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Removes all objects from the receiver, leaving an empty array.
|
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (void) removeAllObjects
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger c = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
|
|
|
|
if (c > 0)
|
|
|
|
|
{
|
|
|
|
|
IMP remLast = [self methodForSelector: rlSel];
|
|
|
|
|
|
|
|
|
|
while (c--)
|
1999-12-13 12:14:01 +00:00
|
|
|
|
{
|
|
|
|
|
(*remLast)(self, rlSel);
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
}
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Adds each object from otherArray to the receiver, in first to last order.
|
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (void) addObjectsFromArray: (NSArray*)otherArray
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger c = [otherArray count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
|
|
|
|
if (c > 0)
|
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP get = [otherArray methodForSelector: oaiSel];
|
|
|
|
|
IMP add = [self methodForSelector: addSel];
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < c; i++)
|
|
|
|
|
(*add)(self, addSel, (*get)(otherArray, oaiSel, i));
|
|
|
|
|
}
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Sets the contents of the receiver to be identical to the contents
|
2005-11-06 13:53:40 +00:00
|
|
|
|
* of otherArray.
|
2002-11-04 08:06:48 +00:00
|
|
|
|
*/
|
1999-04-08 12:17:15 +00:00
|
|
|
|
- (void) setArray: (NSArray *)otherArray
|
1996-03-30 19:14:43 +00:00
|
|
|
|
{
|
|
|
|
|
[self removeAllObjects];
|
1996-03-31 22:23:37 +00:00
|
|
|
|
[self addObjectsFromArray: otherArray];
|
1996-03-30 19:14:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-07-10 17:16:31 +00:00
|
|
|
|
/**
|
|
|
|
|
* Removes objects from the receiver at the indices supplied by an NSIndexSet
|
|
|
|
|
*/
|
|
|
|
|
- (void) removeObjectsAtIndexes: (NSIndexSet *)indexes
|
|
|
|
|
{
|
2009-02-23 20:42:32 +00:00
|
|
|
|
NSUInteger count = [indexes count];
|
|
|
|
|
NSUInteger indexArray[count];
|
2007-07-10 17:16:31 +00:00
|
|
|
|
|
2012-03-27 17:05:19 +00:00
|
|
|
|
[indexes getIndexes: indexArray
|
|
|
|
|
maxCount: count
|
2007-07-10 17:16:31 +00:00
|
|
|
|
inIndexRange: NULL];
|
|
|
|
|
|
|
|
|
|
[self removeObjectsFromIndices: indexArray
|
|
|
|
|
numIndices: count];
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Supplied with a C array of indices containing count values, this method
|
|
|
|
|
* removes all corresponding objects from the receiver. The objects are
|
2005-02-22 11:22:44 +00:00
|
|
|
|
* removed in such a way that the removal is <em>safe</em> irrespective
|
2002-11-04 08:06:48 +00:00
|
|
|
|
* of the order in which they are specified in the indices array.
|
|
|
|
|
*/
|
2009-02-23 20:42:32 +00:00
|
|
|
|
- (void) removeObjectsFromIndices: (NSUInteger*)indices
|
|
|
|
|
numIndices: (NSUInteger)count
|
1994-11-08 16:44:01 +00:00
|
|
|
|
{
|
1999-02-16 16:08:59 +00:00
|
|
|
|
if (count > 0)
|
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger to = 0;
|
|
|
|
|
NSUInteger from = 0;
|
|
|
|
|
NSUInteger i;
|
2009-02-23 20:42:32 +00:00
|
|
|
|
GS_BEGINITEMBUF(sorted, count, NSUInteger);
|
1999-02-16 16:08:59 +00:00
|
|
|
|
|
|
|
|
|
while (from < count)
|
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger val = indices[from++];
|
1999-02-16 16:08:59 +00:00
|
|
|
|
|
|
|
|
|
i = to;
|
2002-12-10 05:44:56 +00:00
|
|
|
|
while (i > 0 && sorted[i-1] > val)
|
1999-02-16 16:08:59 +00:00
|
|
|
|
{
|
|
|
|
|
i--;
|
|
|
|
|
}
|
|
|
|
|
if (i == to)
|
|
|
|
|
{
|
|
|
|
|
sorted[to++] = val;
|
|
|
|
|
}
|
1999-02-16 16:18:26 +00:00
|
|
|
|
else if (sorted[i] != val)
|
1999-02-16 16:08:59 +00:00
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger j = to++;
|
1999-02-16 16:08:59 +00:00
|
|
|
|
|
1999-02-16 16:18:26 +00:00
|
|
|
|
if (sorted[i] < val)
|
|
|
|
|
{
|
|
|
|
|
i++;
|
|
|
|
|
}
|
1999-02-16 16:08:59 +00:00
|
|
|
|
while (j > i)
|
|
|
|
|
{
|
|
|
|
|
sorted[j] = sorted[j-1];
|
|
|
|
|
j--;
|
|
|
|
|
}
|
|
|
|
|
sorted[i] = val;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (to > 0)
|
1999-02-16 16:08:59 +00:00
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
IMP rem = [self methodForSelector: remSel];
|
|
|
|
|
|
|
|
|
|
while (to--)
|
|
|
|
|
{
|
|
|
|
|
(*rem)(self, remSel, sorted[to]);
|
|
|
|
|
}
|
1999-02-16 16:08:59 +00:00
|
|
|
|
}
|
2004-09-07 14:27:14 +00:00
|
|
|
|
GS_ENDITEMBUF();
|
1999-02-16 16:08:59 +00:00
|
|
|
|
}
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Removes from the receiver, all the objects present in otherArray,
|
2005-11-28 15:41:35 +00:00
|
|
|
|
* as determined by using the [NSObject-isEqual:] method.
|
2002-11-04 08:06:48 +00:00
|
|
|
|
*/
|
(allocWithZone): Removed method.
(arrayWithObjects:, initWithObjects:, initWithArray:, count,
indexOfObjectIdenticalTo:, indexOfObject:, isEqualToArray:,
makeObjectsPerform:, makeObjectsPerform:withObject:, lastObject,
firstObjectCommonWithArray:, arrayWithCapacity:, addObject:,
replaceObjectAtIndex:, removeLastObject, insertObject:atIndex:,
removeObjectAtIndex:, removeObjectIdenticalTo:, removeObject:,
removeAllObjects, addObjectsFromArray:,
removeObjectsFromIndices:numIndices:, removeObjectsInArray:,
copyWithZone:, mutableCopyWithZone:): Newly implemented or majorly
overhauled.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@285 72102866-910b-0410-8b05-ffd578937521
1995-04-05 20:23:03 +00:00
|
|
|
|
- (void) removeObjectsInArray: (NSArray*)otherArray
|
|
|
|
|
{
|
2019-09-25 08:54:59 +00:00
|
|
|
|
if (otherArray == self)
|
1999-09-14 19:24:58 +00:00
|
|
|
|
{
|
2019-09-25 08:54:59 +00:00
|
|
|
|
[self removeAllObjects];
|
|
|
|
|
}
|
|
|
|
|
else if (otherArray != nil)
|
|
|
|
|
{
|
|
|
|
|
NSUInteger c;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
2019-09-25 08:54:59 +00:00
|
|
|
|
if (NO == [otherArray isKindOfClass: NSArrayClass])
|
|
|
|
|
{
|
|
|
|
|
[NSException raise: NSInvalidArgumentException
|
|
|
|
|
format: @"-removeObjectsInArray: non-array argument"];
|
|
|
|
|
}
|
|
|
|
|
if ((c = [otherArray count]) > 0)
|
|
|
|
|
{
|
|
|
|
|
NSUInteger i;
|
|
|
|
|
IMP get = [otherArray methodForSelector: oaiSel];
|
|
|
|
|
IMP rem = [self methodForSelector: @selector(removeObject:)];
|
|
|
|
|
|
|
|
|
|
/* Guard otherArray in case it's a subclass which does not
|
|
|
|
|
* retain its contents; in that case it would be possible
|
|
|
|
|
* for otherArray to be contained by the receiver and be
|
|
|
|
|
* deallocated during the loop below.
|
|
|
|
|
*/
|
|
|
|
|
RETAIN(otherArray);
|
|
|
|
|
for (i = 0; i < c; i++)
|
|
|
|
|
{
|
|
|
|
|
(*rem)(self, @selector(removeObject:),
|
|
|
|
|
(*get)(otherArray, oaiSel, i));
|
|
|
|
|
}
|
|
|
|
|
RELEASE(otherArray);
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
}
|
1994-11-08 16:44:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Removes all the objects in aRange from the receiver.
|
|
|
|
|
*/
|
1998-01-19 15:20:15 +00:00
|
|
|
|
- (void) removeObjectsInRange: (NSRange)aRange
|
|
|
|
|
{
|
2015-06-04 09:18:52 +00:00
|
|
|
|
NSUInteger i;
|
|
|
|
|
NSUInteger s = aRange.location;
|
|
|
|
|
NSUInteger c = [self count];
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
1998-01-19 15:20:15 +00:00
|
|
|
|
i = aRange.location + aRange.length;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
1998-01-19 15:20:15 +00:00
|
|
|
|
if (c < i)
|
|
|
|
|
i = c;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
|
|
|
|
|
if (i > s)
|
|
|
|
|
{
|
|
|
|
|
IMP rem = [self methodForSelector: remSel];
|
|
|
|
|
|
|
|
|
|
while (i-- > s)
|
1999-12-13 12:14:01 +00:00
|
|
|
|
{
|
|
|
|
|
(*rem)(self, remSel, i);
|
|
|
|
|
}
|
1999-09-14 19:24:58 +00:00
|
|
|
|
}
|
1998-01-19 15:20:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Sorts the array according to the supplied comparator.
|
|
|
|
|
*/
|
1997-09-01 21:59:51 +00:00
|
|
|
|
- (void) sortUsingSelector: (SEL)comparator
|
|
|
|
|
{
|
2001-09-05 21:31:42 +00:00
|
|
|
|
[self sortUsingFunction: compare context: (void *)comparator];
|
1997-09-01 21:59:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Sorts the array according to the supplied compare function
|
|
|
|
|
* with the context information.
|
|
|
|
|
*/
|
2005-02-22 11:22:44 +00:00
|
|
|
|
- (void) sortUsingFunction: (NSComparisonResult (*)(id,id,void*))compare
|
1999-12-01 19:36:20 +00:00
|
|
|
|
context: (void*)context
|
1995-04-03 03:18:43 +00:00
|
|
|
|
{
|
2012-09-19 13:31:09 +00:00
|
|
|
|
NSUInteger count = [self count];
|
2012-09-19 14:20:01 +00:00
|
|
|
|
|
2012-09-19 13:31:09 +00:00
|
|
|
|
if ((1 < count) && (NULL != compare))
|
2012-09-19 14:20:01 +00:00
|
|
|
|
{
|
|
|
|
|
NSArray *res = nil;
|
|
|
|
|
GS_BEGINIDBUF(objects, count);
|
|
|
|
|
[self getObjects: objects];
|
1997-01-09 16:24:07 +00:00
|
|
|
|
|
2012-09-19 14:20:01 +00:00
|
|
|
|
GSSortUnstable(objects,
|
|
|
|
|
NSMakeRange(0,count), (id)compare, GSComparisonTypeFunction, context);
|
2005-02-22 11:22:44 +00:00
|
|
|
|
|
2012-09-19 14:20:01 +00:00
|
|
|
|
res = [[NSArray alloc] initWithObjects: objects count: count];
|
|
|
|
|
[self setArray: res];
|
|
|
|
|
RELEASE(res);
|
|
|
|
|
GS_ENDIDBUF();
|
|
|
|
|
}
|
2012-09-19 13:31:09 +00:00
|
|
|
|
}
|
1999-12-01 19:36:20 +00:00
|
|
|
|
|
2012-09-19 13:31:09 +00:00
|
|
|
|
- (void) sortWithOptions: (NSSortOptions)options
|
|
|
|
|
usingComparator: (NSComparator)comparator
|
|
|
|
|
{
|
|
|
|
|
NSUInteger count = [self count];
|
|
|
|
|
|
2012-09-19 14:20:01 +00:00
|
|
|
|
if ((1 < count) && (NULL != comparator))
|
1999-12-01 19:36:20 +00:00
|
|
|
|
{
|
2012-09-19 14:20:01 +00:00
|
|
|
|
NSArray *res = nil;
|
|
|
|
|
GS_BEGINIDBUF(objects, count);
|
|
|
|
|
[self getObjects: objects];
|
|
|
|
|
|
|
|
|
|
if (options & NSSortStable)
|
|
|
|
|
{
|
|
|
|
|
if (options & NSSortConcurrent)
|
|
|
|
|
{
|
|
|
|
|
GSSortStableConcurrent(objects, NSMakeRange(0,count),
|
|
|
|
|
(id)comparator, GSComparisonTypeComparatorBlock, NULL);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
GSSortStable(objects, NSMakeRange(0,count),
|
|
|
|
|
(id)comparator, GSComparisonTypeComparatorBlock, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (options & NSSortConcurrent)
|
|
|
|
|
{
|
|
|
|
|
GSSortUnstableConcurrent(objects, NSMakeRange(0,count),
|
|
|
|
|
(id)comparator, GSComparisonTypeComparatorBlock, NULL);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
GSSortUnstable(objects, NSMakeRange(0,count),
|
|
|
|
|
(id)comparator, GSComparisonTypeComparatorBlock, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
res = [[NSArray alloc] initWithObjects: objects count: count];
|
|
|
|
|
[self setArray: res];
|
|
|
|
|
RELEASE(res);
|
|
|
|
|
GS_ENDIDBUF();
|
1999-12-01 19:36:20 +00:00
|
|
|
|
}
|
2012-09-19 13:31:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 14:20:01 +00:00
|
|
|
|
- (void) sortUsingComparator: (NSComparator)comparator
|
2012-09-19 13:31:09 +00:00
|
|
|
|
{
|
|
|
|
|
[self sortWithOptions: 0 usingComparator: comparator];
|
1995-04-03 03:18:43 +00:00
|
|
|
|
}
|
1994-11-08 16:44:01 +00:00
|
|
|
|
@end
|
1996-03-31 22:23:37 +00:00
|
|
|
|
|
|
|
|
|
@implementation NSArrayEnumerator
|
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (id) initWithArray: (NSArray*)anArray
|
1996-03-31 22:23:37 +00:00
|
|
|
|
{
|
2003-10-14 09:00:42 +00:00
|
|
|
|
self = [super init];
|
|
|
|
|
if (self != nil)
|
|
|
|
|
{
|
|
|
|
|
array = anArray;
|
2022-02-17 10:21:36 +00:00
|
|
|
|
IF_NO_ARC(RETAIN(array);)
|
2003-10-14 09:00:42 +00:00
|
|
|
|
pos = 0;
|
|
|
|
|
get = [array methodForSelector: oaiSel];
|
2015-06-04 09:18:52 +00:00
|
|
|
|
cnt = (NSUInteger (*)(NSArray*, SEL))[array methodForSelector: countSel];
|
2003-10-14 09:00:42 +00:00
|
|
|
|
}
|
1996-03-31 22:23:37 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the next object in the enumeration or nil if there are no more
|
|
|
|
|
* objects.<br />
|
|
|
|
|
* NB. modifying a mutable array during an enumeration can break things ...
|
|
|
|
|
* don't do it.
|
|
|
|
|
*/
|
1996-03-31 22:23:37 +00:00
|
|
|
|
- (id) nextObject
|
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (pos >= (*cnt)(array, countSel))
|
1996-03-31 22:23:37 +00:00
|
|
|
|
return nil;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
return (*get)(array, oaiSel, pos++);
|
1996-03-31 22:23:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) dealloc
|
|
|
|
|
{
|
1999-06-30 21:13:19 +00:00
|
|
|
|
RELEASE(array);
|
1996-03-31 22:23:37 +00:00
|
|
|
|
[super dealloc];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
@implementation NSArrayEnumeratorReverse
|
|
|
|
|
|
1999-09-14 19:24:58 +00:00
|
|
|
|
- (id) initWithArray: (NSArray*)anArray
|
1996-03-31 22:23:37 +00:00
|
|
|
|
{
|
2003-10-14 09:00:42 +00:00
|
|
|
|
self = [super initWithArray: anArray];
|
|
|
|
|
if (self != nil)
|
|
|
|
|
{
|
|
|
|
|
pos = (*cnt)(array, countSel);
|
|
|
|
|
}
|
1996-03-31 22:23:37 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-04 08:06:48 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the next object in the enumeration or nil if there are no more
|
|
|
|
|
* objects.<br />
|
|
|
|
|
* NB. modifying a mutable array during an enumeration can break things ...
|
|
|
|
|
* don't do it.
|
|
|
|
|
*/
|
1996-03-31 22:23:37 +00:00
|
|
|
|
- (id) nextObject
|
|
|
|
|
{
|
1999-09-14 19:24:58 +00:00
|
|
|
|
if (pos == 0)
|
1996-03-31 22:23:37 +00:00
|
|
|
|
return nil;
|
1999-09-14 19:24:58 +00:00
|
|
|
|
return (*get)(array, oaiSel, --pos);
|
1996-03-31 22:23:37 +00:00
|
|
|
|
}
|
1999-02-20 19:59:45 +00:00
|
|
|
|
@end
|
2000-08-07 22:00:31 +00:00
|
|
|
|
|