nbloat reduction

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@6713 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 2000-06-17 06:27:00 +00:00
parent 3383434169
commit dd07375316
77 changed files with 80 additions and 10776 deletions

View file

@ -1,38 +0,0 @@
/* Implementation of GNU Objective-C class for writing objects to files
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: January 1996
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/preface.h>
#include <base/Archiver.h>
/* Eventually some functionality may be moved out of Encoder and
Decoder and into these objects.
These class should be used as concrete classes, not the Coder,
Encoder or Decoder classes. */
@implementation Archiver
@end
@implementation Unarchiver
@end

View file

@ -1,263 +0,0 @@
/* Implementation for Objective-C Array collection object
Copyright (C) 1993,1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/Array.h>
#include <base/ArrayPrivate.h>
#include <base/NSString.h>
#include <base/OrderedCollection.h>
#include <base/behavior.h>
@implementation ConstantArray
/* This is the designated initializer of this class */
- initWithObjects: (id*)objs count: (unsigned)c
{
_count = c;
OBJC_MALLOC(_contents_array, id, _count);
while (c--)
_contents_array[c] = objs[c];
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
Array *copy = [super emptyCopy];
copy->_count = 0;
OBJC_MALLOC(copy->_contents_array, id, copy->_capacity);
return copy;
}
- (void) _collectionDealloc
{
OBJC_FREE(_contents_array);
[super _collectionDealloc];
}
// GETTING ELEMENTS BY INDEX;
- objectAtIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count);
return _contents_array[index];
}
// TESTING;
- (unsigned) count
{
return _count;
}
@end
@implementation Array
+ (void) initialize
{
if (self == [Array class])
class_add_behavior (self, [OrderedCollection class]);
}
// MANAGING CAPACITY;
/* Eventually we will want to have better capacity management,
potentially keep default capacity as a class variable. */
+ (unsigned) defaultCapacity
{
return DEFAULT_ARRAY_CAPACITY;
}
+ (int) defaultGrowFactor
{
return DEFAULT_ARRAY_GROW_FACTOR;
}
/* This is the designated initializer for this class */
- initWithCapacity: (unsigned)aCapacity
{
_grow_factor = [[self class] defaultGrowFactor];
_count = 0;
_capacity = (aCapacity < 1) ? 1 : aCapacity;
OBJC_MALLOC(_contents_array, id, _capacity);
return self;
}
/* Archiving must mimic the above designated initializer */
- (void) _encodeCollectionWithCoder: (id <Encoding>)coder
{
[super _encodeCollectionWithCoder:coder];
[coder encodeValueOfCType:@encode(unsigned)
at:&_grow_factor
withName:@"Array Grow Factor"];
[coder encodeValueOfCType:@encode(unsigned)
at:&_capacity
withName:@"Array Capacity"];
}
- _initCollectionWithCoder: (id <Decoding>)coder
{
[super _initCollectionWithCoder:coder];
[coder decodeValueOfCType:@encode(unsigned)
at:&_grow_factor
withName:NULL];
_count = 0;
[coder decodeValueOfCType:@encode(unsigned)
at:&_capacity
withName:NULL];
return self;
}
/* Override superclass' designated initializer to call ours */
- initWithObjects: (id*)objs count: (unsigned)c
{
int i;
[self initWithCapacity: c];
for (i = 0; i < c; i++)
[self insertObject: objs[i] atIndex: i]; // xxx this most efficient method?
return self;
}
/* This must work without sending any messages to content objects */
- (void) empty
{
int i;
for (i = 0; i < _count; i++)
[_contents_array[i] release];
_count = 0;
/* Note this may not work for subclassers. Beware. */
}
// MANAGING CAPACITY;
/* This is the only method that changes the value of the instance
variable _capacity, except for "-initDescription:capacity:" */
- (void) setCapacity: (unsigned)newCapacity
{
if (newCapacity > _count) {
_capacity = newCapacity;
OBJC_REALLOC(_contents_array, id, _capacity);
}
}
- (int) growFactor
{
return _grow_factor;
}
- (void) setGrowFactor: (int)aNum;
{
_grow_factor = aNum;
}
// ADDING;
- (void) appendObject: newObject
{
/* Check to make sure that anObject is not nil, first. */
if (newObject == nil)
{
[NSException raise: NSInvalidArgumentException
format: @"Array: object to add is nil"
];
}
/* Now we can add it. */
incrementCount(self);
[newObject retain];
_contents_array[_count-1] = newObject;
}
- (void) prependObject: newObject
{
incrementCount(self);
[newObject retain];
makeHoleAt(self, 0);
_contents_array[0] = newObject;
}
- (void) insertObject: newObject atIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count+1);
/* Check to make sure that anObject is not nil, first. */
if (newObject == nil)
{
[NSException raise: NSInvalidArgumentException
format: @"Array: object to insert is nil"
];
}
incrementCount(self);
[newObject retain];
makeHoleAt(self, index);
_contents_array[index] = newObject;
}
// REMOVING, REPLACING AND SWAPPING;
- (void) removeObjectAtIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count);
[_contents_array[index] release];
fillHoleAt(self, index);
decrementCount(self);
}
/* We could be more efficient if we override these also.
- removeFirstObject
- removeLastObject;
If you do, remember, you will have to implement this methods
in GapArray also! */
- (void) replaceObjectAtIndex: (unsigned)index withObject: newObject
{
CHECK_INDEX_RANGE_ERROR(index, _count);
[newObject retain];
[_contents_array[index] release];
_contents_array[index] = newObject;
}
- (void) swapAtIndeces: (unsigned)index1 : (unsigned)index2
{
id tmp;
CHECK_INDEX_RANGE_ERROR(index1, _count);
CHECK_INDEX_RANGE_ERROR(index2, _count);
tmp = _contents_array[index1];
_contents_array[index1] = _contents_array[index2];
_contents_array[index2] = tmp;
}
@end

View file

@ -1,211 +0,0 @@
/* Implementation for Objective-C Bag collection object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/Bag.h>
#include <base/CollectionPrivate.h>
#define DEFAULT_BAG_CAPACITY 32
@implementation Bag
// MANAGING CAPACITY;
/* Eventually we will want to have better capacity management,
potentially keep default capacity as a class variable. */
+ (unsigned) defaultCapacity
{
return DEFAULT_BAG_CAPACITY;
}
// INITIALIZING AND FREEING;
/* This is the designated initializer of this class */
/* Override designated initializer of superclass */
- initWithCapacity: (unsigned)cap
{
_contents_map = NSCreateMapTable (NSObjectMapKeyCallBacks,
NSIntMapValueCallBacks,
cap);
_count = 0;
return self;
}
/* Override Collection's designated initializer */
- initWithObjects: (id*)objs count: (unsigned)count
{
[self initWithCapacity: count];
while (count--)
[self addObject: objs[count]];
return self;
}
/* Archiving must mimic the above designated initializer */
/* Archiving must mimic the above designated initializer */
- (void) encodeWithCoder: anEncoder
{
[self notImplemented:_cmd];
}
- initWithCoder: aDecoder
{
[self notImplemented:_cmd];
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
Bag *copy = [super emptyCopy];
copy->_contents_map = NSCreateMapTable (NSObjectMapKeyCallBacks,
NSIntMapValueCallBacks,
0);
copy->_count = 0;
return copy;
}
- (void) dealloc
{
NSFreeMapTable (_contents_map);
[super _collectionDealloc];
}
/* This must work without sending any messages to content objects */
- (void) _collectionEmpty
{
NSResetMapTable (_contents_map);
_count = 0;
}
// ADDING;
- (void) addObject: newObject withOccurrences: (unsigned)count
{
unsigned new_count = (unsigned) NSMapGet (_contents_map, newObject);
new_count += count;
NSMapInsert (_contents_map, newObject, (void*)new_count);
_count += count;
}
- (void) addObject: newObject
{
[self addObject: newObject withOccurrences: 1];
}
// REMOVING AND REPLACING;
- (void) removeObject: oldObject occurrences: (unsigned)count
{
unsigned c = (unsigned) NSMapGet (_contents_map, oldObject);
if (c)
{
if (c <= count)
{
NSMapRemove (_contents_map, oldObject);
_count -= c;
}
else
{
NSMapInsert (_contents_map, oldObject, (void*)(c - count));
_count -= count;
}
}
}
- (void) removeObject: oldObject
{
[self removeObject: oldObject occurrences:1];
}
- (void) uniqueContents
{
[self notImplemented: _cmd];
}
// TESTING;
- (unsigned) count
{
return _count;
}
- (unsigned) uniqueCount
{
return NSCountMapTable (_contents_map);
}
- (unsigned) occurrencesOfObject: anObject
{
return (unsigned) NSMapGet (_contents_map, anObject);
}
// ENUMERATING;
struct BagEnumState
{
NSMapEnumerator me;
id object;
unsigned count;
};
#define ES ((struct BagEnumState *) *enumState)
- nextObjectWithEnumState: (void**)enumState
{
if (!(ES->count))
if (!NSNextMapEnumeratorPair (&(ES->me),
(void**) &(ES->object),
(void**) &(ES->count)))
return NO_OBJECT;
ES->count--;
return ES->object;
}
- (void*) newEnumState
{
/* init for start of enumeration. */
void *vp;
void **enumState = &vp;
OBJC_MALLOC(*enumState, struct BagEnumState, 1);
ES->me = NSEnumerateMapTable (_contents_map);
ES->object = nil;
ES->count = 0;
return vp;
}
- (void) freeEnumState: (void**)enumState
{
if (*enumState)
OBJC_FREE(*enumState);
}
@end

View file

@ -1,607 +0,0 @@
/* Implementation for Objective-C BinaryTree collection object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/BinaryTree.h>
#include <base/IndexedCollectionPrivate.h>
#include <base/BinaryTreeNode.h>
#include <base/NSString.h>
/* the sentinal */
static id nilBinaryTreeNode;
@implementation BinaryTree
+ (void) initialize
{
if (self == [BinaryTree class])
{
nilBinaryTreeNode = [[BinaryTreeNode alloc] init];
}
}
/* This is the designated initializer of this class */
- init
{
_count = 0;
_contents_root = [self nilNode];
return self;
}
/* Archiving must mimic the above designated initializer */
/* xxx See Collection _decodeContentsWithCoder:.
We shouldn't do an -addElement. finishEncodingInterconnectedObjects
should take care of all that. */
- _initCollectionWithCoder: aCoder
{
[self notImplemented:_cmd];
[super _initCollectionWithCoder:aCoder];
_count = 0;
_contents_root = [self nilNode];
return self;
}
- (void) _encodeContentsWithCoder: (id <Encoding>)aCoder
{
[aCoder startEncodingInterconnectedObjects];
[super _encodeContentsWithCoder:aCoder];
[aCoder finishEncodingInterconnectedObjects];
}
- (void) _decodeContentsWithCoder: (id <Decoding>)aCoder
{
[aCoder startDecodingInterconnectedObjects];
[super _decodeContentsWithCoder:aCoder];
[aCoder finishDecodingInterconnectedObjects];
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
BinaryTree *copy = [super emptyCopy];
copy->_count = 0;
copy->_contents_root = [self nilNode];
return copy;
}
/* This must work without sending any messages to content objects */
- (void) _empty
{
_count = 0;
_contents_root = [self nilNode];
}
- nilNode
{
return nilBinaryTreeNode;
}
- rootNode
{
return _contents_root;
}
- leftmostNodeFromNode: aNode
{
id left;
if (aNode && aNode != [self nilNode])
{
while ((left = [aNode leftNode]) != [self nilNode])
aNode = left;
}
return aNode;
}
- rightmostNodeFromNode: aNode
{
id right;
if (aNode && aNode != [self nilNode])
while ((right = [aNode rightNode]) != [self nilNode])
{
aNode = right;
}
return aNode;
}
- firstObject
{
return [self leftmostNodeFromNode: _contents_root];
}
- lastObject
{
return [self rightmostNodeFromNode: _contents_root];
}
/* This is correct only if the tree is sorted. How to deal with this? */
- maxObject
{
return [self rightmostNodeFromNode: _contents_root];
}
/* This is correct only is the tree is sorted. How to deal with this? */
- minObject
{
return [self leftmostNodeFromNode: _contents_root];
}
- successorOfObject: anObject
{
id tmp;
/* Make sure we actually own the anObject. */
NSAssert([anObject binaryTree] == self, NSInternalInconsistencyException);
// here tmp is the right node;
if ((tmp = [anObject rightNode]) != [self nilNode])
return [self leftmostNodeFromNode: tmp];
// here tmp is the parent;
tmp = [anObject parentNode];
while (tmp != [self nilNode] && anObject == [tmp rightNode])
{
anObject = tmp;
tmp = [tmp parentNode];
}
if (tmp == [self nilNode])
return NO_OBJECT;
return tmp;
}
// I should make sure that [_contents_root parentNode] == [self nilNode];
// Perhaps I should make [_contents_root parentNode] == binaryTreeObj ??;
- predecessorObject: anObject
{
id tmp;
/* Make sure we actually own the anObject. */
NSAssert([anObject binaryTree] == self, NSInternalInconsistencyException);
// here tmp is the left node;
if ((tmp = [anObject leftNode]) != [self nilNode])
return [self rightmostNodeFromNode:tmp];
// here tmp is the parent;
tmp = [anObject parentNode];
while (tmp != [self nilNode] && anObject == [tmp leftNode])
{
anObject = tmp;
tmp = [tmp parentNode];
}
if (tmp == [self nilNode])
return NO_OBJECT;
return tmp;
}
/* This relies on [_contents_root parentNode] == [self nilNode] */
- rootFromNode: aNode
{
id parentNode;
/* Make sure we actually own the aNode. */
NSAssert([aNode binaryTree] == self, NSInternalInconsistencyException);
while ((parentNode = [aNode parentNode]) != [self nilNode])
aNode = parentNode;
return aNode;
}
/* This relies on [_contents_root parentNode] == [self nilNode] */
- (unsigned) depthOfNode: aNode
{
unsigned count = 0;
/* Make sure we actually own the aNode. */
NSAssert([aNode binaryTree] == self, NSInternalInconsistencyException);
if (aNode == nil || aNode == [self nilNode])
[self error:"in %s, Can't find depth of nil node", sel_get_name(_cmd)];
do
{
aNode = [aNode parentNode];
count++;
}
while (aNode != [self nilNode]);
return count;
}
- (unsigned) heightOfNode: aNode
{
unsigned leftHeight, rightHeight;
id tmpNode;
/* Make sure we actually own the aNode. */
NSAssert([aNode binaryTree] == self, NSInternalInconsistencyException);
if (aNode == nil || aNode == [self nilNode])
{
[self error:"in %s, Can't find height of nil node", sel_get_name(_cmd)];
return 0;
}
else
{
leftHeight = ((tmpNode = [aNode leftNode])
?
(1 + [self heightOfNode:tmpNode])
:
0);
rightHeight = ((tmpNode = [aNode rightNode])
?
(1 + [self heightOfNode:tmpNode])
:
0);
return MAX(leftHeight, rightHeight);
}
}
- (unsigned) nodeCountUnderNode: aNode
{
unsigned count = 0;
/* Make sure we actually own the aNode. */
NSAssert([aNode binaryTree] == self, NSInternalInconsistencyException);
if ([aNode leftNode] != [self nilNode])
count += 1 + [self nodeCountUnderNode:[aNode leftNode]];
if ([aNode rightNode] != [self nilNode])
count += 1 + [self nodeCountUnderNode:[aNode rightNode]];
return count;
}
- leftRotateAroundNode: aNode
{
id y;
/* Make sure we actually own the aNode. */
NSAssert([aNode binaryTree] == self, NSInternalInconsistencyException);
y = [aNode rightNode];
if (y == [self nilNode])
return self;
[aNode setRightNode:[y leftNode]];
if ([y leftNode] != [self nilNode])
[[y leftNode] setParentNode:aNode];
[y setParentNode:[aNode parentNode]];
if ([aNode parentNode] == [self nilNode])
_contents_root = y;
else
{
if (NODE_IS_LEFTCHILD(aNode))
[[aNode parentNode] setLeftNode:y];
else
[[aNode parentNode] setRightNode:y];
}
[y setLeftNode:aNode];
[aNode setParentNode:y];
return self;
}
- rightRotateAroundNode: aNode
{
id y;
/* Make sure we actually own the aNode. */
NSAssert([aNode binaryTree] == self, NSInternalInconsistencyException);
y = [aNode leftNode];
if (y == [self nilNode])
return self;
[aNode setLeftNode:[y rightNode]];
if ([y rightNode] != [self nilNode])
[[y rightNode] setParentNode:aNode];
[y setParentNode:[aNode parentNode]];
if ([aNode parentNode] == [self nilNode])
_contents_root = y;
else
{
if (NODE_IS_RIGHTCHILD(aNode))
[[aNode parentNode] setRightNode:y];
else
[[aNode parentNode] setLeftNode:y];
}
[y setRightNode:aNode];
[aNode setParentNode:y];
return self;
}
- objectAtIndex: (unsigned)index
{
id ret;
CHECK_INDEX_RANGE_ERROR(index, _count);
ret = [self firstObject];
// Not very efficient; Should be rewritten;
while (index--)
ret = [self successorOfObject: ret];
return ret;
}
- (void) sortAddObject: newObject
{
id theParent, tmpChild;
/* Make sure no one else already owns the newObject. */
NSAssert([newObject binaryTree] == NO_OBJECT, NSInternalInconsistencyException);
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setBinaryTree: self];
[newObject setLeftNode:[self nilNode]];
[newObject setRightNode:[self nilNode]];
theParent = [self nilNode];
tmpChild = _contents_root;
while (tmpChild != [self nilNode])
{
theParent = tmpChild;
if ([newObject compare: theParent] < 0)
tmpChild = [tmpChild leftNode];
else
tmpChild = [tmpChild rightNode];
}
[newObject setParentNode:theParent];
if (theParent == [self nilNode])
_contents_root = newObject;
else
{
if ([newObject compare: theParent] < 0)
[theParent setLeftNode:newObject];
else
[theParent setRightNode:newObject];
}
_count++;
}
- (void) addObject: newObject
{
// By default insert in sorted order.
[self sortAddObject: newObject];
}
- (void) removeObject: oldObject
{
id x, y;
/* Make sure we actually own the aNode. */
NSAssert([oldObject binaryTree] == self, NSInternalInconsistencyException);
/* Extract the oldObject and sew up the cut. */
if ([oldObject leftNode] == [self nilNode]
|| [oldObject rightNode] == [self nilNode])
y = oldObject;
else
y = [self successorOfObject: oldObject];
if ([y leftNode] != [self nilNode])
x = [y leftNode];
else
x = [y rightNode];
if (x != [self nilNode])
[x setParentNode: [y parentNode]];
if ([y parentNode] == [self nilNode])
_contents_root = x;
else
{
if (y == [[y parentNode] leftNode])
[[y parentNode] setLeftNode: x];
else
[[y parentNode] setRightNode: x];
}
if (y != oldObject)
{
/* put y in the place of oldObject */
[y setParentNode: [oldObject parentNode]];
[y setLeftNode: [oldObject leftNode]];
[y setRightNode: [oldObject rightNode]];
if (oldObject == [[oldObject parentNode] leftNode])
[[oldObject parentNode] setLeftNode: y];
else
[[oldObject parentNode] setRightNode: y];
[[oldObject leftNode] setParentNode: y];
[[oldObject rightNode] setParentNode: y];
}
_count--;
/* Release ownership of the object. */
#if 0
[oldObject setRightNode: [self nilNode]];
[oldObject setLeftNode: [self nilNode]];
[oldObject setParentNode: [self nilNode]];
#else
[oldObject setLeftNode: NO_OBJECT];
[oldObject setRightNode: NO_OBJECT];
[oldObject setParentNode: NO_OBJECT];
#endif
[oldObject setBinaryTree: NO_OBJECT];
[oldObject release];
}
// ENUMERATING;
- nextObjectWithEnumState: (void**)enumState
{
if (!(*enumState))
*enumState = [self leftmostNodeFromNode:_contents_root];
else
*enumState = [self successorOfObject:*enumState];
return (id) *enumState;
}
- prevObjectWithEnumState: (void**)enumState
{
if (!(*enumState))
*enumState = [self rightmostNodeFromNode:_contents_root];
else
*enumState = [self predecessorObject:*enumState];
return (id) *enumState;
}
- (unsigned) count
{
return _count;
}
/* replace this with something better eventually */
- _tmpPrintFromNode: aNode indent: (int)count
{
printf("%-*s", count, "");
printf("%s\n", [[aNode description] cString]);
printf("%-*s.", count, "");
if ([aNode leftNode] != [self nilNode])
[self _tmpPrintFromNode:[aNode leftNode] indent:count+2];
else
printf("\n");
printf("%-*s.", count, "");
if ([aNode rightNode] != [self nilNode])
[self _tmpPrintFromNode:[aNode rightNode] indent:count+2];
else
printf("\n");
return self;
}
- binaryTreePrintForDebugger
{
[self _tmpPrintFromNode:_contents_root indent:0];
return self;
}
@end
/* These methods removed because they belong to an
OrderedCollection implementation, not an IndexedCollection
implementation. */
#if 0
// NOTE: This gives you the power to put elements in unsorted order;
- insertObject: newObject before: oldObject
{
id tmp;
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setBinaryTree: self];
[newObject setRightNode:[self nilNode]];
[newObject setLeftNode:[self nilNode]];
if ((tmp = [oldObject leftNode]) != [self nilNode])
{
[(tmp = [self rightmostNodeFromNode:tmp]) setRightNode:newObject];
[newObject setParentNode:tmp];
}
else if (newObject != [self nilNode])
{
[oldObject setLeftNode:newObject];
[newObject setParentNode:oldObject];
}
else
{
_contents_root = newObject;
[newObject setParentNode:[self nilNode]];
}
_count++;
RETAIN_ELT(newObject);
return self;
}
// NOTE: This gives you the power to put elements in unsorted order;
- insertObject: newObject after: oldObject
{
id tmp;
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setBinaryTree: self];
[newObject setRightNode:[self nilNode]];
[newObject setLeftNode:[self nilNode]];
if ((tmp = [oldObject rightNode]) != [self nilNode])
{
[(tmp = [self leftmostNodeFromNode:tmp]) setLeftNode:newObject];
[newObject setParentNode:tmp];
}
else if (newObject != [self nilNode])
{
[oldObject setRightNode:newObject];
[newObject setParentNode:oldObject];
}
else
{
_contents_root = newObject;
[newObject setParentNode:[self nilNode]];
}
_count++;
RETAIN_ELT(newObject);
return self;
}
// NOTE: This gives you the power to put elements in unsorted order;
- insertObject: newObject atIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count+1);
if (index == _count)
[self appendObject:newObject];
else
[self insertObject:newObject before:[self ObjectAtIndex:index]];
return self;
}
// NOTE: This gives you the power to put elements in unsorted order;
- appendObject: newObject
{
if (_count == 0)
{
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setBinaryTree: self];
_contents_root = newObject;
_count = 1;
[newObject setLeftNode:[self nilNode]];
[newObject setRightNode:[self nilNode]];
[newObject setParentNode:[self nilNode]];
}
else
[self insertObject:newObject after:[self lastObject]];
return self;
}
#endif

