gzdoom/src/lists.h
2016-03-01 09:47:10 -06:00

146 lines
3.3 KiB
C++

/*
** lists.h
** Essentially, Amiga Exec lists and nodes
**
**---------------------------------------------------------------------------
** Copyright 1998-2006 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#ifndef __LISTS_H__
#define __LISTS_H__
struct Node
{
Node *Succ, *Pred;
void Insert (Node *putAfter)
{
Succ = putAfter->Succ;
Pred = putAfter;
putAfter->Succ = this;
Succ->Pred = this;
}
void InsertBefore (Node *putBefore)
{
Succ = putBefore;
Pred = putBefore->Pred;
putBefore->Pred = this;
Pred->Succ = this;
}
void Remove ()
{
Pred->Succ = Succ;
Succ->Pred = Pred;
}
};
struct List
{
Node *Head;
const Node *const Tail;
Node *TailPred;
List () : Head ((Node *)&Tail), Tail (NULL), TailPred ((Node *)&Head)
{
}
bool IsEmpty () const
{
return TailPred == (Node *)this;
}
void MakeEmpty ()
{
Head = (Node *)&Tail;
TailPred = (Node *)&Head;
}
void AddHead (Node *node)
{
node->Succ = Head;
node->Pred = (Node *)&Head;
Head->Pred = node;
Head = node;
}
void AddTail (Node *node)
{
node->Pred = TailPred;
node->Succ = (Node *)&Tail;
TailPred->Succ = node;
TailPred = node;
}
Node *RemHead ()
{
Node *node = Head;
if (node->Succ == NULL)
{
return NULL;
}
Head = node->Succ;
Head->Pred = (Node *)&Head;
return node;
}
Node *RemHeadQ () // Only use if list is definitely not empty
{
Node *node = Head;
Head = node->Succ;
Head->Pred = (Node *)&Head;
return node;
}
Node *RemTail ()
{
Node *node = TailPred;
if (node->Pred == NULL)
{
return NULL;
}
TailPred = node->Pred;
TailPred->Succ = (Node *)&Tail;
return node;
}
Node *RemTailQ () // Only use if list is definitely not empty
{
Node *node = TailPred;
TailPred = node->Pred;
TailPred->Succ = (Node *)&Tail;
return node;
}
private:
List &operator= (const List&) { return *this; }
};
#endif //__LISTS_H__