This is Bag.m in view mode; [Download] [Up]
/* Implementation for Objective-C Bag collection object Copyright (C) 1993 R. Andrew McCallum <mccallum@cs.rochester.edu> Dept. of Computer Science, U. of Rochester, Rochester, NY 14627 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <coll/Bag.h> @implementation Bag + initialize { if (self == [Bag class]) [self setVersion:-1]; /* alpha release */ return self; } // INITIALIZING AND FREEING; /* This is the designated initializer of this class */ - initDescription:(const char *)type capacity: (unsigned)aCapacity { [super initDescription:type capacity:aCapacity]; _tally = 0; return self; } // ADDING; - addElement: (elt)newElement withOccurrences: (unsigned)count { node_ptr node = hash_node_for_key(_contents_hash, newElement.void_ptr_t); if (node) ((unsigned)(node->value)) += count; else hash_add(&_contents_hash, newElement.void_ptr_t, (void*)count); _tally += count; return self; } - addElement: (elt)newElement { return [self addElement:newElement withOccurrences:1]; } // REMOVING AND REPLACING; - (elt) removeElement: (elt)oldElement { node_ptr node = hash_node_for_key(_contents_hash, oldElement.void_ptr_t); if (node) { if (node->value > (void*)1) ((unsigned)(node->value))--; else hash_remove(_contents_hash, oldElement.void_ptr_t); _tally--; } return oldElement; } - empty { [super empty]; _tally = 0; } - uniqueContents { node_ptr node = 0; _tally = 0; while (node = hash_next(_contents_hash,node)) { node->value = (void*)1; _tally++; } return self; } // TESTING; - (unsigned) count { return _tally; } - (unsigned) occurrencesOfElement: (elt)anElement { node_ptr node = hash_node_for_key(_contents_hash, anElement.void_ptr_t); if (node) return (unsigned)(node->value); else return 0; } // ENUMERATING; struct BagEnumState { node_ptr node; unsigned count; }; #define ES ((struct BagEnumState *) *enumState) /* It would be nice if the hash.c implementation also used a malloc scheme like this so that a programmer could do more than one enumeration concurrently time. */ - (BOOL) getNextElement:(elt *)anElementPtr withEnumState: (void**)enumState { if (!(*enumState)) { /* init for start of enumeration. */ OBJC_MALLOC(*enumState, struct BagEnumState, 1); ES->node = hash_next(_contents_hash, 0); ES->count = 0; } else if (ES->count >= ((unsigned)ES->node->value)) { /* time to get the next different element */ ES->node = hash_next(_contents_hash, ES->node); ES->count = 0; } if (!(ES->node)) { /* at end of enumeration */ OBJC_FREE(*enumState); *enumState = 0; return NO; } *anElementPtr = ES->node->key; (ES->count)++; return YES; } - withElementsCall: (void(*)(elt))aFunc whileTrue:(BOOL *)flag { int i; node_ptr node = 0; while (node = hash_next(_contents_hash, node)) { for (i = 0; i < (unsigned)(node->value); i++) { if (!(*flag)) return self; aFunc(node->key); } } return self; } - withElementsCall: (void(*)(elt))aFunc { int i; node_ptr node = 0; while (node = hash_next(_contents_hash, node)) { for (i = 0; i < (unsigned)(node->value); i++) { aFunc(node->key); } } return self; } // OBJECT-COMPATIBLE MESSAGE NAMES; - addObject: newObject withOccurrences: (unsigned)count { return [self addElement:newObject withOccurrences:count]; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.