View file

@ -1,104 +0,0 @@
/* Implementation for Objective-C BinaryTreeNode object
Copyright (C) 1993,1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/BinaryTreeNode.h>
#include <base/NSString.h>
@implementation BinaryTreeNode
+ (void) initialize
{
if (self == [BinaryTreeNode class])
[self setVersion:0]; /* beta release */
}
- init
{
[super init];
_left = _right = _parent = nil;
return self;
}
- (void) encodeWithCoder: aCoder
{
[super encodeWithCoder:(id)aCoder];
[aCoder encodeObjectReference:_right withName:@"Right BinaryTree Node"];
[aCoder encodeObjectReference:_left withName:@"Left BinaryTree Node"];
[aCoder encodeObjectReference:_parent withName:@"Parent BinaryTree Node"];
[aCoder encodeObjectReference:_binary_tree
withName:@"BinaryTree"];
}
- initWithCoder: aCoder
{
[super initWithCoder:aCoder];
[aCoder decodeObjectAt:&_right withName:NULL];
[aCoder decodeObjectAt:&_left withName:NULL];
[aCoder decodeObjectAt:&_parent withName:NULL];
[aCoder decodeObjectAt:&_binary_tree withName:NULL];
return self;
}
- leftNode
{
return _left;
}
- rightNode
{
return _right;
}
- parentNode
{
return _parent;
}
- (void) setLeftNode: aNode
{
_left = aNode;
}
- (void) setRightNode: aNode
{
_right = aNode;
}
- (void) setParentNode: aNode
{
_parent = aNode;
}
- binaryTree
{
return _binary_tree;
}
- (void) setBinaryTree: anObject
{
_binary_tree = anObject;
}
@end

View file

@ -1,197 +0,0 @@
/* Implementation for Objective-C CircularArray collection object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/CircularArray.h>
#include <base/CircularArrayPrivate.h>
@implementation CircularArray
/* This is the designated initializer of this class */
- initWithCapacity: (unsigned)aCapacity
{
[super initWithCapacity:aCapacity];
_start_index = 0;
return self;
}
/* Archiving must mimic the above designated initializer */
- _initCollectionWithCoder: coder
{
[super _initCollectionWithCoder:coder];
_start_index = 0;
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
CircularArray *copy = [super emptyCopy];
copy->_start_index = 0;
return copy;
}
- (void) empty
{
[super empty];
_start_index = 0;
}
/* This is the only method that changes the value of the instance
variable _capacity, except for "-initWithCapacity:" */
- (void) setCapacity: (unsigned)newCapacity
{
id *new_contents;
int i;
if (newCapacity > _count) {
/* This could be more efficient */
OBJC_MALLOC(new_contents, id, newCapacity);
for (i = 0; i < _count; i++)
new_contents[i] = _contents_array[CIRCULAR_TO_BASIC(i)];
OBJC_FREE(_contents_array);
_contents_array = new_contents;
_start_index = 0;
_capacity = newCapacity;
}
}
- (void) removeObjectAtIndex: (unsigned)index
{
unsigned basicIndex;
CHECK_INDEX_RANGE_ERROR(index, _count);
basicIndex = CIRCULAR_TO_BASIC(index);
[_contents_array[basicIndex] release];
circularFillHoleAt(self, basicIndex);
decrementCount(self);
}
- (void) removeFirstObject
{
if (!_count)
return;
[_contents_array[_start_index] release];
_start_index = (_start_index + 1) % _capacity;
decrementCount(self);
}
- (void) removeLastObject
{
if (!_count)
return;
[_contents_array[CIRCULAR_TO_BASIC(_count-1)] release];
decrementCount(self);
}
- objectAtIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count);
return _contents_array[CIRCULAR_TO_BASIC(index)];
}
- (void) appendObject: newObject
{
incrementCount(self);
[newObject retain];
_contents_array[CIRCULAR_TO_BASIC(_count-1)] = newObject;
}
- (void) prependElement: newObject
{
incrementCount(self);
[newObject retain];
_start_index = (_capacity + _start_index - 1) % _capacity;
_contents_array[_start_index] = newObject;
}
- (void) insertElement: newObject atIndex: (unsigned)index
{
unsigned basicIndex;
CHECK_INDEX_RANGE_ERROR(index, _count+1);
incrementCount(self);
[newObject retain];
basicIndex = CIRCULAR_TO_BASIC(index);
circularMakeHoleAt(self, basicIndex);
_contents_array[basicIndex] = newObject;
}
- (void) replaceObjectAtIndex: (unsigned)index withObject: newObject
{
unsigned basicIndex;
CHECK_INDEX_RANGE_ERROR(index, _count);
[newObject retain];
basicIndex = CIRCULAR_TO_BASIC(index);
[_contents_array[basicIndex] release];
_contents_array[basicIndex] = newObject;
}
- (void) swapAtIndeces: (unsigned)index1 : (unsigned)index2
{
id tmp;
CHECK_INDEX_RANGE_ERROR(index1, _count);
CHECK_INDEX_RANGE_ERROR(index2, _count);
index1 = CIRCULAR_TO_BASIC(index1);
index2 = CIRCULAR_TO_BASIC(index2);
tmp = _contents_array[index1];
_contents_array[index1] = _contents_array[index2];
_contents_array[index2] = tmp;
}
#if 0
/* just temporary for debugging */
- circularArrayPrintForDebugger
{
int i;
printf("_start_index=%d, _count=%d, _capacity=%d\n",
_start_index, _count, _capacity);
for (i = 0; i < _capacity; i++)
{
printf("%3d ", i);
}
printf("\n");
for (i = 0; i < _capacity; i++)
{
printf("%3d ", _contents_array[i].int_t);
}
printf("\n");
for (i = 0; i < _capacity; i++)
{
printf("%3d ", _contents_array[CIRCULAR_TO_BASIC(i)].int_t);
}
printf("\n");
return self;
}
#endif
@end

View file

@ -1,839 +0,0 @@
/* Implementation for Objective-C Collection object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/Collection.h>
#include <base/CollectionPrivate.h>
#include <stdarg.h>
#include <base/Bag.h> /* for -contentsEqual: */
#include <base/Array.h> /* for -safeWithElementsCall: */
#include <base/Coder.h>
#include <base/NSString.h>
@implementation Enumerator
- initWithCollection: coll
{
self = [super init];
if (self)
{
collection = [coll retain];
enum_state = [coll newEnumState];
}
return self;
}
- nextObject
{
return [collection nextObjectWithEnumState: &enum_state];
}
- (void) dealloc
{
[collection freeEnumState: &enum_state];
[collection release];
[super dealloc];
}
@end
@implementation ConstantCollection
// INITIALIZING AND RELEASING;
- init
{
return [self initWithObjects: NULL count: 0];
}
// This is the designated initializer of this class;
- initWithObjects: (id*)objc count: (unsigned)c
{
[self subclassResponsibility: _cmd];
return self;
}
- initWithObjects: firstObject, ...
{
va_list ap;
va_start(ap, firstObject);
self = [self initWithObjects:firstObject rest:ap];
va_end(ap);
return self;
}
#define INITIAL_OBJECTS_SIZE 10
- initWithObjects: firstObject rest: (va_list)ap
{
id *objects;
int i = 0;
int s = INITIAL_OBJECTS_SIZE;
OBJC_MALLOC(objects, id, s);
if (firstObject != nil)
{
objects[i++] = firstObject;
while ((objects[i++] = va_arg(ap, id)))
{
if (i >= s)
{
s *= 2;
OBJC_REALLOC(objects, id, s);
}
}
}
self = [self initWithObjects:objects count:i-1];
OBJC_FREE(objects);
return self;
}
/* Subclasses can override this for efficiency. For example, Array can
init itself with enough capacity to hold aCollection. */
- initWithContentsOf: (id <Collecting>)aCollection
{
int count = [aCollection count];
id contents_array[count];
id o;
int i = 0;
FOR_COLLECTION(aCollection, o)
{
contents_array[i++] = o;
}
END_FOR_COLLECTION(aCollection);
return [self initWithObjects: contents_array count: count];
}
- (void) dealloc
{
/* xxx Get rid of this since Set, Bag, Dictionary, and String
subclasses don't want to use it? */
[self _collectionReleaseContents];
[self _collectionDealloc];
[super dealloc];
}
// QUERYING COUNTS;
- (BOOL) isEmpty
{
return ([self count] == 0);
}
// Inefficient, so should be overridden in subclasses;
- (unsigned) count
{
unsigned n = 0;
id o;
FOR_COLLECTION(self, o)
{
n++;
}
END_FOR_COLLECTION(self);
return n;
}
// Potentially inefficient, may be overridden in subclasses;
- (BOOL) containsObject: anObject
{
id o;
FOR_COLLECTION (self, o)
{
if ([anObject isEqual: o])
return YES;
}
END_FOR_COLLECTION(self);
return NO;
}
- (unsigned) occurrencesOfObject: anObject
{
unsigned count = 0;
id o;
FOR_COLLECTION(self, o)
{
if ([anObject isEqual: o])
count++;
}
END_FOR_COLLECTION(self);
return count;
}
// COMPARISON WITH OTHER COLLECTIONS;
- (BOOL) isSubsetOf: (id <Collecting>)aCollection
{
id o;
FOR_COLLECTION (self, o)
{
if (![aCollection containsObject: o])
return NO;
}
END_FOR_COLLECTION (self);
return YES;
}
- (BOOL) isDisjointFrom: (id <Collecting>)aCollection
{
// Use objc_msg_lookup here also;
BOOL flag = YES;
id o;
FOR_COLLECTION_WHILE_TRUE(self, o, flag)
{
if (![aCollection containsObject: o])
flag = NO;
}
END_FOR_COLLECTION_WHILE_TRUE(self);
return !flag;
}
// xxx How do we want to compare unordered contents?? ;
- (int) compareContentsOf: (id <Collecting>)aCollection
{
if ([self contentsEqual:aCollection])
return 0;
if (self > aCollection)
return 1;
return -1;
}
- (BOOL) isEqual: anObject
{
if (self == anObject)
return YES;
if ( [self contentsEqual: anObject] )
return YES;
else
return NO;
}
// Deal with this in IndexedCollection also ;
// How do we want to compare collections? ;
- (int) compare: anObject
{
if ([self isEqual:anObject])
return 0;
if (self > anObject)
return 1;
return -1;
}
- (BOOL) contentsEqual: (id <Collecting>)aCollection
{
id bag, o;
BOOL flag;
if ([self count] != [aCollection count])
return NO;
bag = [[Bag alloc] initWithContentsOf:aCollection];
flag = YES;
FOR_COLLECTION_WHILE_TRUE (self, o, flag)
{
if ([bag containsObject: o])
[bag removeObject: o];
else
flag = NO;
}
END_FOR_COLLECTION_WHILE_TRUE(self);
if ((!flag) || [bag count])
flag = NO;
else
flag = YES;
[bag release];
return flag;
}
// PROPERTIES OF CONTENTS;
- (BOOL) trueForAllObjectsByInvoking: (id <Invoking>)anInvocation
{
BOOL flag = YES;
id o;
FOR_COLLECTION_WHILE_TRUE(self, o, flag)
{
[anInvocation invokeWithObject: o];
if (![anInvocation returnValueIsTrue])
flag = NO;
}
END_FOR_COLLECTION_WHILE_TRUE(self);
return flag;
}
- (BOOL) trueForAnyObjectsByInvoking: (id <Invoking>)anInvocation;
{
BOOL flag = YES;
id o;
FOR_COLLECTION_WHILE_TRUE(self, o, flag)
{
[anInvocation invokeWithObject: o];
if ([anInvocation returnValueIsTrue])
flag = NO;
}
END_FOR_COLLECTION_WHILE_TRUE(self);
return !flag;
}
- detectObjectByInvoking: (id <Invoking>)anInvocation;
{
BOOL flag = YES;
id detectedObject = nil;
id o;
FOR_COLLECTION_WHILE_TRUE(self, o, flag)
{
[anInvocation invokeWithObject: o];
if ([anInvocation returnValueIsTrue])
{
flag = NO;
detectedObject = o;
}
}
END_FOR_COLLECTION_WHILE_TRUE(self);
if (flag)
return NO_OBJECT;
else
return detectedObject;
}
- maxObject
{
id o, max = nil;
BOOL firstTime = YES;
FOR_COLLECTION(self, o)
{
if (firstTime)
{
firstTime = NO;
max = o;
}
else
{
if ([o compare: max] > 0)
max = o;
}
}
END_FOR_COLLECTION(self);
return max;
}
- minObject
{
id o, min = nil;
BOOL firstTime = YES;
FOR_COLLECTION(self, o)
{
if (firstTime)
{
firstTime = NO;
min = o;
}
else
{
if ([o compare: min] < 0)
min = o;
}
}
END_FOR_COLLECTION(self);
return min;
}
/* Consider adding:
- maxObjectByInvoking: (id <Invoking>)anInvocation;
- minObjectByInvoking: (id <Invoking>)anInvocation;
*/
// ENUMERATING;
- (id <Enumerating>) objectEnumerator
{
return [[[Enumerator alloc] initWithCollection: self]
autorelease];
}
- (void) withObjectsInvoke: (id <Invoking>)anInvocation
{
id o;
FOR_COLLECTION(self, o)
{
[anInvocation invokeWithObject: o];
}
END_FOR_COLLECTION(self);
}
- (void) withObjectsInvoke: (id <Invoking>)anInvocation whileTrue:(BOOL *)flag;
{
id o;
FOR_COLLECTION_WHILE_TRUE(self, o, *flag)
{
[anInvocation invokeWithObject: o];
}
END_FOR_COLLECTION_WHILE_TRUE(self);
}
- (void) makeObjectsPerform: (SEL)aSel
{
id o;
FOR_COLLECTION(self, o)
{
[o performSelector: aSel];
}
END_FOR_COLLECTION(self);
}
- (void) makeObjectsPerform: (SEL)aSel withObject: argObject
{
id o;
FOR_COLLECTION(self, o)
{
[o performSelector: aSel withObject: argObject];
}
END_FOR_COLLECTION(self);
}
// FILTERED ENUMERATING;
- (void) withObjectsTrueByInvoking: (id <Invoking>)testInvocation
invoke: (id <Invoking>)anInvocation
{
id o;
FOR_COLLECTION(self, o)
{
[testInvocation invokeWithObject: o];
if ([testInvocation returnValueIsTrue])
[anInvocation invokeWithObject: o];
}
END_FOR_COLLECTION(self);
}
- (void) withObjectsFalseByInvoking: (id <Invoking>)testInvocation
invoke: (id <Invoking>)anInvocation
{
id o;
FOR_COLLECTION(self, o)
{
[testInvocation invokeWithObject: o];
if (![testInvocation returnValueIsTrue])
[anInvocation invokeWithObject: o];
}
END_FOR_COLLECTION(self);
}
- (void) withObjectsTransformedByInvoking: (id <Invoking>)transInvocation
invoke: (id <Invoking>)anInvocation
{
id o;
FOR_COLLECTION(self, o)
{
[transInvocation invokeWithObject: o];
[anInvocation invokeWithObject: [transInvocation objectReturnValue]];
}
END_FOR_COLLECTION(self);
}
// LOW-LEVEL ENUMERATING;
- (void*) newEnumState
{
return (void*)0;
}
- nextObjectWithEnumState: (void**)enumState;
{
[self subclassResponsibility: _cmd];
return NO;
}
- (void) freeEnumState: (void**)enumState
{
*enumState = (void*)0;
}
// COPYING;
- allocCopy
{
return NSCopyObject (self, 0, [self zone]);
}
// the copy to be filled by -shallowCopyAs: etc... ;
- emptyCopy
{
// This will copy all instance vars;
// Subclasses will have to change instance vars like Array's _contents_array;
return [self allocCopy];
}
// the copy to be filled by -shallowCopyAs: etc... ;
- emptyCopyAs: (Class)aCollectionClass
{
if (aCollectionClass == [self species])
return [self emptyCopy];
else
return [[(id)aCollectionClass alloc] init];
}
- shallowCopy
{
return [self shallowCopyAs:[self species]];
}
- shallowCopyAs: (Class)aCollectionClass
{
id newColl = [self emptyCopyAs:aCollectionClass];
//#warning fix this addContentsOf for ConstantCollection
[newColl addContentsOf:self];
return newColl;
}
/* We can avoid the ugly [self safeWithElementsCall:doIt];
in -deepen with something like this instead.
This fits with a scheme in which we get rid of the -deepen method, an
idea that I like since calling deepen on an object that has not just
been -shallowCopy'ed can cause major memory leakage. */
- copyAs: (id <Collecting>)aCollectionClass
{
id newColl = [self emptyCopyAs: (Class)aCollectionClass];
id o;
FOR_COLLECTION(self, o)
{
//#warning fix this addObject for ConstantCollection
id n = [o copy];
[newColl addObject:n];
[n release];
}
END_FOR_COLLECTION(self);
return newColl;
}
- species
{
return [self class];
}
// EXTRAS;
- (const char *) libobjectsLicense
{
const char *licenseString =
"Copyright (C) 1993,1994,1995,1996 Free Software Foundation, Inc.\n"
"\n"
"Chief Maintainer: Andrew McCallum <mccallum@gnu.ai.mit.edu>\n"
"\n"
"This object is part of the GNUstep Base Library.\n"
"\n"
"This library is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU Library General Public\n"
"License as published by the Free Software Foundation; either\n"
"version 2 of the License, or (at your option) any later version.\n"
"\n"
"This library is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
"Library General Public License for more details.\n"
"\n"
"You should have received a copy of the GNU Library General Public\n"
"License along with this library; if not, write to the Free\n"
"Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.\n";
return licenseString;
}
- printForDebugger
{
id o;
FOR_COLLECTION(self, o)
{
printf("%s ", [[o description] cString]);
}
END_FOR_COLLECTION(self);
printf(": %s\n", object_get_class_name (self));
return self;
}
- (void) encodeWithCoder: aCoder
{
[self _encodeCollectionWithCoder:aCoder];
[self _encodeContentsWithCoder:aCoder];
}
- initWithCoder: aCoder
{
[self _initCollectionWithCoder:aCoder];
[self _decodeContentsWithCoder:aCoder];
return self;
}
@end
@implementation ConstantCollection (ArchivingHelpers)
- (void) _encodeCollectionWithCoder: aCoder
{
[super encodeWithCoder:aCoder];
// there are no instance vars;
return;
}
- _initCollectionWithCoder: aCoder
{
// there are no instance vars;
return [super initWithCoder:aCoder];
}
- (void) _encodeContentsWithCoder: (id <Encoding>)aCoder
{
unsigned int count = [self count];
id o;
[aCoder encodeValueOfCType: @encode(unsigned)
at: &count
withName: @"Collection content count"];
FOR_COLLECTION(self, o)
{
[aCoder encodeObject: o
withName:@"Collection element"];
}
END_FOR_COLLECTION(self);
}
- (void) _decodeContentsWithCoder: (id <Decoding>)aCoder
{
id *content_array;
unsigned int count, i;
[aCoder decodeValueOfCType:@encode(unsigned)
at:&count
withName:NULL];
content_array = alloca (sizeof (id) * count);
for (i = 0; i < count; i++)
[aCoder decodeObjectAt: &(content_array[i])
withName:NULL];
[self initWithObjects: content_array count: count];
for (i = 0; i < count; i++)
[content_array[i] release];
}
@end
@implementation ConstantCollection (DeallocationHelpers)
/* This must work without sending any messages to content objects.
Content objects already may be dealloc'd when this is executed. */
- (void) _collectionEmpty
{
[self subclassResponsibility:_cmd];
}
- (void) _collectionReleaseContents
{
int c = [self count];
if (c)
{
id *array = (id*) alloca (c * sizeof(id));
int i = 0;
void *es = [self newEnumState];
id o;
while ((o = [self nextObjectWithEnumState:&es]))
{
array[i++] = o;
}
[self freeEnumState: &es];
for (i = 0; i < c; i++)
[array[i] release];
}
}
- (void) _collectionDealloc
{
return;
}
@end
@implementation Collection
// ADDING;
- (void) addObject: anObject
{
[self subclassResponsibility:_cmd];
}
- (void) addObjectIfAbsent: newObject;
{
if (![self containsObject: newObject])
[self addObject: newObject];
}
- (void) addContentsOf: (id <Collecting>)aCollection
{
id o;
FOR_COLLECTION(aCollection, o)
{
[self addObject: o];
}
END_FOR_COLLECTION(aCollection);
}
- (void) addContentsIfAbsentOf: (id <Collecting>)aCollection
{
id o;
FOR_COLLECTION(aCollection, o)
{
if (![self containsObject:o])
[self addObject: o];
}
END_FOR_COLLECTION(aCollection);
}
- (void) addWithObjects: (id*)objc count: (unsigned)c
{
[self notImplemented: _cmd];
}
- (void) addObjects: firstObject, ...
{
[self notImplemented: _cmd];
}
- (void) addObjects: firstObject rest: (va_list)ap
{
[self notImplemented: _cmd];
}
// REMOVING AND REPLACING;
- (void) removeObject: oldObject
{
[self subclassResponsibility: _cmd];
}
- (void) removeAllOccurrencesOfObject: oldObject
{
while ([self containsObject: oldObject])
[self removeObject: oldObject];
}
- (void) removeContentsIn: (id <ConstantCollecting>)aCollection
{
id o;
FOR_COLLECTION(aCollection, o)
{
[self removeObject: o];
}
END_FOR_COLLECTION(aCollection);
}
- (void) removeContentsNotIn: (id <ConstantCollecting>)aCollection
{
id o;
FOR_COLLECTION(self, o)
{
if (![aCollection containsObject: o])
[self removeObject: o];
}
END_FOR_COLLECTION(self);
}
- (void) uniqueContents
{
id cp = [self shallowCopy];
int count;
id o;
FOR_COLLECTION(cp, o)
{
count = [self occurrencesOfObject: o];
if (!count)
continue;
while (count--)
[self removeObject: o];
}
END_FOR_COLLECTION(cp);
}
/* May be inefficient. Could be overridden; */
- (void) empty
{
if ([self isEmpty])
return;
[self _collectionReleaseContents];
[self _collectionEmpty];
}
// REPLACING;
- (void) replaceObject: oldObject withObject: newObject
{
if ([newObject isEqual: newObject])
return;
[oldObject retain];
[self removeObject: oldObject];
[self addObject: newObject];
[oldObject release];
}
- (void) replaceAllOccurrencesOfObject: oldObject withObject: newObject
{
if ([oldObject isEqual: newObject])
return;
while ([self containsObject: oldObject])
[self replaceObject: oldObject withObject: newObject];
}
@end

