Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

ListT.H

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta 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 GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 #ifndef ListT_H
00020 #define ListT_H
00021 
00022 /*****************************************************************************
00023 Data types and operations for Lisp-like lists
00024 
00025 This interface provides Lisp-like lists and their most useful
00026 operations.  Why lists?  The list has proven to be an extremely flexible
00027 data structure with many powerful operations and acceptable efficiency
00028 for many, many applications.  Sequences, sets, tables, and other sorts
00029 of mappings can all be implemented easily with lists, often with more
00030 than enough efficiency for the particular application.
00031 *****************************************************************************/
00032 
00033 #include <Basics.H>
00034 
00035 template <class Value>
00036 class PairT {
00037 public:
00038   Value first;
00039   PairT<Value> *tail;
00040   static PairT<Value> *New(const Value& first, PairT<Value> *tail);
00041 };
00042 
00043 template <class Value>
00044 class ListT {
00045 private:
00046   PairT<Value> *list;
00047   PairT<Value> *last;
00048 
00049 public:
00050   ListT() : list(NULL), last(NULL) { /*SKIP*/ };
00051   ListT(const Value& x1);
00052   ListT(const Value& x1, const Value& x2);
00053   ListT(const Value& x1, const Value& x2, const Value& x3); 
00054     /*
00055     Constructors for convenience:
00056         List()            = NIL
00057         ListT(x1)         = New(x1, NIL)
00058         ListT(x1, x2)     = New(x1, New(x2, NIL)) 
00059         ListT(x1, x2, x3) = New(x1, New(x2, New(x3, NIL))) 
00060     */
00061 
00062   ListT(const Value& first, const ListT<Value>& tail);
00063     /* Constructs a new list cell (Lisp CONS). */
00064 
00065   ListT<Value>& operator=(const ListT<Value>& lst);
00066     /* list assignment */
00067 
00068   bool operator==(const ListT<Value>& lst);
00069     /* list equality */
00070 
00071   bool operator!=(const ListT<Value>& lst);
00072     /* list inequality */
00073 
00074   bool Null() const { return (list == NULL); };
00075     /* Return false if there is at least one element on the list. */
00076 
00077   void SetEmpty() { list = NULL; last = NULL; };
00078     /* Set the list to be empty. */
00079 
00080   void Push(const Value& x);  
00081     /*
00082     Pushes a new element onto the front of "lst", and sets "lst" to be 
00083     the new list.  Equivalent to:
00084     
00085         lst := New( x, lst );
00086     */
00087 
00088   Value Pop();
00089     /*
00090     Removes one element from the front of "lst", and sets "lst" to the 
00091     new list.   Equivalent to:
00092         result := lst^.first
00093         l      := lst^.tail;
00094     */
00095 
00096   int Length() const;
00097     /* Returns the length of a list. */
00098 
00099   Value First() { return list->first; };
00100   Value Second() { return list->tail->first; };
00101   Value Third() { return list->tail->tail->first; };
00102     /* Procedural accessors of list elements. */
00103 
00104   ListT<Value> Tail();
00105     /* returns the tail of "lst". */
00106 
00107   Value Nth(int n) const;
00108     /*
00109     The nth element of a list;  n=0 gets the first element.   Undefined
00110     if n < 0 or n >= Length( lst ). */
00111 
00112   void SetNth(int n, const Value& x);
00113    /*
00114    Destructively changes the nth element of a list to be x.  Undefined
00115    if n < 0 or n >= Length( lst ). */
00116 
00117   ListT<Value> NthTail(int n);
00118    /*
00119    The result of applying Tail to lst n times. Undefined if n < 0 or 
00120    n >= Length( lst ). */
00121 
00122   void SetNthTail(int n, const ListT<Value>& x);
00123    /*
00124    Destructively changes the nth tail of a list to be x.  Undefined
00125    if n < 0 or n >= Length( lst ). */
00126 
00127   Value Last() { return last->first; };
00128    /*
00129    The last element of lst, equivalent to Nth( lst, Length( lst ) - 1 ). 
00130    */
00131 
00132   ListT<Value> LastTail();
00133    /*
00134    The last tail of lst, equivalent to NthTail( lst, Length( lst ) - 1 ). 
00135    */
00136 
00137   ListT<Value> FirstN(int n);
00138    /*
00139    A new list consisting of the first n elements of lst.  Undefined if 
00140    n < 0 or n > Length( lst ). */
00141 
00142   bool EqualQ(const ListT<Value>& x);
00143    /*
00144    Compares two objects for equality.
00145 
00146    Equal is isomorphic structure comparison in which two lists are
00147    equal if their elements are '=='.
00148 
00149    EqualQ is pointer equality (Lisp EQ or Modula-2 "=").  It is
00150    included for consistency and application; normally "=" should be
00151    used instead. */
00152 
00153   bool Member(const Value& x) const;
00154     /*
00155     Returns true if for some y at the top level of list lst, y = x;
00156     returns false otherwise.  Member tests equality using ==. */
00157 
00158   ListT<Value> Append(const ListT<Value>& l2) const;
00159   ListT<Value> AppendD(const ListT<Value>& l2);
00160     /*
00161     Appends two lists together, returning the new list.  AppendD doesn't
00162     create any new list cells, but it destroys its first argument. */
00163 
00164   ListT<Value> Append1(const Value& x);
00165   ListT<Value> Append1D(const Value& x);
00166     /*
00167     Appends an element onto the end of a list, returning the new list. */
00168 
00169   ListT<Value> Copy();
00170     /*
00171     Copy returns a copy of a list, where only the top level of the list is
00172     copied (the elements are not copied). */
00173 
00174   ListT<Value> Reverse();
00175   ListT<Value> ReverseD();
00176     /* Reverses a list. */
00177 };
00178 
00179 // ----------------------------------------------------------------------
00180 // Template method definitions
00181 // ----------------------------------------------------------------------
00182 
00183 template <class Value>
00184 PairT<Value> *PairT<Value>::New(const Value& first, PairT<Value> *tail) {
00185   PairT<Value> *result;
00186 
00187   result = NEW(PairT<Value>);
00188   result->first = first;
00189   result->tail = tail;
00190   return result;
00191 }
00192 
00193 template <class Value>
00194 ListT<Value>& ListT<Value>::operator=(const ListT<Value>& lst) {
00195   if (this == &lst) return *this;
00196   list = lst.list;
00197   last = lst.last;
00198   return *this;
00199 }
00200 
00201 template <class Value>
00202 ListT<Value>::ListT(const Value& x) {
00203   list = PairT<Value>::New(x, NULL);
00204   last = list;
00205 }
00206 
00207 template <class Value>
00208 ListT<Value>::ListT(const Value& x1, const Value& x2) {
00209   PairT<Value> *l;
00210 
00211   l       = PairT<Value>::New(x1, NULL); list = l;
00212   l->tail = PairT<Value>::New(x2, NULL); last = l->tail;
00213 }
00214 
00215 template <class Value>
00216 ListT<Value>::ListT(const Value& x1, const Value& x2, const Value& x3) {
00217   PairT<Value> *l;
00218 
00219   l       = PairT<Value>::New(x1, NULL); list = l;
00220   l->tail = PairT<Value>::New(x2, NULL); l    = l->tail;
00221   l->tail = PairT<Value>::New(x3, NULL); last = l->tail;
00222 }
00223 
00224 template <class Value>
00225 ListT<Value>::ListT(const Value& first, const ListT<Value>& tail) {
00226     list = PairT<Value>::New(first, tail.list);
00227     last = (tail.last) ? tail.last : list;
00228 }
00229 
00230 template <class Value>
00231 bool ListT<Value>::operator==(const ListT<Value>& l) {
00232   PairT<Value> *rest1, *rest2;
00233   
00234   if (this == &l) return true;
00235   rest1 = list;
00236   rest2 = l.list;
00237   while (true) {
00238     if (rest1 == NULL)
00239       return (rest2 == NULL);
00240     else if (rest2 == NULL)
00241        return false;
00242     if (rest1->first != rest2->first)
00243       return false;
00244     else
00245       rest1 = rest1->tail;
00246       rest2 = rest2->tail;
00247   }
00248 }
00249 
00250 template <class Value>
00251 bool ListT<Value>::operator!=(const ListT<Value>& l) {
00252   return (!(*this == l));
00253 }
00254 
00255 template <class Value>
00256 void ListT<Value>::Push(const Value& x) {
00257   *this = ListT<Value>(x, *this);
00258 }
00259 
00260 template <class Value>
00261 Value ListT<Value>::Pop() {
00262   Value x;
00263 
00264   x = list->first;
00265   list = list->tail;
00266   if (!list) last = NULL;
00267   return x;
00268 }
00269 
00270 template <class Value>
00271 int ListT<Value>::Length() const {
00272   int len = 0;
00273   PairT<Value> *rest = list;
00274 
00275   while (rest) {
00276     rest = rest->tail;
00277     len++;
00278   }
00279   return len;
00280 }
00281 
00282 template <class Value>
00283 ListT<Value> ListT<Value>::Tail() {
00284   ListT<Value> result;
00285   
00286   result.list = list->tail;
00287   result.last = (result.list) ? last : NULL;
00288   return result;
00289 }
00290 
00291 template <class Value>
00292 Value ListT<Value>::Nth(int n) const {
00293   int i = 0;
00294   PairT<Value> *rest = list;
00295 
00296   while (i++ < n)
00297     {
00298       assert(rest != 0);
00299       rest = rest->tail;
00300     }
00301   return rest->first;
00302 }
00303 
00304 template <class Value>
00305 void ListT<Value>::SetNth(int n, const Value& x) {
00306   PairT<Value> *rest = list;
00307 
00308   while (n-- > 0)
00309     {
00310       assert(rest != 0);
00311       rest = rest->tail;
00312     }
00313   rest->first = x;
00314 }
00315 
00316 template <class Value>
00317 ListT<Value> ListT<Value>::NthTail(int n) {
00318   int i = 0; 
00319   PairT<Value> *rest = list;
00320   ListT<Value> result;
00321 
00322   while (i++ < n)
00323     {
00324       assert(rest != 0);
00325       rest = rest->tail;
00326     }
00327   result.list = rest;
00328   result.last = (result.list) ? last : NULL;
00329   return result;
00330 }
00331 
00332 template <class Value>
00333 void ListT<Value>::SetNthTail(int n, const ListT<Value>& x) {
00334   PairT<Value> *rest = list;
00335 
00336   while (n-- > 0)
00337     {
00338       assert(rest != 0);
00339       rest = rest->tail;
00340     }
00341   rest->tail = x.list;
00342   last = (x.last) ? x.last : rest;
00343 }
00344 
00345 template <class Value>
00346 ListT<Value> ListT<Value>::LastTail() {
00347   PairT<Value> *rest = list;
00348   ListT<Value> result;
00349 
00350   if (rest == NULL) return result;
00351   while (rest->tail) rest = rest->tail;
00352   result.list = rest;
00353   result.last = rest;
00354   return result;
00355 }
00356 
00357 template <class Value>
00358 ListT<Value> ListT<Value>::FirstN(int n) {
00359   ListT<Value> result;
00360   PairT<Value> *rest, *resultEnd;
00361 
00362   if (n <= 0) return result;
00363   resultEnd = PairT<Value>::New(list->first, NULL);
00364   result.list = resultEnd;
00365   rest = list->tail;
00366   int i = 1;
00367   while (i++ < n) {
00368     assert(rest != 0);
00369     resultEnd->tail = PairT<Value>::New(rest->first, NULL);
00370     resultEnd = resultEnd->tail;
00371     rest = rest->tail;
00372   }
00373   return result;
00374 }
00375 
00376 template <class Value>
00377 bool ListT<Value>::EqualQ(const ListT<Value>& x) {
00378   return (list == x.list);
00379 }
00380 
00381 template <class Value>
00382 bool ListT<Value>::Member(const Value& x) const {
00383   PairT<Value> *rest = list;
00384 
00385   while (rest) {
00386     if (rest->first == x) return true;
00387     rest = rest->tail;
00388   }
00389   return false;
00390 }
00391 
00392 template <class Value>
00393 ListT<Value> ListT<Value>::Append(const ListT<Value>& l2) const {
00394   ListT<Value> result;
00395   PairT<Value> *rest, *end;
00396 
00397   if (list == NULL) return l2;
00398   if (l2.list == NULL) return *this;
00399 
00400   result = ListT<Value>(list->first);
00401   end = result.list;
00402   rest = list->tail;
00403   while (rest) {
00404     end->tail = PairT<Value>::New(rest->first, NULL);
00405     end = end->tail;
00406     rest = rest->tail;
00407   }
00408   end->tail = l2.list;
00409   result.last = l2.last;
00410 
00411   return result;
00412 }
00413 
00414 template <class Value>
00415 ListT<Value> ListT<Value>::AppendD(const ListT<Value>& l2) {
00416   if (l2.list == NULL) return *this;
00417   if (list == NULL) {
00418     list = l2.list;
00419     last = l2.last;
00420   }
00421   else {
00422     last->tail = l2.list;
00423     last = l2.last;
00424   }
00425   return *this;
00426 }
00427 
00428 template <class Value>
00429 ListT<Value> ListT<Value>::Append1(const Value& x) {
00430   ListT<Value> result;
00431   PairT<Value> *rest, *end;
00432 
00433   if (list == NULL) return ListT<Value>(x);
00434   result = ListT<Value>(list->first);
00435   end = result.list;
00436   rest = list->tail;
00437   while (rest) {
00438     end->tail = PairT<Value>::New(rest->first, NULL);
00439     end = end->tail;
00440     rest = rest->tail;
00441   }
00442   end->tail = PairT<Value>::New(x, NULL);
00443   result.last = end->tail;
00444 
00445   return result;
00446 }
00447 
00448 template <class Value>
00449 ListT<Value> ListT<Value>::Append1D(const Value& x) {
00450   if (list == NULL) {
00451     list = PairT<Value>::New(x, NULL);
00452     last = list;
00453   }
00454   else {
00455     last->tail = PairT<Value>::New(x, NULL);
00456     last = last->tail;
00457   }
00458   return *this;
00459 }
00460 
00461 template <class Value>
00462 ListT<Value> ListT<Value>::Copy() {
00463   ListT<Value> result;
00464   PairT<Value> *end, *rest;
00465 
00466   if (list == NULL) return *this;
00467   result = ListT<Value>(list->first);
00468   end = result.list;
00469   rest = list->tail;
00470   while (rest) {
00471     end->tail = PairT<Value>::New(rest->first, NULL);
00472     end = end->tail;
00473     rest = rest->tail;
00474   }
00475   result.last = end;
00476   return result;
00477 }
00478 
00479 template <class Value>
00480 ListT<Value> ListT<Value>::Reverse() {
00481   ListT<Value> result;
00482   PairT<Value> *rest;
00483 
00484   rest = list;
00485   while (rest != NULL) {
00486     result.list = PairT<Value>::New(rest->first, result.list);
00487     rest = rest->tail;
00488   }
00489   result.last = list;
00490   return result;
00491 }
00492 
00493 template <class Value>
00494 ListT<Value> ListT<Value>::ReverseD() {
00495   PairT<Value> *current, *next, *nextTail;  
00496   ListT<Value> result;
00497 
00498   if (list == NULL) return *this;
00499   current = list;
00500   next = list->tail;
00501   current->tail = NULL;
00502   while (next) {
00503     nextTail = next->tail;
00504     next->tail = current;
00505     current = next;
00506     next = nextTail;
00507   }
00508   result.list = current;
00509   result.last = list;
00510   return result;
00511 }
00512 
00513 #endif /* ListT_H */

Generated on Mon May 8 00:48:38 2006 for Vesta by  doxygen 1.4.2