00001 #ifndef NMWR_GB_BIJECTIVE_MAPPING_H
00002 #define NMWR_GB_BIJECTIVE_MAPPING_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "Container/my-hash-map.h"
00021 #include "Container/mapped-value-iterator.h"
00022 #include "Utility/pre-post-conditions.h"
00023
00024 namespace GrAL {
00025
00026
00107 struct fail_if_undefined {};
00108
00115 struct identity_if_undefined {};
00116
00117
00118 template<class T1, class T2, class Policy = fail_if_undefined>
00119 class bijective_mapping;
00120
00121 template<class T1, class T2, class Policy = fail_if_undefined>
00122 class inverse_mapping;
00123
00124 template<class T1, class T2, class Policy = fail_if_undefined>
00125 class domain_of_bijective_mapping;
00126
00127 template<class T1, class T2, class Policy = fail_if_undefined>
00128 class range_of_bijective_mapping;
00129
00130
00131
00132
00133
00137 template<class T1, class T2, class Policy>
00138 void write_bm(bijective_mapping<T1,T2,Policy> const& m, ::std::ostream& out);
00139
00143 template<class T1, class T2, class Policy>
00144 void read_bm(bijective_mapping<T1,T2,Policy> & m, ::std::istream& in);
00145
00149 template<class T1, class T2, class Policy>
00150 class printer_of_bij_mapping {
00151 private:
00152 bijective_mapping<T1,T2,Policy> const* mp;
00153 public:
00154 printer_of_bij_mapping(bijective_mapping<T1,T2,Policy> const& m) : mp(&m) {}
00155
00156 friend ::std::ostream& operator<<(::std::ostream& out, printer_of_bij_mapping<T1,T2,Policy> const& p)
00157 { write_bm(*(p.mp),out); return out;}
00158
00159 };
00160
00172 template<class T1, class T2, class Policy>
00173 inline printer_of_bij_mapping<T1,T2,Policy>
00174 Printer(bijective_mapping<T1,T2,Policy> const& m)
00175 { return printer_of_bij_mapping<T1,T2,Policy>(m);}
00176
00177
00178
00179 template<class T1, class T2, class MAP, class Policy>
00180 struct map_accessor
00181 {
00182 static T2 const& get(MAP const& m, T1 const& t1) {
00183 REQUIRE(m.find(t1) != m.end(), "", 1);
00184 return m.find(t1)->second;
00185 }
00186 };
00187
00188 template<class T1, class MAP>
00189 struct map_accessor<T1,T1,MAP,identity_if_undefined>
00190 {
00191 static T1 const& get(MAP const& m, T1 const& t1) {
00192 return (m.find(t1) == m.end() ? t1 : m.find(t1)->second);
00193 }
00194 };
00195
00196
00197
00198
00199
00204 template<class T1, class T2, class Policy>
00205 class bijective_mapping {
00206 public:
00207 typedef inverse_mapping<T1,T2,Policy> inverse_type;
00208 typedef domain_of_bijective_mapping<T1,T2,Policy> domain_type;
00209 typedef range_of_bijective_mapping <T1,T2,Policy> range_type;
00210
00211 template<class U, class R, class P> friend class bijective_mapping;
00212 template<class U, class R, class P> friend class inverse_mapping;
00213 template<class U, class R, class P> friend class domain_of_bijective_mapping;
00214 template<class U, class R, class P> friend class range_of_bijective_mapping;
00215
00216
00217 typedef T1 argument_type;
00218 typedef T2 result_type;
00219
00220 private:
00221
00222 typedef STDHASH::hash_map<T1,T2> map_table_type;
00223 typedef STDHASH::hash_map<T2,T1> inv_table_type;
00224 typedef map_accessor<T1,T2,map_table_type,Policy> map_accessor_type;
00225 typedef map_accessor<T2,T1,inv_table_type,Policy> inv_accessor_type;
00226
00227
00228 map_table_type the_map;
00229 mutable inv_table_type the_inverse_map;
00230
00231
00232 mutable bool inverse_ok;
00233
00234
00235
00236 typedef typename map_table_type::const_iterator map_iterator;
00237 public:
00238 typedef bijective_mapping<T1,T2,Policy> self;
00239
00240
00241
00243 bijective_mapping() : inverse_ok(false) {}
00245 bijective_mapping(unsigned sz) : the_map(sz), the_inverse_map(sz), inverse_ok(false) {}
00247 bijective_mapping(inverse_mapping<T2,T1,Policy> const& inv);
00248
00249
00250
00252 const T2& operator()(const T1& t1) const {
00253
00254
00255
00256
00257
00258 return map_accessor_type::get(the_map,t1);
00259 }
00261 const T2& operator[](const T1& t1) const {
00262
00263
00264
00265
00266
00267 return map_accessor_type::get(the_map,t1);
00268 }
00270 T2& operator[](const T1& t1) { inverse_ok = false; return the_map[t1];}
00271
00273 bool defined (const T1& t1) const { return (the_map.find(t1) != the_map.end());}
00275 bool undefined(const T1& t1) const { return !defined(t1); }
00276
00277
00278
00279
00281 inverse_type inverse() const;
00282
00284 domain_type domain() const;
00286 range_type range() const;
00287
00288 typedef typename map_table_type::size_type size_type;
00290 size_type size() const { return domain().size();}
00291
00292
00293 private:
00294
00295
00296 void update_inverse() const {
00297 if(! inverse_ok) {
00298 calculate_inverse();
00299 inverse_ok = true;
00300 }
00301
00302 }
00303 void calculate_inverse() const;
00304 };
00305
00306
00307
00308
00309
00310
00320 template<class T1, class T2, class Policy>
00321 class inverse_mapping {
00322 private:
00323 typedef bijective_mapping<T1,T2, Policy> mapping_type;
00324 typedef typename mapping_type::inv_accessor_type accessor_type;
00325 template<class U, class R, class P> friend class bijective_mapping;
00326
00327
00328 const mapping_type* bmap;
00329
00330 public:
00331 typedef T1 result_type;
00332 typedef T2 argument_type;
00333
00334 inverse_mapping(const mapping_type& tm) : bmap(&tm) {}
00335
00336 const T1& operator()(const T2& t2) const {
00337 bmap->update_inverse();
00338 REQUIRE( (defined(t2)),
00339 "inverse map not defined for item " << t2 << '\n',1);
00340 return (*(bmap->the_inverse_map.find(t2))).second;
00341 return accessor_type::get(bmap->the_inverse_map, t2);
00342 }
00343
00344 bool defined(const T2& t2) const {
00345 bmap->update_inverse();
00346 return (bmap->the_inverse_map.find(t2) != bmap->the_inverse_map.end());
00347 }
00348
00349 typedef typename mapping_type::domain_type range_type;
00350 inline range_type range() const;
00351 typedef typename mapping_type::range_type domain_type;
00352 inline domain_type domain() const;
00353 };
00354
00355
00356
00357
00358
00374 template<class T1, class T2, class Policy>
00375 class domain_of_bijective_mapping {
00376 public:
00377 typedef bijective_mapping<T1,T2, Policy> mapping_type;
00378 typedef typename mapping_type::map_table_type map_table_type;
00379 typedef typename map_table_type::value_type base_value_type;
00380 typedef typename map_table_type::const_iterator base_iter_type;
00381 typedef mapped_value_const_iterator<base_iter_type,
00382 get_first<base_value_type> const> const_iterator;
00383
00384 typedef T1 value_type;
00385
00386 private:
00387 const mapping_type* bmap;
00388 public:
00389 domain_of_bijective_mapping(const mapping_type& tm) : bmap(&tm) {}
00390
00391 unsigned size() const { return bmap->the_map.size();}
00392
00394 bool is_member(const value_type& x) const { return bmap->defined(x);}
00395
00396 const_iterator begin() const { return const_iterator(bmap->the_map.begin());}
00397 const_iterator end() const { return const_iterator(bmap->the_map.end());}
00398 T1 const& front() const { return *begin();}
00399 };
00400
00401
00402
00403
00404
00416 template<class T1, class T2, class Policy>
00417 class range_of_bijective_mapping {
00418 public:
00419 typedef bijective_mapping<T1,T2, Policy> mapping_type;
00420 typedef typename mapping_type::map_table_type map_table_type;
00421 typedef typename map_table_type::value_type base_value_type;
00422 typedef typename map_table_type::const_iterator base_iter_type;
00423 typedef mapped_value_const_iterator<base_iter_type,
00424 get_second<base_value_type> const> const_iterator;
00425
00426 typedef T2 value_type;
00427
00428 private:
00429 const mapping_type* bmap;
00430 public:
00431 range_of_bijective_mapping(const mapping_type& tm) : bmap(&tm) {}
00432
00433 unsigned size() const { return bmap->the_map.size();}
00434 bool is_member(const value_type& x) const {
00435 bmap->update_inverse();
00436 return (bmap->the_inverse_map.find(x) != bmap->the_inverse_map.end());
00437 }
00438
00439 const_iterator begin() const { return const_iterator(bmap->the_map.begin());}
00440 const_iterator end() const { return const_iterator(bmap->the_map.end());}
00441 T2 const& front() const { return *begin();}
00442 };
00443
00444
00445
00446
00447
00448
00449
00450 template<class T1, class T2, class Policy>
00451 inline
00452 inverse_mapping<T1,T2, Policy> bijective_mapping<T1,T2, Policy>::inverse() const
00453 { return inverse_type(*this);}
00454
00455 template<class T1, class T2, class Policy>
00456 inline
00457 domain_of_bijective_mapping<T1,T2,Policy> bijective_mapping<T1,T2,Policy >::domain() const
00458 { return domain_type(*this);}
00459
00460 template<class T1, class T2, class Policy>
00461 inline
00462 range_of_bijective_mapping<T1,T2,Policy> bijective_mapping<T1,T2,Policy>::range() const
00463 { return range_type(*this);}
00464
00465 template<class T1, class T2, class Policy>
00466 inline
00467
00468 typename inverse_mapping<T1,T2,Policy>::range_type
00469 inverse_mapping<T1,T2,Policy>::range() const { return bmap->domain();}
00470
00471 template<class T1, class T2, class Policy>
00472 inline
00473 typename inverse_mapping<T1,T2,Policy>::domain_type
00474 inverse_mapping<T1,T2,Policy>::domain() const { return bmap->range();}
00475
00476
00477 }
00478
00479 #ifdef NMWR_INCLUDE_TEMPLATE_DEFS
00480 #include "bijective-mapping.C"
00481 #endif
00482
00483 #endif
00484