View file

@ -1,210 +0,0 @@
/* Implementation of Objective-C "collection of delegates" object
Copyright (C) 1993,1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
This file is part of the GNU Objective-C Collection library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/DelegatePool.h>
#include <base/NSString.h>
@implementation DelegatePool
+ (void) initialize
{
return;
}
+ alloc
{
return (id)class_create_instance(self);
}
+ new
{
return [[self alloc] init];
}
/* This is the designated initializer for this class. */
- init
{
_list = [[Array alloc] init];
_send_behavior = SEND_TO_ALL;
_last_message_had_receivers = NO;
return self;
}
/* Archiving must mimic the above designated initializer */
- (void) encodeWithCoder: anEncoder
{
[anEncoder encodeValueOfCType:@encode(unsigned char)
at:&_send_behavior
withName:@"DelegatePool Send Behavior"];
[anEncoder encodeObject:_list
withName:@"DelegatePool Collection of Delegates"];
}
+ newWithCoder: aDecoder
{
/* xxx Should be:
DelegatePool *n = NSAllocateObject(self, 0, [aDecoder objectZone]); */
DelegatePool *n = (id) NSAllocateObject(self, 0, NSDefaultMallocZone());
[aDecoder decodeValueOfCType:@encode(unsigned char)
at:&(n->_send_behavior)
withName:NULL];
[aDecoder decodeObjectAt:&(n->_list)
withName:NULL];
return n;
}
- write: (TypedStream*)aStream
{
objc_write_type(aStream, @encode(unsigned char), &_send_behavior);
objc_write_object(aStream, _list);
return self;
}
- read: (TypedStream*)aStream
{
objc_write_type(aStream, @encode(unsigned char), &_send_behavior);
objc_read_object(aStream, &_list);
return self;
}
- (void) dealloc
{
[_list release];
#if NeXT_runtime
object_dispose((Object*)self);
#else
NSDeallocateObject((NSObject*)self);
#endif
}
// MANIPULATING COLLECTION OF DELEGATES;
- (void) delegatePoolAddObject: anObject
{
[_list addObject: anObject];
}
- (void) delegatePoolAddObjectIfAbsent: anObject
{
[_list addObjectIfAbsent: anObject];
}
- (void) delegatePoolRemoveObject: anObject
{
[_list removeObject:anObject];
}
- (BOOL) delegatePoolIncludesObject: anObject
{
return [_list containsObject:anObject];
}
- delegatePoolCollection
{
return _list;
}
- (unsigned char) delegatePoolSendBehavior
{
return _send_behavior;
}
- (void) delegatePoolSetSendBehavior: (unsigned char)b
{
_send_behavior = b;
}
- (BOOL) delegatePoolLastMessageHadReceivers
{
return _last_message_had_receivers;
}
// FOR PASSING ALL OTHER MESSAGES TO DELEGATES;
- forward: (SEL)aSel :(arglist_t)argFrame
{
void *ret = 0;
id delegate;
_last_message_had_receivers = NO;
switch (_send_behavior)
{
case SEND_TO_ALL:
FOR_ARRAY(_list, delegate)
{
if ([delegate respondsTo:aSel])
{
ret = [delegate performv:aSel :argFrame];
_last_message_had_receivers = YES;
}
}
END_FOR_ARRAY (_list);
break;
case SEND_TO_FIRST_RESPONDER:
FOR_ARRAY(_list, delegate)
{
if ([delegate respondsTo:aSel])
{
_last_message_had_receivers = YES;
return [delegate performv:aSel :argFrame];
}
}
END_FOR_ARRAY (_list);
break;
case SEND_UNTIL_YES:
FOR_ARRAY(_list, delegate)
{
if ([delegate respondsTo:aSel])
{
_last_message_had_receivers = YES;
if ((ret = [delegate performv:aSel :argFrame]))
return ret;
}
}
END_FOR_ARRAY (_list);
break;
case SEND_UNTIL_NO:
FOR_ARRAY(_list, delegate)
{
if ([delegate respondsTo:aSel])
{
_last_message_had_receivers = YES;
if (!(ret = [delegate performv:aSel :argFrame]))
return ret;
}
}
END_FOR_ARRAY (_list);
break;
}
return ret;
}
@end

View file

@ -1,209 +0,0 @@
/* Implementation for Objective-C Dictionary collection object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/Dictionary.h>
#include <base/CollectionPrivate.h>
#include <Foundation/NSCharacterSet.h>
#define DEFAULT_DICTIONARY_CAPACITY 32
@implementation Dictionary
// MANAGING CAPACITY;
/* Eventually we will want to have better capacity management,
potentially keep default capacity as a class variable. */
+ (unsigned) defaultCapacity
{
return DEFAULT_DICTIONARY_CAPACITY;
}
// INITIALIZING;
/* This is the designated initializer of this class */
- initWithCapacity: (unsigned)cap
{
_contents_hash = NSCreateMapTable (NSObjectMapKeyCallBacks,
NSObjectMapValueCallBacks,
cap);
return self;
}
/* Override the KeyedCollection designated initializer */
- initWithObjects: (id*)objects forKeys: (id*)keys count: (unsigned)c
{
[self initWithCapacity: c];
while (c--)
[self putObject: objects[c] atKey: keys[c]];
return self;
}
- init
{
return [self initWithCapacity: DEFAULT_DICTIONARY_CAPACITY];
}
/* Archiving must mimic the above designated initializer */
- _initCollectionWithCoder: (id <Decoding>)coder
{
_contents_hash = NSCreateMapTable (NSObjectMapKeyCallBacks,
NSObjectMapValueCallBacks,
0);
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
Dictionary *copy = [super emptyCopy];
copy->_contents_hash = NSCreateMapTable (NSObjectMapKeyCallBacks,
NSObjectMapValueCallBacks,
0);
return copy;
}
- (void) _collectionReleaseContents
{
if (_contents_hash) {
NSFreeMapTable (_contents_hash);
_contents_hash = 0;
}
}
- (void) dealloc
{
[self _collectionReleaseContents];
[super dealloc];
}
/* This must work without sending any messages to content objects */
- (void) _collectionEmpty
{
NSResetMapTable (_contents_hash);
}
// ADDING OR REPLACING;
- (void) addObject: newObject
{
[self shouldNotImplement: _cmd];
/* or should I make up some default behavior here?
Base it on object conforming to <Associating> protocol, perhaps */
}
- (void) putObject: newObject atKey: aKey
{
NSMapInsert (_contents_hash, aKey, newObject);
}
// REMOVING;
- (void) removeObjectAtKey: aKey
{
NSMapRemove (_contents_hash, aKey);
}
- (void) removeObject: oldObject
{
/* xxx Could be more efficient! */
int count = [self count];
id keys_to_remove[count];
int num_keys_to_remove = 0;
id o, k;
NSMapEnumerator me = NSEnumerateMapTable (_contents_hash);
/* Find all the keys with corresponding objects that equal oldObject. */
while (NSNextMapEnumeratorPair (&me, (void**)&k, (void**)&o))
if ([oldObject isEqual: o])
keys_to_remove[num_keys_to_remove++] = k;
/* Remove them. */
while (num_keys_to_remove--)
[self removeObjectAtKey: keys_to_remove[num_keys_to_remove]];
}
// GETTING ELEMENTS;
- (NSArray*) allKeys
{
return NSAllMapTableKeys(_contents_hash);
}
- (NSArray*) allValues
{
return NSAllMapTableValues(_contents_hash);
}
- objectAtKey: aKey
{
return NSMapGet (_contents_hash, aKey);
}
// TESTING;
- (BOOL) containsKey: aKey
{
if (NSMapGet (_contents_hash, aKey))
return YES;
else
return NO;
}
- (unsigned) count
{
return NSCountMapTable (_contents_hash);
}
// ENUMERATIONS;
- nextObjectAndKey: (id*)aKeyPtr withEnumState: (void**)enumState
{
id o;
if (!NSNextMapEnumeratorPair (*enumState, (void**)aKeyPtr, (void**)&o))
return NO_OBJECT;
return o;
}
- (void*) newEnumState
{
void *me;
OBJC_MALLOC (me, NSMapEnumerator, 1);
*((NSMapEnumerator*)me) = NSEnumerateMapTable (_contents_hash);
return me;
}
- (void) freeEnumState: (void**)enumState
{
OBJC_FREE (*enumState);
}
@end

View file

@ -69,42 +69,17 @@ FILE_AUTHORS = \
# The GNU source files
GNU_MFILES = \
Archiver.m \
Array.m \
Bag.m \
BinaryCStream.m \
BinaryTree.m \
BinaryTreeNode.m \
CircularArray.m \
Collection.m \
ConnectedCoder.m \
Coder.m \
CStream.m \
Decoder.m \
DelegatePool.m \
Dictionary.m \
Encoder.m \
GapArray.m \
GetDefEncoding.m \
Heap.m \
IndexedCollection.m \
Invocation.m \
KeyedCollection.m \
LinkedList.m \
LinkedListNode.m \
MachPort.m \
MappedCollector.m \
MemoryStream.m \
NotificationDispatcher.m \
OrderedCollection.m \
Port.m \
Queue.m \
RawCStream.m \
RBTree.m \
RBTreeNode.m \
Set.m \
SplayTree.m \
Stack.m \
StdioStream.m \
Stream.m \
TcpPort.m \
@ -137,11 +112,6 @@ mframe.m \
objc-gnu2next.m
GNU_EXTRAS_MFILES = \
Magnitude.m \
Random.m \
RNGAdditiveCongruential.m \
RNGBerkeley.m \
Time.m
GNU_CFILES = \
md5.c \
@ -163,59 +133,23 @@ fast.x \
GSUnion.h \
GSIArray.h \
GSIMap.h \
Archiver.h \
Array.h \
ArrayPrivate.h \
Bag.h \
BinaryCStream.h \
BinaryTree.h \
BinaryTreeNode.h \
CircularArray.h \
CircularArrayPrivate.h \
Coder.h \
CoderPrivate.h \
Coding.h \
Collecting.h \
Collection.h \
CollectionPrivate.h \
ConnectedCoder.h \
CStream.h \
CStreaming.h \
DelegatePool.h \
Dictionary.h \
Enumerating.h \
GapArray.h \
GapArrayPrivate.h \
GetDefEncoding.h \
Heap.h \
IndexedCollecting.h \
IndexedCollection.h \
IndexedCollectionPrivate.h \
InvalidationListening.h \
Invocation.h \
Invoking.h \
KeyedCollecting.h \
KeyedCollection.h \
LinkedList.h \
LinkedListNode.h \
Locking.h \
MachPort.h \
MappedCollector.h \
MemoryStream.h \
NotificationDispatcher.h \
Ordering.h \
OrderedCollecting.h \
OrderedCollection.h \
Port.h \
Queue.h \
RBTree.h \
RBTreeNode.h \
RawCStream.h \
Retaining.h \
RunLoop.h \
Set.h \
SplayTree.h \
Stack.h \
StdioStream.h \
Stream.h \
Streaming.h \
@ -245,13 +179,6 @@ objc-gnu2next.h \
preface.h
GNU_EXTRAS_HFILES = \
all.h \
Magnitude.h \
Random.h \
RNGAdditiveCongruential.h \
RNGBerkeley.h \
RandomGenerating.h \
Time.h
# GNUStep source files

View file

@ -1,144 +0,0 @@
/* Implementation for Objective-C GapArray collection object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Kresten Krab Thorup <krab@iesd.auc.dk>
Dept. of Mathematics and Computer Science, Aalborg U., Denmark
Overhauled by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/GapArray.h>
#include <base/GapArrayPrivate.h>
@implementation GapArray
/* This is the designated initializer of this class */
/* Override designated initializer of superclass */
- initWithCapacity: (unsigned)aCapacity
{
[super initWithCapacity: aCapacity];
_gap_start = 0;
_gap_size = aCapacity;
return self;
}
/* Archiving must mimic the above designated initializer */
- (void) encodeWithCoder: anEncoder
{
[self notImplemented:_cmd];
}
+ newWithCoder: aDecoder
{
[self notImplemented:_cmd];
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
GapArray *copy = [super emptyCopy];
copy->_gap_start = 0;
copy->_gap_size = copy->_capacity;
return copy;
}
- (void) empty
{
[super empty];
_gap_start = 0;
_gap_size = _capacity;
}
- (void) setCapacity: (unsigned)newCapacity
{
if (newCapacity > _count)
{
gapMoveGapTo (self, _capacity-_gap_size); /* move gap to end */
[super setCapacity: newCapacity]; /* resize */
_gap_size = _capacity - _gap_start;
}
}
- (void) removeObjectAtIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count);
[_contents_array[GAP_TO_BASIC (index)] release];
gapFillHoleAt (self, index);
decrementCount(self);
}
- objectAtIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count);
return _contents_array[GAP_TO_BASIC(index)];
}
- (void) appendObject: newObject
{
incrementCount(self);
[newObject retain];
gapMakeHoleAt (self, _count-1);
_contents_array[_count-1] = newObject;
}
- (void) prependObject: newObject
{
incrementCount(self);
[newObject retain];
gapMakeHoleAt (self, 0);
_contents_array[0] = newObject;
}
- (void) insertObject: newObject atIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count+1);
incrementCount(self);
[newObject retain];
gapMakeHoleAt (self, index);
_contents_array[index] = newObject;
}
- (void) replaceObjectAtIndex: (unsigned)index withObject: newObject
{
CHECK_INDEX_RANGE_ERROR(index, _count);
[newObject retain];
[_contents_array[GAP_TO_BASIC(index)] release];
_contents_array[GAP_TO_BASIC(index)] = newObject;
}
- (void) swapAtIndeces: (unsigned)index1 : (unsigned)index2
{
id tmp;
CHECK_INDEX_RANGE_ERROR(index1, _count);
CHECK_INDEX_RANGE_ERROR(index2, _count);
index1 = GAP_TO_BASIC(index1);
index2 = GAP_TO_BASIC(index2);
tmp = _contents_array[index1];
_contents_array[index1] = _contents_array[index2];
_contents_array[index2] = tmp;
}
@end

