slist.hxx

Go to the documentation of this file.
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_

Generated on Thu Mar 22 13:51:08 2007 for anvil by  doxygen 1.5.1