This is LinkList.m in view mode; [Download] [Up]
/* Implementation for Objective-C LinkList 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/LinkList.h>
#include <objc/objc-api.h>
#include <coll/IndexedCollectionPrivate.h>
@implementation LinkList (ErrorReporting)
- errorElementNotLinking: (elt)anElement inMethod: (SEL)aSel
{
[self warning:"in %s, element=0x%x does not conform to <ListLinking>"];
return self;
}
@end
@implementation LinkList
+ initialize
{
if (self == [LinkList class])
[self setVersion:-1]; /* alpha release */
return self;
}
/* This is the designated initializer of this class */
- init
{
[super initDescription:"@"];
_count = 0;
_firstLink = nil;
return self;
}
/* Override the designated initializer for our superclass IndexedCollection
to make sure we have object values. */
- initDescription: (const char *)description
{
if (*description != _C_ID)
[self error:"LinkList contents must be objects conforming to "
"<DoubleLinking> protocol"];
[self init];
return self;
}
/* These next four methods are the only ones that change the values of
the instance variables _count, _firstLink, except for
"-initDescription:". */
- (elt) removeElement: (elt)oldElement
{
if (_firstLink == oldElement.id_t)
{
if (_count > 1)
_firstLink = [oldElement.id_t nextLink];
else
_firstLink = nil;
}
[[oldElement.id_t nextLink] setPrevLink:[oldElement.id_t prevLink]];
[[oldElement.id_t prevLink] setNextLink:[oldElement.id_t nextLink]];
_count--;
return oldElement;
}
- insertElement: (elt)newElement after: (elt)oldElement
{
if (_count == 0)
{
/* link to self */
_firstLink = newElement.id_t;
[newElement.id_t setNextLink:newElement.id_t];
[newElement.id_t setPrevLink:newElement.id_t];
}
else
{
[newElement.id_t setNextLink:[oldElement.id_t nextLink]];
[newElement.id_t setPrevLink:oldElement.id_t];
[[oldElement.id_t nextLink] setPrevLink:newElement.id_t];
[oldElement.id_t setNextLink:newElement.id_t];
}
_count++;
return self;
}
- insertElement: (elt)newElement before: (elt)oldElement
{
if (oldElement.id_t == _firstLink)
_firstLink = newElement.id_t;
if (_count == 0)
{
/* Link to self */
[newElement.id_t setNextLink:newElement.id_t];
[newElement.id_t setPrevLink:newElement.id_t];
}
else
{
[newElement.id_t setPrevLink:[oldElement.id_t prevLink]];
[newElement.id_t setNextLink:oldElement.id_t];
[[oldElement.id_t prevLink] setNextLink:newElement.id_t];
[oldElement.id_t setPrevLink:newElement.id_t];
}
_count++;
return self;
}
- (elt) replaceElement: (elt)oldElement with: (elt)newElement
{
if (oldElement.id_t == _firstLink)
_firstLink = newElement.id_t;
[newElement.id_t setNextLink:[oldElement.id_t nextLink]];
[newElement.id_t setPrevLink:[oldElement.id_t prevLink]];
[[oldElement.id_t prevLink] setNextLink:newElement.id_t];
[[oldElement.id_t nextLink] setPrevLink:newElement.id_t];
return oldElement;
}
/* End of methods that change the instance variables. */
- appendElement: (elt)newElement
{
[self insertElement:newElement after:[self lastElement]];
return self;
}
- prependElement: (elt)newElement
{
[self insertElement:newElement before:_firstLink];
return self;
}
- insertElement: (elt)newElement atIndex: (unsigned)index
{
if (INDEX_RANGE_WARNING(index, (_count+1)))
return nil;
if (index == _count)
[self appendElement:newElement];
else
[self insertElement:newElement before:[self elementAtIndex:index]];
return self;
}
- (elt) removeElementAtIndex: (unsigned)index
{
if (INDEX_RANGE_WARNING(index, _count))
return COLL_NO_ELEMENT;
[self removeElement:[self elementAtIndex:index]];
return self;
}
- (elt) elementAtIndex: (unsigned)index
{
id <ListLinking> aLink;
if (INDEX_RANGE_WARNING(index, _count))
return COLL_NO_ELEMENT;
if (index < _count / 2)
for (aLink = _firstLink;
index;
aLink = [aLink nextLink], index--)
;
else
for (aLink = [_firstLink prevLink], index = _count - index - 1;
index;
aLink = [aLink prevLink], index--)
;
return aLink;
}
- (elt) firstElement
{
return _firstLink;
}
- (elt) lastElement
{
if (_count)
return [_firstLink prevLink];
else
return COLL_NO_ELEMENT;
}
- (BOOL) getNextElement:(elt *)anElementPtr withEnumState: (void**)enumState
{
if (*enumState == _firstLink)
return NO;
else if (!(*enumState))
*enumState = _firstLink;
*anElementPtr = *enumState;
*enumState = [(id)(*enumState) nextLink];
return YES;
}
- (BOOL) getPrevElement:(elt *)anElementPtr withEnumState: (void**)enumState
{
if (*enumState == _firstLink)
return NO;
if (!(*enumState))
*enumState = _firstLink;
*enumState = [(id)(*enumState) prevLink];
*anElementPtr = *enumState;
return YES;
}
- withElementsCall: (void(*)(elt))aFunc whileTrue:(BOOL *)flag
{
id link;
unsigned i;
for (link = _firstLink, i = 0;
*flag && i < _count;
link = [link nextLink], i++)
{
aFunc(link);
}
return self;
}
- withElementsInReverseCall: (void(*)(elt))aFunc whileTrue:(BOOL *)flag
{
id link;
unsigned i;
if (!_firstLink)
return self;
for (link = [_firstLink prevLink], i = 0;
*flag && i < _count;
link = [link prevLink], i++)
{
aFunc(link);
}
return self;
}
- (unsigned) count
{
return _count;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.