casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
List.h
Go to the documentation of this file.
00001 //# List.h: Doubly linked list classes
00002 //# Copyright (C) 1993,1994,1995,1996,1997,1998,1999,2000,2001
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: List.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $
00027 
00028 #ifndef CASA_LIST_H
00029 #define CASA_LIST_H
00030 
00031 
00032 //# Includes
00033 #include <casa/Utilities/Register.h>
00034 #include <casa/Utilities/Notice.h>
00035 #include <casa/Containers/Link.h>
00036 #include <casa/Utilities/Assert.h>
00037 #include <casa/Containers/IterError.h>
00038 
00039 namespace casa { //#Begin casa namespace
00040 
00041 // The function which throws an exception for advancing the internal
00042 // cursor past the end of a list
00043 void throw_list_end_error();
00044 void throw_list_init_error();
00045 void throw_list_start_error();
00046 void throw_list_swapright_same_error();
00047 
00048 //# Forward Declarations
00049 template<class t> class ListIter;
00050 template<class t> class ConstListIter;
00051 template<class t> class List;
00052 
00053 
00054 //
00055 // <summary>Linked list update notice</summary> 
00056 // <use visibility=local>
00057 //
00058 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00059 // </reviewed>
00060 //
00061 // <synopsis>
00062 // This class is the notification which is passed between <src>List<t></src>
00063 // and <src>ListIter<t></src> in order to keep cursors and container in sync.
00064 // This is the mechanism which allows multiple iterators to view the same
00065 // list and automatically update as the list is changed. See the
00066 // <linkto class=Notice:description>Notice</linkto> class for more information.
00067 // </synopsis>
00068 //
00069 template<class t> class ListNotice : public Notice {
00070 friend class ConstListIter<t>;
00071 friend class ListIter<t>;
00072 friend class List<t>;
00073 public:
00074     enum modification { DELETE, ADD, REMOVE, SWAP };
00075     //
00076     // This function returns the Notice "type", which is retrieved
00077     // from the "type registry". The registry information is maintained 
00078     // automatically by the Notice constructors.  A form of run 
00079     // time type information, this function is mostly intended for advanced 
00080     // users.
00081     //
00082     uInt type() const;
00083 
00084     //
00085     // This operator can be used to compare two
00086     // ListNotices.
00087     //
00088     int operator==(const Notice &op) const;
00089 
00090 private:
00091     modification mod;
00092     Link<t> *oprev;
00093     Link<t> *ocur;
00094     Link<t> *nprev;
00095     Link<t> *ncur;
00096     int off;
00097     int otherOff;
00098 
00099     //
00100     // This is used to construct a list notice. The parameters are:
00101     // <ul>
00102     //    <li> (m) what was done to the list
00103     //    <li> (oc) the old current position
00104     //    <li> (op) the old previous position
00105     //    <li> (nc) the new current position
00106     //    <li> (np) the new previous position
00107     //    <li> (of) current offset;
00108     //    <li> (nf) other offset (only used with SWAP mod)
00109     // </ul>
00110     //
00111     ListNotice(modification m, Link<t> *oc,Link<t> *op,Link<t> *nc,Link<t> *np, int of, int nf=0) : 
00112                 mod(m),oprev(op),ocur(oc),nprev(np),ncur(nc), off(of), otherOff(nf) {}
00113 
00114     //
00115     // This constructor is used to initialize a notice for a deleted
00116     // "List". 
00117     //
00118     ListNotice() : mod(DELETE), oprev(0),ocur(0),
00119                         nprev(0),ncur(0),off(0),otherOff(0) {}
00120 
00121 };
00122 
00123 //
00124 // <summary>Doubly linked list</summary> 
00125 // <use visibility=export>
00126 //
00127 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00128 // </reviewed>
00129 //
00130 // <synopsis>
00131 //     This class is a container which by itself has little functionality
00132 //     because the iteration functionality is contained in the iterator
00133 //     classes, <linkto class=ListIter>ListIter</linkto> and
00134 //     <linkto class=ConstListIter>ConstListIterr</linkto>. These iterator
00135 //     classes allow traversal, insertion into list, and removal from the list.
00136 //
00137 //     This group of classes, List and iterators, was designed to allow
00138 //     multiple iterators to manipulate a list at the same time. However,
00139 //     if only one iterator is required the <a href=#simple_example>simple
00140 //     example</a> below shows how a simple list can be created and used
00141 //     without complication. The <a href=#complete_example>more complete
00142 //     example</a> below demonstrates all of the functionality of the List
00143 //     classes.
00144 // </synopsis>
00145 //
00146 // <anchor name=simple_example>
00147 // <example>
00148 //     <srcblock>
00149 // #include <casa/Containers/List.h>
00150 // #include <casa/Containers/ListIO.h>
00151 // 
00152 // main() {
00153 //                                              // List, conceptual
00154 //                                              //       cursor = "|"
00155 //   ListIter<int> list(new List<int>(),True);  //  |
00156 //   list.addRight(12);                         //  | 12
00157 //   list.addRight(2);                          //  | 2 12
00158 //   list.addRight(89);                         //  | 89 2 12
00159 //   list++;                                    //  89 | 2 12
00160 //   list.addRight(10);                         //  89 | 10 2 12
00161 //   list++;                                    //  89 10 | 2 12
00162 //   list.addRight(8);                          //  89 10 | 8 2 12
00163 //   list--;                                    //  89 | 10 8 2 12
00164 //   list.pos(0);                               //  | 89 10 8 2 12
00165 //   list.pos(5);                               //  89 10 8 2 12 |
00166 //   list.pos(4);                               //  89 10 8 2 | 12
00167 //   list.step(3);                              //  89 | 10 8 2 12
00168 //   list.step();                               //  89 10 | 8 2 12
00169 //   list.step(-4);                             //  89 10 8 2 | 12
00170 //   list.removeRight();                        //  89 10 8 2 |
00171 //   cout << list << endl;
00172 //   return 0;
00173 // }
00174 //     </srcblock>
00175 //     <em>The output from this example looks like:</em>
00176 //     <pre>
00177 //          len=4 pos=4 89 10 8 2
00178 //     </pre>
00179 // </example>
00180 // </anchor>
00181 // 
00182 template<class t> class List : public NoticeSource
00183 {
00184 friend class ConstListIter<t>;
00185 friend class ListIter<t>;
00186 public:
00187     //
00188     // Creates an empty list.
00189     //
00190     List() : head(0), tail(0), length(0){}
00191     //
00192     // Copy Semantics
00193     // <group>
00194     List(const List<t> &other);
00195     List(const List<t> *other);
00196     List<t> &operator=(const List<t> &other);
00197     List<t> &operator=(const List<t> *other);
00198     // </group>
00199 
00200     //*display 4
00201     //
00202     // Destructs the list.
00203     //
00204     ~List();
00205 
00206     //
00207     //    Returns the length of the list.
00208     //
00209     uInt len() const {return length;}
00210 
00211     //
00212     // List version
00213     //
00214     enum {ListVersion = 2};
00215 
00216 protected:
00217     Link<t> *head;
00218     Link<t> *tail;
00219     uInt length;
00220 
00221     //
00222     // Updates the extreme pointers, head or tail
00223     // under the appropriate conditions
00224     //
00225     // <group>
00226     virtual void added(Link<t> *, Link<t> *);
00227     virtual void removed(Link<t> *, Link<t> *, Link<t> *);
00228     // </group>
00229 };
00230 
00231 
00232 // 
00233 // <summary>Doubly linked constant list iterator</summary> 
00234 //
00235 //  <synopsis>
00236 //  The <linkto class=List>List</linkto> class above only provides for
00237 //  the list framework. This is one of two classes which allow list
00238 //  iteration, insertion, and removal. This class <em>cannot</em> be
00239 //  used to modify a list, but rather, it can only be used to look at
00240 //  or observe a list. It provides <em>no</em> functions for modifying
00241 //  the list.
00242 //
00243 //  All of the operations take place to the right of a conceptual cursor.
00244 //  The cursor starts out before the first element of the list and can
00245 //  be incremented past the last element of the list. Going further than
00246 //  the end of the list results in an exception.
00247 //
00248 // <example>
00249 //    In this example, assume that this function is called at the
00250 //    end of the <a href=#simple_example>example above</a>, i.e.
00251 //    assume that the line before the return, 
00252 //    <a href=#simple_example>above</a>, is uncommented.
00253 //
00254 // <srcblock>
00255 // void iterate(ListIter<int> &list) {
00256 //                                             // List, conceptual
00257 //                                             //       cursor = "|"
00258 //   ConstListIter<int> li = list;             //  89 10 8 2 |
00259 //   li--;                                     //  89 10 8 | 2
00260 //   cout << li.getRight() << " ";             //  89 10 8 | 2
00261 //   li--;                                     //  89 10 | 8 2
00262 //   li.pos(0);                                //  | 89 10 8 2
00263 //   li.pos(3);                                //  89 10 8 | 2
00264 //   li.pos(1);                                //  89 | 10 8 2
00265 //   li.step();                                //  89 10 | 8 2
00266 //   li.pos(0);                                //  | 89 10 8 2
00267 //   li.step(-3);                              //  89 10 | 8 2
00268 //   cout << li.getRight() << endl;            //  89 10 | 8 2
00269 //   cout << li << endl;                       //  89 10 | 8 2
00270 // }
00271 // </srcblock>
00272 // The output which this function, <src>iterate()</src>, would
00273 // produce would look like:
00274 // <pre>
00275 //         2 8
00276 //         len=4 pos=2 89 10 8 2
00277 // </pre>
00278 //
00279 // As shown above:
00280 // <dl> 
00281 //    <dt> <src>pos()</src>
00282 //      <dd> allows for arbitrary positioning of the cursor
00283 //    <dt> <src>step()</src>, <src>operator++()</src>, and <src>operator--()</src>
00284 //      <dd> allow for relative positioning
00285 //    <dt> <src>getRight()</src>
00286 //      <dd> fetches the next element in the list. 
00287 // </dl>
00288 // In addition:
00289 // <dl>
00290 //    <dt> <src>atStart()</src>, <src>atEnd()</src>, and <src>pos()</src>
00291 //      <dd> allow querying the position of the  cursor
00292 //    <dt> <src>len()</src>
00293 //      <dd> returns the number of elements in the list.
00294 // </dl>
00295 // </example>
00296 //
00297 // <note role=tip> This class uses the <linkto class=Notice>Notice
00298 //        classes</linkto> to implement "dynamic" cursors so that
00299 //        multiple cursors are updated as elements are added and
00300 //        removed from the list.
00301 // </note>
00302 //    
00303 template<class t> class ConstListIter : public NoticeTarget
00304 {
00305 public:
00306 
00307     //
00308     // This constructor creates a "ConstListIter" which tracks the
00309     // "List<t>" parameter.
00310     //
00311     // <group>
00312     ConstListIter(const List<t> *st);
00313     ConstListIter(const List<t> &st) : NoticeTarget((NoticeSource &)st),
00314                                        cur(st.head), prev(0), curPos(0), 
00315                                        container_((List<t> *) (&st)) 
00316                                          {}
00317     // </group>
00318 
00319     //
00320     // This constructor creates a "ConstListIter" which tracks the 
00321     // same list tracked by the "ConstListIter<t>" parameter.
00322     //
00323     // <group>
00324     ConstListIter(const ConstListIter<t> &other) : 
00325                         NoticeTarget((NoticeTarget &)other),
00326                         cur(other.cur), prev(other.prev), curPos(other.curPos),
00327                         container_(other.container_) {}
00328 
00329     ConstListIter(const ConstListIter<t> *other);
00330     // </group>
00331 
00332 
00333     //
00334     // This is the default constructor. It allows one
00335     // to create an initially invalid empty ConstListIter.  The instantiated
00336     // class will accept assignment and thus become valid later.
00337     //
00338     ConstListIter() : NoticeTarget(),cur(0), prev(0), curPos(0), 
00339                       container_(0) {}
00340 
00341     //*display 4
00342     //
00343     // Destructor doesn\'t do anything special because
00344     // all of the "real" information is in the "List<t>".
00345     //
00346     ~ConstListIter();
00347 
00348     //*display 4
00349     //
00350     // This function is the hook through which iterators
00351     // are notified of important changes to the underlying
00352     // list. For advanced users. 
00353     //
00354     void notify(const Notice &);
00355 
00356     //
00357     // This functions allows one to checked if the cursor
00358     // is at an extreme list position. "atStart()" checks
00359     // to see if the cursor is at the beginning of the list,
00360     // and "atEnd()" checks to see if the cursor is at the
00361     // end of the list.
00362     //
00363     // <group>
00364     Bool atStart() const {
00365         AlwaysAssert(isValid(),InvalidIterError);
00366         if (prev == 0) return True;
00367         else return False;}
00368 
00369     Bool atEnd() const {
00370         AlwaysAssert(isValid(),InvalidIterError);
00371         if (cur == 0) return True;
00372         else return False;}
00373     // </group>
00374 
00375     //
00376     // This function is used to step the cursor forward through
00377     // the list.
00378     //
00379     // <group>
00380     void operator++() {
00381         AlwaysAssert(isValid(),InvalidIterError);
00382         if (cur) {
00383             curPos++;
00384             prev = cur;
00385             cur = (*cur).next();
00386         } else throw_list_end_error();}
00387 
00388     inline void operator++(int) {
00389         AlwaysAssert(isValid(),InvalidIterError);
00390         if (cur != 0) {
00391             curPos++;
00392             prev = cur;
00393             cur = (*cur).next();
00394         } else throw_list_end_error();}
00395     // </group>
00396 
00397     //
00398     // This function allow for stepping the cursor toward the 
00399     // front of the list. 
00400     //
00401     // <group>
00402     void operator--() {
00403         if (prev) {
00404             curPos--;
00405             cur = prev;
00406             prev = (*prev).prev();
00407         } else throw_list_start_error();}
00408 
00409     void operator--(int) {
00410         if (prev) {
00411             curPos--;
00412             cur = prev;
00413             prev = (*prev).prev();
00414         } else throw_list_start_error();}
00415     // </group>
00416 
00417     //
00418     // "pos()" without arguments returns the current postion
00419     // of the cursor.
00420     // "pos()" with an unsigned integer parameter
00421     // moves the cursor to an absolute position.
00422     //
00423     // <group>
00424     virtual uInt pos(uInt);
00425 
00426     uInt pos() const {
00427         AlwaysAssert(isValid(),InvalidIterError);
00428         return curPos;}
00429     // </group>
00430 
00431     //
00432     // This function returns the number of elements in the list.
00433     //
00434     uInt len() const {
00435         AlwaysAssert(isValid(),InvalidIterError);
00436         return (*container_).length;}
00437 
00438     //
00439     // "step()" with no parameters advances the cursor forward 
00440     // one element.
00441     // "step()" with a signed integer parameter moves the cursor
00442     // (forward or backward) by a relative offset indicated by the
00443     // parameter. 
00444     //
00445     // <group>
00446     inline uInt step(Int offset){
00447         Int toffset;
00448         AlwaysAssert(isValid(),InvalidIterError);
00449         //# Traps a negative offset because aparently some compilers
00450         //# do not handle modulo of a negative number correctly.
00451         toffset = offset < 0 && -offset > Int(curPos) ? -((- curPos - offset) % ((*container_).length + 1)) 
00452                                            : (curPos + offset) % ((*container_).length + 1);
00453         return(pos(toffset >= 0 ? toffset : (*container_).length + toffset + 1));}
00454 
00455     inline uInt step() {return(step(1));}
00456     // </group>
00457 
00458     //
00459     // Returns the element to the right of the cursor.
00460     //
00461     const t &getRight() const {
00462         AlwaysAssert(isValid(),InvalidIterError);
00463         if (!cur) throw_list_end_error();
00464         return((*cur).val());}
00465 
00466     //
00467     // This assignment operator substitutes the "List<t>" 
00468     // tracked by this iterator to the "List<t>" passed as an argument.
00469     //
00470     // <group>
00471     virtual ConstListIter<t> &operator=(const List<t> &other);
00472     virtual ConstListIter<t> &operator=(const List<t> *other);
00473     // </group>
00474 
00475     //
00476     // This assignment operator substitutes the "List<t>"
00477     // tracked by this iterator to the "List<t>" tracked by the
00478     // passed "ConstListIter<t>" argument.
00479     //
00480     // <group>
00481     virtual ConstListIter<t> &operator=(const ConstListIter<t> &other);
00482     virtual ConstListIter<t> &operator=(const ConstListIter<t> *other);
00483     // </group>
00484 
00485     //
00486     // This function moves the cursor to the beginning of the list.
00487     //
00488     void toStart() {
00489         AlwaysAssert(isValid(),InvalidIterError);
00490         cur = (*container_).head; prev = 0; curPos = 0;}
00491   
00492     //
00493     // This function moves the cursor to the end of the list.
00494     //
00495     void toEnd() {
00496         AlwaysAssert(isValid(),InvalidIterError);
00497         prev = (*container_).tail; 
00498         cur = 0;
00499         curPos = (*container_).length;
00500     }
00501 
00502     //
00503     // Get the container over which we are iterating, could be null...
00504     //
00505     const List<t> *container() const {return container_;}
00506 
00507     // enum outside class because of compiler errors on HPUX
00508     //enum {ConstListIterVersion = 1};
00509 
00510 protected:
00511 
00512     Link<t> *cur;
00513     Link<t> *prev;
00514     uInt curPos;
00515     List<t> *container_;
00516 };
00517 
00518 // 
00519 // <summary>Doubly linked non-constant list iterator</summary> 
00520 //
00521 //  The <linkto class=List>List</linkto> class above only provides for
00522 //  the list framework. This is one of two classes which allow list
00523 //  iteration, insertion, and removal. This class <em>can</em> be
00524 //  used to modify a list. Unlike
00525 //  <linkto class=ConstListIter>ConstListIter</linkto>, this class can
00526 //  insert and remove elements from a list as well as look at
00527 //  or observe a list. <linkto class=ConstListIter>ConstListIter</linkto>
00528 //  should be used whenever the list is not modified.
00529 //
00530 //  All of the operations take place to the right of a conceptual cursor.
00531 //  The cursor starts out before the first element of the list and can
00532 //  be incremented past the last element of the list. Going further than
00533 //  the end of the list results in an exception. All additions and deletions
00534 //  occur to the right of this conceptual cursor. In addition, this class
00535 //  uses the <linkto class=Notice>Notice</linkto> class to ensure that multiple
00536 //  iterators which are observing the same list are updated as the list
00537 //  changes. This is important when multiple iterators are used.
00538 //
00539 // <anchor name=complete_example>
00540 // <example>
00541 // <srcblock>
00542 // #include <casa/Containers/List.h>
00543 // #include <casa/Containers/ListIO.h>
00544 //
00545 // main() {
00546 //                                             // The conceptual cursors are:
00547 //                                             //   |  for one
00548 //                                             //   ^  for two
00549 //                                             //   _  for three
00550 //     ListIter<int> one(new List<int>,True);
00551 //     ListIter<int> three, two = one;
00552 //     one.addRight(12);                       //  |^ 12
00553 //     one.addRight(2);                        //  |^ 2 12
00554 //     one.addRight(89);                       //  |^ 89 2 12
00555 //     cout << one.getRight() << " " 
00556 //          << two.getRight() << endl;
00557 //     two.addRight(21);                       //  |^ 21 89 2 12
00558 //     cout << one.getRight() << " " 
00559 //          << two.getRight() << endl;
00560 //     one++; two++; two++;                    //   21 | 89 ^ 2 12
00561 //     three = one;                            //   21 |_ 89 ^ 2 12
00562 //     one.removeRight();                      //   21 |^_ 2 12
00563 //     cout << one.getRight() << " " 
00564 //          << two.getRight() << " "
00565 //          << three.getRight() << endl;
00566 //     three.addRight(17);                     //   21 |^_ 17 2 12
00567 //
00568 //     cout << one.getRight() << " " 
00569 //          << two.getRight() << " "
00570 //          << three.getRight() << endl;
00571 //
00572 //     one.toEnd();                            //   21 ^_ 17 2 12 |
00573 //     one.addRight(18);                       //   21 ^_ 17 2 12 | 18
00574 //     two.pos(3);                             //   21 _ 17 2 ^ 12 | 18
00575 //     three--;                                //   _ 21 17 2 ^ 12 | 18
00576 //     two.step();                             //   _ 21 17 2 12 ^| 18
00577 //     one.step(4);                            //   _ 21 17 | 2 12 ^ 18
00578 //     cout << "one:   " << one << endl;
00579 //     cout << "two:   " << two << endl;
00580 //     cout << "three: " << three << endl;
00581 //
00582 //     return 0;
00583 // }
00584 // </srcblock>
00585 //     The output from this example would look like:
00586 //     <pre>
00587 //           89 89
00588 //           21 21
00589 //           2 2 2
00590 //           17 2 17
00591 //           one:   len=5 pos=2 21 17 2 12 18
00592 //           two:   len=5 pos=4 21 17 2 12 18
00593 //           three: len=5 pos=0 21 17 2 12 18
00594 //     </pre>
00595 // </example>
00596 // </anchor>
00597 //
00598 // <note role=tip> This class uses the "Notice" classes to implement "dynamic" cursors
00599 //        so that multiple cursors are updated as elements are added and
00600 //        removed from the list.
00601 // </note>
00602 //    
00603 template<class t> class ListIter : virtual public ConstListIter<t> {
00604 public:
00605 
00606     //
00607     // This constructor allows one to construct a ListIter and
00608     // attach it to the List parameter. The own flag can be
00609     // set to indicate that the List should be destroyed when
00610     // the ListIter is deleted.
00611     //
00612     ListIter(List<t> *st, Bool OWN = False) : ConstListIter<t>(st), own(OWN){}
00613     
00614 
00615     //
00616     // This constructor allows one to construct a ListIter and
00617     // attach it to the List parameter. 
00618     //
00619     ListIter(List<t> &st);
00620 
00621     //
00622     // These constructors allow for the creation of a ListIter from
00623     // another ListIter. This will attach this ListIter to the List
00624     // tracked by the ListIter parameter at the time of construction.
00625     //
00626     // <group>
00627     ListIter(const ListIter<t> &other);
00628     ListIter(const ListIter<t> *other) : ConstListIter<t>(other), own(False){}
00629     // </group>
00630 
00631     //
00632     // This is the default constructor. It allows one
00633     // to create an initially invalid empty ListIter.  The instantiated
00634     // class will accept assignment and thus become valid later.
00635     //
00636     ListIter() : ConstListIter<t>() {}
00637 
00638 
00639     //
00640     // This function adds the element to the right of the 
00641     // current cursor position.
00642     //
00643     void addRight(t e) { 
00644         AlwaysAssert(this->isValid(),InvalidIterError);
00645         Link<t> *c = this->cur;
00646         Link<t> *p = this->prev;
00647         this->cur = newLink(e,this->prev,this->cur);
00648         // Allow container to update
00649         (*this->container_).added(this->prev,this->cur);
00650         ListNotice<t> state(ListNotice<t>::ADD,c,p,this->cur,this->prev,
00651                             this->curPos);
00652         (*this->container_).notify(state);
00653     }
00654 
00655     //
00656     // This function removes the element to the right of the 
00657     // current cursor position.
00658     //
00659     void removeRight();
00660 
00661     //
00662     // This function swaps the list section after the
00663     // current position of the list with the right section
00664     // of the list of another iterator. This can be 
00665     // particularly useful for "remembering" the position 
00666     // of a cursor in a list.
00667     //
00668     virtual void swapRight(ListIter<t> &);
00669 
00670 
00671     //
00672     // Returns the element to the right of the cursor.
00673     //
00674     // <group>
00675     t &getRight() {
00676         AlwaysAssert(this->isValid(),InvalidIterError);
00677         if (!this->cur) throw_list_end_error();
00678         return((*this->cur).val());}
00679 
00680     const t &getRight() const { return(ConstListIter<t>::getRight());}
00681     // </group>
00682 
00683     //
00684     // This function changes the List
00685     // which this ListIter tracks and specifies that the List
00686     // should be deleted when this iterator is deleted.
00687     //
00688     virtual ListIter<t> &assign(List<t> *other,Bool OWN = False);
00689 
00690     //
00691     // This assignment operator changes the List which this
00692     // iterator tracks to the List parameter.
00693     //
00694     // <group>
00695     virtual ListIter<t> &operator=(List<t> &other);
00696 
00697     virtual ListIter<t> &operator=(List<t> *other);
00698     // </group>
00699   
00700     //
00701     // These assignment operators allow one to change the List
00702     // to which this iterator tracks to the List currently associated
00703     // with the argument ListIter.
00704     //
00705     // <group>
00706     virtual ListIter<t> &operator=(const ListIter<t> &other);
00707 
00708     virtual ListIter<t> &operator=(const ListIter<t> *other);
00709     // </group>
00710 
00711     ~ListIter();
00712 
00713 //# **Seems to cause an internal compiler error on Sun's
00714 //# **Cfront compiler. Remove when really need or compiler
00715 //# **recovers from brain damage (Thu May  4 13:08:21 EDT 1995).
00716 //#
00717 //#  enum {ListIterVersion = 1};
00718 
00719 protected:
00720     //
00721     // Indicates if this iterator "owns" the container it observes.
00722     //
00723     Bool own;
00724 
00725     //*display 1
00726     //
00727     // This function creates a new link. By separating link
00728     // creation out into "newLink", the "addRight(t)"
00729     // functionality can be performed in the base class.
00730     // 
00731     virtual Link<t> *newLink(t &e, Link<t> *p=0, Link<t> *n=0);
00732 
00733 private:
00734 
00735     //*display 6
00736     //
00737     // These functions are for internal use.  They ONLY throw an exception
00738     // to prevent improper initialization of a constant OrderedMapIter.
00739     //
00740     // <group>
00741     ConstListIter<t> &operator=(const List<t> &);
00742     ConstListIter<t> &operator=(const List<t> *);
00743     ConstListIter<t> &operator=(const ConstListIter<t> &);
00744     ConstListIter<t> &operator=(const ConstListIter<t> *);
00745     // </group>
00746 };  
00747 
00748 // enum outside class because of compiler errors on HPUX
00749 enum {ConstListIterVersion = 1};
00750 
00751 } //#End casa namespace
00752 #ifndef CASACORE_NO_AUTO_TEMPLATES
00753 #include <casa/Containers/List.tcc>
00754 #endif //# CASACORE_NO_AUTO_TEMPLATES
00755 #endif