View file

@ -1,102 +0,0 @@
/* Implementation for Objective-C Heap object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/* This class could be improved by somehow making is a subclass of
IndexedCollection, but not OrderedCollection. */
#include <config.h>
#include <base/Heap.h>
#include <base/ArrayPrivate.h>
#define HEAP_PARENT(i) (i/2)
#define HEAP_LEFT(i) (2 * i)
#define HEAP_RIGHT(i) ((2 * i) + 1)
@implementation Heap
/* We could take out the recursive call to make it a little more efficient */
- (void) heapifyFromIndex: (unsigned)index
{
unsigned right, left, largest;
id tmp;
right = HEAP_RIGHT(index);
left = HEAP_LEFT(index);
if (left < _count
&& [_contents_array[index] compare: _contents_array[left]] > 0)
largest = left;
else
largest = index;
if (right < _count
&& [_contents_array[largest] compare: _contents_array[right]] > 0)
largest = right;
if (largest != index)
{
tmp = _contents_array[index];
_contents_array[index] = _contents_array[largest];
_contents_array[largest] = tmp;
[self heapifyFromIndex:largest];
}
}
- (void) heapify
{
int i;
// could use objc_msg_lookup here;
for (i = _count / 2; i >= 1; i--)
[self heapifyFromIndex:i];
}
- (void) removeFirstObject
{
if (_count == 0)
return;
[_contents_array[0] release];
_contents_array[0] = _contents_array[_count-1];
decrementCount(self);
[self heapifyFromIndex:0];
}
- (void) addObject: newObject
{
int i;
incrementCount(self);
[newObject retain];
for (i = _count-1;
i > 0
&& [newObject compare: _contents_array[HEAP_PARENT(i)]] < 0;
i = HEAP_PARENT(i))
{
_contents_array[i] = _contents_array[HEAP_PARENT(i)];
}
_contents_array[i] = newObject;
}
- (id) minObject
{
return [self firstObject];
}
@end

View file

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

View file

@ -1,861 +0,0 @@
/* Implementation for Objective-C Invocation object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <mframe.h>
#include <base/preface.h>
#include <base/Invocation.h>
#include <Foundation/DistributedObjects.h>
#include <Foundation/NSValue.h>
#include <Foundation/NSString.h>
#include <Foundation/NSConnection.h>
#include <Foundation/NSException.h>
extern BOOL sel_types_match(const char* t1, const char* t2);
/* xxx We are currently retaining the return value.
We shouldn't always do this. Make is an option. */
/* Deal with strrchr: */
#if STDC_HEADERS || HAVE_STRING_H
#include <string.h>
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
#if !STDC_HEADERS && HAVE_MEMORY_H
#include <memory.h>
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
#define rindex strrchr
#define bcopy(s, d, n) memcpy ((d), (s), (n))
#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
#define bzero(s, n) memset ((s), 0, (n))
#else /* not STDC_HEADERS and not HAVE_STRING_H */
#include <strings.h>
/* memory.h and strings.h conflict on some systems. */
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
/* xxx Perhaps make this an ivar. */
#define return_retained 0
@implementation Invocation
- initWithReturnType: (const char *)enc
{
int l = strlen(enc);
OBJC_MALLOC(return_type, char, l + 1);
memcpy(return_type, enc, l);
return_type[l] = '\0';
enc = objc_skip_type_qualifiers (return_type);
if (*enc != 'v')
{
/* Work around bug in objc_sizeof_type; it doesn't handle void type */
return_size = objc_sizeof_type (enc);
return_value = objc_calloc (1, return_size);
}
else
{
return_size = 0;
return_value = NULL;
}
return self;
}
- (void) encodeWithCoder: (id <Encoding>)coder
{
[super encodeWithCoder: coder];
[coder encodeValueOfCType: @encode(char*)
at: &return_type
withName: @"Invocation return type"];
[coder encodeValueOfCType: @encode(unsigned)
at: &return_size
withName: @"Invocation return size"];
if (return_size)
[coder encodeValueOfObjCType: return_type
at: return_value
withName: @"Invocation return value"];
}
- initWithCoder: (id <Decoding>)coder
{
self = [super initWithCoder: coder];
[coder decodeValueOfCType: @encode(char*)
at: &return_type
withName: NULL];
[coder decodeValueOfCType: @encode(unsigned)
at: &return_size
withName: NULL];
if (return_size)
{
return_value = objc_malloc (return_size);
[coder decodeValueOfObjCType: return_type
at: return_value
withName: NULL];
}
else
return_value = 0;
return self;
}
- (Class) classForConnectedCoder: coder
{
/* Make sure that Connection's always send us bycopy,
i.e. as our own class, not a Proxy class. */
return [self class];
}
/* Next two methods for OPENSTEP */
- (Class) classForPortCoder
{
return [self class];
}
- replacementObjectForPortCoder: coder
{
return self;
}
- (void) invoke
{
[self subclassResponsibility:_cmd];
}
- (void) invokeWithObject: anObj
{
[self subclassResponsibility:_cmd];
}
- (const char *) returnType
{
return return_type;
}
- (unsigned) returnSize
{
return return_size;
}
- (void) getReturnValue: (void *)addr
{
if (return_value)
memcpy (addr, return_value, return_size);
/* xxx what if it hasn't been invoked yet, and there isn't
a return value yet. */
}
- (void) setReturnValue: (void*)addr
{
if (return_value)
{
if (return_retained && *return_type == _C_ID)
{
[*(id*)return_value release];
*(id*)return_value = *(id*)addr;
[*(id*)return_value retain];
}
else
memcpy (return_value, addr, return_size);
}
}
- objectReturnValue
{
switch (*return_type)
{
#define CASE_RETURN(C,T,S) \
case C: return [NSNumber numberWith ## S: *(T*)return_value]
CASE_RETURN (_C_LNG, long, Long);
CASE_RETURN (_C_ULNG, unsigned long, UnsignedLong);
CASE_RETURN (_C_INT, int, Int);
CASE_RETURN (_C_UINT, unsigned int, UnsignedInt);
CASE_RETURN (_C_SHT, short, Short);
CASE_RETURN (_C_USHT, unsigned short, UnsignedShort);
CASE_RETURN (_C_CHR, char, Char);
CASE_RETURN (_C_UCHR, unsigned char, UnsignedChar);
CASE_RETURN (_C_FLT, float, Float);
CASE_RETURN (_C_DBL, double, Double);
#undef CASE_RETURN
case _C_PTR:
return [NSNumber numberWithUnsignedLong: (long) *(void**)return_value];
case _C_CHARPTR:
return [NSString stringWithCString: *(char**)return_value];
case _C_ID:
return *(id*)return_value;
case 'v':
return nil;
default:
[self notImplemented: _cmd];
}
return 0;
[self notImplemented: _cmd];
return nil;
}
- (int) intReturnValue
{
switch (*return_type)
{
#define CASE_RETURN(_C,_T) case _C: return (int) *(_T*)return_value
CASE_RETURN (_C_LNG, long);
CASE_RETURN (_C_ULNG, unsigned long);
CASE_RETURN (_C_INT, int);
CASE_RETURN (_C_UINT, unsigned int);
CASE_RETURN (_C_SHT, short);
CASE_RETURN (_C_USHT, unsigned short);
CASE_RETURN (_C_CHR, char);
CASE_RETURN (_C_UCHR, unsigned char);
CASE_RETURN (_C_CHARPTR, char*);
CASE_RETURN (_C_FLT, float);
CASE_RETURN (_C_DBL, double);
CASE_RETURN (_C_PTR, void*);
#undef CASE_RETURN
case _C_ID:
return [*(id*)return_value intValue];
case 'v':
return 0;
default:
[self notImplemented: _cmd];
}
return 0;
}
- (BOOL) returnValueIsTrue
{
switch (return_size)
{
case sizeof(char):
return (*(char*)return_value != 0);
case sizeof(short):
return (*(short*)return_value != 0);
case sizeof(int):
return (*(int*)return_value != 0);
}
{
int i;
for (i = 0; i < return_size; i++)
if (*((char*)return_value + i) != 0)
return YES;
return NO;
}
}
- (void) dealloc
{
if (return_retained && *return_type == _C_ID)
[*(id*)return_value release];
OBJC_FREE(return_type);
[super dealloc];
}
@end
static int
types_get_size_of_stack_arguments(const char *types)
{
const char* type = objc_skip_typespec (types);
return atoi(type);
}
static int
types_get_size_of_register_arguments(const char *types)
{
const char* type = strrchr(types, '+');
if (type)
return atoi(++type) + sizeof(void*);
else
return 0;
}
/* To fix temporary bug in method_get_next_argument() on m68k */
static char*
my_method_get_next_argument (arglist_t argframe,
const char **type)
{
const char *t = objc_skip_argspec (*type);
if (*t == '\0')
return 0;
*type = t;
t = objc_skip_typespec (t);
if (*t == '+')
return argframe->arg_regs + atoi(++t);
else
/* xxx What's going on here? This -8 needed on my 68k NeXT box. */
#if m68k
return argframe->arg_ptr + (atoi(t) - 8);
#else
return argframe->arg_ptr + atoi(t);
#endif
}
@implementation ArgframeInvocation
- (void) _retainArguments
{
const char *tmptype;
void *datum;
tmptype = return_type;
while ((datum = my_method_get_next_argument (argframe, &tmptype)))
{
tmptype = objc_skip_type_qualifiers (tmptype);
if (*tmptype == _C_ID)
[*(id*)datum retain];
}
}
- (void) _initArgframeFrom: (arglist_t)frame
withType: (const char*)type
retainArgs: (BOOL)f
{
int stack_argsize, reg_argsize;
/* allocate the argframe */
stack_argsize = types_get_size_of_stack_arguments (type);
reg_argsize = types_get_size_of_register_arguments(type);
argframe = (arglist_t) objc_calloc (1 ,sizeof(char*) + reg_argsize);
if (stack_argsize)
argframe->arg_ptr = objc_calloc (1, stack_argsize);
else
argframe->arg_ptr = 0;
/* copy the frame into the argframe */
if (frame)
{
memcpy((char*)argframe + sizeof(char*),
(char*)frame + sizeof(char*),
reg_argsize);
memcpy(argframe->arg_ptr, frame->arg_ptr, stack_argsize);
if (f)
{
[self _retainArguments];
args_retained = YES;
}
}
}
/* This is the designated initializer. */
- initWithArgframe: (arglist_t)frame type: (const char *)type
{
/* xxx we are just using the return part. Does this matter? */
[super initWithReturnType: type];
[self _initArgframeFrom: frame withType: type retainArgs: NO];
return self;
}
- (void) encodeWithCoder: (id <Encoding>)coder
{
const char *tmptype;
void *datum;
[super encodeWithCoder: coder];
tmptype = return_type;
while ((datum = my_method_get_next_argument(argframe, &tmptype)))
{
[coder encodeValueOfObjCType: tmptype
at: datum
withName: @"Invocation Argframe argument"];
}
}
- initWithCoder: (id <Decoding>)coder
{
const char *tmptype;
void *datum;
self = [super initWithCoder: coder];
[self _initArgframeFrom: NULL withType: return_type retainArgs: NO];
tmptype = return_type;
while ((datum = my_method_get_next_argument(argframe, &tmptype)))
{
[coder decodeValueOfObjCType: tmptype
at: datum
withName: NULL];
}
return self;
}
- initWithType: (const char *)e
{
[self initWithArgframe:NULL type:e];
return self;
}
- (void) retainArguments
{
if (!args_retained)
{
if (argframe)
[self _retainArguments];
args_retained = YES;
}
}
- (BOOL) argumentsRetained
{
return args_retained;
}
- (const char *) argumentTypeAtIndex: (unsigned)i
{
const char *tmptype = return_type;
do
{
tmptype = objc_skip_argspec (tmptype);
}
while (i--);
return tmptype;
}
- (unsigned) argumentSizeAtIndex: (unsigned)i
{
return objc_sizeof_type ([self argumentTypeAtIndex:i]);
}
- (void) getArgument: (void*)addr atIndex: (unsigned)i
{
const char *tmptype = return_type;
void *datum;
do
datum = my_method_get_next_argument(argframe, &tmptype);
while (i-- && datum);
/* xxx Give error msg for null datum */
memcpy (addr, datum, objc_sizeof_type(tmptype));
}
- (void) setArgument:(const void *)addr atIndex: (unsigned)i
{
const char *tmptype = return_type;
void *datum;
do
datum = my_method_get_next_argument(argframe, &tmptype);
while (i--);
memcpy (datum, addr, objc_sizeof_type(tmptype));
}
- (void) setArgumentAtIndex: (unsigned)i
toValueAt: (const void*)addr
{
[self setArgument: addr atIndex: i];
}
- (void) _deallocArgframe
{
if (argframe)
{
if (argframe->arg_ptr)
objc_free (argframe->arg_ptr);
objc_free (argframe);
}
}
- (void) dealloc
{
void *datum;
const char *tmptype = return_type;
while ((datum = my_method_get_next_argument(argframe, &tmptype)))
{
tmptype = objc_skip_type_qualifiers (tmptype);
if (args_retained && *tmptype == _C_ID)
[*(id*)datum release];
}
[self _deallocArgframe];
[super dealloc];
}
#if 0
- resetArgframeWithReturnType: (const char*)encoding
{
[self _deallocArgframe];
[self _allocArgframe];
}
#endif
@end
@implementation MethodInvocation
- (void) _initTargetAndSelPointers
{
const char *tmptype = return_type;
target_pointer = (id*) my_method_get_next_argument (argframe, &tmptype);
sel_pointer = (SEL*) my_method_get_next_argument (argframe, &tmptype);
}
/* This is the designated initializer */
- initWithArgframe: (arglist_t)frame type: (const char*)t
{
[super initWithArgframe: frame type: t];
[self _initTargetAndSelPointers];
return self;
}
- initWithArgframe: (arglist_t)frame selector: (SEL)sel
{
const char *sel_type;
if (! (sel_type = sel_get_type (sel)) )
sel_type = sel_get_type ( sel_get_any_typed_uid (sel_get_name (sel)));
/* xxx Try harder to get this type by looking up the method in the target.
Hopefully the target can be found in the FRAME. */
if (!sel_type)
[NSException raise: @"SelectorWithoutType"
format: @"Couldn't find encoding type for selector %s.",
sel_get_name (sel)];
[self initWithArgframe: frame type: sel_type];
if (!frame)
*sel_pointer = sel;
return self;
}
- initWithCoder: (id <Decoding>)coder
{
self = [super initWithCoder: coder];
[self _initTargetAndSelPointers];
return self;
}
- initWithSelector: (SEL)s
{
[self initWithArgframe: NULL selector: s];
*sel_pointer = s;
return self;
}
- initWithTarget: target selector: (SEL)s, ...
{
const char *tmptype;
void *datum;
va_list ap;
[self initWithArgframe: NULL selector: s];
tmptype = return_type;
datum = my_method_get_next_argument(argframe, &tmptype);
if (args_retained)
[target retain];
*((id*)datum) = target;
datum = my_method_get_next_argument(argframe, &tmptype);
*((SEL*)datum) = s;
datum = my_method_get_next_argument(argframe, &tmptype);
va_start (ap, s);
while (datum)
{
#define CASE_TYPE(_C,_T) case _C: *(_T*)datum = va_arg (ap, _T); break
switch (*tmptype)
{
case _C_ID:
*(id*)datum = va_arg (ap, id);
if (args_retained)
[*(id*)datum retain];
break;
CASE_TYPE(_C_CLASS, Class);
CASE_TYPE(_C_SEL, SEL);
CASE_TYPE(_C_LNG, long);
CASE_TYPE(_C_ULNG, unsigned long);
CASE_TYPE(_C_INT, int);
CASE_TYPE(_C_UINT, unsigned int);
case _C_SHT:
*(short*)datum = (short)va_arg(ap, int);
break;
case _C_USHT:
*(unsigned short*)datum = (unsigned short)va_arg(ap, int);
break;
CASE_TYPE(_C_CHR, int);
case _C_UCHR:
*(unsigned char*)datum = (unsigned char)va_arg(ap, int);
break;
case _C_FLT:
*(float*)datum = (float)va_arg(ap, int);
break;
CASE_TYPE(_C_DBL, double);
CASE_TYPE(_C_CHARPTR, char*);
CASE_TYPE(_C_PTR, void*);
default:
{
int copysize;
copysize = objc_sizeof_type(tmptype);
memcpy(datum, (char *)va_arg(ap, int), copysize);
} /* default */
}
datum = my_method_get_next_argument (argframe, &tmptype);
}
return self;
}
- (void) invoke
{
void *ret;
IMP imp;
id target;
id cl;
SEL sel;
/* xxx This could be more efficient by using my_method_get_next_argument
instead of -target and -selector. Or, even better, caching the
memory offsets of the target and selector in the argframe. */
target = *target_pointer;
if (target == nil)
return;
cl = object_get_class (target);
sel = *sel_pointer;
/* xxx Perhaps we could speed things up by making this an ivar,
and caching it. */
imp = get_imp (cl, sel);
NSAssert(imp, NSInternalInconsistencyException);
ret = __builtin_apply((void(*)(void))imp,
argframe,
types_get_size_of_stack_arguments(return_type));
if (return_size)
{
if (*return_type == _C_ID)
{
id old = *(id*)return_value;
mframe_decode_return(return_type, return_value, ret);
if (return_retained && (*(id*)return_value != old))
{
[old release];
[*(id*)return_value retain];
}
}
else
{
mframe_decode_return(return_type, return_value, ret);
}
}
}
- (void) invokeWithTarget: t
{
[self setTarget: t];
[self invoke];
}
- (void) invokeWithObject: anObj
{
[self invokeWithTarget: anObj];
}
- (SEL) selector
{
return *sel_pointer;
}
- (void) setSelector: (SEL)s
{
SEL mysel = [self selector];
if (mysel == (SEL)0)
/* XXX Type check is needed! (masata-y@is.aist-nara.ac.jp) */
*sel_pointer = sel_get_any_typed_uid (sel_get_name (s));
else if (sel_types_match(sel_get_type(mysel), sel_get_type(s)))
*sel_pointer = s;
else
{
/* We need to reallocate the argframe */
[self notImplemented:_cmd];
}
}
- target
{
return *target_pointer;
}
- (void) setTarget: t
{
if (*target_pointer != t)
{
if (args_retained)
{
[*target_pointer release];
[t retain];
}
*target_pointer = t;
}
}
@end
@implementation ObjectMethodInvocation
- (void) _initArgObjectPointer
{
const char *tmptype;
void *datum;
tmptype = return_type;
my_method_get_next_argument (argframe, &tmptype);
my_method_get_next_argument (argframe, &tmptype);
do
{
datum = my_method_get_next_argument (argframe, &tmptype);
tmptype = objc_skip_type_qualifiers (tmptype);
}
while (datum && tmptype && *tmptype != _C_ID);
if (*tmptype != _C_ID)
[self error: "This method does not have an object argument."];
arg_object_pointer = (id*) datum;
}
- initWithArgframe: (arglist_t)frame selector: (SEL)sel
{
[super initWithArgframe: frame selector: sel];
[self _initArgObjectPointer];
return self;
}
- initWithCoder: (id <Decoding>)coder
{
self = [super initWithCoder: coder];
[self _initArgObjectPointer];
return self;
}
- (void) invokeWithObject: anObject
{
if (*arg_object_pointer != anObject)
{
if (args_retained)
{
[*arg_object_pointer release];
[anObject retain];
}
*arg_object_pointer = anObject;
}
[self invoke];
}
@end
@implementation VoidFunctionInvocation
#if 0
- initWithFunction: (void(*)())f
argframe: (arglist_t)frame type: (const char *)e
{
[super initWithArgframe: frame type: e];
function = f;
return self;
}
#endif
- initWithVoidFunction: (void(*)())f
{
[super initWithReturnType: "v"];
function = f;
return self;
}
/* Encode ourself as a proxies across Connection's; we can't encode
a function across the wire. */
- classForPortCoder
{
return [NSDistantObject class];
}
- (void) encodeWithCoder: (id <Encoding>)coder
{
[self shouldNotImplement: _cmd];
}
- (void) invoke
{
(*function) ();
}
- (void) invokeWithObject
{
[self shouldNotImplement: _cmd];
}
@end
@implementation ObjectFunctionInvocation
- initWithObjectFunction: (id(*)(id))f
{
[super initWithReturnType: "@"];
function = f;
return self;
}
/* Encode ourself as a proxies across Connection's; we can't encode
a function across the wire. */
- classForPortCoder
{
return [NSDistantObject class];
}
- (void) encodeWithCoder: (id <Encoding>)coder
{
[self shouldNotImplement: _cmd];
}
- (void) invoke
{
[self invokeWithObject: nil];
}
- (void) invokeWithObject: anObject
{
id r;
r = (*function) (anObject);
if (*(id*)return_value != r)
{
if (return_retained)
{
[*(id*)return_value release];
[r retain];
}
*(id*)return_value = r;
}
}
@end
/* Many other kinds of Invocations are possible:
SchemeInvocation, TclInvocation */
#if 0
@implementation CurriedInvocation
@end
What is this nonsense?
@interface StreamInvocation
@interface LogInvocation
@interface PrintingInvocation
{
Stream *stream;
char *format_string;
}
@end
#endif

View file

@ -1,280 +0,0 @@
/* Implementation for Objective-C KeyedCollection collection object
Copyright (C) 1993,1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/KeyedCollection.h>
#include <base/CollectionPrivate.h>
#include <stdio.h>
#include <base/Array.h>
#include <base/NSString.h>
#include <base/behavior.h>
@implementation KeyEnumerator
- nextObject
{
id k;
[collection nextObjectAndKey: &k withEnumState: &enum_state];
return k;
}
@end
@implementation ConstantKeyedCollection
// INITIALIZING;
/* This is the designated initializer */
- initWithObjects: (id*)objects forKeys: (id*)keys count: (unsigned)c
{
[self subclassResponsibility: _cmd];
return nil;
}
// GETTING ELEMENTS AND KEYS;
- objectAtKey: aKey
{
[self subclassResponsibility: _cmd];
return nil;
}
- keyOfObject: aContentObject
{
[self subclassResponsibility: _cmd];
return nil;
}
// TESTING;
- (BOOL) containsKey: aKey
{
if ([self objectAtKey: aKey] == NO_OBJECT)
return NO;
return YES;
}
// ENUMERATIONS;
- (id <Enumerating>) keyEnumerator
{
return [[[KeyEnumerator alloc] initWithCollection: self]
autorelease];
}
- (void) withKeysInvoke: (id <Invoking>)anInvocation
{
id o, k;
FOR_KEYED_COLLECTION(self, o, k)
{
[anInvocation invokeWithObject: k];
}
END_FOR_KEYED_COLLECTION(self);
}
- (void) withKeysInvoke: (id <Invoking>)anInvocation
whileTrue: (BOOL *)flag
{
id o, k;
FOR_KEYED_COLLECTION_WHILE_TRUE(self, o, k, *flag)
{
[anInvocation invokeWithObject: k];
}
END_FOR_KEYED_COLLECTION(self);
}
/* Override this Collection method */
- nextObjectWithEnumState: (void**)enumState
{
id k;
return [self nextObjectAndKey: &k withEnumState: enumState];
}
// LOW-LEVEL ENUMERATING;
- nextObjectAndKey: (id*)keyPtr withEnumState: (void**)enumState
{
[self subclassResponsibility: _cmd];
return nil;
}
// COPYING;
- shallowCopyValuesAs: (Class)aConstantCollectingClass
{
int count = [self count];
id contents[count];
id k;
int i = 0;
id o;
FOR_KEYED_COLLECTION(self, o, k)
{
contents[i++] = o;
}
END_FOR_KEYED_COLLECTION(self);
return [[aConstantCollectingClass alloc]
initWithObjects: contents count: count];
}
- shallowCopyKeysAs: (Class)aCollectingClass;
{
int count = [self count];
id contents[count];
id k;
int i = 0;
id o;
FOR_KEYED_COLLECTION(self, o, k)
{
contents[i++] = k;
}
END_FOR_KEYED_COLLECTION(self);
return [[aCollectingClass alloc]
initWithObjects: contents count: count];
}
- copyValuesAs: (Class)aCollectingClass
{
[self notImplemented: _cmd];
return nil;
}
- copyKeysAs: (Class)aCollectingClass;
{
[self notImplemented: _cmd];
return nil;
}
// ARCHIVING
- (void) _encodeContentsWithCoder: (id <Encoding>)aCoder
{
unsigned int count = [self count];
id o, k;
[aCoder encodeValueOfCType: @encode(unsigned)
at: &count
withName: @"Collection content count"];
FOR_KEYED_COLLECTION(self, o, k)
{
[aCoder encodeObject: k
withName: @"KeyedCollection key"];
[aCoder encodeObject: o
withName:@"KeyedCollection content"];
}
END_FOR_KEYED_COLLECTION(self);
}
- (void) _decodeContentsWithCoder: (id <Decoding>)aCoder
{
unsigned int count, i;
id *objs, *keys;
[aCoder decodeValueOfCType:@encode(unsigned)
at:&count
withName:NULL];
OBJC_MALLOC(objs, id, count);
OBJC_MALLOC(keys, id, count);
for (i = 0; i < count; i++)
{
[aCoder decodeObjectAt: &(keys[i])
withName: NULL];
[aCoder decodeObjectAt: &(objs[i])
withName: NULL];
}
[self initWithObjects: objs forKeys: keys count: count];
for (i = 0; i < count; i++)
{
[keys[i] release];
[objs[i] release];
}
OBJC_FREE(objs);
OBJC_FREE(keys);
}
- (NSString*) description
{
id s = [NSMutableString new];
id o, k;
FOR_KEYED_COLLECTION(self, o, k)
{
[s appendFormat: @"(%@,%@) ", [k description], [o description]];
}
END_FOR_KEYED_COLLECTION(self);
[s appendFormat: @" :%s\n", object_get_class_name (self)];
return [s autorelease];
}
@end
@implementation KeyedCollection
+ (void) initialize
{
if (self == [KeyedCollection class])
class_add_behavior(self, [Collection class]);
}
// ADDING;
- (void) putObject: newContentObject atKey: aKey
{
[self subclassResponsibility: _cmd];
}
// REPLACING AND SWAPPING;
- (void) replaceObjectAtKey: aKey with: newContentObject
{
[self subclassResponsibility: _cmd];
}
- (void) swapObjectsAtKeys: key1 : key2
{
[self subclassResponsibility: _cmd];
}
// REMOVING;
- (void) removeObjectAtKey: aKey
{
[self subclassResponsibility: _cmd];
}
@end

View file

@ -1,408 +0,0 @@
/* Implementation for Objective-C LinkedList collection object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/LinkedList.h>
#include <base/IndexedCollectionPrivate.h>
#include <base/Coder.h>
@implementation LinkedList
/* This is the designated initializer of this class */
- init
{
_count = 0;
_first_link = nil;
_last_link = nil;
return self;
}
- initWithObjects: (id*)objs count: (unsigned)c
{
[self init];
while (c--)
[self prependObject: objs[c]];
return self;
}
/* Archiving must mimic the above designated initializer */
- (void) encodeWithCoder: coder
{
id l;
[super encodeWithCoder: coder];
[coder encodeValueOfCType: @encode (typeof (_count))
at: &_count
withName: @"LinkedList count"];
FOR_COLLECTION (self, l)
{
[coder encodeObject: l
withName: @"LinkedList element"];
}
END_FOR_COLLECTION (self);
[coder encodeObjectReference: _first_link
withName: @"LinkedList first link"];
[coder encodeObjectReference: _last_link
withName: @"LinkedList last link"];
}
- initWithCoder: coder
{
int i;
// id link;
self = [super initWithCoder: coder];
[coder decodeValueOfCType: @encode (typeof (_count))
at: &_count
withName: NULL];
/* We don't really care about storing the elements decoded, because
we access them through their own link pointers. */
for (i = 0; i < _count; i++)
[coder decodeObjectAt: NULL
withName: NULL];
[coder decodeObjectAt: &_first_link
withName: NULL];
[coder decodeObjectAt: &_last_link
withName: NULL];
#if 0
/* xxx Not necessary, since the links encode this?
But should we rely on the links encoding this?
BUT! Look out: the next link pointers may not be set until
the last finishDecoding... method is run... */
FOR_COLLECTION (self, link)
{
[link setLinkedList: self];
}
END_FOR_COLLECTION (self);
#endif
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
LinkedList *copy = [super emptyCopy];
copy->_first_link = nil;
copy->_last_link = nil;
copy->_count = 0;
return copy;
}
/* This must work without sending any messages to content objects */
- (void) _empty
{
_count = 0;
_first_link = nil;
_last_link = nil;
}
/* These next four methods are the only ones that change the values of
the instance variables _count, _first_link, except for
"-init". */
- (void) removeObject: oldObject
{
NSAssert([oldObject linkedList] == self, NSInternalInconsistencyException);
if (_first_link == oldObject)
{
if (_count > 1)
_first_link = [oldObject nextLink];
else
_first_link = nil;
}
else
[[oldObject prevLink] setNextLink:[oldObject nextLink]];
if (_last_link == oldObject)
{
if (_count > 1)
_last_link = [oldObject prevLink];
else
_first_link = nil;
}
else
[[oldObject nextLink] setPrevLink:[oldObject prevLink]];
_count--;
[oldObject setNextLink: NO_OBJECT];
[oldObject setPrevLink: NO_OBJECT];
[oldObject setLinkedList: NO_OBJECT];
[oldObject release];
}
- (void) insertObject: newObject after: oldObject
{
/* Make sure we actually own the oldObject. */
NSAssert([oldObject linkedList] == self, NSInternalInconsistencyException);
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setLinkedList: self];
/* Insert it. */
if (_count == 0)
{
_first_link = newObject;
_last_link = newObject;
_count = 1;
[newObject setNextLink: NO_OBJECT];
[newObject setPrevLink: NO_OBJECT];
}
else
{
if (oldObject == _last_link)
_last_link = newObject;
[newObject setNextLink: [oldObject nextLink]];
[newObject setPrevLink: oldObject];
[[oldObject nextLink] setPrevLink: newObject];
[oldObject setNextLink: newObject];
}
_count++;
}
- (void) insertObject: newObject before: oldObject
{
/* Make sure we actually own the oldObject. */
NSAssert([oldObject linkedList] == self, NSInternalInconsistencyException);
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setLinkedList: self];
/* Insert it. */
if (_count == 0)
{
_first_link = newObject;
_last_link = newObject;
_count = 1;
[newObject setNextLink: NO_OBJECT];
[newObject setPrevLink: NO_OBJECT];
}
else
{
if (oldObject == _first_link)
_first_link = newObject;
[newObject setPrevLink: [oldObject prevLink]];
[newObject setNextLink: oldObject];
[[oldObject prevLink] setNextLink: newObject];
[oldObject setPrevLink: newObject];
}
_count++;
}
- (void) replaceObject: oldObject with: newObject
{
/* Make sure we actually own the oldObject. */
NSAssert([oldObject linkedList] == self, NSInternalInconsistencyException);
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setLinkedList: self];
/* Do the replacement. */
if (oldObject == _first_link)
_first_link = newObject;
[newObject setNextLink:[oldObject nextLink]];
[newObject setPrevLink:[oldObject prevLink]];
[[oldObject prevLink] setNextLink:newObject];
[[oldObject nextLink] setPrevLink:newObject];
/* Release ownership of the oldObject. */
[oldObject setNextLink: NO_OBJECT];
[oldObject setPrevLink: NO_OBJECT];
[oldObject setLinkedList: NO_OBJECT];
[oldObject release];
}
/* End of methods that change the instance variables. */
- (void) appendObject: newObject
{
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Insert it. */
if (_count == 0)
{
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setLinkedList: self];
/* Put it in as the only node. */
_first_link = newObject;
_last_link = newObject;
_count = 1;
[newObject setNextLink: NO_OBJECT];
[newObject setPrevLink: NO_OBJECT];
}
else
[self insertObject: newObject after: _last_link];
}
- (void) prependObject: newObject
{
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Insert it. */
if (_count == 0)
{
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setLinkedList: self];
/* Put it in as the only node. */
_first_link = newObject;
_last_link = newObject;
_count = 1;
[newObject setNextLink: NO_OBJECT];
[newObject setPrevLink: NO_OBJECT];
}
else
[self insertObject: newObject before: _first_link];
}
- (void) insertObject: newObject atIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, (_count+1));
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Insert it. */
if (_count == 0)
{
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setLinkedList: self];
/* Put it in as the only node. */
_first_link = newObject;
_last_link = newObject;
_count = 1;
[newObject setNextLink: NO_OBJECT];
[newObject setPrevLink: NO_OBJECT];
}
else if (index == _count)
[self insertObject: newObject after: _last_link];
else
[self insertObject:newObject before: [self objectAtIndex: index]];
}
- (void) removeObjectAtIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count);
[self removeObject: [self objectAtIndex: index]];
}
- objectAtIndex: (unsigned)index
{
id <LinkedListComprising> link;
CHECK_INDEX_RANGE_ERROR(index, _count);
if (index < _count / 2)
for (link = _first_link;
index;
link = [link nextLink], index--)
;
else
for (link = _last_link, index = _count - index - 1;
index;
link = [link prevLink], index--)
;
return link;
}
- firstObject
{
return _first_link;
}
- lastObject
{
return _last_link;
}
- successorOfObject: oldObject
{
/* Make sure we actually own the oldObject. */
NSAssert([oldObject linkedList] == self, NSInternalInconsistencyException);
return [oldObject nextLink];
}
- predecessorOfObject: oldObject
{
/* Make sure we actually own the oldObject. */
NSAssert([oldObject linkedList] == self, NSInternalInconsistencyException);
return [oldObject prevLink];
}
- (void*) newEnumState
{
return _first_link;
}
- nextObjectWithEnumState: (void**)enumState
{
id ret;
if (!*enumState)
return nil;
ret = *enumState;
*enumState = [(id)(*enumState) nextLink];
/* *enumState points to the next object to be returned. */
return ret;
}
- prevObjectWithEnumState: (void**)enumState
{
/* *enumState points to the object returned last time. */
if (!*enumState)
return nil;
if (*enumState == _first_link)
/* enumState was just initialized from -newEnumState. */
return *enumState = _last_link;
return (id) *enumState = [(id)(*enumState) prevLink];
}
- (unsigned) count
{
return _count;
}
@end

