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