dllist.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** 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 ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : ww3d *
  23. * *
  24. * $Archive:: /Commando/Code/ww3d2/dllist.h $*
  25. * *
  26. * Original Author:: Jani Penttinen *
  27. * *
  28. * $Author:: Jani_p $*
  29. * *
  30. * $Modtime:: 3/21/01 6:18p $*
  31. * *
  32. * $Revision:: 11 $*
  33. * *
  34. *---------------------------------------------------------------------------------------------*
  35. * Functions: *
  36. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  37. #if defined(_MSC_VER)
  38. #pragma once
  39. #endif
  40. #ifndef DLLIST_H
  41. #define DLLIST_H
  42. template <class T> class DLNodeClass;
  43. template <class T>
  44. class DLListClass
  45. {
  46. friend DLNodeClass<T>;
  47. DLNodeClass<T>* head;
  48. DLNodeClass<T>* tail;
  49. public:
  50. DLListClass() : head(0), tail(0) {}
  51. virtual ~DLListClass() { }
  52. void Add_Head(DLNodeClass<T>* node);
  53. void Remove_Head();
  54. void Add_Tail(DLNodeClass<T>* node);
  55. void Remove_Tail();
  56. T* Head() { return static_cast<T*>(head); }
  57. T* Tail() { return static_cast<T*>(tail); }
  58. const T* Const_Head() const { return static_cast<const T*>(head); }
  59. const T* Const_Tail() const { return static_cast<const T*>(tail); }
  60. };
  61. // Destroy-list will call delete for all nodes when the list is destructed. Note that the class doesn't work
  62. // with undeclared pointer types (destructor has to be known).
  63. template <class T>
  64. class DLDestroyListClass : public DLListClass<T>
  65. {
  66. public:
  67. virtual ~DLDestroyListClass()
  68. {
  69. while (T* t=Head()) {
  70. delete t;
  71. }
  72. }
  73. };
  74. template <class T>
  75. class DLNodeClass
  76. {
  77. friend DLListClass<T>;
  78. DLNodeClass<T>* succ;
  79. DLNodeClass<T>* pred;
  80. DLListClass<T>* list;
  81. public:
  82. DLNodeClass() : succ(0), pred(0), list(0) {}
  83. ~DLNodeClass() { Remove(); }
  84. void Insert_Before(DLNodeClass<T>* n)
  85. {
  86. list=n->list;
  87. succ=n;
  88. pred=n->pred;
  89. if (n->pred) n->pred->succ=this;
  90. n->pred=this;
  91. if (list->head==n) {
  92. list->head=this;
  93. }
  94. }
  95. void Insert_After(DLNodeClass<T>* n)
  96. {
  97. list=n->list;
  98. pred=n;
  99. succ=n->succ;
  100. if (n->succ) n->succ->pred=this;
  101. n->succ=this;
  102. if (list->tail==n) {
  103. list->tail=this;
  104. }
  105. }
  106. void Remove()
  107. {
  108. if (!list) return;
  109. if (list->Head()==this) {
  110. DLListClass<T>* tmp_list=list;
  111. list=0;
  112. tmp_list->Remove_Head();
  113. return;
  114. }
  115. if (list->Tail()==this) {
  116. DLListClass<T>* tmp_list=list;
  117. list=0;
  118. tmp_list->Remove_Tail();
  119. return;
  120. }
  121. if (succ) succ->pred=pred;
  122. if (pred) pred->succ=succ;
  123. list=0;
  124. }
  125. T* Succ() { return static_cast<T*>(succ); }
  126. T* Pred() { return static_cast<T*>(pred); }
  127. const T* Const_Succ() const { return static_cast<const T*>(succ); }
  128. const T* Const_Pred() const { return static_cast<const T*>(pred); }
  129. DLListClass<T>* List() { return list; }
  130. };
  131. template <class T>
  132. inline void DLListClass<T>::Add_Head(DLNodeClass<T>* n)
  133. {
  134. n->list=this;
  135. if (head) {
  136. n->Insert_Before(head);
  137. head=n;
  138. }
  139. else {
  140. tail=n;
  141. head=n;
  142. n->succ=0;
  143. n->pred=0;
  144. }
  145. }
  146. template <class T>
  147. inline void DLListClass<T>::Add_Tail(DLNodeClass<T>* n)
  148. {
  149. n->list=this;
  150. if (tail) {
  151. n->Insert_After(tail);
  152. tail=n;
  153. }
  154. else {
  155. tail=n;
  156. head=n;
  157. n->succ=0;
  158. n->pred=0;
  159. }
  160. }
  161. template <class T>
  162. inline void DLListClass<T>::Remove_Head()
  163. {
  164. if (!head) return;
  165. DLNodeClass<T>* n=head;
  166. head=head->Succ();
  167. if (!head) tail=head;
  168. else head->pred=0;
  169. n->Remove();
  170. }
  171. template <class T>
  172. inline void DLListClass<T>::Remove_Tail()
  173. {
  174. if (!tail) return;
  175. DLNodeClass<T>* n=tail;
  176. tail=tail->Pred();
  177. if (!tail) head=tail;
  178. else tail->succ=0;
  179. n->Remove();
  180. }
  181. #endif //DLLIST_H