View file

@ -1,84 +0,0 @@
/* Implementation for Objective-C LinkedListNode object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/LinkedListNode.h>
#include <base/Coder.h>
@implementation LinkedListNode
- init
{
[super init];
_next = _prev = _linked_list = nil;
return self;
}
- (void) encodeWithCoder: aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObjectReference:_next withName:@"Next LinkedList Node"];
[aCoder encodeObjectReference:_prev withName:@"Prev LinkedList Node"];
[aCoder encodeObjectReference:_linked_list withName:@"LinkedList"];
}
- initWithCoder: aCoder
{
[super initWithCoder:aCoder];
[aCoder decodeObjectAt:&_next withName:NULL];
[aCoder decodeObjectAt:&_prev withName:NULL];
[aCoder decodeObjectAt:&_linked_list withName:NULL];
return self;
}
- (id <LinkedListComprising>) nextLink
{
return _next;
}
- (id <LinkedListComprising>) prevLink
{
return _prev;
}
- (void) setNextLink: (id <LinkedListComprising>)aLink
{
_next = aLink;
}
- (void) setPrevLink: (id <LinkedListComprising>)aLink
{
_prev = aLink;
}
- linkedList
{
return _linked_list;
}
- (void) setLinkedList: anObject;
{
_linked_list = anObject;
}
@end

View file

@ -1,99 +0,0 @@
/* Implementation for Objective-C Magnitude object
Copyright (C) 1993,1994 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/preface.h>
#include <base/Magnitude.h>
/* These methods accesses no instance variables. It is exactly the kind
of thing that should be a "behavior" associated with a protocol.
i.e. #3 on Steve Naroff's wish list. */
@implementation Magnitude
- (int) compare: anObject
{
return [super compare:anObject];
}
- (BOOL) greaterThan: anObject
{
if ([self compare:anObject] > 0)
return YES;
else
return NO;
}
- (BOOL) greaterThanOrEqual: anObject
{
if ([self compare:anObject] >= 0)
return YES;
else
return NO;
}
- (BOOL) lessThan: anObject
{
if ([self compare:anObject] < 0)
return YES;
else
return NO;
}
- (BOOL) lessThanOrEqual: anObject
{
if ([self compare:anObject] <= 0)
return YES;
else
return NO;
}
- (BOOL) between: firstObject and: secondObject
{
if ([self compare:firstObject] >= 0
&& [self compare:secondObject] <= 0)
return YES;
else
return NO;
}
- maximum: anObject
{
if ([self compare:anObject] >= 0)
return self;
else
return anObject;
}
- minimum: anObject
{
if ([self compare:anObject] <= 0)
return self;
else
return anObject;
}
@end

View file

@ -1,138 +0,0 @@
/* Implementation for Objective-C MappedCollector collection object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/MappedCollector.h>
#include <base/Dictionary.h>
#include <base/CollectionPrivate.h>
@implementation MappedCollector
/* This is the designated initializer for this class */
- initWithCollection: (id <KeyedCollecting>)aDomain
map: (id <KeyedCollecting>)aMap
{
_map = aMap;
_domain = aDomain;
return self;
}
/* Archiving must mimic the above designated initializer */
- (void) encodeWithCoder: anEncoder
{
[self notImplemented:_cmd];
}
+ newWithCoder: aDecoder
{
[self notImplemented:_cmd];
return self;
}
/* Override our superclass' designated initializer */
- initWithObjects: (id*)objects forKeys: (id*)keys count: (unsigned)c
{
[self notImplemented: _cmd];
return nil;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
MappedCollector *copy = [super emptyCopy];
copy->_map = [_map emptyCopy];
copy->_domain = [_domain emptyCopy];
return copy;
}
/* This must work without sending any messages to content objects */
- (void) empty
{
[_domain empty];
}
- objectAtKey: aKey
{
return [_domain objectAtKey: [_map objectAtKey: aKey]];
}
- keyOfObject: aContentObject
{
[self notImplemented: _cmd];
return self;
}
- (void) replaceObjectAtKey: aKey with: newObject
{
return [_domain replaceObjectAtKey: [_map objectAtKey: aKey]
with: newObject];
}
- (void) putObject: newObject atKey: aKey
{
return [_domain putObject: newObject
atKey: [_map objectAtKey:aKey]];
}
- (void) removeObjectAtKey: aKey
{
return [_domain removeObjectAtKey: [_map objectAtKey: aKey]];
}
- (BOOL) containsKey: aKey
{
return [_domain containsKey: [_map objectAtKey:aKey]];
}
- (void*) newEnumState
{
return [_domain newEnumState];
}
- (void) freeEnumState: (void**)enumState
{
return [_domain freeEnumState: enumState];
}
- nextObjectAndKey: (id*)keyPtr withEnumState: (void**)enumState
{
id mapContent;
id domainKey;
/* xxx This needs debugging; see checks/test02.m */
while ((mapContent = [_map nextObjectAndKey:keyPtr withEnumState:enumState])
&&
(![_domain containsKey: (domainKey = [_map objectAtKey:*keyPtr])]))
;
if (mapContent == NO_OBJECT)
return NO_OBJECT;
return [_domain objectAtKey: domainKey];
}
- species
{
return [Dictionary class];
}
@end

