casa
$Rev:20696$
|
00001 //# <HashMap.h>: this defines HashMap, which is a hashed associative array 00002 //# Copyright (C) 1995,1996,1998,1999,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: HashMapIter.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $ 00027 #ifndef CASA_HASHMAPITER_H 00028 #define CASA_HASHMAPITER_H 00029 00030 00031 #include <casa/Containers/HashMap.h> 00032 00033 // <summary> 00034 // Step through a const HashMap 00035 // </summary> 00036 // <use visibility=export> 00037 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00038 // 00039 // <synopsis> 00040 // This class is an iterator, and it used to step through const 00041 // <linkto class=HashMap><src>HashMap</src></linkto>s. This is useful 00042 // when one wishes to find each of the user defined mappings in a 00043 // particular map. 00044 // </synopsis> 00045 // 00046 // <example> 00047 // <srcblock> 00048 // #include <casa/Containers/HashMap.h> 00049 // #include <casa/BasicSL/String.h> 00050 // #include <casa/iostream.h> 00051 // 00052 // main() { 00053 // HashMap<String,Int> hash; 00054 // 00055 // hash.define("one",1); 00056 // hash.define("two",2); 00057 // hash.define("three",3); 00058 // hash.define("four",4); 00059 // hash.define("five",5); 00060 // hash.define("six",6); 00061 // 00062 // ConstHashMapIter<String,Int> iter(hash); 00063 // for ( iter.toStart(); ! iter.atEnd(); iter++ ) 00064 // cout << iter.getVal() << ": " << iter.getKey() << endl; 00065 // } 00066 // </srcblock> 00067 // </example> 00068 // 00069 // <motivation> 00070 // Sometimes one needs to step through the defined elements of an 00071 // associative array. The user should be told when iterator does 00072 // not modify the underlying data structure. The standard C++ 00073 // <em>const</em> is not sufficient because while the internal 00074 // state of the iterator changes, the underlying data structure 00075 // is not modified. For this reason, both const and non-const 00076 // versions of the iterator are useful. 00077 // </motivation> 00078 // 00079 namespace casa { //#Begin casa namespace 00080 00081 template<class key, class val> class ConstHashMapIter { 00082 public: 00083 00084 // 00085 // Move the iterator to the start of the Map. 00086 // 00087 void toStart(); 00088 00089 // 00090 // Advance to the next element of the Map. 00091 // 00092 // <group> 00093 void operator++() { step(); } 00094 void operator++(int) { step(); } 00095 // </group> 00096 00097 // 00098 // Get the key or value for the current position in 00099 // the Map. 00100 // 00101 // <group> 00102 const key &getKey() const; 00103 const val &getVal() const; 00104 // </group> 00105 00106 // 00107 // Check to see if the iterator position is at the 00108 // end or beginning of the Map. 00109 // 00110 // <group> 00111 Bool atEnd() const { return atEnd_; } 00112 Bool atStart() const; 00113 // </group> 00114 00115 // 00116 // Check to see if the iterator is in a valid state. 00117 // 00118 Bool isValid() const { return Container != 0 ? True : False; } 00119 00120 // 00121 // Constructs a Map iterator from a Map (with reference semantics). 00122 // 00123 ConstHashMapIter(const HashMap<key,val> &st); 00124 00125 // 00126 // Assign one map iterator to a map (with reference semantics). 00127 // 00128 virtual ConstHashMapIter<key,val> &operator=(const HashMap<key,val> &other); 00129 00130 // 00131 // Constructs a Map iterator from another iterator (with reference semantics). 00132 // 00133 ConstHashMapIter(const ConstHashMapIter<key,val> &st); 00134 00135 // 00136 // Assign one map iterator to another iterator (with reference semantics). 00137 // 00138 virtual ConstHashMapIter<key,val> &operator=(const ConstHashMapIter<key,val> &other); 00139 00140 // 00141 // Default constructor creates an invalid Map iterator. 00142 // 00143 ConstHashMapIter() : Container(0), curBucket(0), atEnd_(False) {} 00144 00145 00146 // 00147 // Returns the default value for the Map on which this 00148 // iterator is operating if it is a valid iterator, otherwise 00149 // it throws an exception. 00150 // 00151 const val &defaultVal() const { 00152 if ( ! isValid() ) 00153 throw_invalid_hashmapiter_error(); 00154 return Container->defaultVal(); 00155 } 00156 00157 // 00158 // Allows mapping functions to be performed with the 00159 // map on which this iterator operates. If this iterator 00160 // is invalid, then an exception will be thrown. 00161 // 00162 const val &operator()(const key &ky) const { 00163 if ( ! isValid() ) 00164 throw_invalid_hashmapiter_error(); 00165 return Container->operator()(ky); 00166 } 00167 00168 // 00169 // Allows one to check to see if a given key is defined 00170 // in the map which this iterator tracks. If this iterator 00171 // is invalid, then an exception will be thrown. 00172 // 00173 Bool isDefined(const key &ky) const { 00174 if (! isValid() ) 00175 throw_invalid_hashmapiter_error(); 00176 return Container->isDefined(ky); 00177 } 00178 00179 // 00180 // Returns the number of user defined mappings 00181 // 00182 uInt ndefined() const { 00183 if (! isValid() ) 00184 throw_invalid_hashmapiter_error(); 00185 return Container->ndefined(); 00186 } 00187 00188 // 00189 // Returns the container on which this iterator is 00190 // operating. 00191 // 00192 const HashMap<key,val> &container() const { 00193 if ( !isValid() ) 00194 throw_invalid_hashmapiter_error(); 00195 return *Container; 00196 } 00197 00198 // dtor 00199 virtual ~ConstHashMapIter(); 00200 00201 protected: 00202 00203 void step(); 00204 00205 ListIter<OrderedPair<key,val> > iter; 00206 HashMap<key,val> *Container; 00207 uInt curBucket; 00208 Bool atEnd_; 00209 }; 00210 00211 00212 // <summary> 00213 // Step through a non-const HashMap 00214 // </summary> 00215 // <use visibility=export> 00216 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos=""> 00217 // 00218 // <synopsis> 00219 // This class is an iterator, and it used to step through non-const 00220 // <linkto class=HashMap><src>HashMap</src></linkto>s. This is useful 00221 // when one wishes to find each of the user defined mappings in a 00222 // particular map. 00223 // </synopsis> 00224 // 00225 // <example> 00226 // <srcblock> 00227 // #include <aips/Containers/HashMap.h> 00228 // #include <casa/BasicSL/String.h> 00229 // #include <iostream> 00230 // 00231 // main() { 00232 // HashMap<String,Int> hash; 00233 // 00234 // hash.define("one",1); 00235 // hash.define("two",2); 00236 // hash.define("three",3); 00237 // hash.define("four",4); 00238 // hash.define("five",5); 00239 // hash.define("six",6); 00240 // 00241 // HashMapIter<String,Int> iter(hash); 00242 // for ( iter.toStart(); ! iter.atEnd(); iter++ ) 00243 // cout << iter.getVal() << ": " << iter.getKey() << endl; 00244 // } 00245 // </srcblock> 00246 // </example> 00247 // 00248 // <motivation> 00249 // Same as <linkto class=ConstHashMapIter><src>ConstHashMapIter</src></linkto>, 00250 // but allows for modification of the underlying structure. 00251 // </motivation> 00252 // 00253 template<class key, class val> class HashMapIter : public ConstHashMapIter<key,val> { 00254 public: 00255 // 00256 // Get the key or value for the current position in 00257 // the Map. 00258 // 00259 // <group> 00260 val &getVal(); 00261 00262 virtual const val &getVal() const; 00263 // </group> 00264 00265 // 00266 // These functions allow for the definition and removal of key/value 00267 // relations. The "define(key &, value &)" function defines a key/value 00268 // relation, and "remove(key &)" function removes a relation if it has 00269 // been previously defined. 00270 // 00271 // <group> 00272 val &define(const key &k, const val &v) { 00273 if (!this->isValid()) 00274 throw_invalid_hashmapiter_error(); 00275 return(this->Container->define(k,v)); 00276 } 00277 void remove(const key &k) { 00278 if (!this->isValid()) 00279 throw_invalid_hashmapiter_error(); 00280 this->Container->remove(k); 00281 } 00282 // </group> 00283 00284 // 00285 // This returns the default value for the map that this iterator 00286 // is tracking. With a non-const iterator the default value can 00287 // be changed. 00288 // 00289 // <group> 00290 const val &defaultVal() const { 00291 return ConstHashMapIter<key,val>::defaultVal(); 00292 } 00293 00294 val &defaultVal() { 00295 if (!this->isValid()) 00296 throw_invalid_hashmapiter_error(); 00297 return this->Container->defaultVal(); 00298 } 00299 // </group> 00300 00301 // 00302 // Clear all of the mappings. 00303 // 00304 void clear() { 00305 if (!this->isValid()) 00306 throw_invalid_hashmapiter_error(); 00307 this->Container->clear(); 00308 } 00309 00310 // 00311 // Allows mapping functions to be performed with the 00312 // map on which this iterator operates. If this iterator 00313 // is invalid, then an exception will be thrown. With 00314 // a non-const operator, the value can be changed. 00315 // 00316 // <group> 00317 const val &operator()(const key &ky) const { 00318 return ConstHashMapIter<key,val>::operator()(ky); 00319 } 00320 00321 val &operator()(const key &ky) { 00322 if (!this->isValid()) 00323 throw_invalid_hashmapiter_error(); 00324 return(this->Container->operator()(ky)); 00325 } 00326 // </group> 00327 00328 // 00329 // This allows a MapIter to be constructed from a Map. When 00330 // created the new MapIter maintains a reference to the original 00331 // Map. If the Map to which this MapIter points is deleted, then 00332 // the MapIter is marked as invalid. 00333 // 00334 HashMapIter(HashMap<key,val> &st) : ConstHashMapIter<key,val>(st) {} 00335 00336 // 00337 // This allows a MapIter to be constructed from another MapIter. 00338 // When created the new MapIter maintains a reference to the Map 00339 // which the MapIter parameter tracked. If this Map is deleted, then 00340 // this MapIter is marked as invalid. 00341 // 00342 HashMapIter(const HashMapIter<key,val> &other) : ConstHashMapIter<key,val>(other) {} 00343 00344 // 00345 // Default constructor creates an invalid Map iterator. 00346 // 00347 HashMapIter() : ConstHashMapIter<key,val>() {} 00348 00349 00350 // 00351 // This assignment operator allows the Map which this MapIter tracks 00352 // to be changed. After a call to this operator, the MapIter will track 00353 // the Map parameter. 00354 // 00355 virtual HashMapIter<key,val> &operator=(HashMap<key,val> &other); 00356 00357 // 00358 // This assignment operator allows the Map which this MapIter tracks 00359 // to be changed. After a call to this operator, this MapIter will track 00360 // the Map which the MapIter parameter tracks, i.e. it will contain a 00361 // reference to this new Map. 00362 // 00363 virtual HashMapIter<key,val> &operator=(const HashMapIter<key,val> &other); 00364 00365 // 00366 // Returns the container on which this iterator is 00367 // operating. 00368 // 00369 // <group> 00370 HashMap<key,val> &container() { 00371 if (!this->isValid()) 00372 throw_invalid_hashmapiter_error(); 00373 return(*this->Container); 00374 } 00375 const HashMap<key,val> &container() const { 00376 if (!this->isValid()) 00377 throw_invalid_hashmapiter_error(); 00378 return(*this->Container); 00379 } 00380 // </group> 00381 00382 // dtor 00383 ~HashMapIter(); 00384 00385 protected: 00386 //*display 4 00387 // 00388 // These assignment operators are private and ONLY throw an 00389 // exception to prevent incorrect assignments to a non-const 00390 // iterator. 00391 // 00392 // <group> 00393 ConstHashMapIter<key,val> &operator=(const HashMap<key,val> &) { 00394 throw_hashmapiter_init_error(); 00395 return *this;} 00396 ConstHashMapIter<key,val> &operator=(const ConstHashMapIter<key,val> &) { 00397 throw_hashmapiter_init_error(); 00398 return *this;} 00399 // </group> 00400 00401 }; 00402 00403 } //#End casa namespace 00404 00405 #ifndef CASACORE_NO_AUTO_TEMPLATES 00406 #include <casa/Containers/HashMapIter.tcc> 00407 #endif //# CASACORE_NO_AUTO_TEMPLATES 00408 #endif