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

Chain.hpp

Go to the documentation of this file.
00001 
00027 // *************************************************************
00028 //
00029 //  Class Chain<C> for implementing double-linked lists
00030 //  03/05/2002 Manchester
00031 //
00032 // *************************************************************
00033 
00034 
00035 #ifndef __chain__
00036 #  define __chain__
00037 
00038 
00039 #include "Memory.hpp"
00040 #include "Sort.hpp"
00041 
00042 
00043 // *******************Class Chain*******************************
00044 
00045 template <class C,ClassID ID>
00046 class Chain
00047 {
00048  public:
00049   class Link
00050   {
00051    private:
00052     Link* _prev;
00053     Link* _next;
00054     C _elem;
00055    public:
00056     inline Link (C elem) 
00057       : _elem (elem) 
00058       {
00059       }
00060 
00061     inline Link ()  // for making the header to a chain only
00062       { 
00063         _prev = this;
00064         _next = this; 
00065       }
00066 
00067     inline Link* prev () const { return _prev; }
00068     inline void prev ( Link* p ) { _prev = p; }
00069     inline Link* next () const { return _next; }
00070     inline void next ( Link* n ) { _next = n; }
00071 
00072     inline bool less (const Link* lnk) const 
00073       { return _elem.less (lnk->_elem); }
00074 
00075     void insertAfter (C elem)
00076       {
00077         Link* l = new Link (elem);
00078         l->_prev = this;
00079         l->_next = _next;
00080         _next->_prev = l;
00081         _next = l;
00082       }
00083 
00084     void insertBefore (C elem)
00085       {
00086         Link* l = new Link (elem);
00087         l->_next = this;
00088         l->_prev = _prev;
00089         _prev->_next = l;
00090         _prev = l;
00091       }
00092 
00093     void del ()
00094       {
00095         TRACER( "Chain::del" );
00096         ASS(_next != this && _prev != this);
00097 
00098         _prev->_next = _next;
00099         _next->_prev = _prev;
00100         delete this;
00101       }
00102 
00103     const C& content () const { return _elem; }
00104   }; // Class Chain::Link
00105 
00106   // I had to make this public since VC++ ignores my declaration of DelIterator as friend
00107   inline const Link* header () const { return &_header; }
00108 
00109   // Chain public members
00110   inline void addLast (C elem)   
00111     { _header.insertBefore (elem); }
00112 
00113   inline void addFirst (C elem)   
00114     { _header.insertAfter (elem); }
00115 
00116   inline void delLast ()    
00117     { _header.prev()->del(); }
00118 
00119   void delFirst ()    
00120     { _header.next()->del(); }
00121 
00122   inline bool isEmpty () const
00123     { return _header.prev() == &_header; }
00124 
00125   Link* first () const
00126     { ASS(! isEmpty());
00127       return _header.next(); }
00128 
00129   C last () const
00130     { ASS(! isEmpty());
00131       return _header.prev(); }
00132 
00133   void sort () // sort links using the less function on C
00134     {
00135       int len = length ();
00136       Sort<Link*> srt (len);
00137 
00138       for (Link* lnk = _header.next ();
00139            lnk != &_header;
00140            lnk = lnk->next () ) {
00141         srt.add (lnk);
00142       }
00143 
00144       // sort the chain using the comparison function less ()
00145       srt.sortF ();
00146 
00147       // sort now contains a sorted array of links
00148       // insert them one by one to the chain
00149       Link* last = &_header; // the last link
00150       for (int i = len - 1; i >= 0; i--) {
00151         Link* nxt = srt[i];
00152         // remove nxt from the chain
00153         nxt->prev()->next (nxt->next());
00154         nxt->next()->prev (nxt->prev());
00155         // insert before the last link
00156         nxt->next (last);
00157         nxt->prev (last->prev());
00158         nxt->prev()->next (nxt);
00159         last->prev (nxt);
00160         last = nxt;
00161       }
00162     }
00163 
00164   int length () const
00165     { int len = 0;
00166       Iterator links (*this);
00167       while (links.more()) {
00168         links.next ();
00169         len ++;
00170       }
00171       return len;
00172     } // length ()
00173       
00174 
00175   class Iterator {
00176    public: 
00177     inline explicit 
00178     Iterator (Chain& c) 
00179       : _header (c.header()),
00180         _current (_header->next())
00181         {}
00182     Iterator (const Chain& c) 
00183       : _header (c.header()),
00184         _current (_header->next())
00185         {}
00186     
00187     inline 
00188     bool more () 
00189       { return _header != _current; }
00190 
00191     inline 
00192     C next () 
00193       { ASS(more());
00194 
00195         C result = _current->content();
00196         _current = _current->next();
00197 
00198         return result;
00199       }
00200     
00201    private:
00202     const Link* _header;
00203     Link* _current;
00204   };
00205 
00206   class DelIterator {
00207    public:
00208     
00209     inline 
00210     DelIterator ( Chain& c ) : 
00211       _header ( c.header() ),
00212       _current ( _header->next() )
00213       {}  
00214     
00215     inline 
00216     bool more () 
00217       { return _header != _current; }
00218 
00219     inline 
00220     C next () 
00221       { 
00222         ASS(_current != _header);
00223         
00224         C result = _current->content();
00225         _current = _current->next();
00226         return result;
00227       }
00228     
00229     inline
00230     void del () 
00231       {
00232         ASS( _current->prev() != _header ); 
00233 
00234         _current->prev()->del();
00235       }
00236 
00237     // 07/05/2002 Manchester
00238     inline
00239     void replace (C elem) 
00240       {
00241         ASS( _current->prev() != _header ); 
00242 
00243         _current->prev()->del();
00244         _current->insertBefore (elem);
00245       }
00246 
00247    private:
00248     const Link* _header;
00249     Link* _current;
00250   };
00251 
00252  private:
00253   Link _header;
00254 
00255  friend class Iterator;
00256 };  // class Chain
00257 
00258 
00259 #endif
00260 
00261 

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