Main Page   Class Hierarchy   Compound List   File List   Compound Members  

mmap.h

00001 /***************************************************************************
00002  *   This file is part of the MagiC++ library.                             *
00003  *                                                                         *
00004  *   Copyright (C) 1998-2001 Marko Grönroos <magi@iki.fi>                  *
00005  *                                                                         *
00006  ***************************************************************************
00007  *                                                                         *
00008  *  This library is free software; you can redistribute it and/or          *
00009  *  modify it under the terms of the GNU Library General Public            *
00010  *  License as published by the Free Software Foundation; either           *
00011  *  version 2 of the License, or (at your option) any later version.       *
00012  *                                                                         *
00013  *  This library is distributed in the hope that it will be useful,        *
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      *
00016  *  Library General Public License for more details.                       *
00017  *                                                                         *
00018  *  You should have received a copy of the GNU Library General Public      *
00019  *  License along with this library; see the file COPYING.LIB.  If         *
00020  *  not, write to the Free Software Foundation, Inc., 59 Temple Place      *
00021  *  - Suite 330, Boston, MA 02111-1307, USA.                               *
00022  *                                                                         *
00023  ***************************************************************************/
00024 
00025 #ifndef __MAP_H__
00026 #define __MAP_H__
00027 
00028 #include <iostream.h>
00029 #include "magic/mobject.h"
00030 #include "magic/mmagisupp.h"
00031 #include "magic/mpararr.h"
00032 
00033 // Externals
00034 class DumpContext;
00035 
00036 class MapPair;
00037 class HashBucket;
00038 class HashFunc;
00039 class GenHash;
00040 class GenHashIter;
00041 
00044 class MapPair : public Object {
00045   public:
00046     const Comparable*   key;
00047     Object*             value;
00048     bool                isref;
00049                         MapPair     () {key=NULL; value=NULL; isref=0;}
00050                         ~MapPair    ();
00051     int                 match       (const Comparable& okey) const {return (*key) == okey;}
00052     DumpContext&        operator>>  (DumpContext& out) const;
00053     void                check       () const;
00054 
00055   private:
00056     decl_dynamic (MapPair);
00057 };
00058 
00060 
00063 class HashBucket : public Object {
00064   public:
00065     MapPair     pair;
00066     HashBucket* next;
00067 
00068                     HashBucket  ();
00069                     ~HashBucket ();
00070     DumpContext&    operator>>  (DumpContext& out) const;
00071     void            check       () const;
00072 
00073   private:
00074     decl_dynamic (HashBucket);
00075 };
00076 
00079 class HashFunc {
00080   public:
00081     virtual void    hashfunc    (int hashsize) const = 0;
00082 };
00083 
00084 EXCEPTIONCLASS (not_found);
00085 
00088 class GenHash : public Object {
00089   public:
00090 
00091                     GenHash     (int hsize=64, int flags=0) {make (NULL, hsize, flags);}
00092                     GenHash     (HashFunc* hfunc, int hsize=16, int flags=0) {
00093                         make (hfunc, hsize, flags);
00094                     }
00095     void            make        (HashFunc* hashfunc, int hsize, int flags);
00096     
00097     void            set         (const Comparable* key, Object* value);
00098     const Object*   get         (const Comparable& key) const throw (not_found);
00099     DumpContext&    operator>>  (DumpContext& out) const;
00100     ostream&        operator>>  (ostream& out) const;
00101     void            empty       ();
00102     void            remove      (const Comparable& key);
00103     void            operator+=  (const GenHash& other);
00104 
00105     void            check       () const;
00106     
00107   protected:
00108     Array<HashBucket>   hash;
00109     int                 hashsize;
00110     HashFunc*           hashfunc;
00111     bool                isref;
00112 
00113   private:
00114     decl_dynamic (GenHash);
00115     friend GenHashIter;
00116 };
00117 
00120 class GenHashIter {
00121   public:
00122 
00123                         GenHashIter (const GenHash* hash);
00124     
00125     void                first       ();
00126     void                next        ();
00127     Comparable&         getkeyv     ();
00128     Object&             getvaluev   ();
00129     const Comparable&   getkey      () const;
00130     const Object&       getvalue    () const;
00131     int                 exhausted   () const {return exh;}
00132 
00133   protected:
00134     const GenHash*  hash;
00135     int             bucket;
00136     HashBucket*     currbucket;
00137     int             exh;
00138 };
00139 
00140 EXCEPTIONCLASS (map_item_not_found);
00141 
00142 // Varsinainen käyttöliittymäluokka.
00143 // Avainluokan on oltava Comparable-perillinen, mutta arvo voi olla mikä hyvänsä
00144 
00164 template <class keyclass, class valueclass>
00165 class Map : public Object {
00166   public:
00169                         Map         () {
00170                             hash = new GenHash ();
00171                             isref = 0;
00172                             mFailByThrow=false;
00173                             mFailByThrowOnce=false;
00174                             mFailByNullOnce=false;
00175                         }
00185                         Map         (int hashsize, int flags) {
00186                             hash = new GenHash (hashsize, flags);
00187                             isref = flags & MAP_REF;
00188                             mFailByThrow=false;
00189                             mFailByThrowOnce=false;
00190                             mFailByNullOnce=false;
00191                         }
00192                         Map (const Map& orig) {
00193                             hash = new GenHash ();
00194                             isref = 0;
00195                             mFailByThrow=false;
00196                             mFailByThrowOnce=false;
00197                             mFailByNullOnce=false;
00198 
00199                             // And copy
00200                             operator= (orig);
00201                         }
00202                         ~Map            () {delete hash;}
00203 
00207     void                set             (const keyclass& key, const valueclass& value) {
00208         keyclass* nkey = new keyclass (key);
00209         valueclass* nvalue = NULL;
00210         if (isref)
00211             nvalue = const_cast<valueclass*> (&value);
00212         else
00213             nvalue = new valueclass (value);
00214         hash->set (nkey, nvalue);
00215     }
00216 
00219     void                set             (const keyclass& key, const valueclass* value) {
00220         hash->set (new keyclass (key), const_cast<valueclass*> (value));
00221     }
00222 
00225     void                remove          (const keyclass& key) {
00226         hash->remove (key);
00227     }
00228 
00230     bool                hasKey          (const keyclass& key) const {
00231         return int(hash->get (key));
00232     }
00233     
00239     const valueclass&   operator[]      (const keyclass& key) const {
00240         return get (key);
00241     }
00242 
00248     valueclass& operator[]              (const keyclass& key) {
00249         return const_cast<valueclass&> (get (key));
00250     }
00251 
00259     const valueclass&   get             (const keyclass& key) const {
00260         const valueclass& result = (valueclass&) *hash->get (key);
00261         if ((mFailByThrow || mFailByThrowOnce) && !mFailByNullOnce) {
00262             mFailByThrowOnce = false;
00263             if (isnull(result)) {
00264                 try {
00265                     const keyclass* dummy = &dynamic_cast<const keyclass&> (key);
00266                     dummy=NULL; // Have to do this to avoid a silly warning
00267                 } catch (...) {
00268                     throw map_item_not_found ("Map item not found");
00269                 }
00270                 throw map_item_not_found (format("Map item '%s' not found", (CONSTR) key));
00271             }
00272         }
00273         mFailByNullOnce = false;
00274         return result;
00275     }
00276 
00284     valueclass&         getv            (const keyclass& key) {
00285         return const_cast<valueclass&> (get (key));
00286     }
00287 
00297     const valueclass&   getOr           (const keyclass& key, const valueclass& def) const {
00298         valueclass* tmp = (valueclass*) hash->get (key);
00299         return tmp? *tmp : def;
00300     }
00301 
00307     const valueclass*   getp            (const keyclass& key) const {
00308         return (valueclass*) hash->get (key);
00309     }
00310 
00316     valueclass*         getvp           (const keyclass& key) {
00317         return (valueclass*) hash->get (key);
00318     }
00319 
00320     // Miscellaneous operators
00321 
00323     virtual DumpContext&            operator>>  (DumpContext& out) const {
00324         hash->operator>> (out);
00325         return out;
00326     }
00327 
00329     virtual ostream&            operator>>      (ostream& out) const {
00330         hash->operator>> (out);
00331         return out;
00332     }
00333 
00335     Map<keyclass,valueclass>&   operator+=  (const Map<keyclass,valueclass>& other) {
00336         hash->operator+= (*other.hash);
00337         return *this;
00338     }
00339 
00341     Map<keyclass,valueclass>&   operator=   (const Map<keyclass,valueclass>& other) {
00342         hash->empty ();
00343         hash->operator+= (*other.hash);
00344         isref = other.isref;
00345         mFailByThrow=other.mFailByThrow;
00346         mFailByThrowOnce=other.mFailByThrowOnce;
00347         mFailByNullOnce=other.mFailByNullOnce;
00348         return *this;
00349     }
00350 
00353     void                empty           () {
00354         hash->empty ();
00355     }
00356 
00359     const GenHash*      gethash         () const {return hash;}
00360 
00362     void                check           () const {hash->check();}
00363 
00371     void failByThrow (bool bythrow=true) {mFailByThrow=bythrow;}
00372 
00379     void                failByThrowOnce (bool bythrow=true) const {mFailByThrowOnce=bythrow;}
00380 
00387     void                failByNullOnce  (bool bynull=true) const {mFailByNullOnce=bynull;}
00388     
00389   private:
00390     GenHash*        hash;
00391     bool            isref;
00392     bool            mFailByThrow;
00393     mutable bool    mFailByThrowOnce, mFailByNullOnce;
00394 };
00395 
00396 enum mapdefs {MAP_NONE=0, MAP_REF=1};
00397 
00398 #define CMap Map
00399 
00404 #define getOrDefault(map,key,def)\
00405     (isnull(map[key])? def : map[key])
00406 
00407 
00408 
00410 //                    |   |            ---                                  //
00411 //                    |\ /|  ___   --   |   |   ___                         //
00412 //                    | V |  ___| |  )  |  -+- /   ) |/\                    //
00413 //                    | | | (   | |--   |   |  |---  |                      //
00414 //                    |   |  \__| |    _|_   \  \__  |                      //
00416 
00432 template <class keyclass, class valueclass>
00433 class MapIter {
00434   public:
00435     MapIter (const Map<keyclass,valueclass>& map) : iter (map.gethash()) {;}
00436 
00438     void                first       () {iter.first();}
00439 
00441     void                next        () {iter.next();}
00442 
00446     const keyclass&     key         () const {return (const keyclass&) iter.getkey();}
00447 
00451     keyclass&           key         () {return (keyclass&) iter.getkeyv();}
00452 
00456     const valueclass&   value       () const {return (const valueclass&) iter.getvalue();}
00457 
00461     valueclass&         value       () {return (valueclass&) iter.getvaluev();}
00462 
00466     int                 exhausted   () const {return iter.exhausted();}
00467 
00468   protected:
00469     GenHashIter iter;
00470 };
00471 
00478 #define forMap(keytype,valuetype,mapname,varname) \
00479     for (MapIter<keytype,valuetype> varname (mapname); !varname.exhausted(); varname.next())
00480 
00481 
00482 
00484 //                ----         o             |   |                          //
00485 //               (      |          _         |\ /|  ___   --                //
00486 //                ---  -+- |/\ | |/ \   ___  | V |  ___| |  )               //
00487 //                   )  |  |   | |   | (   \ | | | (   | |--                //
00488 //               ___/    \ |   | |   |  ---/ |   |  \__| |                  //
00489 //                                      __/                                 //
00491 
00492 // StringMap is just an alias
00493 typedef Map<String,String> StringMap;
00494 
00495 // Reads String Map from file. Throws exception file_not_found if
00496 // opening fails.
00497 StringMap readStringMap (const String& filename);
00498 
00499 // Reads String Map from stream
00500 StringMap readStringMap (istream& in, const char* path=NULL);
00501 
00502 void writeStringMap (const Map<String,String>& map, ostream& out);
00503 
00507 String toString (const StringMap& map);
00508 
00514 void splitpairs (StringMap& trg, const String& source, char psep='=', char rsep='&');
00515 
00521 String joinpairs (const StringMap& src, char psep='=', char rsep='&');
00522 
00523 
00531 #define forStringMap(mapname,varname) \
00532     for (MapIter<String,String> varname (mapname); !varname.exhausted(); varname.next())
00533 
00534 #endif

Generated at Tue Dec 4 19:53:26 2001 for MagiC++ by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001