casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
HashMapIter.h
Go to the documentation of this file.
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