casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Map.h
Go to the documentation of this file.
00001 //# Map.h: Associative array classes
00002 //# Copyright (C) 1994,1995,1999,2000
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: Map.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $
00027 
00028 #ifndef CASA_MAP_H
00029 #define CASA_MAP_H
00030 
00031 
00032 //# Includes
00033 #include <casa/aips.h>
00034 #include <casa/Exceptions/Error.h>
00035 
00036 //
00037 // Work around bugs in SUN\'s stupid compiler
00038 //
00039 #define AIPS_STUPID_SUN 1
00040 
00041 namespace casa { //#Begin casa namespace
00042 
00043 //# Forward Declarations
00044 class AipsIO;
00045 
00046 extern void throw_mapiter_init_error();
00047 extern void throw_map_init_error();
00048 extern void throw_invalid_mapiter_error();
00049 extern void throw_map_constop_error();
00050 
00051 template<class key, class value> class MapIterRep;
00052 template<class key, class value> class ConstMapIter;
00053 template<class key, class value> class Map;
00054 
00055 // <summary>Map representation class </summary>
00056 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00057 // </reviewed>
00058 
00059 template<class key, class value> class MapRep {
00060 public:
00061 
00062   //
00063   //  This is the only MapRep constructor. It takes as a parameter the
00064   //  default value for the map.
00065   //
00066   MapRep(const value &dflt) : DefaultVal(dflt) { }
00067 
00068   //
00069   //  This is the mapping function which maps keys to values. If the
00070   //  map from the key to a value is not defined, a mapping will be
00071   //  defined from the key to the default value (which is set from
00072   //  the constructor. The "isDefined()" member function can be used
00073   //  to check to see if a mapping is defined before using the
00074   //  "operator()()".
00075   //
00076   //  <note> With a constant map in the case where the key is not
00077   //         defined, the mapping between key and default value is 
00078   //         not created, but rather an exception is thrown.
00079   //  </note>
00080   //+grp
00081   value &operator()(const key &ky);
00082   const value &operator()(const key &ky) const;
00083   //-grp
00084 
00085   //
00086   // Returns the default value for the Map.
00087   //
00088   //+grp
00089   value &defaultVal() {return DefaultVal;}
00090   const value &defaultVal() const {return DefaultVal;}
00091   //-grp
00092 
00093   //
00094   // Returns a non-zero value if a mapping is defined for
00095   // the key parameter.
00096   //
00097   //+grp
00098   virtual const value *isDefined(const key &) const = 0;
00099   virtual value *isDefined(const key &) = 0;
00100   //-grp
00101 
00102   //
00103   // Returns the number of user defined mappings
00104   //
00105   virtual uInt ndefined() const = 0;
00106 
00107   //
00108   //  These functions allow for the definition and removal of key/value
00109   //  relations. The "define(key &, value &)" call defines a key/value
00110   //  relation, and "remove(key &)" removes a relation if it has
00111   //  been previously defined.
00112   //
00113   //+grp
00114   virtual value &define(const key &, const value &) = 0;
00115   virtual void remove(const key &) = 0;
00116   //-grp
00117 
00118   //
00119   // Clear all of the mappings.
00120   //
00121   virtual void clear() = 0;
00122 
00123   virtual MapIterRep<key,value> *getRep(Map<key,value>*) const = 0;
00124 
00125   virtual MapRep<key,value> *Clone() const = 0;
00126 
00127   //
00128   // Does nothing.
00129   //
00130   virtual ~MapRep();
00131 
00132   enum {MapRepVersion = 1};
00133 
00134 protected:
00135 
00136   //  This is the default value which is return when no match is found.
00137   //  This prevents this class from being a PartialMap.
00138   value DefaultVal;
00139 
00140 };
00141 
00142 
00143 //
00144 // <category lib=aips sect="Containers">
00145 // <summary>Abstract base class for associative arrays</summary>
00146 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00147 // </reviewed>
00148 //
00149 //  This is the abstract class for all "Map" classes which implement the
00150 //  equivalent of an associative array.
00151 //
00152 template<class key, class value> class Map
00153 {
00154 public:
00155 
00156   //
00157   //  This is the mapping function which maps keys to values. If the
00158   //  map from the key to a value is not defined, a mapping will be
00159   //  defined from the key to the default value (which is set from
00160   //  the constructor. The "isDefined()" member function can be used
00161   //  to check to see if a mapping is defined before using the
00162   //  "operator()()".
00163   //
00164   //  <note> With a constant map in the case where the key is not
00165   //         defined, the mapping between key and default value is 
00166   //         not created, but rather an exception is thrown.
00167   //  </note>
00168   //+grp
00169   value &operator()(const key &ky);
00170   const value &operator()(const key &ky) const;
00171   //-grp
00172 
00173 
00174   //
00175   // Returns the default value for the Map.
00176   //
00177   //+grp
00178   value &defaultVal();
00179   const value &defaultVal() const;
00180   //-grp
00181 
00182   //
00183   // Returns a non-zero value if a mapping is defined for
00184   // the key parameter.
00185   //
00186   //+grp
00187   const value *isDefined(const key &k) const;
00188   value *isDefined(const key &k);
00189   //-grp
00190 
00191   //
00192   // Returns the number of user defined mappings
00193   //
00194   uInt ndefined() const;
00195 
00196   //
00197   //  These functions allow for the definition and removal of key/value
00198   //  relations. The "define(key &, value &)" call defines a key/value
00199   //  relation, and "remove(key &)" removes a relation if it has
00200   //  been previously defined.
00201   //
00202   //+grp
00203   value &define(const key &k, const value &v);
00204   void remove(const key &k);
00205   //-grp
00206 
00207   //
00208   // Clear all of the mappings.
00209   //
00210   void clear();
00211 
00212   //
00213   // Returns the iterator rep appropriate for this particular Map
00214   //
00215   MapIterRep<key,value> *getRep() const;
00216 
00217   //
00218   // This copy constructor will, for the moment, be the only
00219   // way to create a map.
00220   //
00221   //+grp
00222   Map(const Map<key,value> &m);
00223   Map(const Map<key,value> *m);
00224   //-grp
00225 
00226   Map<key,value> &operator=(const Map<key,value> &);
00227   Map<key,value> &operator=(const Map<key,value> *);
00228 
00229   //*display 2
00230   //
00231   // Does nothing.
00232   //
00233   virtual ~Map();
00234 
00235   enum {MapVersion = 1};
00236 
00237 #if defined(AIPS_STUPID_SUN)
00238   ConstMapIter<key,value> *getIter() const;
00239 #endif
00240 
00241 protected:
00242 
00243   MapRep<key,value> *Rep;
00244 
00245   //
00246   // Used by derived classes
00247   //
00248   Map(MapRep<key,value> *nRep);
00249 
00250   //
00251   // Used the set the representation.
00252   // Always DELETES Rep if necessary.
00253   //
00254   void SetRep(MapRep<key,value> *st) {
00255     if (Rep) 
00256       delete Rep;
00257     Rep = st;
00258   }
00259 
00260 };
00261 
00262 //
00263 // <category lib=aips sect="Containers">
00264 // <summary>Abstract base class for associative array iterators</summary>
00265 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00266 // </reviewed>
00267 //
00268 // This is the abstract base class for all (Const)MapIter
00269 // "letters". That is all Map specializations must provide
00270 // a "IterRep" for the particular specialization which
00271 // will allow the (Const)MapIter envelope to traverse the
00272 // new type of map.
00273 //
00274 template<class key, class value> class MapIterRep {
00275 public:
00276 
00277   //
00278   // Check to see if the iterator is in a valid state.
00279   //
00280   virtual Bool isValid() const = 0;
00281 
00282   //
00283   // Check to see if the iterator position is at the 
00284   // end or beginning of the Map.
00285   //
00286   //+grp
00287   virtual Bool atEnd() const = 0;
00288   virtual Bool atStart() const = 0;
00289   //-grp
00290 
00291   //
00292   // Move the iterator to the start of the Map.
00293   //
00294   virtual void toStart() = 0;
00295 
00296   //
00297   // Advance to the next element of the Map.
00298   //
00299   //+grp
00300   virtual void operator++() = 0;
00301   virtual void operator++(int) = 0;
00302   //-grp
00303 
00304   //
00305   // Get the key for the current position in 
00306   // the Map.
00307   //
00308   virtual const key &getKey() const = 0;
00309 
00310   //
00311   // Return the value at the current location of the map iterator.
00312   // Should throw an exception if the iterator is "past the end of 
00313   // the Map" or if the iterator is invalid.
00314   //
00315   //+grp
00316   virtual value &getVal() = 0;
00317   virtual const value &getVal() const = 0;
00318   //-grp
00319 
00320   //
00321   // This returns the default value for the map that this iterator
00322   // is tracking. With a non-const iterator the default value can
00323   // be changed.
00324   //
00325   //+grp
00326   const value &defaultVal() const;
00327   value &defaultVal();
00328   //-grp
00329 
00330   //
00331   //  These functions allow for the definition and removal of key/value
00332   //  relations. The "define(key &, value &)" function defines a key/value
00333   //  relation, and "remove(key &)" function removes a relation if it has
00334   //  been previously defined.
00335   //
00336   //+grp
00337   value &define(const key &ky, const value &val);
00338   void remove(const key &ky);
00339   //-grp
00340 
00341   //
00342   // Clear all of the mappings.
00343   //
00344   void clear();
00345     
00346 
00347   //
00348   // Allows mapping functions to be performed with the
00349   // map on which this iterator operates. If this iterator
00350   // is invalid, then an exception will be thrown. With
00351   // a non-const operator, the value can be changed.
00352   //
00353   //+grp
00354   const value &operator()(const key &ky) const;
00355   value &operator()(const key &ky);
00356   //-grp
00357 
00358   //
00359   // Allows one to check to see if a given key is defined
00360   // in the map which this iterator tracks. If this iterator
00361   // is invalid, then an exception will be thrown. With
00362   // a non-const iterator the returned pointer can be used
00363   // to change the value in the map.
00364   //
00365   //+grp
00366   const value *isDefined(const key &ky) const;
00367   value *isDefined(const key &ky);
00368   //-grp
00369 
00370   //
00371   // Returns the number of user defined mappings
00372   //
00373   uInt ndefined() const;
00374 
00375   //
00376   // Returns the container on which this iterator is
00377   // operating.
00378   //
00379   //+grp
00380   Map<key,value> &container();
00381   const Map<key,value> &container() const;
00382   //-grp
00383 
00384   //
00385   // Duplicate a map iterator
00386   //
00387   //+grp
00388   virtual MapIterRep<key,value> *Clone() = 0;
00389   //-grp
00390 
00391   //
00392   // This allows a MapIter to be constructed from a Map. When
00393   // created the new MapIter maintains a reference to the original
00394   // Map. If the Map to which this MapIter points is deleted, then
00395   // the MapIter is marked as invalid.
00396   //
00397   //+grp
00398   MapIterRep(Map<key,value> &st);
00399   MapIterRep(Map<key,value> *st);
00400   //-grp
00401 
00402   virtual ~MapIterRep();
00403 
00404   enum {MapIterRepVersion = 1};
00405 
00406 protected:
00407 
00408   Map<key,value> *Container;
00409 
00410 };
00411 
00412 //
00413 // <category lib=aips sect="Containers">
00414 // <summary>Const associative array iterator</summary>
00415 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00416 // </reviewed>
00417 //
00418 // This class implements the mechanism for traversing constant
00419 // associative arrays, i.e. "Map"s. This allows one to move
00420 // the cursor to the beginning of the map and serially traverse
00421 // the map. The key and value elements can be extracted at
00422 // each position in the Map. For example:
00423 // <code>
00424 //   template<class key,class value> void print(const Map<key,value> &xx){
00425 //     ConstMapIter<key,value> x(xx);
00426 //     x.toStart();
00427 //     while (!x.atEnd()) {
00428 //       cout << "(" << x.getKey() << "," << x.getVal() << ")" << " ";
00429 //       x++;
00430 //     }
00431 //     cout << endl;
00432 //  }
00433 // </code>
00434 // This example declares a templated function which accepts a const
00435 // Map as a parameter, and iterates through the map displaying the
00436 // key/value pairs at each positon.
00437 //
00438 template<class key, class value> class ConstMapIter
00439 {
00440 public:
00441 
00442   //
00443   // Move the iterator to the start of the Map.
00444   //
00445   virtual void toStart();
00446 
00447   //
00448   // Advance to the next element of the Map.
00449   //
00450   //+grp
00451   virtual void operator++();
00452   virtual void operator++(int);
00453   //-grp
00454 
00455   //
00456   // Get the key or value for the current position in 
00457   // the Map.
00458   //
00459   //+grp
00460   virtual const key &getKey() const;
00461   virtual const value &getVal() const;
00462   //-grp
00463 
00464   //
00465   // Check to see if the iterator position is at the 
00466   // end or beginning of the Map.
00467   //
00468   //+grp
00469   virtual Bool atEnd() const;
00470   virtual Bool atStart() const;
00471   //-grp
00472 
00473   //
00474   // Check to see if the iterator is in a valid state.
00475   //
00476   virtual Bool isValid() const;
00477 
00478   //
00479   // Constructs a Map iterator from a Map (with reference semantics).
00480   //
00481   //+grp
00482   ConstMapIter(const Map<key,value> *st);
00483   ConstMapIter(const Map<key,value> &st);
00484   //-grp
00485 
00486   //
00487   // Assign one map iterator to a map (with reference semantics).
00488   //
00489   //+grp
00490   virtual ConstMapIter<key,value> &operator=(const Map<key,value> &other);
00491   virtual ConstMapIter<key,value> &operator=(const Map<key,value> *other);
00492   //-grp
00493 
00494   //
00495   // Constructs a Map iterator from another iterator (with reference semantics).
00496   //
00497   //+grp
00498   ConstMapIter(const ConstMapIter<key,value> *st);
00499   ConstMapIter(const ConstMapIter<key,value> &st);
00500 
00501   //-grp
00502 
00503   //
00504   // Assign one map iterator to another iterator (with reference semantics).
00505   //
00506   //+grp
00507   virtual ConstMapIter<key,value> &operator=(const ConstMapIter<key,value> &other);
00508   virtual ConstMapIter<key,value> &operator=(const ConstMapIter<key,value> *other);
00509   //-grp
00510 
00511   //
00512   // Default constructor creates an invalid Map iterator.
00513   //
00514   ConstMapIter() : Rep(0) {}
00515 
00516   
00517   //
00518   // Returns the default value for the Map on which this
00519   // iterator is operating if it is a valid iterator, otherwise
00520   // it throws an exception.
00521   //
00522   const value &defaultVal() const;
00523 
00524   //
00525   // Allows mapping functions to be performed with the
00526   // map on which this iterator operates. If this iterator
00527   // is invalid, then an exception will be thrown.
00528   //
00529   const value &operator()(const key &ky) const;
00530 
00531   //
00532   // Allows one to check to see if a given key is defined
00533   // in the map which this iterator tracks. If this iterator
00534   // is invalid, then an exception will be thrown.
00535   //
00536   const value *isDefined(const key &ky) const;
00537 
00538   //
00539   // Returns the number of user defined mappings
00540   //
00541   uInt ndefined() const;
00542 
00543   //
00544   // Returns the container on which this iterator is
00545   // operating.
00546   //
00547   const Map<key,value> &container() const;
00548 
00549   virtual ~ConstMapIter();
00550 
00551   enum {ConstMapIterVersion = 1};
00552 
00553 protected:
00554   MapIterRep<key,value> *Rep;
00555 
00556   //
00557   // Dummy used to initialization by derived classes.
00558   //
00559   ConstMapIter(MapIterRep<key,value> *st) : Rep(st) {}
00560 
00561   //
00562   // Always DELETES Rep if necessary
00563   //
00564   void SetRep(MapIterRep<key,value> *st) {
00565     if (Rep) 
00566       delete Rep;
00567     Rep = st;
00568   }
00569 
00570 };
00571 
00572 
00573 //#
00574 //
00575 // <category lib=aips sect="Containers">
00576 // <summary>Associative array iterator</summary>
00577 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00578 // </reviewed>
00579 //
00580 // This class implements the mechanism for traversing associative 
00581 // arrays, i.e. "Map"s. It provides the traversal mechanisms of the
00582 // ConstMapIter, but adds the mechansims to modify the values, and
00583 // perform other modification functions which the Maps provide, e.g.
00584 // define(). 
00585 //
00586 template<class key, class value> class MapIter : virtual public ConstMapIter<key,value> {
00587 public:
00588 
00589   //
00590   // Return the value at the current location of the map iterator.
00591   // Should throw an exception if the iterator is "past the end of 
00592   // the Map" or if the iterator is invalid.
00593   //
00594   //+grp
00595   virtual value &getVal();
00596 
00597   virtual const value &getVal() const;
00598   //-grp
00599 
00600   //
00601   //  These functions allow for the definition and removal of key/value
00602   //  relations. The "define(key &, value &)" function defines a key/value
00603   //  relation, and "remove(key &)" function removes a relation if it has
00604   //  been previously defined.
00605   //
00606   //+grp
00607   value &define(const key &ky, const value &val) {
00608     if (!this->isValid())
00609       throw_invalid_mapiter_error();
00610     return(this->Rep->define(ky,val));
00611   }
00612   void remove(const key &ky) {
00613     if (!this->isValid())
00614       throw_invalid_mapiter_error();
00615     this->Rep->remove(ky);
00616   }
00617   //-grp
00618 
00619   //
00620   // This returns the default value for the map that this iterator
00621   // is tracking. With a non-const iterator the default value can
00622   // be changed.
00623   //
00624   //+grp
00625   const value &defaultVal() const {
00626     return ConstMapIter<key,value>::defaultVal();
00627   }
00628 
00629   value &defaultVal() {
00630     if (!this->isValid())
00631       throw_invalid_mapiter_error();
00632     return this->Rep->defaultVal();
00633   }
00634   //-grp
00635 
00636   //
00637   // Clear all of the mappings.
00638   //
00639   void clear() {
00640     if (!this->isValid())
00641       throw_invalid_mapiter_error();
00642     this->Rep->clear();
00643   }
00644 
00645   //
00646   // Allows mapping functions to be performed with the
00647   // map on which this iterator operates. If this iterator
00648   // is invalid, then an exception will be thrown. With
00649   // a non-const operator, the value can be changed.
00650   //
00651   //+grp
00652   const value &operator()(const key &ky) const {
00653     return ConstMapIter<key,value>::operator()(ky);
00654   }
00655 
00656   value &operator()(const key &ky) {
00657     if (!this->isValid())
00658       throw_invalid_mapiter_error();
00659     return(this->Rep->operator()(ky));
00660   }
00661   //-grp
00662 
00663   //
00664   // Allows one to check to see if a given key is defined
00665   // in the map which this iterator tracks. If this iterator
00666   // is invalid, then an exception will be thrown. With
00667   // a non-const iterator the returned pointer can be used
00668   // to change the value in the map.
00669   //
00670   //+grp
00671   const value *isDefined(const key &ky) const {
00672     return ConstMapIter<key,value>::isDefined(ky);
00673   }
00674 
00675   value *isDefined(const key &ky) {
00676     if (!this->isValid())
00677       throw_invalid_mapiter_error();
00678     return(this->Rep->isDefined(ky));
00679   }
00680   //-grp
00681 
00682   //
00683   // This allows a MapIter to be constructed from a Map. When
00684   // created the new MapIter maintains a reference to the original
00685   // Map. If the Map to which this MapIter points is deleted, then
00686   // the MapIter is marked as invalid.
00687   //
00688   //+grp
00689   MapIter(Map<key,value> *other) : 
00690               ConstMapIter<key,value>(other ? other->getRep() : 0) {}
00691   MapIter(Map<key,value> &st) : ConstMapIter<key,value>(st.getRep()) {}
00692   //-grp
00693 
00694   //
00695   // This allows a MapIter to be constructed from another MapIter. 
00696   // When created the new MapIter maintains a reference to the Map
00697   // which the MapIter parameter tracked. If this Map is deleted, then
00698   // this MapIter is marked as invalid.
00699   //
00700   //+grp
00701   MapIter(const MapIter<key,value> &other) : 
00702               ConstMapIter<key,value>(other.isValid() ? other.Rep->Clone() : 0) {}
00703 
00704   MapIter(const MapIter<key,value> *other) : 
00705               ConstMapIter<key,value>(other && (*other).isValid() ? other->Rep->Clone() : 0) {}
00706   //-grp
00707 
00708   //
00709   // Default constructor creates an invalid Map iterator.
00710   //
00711   MapIter() : ConstMapIter<key,value>() {}
00712 
00713 
00714   //
00715   // This assignment operator allows the Map which this MapIter tracks
00716   // to be changed. After a call to this operator, the MapIter will track
00717   // the Map parameter.
00718   //
00719   //+grp
00720   virtual MapIter<key,value> &operator=(Map<key,value> &other);
00721 
00722   virtual MapIter<key,value> &operator=(Map<key,value> *other);
00723   //-grp
00724 
00725   //
00726   // This assignment operator allows the Map which this MapIter tracks
00727   // to be changed. After a call to this operator, this MapIter will track
00728   // the Map which the MapIter parameter trackes, i.e. it will contain a
00729   // reference to this new Map.
00730   //
00731   //+grp
00732   virtual MapIter<key,value> &operator=(const MapIter<key,value> &other);
00733 
00734   virtual MapIter<key,value> &operator=(const MapIter<key,value> *other);
00735   //-grp
00736   
00737   //
00738   // Returns the container on which this iterator is
00739   // operating.
00740   //
00741   //+grp
00742   Map<key,value> &container() { 
00743     return(this->Rep->container());}
00744   const Map<key,value> &container() const {
00745     return(ConstMapIter<key,value>::container());}
00746   //-grp
00747 
00748   ~MapIter() {}
00749 
00750   enum {MapIterVersion = 1};
00751 
00752 protected:
00753   //*display 4
00754   //
00755   // These assignment operators are private and ONLY throw an 
00756   // exception to prevent incorrect assignments to a non-const
00757   // iterator.
00758   //
00759   //+grp
00760   ConstMapIter<key,value> &operator=(const Map<key,value> &) {
00761     throw_mapiter_init_error();
00762     return *this;}
00763   ConstMapIter<key,value> &operator=(const Map<key,value> *) {
00764     throw_mapiter_init_error();
00765     return *this;}
00766   ConstMapIter<key,value> &operator=(const ConstMapIter<key,value> &) {
00767     throw_mapiter_init_error();
00768     return *this;}
00769   ConstMapIter<key,value> &operator=(const ConstMapIter<key,value> *) {
00770     throw_mapiter_init_error();
00771     return *this;}
00772   //-grp
00773 
00774 };
00775 
00776 } //#End casa namespace
00777 #ifndef CASACORE_NO_AUTO_TEMPLATES
00778 #include <casa/Containers/Map.tcc>
00779 #endif //# CASACORE_NO_AUTO_TEMPLATES
00780 #endif