/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** 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 3 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, see . */ /*********************************************************************************************** *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** *********************************************************************************************** * * * Project Name : ww3d * * * * $Archive:: /Commando/Code/ww3d2/dllist.h $* * * * Original Author:: Jani Penttinen * * * * $Author:: Jani_p $* * * * $Modtime:: 3/21/01 6:18p $* * * * $Revision:: 11 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #if defined(_MSC_VER) #pragma once #endif #ifndef DLLIST_H #define DLLIST_H template class DLNodeClass; template class DLListClass { friend DLNodeClass; DLNodeClass* head; DLNodeClass* tail; public: DLListClass() : head(0), tail(0) {} virtual ~DLListClass() { } void Add_Head(DLNodeClass* node); void Remove_Head(); void Add_Tail(DLNodeClass* node); void Remove_Tail(); T* Head() { return static_cast(head); } T* Tail() { return static_cast(tail); } const T* Const_Head() const { return static_cast(head); } const T* Const_Tail() const { return static_cast(tail); } }; // Destroy-list will call delete for all nodes when the list is destructed. Note that the class doesn't work // with undeclared pointer types (destructor has to be known). template class DLDestroyListClass : public DLListClass { public: virtual ~DLDestroyListClass() { while (T* t=Head()) { delete t; } } }; template class DLNodeClass { friend DLListClass; DLNodeClass* succ; DLNodeClass* pred; DLListClass* list; public: DLNodeClass() : succ(0), pred(0), list(0) {} ~DLNodeClass() { Remove(); } void Insert_Before(DLNodeClass* n) { list=n->list; succ=n; pred=n->pred; if (n->pred) n->pred->succ=this; n->pred=this; if (list->head==n) { list->head=this; } } void Insert_After(DLNodeClass* n) { list=n->list; pred=n; succ=n->succ; if (n->succ) n->succ->pred=this; n->succ=this; if (list->tail==n) { list->tail=this; } } void Remove() { if (!list) return; if (list->Head()==this) { DLListClass* tmp_list=list; list=0; tmp_list->Remove_Head(); return; } if (list->Tail()==this) { DLListClass* tmp_list=list; list=0; tmp_list->Remove_Tail(); return; } if (succ) succ->pred=pred; if (pred) pred->succ=succ; list=0; } T* Succ() { return static_cast(succ); } T* Pred() { return static_cast(pred); } const T* Const_Succ() const { return static_cast(succ); } const T* Const_Pred() const { return static_cast(pred); } DLListClass* List() { return list; } }; template inline void DLListClass::Add_Head(DLNodeClass* n) { n->list=this; if (head) { n->Insert_Before(head); head=n; } else { tail=n; head=n; n->succ=0; n->pred=0; } } template inline void DLListClass::Add_Tail(DLNodeClass* n) { n->list=this; if (tail) { n->Insert_After(tail); tail=n; } else { tail=n; head=n; n->succ=0; n->pred=0; } } template inline void DLListClass::Remove_Head() { if (!head) return; DLNodeClass* n=head; head=head->Succ(); if (!head) tail=head; else head->pred=0; n->Remove(); } template inline void DLListClass::Remove_Tail() { if (!tail) return; DLNodeClass* n=tail; tail=tail->Pred(); if (!tail) head=tail; else tail->succ=0; n->Remove(); } #endif //DLLIST_H