Main Page | Namespace List | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

Lst.hpp

Go to the documentation of this file.
00001 
00027 //
00028 //  file Lst.hpp
00029 //  defines class Lst
00030 //
00031 
00032 #ifndef __Lst__
00033 #define __Lst__
00034 
00035 #include "assert.hpp"
00036 
00037 template <class C> class LstData;
00038 
00039 
00040 template <class C>
00041 class Lst 
00042 {
00043  public:
00044   // constructors
00045   Lst ();
00046   Lst (const Lst&);
00047   Lst (const C& head, const Lst& tail);
00048   explicit Lst (const C& t); // one-element list
00049   explicit Lst (LstData<C>*);
00050   ~Lst ();
00051   void operator = (const Lst& rhs);
00052 
00053   // declared but not defined, to prevent on-heap allocation
00054   // void* operator new (size_t);
00055   void append (const Lst&);
00056 
00057   // structure
00058   bool isEmpty () const;
00059   bool isNonEmpty () const;
00060   const C& head () const;
00061   const C& second () const;
00062   const Lst& tail () const;
00063   void pop ();
00064   bool operator == (const Lst& rhs) const;
00065   void makeEmpty ();
00066 
00067   // miscellaneous
00068   int length () const;
00069   bool member (const C elem) const;
00070   void push (C elem);
00071   void reverse (Lst& result) const;
00072   void reverse (Lst& result, const Lst& appendTo) const;
00073   void copy (Lst& to) const;
00074 
00075  protected:
00076   // structure
00077   LstData<C>* _data;
00078 }; // class Lst
00079 
00080 
00081 // this class was inside Lst but VC++ had not enough intelligence to compile it
00082 template <class C>
00083 class LstData 
00084 {
00085  public:
00086   LstData ();
00087 
00088   inline LstData (const C& t, const Lst<C>& ts)
00089     :
00090     _counter (1),
00091     _head (t),
00092     _tail (ts)
00093         {
00094       TRACER( "LstData::LstData" );
00095         } // LstData::LstData
00096 
00097   inline explicit LstData (const C& t)
00098     :
00099     _counter (1),
00100     _head (t),
00101     _tail ((LstData<C>*)0)
00102         {
00103           TRACER( "LstData::LstData" );
00104         } // LstData::LstData
00105 
00106   inline ~LstData ()
00107         {
00108           TRACER( "LstData::~LstData" );
00109 
00110           ASS (_counter == 0);
00111   } // LstData::~LstData
00112 
00113   inline void ref ()
00114     { 
00115       ASS (this);
00116 
00117       _counter++;
00118     } // LstData::ref ()
00119 
00120 
00121   inline void deref ()
00122   { 
00123     ASS (this);
00124     ASS (_counter > 0);
00125 
00126     _counter--;
00127     if (_counter == 0) {
00128       delete this;
00129     }
00130   } // LstData::deref ()
00131 
00132   inline const C& head () const
00133   { 
00134     ASS (this);
00135     ASS (_counter > 0);
00136 
00137     return _head; 
00138   } // LstData::head
00139 
00140   inline const Lst<C>& tail () const
00141   { 
00142     ASS (this);
00143     ASS (_counter > 0);
00144 
00145     return _tail;
00146   } // LstData::tail
00147 
00148  private:
00149   // structure
00150   unsigned _counter;
00151   C _head;
00152   Lst<C> _tail;
00153 }; // LstData
00154 
00155 
00156 // this class was Lst::Iterator but there was no way for VC++ to
00157 // compile it
00158 template <class C>
00159 class Iterator
00160 {
00161  public: 
00162   inline explicit Iterator (const Lst<C>& lst)
00163     : 
00164     _list (lst) 
00165   {
00166   } // Iterator::Iterator
00167 
00168   inline bool more () const
00169   { 
00170     return _list.isNonEmpty(); 
00171   } // Iterator::more ()
00172 
00173   inline C next ()
00174   {
00175     ASS( more() );
00176 
00177     C result (_list.head());
00178     _list.pop ();
00179   
00180     return result;
00181   } // Iterator::next
00182 
00183   inline void reset (const Lst<C>& lst)
00184   {
00185     _list = lst;
00186   } // Iterator::reset
00187 
00188  private:
00189   Lst<C> _list;
00190 }; // class Iterator
00191 
00192 
00193 // ******************* Lst definitions ************************
00194 
00195 template <class C>
00196 inline
00197 Lst<C>::Lst () 
00198   : 
00199   _data (0) 
00200 {
00201 } // Lst::Lst
00202 
00203 
00204 template <class C>
00205 inline
00206 Lst<C>::~Lst () 
00207 {
00208   if (_data) {
00209     _data->deref ();
00210   }
00211 } // Lst::~Lst
00212 
00213 
00214 // copy constructor
00215 // 25/08/2002 Torrevieja
00216 template <class C>
00217 inline
00218 Lst<C>::Lst (const Lst& ts)
00219   :
00220   _data (ts._data)
00221 {
00222   if (_data) {
00223     _data->ref ();
00224   }
00225 } // Lst::Lst
00226 
00227 
00228 // almost a copy constructor
00229 // 25/08/2002 Torrevieja
00230 template <class C>
00231 inline
00232 Lst<C>::Lst (LstData<C>* d)
00233   :
00234   _data (d)
00235 {
00236   if (d) {
00237     d->ref ();
00238   }
00239 } // Lst::Lst
00240 
00241 
00242 // 'cons' list constructor
00243 // 25/08/2002 Torrevieja
00244 template <class C>
00245 inline
00246 Lst<C>::Lst (const C &hd, const Lst& tl)
00247   :
00248   _data (new LstData<C> (hd,tl))
00249 {
00250 } // Lst::Lst
00251 
00252 
00253 // 'cons' list constructor
00254 // 25/08/2002 Torrevieja
00255 template <class C>
00256 inline
00257 Lst<C>::Lst (const C &hd)
00258   :
00259   _data (new LstData<C> (hd))
00260 {
00261 } // Lst::Lst
00262 
00263 
00264 template <class C>
00265 inline
00266 bool Lst<C>::operator == (const Lst& rhs) const
00267 { 
00268   return _data == rhs._data; 
00269 } // Lst::operator == (const Lst& rhs) const
00270 
00271 
00272 template <class C>
00273 inline
00274 bool Lst<C>::isEmpty () const 
00275 { 
00276   return _data == 0; 
00277 } // Lst::isEmpty ()
00278 
00279 
00280 template <class C>
00281 inline
00282 bool Lst<C>::isNonEmpty () const 
00283 { 
00284   return _data != 0; 
00285 } // Lst::isNonEmpty ()
00286 
00287 
00288 template <class C>
00289 inline
00290 const C& Lst<C>::head () const 
00291 { 
00292   return _data->head (); 
00293 } // Lst::head
00294 
00295 
00296 template <class C>
00297 inline
00298 const C& Lst<C>::second () const 
00299 { 
00300   return _data->tail().head(); 
00301 }
00302 
00303 
00304 template <class C>
00305 inline
00306 const Lst<C>& Lst<C>::tail () const 
00307 { 
00308   return _data->tail(); 
00309 }
00310 
00311 
00312 // pop a list
00313 // 25/08/2002 Torrevieja
00314 // 04/05/2003 Manchester changed simply *this = tail () (caused errors???)
00315 template <class C>
00316 void Lst<C>::pop ()
00317 {
00318   ASS (_data);
00319 
00320   LstData<C>* dtl = tail()._data;
00321   if (! dtl) {
00322     _data->deref();
00323     _data = 0;
00324     return;
00325   }
00326 
00327   dtl->ref ();
00328   _data->deref ();
00329   _data = dtl;
00330   //  *this = tail ();
00331 } // Lst::pop
00332 
00333 
00334 // C is a member of the list
00335 // 05/09/2002 Bolzano
00336 template <class C>
00337 bool Lst<C>::member (const C elem) const
00338 {
00339   Iterator<C> it (*this);
00340   while (it.more()) {
00341     if (it.next() == elem) {
00342       return true;
00343     }
00344   }
00345 
00346   return false;
00347 } // Lst::member
00348 
00349 
00350 template <class C>
00351 inline
00352 void Lst<C>::push (C elem)
00353 {
00354   *this = Lst (elem,*this);
00355 } // Lst::push
00356 
00357 
00358 template <class C>
00359 inline
00360 void Lst<C>::makeEmpty ()
00361 {
00362   if (_data) {
00363     _data->deref ();
00364     _data = 0;
00365   }
00366 } // Lst::makeEmpty 
00367 
00368 
00369 template <class C>
00370 void Lst<C>::operator = (const Lst& t)
00371 {
00372   if (t._data) {
00373     t._data->ref ();
00374   }
00375 
00376   if (_data) {
00377     _data->deref ();
00378   }
00379 
00380   _data = t._data;
00381 } // Lst::operator=
00382 
00383 
00384 // list append
00385 // 30/08/2002 Torrevieja, not the fastest implementation,
00386 //  can be made tail-recursive
00387 // 14/04/2003 Torrevieja, type of to changed to reference
00388 template <class C>
00389 void Lst<C>::append (const Lst& to)
00390 {
00391   if (isEmpty()) {
00392     *this = to;
00393     return;
00394   }
00395 
00396   Lst tl (tail());
00397   tl.append (to);
00398   *this = Lst (head(),tl);
00399 } // Lst::append
00400 
00401 
00402 // list length
00403 // 30/08/2002 Torrevieja, copied from TermList
00404 template <class C>
00405 int Lst<C>::length () const
00406 {
00407   int len = 0;
00408 
00409   for (LstData<C>* d = _data; d; d = d->tail()._data) {
00410     len ++;
00411   }
00412 
00413   return len;
00414 } // Lst::length
00415 
00416 
00417 // list reverse
00418 // 14/04/2003 Torrevieja
00419 template <class C>
00420 void Lst<C>::reverse (Lst& result, const Lst& appendTo) const
00421 {
00422   TRACER("LST::reverse/3");
00423 
00424   Lst rev (appendTo);
00425 
00426   Iterator<C> it (*this);
00427   while (it.more()) {
00428     rev.push (it.next());
00429   }
00430 
00431   result = rev;
00432 } // Lst::reverse
00433 
00434 
00435 // list reverse
00436 // 15/04/2003 Torrevieja
00437 template <class C>
00438 inline
00439 void Lst<C>::reverse (Lst& result) const
00440 {
00441   TRACER("LST::reverse/2");
00442 
00443   Lst empty;
00444   reverse (result,empty);
00445 } // Lst::reverse
00446 
00447 
00448 // list copy
00449 // 25/04/2003 Manchester
00450 template <class C>
00451 inline
00452 void Lst<C>::copy (Lst& to) const
00453 {
00454   TRACER("Lst::copy");
00455 
00456   if (isEmpty()) {
00457     return;
00458   }
00459 
00460   to = Lst (head());
00461   tail().copy (const_cast<Lst&>(to.tail()));
00462 } // Lst::copy
00463 
00464 
00465 // **************** Lst::Data definitions *********************
00466 
00467 /*
00468 template <class C>
00469 inline 
00470 Lst<C>::Data::Data (const C& t)
00471   :
00472   _counter (1),
00473   _head (t),
00474   _tail ((Data*)0)
00475 {
00476   TRACER( "Lst::Data::Data" );
00477 } // Lst::Data::Data
00478 
00479 template <class C>
00480 inline 
00481 Lst<C>::Data::Data (const C& t, const Lst& ts)
00482   :
00483   _counter (1),
00484   _head (t),
00485   _tail (ts)
00486 {
00487   TRACER( "Lst::Data::Data" );
00488 } // Lst::Data::Data
00489 
00490 
00491 template <class C>
00492 inline 
00493 Lst<C>::Data::~Data ()
00494 {
00495   TRACER( "Lst::Data::~Data" );
00496 
00497   ASS (_counter == 0);
00498 } // Lst::Data::~Data ()
00499 
00500 
00501 template <class C>
00502 inline
00503 const C& Lst<C>::Data::head () const 
00504 { 
00505   ASS (this);
00506   ASS (_counter > 0);
00507 
00508   return _head; 
00509 } // Lst::Data::head
00510 
00511 
00512 template <class C>
00513 inline
00514 const Lst<C>& Lst<C>::Data::tail () const 
00515 { 
00516   ASS (this);
00517   ASS (_counter > 0);
00518 
00519   return _tail;
00520 } // Lst::Data::tail
00521 
00522 
00523 template <class C>
00524 inline
00525 void Lst<C>::Data::ref () 
00526 { 
00527   ASS (this);
00528 
00529   _counter++;
00530 } // Lst::Data::ref ()
00531 
00532 
00533 template <class C>
00534 inline
00535 void Lst<C>::Data::deref () 
00536 { 
00537   ASS (this);
00538   ASS (_counter > 0);
00539 
00540   _counter--;
00541   if (_counter == 0) {
00542     delete this;
00543   }
00544 } // Lst::Data::deref ()
00545 
00546 
00547 */
00548 
00549 // **************** Lst::Iterator definitions *********************
00550 
00551 
00552 /*
00553 template <class C>
00554 inline
00555 Lst<C>::Iterator::Iterator (const Lst& lst)
00556   : 
00557   _list (lst) 
00558 {
00559 } // Lst::Iterator::Iterator
00560 
00561 
00562 template <class C>
00563 inline
00564 void Lst<C>::Iterator::reset (const Lst& lst)
00565 {
00566   _list = lst;
00567 } // Lst<C>::Iterator::reset
00568 
00569 
00570 template <class C>
00571 inline
00572 bool Lst<C>::Iterator::more () const 
00573 { 
00574   return _list.isNonEmpty(); 
00575 } // Lst::Iterator::more ()
00576 
00577 
00578 // Lst::Iterator::next
00579 // 30/08/2002 Torrevieja, copied from Term
00580 template <class C>
00581 C Lst<C>::Iterator::next ()
00582 {
00583   ASS( more() );
00584 
00585   C result (_list.head());
00586   _list.pop ();
00587   
00588   return result;
00589 } // Lst::Iterator::next
00590 */
00591 
00592 
00593 #endif // __Lst__
00594 

Generated on Sat Jun 28 15:08:57 2003 for Vampire by doxygen 1.3.2