Make GNUstep copying of containers consistent with OPENSTEP

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@4047 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 1999-04-08 12:17:15 +00:00
parent 25a03bd13b
commit f6468a06aa
6 changed files with 437 additions and 222 deletions

View file

@ -1,3 +1,9 @@
Thu Apr 8 12:40:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Source/NSArray.m: Make copying behavior consistent with OPENSTEP.
* Source/NSDictionary.m: Make copying behavior consistent with OPENSTEP.
* Source/NSSet.m: Make copying behavior consistent with OPENSTEP.
Wed Apr 7 12:22:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk> Wed Apr 7 12:22:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Source/NSCharacterSet.m: Use punctuationCharSet.dat * Source/NSCharacterSet.m: Use punctuationCharSet.dat

View file

@ -178,38 +178,13 @@ static Class NSMutableArray_concrete_class;
- copyWithZone: (NSZone*)zone - copyWithZone: (NSZone*)zone
{ {
/* a deep copy */ return [self retain];
unsigned count = [self count];
id oldObjects[count];
id newObjects[count];
id newArray;
unsigned i;
BOOL needCopy = [self isKindOfClass: [NSMutableArray class]];
if (NSShouldRetainWithZone(self, zone) == NO)
needCopy = YES;
[self getObjects: oldObjects];
for (i = 0; i < count; i++)
{
newObjects[i] = [oldObjects[i] copyWithZone:zone];
if (newObjects[i] != oldObjects[i])
needCopy = YES;
}
if (needCopy)
newArray = [[[[self class] _concreteClass] allocWithZone:zone]
initWithObjects:newObjects count:count];
else
newArray = [self retain];
for (i = 0; i < count; i++)
[newObjects[i] release];
return newArray;
} }
/* The NSMutableCopying Protocol */ /* The NSMutableCopying Protocol */
- mutableCopyWithZone: (NSZone*)zone - mutableCopyWithZone: (NSZone*)zone
{ {
/* a shallow copy */
return [[[[self class] _mutableConcreteClass] allocWithZone: zone] return [[[[self class] _mutableConcreteClass] allocWithZone: zone]
initWithArray: self]; initWithArray: self];
} }
@ -725,6 +700,26 @@ static NSString *indentStrings[] = {
return [super allocWithZone: z]; return [super allocWithZone: z];
} }
/* The NSCopying Protocol */
- copyWithZone: (NSZone*)zone
{
/* a deep copy */
unsigned count = [self count];
id objects[count];
NSArray *newArray;
unsigned i;
[self getObjects: objects];
for (i = 0; i < count; i++)
objects[i] = [objects[i] copyWithZone: zone];
newArray = [[[[self class] _concreteClass] allocWithZone: zone]
initWithObjects: objects count: count];
while (i > 0)
[objects[--i] release];
return newArray;
}
/* This is the desgnated initializer for NSMutableArray */ /* This is the desgnated initializer for NSMutableArray */
- initWithCapacity: (unsigned)numItems - initWithCapacity: (unsigned)numItems
{ {

View file

@ -117,48 +117,12 @@ static Class NSMutableDictionary_concrete_class;
- copyWithZone: (NSZone*)z - copyWithZone: (NSZone*)z
{ {
/* a deep copy */ return [self retain];
unsigned count = [self count];
id oldKeys[count];
id newKeys[count];
id oldObjects[count];
id newObjects[count];
id newDictionary;
unsigned i;
id key;
NSEnumerator *enumerator = [self keyEnumerator];
BOOL needCopy = [self isKindOfClass: [NSMutableDictionary class]];
if (NSShouldRetainWithZone(self, z) == NO)
needCopy = YES;
for (i = 0; (key = [enumerator nextObject]); i++)
{
oldKeys[i] = key;
oldObjects[i] = [self objectForKey:key];
newKeys[i] = [oldKeys[i] copyWithZone:z];
newObjects[i] = [oldObjects[i] copyWithZone:z];
if (oldKeys[i] != newKeys[i] || oldObjects[i] != newObjects[i])
needCopy = YES;
}
if (needCopy)
newDictionary = [[[[self class] _concreteClass] alloc]
initWithObjects:newObjects
forKeys:newKeys
count:count];
else
newDictionary = [self retain];
for (i = 0; i < count; i++)
{
[newKeys[i] release];
[newObjects[i] release];
}
return newDictionary;
} }
- mutableCopyWithZone: (NSZone*)z - mutableCopyWithZone: (NSZone*)z
{ {
/* a shallow copy */ return [[[[self class] _mutableConcreteClass] allocWithZone: z]
return [[[[[self class] _mutableConcreteClass] _mutableConcreteClass] alloc]
initWithDictionary: self]; initWithDictionary: self];
} }
@ -659,13 +623,11 @@ static NSString *indentStrings[] = {
(*appImp)(result, appSel, @" = "); (*appImp)(result, appSel, @" = ");
if ([item respondsToSelector: if ([item respondsToSelector: @selector(descriptionWithLocale:indent:)])
@selector(descriptionWithLocale:indent:)])
{ {
[item descriptionWithLocale: locale indent: level to: result]; [item descriptionWithLocale: locale indent: level to: result];
} }
else if ([item respondsToSelector: else if ([item respondsToSelector: @selector(descriptionWithLocale:)])
@selector(descriptionWithLocale:)])
{ {
[item descriptionWithLocale: locale to: result]; [item descriptionWithLocale: locale to: result];
} }
@ -700,6 +662,38 @@ static NSString *indentStrings[] = {
return [super allocWithZone: z]; return [super allocWithZone: z];
} }
- copyWithZone: (NSZone*)z
{
/* a deep copy */
unsigned count = [self count];
id keys[count];
id objects[count];
NSDictionary *newDictionary;
unsigned i;
id key;
NSEnumerator *enumerator = [self keyEnumerator];
static SEL nxtSel = @selector(nextObject);
IMP nxtImp = [enumerator methodForSelector: nxtSel];
static SEL objSel = @selector(objectForKey:);
IMP objImp = [self methodForSelector: objSel];
for (i = 0; (key = (*nxtImp)(enumerator, nxtSel)); i++)
{
keys[i] = key;
objects[i] = (*objImp)(self, objSel, key);
objects[i] = [objects[i] copyWithZone: z];
}
newDictionary = [[[[self class] _concreteClass] allocWithZone: z]
initWithObjects: objects
forKeys: keys
count: count];
while (i > 0)
{
[objects[--i] release];
}
return newDictionary;
}
/* This is the designated initializer */ /* This is the designated initializer */
- initWithCapacity: (unsigned)numItems - initWithCapacity: (unsigned)numItems
{ {

View file

@ -154,36 +154,11 @@ static Class NSMutableSet_concrete_class;
- copyWithZone: (NSZone*)z - copyWithZone: (NSZone*)z
{ {
/* a deep copy */ return [self retain];
int count = [self count];
id objects[count];
id enumerator = [self objectEnumerator];
id o;
NSSet *newSet;
int i;
BOOL needCopy = [self isKindOfClass: [NSMutableSet class]];
if (NSShouldRetainWithZone(self, z) == NO)
needCopy = YES;
for (i = 0; (o = [enumerator nextObject]); i++) {
objects[i] = [o copyWithZone:z];
if (objects[i] != o)
needCopy = YES;
}
if (needCopy)
newSet = [[[[self class] _concreteClass] allocWithZone: z]
initWithObjects:objects count:count];
else
newSet = [self retain];
for (i = 0; i < count; i++)
[objects[i] release];
return newSet;
} }
- mutableCopyWithZone: (NSZone*)z - mutableCopyWithZone: (NSZone*)z
{ {
/* a shallow copy */
return [[[[self class] _mutableConcreteClass] allocWithZone: z] return [[[[self class] _mutableConcreteClass] allocWithZone: z]
initWithSet: self]; initWithSet: self];
} }
@ -457,6 +432,12 @@ static Class NSMutableSet_concrete_class;
return NSAllocateObject([self _mutableConcreteClass], 0, z); return NSAllocateObject([self _mutableConcreteClass], 0, z);
} }
- copyWithZone: (NSZone*)z
{
return [[[[self class] _concreteClass] allocWithZone: z]
initWithSet: self];
}
/* This is the designated initializer */ /* This is the designated initializer */
- initWithCapacity: (unsigned)numItems - initWithCapacity: (unsigned)numItems
{ {

View file

@ -79,12 +79,14 @@ awake \
thread-except \ thread-except \
nscharacterset \ nscharacterset \
NSData-test \ NSData-test \
containers \
nstimezone \ nstimezone \
create-abbrevs \ create-abbrevs \
create-regions create-regions
# The tool Objective-C source files to be compiled # The tool Objective-C source files to be compiled
benchmark_OBJC_FILES = benchmark.m benchmark_OBJC_FILES = benchmark.m
containers_OBJC_FILES = containers.m
test01_OBJC_FILES = test01.m test01_OBJC_FILES = test01.m
test02_OBJC_FILES = test02.m test02_OBJC_FILES = test02.m
heap_OBJC_FILES = heap.m heap_OBJC_FILES = heap.m

237
Testing/containers.m Normal file
View file

@ -0,0 +1,237 @@
#import <Foundation/Foundation.h>
#import <objc/Protocol.h>
@interface Foo: NSObject
{
}
+ foo;
- (BOOL) conformsToProtocol: (Protocol *) aProtocol;
- (BOOL) respondsToSelector: (SEL) aSelector;
- copyWithZone: (NSZone *) zone;
- mutableCopyWithZone: (NSZone *) zone;
@end
@implementation Foo
+ foo
{
return [[[Foo alloc] init] autorelease];
}
- (BOOL) conformsToProtocol: (Protocol *) aProtocol
{
BOOL ret = [super conformsToProtocol: aProtocol];
NSLog(@"-[<%@:0x%x> %@<%s>] -> %@",
NSStringFromClass([self class]), self, NSStringFromSelector(_cmd),
[aProtocol name], ret ? @"YES" : @"NO");
return ret;
}
- (BOOL) respondsToSelector: (SEL) aSelector
{
BOOL ret = [super respondsToSelector: aSelector];
if (![NSStringFromSelector(aSelector) hasPrefix:@"description"])
NSLog(@"-[<%@:0x%x> %@%@] -> %@",
NSStringFromClass([self class]), self, NSStringFromSelector(_cmd),
NSStringFromSelector(aSelector), ret ? @"YES" : @"NO");
return ret;
}
- copyWithZone: (NSZone *) zone
{
id ret = [Foo foo];
NSLog(@"-[<%@:0x%x> %@0x%x] -> <%@:0x%x>",
NSStringFromClass([self class]), self,
NSStringFromSelector(_cmd), zone, NSStringFromClass([ret class]), ret);
return ret;
}
- mutableCopyWithZone: (NSZone *) zone
{
id ret = [Foo foo];
NSLog(@"-[<%@:0x%x> %@0x%x] -> <%@:0x%x>",
NSStringFromClass([self class]), self,
NSStringFromSelector(_cmd), zone, NSStringFromClass([ret class]), ret);
return ret;
}
- retain
{
id ret = [super retain];
NSLog(@"-[<%@:0x%x> %@] -> retainCount = %d",
NSStringFromClass([self class]), self,
NSStringFromSelector(_cmd), [ret retainCount]);
return ret;
}
@end
void
isDeepArrayCopy(NSArray *obj1, NSArray *obj2)
{
id obj1FirstObject = [obj1 objectAtIndex:0];
id obj2FirstObject = [obj2 objectAtIndex:0];
NSLog(@"<%@:0x%x> -> <%@:0x%x>, %@",
NSStringFromClass([obj1 class]), obj1,
NSStringFromClass([obj2 class]), obj2,
(obj1FirstObject == obj2FirstObject) ? ((obj1 == obj2) ? @"retained" : @"shallow") : @"deep(ish)");
}
void
isDeepDictionaryCopy(NSDictionary *obj1, NSDictionary *obj2)
{
id obj1FirstObject = [obj1 objectForKey: @"Key"];
id obj2FirstObject = [obj2 objectForKey: @"Key"];
NSLog(@"<%@:0x%x> -> <%@:0x%x>, %@",
NSStringFromClass([obj1 class]), obj1,
NSStringFromClass([obj2 class]), obj2,
(obj1FirstObject == obj2FirstObject) ? ((obj1 == obj2) ? @"retained" : @"shallow") : @"deep(ish)");
}
void
isDeepSetCopy(NSSet *obj1, NSSet *obj2)
{
id obj1FirstObject = [obj1 anyObject];
id obj2FirstObject = [obj2 anyObject];
NSLog(@"<%@:0x%x> -> <%@:0x%x>, %@",
NSStringFromClass([obj1 class]), obj1,
NSStringFromClass([obj2 class]), obj2,
(obj1FirstObject == obj2FirstObject) ? ((obj1 == obj2) ? @"retained" : @"shallow") : @"deep(ish)");
}
int main(int argc, char **argv)
{
NSAutoreleasePool *thePool = [[NSAutoreleasePool alloc] init];
NSArray *anArrayCopy;
NSArray *aMutableArrayCopy;
NSArray *anArrayMutableCopy;
NSArray *aMutableArrayMutableCopy;
NSMutableArray *aMutableArray
= [NSMutableArray arrayWithObject: [Foo foo]];
NSArray *anArray = [NSArray arrayWithObject: [Foo foo]];
NSDictionary *aDictionaryCopy;
NSDictionary *aMutableDictionaryCopy;
NSDictionary *aDictionaryMutableCopy;
NSDictionary *aMutableDictionaryMutableCopy;
NSMutableDictionary *aMutableDictionary
= [NSMutableDictionary dictionaryWithObjectsAndKeys: [Foo foo], @"Key", nil];
NSDictionary *aDictionary
= [NSDictionary dictionaryWithObjectsAndKeys: [Foo foo], @"Key", nil];
NSSet *aSetCopy;
NSSet *aMutableSetCopy;
NSSet *aSetMutableCopy;
NSSet *aMutableSetMutableCopy;
NSMutableSet *aMutableSet = [NSMutableSet setWithObject: [Foo foo]];
NSSet *aSet = [NSSet setWithObject: [Foo foo]];
NSZone *zone = NSDefaultMallocZone();
while (zone != 0)
{
NSLog(@"Copying from zone 0x%x -> 0x%x", NSDefaultMallocZone(), zone);
NSLog(@"MutableArray -copy");
aMutableArrayCopy = [aMutableArray copyWithZone:zone];
NSLog(@"MutableArray -mutableCopy");
aMutableArrayMutableCopy = [aMutableArray mutableCopyWithZone:zone];
NSLog(@"Array -copy");
anArrayCopy = [anArray copyWithZone:zone];
NSLog(@"Array -mutableCopy");
anArrayMutableCopy = [anArray mutableCopyWithZone:zone];
NSLog(@"MutableArray: %@", aMutableArray);
NSLog(@"MutableArrayCopy: %@", aMutableArrayCopy);
NSLog(@"MutableArrayMutableCopy: %@", aMutableArrayMutableCopy);
NSLog(@"anArray: %@", anArray);
NSLog(@"anArrayCopy: %@", anArrayCopy);
NSLog(@"anArrayCopy: %@", anArrayMutableCopy);
NSLog(@"Test MutableArray against Copy");
isDeepArrayCopy(aMutableArray, aMutableArrayCopy);
NSLog(@"Test MutableArray against MutableCopy");
isDeepArrayCopy(aMutableArray, aMutableArrayMutableCopy);
NSLog(@"Test Array against Copy");
isDeepArrayCopy(anArray, anArrayCopy);
NSLog(@"Test Array against MutableCopy");
isDeepArrayCopy(anArray, anArrayMutableCopy);
NSLog(@"MutableDictionary -copy");
aMutableDictionaryCopy = [aMutableDictionary copyWithZone:zone];
NSLog(@"MutableDictionary -mutableCopy");
aMutableDictionaryMutableCopy = [aMutableDictionary mutableCopyWithZone:zone];
NSLog(@"Dictionary -copy");
aDictionaryCopy = [aDictionary copyWithZone:zone];
NSLog(@"Dictionary -mutableCopy");
aDictionaryMutableCopy = [aDictionary mutableCopyWithZone:zone];
NSLog(@"MutableDictionary: %@", aMutableDictionary);
NSLog(@"MutableDictionaryCopy: %@", aMutableDictionaryCopy);
NSLog(@"MutableDictionaryMutableCopy: %@", aMutableDictionaryMutableCopy);
NSLog(@"aDictionary: %@", aDictionary);
NSLog(@"aDictionaryCopy: %@", aDictionaryCopy);
NSLog(@"aDictionaryCopy: %@", aDictionaryMutableCopy);
NSLog(@"Test MutableDictionary against Copy");
isDeepDictionaryCopy(aMutableDictionary, aMutableDictionaryCopy);
NSLog(@"Test MutableDictionary against MutableCopy");
isDeepDictionaryCopy(aMutableDictionary, aMutableDictionaryMutableCopy);
NSLog(@"Test Dictionary against Copy");
isDeepDictionaryCopy(aDictionary, aDictionaryCopy);
NSLog(@"Test Dictionary against MutableCopy");
isDeepDictionaryCopy(aDictionary, aDictionaryMutableCopy);
NSLog(@"MutableSet -copy");
aMutableSetCopy = [aMutableSet copyWithZone:zone];
NSLog(@"MutableSet -mutableCopy");
aMutableSetMutableCopy = [aMutableSet mutableCopyWithZone:zone];
NSLog(@"Set -copy");
aSetCopy = [aSet copyWithZone:zone];
NSLog(@"Set -mutableCopy");
aSetMutableCopy = [aSet mutableCopyWithZone:zone];
NSLog(@"MutableSet: %@", aMutableSet);
NSLog(@"MutableSetCopy: %@", aMutableSetCopy);
NSLog(@"MutableSetMutableCopy: %@", aMutableSetMutableCopy);
NSLog(@"aSet: %@", aSet);
NSLog(@"aSetCopy: %@", aSetCopy);
NSLog(@"aSetCopy: %@", aSetMutableCopy);
NSLog(@"Test MutableSet against Copy");
isDeepSetCopy(aMutableSet, aMutableSetCopy);
NSLog(@"Test MutableSet against MutableCopy");
isDeepSetCopy(aMutableSet, aMutableSetMutableCopy);
NSLog(@"Test Set against Copy");
isDeepSetCopy(aSet, aSetCopy);
NSLog(@"Test Set against MutableCopy");
isDeepSetCopy(aSet, aSetMutableCopy);
if (zone == NSDefaultMallocZone())
zone = NSCreateZone(NSPageSize(), NSPageSize(), YES);
else
zone = 0;
}
[thePool release];
return 0;
}