Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

List.H

Go to the documentation of this file.
00001 /* _______              __
00002   / ___/ /  ___  __ _  / /  ___
00003  / /__/ _ \/ _ \/  ' \/ _ \/ _ \
00004  \___/_//_/\___/_/_/_/_.__/\___/ 
00005 */
00006 //
00007 // This software is copyright (C) by the Lawrence Berkeley
00008 // National Laboratory.  Permission is granted to reproduce
00009 // this software for non-commercial purposes provided that
00010 // this notice is left intact.
00011 // 
00012 // It is acknowledged that the U.S. Government has rights to
00013 // this software under Contract DE-AC03-765F00098 between
00014 // the U.S.  Department of Energy and the University of
00015 // California.
00016 //
00017 // This software is provided as a professional and academic
00018 // contribution for joint exchange. Thus it is experimental,
00019 // is provided ``as is'', with no warranties of any kind
00020 // whatsoever, no support, no promise of updates, or printed
00021 // documentation. By using this software, you acknowledge
00022 // that the Lawrence Berkeley National Laboratory and
00023 // Regents of the University of California shall have no
00024 // liability with respect to the infringement of other
00025 // copyrights by any part of this software.
00026 //
00027 
00028 
00029 #ifndef _LIST_H_
00030 #define _LIST_H_
00031 
00032 #include "MayDay.H"
00033 
00034 
00035 template <class T> class ListLink;
00036 template <class T> class ListIterator;
00037 template <class T> class List;
00038 
00039 template <class T>
00040 class ListLink
00041 {
00042 private:
00043     friend class List<T>;
00044     friend class ListIterator<T>;
00045 
00046     ListLink (const T&     _val,
00047               ListLink<T>* _pre,
00048               ListLink<T>* _suc)
00049         : val(_val),
00050           pre(_pre),
00051           suc(_suc)
00052     {}
00053 
00054 private:
00055     T            val;
00056     ListLink<T>* pre;
00057     ListLink<T>* suc;
00058 };
00059 
00060 //
00061 //@Man:
00062 //@Memo: Iterate over a List
00063 /*@Doc:
00064 
00065   The class ListIterator<T> is an iterator over class List<T>.
00066   
00067   This class does NOT provide a default constructor or an assignment operator.
00068 */
00069 
00070 template <class T>
00071 class ListIterator
00072 {
00073 public:
00074     //
00075     //@ManDoc: Construct a ListIterator<T> to first element of aList.
00076     //
00077     inline ListIterator (const List<T>& aList);
00078     //
00079     //@ManDoc: The copy constructor.
00080     //
00081     inline ListIterator (const ListIterator<T>& rhs);
00082 
00083     /*@ManDoc: Reset this ListIterator<T> to point to the first element
00084                in the List<T>.
00085     */
00086     inline void rewind ();
00087 
00088     /*@ManDoc: Return a constant reference to the object in the List<T>
00089                currently pointed to by this ListIterator<T>.
00090     */
00091     inline const T& operator() () const;
00092 
00093     /*@ManDoc: Return a constant reference to the object in the List<T>
00094                currently pointed to by this ListIterator<T>.
00095     */
00096     inline const T& operator* () const;
00097 
00098     /*@ManDoc: This is a conversion operator that makes the iterator look
00099                like a pointer.  This operator makes it easy to check if the
00100                iterator is pointing to an element on the List<T>.  If the
00101                iterator has been moved off the List<T> or if the List<T> is
00102                empty, this conversion returns the NULL pointer.
00103     */
00104     inline operator bool () const;
00105     inline bool ok() const ;
00106 
00107     /*@ManDoc: Returns true if ListIterator<T> doesn't point to any
00108                element on the List<T>.
00109     */
00110     inline bool operator! () const;
00111 
00112     /*@ManDoc: Return a constant reference to the object in the List<T>
00113                currently pointed to by the iterator.
00114     */
00115     inline const T& value () const;
00116 
00117     /*@ManDoc: This is the prefix auto-increment operator.  It advances the
00118                ListIterator<T> to point to the next element on the List<T>.
00119                It then returns a reference to itself to allow for chaining
00120                with other operators.
00121     */
00122     inline ListIterator<T>& operator++ ();
00123 
00124     /*@ManDoc: This is the prefix auto-decrement operator.  It moves the
00125                ListIterator<T> to point to the previous element on the
00126                List<T>.  It then returns a reference to itself to allow for
00127                chaining with other operators.
00128     */
00129     inline ListIterator<T>& operator-- ();
00130 
00131     /*@ManDoc: This is the postfix auto-decrement operator.  It moves the
00132                ListIterator<T> to point to the previous element on the
00133                List<T>.  It then returns a ListIterator<T> that points to
00134                the old element to allow for chaining with other operators.
00135 
00136     */
00137     inline ListIterator<T> operator-- (int);
00138 
00139     /*@ManDoc: This is the postfix auto-increment operator.  It advances the
00140                ListIterator<T> to point to the next element on the List<T>.
00141                It then returns a ListIterator<T> that points to the old
00142                element to allow for chaining with other operators.
00143     */
00144     inline ListIterator<T> operator++ (int);
00145 
00146     /*@ManDoc: Do the two ListIterator<T>s point to the same List<T> and
00147                the same element within the List<T>?
00148     */
00149     inline bool operator== (const ListIterator<T>&) const;
00150     //
00151     //@ManDoc: Are the ListIterator<T>s not equal?
00152     //
00153     inline bool operator!= (const ListIterator<T>&) const;
00154 
00155 protected:
00156     //
00157     // Construct a ListIterator<T> to a List<T> and object in that List<T>.
00158     //
00159     inline ListIterator (const List<T>& _list,
00160                          ListLink<T>*   _p);
00161     //
00162     // A reference to the List<T> to which we point.
00163     //
00164     const List<T>& list;
00165     //
00166     // A pointer to the element in the List<T> to which we point.
00167     //
00168     ListLink<T>* p;
00169 
00170 private:
00171     friend class List<T>;
00172     //
00173     // These are disallowed.
00174     //
00175     ListIterator ();
00176     ListIterator<T>& operator= (const ListIterator<T>&);
00177 };
00178 
00179 //
00180 //@Man:
00181 //@Memo: A Doubly-Linked List
00182 /*@Doc:
00183 
00184   The List<T> class is a template class that implements a doubly-linked list
00185   of objects.  A List<T> is a useful container class when the number of
00186   objects in the collection is not known ahead of time.   A List<T> can
00187   contain an arbitrary number of elements; operations such as insertion,
00188   deletion, and catenation are easily implemented and inexpensive.
00189 
00190   The only difficulty when defining a list class is devising a mechanism to
00191   access the elements.  In an array, an element is accessed using an
00192   integer index.  Since the elements in a List<T> are ordered by position,
00193   we could define an integer indexing operation that walks along the
00194   List<T> links from the beginning until the numbered element is found.
00195   Unfortunately, this would be very inefficient when accessing elements near
00196   the  end of a long list.  Another solution is to allow user access to the
00197   individual link objects that contain the element as well as the forward and
00198   backward pointers.  This is not a satisfactory solution since it allows
00199   user access to the internal representation of the class.  The solution
00200   chosen is to define a ListIterator<T> template class.
00201   
00202   Think of a ListIterator<T> as a pointer to an object in the List<T>.  You
00203   can access the element currently pointed to by the iterator, move the
00204   iterator forward and backward through the List<T>, and use it as a
00205   mechanism to define where elements should be inserted and deleted.  If the
00206   iterator is moved off the end of the list it behaves as a null pointer.
00207 
00208   This is a concrete class, not a polymorphic one.
00209 */
00210 
00211 template <class T>
00212 class List
00213 {
00214 public:
00215     //
00216     //@ManDoc: Construct an empty List<T>.
00217     //
00218     inline List ();
00219     //
00220     //@ManDoc: The copy constructor.
00221     //
00222     List (const List<T>& rhs);
00223     //
00224     //@ManDoc: The assignment operator.
00225     //
00226     List<T>& operator= (const List<T>& rhs);
00227     //
00228     //@ManDoc: The destructor.
00229     //
00230     inline ~List();
00231     //
00232     //@ManDoc: Adds a copy of the value to the beginning of the List<T>.
00233     //
00234     inline void prepend (const T& value);
00235     //
00236     //@ManDoc: Adds a copy of the value to the end of the List<T>.
00237     //
00238     inline void append (const T& value);
00239     //
00240     //@ManDoc: Adds a copy of the value to the end of the List<T>.
00241     //
00242     void add (const T& value);
00243     //
00244     //@ManDoc: Appends a copy of all items in List<T> src to this List<T>.
00245     //
00246     void join (const List<T>& src);
00247 
00248     /*@ManDoc: Appends a copy of all items in List<T> src to this List<T>.
00249                This differs from join() in that it unlinks the objects from
00250                the List<T> src and glues them to the end of this List<T>,
00251                leaving List<T> src empty.  This is more efficient that
00252                join() if src is no longer needed.
00253     */
00254     void catenate (List<T>& src);
00255     //
00256     //@ManDoc: Removes all objects from the List<T>.
00257     //
00258     void clear ();
00259 
00260     /*@ManDoc: Returns a copy of this List<T> on the heap.  It is the user's
00261                responsibility to delete this when no longer needed.
00262     */
00263     inline List<T>* copy () const;
00264     //
00265     //@ManDoc: Returns a reference to the first element in the List<T>.
00266     //
00267     inline T& firstElement () const;
00268     //
00269     //@ManDoc: Returns a reference to the last element in the List<T>.
00270     //
00271     inline T& lastElement () const;
00272 
00273     /*@ManDoc: Returns true if the List<T> contains an object identical
00274                to value.  Type T must have an operator==() defined, or
00275                be an intrinsic type.
00276     */
00277     bool includes (const T& value) const;
00278 
00279     /*@ManDoc: Returns true if the this and rhs are memberwise equal;
00280                i.e. the two lists are the same size and each of the
00281                elements in the list compare equal. Type T must have an
00282                operator==() defined, or be an intrinsic type.
00283     */
00284     bool operator== (const List<T>& rhs) const;
00285     //
00286     //@ManDoc: Returns true if the this and rhs are not equal.
00287     //
00288     bool operator!= (const List<T>& rhs) const;
00289     //
00290     //@ManDoc: Returns true if the List<T> is empty.
00291     //
00292     inline bool isEmpty () const;
00293     //
00294     //@ManDoc: Returns true if the List<T> is not empty.
00295     //
00296     inline bool isNotEmpty () const;
00297     //
00298     //@ManDoc: Returns the number of objects in the List<T>.
00299     //
00300     int length () const;
00301     //
00302     //@ManDoc: Removes the first element in the List<T>.
00303     //
00304     inline void removeFirst ();
00305     //
00306     //@ManDoc: Removes the last element in the List<T>.
00307     //
00308     inline void removeLast ();
00309     //
00310     //@ManDoc: Returns reference to object pointed to by the ListIterator<T>.
00311     //
00312     inline const T& operator[] (const ListIterator<T>& li) const;
00313     //
00314     //@ManDoc: Returns reference to object pointed to by the ListIterator<T>.
00315     //
00316     inline T& operator[] (const ListIterator<T>& li);
00317     //
00318     //@ManDoc: Removes all objects in the List<T> equal to value.
00319     //
00320     void remove (const T& value);
00321 
00322     /*@ManDoc: Removes all objects in the List<T> equal to any of the
00323                values in lst.
00324     */
00325     void remove (const List<T>& lst);
00326     //
00327     //@ManDoc: Removes the object pointed to by the ListIterator<T>.
00328     //
00329     void remove (ListIterator<T>& lit);
00330     //
00331     //@ManDoc: Replace the value pointed to by the ListIterator<T> by val.
00332     //
00333     inline void replace (ListIterator<T>& li,
00334                          const T&         val);
00335 
00336     /*@ManDoc: Insert val into List<T> after the object pointed to by
00337                ListIterator<T>.
00338     */
00339     inline void addAfter (ListIterator<T>& lit,
00340                           const T&         val);
00341 
00342     /*@ManDoc: Insert val into List<T> before the object pointed to by
00343                ListIterator<T>.
00344     */
00345     inline void addBefore (ListIterator<T>& lit,
00346                            const T&         val);
00347     //
00348     //@ManDoc: Returns a ListIterator<T> to the first object in this List<T>.
00349     //
00350     inline ListIterator<T> first () const;
00351     //
00352     //@ManDoc: Returns a ListIterator<T> to the last object in this List<T>.
00353     //
00354     inline ListIterator<T> last () const;
00355 
00356 protected:
00357     //
00358     // A helper function for removing nodes.
00359     //
00360     void remove (ListLink<T> *ln);
00361     //
00362     // A helper function for adding nodes.
00363     //
00364     ListLink<T>* addBefore (ListLink<T>* ln,
00365                             const T&     val);
00366     //
00367     // A helper function for adding nodes.
00368     //
00369     ListLink<T>* addAfter (ListLink<T>* ln,
00370                            const T&     val);
00371     //
00372     // The head of the list.
00373     //
00374     ListLink<T>* head;
00375     //
00376     // The tail of the list.
00377     //
00378     ListLink<T>* tail;
00379     //
00380     // Our good and trusted friend.
00381     //
00382     friend class ListIterator<T>;
00383 };
00384 
00385 //
00386 // Inlines.
00387 //
00388 
00389 //
00390 // The ListIterator stuff.
00391 //
00392 
00393 template <class T>
00394 inline
00395 ListIterator<T>::ListIterator (const List<T>& _list,
00396                                ListLink<T>*   _p)
00397     : list(_list),
00398       p(_p)
00399 {}
00400 
00401 template <class T>
00402 inline
00403 ListIterator<T>::ListIterator (const List<T>& aList)
00404     : list(aList)
00405 {
00406     p = list.head;
00407 }
00408 
00409 template <class T>
00410 inline
00411 ListIterator<T>::ListIterator (const ListIterator<T>& li)
00412     : list(li.list),
00413       p(li.p)
00414 {}
00415 
00416 template <class T>
00417 inline
00418 void
00419 ListIterator<T>::rewind ()
00420 {
00421     p = list.head;
00422 }
00423 
00424 template <class T>
00425 inline
00426 const T&
00427 ListIterator<T>::operator() () const
00428 {
00429     assert(p != 0);
00430     return p->val;
00431 }
00432 
00433 template <class T>
00434 inline
00435 const T&
00436 ListIterator<T>::operator* () const
00437 {
00438     assert(p != 0);
00439     return p->val;
00440 }
00441 
00442 template <class T>
00443 inline
00444 bool
00445 ListIterator<T>::ok() const
00446 {
00447     return p != 0 ? true : false;
00448 }
00449 
00450 template <class T>
00451 inline
00452 ListIterator<T>::operator bool () const
00453 {
00454     return ok() ;
00455 }
00456 
00457 template <class T>
00458 inline
00459 bool
00460 ListIterator<T>::operator! () const
00461 {
00462     return p == 0 ? true : false;
00463 }
00464 
00465 template <class T>
00466 inline
00467 const T&
00468 ListIterator<T>::value () const
00469 {
00470     assert(p != 0);
00471     return p->val;
00472 }
00473 
00474 template <class T>
00475 inline
00476 ListIterator<T>&
00477 ListIterator<T>::operator++ ()
00478 {
00479     if (p)
00480         p = p->suc;
00481     return *this;
00482 }
00483 
00484 template <class T>
00485 inline
00486 ListIterator<T>&
00487 ListIterator<T>::operator-- ()
00488 {
00489     if (p)
00490         p = p->pre;
00491     return *this;
00492 }
00493 
00494 template <class T>
00495 inline
00496 ListIterator<T>
00497 ListIterator<T>::operator++ (int)
00498 {
00499     const ListIterator<T> li = *this;
00500     ++(*this);
00501     return li;
00502 }
00503 
00504 template <class T>
00505 inline
00506 ListIterator<T>
00507 ListIterator<T>::operator-- (int)
00508 {
00509     const ListIterator<T> li = *this;
00510     --(*this);
00511     return li;
00512 }
00513 
00514 template <class T>
00515 inline
00516 bool
00517 ListIterator<T>::operator== (const ListIterator<T>& _li) const
00518 {
00519     return (&list == &_li.list && p == _li.p) ? true : false;
00520 }
00521 
00522 template <class T>
00523 inline
00524 bool
00525 ListIterator<T>::operator!= (const ListIterator<T>& _li) const
00526 {
00527     return ! ListIterator<T>::operator==(_li);
00528 }
00529 
00530 //
00531 // List stuff.
00532 //
00533 
00534 template <class T>
00535 inline
00536 List<T>::List ()
00537     : head(0),
00538       tail(0)
00539 {}
00540 
00541 template <class T>
00542 inline
00543 List<T>::~List ()
00544 {
00545     clear();
00546 }
00547 
00548 template <class T>
00549 inline
00550 void
00551 List<T>::prepend (const T& value)
00552 {
00553     addBefore(head, value);
00554 }
00555 
00556 template <class T>
00557 inline
00558 void
00559 List<T>::append (const T& value)
00560 {
00561     addAfter(tail, value);
00562 }
00563 
00564 template <class T>
00565 inline
00566 List<T>*
00567 List<T>::copy () const
00568 {
00569     List<T>* newlist = new List<T>(*this);
00570     if (newlist == 0)
00571       MayDay::Error("Out of memory in List::copy ");
00572     return newlist;
00573 }
00574 
00575 template <class T>
00576 inline
00577 T&
00578 List<T>::firstElement () const
00579 {
00580     assert(head != 0);
00581     return head->val;
00582 }
00583 
00584 template <class T>
00585 inline
00586 T&
00587 List<T>::lastElement () const
00588 {
00589     assert(tail != 0);
00590     return tail->val;
00591 }
00592 
00593 template <class T>
00594 inline
00595 bool
00596 List<T>::isEmpty () const
00597 {
00598     return head == 0 && tail == 0;
00599 }
00600 
00601 template <class T>
00602 inline
00603 bool
00604 List<T>::isNotEmpty () const
00605 {
00606     return !isEmpty();
00607 }
00608 
00609 template <class T>
00610 inline
00611 void
00612 List<T>::removeFirst ()
00613 {
00614     remove(head);
00615 }
00616 
00617 template <class T>
00618 inline
00619 void
00620 List<T>::removeLast ()
00621 {
00622     remove(tail);
00623 }
00624 
00625 template <class T>
00626 inline
00627 const T&
00628 List<T>::operator[] (const ListIterator<T>& li) const
00629 {
00630     assert(li.p != 0);
00631     return li.p->val;
00632 }
00633 
00634 template <class T>
00635 inline
00636 T&
00637 List<T>::operator[] (const ListIterator<T>& li)
00638 {
00639     assert(li.p != 0);
00640     return li.p->val;
00641 }
00642 
00643 template <class T>
00644 inline
00645 void
00646 List<T>::replace (ListIterator<T>& li,
00647                   const T&         _val)
00648 {
00649     assert(li.p != 0);
00650     li.p->val = _val;
00651 }
00652 
00653 template <class T>
00654 inline
00655 void
00656 List<T>::addAfter (ListIterator<T>& lit,
00657                    const T&         val)
00658 {
00659     addAfter(lit.p, val);
00660 }
00661 
00662 template <class T>
00663 inline
00664 void
00665 List<T>::addBefore (ListIterator<T>& lit,
00666                     const T&         val)
00667 {
00668     addBefore(lit.p, val);
00669 }
00670 
00671 template <class T>
00672 inline
00673 ListIterator<T>
00674 List<T>::first () const
00675 {
00676     return ListIterator<T>(*this,head);
00677 }
00678 
00679 template <class T>
00680 inline
00681 ListIterator<T>
00682 List<T>::last () const
00683 {
00684     return ListIterator<T>(*this,tail);
00685 }
00686 
00687 #include "ListImplem.H"
00688 
00689 #endif /*_LIST_H_*/

Generated on Wed Apr 16 14:26:49 2003 for Chombo by doxygen1.2.16