casa
$Rev:20696$
|
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