View file

@ -1,750 +0,0 @@
/* Implementation of object for broadcasting Notification objects
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: March 1996
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/* The implementation for NotificationDispatcher. */
/* NeXT says you can only have one NotificationCenter per task;
I don't think GNU needs this restriction with its corresponding
NotificationDistributor class. */
#include <config.h>
#include <base/NotificationDispatcher.h>
#include <base/LinkedListNode.h>
#include <base/Array.h>
#include <base/Invocation.h>
#include <Foundation/NSNotification.h>
#include <Foundation/NSException.h>
/* NotificationRequest class - One of these objects is created for
each -addObserver... request. It holds the requested invocation,
name and object. Each object is placed
(1) in one LinkedList, as keyed by the NAME/OBJECT parameters (accessible
through one of the ivars: anonymous_nr_list, object_2_nr_list,
name_2_nr_list), and
(2) in the Array, as keyed by the OBSERVER (as accessible through
the ivar observer_2_nr_array.
To post a notification in satisfaction of this request,
send -postNotification:. */
@interface NotificationRequest : LinkedListNode
{
int _retain_count;
id _name;
id _object;
}
- initWithName: n object: o;
- (NSString*) notificationName;
- notificationObject;
- (void) postNotification: n;
@end
@implementation NotificationRequest
- initWithName: n object: o
{
[super init];
_retain_count = 0;
_name = [n retain];
_object = o;
/* Note that OBJECT is not retained. See the comment for
-addObserver... in NotificationDispatcher.h. */
return self;
}
/* Implement these retain/release methods here for efficiency, since
NotificationRequest's get retained and released by all their
holders. Doing this is a judgement call; I'm choosing speed over
space. */
- retain
{
_retain_count++;
return self;
}
- (oneway void) release
{
if (_retain_count-- == 0)
[self dealloc];
}
- (unsigned) retainCount
{
return _retain_count + 1;
}
- (void) dealloc
{
[_name release];
[super dealloc];
}
- (BOOL)isEqual:other
{
if ([self class] != [other class])
return NO;
if (_object != [other notificationObject])
return NO;
if (_name != [other notificationName] &&
![_name isEqual: [other notificationName]])
return NO;
return YES;
}
- (NSString*) notificationName
{
return _name;
}
- notificationObject
{
return _object;
}
- (void) postNotification: n
{
[self subclassResponsibility: _cmd];
}
@end
@interface NotificationInvocation : NotificationRequest
{
id _invocation;
}
- initWithInvocation: i name: n object: o;
@end
@implementation NotificationInvocation
- initWithInvocation: i name: n object: o
{
[super initWithName: n object: o];
_invocation = [i retain];
return self;
}
- (void) dealloc
{
[_invocation release];
[super dealloc];
}
- (void) postNotification: n
{
[_invocation invokeWithObject: n];
}
@end
@interface NotificationPerformer : NotificationRequest
{
id _target;
SEL _selector;
}
- initWithTarget: t selector: (SEL)s name: n object: o;
@end
@implementation NotificationPerformer
- initWithTarget: t selector: (SEL)s name: n object: o
{
[super initWithName: n object: o];
/* Note that TARGET is not retained. See the comment for
-addObserver... in NotificationDispatcher.h. */
_target = t;
_selector = s;
return self;
}
- (void) postNotification: n
{
[_target performSelector: _selector withObject: n];
}
@end
@implementation NotificationDispatcher
/* The default instance, most often the only one created.
It is accessed by the class methods at the end of this file.
There is no need to mutex locking of this variable. */
static NotificationDispatcher *default_notification_dispatcher = nil;
+ (void) initialize
{
if (self == [NotificationDispatcher class])
default_notification_dispatcher = [self new];
}
/* Initializing. */
- init
{
[super init];
_anonymous_nr_list = [LinkedList new];
/* Use NSNonOwnedPointerOrNullMapKeyCallBacks so we won't retain
the object. We will, however, retain the values, which are
LinkedList's. */
_object_2_nr_list =
NSCreateMapTable (NSNonOwnedPointerOrNullMapKeyCallBacks,
NSObjectMapValueCallBacks, 0);
/* Use NSObjectMapKeyCallBacks so we retain the NAME. We also retain
the values, which are LinkedList's. */
_name_2_nr_list =
NSCreateMapTable (NSObjectMapKeyCallBacks,
NSObjectMapValueCallBacks, 0);
/* Use NSNonOwnedPointerOrNullMapKeyCallBacks so we won't retain
the observer. We will, however, retain the values, which are Array's. */
_observer_2_nr_array =
NSCreateMapTable (NSNonOwnedPointerOrNullMapKeyCallBacks,
NSObjectMapValueCallBacks, 0);
_lock = [NSRecursiveLock new];
return self;
}
- (void) dealloc
{
[_anonymous_nr_list release];
NSFreeMapTable( _object_2_nr_list);
NSFreeMapTable (_name_2_nr_list);
NSFreeMapTable (_observer_2_nr_array);
[_lock release];
[super dealloc];
}
/* Adding new observers. */
/* This is the (private) designated method for adding observers. If we
came from -addInvocation... then OBSERVER is actually an Invocation. */
- (void) _addObserver: observer
notificationRequest: nr
name: (NSString*)name
object: object
{
/* If observer is nil, there is nothing to do; return. */
if (!observer)
return;
[_lock lock];
/* Record the notification request in an array keyed by OBSERVER. */
{
/* Find the array of all the requests by OBSERVER. */
Array *nr_array = NSMapGet (_observer_2_nr_array, observer);
if (!nr_array)
{
nr_array = [Array new];
/* nr_array is retained; observer is not. */
NSMapInsert (_observer_2_nr_array, observer, nr_array);
/* Now that nr_array is retained by the map table, release it;
this way the array will be completely released when the
map table is done with it. */
[nr_array release];
}
/* If the observer is already watching this request, do nothing. */
if ([nr_array containsObject:nr])
{
[_lock unlock];
return;
}
[nr_array appendObject: nr];
}
/* Record the NotificationRequest in one of three MapTable->LinkedLists. */
/* Record the request in one, and only one, LinkedList. The LinkedList
is stored in a hash table accessed by a key. Which key is used
depends on what combination of NAME and OBJECT are non-nil. */
if (!name)
{
if (!object)
{
/* This NotificationRequest will get posted notifications
for all NAME and OBJECT combinations. */
[_anonymous_nr_list appendObject: nr];
}
else
{
LinkedList *nr_list = NSMapGet (_object_2_nr_list, object);
if (!nr_list)
{
nr_list = [LinkedList new];
/* nr_list is retained; object is not retained. */
NSMapInsert (_object_2_nr_list, object, nr_list);
/* Now that nr_list is retained by the map table, release it;
this way the list will be completely released when the
map table is done with it. */
[nr_list release];
}
[nr_list appendObject: nr];
}
}
else
{
LinkedList *nr_list = NSMapGet (_name_2_nr_list, name);
if (!nr_list)
{
nr_list = [LinkedList new];
/* nr_list is retained; object is not retained. */
NSMapInsert (_name_2_nr_list, name, nr_list);
/* Now that nr_list is retained by the map table, release it;
this way the list will be completely released when the
map table is done with it. */
[nr_list release];
}
[nr_list appendObject: nr];
}
[_lock unlock];
}
- (void) addInvocation: (id <Invoking>)invocation
name: (NSString*)name
object: object
{
id nr;
/* Create the NotificationRequest object that will hold this
observation request. This will retain INVOCATION and NAME. */
nr = [[NotificationInvocation alloc]
initWithInvocation: invocation
name: name
object: object];
/* Record it in all the right places. */
[self _addObserver: invocation
notificationRequest: nr
name: name
object: object];
/* Since nr was retained when it was added to the Array and
LinkedList above, we can release it now. */
[nr release];
}
/* For those that want to specify a selector instead of an invocation
as a way to contact the observer. */
- (void) addObserver: observer
selector: (SEL)sel
name: (NSString*)name
object: object
{
id nr;
/* Create the NotificationRequest object that will hold this
observation request. This will retain INVOCATION and NAME. */
nr = [[NotificationPerformer alloc]
initWithTarget: observer
selector: sel
name: name
object: object];
/* Record it in all the right places. */
[self _addObserver: observer
notificationRequest: nr
name: name
object: object];
/* Since nr was retained when it was added to the Array and
LinkedList above, we can release it now. */
[nr release];
}
/* Removing objects. */
/* A private method.
Remove the NR object from its one LinkedList; if this is the last
element of that LinkedList, and the LinkedList is map-accessible,
also release the LinkedList. */
- (void) _removeFromLinkedListNotificationRequest: nr
{
id nr_list = [nr linkedList];
/* See if, instead of removing the NR from its LinkedList, we can
actually release the entire list. */
if ([nr_list count] == 1
&& nr_list != _anonymous_nr_list)
{
id nr_name;
id nr_object;
LinkedList *mapped_nr_list;
NSAssert([nr_list firstObject] == nr, NSInternalInconsistencyException);
if ((nr_name = [nr notificationName]))
{
mapped_nr_list = NSMapGet (_name_2_nr_list, nr_name);
NSAssert(mapped_nr_list == nr_list, NSInternalInconsistencyException);
NSMapRemove (_name_2_nr_list, nr_name);
}
else
{
nr_object = [nr notificationObject];
NSAssert(nr_object, NSInternalInconsistencyException);
mapped_nr_list = NSMapGet (_object_2_nr_list, nr_object);
NSAssert(mapped_nr_list == nr_list, NSInternalInconsistencyException);
NSMapRemove (_object_2_nr_list, nr_object);
}
}
else
[nr_list removeObject: nr];
}
/* Removing notification requests. */
/* Remove all notification requests that would be sent to INVOCATION. */
- (void) removeInvocation: invocation
{
[self removeObserver: invocation];
}
/* Remove the notification requests matching NAME and OBJECT that
would be sent to INVOCATION. As with adding an observation
request, nil NAME or OBJECT act as wildcards. */
- (void) removeInvocation: invocation
name: (NSString*)name
object: object
{
[self removeObserver: invocation
name: name
object: object];
}
/* Remove all records pertaining to OBSERVER. For instance, this
should be called before the OBSERVER is -dealloc'ed. */
- (void) removeObserver: observer
{
Array *observer_nr_array;
NotificationRequest *nr;
/* If OBSERVER is nil, do nothing; just return. NOTE: This *does not*
remove all requests with a nil OBSERVER; it would be too easy to
unintentionally remove other's requests that way. If you need to
remove a request with a nil OBSERVER, use -removeObserver:name:object: */
if (!observer)
return;
[_lock lock];
/* Get the array of NotificationRequest's associated with OBSERVER. */
observer_nr_array = NSMapGet (_observer_2_nr_array, observer);
if (!observer_nr_array)
/* OBSERVER was never registered for any notification requests with us.
Nothing to do. */
return;
/* Remove each of these from it's LinkedList. */
FOR_ARRAY (observer_nr_array, nr)
{
[self _removeFromLinkedListNotificationRequest: nr];
}
END_FOR_ARRAY (observer_nr_array);
/* Remove from the MapTable the list of NotificationRequest's
associated with OBSERVER. This also releases the observer_nr_array,
and its contents. */
NSMapRemove (_observer_2_nr_array, observer);
[_lock unlock];
}
/* Remove the notification requests for the given parameters. As with
adding an observation request, nil NAME or OBJECT act as wildcards. */
- (void) removeObserver: observer
name: (NSString*)name
object: object
{
Array *observer_nr_array;
/* If both NAME and OBJECT are nil, this call is the same as
-removeObserver:, so just call it. */
if (!name && !object)
[self removeObserver: observer];
/* We are now guaranteed that at least one of NAME and OBJECT is non-nil. */
[_lock lock];
/* Get the list of NotificationRequest's associated with OBSERVER. */
observer_nr_array = NSMapGet (_observer_2_nr_array, observer);
if (!observer_nr_array)
/* OBSERVER was never registered for any notification requests with us.
Nothing to do. */
return;
/* Find those NotificationRequest's from the array that
match NAME and OBJECT, and remove them from the array and
their linked list. */
/* xxx If we thought the LinkedList from the map table keyed on NAME
would be shorter, we could use that instead. */
{
NotificationRequest *nr;
int count = [observer_nr_array count];
int i;
for (i = count-1; i >= 0; i--)
{
nr = [observer_nr_array objectAtIndex: i];
if ((!name || [name isEqual: [nr notificationName]])
&& (!object || [object isEqual: [nr notificationObject]]))
{
/* We can remove from the array, even though we are "enumerating"
over it, because we are enumerating from back-to-front,
and the indices of yet-to-come objects don't change when
high-indexed objects are removed. */
[observer_nr_array removeObjectAtIndex: i];
[self _removeFromLinkedListNotificationRequest: nr];
}
}
/* xxx If there are some LinkedList's that are empty, I should
remove them from the map table's. */
}
[_lock unlock];
}
/* Post NOTIFICATION to all the observers that match its NAME and OBJECT. */
- (void) postNotification: notification
{
id notification_name = [(NSNotification *)notification name];
id notification_object = [notification object];
id nr;
LinkedList *nr_list;
NSMutableArray* array;
/* Make sure the notification has a name. */
if (!notification_name)
[NSException raise: NSInvalidArgumentException
format: @"Tried to post a notification with no name."];
[_lock lock];
array = [[NSMutableArray arrayWithCapacity:10] retain];
/* Post the notification to all the observers that specified neither
NAME or OBJECT. */
if ([_anonymous_nr_list count])
{
FOR_COLLECTION (_anonymous_nr_list, nr)
{
[array addObject:nr];
}
END_FOR_COLLECTION (_anonymous_nr_list);
while ([array count] > 0)
{
nr = [array objectAtIndex:0];
if ([nr linkedList] != NO_OBJECT) /* Has request been removed? */
[nr postNotification:notification];
[array removeObjectAtIndex:0];
}
}
/* Post the notification to all the observers that specified OBJECT,
but didn't specify NAME. */
if (notification_object)
{
nr_list = NSMapGet (_object_2_nr_list, notification_object);
if (nr_list)
{
FOR_COLLECTION (nr_list, nr)
{
[array addObject:nr];
}
END_FOR_COLLECTION (nr_list);
while ([array count] > 0)
{
nr = [array objectAtIndex:0];
if ([nr linkedList] != NO_OBJECT) /* Has request been removed? */
[nr postNotification:notification];
[array removeObjectAtIndex:0];
}
}
}
/* Post the notification to all the observers of NAME; (and if the
observer's OBJECT is non-nil, don't send unless the observer's OBJECT
matches the notification's OBJECT). */
nr_list = NSMapGet (_name_2_nr_list, notification_name);
if (nr_list)
{
FOR_COLLECTION (nr_list, nr)
{
id nr_object = [nr notificationObject];
if (!nr_object || nr_object == notification_object)
[array addObject:nr];
}
END_FOR_COLLECTION (nr_list);
while ([array count] > 0)
{
nr = [array objectAtIndex:0];
if ([nr linkedList] != NO_OBJECT) /* Has request been removed? */
[nr postNotification:notification];
[array removeObjectAtIndex:0];
}
}
[array release];
[_lock unlock];
}
- (void) postNotificationName: (NSString*)name
object: object
{
[self postNotification: [NSNotification notificationWithName: name
object: object]];
}
- (void) postNotificationName: (NSString*)name
object: object
userInfo: info
{
[self postNotification: [NSNotification notificationWithName: name
object: object
userInfo: info]];
}
/* Class methods. */
+ defaultInstance
{
return default_notification_dispatcher;
}
+ (void) addInvocation: (id <Invoking>)invocation
name: (NSString*)name
object: object
{
[default_notification_dispatcher addInvocation: invocation
name: name
object: object];
}
+ (void) addObserver: observer
selector: (SEL)sel
name: (NSString*)name
object: object
{
[default_notification_dispatcher addObserver: observer
selector: sel
name: name
object: object];
}
+ (void) removeInvocation: invocation
{
[default_notification_dispatcher removeInvocation: invocation];
}
+ (void) removeInvocation: invocation
name: (NSString*)name
object: object
{
[default_notification_dispatcher removeInvocation: invocation
name: name
object: object];
}
+ (void) removeObserver: observer
{
[default_notification_dispatcher removeObserver: observer];
}
+ (void) removeObserver: observer
name: (NSString*)name
object: object
{
[default_notification_dispatcher removeObserver: observer
name: name
object: object];
}
+ (void) postNotification: notification
{
[default_notification_dispatcher postNotification: notification];
}
+ (void) postNotificationName: (NSString*)name
object: object
{
[default_notification_dispatcher postNotificationName: name
object: object];
}
+ (void) postNotificationName: (NSString*)name
object: object
userInfo: info
{
[default_notification_dispatcher postNotificationName: name
object: object
userInfo: info];
}
@end
@implementation NotificationDispatcher (OpenStepCompat)
/* For OpenStep compatibility. */
+ defaultCenter
{
return default_notification_dispatcher;
}
@end

View file

