00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 // This code is really -*- c++ -*- 00037 00038 #ifndef CXX_QUEUE_INCLUDED 00039 #define CXX_QUEUE_INCLUDED "cxx_queue.h" 00040 00041 template <class ITEM_TYPE> 00042 class QUEUE_NODE { 00043 private: 00044 ITEM_TYPE _queue_item; 00045 QUEUE_NODE *_queue_next; 00046 00047 public: 00048 ITEM_TYPE Qnode_Item() { 00049 return _queue_item; 00050 } 00051 QUEUE_NODE *Qnode_Next() { 00052 return _queue_next; 00053 } 00054 void Qnode_Next(QUEUE_NODE *n) { 00055 _queue_next = n; 00056 } 00057 QUEUE_NODE(ITEM_TYPE item) { 00058 _queue_item = item; 00059 _queue_next = NULL; 00060 } 00061 }; 00062 00063 template<class ITEM_TYPE> 00064 class QUEUE { 00065 private: 00066 MEM_POOL *_pool; 00067 UINT32 _length; 00068 QUEUE_NODE<ITEM_TYPE> *_first; 00069 QUEUE_NODE<ITEM_TYPE> *_last; 00070 public: 00071 QUEUE_NODE<ITEM_TYPE> *Queue_First() const{ 00072 return _first; 00073 } 00074 QUEUE_NODE<ITEM_TYPE> *Queue_Last() const{ 00075 return _last; 00076 } 00077 UINT32 Queue_Length() const{ 00078 return _length; 00079 } 00080 BOOL Queue_Isempty() { 00081 return (0 == _length); 00082 } 00083 // A constructor 00084 QUEUE<ITEM_TYPE> (MEM_POOL *pool); 00085 void Add_Tail_Q (ITEM_TYPE); 00086 ITEM_TYPE Get_Q (); 00087 ITEM_TYPE Get_Tail_Q(); 00088 INT32 Index(ITEM_TYPE item, BOOL Insert_If_Absent=FALSE); 00089 }; 00090 00091 template <class ITEM_TYPE> 00092 class QUEUE_ITER { 00093 private: 00094 QUEUE_NODE<ITEM_TYPE> *_node; 00095 const QUEUE<ITEM_TYPE> *_q; 00096 public: 00097 BOOL Step (ITEM_TYPE *i) { 00098 if (NULL == _node) 00099 return FALSE; 00100 else { 00101 *i = _node->Qnode_Item(); 00102 _node = _node->Qnode_Next(); 00103 return TRUE; 00104 } 00105 } 00106 QUEUE_ITER (const QUEUE<ITEM_TYPE> *q) : _q (q) { 00107 _node = q->Queue_First(); 00108 } 00109 }; 00110 00111 /* A wklist q is different from an ordinary q in that it is mutable. 00112 Essentially, it exports the queue underneath it, so that an outer 00113 level of the iterator can modify it. */ 00114 00115 template<class ITEM_TYPE> 00116 class QUEUE_WKLIST_ITER { 00117 private: 00118 QUEUE_NODE<ITEM_TYPE> *_node; 00119 QUEUE<ITEM_TYPE> *_q; 00120 MEM_POOL *_pool; 00121 public: 00122 QUEUE<ITEM_TYPE> *Wklist_Queue() { 00123 return _q; 00124 } 00125 BOOL Step(ITEM_TYPE *i) { 00126 assert (NULL != _q); 00127 if (0 == _q->Queue_Length()) 00128 return FALSE; 00129 else { 00130 *i = _q->Get_Q(); 00131 return TRUE; 00132 } 00133 } 00134 QUEUE_WKLIST_ITER (const ITEM_TYPE i, MEM_POOL *pool) { 00135 _pool = pool; 00136 _q = CXX_NEW (QUEUE<ITEM_TYPE>(pool), pool); 00137 _q->Add_Tail_Q (i); 00138 } 00139 }; 00140 00141 #ifdef __GNUC__ 00142 // Implementation stuff included here because g++ 00143 // (rightly) doesn't do implicit .cxx file inclusion. 00144 00145 template <class ITEM_TYPE> 00146 QUEUE<ITEM_TYPE>::QUEUE (MEM_POOL *pool) 00147 { 00148 _pool = pool; 00149 _length = 0; 00150 _first = _last = NULL; 00151 } 00152 00153 template <class ITEM_TYPE> 00154 void 00155 QUEUE<ITEM_TYPE>::Add_Tail_Q(ITEM_TYPE item) 00156 { 00157 QUEUE_NODE<ITEM_TYPE> *node; 00158 00159 node = CXX_NEW (QUEUE_NODE<ITEM_TYPE>(item), _pool); 00160 if (0 == _length) 00161 _first = _last = node; 00162 else { 00163 _last->Qnode_Next(node); 00164 _last = node; 00165 } 00166 _length++; 00167 return; 00168 } 00169 00170 template<class ITEM_TYPE> 00171 ITEM_TYPE 00172 QUEUE<ITEM_TYPE>::Get_Q () 00173 { 00174 ITEM_TYPE item; 00175 QUEUE_NODE<ITEM_TYPE> *node; 00176 00177 if (0 == _length) 00178 return (ITEM_TYPE) 0; 00179 node = _first; 00180 item = node->Qnode_Item(); 00181 /* Remove node from queue */ 00182 _first = node->Qnode_Next(); 00183 _length--; 00184 if (0 == _length) 00185 _last = NULL; 00186 return item; 00187 } 00188 00189 template<class ITEM_TYPE> 00190 ITEM_TYPE 00191 QUEUE<ITEM_TYPE>::Get_Tail_Q () 00192 { 00193 ITEM_TYPE item; 00194 QUEUE_NODE<ITEM_TYPE> *node; 00195 INT32 count, i; 00196 00197 if (0 == _length) 00198 return (ITEM_TYPE) 0; 00199 else if (1 == _length) 00200 return this->Get_Q(); 00201 else { 00202 count = _length - 2; 00203 node = _first; 00204 for (i = 0; i < count; i++) { 00205 node = node->Qnode_Next(); 00206 } 00207 assert (node->Qnode_Next() == _last); 00208 item = _last->Qnode_Item(); 00209 node->Qnode_Next(NULL); 00210 _length--; 00211 _last = node; 00212 return item; 00213 } 00214 } 00215 00216 template<class ITEM_TYPE> 00217 INT32 00218 QUEUE<ITEM_TYPE>::Index(ITEM_TYPE item, BOOL Insert_If_Absent) 00219 { 00220 INT32 ret_val = 0; 00221 QUEUE_NODE<ITEM_TYPE> *node = _first; 00222 while (NULL != node) { 00223 if (node->Qnode_Item() == item) 00224 return ret_val; 00225 node = node->Qnode_Next(); 00226 ret_val++; 00227 } 00228 FmtAssert (ret_val == _length, ("Inconsistency in queue index function")); 00229 if (Insert_If_Absent) { 00230 this->Add_Tail_Q (item); 00231 return ret_val; 00232 } 00233 else 00234 return -1; 00235 } 00236 00237 #endif 00238 00239 #endif
1.5.6