Fix bug #43915 (equality not checked correctly for NSCountedSet)

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@38470 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Niels Grewe 2015-05-02 08:03:05 +00:00
parent 70749467e1
commit 6f2611363a
5 changed files with 68 additions and 3 deletions

View file

@ -1,3 +1,13 @@
2015-05-02 Niels Grewe <niels.grewe@halbordnung.de>
* Source/GSSet.m
* Source/NSCountedSet.m
* Source/NSSet.m:
Implement a private method -_countForObject: that enables to correctly
compare NSSet and NSCountedSet (behaviour verified to match OS X).
Fixes bug #43915.
* Tests/base/NSCountedSet/equality.m: Test cases for equality behaviour.
2015-04-20 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSTimeZone.m: Improve caching of common absolute timezones.

View file

@ -48,7 +48,7 @@ static GC_descr nodeDesc; // Type descriptor for map node.
#include "GNUstepBase/GSIMap.h"
static SEL memberSel;
static SEL privateCountOfSel;
@interface GSSet : NSSet
{
@public
@ -128,6 +128,7 @@ static Class mutableSetClass;
setClass = [GSSet class];
mutableSetClass = [GSMutableSet class];
memberSel = @selector(member:);
privateCountOfSel = @selector(_countForObject:);
}
}
@ -424,8 +425,10 @@ static Class mutableSetClass;
GSIMapEnumerator_t enumerator;
GSIMapNode node;
IMP imp;
IMP countImp;
imp = [other methodForSelector: memberSel];
countImp = [other methodForSelector: privateCountOfSel];
enumerator = GSIMapEnumeratorForMap(&map);
node = GSIMapEnumeratorNextNode(&enumerator);
@ -436,6 +439,16 @@ static Class mutableSetClass;
GSIMapEndEnumerator(&enumerator);
return NO;
}
else
{
NSUInteger c = (NSUInteger)
countImp(other,privateCountOfSel,node->key.obj);
// GSSet does not have duplicate entries
if (c != 1)
{
return NO;
}
}
node = GSIMapEnumeratorNextNode(&enumerator);
}
GSIMapEndEnumerator(&enumerator);

View file

@ -91,6 +91,11 @@ static Class NSCountedSet_concrete_class;
}
}
- (NSUInteger) _countForObject: (id)anObject
{
return [self countForObject: anObject];
}
/**
* Returns the number of times that an object that is equal to the
* specified object (as determined by the [-isEqual:] method) has

View file

@ -590,6 +590,11 @@ static Class NSMutableSet_concrete_class;
return NO;
}
- (NSUInteger)_countForObject: (id)object
{
return 1;
}
/**
* Return whether each set is subset of the other.
*/
@ -602,8 +607,19 @@ static Class NSMutableSet_concrete_class;
id o, e = [self objectEnumerator];
while ((o = [e nextObject]))
if (![other member: o])
return NO;
{
if (![other member: o])
{
return NO;
}
else
{
if ([self _countForObject: o] != [other _countForObject: o])
{
return NO;
}
}
}
}
/* xxx Recheck this. */
return YES;

View file

@ -0,0 +1,21 @@
#import "ObjectTesting.h"
#import <Foundation/NSSet.h>
#import <Foundation/NSAutoreleasePool.h>
int main()
{
NSAutoreleasePool *arp = [NSAutoreleasePool new];
NSCountedSet *count1 = [NSCountedSet setWithObjects: @"1", @"1", nil];
NSCountedSet *count2 = [NSCountedSet setWithObjects: @"1", @"1", nil];
NSCountedSet *count3 = [NSCountedSet setWithObjects: @"1", nil];
NSSet *set = [NSSet setWithObjects: @"1", nil];
PASS([count1 isEqualToSet: count2], "Identical counted sets are equal");
PASS(![count1 isEqualToSet: count3], "Different counted sets are not equal");
PASS([count3 isEqualToSet: set], "Counted set is equal to plain set");
PASS([set isEqualToSet: count3], "Plain set is equal to counted set");
PASS(![count1 isEqualToSet: set], "Counted set with different counts is not equal to plain set");
PASS(![set isEqualToSet: count1], "Plain set is not equal to counted set with different counts");
[arp release]; arp = nil;
return 0;
}