@ -1,265 +0,0 @@
/* Implementation for Objective-C OrderedCollection object
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: Feb 1996
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/OrderedCollection.h>
#include <stdio.h>
#include <base/Array.h>
#include <base/NSString.h>
#include <Foundation/NSException.h>
@implementation OrderedCollection
// ADDING;
- (void) insertObject: newObject atIndex: (unsigned)index
{
[self subclassResponsibility: _cmd];
}
- (void) insertObject: newObject before: oldObject
{
int i = [self indexOfObject: oldObject];
[self insertObject: newObject atIndex: i];
}
- (void) insertObject: newObject after: oldObject
{
int i = [self indexOfObject: oldObject];
[self insertObject: newObject atIndex: i+1];
}
- (void) insertContentsOf: (id <ConstantCollecting>) aCollection
atIndex: (unsigned)index
{
[self notImplemented: _cmd];
#if 0
void doIt(elt e)
{
[self insertElement: e atIndex: index];
}
if (aCollection == self)
[self safeWithElementsInReverseCall:doIt];
else
{
if ([(id)aCollection respondsToSelector:
@selector(withElemetnsInReverseCall:)])
[(id)aCollection withElementsInReverseCall:doIt];
else
[aCollection withElementsCall:doIt];
}
#endif
}
- (void) appendObject: newObject
{
[self insertObject: newObject atIndex: [self count]];
}
- (void) prependObject: newObject
{
[self insertObject: newObject atIndex: 0];
}
- (void) appendContentsOf: (id <ConstantCollecting>) aCollection
{
id o;
NSAssert(aCollection != self, NSInvalidArgumentException);
/* xxx Could be more efficient. */
FOR_COLLECTION(aCollection, o)
{
[self appendObject: o];
}
END_FOR_COLLECTION(aCollection);
}
- (void) prependContentsOf: (id <ConstantCollecting>)aCollection
{
id o;
NSAssert(aCollection != self, NSInvalidArgumentException);
if ([(id)aCollection conformsTo: @protocol(IndexedCollecting)])
{
FOR_INDEXED_COLLECTION_REVERSE(self, o)
{
[self prependObject: o];
}
END_FOR_INDEXED_COLLECTION_REVERSE(self);
}
else
{
FOR_COLLECTION(self, o)
{
[self prependObject: o];
}
END_FOR_COLLECTION(self);
}
}
// SWAPPING AND SORTING;
- (void) swapAtIndeces: (unsigned)index1 : (unsigned)index2
{
id tmp = [self objectAtIndex:index1];
[self replaceObjectAtIndex: index1 with: [self objectAtIndex: index2]];
[self replaceObjectAtIndex: index2 with: tmp];
}
/* This could be hacked a bit to make it more efficient */
- (void) quickSortContentsFromIndex: (unsigned)p
toIndex: (unsigned)r
{
unsigned i ,j;
id x;
if (p < r)
{
/* Partition */
x = [self objectAtIndex:p];
i = p - 1;
j = r + 1;
for (;;)
{
do
j = j - 1;
while ([[self objectAtIndex: j] compare: x] > 0);
do
i = i + 1;
while ([[self objectAtIndex: i] compare: x] < 0);
if (i < j)
[self swapAtIndeces: i : j];
else
break;
}
/* Sort partitions */
[self quickSortContentsFromIndex: p toIndex: j];
[self quickSortContentsFromIndex: j+1 toIndex: r];
}
}
- (void) sortContents
{
[self quickSortContentsFromIndex: 0 toIndex: [self count]-1];
}
// REPLACING;
- (void) replaceRange: (IndexRange)aRange
withCollection: (id <ConstantCollecting>)aCollection
{
[self notImplemented: _cmd];
}
- (void) replaceRange: (IndexRange)aRange
usingCollection: (id <ConstantCollecting>)aCollection
{
[self notImplemented: _cmd];
}
#if 0
- replaceRange: (IndexRange)aRange
with: (id <Collecting>)aCollection
{
CHECK_INDEX_RANGE_ERROR(aRange.location, [self count]);
CHECK_INDEX_RANGE_ERROR(aRange.location+aRange.length-1, [self count]);
[self removeRange:aRange];
[self insertContentsOf:aCollection atIndex:aRange.location];
return self;
}
- replaceRange: (IndexRange)aRange
using: (id <Collecting>)aCollection
{
int i;
void *state = [aCollection newEnumState];
elt e;
CHECK_INDEX_RANGE_ERROR(aRange.location, [self count]);
CHECK_INDEX_RANGE_ERROR(aRange.location+aRange.length-1, [self count]);
for (i = aRange.location;
i < aRange.location + aRange.length
&& [aCollection getNextElement:&e withEnumState:&state];
i++)
{
[self replaceElementAtIndex:i with:e];
}
[aCollection freeEnumState:&state];
return self;
}
#endif
// OVERRIDE SOME COLLECTION METHODS;
- (void) addObject: newObject
{
[self appendObject: newObject];
}
- (void) addContentsOf: (id <Collecting>)aCollection
{
[self appendContentsOf: aCollection];
}
#if 0
// OVERRIDE SOME KEYED COLLECTION METHODS;
/* Semantics: You can "put" an element only at index "count" or less */
- (void) putObject: newObject atIndex: (unsigned)index
{
unsigned c = [self count];
if (index < c)
[self replaceObjectAtIndex: index withObject: newObject];
else if (index == c)
[self appendObject: newObject];
else
[NSException
raise: NSRangeException
format: @"in %s, can't put an element at index beyond [self count]"];
}
- putObject: newObject atKey: index
{
return [self putObject: newObject atIndex: [index unsignedIntValue]];
}
#endif
// OVERRIDE SOME INDEXED COLLECTION METHODS;
/* Should be more efficiently overriden by some subclasses. */
- (void) replaceObjectAtIndex: (unsigned)index withObject: newObject
{
[self removeObjectAtIndex: index];
[self insertObject: newObject atIndex: index];
}
@end

View file

@ -1,48 +0,0 @@
/* Implementation for Objective-C Queue object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/Queue.h>
#include <base/ArrayPrivate.h>
@implementation Queue
- (void) enqueueObject: newObject
{
[self prependObject: newObject];
}
- dequeueObject
{
id ret = [[self lastObject] retain];
[self removeLastObject];
return [ret autorelease];
}
/* Overriding */
- (void) addObject: newObject
{
[self enqueueObject: newObject];
}
@end

View file

@ -1,250 +0,0 @@
/* Implementation for Objective-C Red-Black Tree collection object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/RBTree.h>
#include <base/IndexedCollectionPrivate.h>
#include <base/RBTreeNode.h>
#define NODE_IS_RED(NODE) ([NODE isRed])
#define NODE_IS_BLACK(NODE) (![NODE isRed])
/* sentinal */
static id nilRBNode;
@implementation RBTree
+ (void) initialize
{
if (self == [RBTree class])
{
nilRBNode = [[RBTreeNode alloc] init];
[nilRBNode setBlack];
}
}
- nilNode
{
return nilRBNode;
}
- (void) sortAddObject: newObject
{
id y;
[super sortAddObject: newObject];
[newObject setRed];
while (newObject != _contents_root
&& [[newObject parentNode] isRed])
{
if ([newObject parentNode] ==
[[[newObject parentNode] parentNode] leftNode])
{
y = [[[newObject parentNode] parentNode] leftNode];
if ([y isRed])
{
[[newObject parentNode] setBlack];
[y setBlack];
[[[newObject parentNode] parentNode] setRed];
newObject = [[newObject parentNode] parentNode];
}
else
{
if (newObject == [[newObject parentNode] rightNode])
{
newObject = [newObject parentNode];
[self leftRotateAroundNode:newObject];
}
[[newObject parentNode] setBlack];
[[[newObject parentNode] parentNode] setRed];
[self rightRotateAroundNode:
[[newObject parentNode] parentNode]];
}
}
else
{
y = [[[newObject parentNode] parentNode] rightNode];
if ([y isRed])
{
[[newObject parentNode] setBlack];
[y setBlack];
[[[newObject parentNode] parentNode] setRed];
newObject = [[newObject parentNode] parentNode];
}
else
{
if (newObject == [[newObject parentNode] leftNode])
{
newObject = [newObject parentNode];
[self rightRotateAroundNode:newObject];
}
[[newObject parentNode] setBlack];
[[[newObject parentNode] parentNode] setRed];
[self leftRotateAroundNode:
[[newObject parentNode] parentNode]];
}
}
}
[_contents_root setBlack];
}
- (void) _RBTreeDeleteFixup: x
{
id w;
while (x != _contents_root && NODE_IS_BLACK(x))
{
if (NODE_IS_LEFTCHILD(x))
{
w = [[x parentNode] rightNode];
if (NODE_IS_RED(w))
{
[w setBlack];
[[x parentNode] setRed];
[self leftRotateAroundNode:[x parentNode]];
w = [[x parentNode] rightNode];
}
if (NODE_IS_BLACK([w leftNode]) && NODE_IS_BLACK([w rightNode]))
{
[w setRed];
x = [x parentNode];
}
else
{
if (NODE_IS_BLACK([w rightNode]))
{
[[w leftNode] setBlack];
[w setRed];
[self rightRotateAroundNode:w];
w = [[x parentNode] rightNode];
}
if (NODE_IS_BLACK([x parentNode]))
[w setBlack];
else
[w setRed];
[[x parentNode] setBlack];
[[w rightNode] setBlack];
[self leftRotateAroundNode:[x parentNode]];
x = _contents_root;
}
}
else
{
w = [[x parentNode] leftNode];
if (NODE_IS_RED(w))
{
[w setBlack];
[[x parentNode] setRed];
[self rightRotateAroundNode:[x parentNode]];
w = [[x parentNode] leftNode];
}
if (NODE_IS_BLACK([w rightNode]) && NODE_IS_BLACK([w leftNode]))
{
[w setRed];
x = [x parentNode];
}
else
{
if (NODE_IS_BLACK([w leftNode]))
{
[[w rightNode] setBlack];
[w setRed];
[self leftRotateAroundNode:w];
w = [[x parentNode] leftNode];
}
if (NODE_IS_BLACK([x parentNode]))
[w setBlack];
else
[w setRed];
[[x parentNode] setBlack];
[[w leftNode] setBlack];
[self rightRotateAroundNode:[x parentNode]];
x = _contents_root;
}
}
}
[x setBlack];
}
- (void) removeObject: oldObject
{
id x, y;
if ([oldObject leftNode] == [self nilNode]
|| [oldObject rightNode] == [self nilNode])
y = oldObject;
else
y = [self successorOfObject: oldObject];
if ([y leftNode] != [self nilNode])
x = [y leftNode];
else
x = [y rightNode];
[x setParentNode:[y parentNode]];
if ([y parentNode] == [self nilNode])
_contents_root = x;
else
{
if (y == [[y parentNode] leftNode])
[[y parentNode] setLeftNode:x];
else
[[y parentNode] setRightNode:x];
}
if (y != oldObject)
{
/* put y in the place of oldObject */
[y setParentNode:[oldObject parentNode]];
[y setLeftNode:[oldObject leftNode]];
[y setRightNode:[oldObject rightNode]];
if (oldObject == [[oldObject parentNode] leftNode])
[[oldObject parentNode] setLeftNode:y];
else
[[oldObject parentNode] setRightNode:oldObject];
[[oldObject leftNode] setParentNode:y];
[[oldObject rightNode] setParentNode:y];
}
if (NODE_IS_BLACK(y))
[self _RBTreeDeleteFixup:x];
_count--;
/* Release ownership of the object. */
#if 0
[oldObject setRightNode: [self nilNode]];
[oldObject setLeftNode: [self nilNode]];
[oldObject setParentNode: [self nilNode]];
#else
[oldObject setLeftNode: NO_OBJECT];
[oldObject setRightNode: NO_OBJECT];
[oldObject setParentNode: NO_OBJECT];
#endif
[oldObject setBinaryTree: NO_OBJECT];
[oldObject release];
}
@end

View file

@ -1,87 +0,0 @@
/* Implementation for Objective-C RBTreeNode objects
Copyright (C) 1993,1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/RBTreeNode.h>
#include <base/NSString.h>
@implementation RBTreeNode
+ (void) initialize
{
if (self == [RBTreeNode class])
[self setVersion:0]; /* beta release */
}
- init
{
[super init];
_red = YES;
return self;
}
- (void) encodeWithCoder: aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeValueOfObjCType:@encode(BOOL) at:&_red withName:@"RBTreeNode isRed"];
}
- initWithCoder: aCoder
{
[self initWithCoder:aCoder];
[aCoder decodeValueOfObjCType:@encode(BOOL) at:&_red withName:NULL];
return self;
}
- write: (TypedStream*)aStream
{
[super write:aStream];
objc_write_type(aStream, @encode(BOOL), &_red);
return self;
}
- read: (TypedStream*)aStream
{
[super read:aStream];
objc_read_type(aStream, @encode(BOOL), &_red);
return self;
}
- (BOOL) isRed
{
return _red;
}
- setRed
{
_red = YES;
return self;
}
- setBlack
{
_red = NO;
return self;
}
@end

View file

@ -1,112 +0,0 @@
/* Implementation additive congruential pseudo-random num generating
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: July 1994
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/RNGAdditiveCongruential.h>
#include <base/Coder.h>
#include <limits.h>
/* Additive Congruential Method,
from Robert Sedgewick, "Algorithms" */
/* The Chi^2 test results for this RNG is bad.
xxx Find the bug. */
@implementation RNGAdditiveCongruential
- initWithTableSize: (int)s tapsAtOffsets: (int)t1 :(int)t2
{
[super init];
table_size = s;
tap1 = t1;
tap2 = t2;
OBJC_MALLOC(table, long, table_size);
[self setRandomSeed:0];
return self;
}
- (void) encodeWithCoder: anEncoder
{
[self notImplemented:_cmd];
}
- initWithCoder: aDecoder
{
[self notImplemented:_cmd];
return self;
}
- (void) dealloc
{
OBJC_FREE(table);
[super dealloc];
}
- init
{
[self initWithTableSize:55 tapsAtOffsets:31 :55];
return self;
}
#define BITS_PER_CHAR 8
#define HIGH_BYTE(X) ((X) / (1 << (sizeof(X)-1) * BITS_PER_CHAR))
- (long) nextRandom
{
int i;
long result = 0;
/* Grab only the high bytes---they are the most random */
for (i = 0; i < sizeof(long); i++)
{
index = (index + 1) % table_size;
table[index] = (table[(index + table_size - tap1) % table_size]
+
table[(index + table_size - tap2) % table_size]);
result = (result << BITS_PER_CHAR) + HIGH_BYTE(table[index]);
}
return result;
}
- (void) setRandomSeed: (long)s
{
/* Fill the table with the linear congruential method,
from Robert Sedgewick, "Algorithms" */
/* b must be x21, with x even, one less number of digits than ULONG_MAX */
unsigned long b = ((ULONG_MAX / 1000) * 200) + 21;
unsigned char *byte_table = (unsigned char*) table;
int byte_table_size = table_size * sizeof(*table);
int i;
for (i = 0; i < byte_table_size; i++)
{
s = s * b + 1;
byte_table[i] = HIGH_BYTE(s);
}
/* Reset index to beginning */
index = 0;
return;
}
@end

View file

@ -1,443 +0,0 @@
/* Implementation of Berkeley random()-compatible generation for Objective-C
Reworked by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: July 1994
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/*
* Copyright (c) 1983, 1995 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
* This is derived from the Berkeley source:
* @(#)random.c 5.5 (Berkeley) 7/6/88
* It was reworked for the GNU C Library by Roland McGrath.
* It was reworked for the GNU Objective-C Library by Andrew Kachites McCallum
*/
#include <config.h>
#include <base/RNGBerkeley.h>
#include <base/Coder.h>
#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
//#include <sys/time.h>
/* Deal with bcopy: */
#if STDC_HEADERS || HAVE_STRING_H
#include <string.h>
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
#if !STDC_HEADERS && HAVE_MEMORY_H
#include <memory.h>
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
#define index strchr
#define rindex strrchr
#define bcopy(s, d, n) memcpy ((d), (s), (n))
#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
#define bzero(s, n) memset ((s), 0, (n))
#else /* not STDC_HEADERS and not HAVE_STRING_H */
#include <strings.h>
/* memory.h and strings.h conflict on some systems. */
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
/* An improved random number generation package. In addition to the standard
rand()/srand() like interface, this package also has a special state info
interface. The initstate() routine is called with a seed, an array of
bytes, and a count of how many bytes are being passed in; this array is
then initialized to contain information for random number generation with
that much state information. Good sizes for the amount of state
information are 32, 64, 128, and 256 bytes. The state can be switched by
calling the setstate() function with the same array as was initiallized
with initstate(). By default, the package runs with 128 bytes of state
information and generates far better random numbers than a linear
congruential generator. If the amount of state information is less than
32 bytes, a simple linear congruential R.N.G. is used. Internally, the
state information is treated as an array of longs; the zeroeth element of
the array is the type of R.N.G. being used (small integer); the remainder
of the array is the state information for the R.N.G. Thus, 32 bytes of
state information will give 7 longs worth of state information, which will
allow a degree seven polynomial. (Note: The zeroeth word of state
information also has some other information stored in it; see setstate
for details). The random number generation technique is a linear feedback
shift register approach, employing trinomials (since there are fewer terms
to sum up that way). In this approach, the least significant bit of all
the numbers in the state table will act as a linear feedback shift register,
and will have period 2^deg - 1 (where deg is the degree of the polynomial
being used, assuming that the polynomial is irreducible and primitive).
The higher order bits will have longer periods, since their values are
also influenced by pseudo-random carries out of the lower bits. The
total period of the generator is approximately deg*(2**deg - 1); thus
doubling the amount of state information has a vast influence on the
period of the generator. Note: The deg*(2**deg - 1) is an approximation
only good for large deg, when the period of the shift register is the
dominant factor. With deg equal to seven, the period is actually much
longer than the 7*(2**7 - 1) predicted by this formula. */
/* For each of the currently supported random number generators, we have a
break value on the amount of state information (you need at least thi
bytes of state info to support this random number generator), a degree for
the polynomial (actually a trinomial) that the R.N.G. is based on, and
separation between the two lower order coefficients of the trinomial. */
/* Linear congruential. */
#define TYPE_0 0
#define BREAK_0 8
#define DEG_0 0
#define SEP_0 0
/* x**7 + x**3 + 1. */
#define TYPE_1 1
#define BREAK_1 32
#define DEG_1 7
#define SEP_1 3
/* x**15 + x + 1. */
#define TYPE_2 2
#define BREAK_2 64
#define DEG_2 15
#define SEP_2 1
/* x**31 + x**3 + 1. */
#define TYPE_3 3
#define BREAK_3 128
#define DEG_3 31
#define SEP_3 3
/* x**63 + x + 1. */
#define TYPE_4 4
#define BREAK_4 256
#define DEG_4 63
#define SEP_4 1
/* Array versions of the above information to make code run faster.
Relies on fact that TYPE_i == i. */
#define MAX_TYPES 5 /* Max number of types above. */
static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
static int seps[MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
/* Initially, everything is set up as if from:
initstate(1, randtbl, 128);
Note that this initialization takes advantage of the fact that srandom
advances the front and rear pointers 10*rand_deg times, and hence the
rear pointer which starts at 0 will also end up at zero; thus the zeroeth
element of the state information, which contains info about the current
position of the rear pointer is just
(MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3. */
#if 0 /* moved to RNGBerkeley.h -am */
static long int randtbl[DEG_3 + 1] =
{
TYPE_3,
-851904987, -43806228, -2029755270, 1390239686, -1912102820,
-485608943, 1969813258, -1590463333, -1944053249, 455935928, 508023712,
-1714531963, 1800685987, -2015299881, 654595283, -1149023258,
-1470005550, -1143256056, -1325577603, -1568001885, 1275120390,
-607508183, -205999574, -1696891592, 1492211999, -1528267240,
-952028296, -189082757, 362343714, 1424981831, 2039449641,
};
#endif /* moved to RNGBerkeley.h -am */
/* FPTR and RPTR are two pointers into the state info, a front and a rear
pointer. These two pointers are always rand_sep places aparts, as they
cycle through the state information. (Yes, this does mean we could get
away with just one pointer, but the code for random is more efficient
this way). The pointers are left positioned as they would be from the call:
initstate(1, randtbl, 128);
(The position of the rear pointer, rptr, is really 0 (as explained above
in the initialization of randtbl) because the state table pointer is set
to point to randtbl[1] (as explained below).) */
#if 0 /* moved to RNGBerkeley.h -am */
static long int *fptr = &randtbl[SEP_3 + 1];
static long int *rptr = &randtbl[1];
#endif /* moved to RNGBerkeley.h -am */
/* The following things are the pointer to the state information table,
the type of the current generator, the degree of the current polynomial
being used, and the separation between the two pointers.
Note that for efficiency of random, we remember the first location of
the state information, not the zeroeth. Hence it is valid to access
state[-1], which is used to store the type of the R.N.G.
Also, we remember the last location, since this is more efficient than
indexing every time to find the address of the last element to see if
the front and rear pointers have wrapped. */
#if 0 /* moved to RNGBerkeley.h -am */
static long int *state = &randtbl[1];
static int rand_type = TYPE_3;
static int rand_deg = DEG_3;
static int rand_sep = SEP_3;
static long int *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])];
#endif /* moved to RNGBerkeley.h -am */
@implementation RNGBerkeley
- init
{
static long int static_randtbl[DEG_3 + 1] =
{
TYPE_3,
-851904987, -43806228, -2029755270, 1390239686, -1912102820,
-485608943, 1969813258, -1590463333, -1944053249, 455935928, 508023712,
-1714531963, 1800685987, -2015299881, 654595283, -1149023258,
-1470005550, -1143256056, -1325577603, -1568001885, 1275120390,
-607508183, -205999574, -1696891592, 1492211999, -1528267240,
-952028296, -189082757, 362343714, 1424981831, 2039449641,
};
[super init];
bcopy(static_randtbl, randtbl, sizeof(randtbl));
fptr = &randtbl[SEP_3 + 1];
rptr = &randtbl[1];
state = &randtbl[1];
rand_type = TYPE_3;
rand_deg = DEG_3;
rand_sep = SEP_3;
end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])];
return self;
}
/* Initialize the random number generator based on the given seed. If the
type is the trivial no-state-information type, just remember the seed.
Otherwise, initializes state[] based on the given "seed" via a linear
congruential generator. Then, the pointers are set to known locations
that are exactly rand_sep places apart. Lastly, it cycles the state
information a given number of times to get rid of any initial dependencies
introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
for default usage relies on values produced by this routine. */
- (void) _srandom: (unsigned int)x
{
state[0] = x;
if (rand_type != TYPE_0)
{
register long int i;
for (i = 1; i < rand_deg; ++i)
state[i] = (1103515145 * state[i - 1]) + 12345;
fptr = &state[rand_sep];
rptr = &state[0];
for (i = 0; i < 10 * rand_deg; ++i)
[self nextRandom]; /* (void) __random(); */
}
}
- (void) setRandomSeed: (long)aSeed
{
[self _srandom:aSeed];
return;
}
/* Initialize the state information in the given array of N bytes for
future random number generation. Based on the number of bytes we
are given, and the break values for the different R.N.G.'s, we choose
the best (largest) one we can and set things up for it. srandom is
then called to initialize the state information. Note that on return
from srandom, we set state[-1] to be the type multiplexed with the current
value of the rear pointer; this is so successive calls to initstate won't
lose this information and will be able to restart with setstate.
Note: The first thing we do is save the current state, if any, just like
setstate so that it doesn't matter when initstate is called.
Returns a pointer to the old state. */
- (void*) _initstateSeed: (unsigned int)seed
state: (void*)arg_state
size: (size_t)n
{
void* ostate = (void*) &state[-1];
if (rand_type == TYPE_0)
state[-1] = rand_type;
else
state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
if (n < BREAK_1)
{
if (n < BREAK_0)
{
errno = EINVAL;
return NULL;
}
rand_type = TYPE_0;
rand_deg = DEG_0;
rand_sep = SEP_0;
}
else if (n < BREAK_2)
{
rand_type = TYPE_1;
rand_deg = DEG_1;
rand_sep = SEP_1;
}
else if (n < BREAK_3)
{
rand_type = TYPE_2;
rand_deg = DEG_2;
rand_sep = SEP_2;
}
else if (n < BREAK_4)
{
rand_type = TYPE_3;
rand_deg = DEG_3;
rand_sep = SEP_3;
}
else
{
rand_type = TYPE_4;
rand_deg = DEG_4;
rand_sep = SEP_4;
}
state = &((long int *) arg_state)[1]; /* First location. */
/* Must set END_PTR before srandom. */
end_ptr = &state[rand_deg];
[self _srandom:seed]; /*__srandom(seed); */
if (rand_type == TYPE_0)
state[-1] = rand_type;
else
state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
return ostate;
}
/* Restore the state from the given state array.
Note: It is important that we also remember the locations of the pointers
in the current state information, and restore the locations of the pointers
from the old state information. This is done by multiplexing the pointer
location into the zeroeth word of the state information. Note that due
to the order in which things are done, it is OK to call setstate with the
same state as the current state
Returns a pointer to the old state information. */
- (void*) _setstate: (void*)arg_state
{
register long int *new_state = (long int *) arg_state;
register int type = new_state[0] % MAX_TYPES;
register int rear = new_state[0] / MAX_TYPES;
void* ostate = (void*) &state[-1];
if (rand_type == TYPE_0)
state[-1] = rand_type;
else
state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
switch (type)
{
case TYPE_0:
case TYPE_1:
case TYPE_2:
case TYPE_3:
case TYPE_4:
rand_type = type;
rand_deg = degrees[type];
rand_sep = seps[type];
break;
default:
/* State info munged. */
errno = EINVAL;
return NULL;
}
state = &new_state[1];
if (rand_type != TYPE_0)
{
rptr = &state[rear];
fptr = &state[(rear + rand_sep) % rand_deg];
}
/* Set end_ptr too. */
end_ptr = &state[rand_deg];
return ostate;
}
/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
congruential bit. Otherwise, we do our fancy trinomial stuff, which is the
same in all ther other cases due to all the global variables that have been
set up. The basic operation is to add the number at the rear pointer into
the one at the front pointer. Then both pointers are advanced to the next
location cyclically in the table. The value returned is the sum generated,
reduced to 31 bits by throwing away the "least random" low bit.
Note: The code takes advantage of the fact that both the front and
rear pointers can't wrap on the same call by not testing the rear
pointer if the front one has wrapped. Returns a 31-bit random number. */
- (long) nextRandom
{
if (rand_type == TYPE_0)
{
state[0] = ((state[0] * 1103515245) + 12345) & LONG_MAX;
return state[0];
}
else
{
long int i;
*fptr += *rptr;
/* Chucking least random bit. */
i = (*fptr >> 1) & LONG_MAX;
++fptr;
if (fptr >= end_ptr)
{
fptr = state;
++rptr;
}
else
{
++rptr;
if (rptr >= end_ptr)
rptr = state;
}
return i;
}
}
- (void) encodeWithCoder: anEncoder
{
[self notImplemented:_cmd];
}
- initWithCoder: aDecoder
{
[self notImplemented:_cmd];
return self;
}
@end

