00001 /* 00002 * xyzzy 00003 * Copyright (C) 2007 Karl W. Pfalzer 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public License 00007 * as published by the Free Software Foundation; either version 2 00008 * of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the 00017 * Free Software Foundation, Inc. 00018 * 51 Franklin Street, Fifth Floor 00019 * Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #if !defined(_xyzzy_slist_hxx_) 00023 # define _xyzzy_slist_hxx_ 00024 00025 namespace xyzzy 00026 { 00027 class TSlist 00028 { 00029 public: 00030 unsigned length() const 00031 { 00032 return m_len; 00033 } 00034 00035 bool isEmpty() const 00036 { 00037 return (0 == m_len); 00038 } 00039 00040 bool hasMore() const 00041 { 00042 return !isEmpty(); 00043 } 00044 00045 protected: 00046 TSlist() 00047 : m_len(0) 00048 {} 00049 00050 virtual ~TSlist() 00051 {} 00052 00053 unsigned m_len; 00054 }; 00055 00056 template<typename T> 00057 class PTSlist : public TSlist 00058 { 00059 public: 00060 PTSlist() 00061 : TSlist(), 00062 mp_head(0), 00063 mp_tail(0) 00064 {} 00065 00066 private: 00067 struct Ele 00068 { 00069 Ele(T dat, Ele *pnext = 0) 00070 : m_dat(dat), mp_next(pnext) 00071 {} 00072 00073 T m_dat; 00074 Ele *mp_next; 00075 }; 00076 00077 public: 00078 T peek() const 00079 { 00080 return mp_head->m_dat; 00081 } 00082 00083 T pop() 00084 { 00085 T rval = peek(); 00086 Ele *p = mp_head; 00087 mp_head = mp_head->mp_next; 00088 if (0 == --m_len) 00089 { 00090 mp_tail = 0; 00091 } 00092 delete p; 00093 return rval; 00094 } 00095 00096 void append(T dat) 00097 { 00098 Ele *p = new Ele(dat); 00099 if (0 != mp_tail) 00100 { 00101 mp_tail->mp_next = p; 00102 mp_tail = p; 00103 } 00104 else 00105 { 00106 mp_head = mp_tail = p; 00107 } 00108 m_len++; 00109 } 00110 00111 void prepend(T dat) 00112 { 00113 Ele *p = new Ele(dat, mp_head); 00114 mp_head = p; 00115 if (0 == mp_tail) 00116 { 00117 mp_tail = p; 00118 } 00119 m_len++; 00120 } 00121 00122 void push(T dat) 00123 { 00124 prepend(dat); 00125 } 00126 00127 ~PTSlist() 00128 { 00129 erase(mp_head); 00130 delete mp_head; 00131 } 00132 00133 private: 00134 Ele *mp_head; 00135 Ele *mp_tail; 00136 00138 void erase(Ele *start) 00139 { 00140 if (0 == start) 00141 { 00142 return; 00143 } 00144 Ele *p, *q = start->mp_next; 00145 while (q != 0) 00146 { 00147 p = q; 00148 q = q->mp_next; 00149 delete p; 00150 m_len--; 00151 } 00152 mp_tail = start; 00153 mp_tail->mp_next = 0; 00154 } 00155 00156 friend class Iterator; 00157 00158 public: 00159 class Iterator 00160 { 00161 public: 00162 Iterator(PTSlist &list) 00163 : mp_curr(list.mp_head) 00164 {} 00165 00166 Iterator(const Iterator &iter) 00167 : mp_curr(iter.mp_curr) 00168 {} 00169 00170 const Iterator& operator=(const Iterator &iter) 00171 { 00172 mp_curr = iter.mp_curr; 00173 return *this; 00174 } 00175 00176 T& operator*() const 00177 { 00178 return mp_curr->m_dat; 00179 } 00180 00181 T* operator->() const 00182 { 00183 return &(operator*()); 00184 } 00185 00186 const Ele* operator()() const 00187 { 00188 return mp_curr; 00189 } 00190 00191 bool hasMore() const 00192 { 00193 return (0 != mp_curr); 00194 } 00195 00196 // pre-incr 00197 Iterator& operator++() 00198 { 00199 incr(); 00200 return *this; 00201 } 00202 00203 // NOTE: post-incr requires copy constructor. 00204 Iterator operator++(int) 00205 { 00206 Iterator rval(*this); 00207 incr(); 00208 return rval; 00209 } 00210 00211 private: 00212 void incr() 00213 { 00214 if (0 != mp_curr) 00215 { 00216 mp_curr = mp_curr->mp_next; 00217 } 00218 } 00219 00221 Iterator(Ele *where) 00222 : mp_curr(where) 00223 {} 00224 00225 Ele *mp_curr; 00226 00227 friend class PTSlist; 00228 }; 00229 00231 void erase(const Iterator &start) 00232 { 00233 erase(start.mp_curr); 00234 } 00235 00236 Iterator last() 00237 { 00238 Iterator rval(mp_tail); 00239 return rval; 00240 } 00241 00243 void insert(Iterator &after, T dat) 00244 { 00245 Ele *q = const_cast<Ele*>(after()); 00246 if (mp_tail == q) 00247 { 00248 append(dat); 00249 } 00250 else 00251 { 00252 Ele *p = new Ele(dat, q->mp_next); 00253 q->mp_next = p; 00254 m_len++; 00255 } 00256 } 00257 }; 00258 }; 00259 00260 #endif //_xyzzy_slist_hxx_