Go to Overview over all GrAL packages.
Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

Container/bijective-mapping.h

Go to the documentation of this file.
00001 #ifndef NMWR_GB_BIJECTIVE_MAPPING_H
00002 #define NMWR_GB_BIJECTIVE_MAPPING_H
00003 
00004 
00005 // $LICENSE
00006 
00007 // namespace sgistl {
00008 #include "Container/my-hash-map.h" // STL
00009 //}
00010 //using namespace std;
00011 // using sgistl::hash;
00012 // using sgistl::hash_map;
00013 
00014 
00015 #include "Container/mapped-value-iterator.h"
00016 #include "Utility/pre-post-conditions.h"
00017 
00081 template<class T1, class T2>
00082 class bijective_mapping;
00083 
00084 template<class T1, class T2>
00085 class inverse_mapping;
00086 
00087 template<class T1, class T2>
00088 class domain_of_bijective_mapping;
00089 
00090 template<class T1, class T2>
00091 class range_of_bijective_mapping;
00092 
00093 //----------------------------------------------------------------
00094 //          [0] output facilities
00095 //----------------------------------------------------------------
00096 
00100 template<class T1, class T2>
00101 void write_bm(bijective_mapping<T1,T2> const& m, ostream& out);
00102 
00106 template<class T1, class T2>
00107 void read_bm(bijective_mapping<T1,T2>       & m, istream& in);
00108 
00112 template<class T1, class T2>
00113 class printer_of_bij_mapping {
00114 private:
00115   bijective_mapping<T1,T2> const* mp;
00116 public:
00117   printer_of_bij_mapping(bijective_mapping<T1,T2> const& m) : mp(&m) {}
00118 
00119   friend ostream& operator<<(ostream& out, printer_of_bij_mapping<T1,T2> const& p)
00120     { write_bm(*(p.mp),out); return out;}
00121 
00122 };
00123 
00135 template<class T1, class T2>
00136 inline printer_of_bij_mapping<T1,T2>
00137 Printer(bijective_mapping<T1,T2> const& m)
00138 { return printer_of_bij_mapping<T1,T2>(m);}
00139 
00140 //----------------------------------------------------------------
00141 //          [1] class bijective_mapping<T1,T2>
00142 //----------------------------------------------------------------
00143 
00148 template<class T1, class T2>
00149 class bijective_mapping {
00150 public:
00151   typedef inverse_mapping<T1,T2>              inverse_type;
00152   typedef domain_of_bijective_mapping<T1,T2>  domain_type;
00153   typedef range_of_bijective_mapping <T1,T2>  range_type;
00154 
00155   template<class U, class R> friend class bijective_mapping;
00156   template<class U, class R> friend class inverse_mapping;
00157   template<class U, class R> friend class domain_of_bijective_mapping;
00158   template<class U, class R> friend class range_of_bijective_mapping;
00159   
00160   // STL unary function conformance
00161   typedef T1                         argument_type;
00162   typedef T2                         result_type;
00163 
00164 private:
00165   typedef std::hash_map<T1,T2, std::hash<T1>,std::equal_to<T1> >  map_table_type;
00166   typedef std::hash_map<T2,T1, std::hash<T2>,std::equal_to<T2> >  inv_table_type; 
00167   //--------------- DATA -------------------------
00168 
00169   map_table_type         the_map;
00170   mutable inv_table_type the_inverse_map;
00171 
00172   // flag if the_inverse_map really reflects the inverse mapping
00173   mutable bool                       inverse_ok;
00174 
00175   //-------  internal types ----------------
00176 
00177   typedef typename map_table_type::const_iterator map_iterator;
00178 public:
00179   typedef bijective_mapping<T1,T2>   self;
00180   
00181   //---------- construction ----------------
00182 
00184   bijective_mapping() : inverse_ok(false) {}
00186   bijective_mapping(unsigned sz) : the_map(sz), the_inverse_map(sz), inverse_ok(false) {}
00188   bijective_mapping(inverse_mapping<T2,T1> const& inv);
00189 
00190   //---------- data access -----------------
00191 
00193   const T2& operator()(const T1& t1) const {
00194     REQUIRE( (the_map.find(t1) != the_map.end()), 
00195              "map not defined for item " << t1 << '\n',1);
00196     return (*(the_map.find(t1))).second;
00197   }
00199   const T2& operator[](const T1& t1) const {
00200     REQUIRE( (the_map.find(t1) != the_map.end()), 
00201              "map not defined for item " << t1 << '\n',1);
00202     return (*(the_map.find(t1))).second;
00203   }
00205   T2& operator[](const T1& t1) { return the_map[t1];}
00206 
00208   bool defined(const T1& t1) const { return (the_map.find(t1) != the_map.end());}
00209 
00210 
00211   //-------------- related functions and sets ----------------
00212 
00214   inverse_type inverse() const;
00215 
00217   domain_type domain() const;
00219   range_type  range()  const;
00220 
00221   typedef typename map_table_type::size_type  size_type;
00223   size_type size() const { return domain().size();}
00224 
00225 
00226 private:
00227   //--------------- consistency -------------------------------
00228 
00229   void update_inverse() const {
00230     if(! inverse_ok) {
00231       calculate_inverse();
00232       (bool&)inverse_ok = true;
00233     }
00234 
00235   }
00236   void calculate_inverse() const;
00237 };
00238 
00239 
00240 //-----------------------------------------------------------------
00241 //          [2]  class inverse_mapping<T1,T2>
00242 //-----------------------------------------------------------------
00243 
00253 template<class T1, class T2>
00254 class inverse_mapping {
00255 private:
00256   typedef bijective_mapping<T1,T2> mapping_type;
00257   template<class U, class R> friend class bijective_mapping;
00258 
00259   //-------- DATA ----------
00260   const  mapping_type*    bmap; // reference
00261 
00262 public:
00263   inverse_mapping(const mapping_type& tm) : bmap(&tm) {}
00264 
00265   const T1& operator()(const T2& t2) const { 
00266     bmap->update_inverse();
00267     REQUIRE( (defined(t2)),
00268             "inverse map not defined for item " << t2 << '\n',1);
00269     return (*(bmap->the_inverse_map.find(t2))).second;
00270   }
00271 
00272   bool defined(const T2& t2) const {
00273     bmap->update_inverse();
00274     return (bmap->the_inverse_map.find(t2) != bmap->the_inverse_map.end());
00275   }
00276 
00277   typedef typename mapping_type::domain_type range_type;
00278   inline range_type   range() const;
00279   typedef typename mapping_type::range_type  domain_type;
00280   inline domain_type  domain() const;
00281 };
00282 
00283 //-----------------------------------------------------------------
00284 //           [3]  class domain_of_bijective_mapping<T1,T2>
00285 //-----------------------------------------------------------------
00286 
00302 template<class T1, class T2>
00303 class domain_of_bijective_mapping {
00304 public:
00305   typedef bijective_mapping<T1,T2>                         mapping_type;
00306   typedef typename mapping_type::map_table_type            map_table_type;
00307   typedef typename map_table_type::value_type              base_value_type;
00308   typedef typename map_table_type::const_iterator          base_iter_type;
00309   typedef mapped_value_const_iterator<base_iter_type,
00310                                       get_first<base_value_type> > const_iterator;
00311 
00312   typedef T1                                                value_type;
00313 
00314 private:
00315   const mapping_type*  bmap; // reference to mapping f
00316 public:
00317   domain_of_bijective_mapping(const mapping_type& tm) : bmap(&tm) {}
00318 
00319   unsigned size() const { return bmap->the_map.size();}
00320 
00322   bool is_member(const value_type& x) const { return bmap->defined(x);}  
00323 
00324   const_iterator begin() const { return const_iterator(bmap->the_map.begin());}
00325   const_iterator end()   const { return const_iterator(bmap->the_map.end());}
00326   
00327   T1 const& front() const { return *begin();}
00328 };
00329 
00330 //-----------------------------------------------------------------
00331 //          [4]   class range_of_bijective_mapping<T1,T2>
00332 //-----------------------------------------------------------------
00333 
00345 template<class T1, class T2>
00346 class range_of_bijective_mapping {
00347 public:
00348   typedef bijective_mapping<T1,T2>                         mapping_type;
00349   typedef typename mapping_type::map_table_type            map_table_type;
00350   typedef typename map_table_type::value_type              base_value_type;
00351   typedef typename map_table_type::const_iterator          base_iter_type;
00352   typedef mapped_value_const_iterator<base_iter_type,
00353                                       get_second<base_value_type> > const_iterator;
00354 
00355   typedef T2                                                     value_type;
00356 
00357 private:
00358   const mapping_type*  bmap; // reference
00359 public:
00360   range_of_bijective_mapping(const mapping_type& tm)  : bmap(&tm) {}
00361 
00362   unsigned size() const { return bmap->the_map.size();}
00363   bool is_member(const value_type& x) const { 
00364     bmap->update_inverse();    
00365     return (bmap->the_inverse_map.find(x) != bmap->the_inverse_map.end());
00366   }  
00367 
00368   const_iterator begin() const { return const_iterator(bmap->the_map.begin());}
00369   const_iterator end()   const { return const_iterator(bmap->the_map.end());}
00370   T2 const& front() const { return *begin();}
00371 };
00372 
00373 
00374 //-----------------------------------------------------------------
00375 //         inline functions of bijective_mapping<T1,T2>
00376 //-----------------------------------------------------------------
00377 
00378 
00379 template<class T1, class T2>
00380 inline
00381 inverse_mapping<T1,T2> bijective_mapping<T1,T2>::inverse() const 
00382 { return inverse_type(*this);}
00383 
00384 template<class T1, class T2>
00385 inline
00386 domain_of_bijective_mapping<T1,T2> bijective_mapping<T1,T2>::domain() const 
00387 { return domain_type(*this);}
00388  
00389 template<class T1, class T2>
00390 inline
00391 range_of_bijective_mapping<T1,T2> bijective_mapping<T1,T2>::range() const 
00392 { return range_type(*this);}
00393 
00394 template<class T1, class T2>
00395 inline
00396 //domain_of_bijective_mapping<T1,T2>
00397 inverse_mapping<T1,T2>::range_type
00398 inverse_mapping<T1,T2>::range() const { return bmap->domain();}
00399 
00400 template<class T1, class T2>
00401 inline
00402 inverse_mapping<T1,T2>::domain_type //range_of_bijective_mapping<T1,T2>
00403 inverse_mapping<T1,T2>::domain() const { return bmap->range();}
00404 
00405 
00406 #ifdef NMWR_INCLUDE_TEMPLATE_DEFS
00407 #include "bijective-mapping.C"
00408 #endif
00409 
00410 #endif
00411 

Copyright (c) Guntram Berti 1997-2002. See the GrAL Homepage for up-to-date information.

Generated at Tue Feb 26 15:57:14 2002 for Sequence by doxygen 1.2.11-20011104 written by Dimitri van Heesch, © 1997-2000