/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at
golgotha_source@usa.net (Subject should have "GOLG" in it)
***********************************************************************/
//{{{ Intrusive singly linked list
//
// Notes:
// The templatized class MUST have member:
// T* next;
//
#ifndef ISLLIST_HPP
#define ISLLIST_HPP
#include "arch.hh" // for definition of i4_bool
template
class i4_isl_list
{
protected:
typedef T* link;
link list;
public:
T *first() { return list; }
i4_isl_list() : list(0) {}
class iterator
{
friend class i4_isl_list;
protected:
link node;
public:
iterator() : node(0) {}
iterator(const iterator &p) : node(p.node) {}
iterator(link p) : node(p) {}
int operator==(const iterator &p) const { return (node == p.node); }
int operator!=(const iterator &p) const { return (node != p.node); }
T& operator*() const { return *node; }
T* operator->() const { return node; }
iterator& operator++()
{
node = node->next;
return *this;
}
iterator& operator++(int)
{
node = node->next;
return *this;
}
};
iterator end() const { return 0; }
iterator begin() const { return list; }
i4_bool empty() const { return begin() == end(); }
iterator insert_after(iterator _pos, T &item)
{
item.next = (*_pos.node).next;
_pos.node->next = &item;
return &item;
}
void erase_after(iterator _pos)
{
_pos.node->next = _pos.node->next->next;
}
void insert_end(T &item)
{
item.next=0;
if (!list)
list=&item;
else
{
link last=list;
while (last->next)
last=last->next;
last->next=&item;
}
}
void insert(T& item) { item.next = list; list = &item; }
void erase() { list = list->next; }
void destroy_all()
{
link p;
while (list)
{
p = list;
erase();
delete p;
}
}
iterator find(T *item)
{
iterator p=begin();
for (;p!=end();++p)
if (p.node==item)
return p;
return end();
}
void swap(i4_isl_list &other)
{
link other_list=other.list;
other.list=list;
list=other_list;
}
T *find_and_unlink(T *item)
{
iterator p=begin(), last=end();
for (;p!=end(); ++p)
if (p.node==item)
{
if (last!=end())
erase_after(last);
else
erase();
return item;
}
else last=p;
return 0;
}
};
#endif