/// LinkedList.cc apdated for use in bbtools 23-10-1998 by John Kennis
//
//
// Original notice:
//
// LinkedList.cc for Blackbox - an X11 Window manager
// Copyright (c) 1997, 1998 by Brad Hughes, bhughes@tcac.net
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// (See the included file COPYING / GPL-2.0)
//
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include "LinkedList.hh"
// *************************************************************************
// Linked List iterator class code
// *************************************************************************
__llist_iterator::__llist_iterator(__llist *l) {
list = l;
reset();
}
__llist_iterator::~__llist_iterator(void) {
}
void *__llist_iterator::current(void) {
return ((node) ? node->data : 0);
}
void __llist_iterator::reset(void) {
if (list)
node = list->_first;
}
void __llist_iterator::resetLast(void) {
if (list)
node = list->_last;
}
const int __llist_iterator::set(const int index) {
if (list) {
if (index < list->elements && index >= 0) {
node = list->_first;
int i;
for (i = 0; i < index; i++)
node = node->next;
return 1;
}
}
node = (__llist_node *) 0;
return 0;
}
void __llist_iterator::operator++(int) {
node = ((node) ? node->next : 0);
}
void __llist_iterator::operator--(int) {
node = ((node) ? node->prev : 0);
}
// *************************************************************************
// Linked List class code
// *************************************************************************
__llist::__llist(void *d) {
if (! d) {
_first = (__llist_node *) 0;
_last = (__llist_node *) 0;
elements = 0;
} else {
_first = new __llist_node;
_first->data = d;
_first->next = (__llist_node *) 0;
_first->prev = (__llist_node *) 0;
_last = _first;
elements = 1;
}
}
__llist::~__llist(void) {
int i, r = elements;
for (i = 0; i < r; i++)
remove(0);
}
const int __llist::insert(void *d, int index) {
if (! _first) {
_first = new __llist_node;
_first->data = d;
_first->next = (__llist_node *) 0;
_first->prev = (__llist_node *) 0;
_last = _first;
} else {
// if index is -1... append the data to the end of the list
if (index == -1) {
__llist_node *nnode = new __llist_node;
nnode->data = d;
nnode->next = (__llist_node *) 0;
nnode->prev = _last;
_last->next = nnode;
_last = nnode;
} else {
__llist_node *nnode = new __llist_node, *inode = _first;
// otherwise... insert the item at the position specified by index
if (index > elements) return -1;
int i;
for (i = 0; i < index; i++)
inode = inode->next;
if ((! inode) || inode == _last) {
nnode->data = d;
nnode->next = (__llist_node *) 0;
nnode->prev = _last;
_last->next = nnode;
_last = nnode;
} else {
nnode->data = d;
nnode->next = inode->next;
nnode->prev = inode;
inode->next->prev = nnode;
inode->next = nnode;
}
}
}
return ++elements;
}
const int __llist::remove(void *d) {
// remove list item whose data pointer address matches the pointer address
// given
__llist_node *rnode = _first;
int i;
for (i = 0; i < elements; i++) {
if (rnode->data == d) {
if (rnode->prev) {
rnode->prev->next = rnode->next;
if (rnode->next)
rnode->next->prev = rnode->prev;
} else {
// we removed the _first item in the list... reflect that removal in
// the list internals
_first = rnode->next;
if (_first)
_first->prev = (__llist_node *) 0;
}
if (rnode == _last) {
_last = rnode->prev;
if (_last)
_last->next = (__llist_node *) 0;
}
--elements;
delete rnode;
break;
}
if (rnode)
rnode = rnode->next;
else
return -1;
}
return i;
}
void *__llist::remove(const int index) {
if (index < elements && index >= 0) {
// remove list item at specified index within the list
__llist_node *rnode = _first;
void *data_return = 0;
int i;
for (i = 0; i < index; i++)
rnode = rnode->next;
if (rnode->prev) {
rnode->prev->next = rnode->next;
if (rnode->next)
rnode->next->prev = rnode->prev;
} else {
// we removed the _first item in the list... reflect that removal in the
// list internals
_first = rnode->next;
if (_first)
_first->prev = (__llist_node *) 0;
}
if (rnode == _last) {
_last = rnode->prev;
if (_last)
_last->next = (__llist_node *) 0;
}
--elements;
data_return = rnode->data;
delete rnode;
return data_return;
}
return (void *) 0;
}
void *__llist::find(const int index) {
if (index < elements && index >= 0) {
__llist_node *fnode = _first;
int i;
for (i = 0; i < index; i++)
fnode = fnode->next;
return fnode->data;
}
return (void *) 0;
}
syntax highlighted by Code2HTML, v. 0.9.1