slist.hpp

Go to the documentation of this file.
00001 /* Copyright 1994-96, LongView Technologies L.L.C. $Revision: 1.7 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 // Yet another version of lists, this one allowing efficient insert/delete in the middle.
00025 
00026 # ifdef DELTA_COMPILER
00027   
00028 class GenericSListElem : public ResourceObj  {
00029  protected:
00030   void* _data;
00031   GenericSListElem*  _next;
00032  public: 
00033   GenericSListElem(void* d, GenericSListElem* n = NULL) { _data = d; _next = n; }
00034   
00035   void* dataL() const                   { return this ? _data : NULL; }
00036   void setDataL(void* d)                { _data = d; }
00037   
00038   GenericSListElem* nextL() const       { return _next; }
00039   void setNextL(GenericSListElem* n)    { _next = n; }
00040 
00041  protected:
00042   void insertAfterL(void* d)            { _next = new GenericSListElem(d, _next); }
00043   
00044   friend class GenericSList;
00045 };
00046 
00047 typedef bool (*slistFindFn)(void* token, void* elem);
00048 
00049 class GenericSList : public PrintableResourceObj {
00050  protected:
00051   GenericSListElem* _head;
00052   GenericSListElem* _tail;
00053   int _len;
00054  public:
00055   GenericSList() { _head = _tail = NULL; _len = 0; }
00056   
00057   void prependL(void* d) {
00058     _head = new GenericSListElem(d, _head);
00059     if (_tail == NULL) _tail = _head;
00060     _len++;
00061   }
00062   void appendL(void* d) {
00063     GenericSListElem* e = new GenericSListElem(d);
00064     if (_tail == NULL) {
00065       _head = _tail = e;
00066     } else {
00067       _tail->_next = e;
00068       _tail = e;
00069     }
00070     _len++;
00071   }
00072   
00073   GenericSListElem* headL() const               { return _head; }
00074   GenericSListElem* tailL() const               { return _tail; }
00075   
00076   void applyL(void f(void*));
00077   
00078   bool isEmpty() const                          { return _head == NULL; }
00079   bool nonEmpty() const                         { return ! isEmpty(); }
00080   int length() const                            { return _len; }
00081   bool includesL(void* p) const                 { return findL(p) != NULL; }
00082   GenericSListElem* findL(void* p) const;
00083   GenericSListElem* findL(void* p, slistFindFn f) const;
00084   
00085   void* nthL(int i) const;
00086   
00087   void* firstL() const                          { return headL()->dataL(); }
00088   void* secondL() const                         { return headL()->nextL()->dataL(); }
00089   void* lastL() const                           { return tailL()->dataL(); }
00090   
00091   void insertAfterL(GenericSListElem* e, void* d);
00092   void removeL(void* d);
00093   void removeAfterL(GenericSListElem* e);
00094   
00095  protected:
00096   void* removeHeadL() {
00097     assert(nonEmpty(), "removing from an empty list");
00098     void* d = firstL();
00099     _head = headL()->nextL();
00100     if (--_len == 0) _tail = _head;
00101     return d; }
00102   
00103  public:
00104   void pushL(void* d)                           { prependL(d); }
00105   void* popL()                                  { return removeHeadL(); }
00106   
00107   void print();
00108   void print_short();
00109 };
00110 
00111 
00112 template <class T> class SListElem : public GenericSListElem {
00113  public:
00114   SListElem(T d, SListElem<T>* n = NULL) : GenericSListElem((void*) d, (GenericSListElem*) n) {}                                      \
00115 
00116   T data() const                { return (T)GenericSListElem::dataL(); }
00117   void setData(T d)             { GenericSListElem::setDataL((void*) d); }
00118   SListElem<T>* next() const    { return (SListElem<T>*) GenericSListElem::nextL(); }
00119   void setNext(SListElem<T>* n) { GenericSListElem::setNextL(n); }
00120   void insertAfter(T d)         { GenericSListElem::insertAfterL((void*) d); }
00121 };
00122 
00123 template <class T> class SList : public GenericSList {
00124  public:
00125   SList() {}
00126 
00127   SListElem<T>* head() const    { return (SListElem<T>*) GenericSList::headL(); }
00128   SListElem<T>* tail() const    { return (SListElem<T>*) GenericSList::tailL(); }
00129   bool includes(T e) const      { return GenericSList::includesL((void*)e); } 
00130   SListElem<T>* find(T e) const { return (SListElem<T>*)GenericSList::findL((void*)e); }
00131   SListElem<T>* find(void* token, slistFindFn f) const {
00132                                   return (SListElem<T>*)GenericSList::findL(token, (slistFindFn)f); } 
00133                                                                             
00134   T first() const               { return (T) GenericSList::firstL(); }
00135   T second() const              { return (T) GenericSList::secondL(); }
00136   T at(int i) const             { return (T) GenericSList::nthL(i); }
00137   T last() const                { return (T) GenericSList::lastL(); }
00138                                                                             
00139   void prepend(T d)             { GenericSList::prependL((void*) d); }
00140   void append(T d)              { GenericSList::appendL((void*) d); }
00141   void apply(void f(T))         { GenericSList::applyL((void (*)(void*))f); }
00142   void insertAfter(SListElem<T>* e, T d) { GenericSList::insertAfterL((SListElem<T>*) e, (void*) d); }
00143   void removeAfter(SListElem<T>* e, T d) { GenericSList::removeAfterL((SListElem<T>*) e); }
00144   void remove(T d)              { GenericSList::removeL((void*) d); }
00145   T removeHead()                { return (T) GenericSList::removeHeadL(); }
00146   void push(T d)                { GenericSList::pushL((void*) d); }
00147   T pop()                       { return (T) GenericSList::popL(); }
00148   void apply(Closure<T>* c)     { 
00149     SListElem<T>* nexte;        // to permit removing during iteration
00150     for (SListElem<T>* e = head(); e; e = nexte) { nexte = e->next(); c->do_it(e->data()); }
00151   }
00152 };
00153 
00154 # endif

Generated on Mon Oct 9 13:37:27 2006 for Strongtalk VM by  doxygen 1.4.7