c++ - One-to-one relation in STL terms -


as know there no biunivocal mapping datastruct/adt in c++ (stl) , c++1y. need sorted associative container allows me map key set value set , vice versa.

what best approach or existant solution?

my proposal is:

#!/usr/bin/env bash -vex # cls ; bash self.bash 2>&1 | tee self.log | less warn="-w -wall -wextra -werror" g++ -x c++ - -std=gnu++1y $warn -ofast -o <<__eof && ./a && echo -e "\e[1;32msucceeded\e[0m" || echo -e "\e[1;31mfailed\e[0m" #include <list> #include <tuple> #include <map> #include <functional>  #include <string>  #include <cstdlib> #include <cassert>  template< typename a, typename b > class bijection {      using data_type = std::list< std::tuple< const, b const > >;  public :      using iterator = typename data_type::iterator;     using const_iterator = typename data_type::const_iterator;  private :      using direct_mapping_type = std::map< std::reference_wrapper< const >, iterator, std::less< const & > > ;     using inverse_mapping_type = std::map< std::reference_wrapper< b const >, iterator, std::less< b const & > >;     using direct_iterator = typename direct_mapping_type::iterator;     using inverse_iterator = typename inverse_mapping_type::iterator;  public :      auto size() const { return data_.size(); }      iterator find(a const & a)     {         auto const direct = direct_mapping_.find(a);         if (direct == direct_mapping_.end()) {             return data_.end();         } else {             return direct->second;         }     }      iterator find(b const & b)     {         auto const inverse = inverse_mapping_.find(b);         if (inverse == inverse_mapping_.end()) {             return data_.end();         } else {             return inverse->second;         }     }      auto erase(iterator pos)     {         auto const & element = *pos;         direct_mapping_.erase(std::get< 0 >(element));         inverse_mapping_.erase(std::get< 1 >(element));         return data_.erase(pos);     }      template< typename x, typename y >     std::tuple< iterator, bool, bool > insert(x && x, y && y)     {         direct_iterator direct = direct_mapping_.find(x);         inverse_iterator inverse = inverse_mapping_.find(y);         bool const d = (direct != direct_mapping_.end());         bool const = (inverse != inverse_mapping_.end());         if (d && i) {             iterator ix = inverse->second;             iterator iy = direct->second;             inverse_mapping_.erase(inverse);             direct_mapping_.erase(direct);             if (ix != iy) {                 inverse_mapping_.erase(std::get< 1 >(*iy));                 direct_mapping_.erase(std::get< 0 >(*ix));                 data_.erase(iy);                 data_.erase(ix);             } else {                 data_.erase(ix); // iy             }         } else if (d) {             iterator iy = direct->second;             direct_mapping_.erase(direct);             inverse_mapping_.erase(std::get< 1 >(*iy));             data_.erase(iy);         } else if (i) {             iterator ix = inverse->second;             inverse_mapping_.erase(inverse);             direct_mapping_.erase(std::get< 0 >(*ix));             data_.erase(ix);         }         data_.emplace_back(std::forward< x >(x), std::forward< y >(y));         auto const & element = data_.back();         iterator = --data_.end();         direct_mapping_.emplace(std::get< 0 >(element), it);         inverse_mapping_.emplace(std::get< 1 >(element), it);         return std::make_tuple(it, d, i);     }  private :      data_type data_;     direct_mapping_type direct_mapping_;     inverse_mapping_type inverse_mapping_;  };  int main() {     using = std::size_t;     using b = std::string;     using m = bijection< a, b >;     m m;     assert(1 == (m.insert(a(111), b("111")), m.size()));     assert(1 == (m.insert(a(111), b("111")), m.size()));     assert(2 == (m.insert(a(222), b("222")), m.size()));     assert(3 == (m.insert(a(333), b("333")), m.size()));     assert(2 == (m.insert(a(222), b("111")), m.size()));     assert(3 == (m.insert(a(111), b("222")), m.size()));     assert(2 == (m.insert(a(111), b("111")), m.size()));     assert(1 == (m.insert(a(333), b("111")), m.size()));     assert(1 == (m.insert(a(333), b("333")), m.size()));     assert(1 == (m.insert(a(111), b("333")), m.size()));     assert(0 == (m.erase(m.find(a(111))), m.size()));     return exit_success; } __eof 

if need tested can use boost bimap library.


Comments

Popular posts from this blog

Detect support for Shoutcast ICY MP3 without navigator.userAgent in Firefox? -

web - SVG not rendering properly in Firefox -

java - JavaFX 2 slider labelFormatter not being used -