00001 #ifndef NMWR_GB_BIJECTIVE_MAPPING_H
00002 #define NMWR_GB_BIJECTIVE_MAPPING_H
00003
00004
00005
00006
00007
00008 #include "Container/my-hash-map.h"
00009
00010
00011
00012
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
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
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
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
00168
00169 map_table_type the_map;
00170 mutable inv_table_type the_inverse_map;
00171
00172
00173 mutable bool inverse_ok;
00174
00175
00176
00177 typedef typename map_table_type::const_iterator map_iterator;
00178 public:
00179 typedef bijective_mapping<T1,T2> self;
00180
00181
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
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
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
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
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
00260 const mapping_type* bmap;
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
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;
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
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;
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
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
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
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