View file

@ -1,306 +0,0 @@
/* Implementation Objective-C object providing randoms in uniform distribution
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: July 1994
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/* TODO:
RNGBerkeley nextRandom returns only positive numbers
RNGAdditiveCongruential nextRandom returns positive and negative numbers
*/
#include <config.h>
#include <base/Random.h>
#include <base/RNGBerkeley.h>
#include <base/Time.h>
#include <base/Coder.h>
#include <Foundation/NSException.h>
#include <limits.h>
typedef union {
float f;
unsigned long u;
} float_and_long_u;
typedef union {
double d;
unsigned long u[2];
} double_and_long_u;
static float_and_long_u singleMantissa;
static double_and_long_u doubleMantissa;
static id defaultRNG = nil;
@class RNGBerkeley;
@implementation Random
+ initialize
{
if (self == [Random class])
{
defaultRNG = [RNGBerkeley class];
NSAssert(sizeof(double) == 2 * sizeof(long), NSInternalInconsistencyException);
NSAssert(sizeof(float) == sizeof(long), NSInternalInconsistencyException);
/* Following taken from libg++ */
/*
The following is a hack that I attribute to
Andres Nowatzyk at CMU. The intent of the loop
is to form the smallest number 0 <= x < 1.0,
which is then used as a mask for two longwords.
this gives us a fast way way to produce double
precision numbers from longwords.
I know that this works for IEEE and VAX floating
point representations.
A further complication is that gnu C will blow
the following loop, unless compiled with -ffloat-store,
because it uses extended representations for some of
of the comparisons. Thus, we have the following hack.
If we could specify #pragma optimize, we wouldn't need this.
*/
{
double_and_long_u t;
float_and_long_u s;
#if _IEEE == 1
t.d = 1.5;
if ( t.u[1] == 0 ) { // sun word order?
t.u[0] = 0x3fffffff;
t.u[1] = 0xffffffff;
}
else {
t.u[0] = 0xffffffff; // encore word order?
t.u[1] = 0x3fffffff;
}
s.u = 0x3fffffff;
#else
volatile double x = 1.0; /* volatile needed when fp hardware used,
and has greater precision than memory
doubles */
double y = 0.5;
volatile float xx = 1.0; /* volatile needed when fp hardware used,
and has greater precision than memory
floats */
float yy = 0.5;
do { /* find largest fp-number < 2.0 */
t.d = x;
x += y;
y *= 0.5;
} while (x != t.d && x < 2.0);
do { /*find largest fp-number < 2.0 */
s.f = xx;
xx += yy;
yy *= 0.5;
} while (xx != s.f && xx < 2.0);
#endif
// set doubleMantissa to 1 for each doubleMantissa bit;
doubleMantissa.d = 1.0;
doubleMantissa.u[0] ^= t.u[0];
doubleMantissa.u[1] ^= t.u[1];
// set singleMantissa to 1 for each singleMantissa bit;
singleMantissa.f = 1.0;
singleMantissa.u ^= s.u;
}
}
return self;
}
+ setDefaultRandomGeneratorClass: (id <RandomGenerating>)aRNG
{
defaultRNG = aRNG;
return self;
}
+ (id <RandomGenerating>) defaultRandomGeneratorClass
{
return defaultRNG;
}
/* For testing randomness of a random generator,
the closer to r the returned value is, the better the randomness. */
+ (float) chiSquareOfRandomGenerator: (id <RandomGenerating>)aRNG
iterations: (int)n
range: (long)r
{
long table[r];
int i, j;
for (i = 0; i < r; i++)
table[i] = 0;
for (i = 0; i < n; i++)
{
j = ABS([aRNG nextRandom]) % r;
table[j]++;
}
j = 0;
for (i = 0; i < r; i++)
j += table[i] * table[i];
return ((((float)r * j) / n) - n);
}
/* For testing randomness of a random generator,
the closer to 1.0 the returned value is, the better the randomness. */
+ (float) chiSquareOfRandomGenerator: (id <RandomGenerating>)aRNG
{
return [self chiSquareOfRandomGenerator:aRNG
iterations:1000
range:100] / 100.0;
}
- initWithRandomGenerator: (id <RandomGenerating>)aRNG
{
[super init];
rng = aRNG;
return self;
}
- init
{
/* Without the (id) we get:
Random.m: In function `_i_Random__init':
Random.m:172: warning: method `alloc' not implemented by protocol.
This is a bug in gcc.
*/
return [self initWithRandomGenerator:
[[(id)[[self class] defaultRandomGeneratorClass] alloc] init]];
}
- setRandomSeedFromClock
{
[self setRandomSeed:[Time secondClockValue]];
return self;
}
- setRandomSeed: (long)seed
{
[rng setRandomSeed:seed];
return self;
}
- (long) randomInt
{
return [rng nextRandom];
}
- (long) randomIntBetween: (long)lowBound and: (long)highBound
{
return ([rng nextRandom] % (highBound - lowBound + 1) + lowBound);
}
/* return between 0 and numSides-1 */
- (long) randomDie: (long)numSides
{
return ([rng nextRandom] % numSides);
}
- (BOOL) randomCoin
{
return ([rng nextRandom] % 2);
}
- (BOOL) randomCoinWithProbability: (double)p
{
return (p >= [self randomDoubleProbability]);
}
/* Returns 0.0 <= r < 1.0. Is this what people want?
I'd like it to return 1.0 also. */
- (float) randomFloat
{
union {long i; float f;} result;
result.f = 1.0;
result.i |= ([rng nextRandom] & singleMantissa.u);
result.f -= 1.0;
NSAssert(result.f < 1.0 && result.f >= 0, NSInternalInconsistencyException);
return result.f;
}
- (float) randomFloatBetween: (float)lowBound and: (float)highBound
{
return ([self randomFloat] * (highBound - lowBound) + lowBound);
}
- (float) randomFloatProbability
{
return [self randomFloat];
}
/* Returns 0.0 <= r < 1.0. Is this what people want?
I'd like it to return 1.0 also. */
- (double) randomDouble
{
union {unsigned long u[2]; double d;} result;
result.d = 1.0;
result.u[0] |= ([rng nextRandom] & doubleMantissa.u[0]);
result.u[1] |= ([rng nextRandom] & doubleMantissa.u[1]);
result.d -= 1.0;
NSAssert(result.d < 1.0 && result.d >= 0, NSInternalInconsistencyException);
return result.d;
}
- (double) randomDoubleBetween: (double)lowBound and: (double)highBound
{
return [self randomDouble] * (highBound - lowBound);
}
- (double) randomDoubleProbability
{
return [self randomDouble];
}
- (void) encodeWithCoder: anEncoder
{
[self notImplemented:_cmd];
}
- initWithCoder: aDecoder
{
[self notImplemented:_cmd];
return self;
}
- write: (TypedStream*)aStream
{
[super write:aStream];
// [rng read:aStream];
[self notImplemented:_cmd];
return self;
}
- read: (TypedStream*)aStream
{
[super read:aStream];
// [rng read:aStream];
[self notImplemented:_cmd];
return self;
}
@end

View file

@ -1,229 +0,0 @@
/* Implementation for Objective-C Set collection object
Copyright (C) 1993,1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/Set.h>
#include <base/CollectionPrivate.h>
#include <base/Coder.h>
#include <Foundation/NSHashTable.h>
#define DEFAULT_SET_CAPACITY 32
@implementation Set
// MANAGING CAPACITY;
/* Eventually we will want to have better capacity management,
potentially keep default capacity as a class variable. */
+ (unsigned) defaultCapacity
{
return DEFAULT_SET_CAPACITY;
}
// INITIALIZING AND FREEING;
/* This is the designated initializer of this class */
- initWithCapacity: (unsigned)cap
{
_contents_hash = NSCreateHashTable(NSObjectHashCallBacks, cap);
return self;
}
/* Override Collection's designated initializer */
- initWithObjects: (id*)objs count: (unsigned)count
{
[self initWithCapacity: count];
while (count--)
[self addObject: objs[count]];
return self;
}
/* Archiving must mimic the above designated initializer */
- _initCollectionWithCoder: aCoder
{
[super _initCollectionWithCoder:aCoder];
_contents_hash = NSCreateHashTable(NSObjectHashCallBacks,
DEFAULT_SET_CAPACITY);
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
Set *copy = [super emptyCopy];
copy->_contents_hash =
NSCreateHashTable (NSObjectHashCallBacks, 0);
return copy;
}
- (void) dealloc
{
if (_contents_hash)
{
NSFreeHashTable (_contents_hash);
_contents_hash = 0;
}
[super dealloc];
}
// SET OPERATIONS;
- (void) intersectWithCollection: (id <Collecting>)aCollection
{
[self removeContentsNotIn: aCollection];
}
- (void) unionWithCollection: (id <Collecting>)aCollection
{
[self addContentsIfAbsentOf: aCollection];
}
- (void) differenceWithCollection: (id <Collecting>)aCollection
{
[self removeContentsIn: aCollection];
}
- shallowCopyIntersectWithCollection: (id <Collecting>)aCollection
{
[self notImplemented: _cmd];
return nil;
#if 0
id newColl = [self emptyCopyAs:[self species]];
void doIt(elt e)
{
if ([aCollection includesElement:e])
[newColl addElement:e];
}
[self withElementsCall:doIt];
return newColl;
#endif
}
- shallowCopyUnionWithCollection: (id <Collecting>)aCollection
{
[self notImplemented: _cmd];
return nil;
#if 0
id newColl = [self shallowCopy];
[newColl addContentsOf:aCollection];
return newColl;
#endif
}
- shallowCopyDifferenceWithCollection: (id <Collecting>)aCollection
{
[self notImplemented: _cmd];
return nil;
#if 0
id newColl = [self emptyCopyAs:[self species]];
void doIt(elt e)
{
if (![aCollection includesElement:e])
[newColl addElement:e];
}
[self withElementsCall:doIt];
return newColl;
#endif
}
// ADDING;
- (void) addObject: newObject
{
NSHashInsert (_contents_hash, newObject);
}
// REMOVING AND REPLACING;
- (void) removeObject: oldObject
{
NSHashRemove (_contents_hash, oldObject);
}
/* This must work without sending any messages to content objects */
- (void) _collectionEmpty
{
NSResetHashTable (_contents_hash);
}
- (void) uniqueContents
{
return;
}
// TESTING;
- (BOOL) containsObject: anObject
{
return (NSHashGet (_contents_hash, anObject) ? 1 : 0);
}
- (unsigned) count
{
if (!_contents_hash)
return 0;
return NSCountHashTable (_contents_hash);
}
- (unsigned) occurrencesOfObject: anObject
{
if ([self containsObject: anObject])
return 1;
else
return 0;
}
- member: anObject
{
return NSHashGet(_contents_hash, anObject);
}
// ENUMERATING;
- nextObjectWithEnumState: (void**)enumState
{
return NSNextHashEnumeratorItem ((*(NSHashEnumerator**)enumState));
}
- (void*) newEnumState
{
void *es;
OBJC_MALLOC (es, NSMapEnumerator, 1);
*((NSHashEnumerator*)es) = NSEnumerateHashTable (_contents_hash);
return es;
}
- (void) freeEnumState: (void**)enumState
{
OBJC_FREE (*enumState);
}
@end

View file

@ -1,102 +0,0 @@
/* Implementation for Objective-C SplayTree collection object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/SplayTree.h>
#include <base/IndexedCollectionPrivate.h>
@implementation SplayTree
/* Make this a function ? */
- (void) _doSplayOperationOnNode: aNode
{
id parent = [aNode parentNode];
id parentRightChild =
((parent == [self nilNode]) ? [self nilNode] : [parent rightNode]);
if (aNode == _contents_root || aNode == [self nilNode])
{
return;
}
else if (aNode == parentRightChild)
{
if (parent == _contents_root)
{
[self leftRotateAroundNode:parent];
}
else if (NODE_IS_RIGHTCHILD(parent))
{
[self leftRotateAroundNode:[parent parentNode]];
[self leftRotateAroundNode:parent];
}
else
/* NODE_IS_LEFTCHILD(parent) */
{
[self leftRotateAroundNode:parent];
[self rightRotateAroundNode:[aNode parentNode]];
}
}
else
/* aNode == parentLeftChild */
{
if (parent == _contents_root)
{
[self rightRotateAroundNode:parent];
}
else if (NODE_IS_LEFTCHILD(parent))
{
[self rightRotateAroundNode:[parent parentNode]];
[self rightRotateAroundNode:parent];
}
else
/* NODE_IS_RIGHTCHILD(parent) */
{
[self rightRotateAroundNode:parent];
[self leftRotateAroundNode:[aNode parentNode]];
}
}
}
- (void) splayNode: aNode
{
while (aNode != _contents_root)
[self _doSplayOperationOnNode:aNode];
}
/* We could make this a little more efficient by doing the splay as
we search down the tree for the correct insertion point. */
- (void) sortAddObject: newObject
{
[super sortAddObject: newObject];
[self splayNode: newObject];
}
- (void) removeObject: anObject
{
id parent = [anObject parentNode];
[super removeObject: anObject];
if (parent && parent != [self nilNode])
[self splayNode:parent];
}
@end

View file

@ -1,66 +0,0 @@
/* Implementation for Objective-C Stack object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/Stack.h>
#include <base/ArrayPrivate.h>
@implementation Stack
- (void) pushObject: newObject
{
[self appendObject: newObject];
}
/* Overriding */
- (void) addObject: newObject
{
[self pushObject: newObject];
}
- popObject
{
id ret;
ret = [[self lastObject] retain];
[self removeLastObject];
return [ret autorelease];
}
- topObject
{
return [self lastObject];
}
/* xxx Yipes. What copying semantics do we want here? */
- (void) duplicateTop
{
[self pushObject: [self topObject]];
}
- (void) exchangeTop
{
if (_count > 1)
[self swapAtIndeces:_count-1 :_count-2];
}
@end