bimap.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /* Boost.MultiIndex example of a bidirectional map.
  2. *
  3. * Copyright 2003-2009 Joaquin M Lopez Munoz.
  4. * Distributed under the Boost Software License, Version 1.0.
  5. * (See accompanying file LICENSE_1_0.txt or copy at
  6. * http://www.boost.org/LICENSE_1_0.txt)
  7. *
  8. * See http://www.boost.org/libs/multi_index for library home page.
  9. */
  10. #if !defined(NDEBUG)
  11. #define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
  12. #define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
  13. #endif
  14. #include <boost/multi_index_container.hpp>
  15. #include <boost/multi_index/member.hpp>
  16. #include <boost/multi_index/ordered_index.hpp>
  17. #include <iostream>
  18. #include <string>
  19. using boost::multi_index_container;
  20. using namespace boost::multi_index;
  21. /* tags for accessing both sides of a bidirectional map */
  22. struct from{};
  23. struct to{};
  24. /* The class template bidirectional_map wraps the specification
  25. * of a bidirectional map based on multi_index_container.
  26. */
  27. template<typename FromType,typename ToType>
  28. struct bidirectional_map
  29. {
  30. struct value_type
  31. {
  32. value_type(const FromType& first_,const ToType& second_):
  33. first(first_),second(second_)
  34. {}
  35. FromType first;
  36. ToType second;
  37. };
  38. #if defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS) ||\
  39. defined(BOOST_MSVC)&&(BOOST_MSVC<1300) ||\
  40. defined(BOOST_INTEL_CXX_VERSION)&&defined(_MSC_VER)&&\
  41. (BOOST_INTEL_CXX_VERSION<=700)
  42. /* see Compiler specifics: Use of member_offset for info on member<> and
  43. * member_offset<>
  44. */
  45. BOOST_STATIC_CONSTANT(unsigned,from_offset=offsetof(value_type,first));
  46. BOOST_STATIC_CONSTANT(unsigned,to_offset =offsetof(value_type,second));
  47. typedef multi_index_container<
  48. value_type,
  49. indexed_by<
  50. ordered_unique<
  51. tag<from>,member_offset<value_type,FromType,from_offset> >,
  52. ordered_unique<
  53. tag<to>, member_offset<value_type,ToType,to_offset> >
  54. >
  55. > type;
  56. #else
  57. /* A bidirectional map can be simulated as a multi_index_container
  58. * of pairs of (FromType,ToType) with two unique indices, one
  59. * for each member of the pair.
  60. */
  61. typedef multi_index_container<
  62. value_type,
  63. indexed_by<
  64. ordered_unique<
  65. tag<from>,member<value_type,FromType,&value_type::first> >,
  66. ordered_unique<
  67. tag<to>, member<value_type,ToType,&value_type::second> >
  68. >
  69. > type;
  70. #endif
  71. };
  72. /* a dictionary is a bidirectional map from strings to strings */
  73. typedef bidirectional_map<std::string,std::string>::type dictionary;
  74. int main()
  75. {
  76. dictionary d;
  77. /* Fill up our microdictionary. first members Spanish, second members
  78. * English.
  79. */
  80. d.insert(dictionary::value_type("hola","hello"));
  81. d.insert(dictionary::value_type("adios","goodbye"));
  82. d.insert(dictionary::value_type("rosa","rose"));
  83. d.insert(dictionary::value_type("mesa","table"));
  84. std::cout<<"enter a word"<<std::endl;
  85. std::string word;
  86. std::getline(std::cin,word);
  87. #if defined(BOOST_NO_MEMBER_TEMPLATES) /* use global get<> and family instead */
  88. dictionary::iterator it=get<from>(d).find(word);
  89. if(it!=d.end()){
  90. std::cout<<word<<" is said "<<it->second<<" in English"<<std::endl;
  91. }
  92. else{
  93. nth_index<dictionary,1>::type::iterator it2=get<1>(d).find(word);
  94. if(it2!=get<1>(d).end()){
  95. std::cout<<word<<" is said "<<it2->first<<" in Spanish"<<std::endl;
  96. }
  97. else std::cout<<"No such word in the dictionary"<<std::endl;
  98. }
  99. #else
  100. /* search the queried word on the from index (Spanish) */
  101. dictionary::iterator it=d.get<from>().find(word);
  102. if(it!=d.end()){ /* found */
  103. /* the second part of the element is the equivalent in English */
  104. std::cout<<word<<" is said "<<it->second<<" in English"<<std::endl;
  105. }
  106. else{
  107. /* word not found in Spanish, try our luck in English */
  108. dictionary::index<to>::type::iterator it2=d.get<to>().find(word);
  109. if(it2!=d.get<to>().end()){
  110. std::cout<<word<<" is said "<<it2->first<<" in Spanish"<<std::endl;
  111. }
  112. else std::cout<<"No such word in the dictionary"<<std::endl;
  113. }
  114. #endif
  115. return 0;
  116. }