quick_tutorial.qbk 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. [/license
  2. Boost.Bimap
  3. Copyright (c) 2006-2007 Matias Capeletto
  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. [/ QuickBook Document version 1.4 ]
  9. [section One minute tutorial]
  10. [heading What is a bimap?]
  11. A Bimap is a data structure that represents bidirectional relations between
  12. elements of two collections. The container is designed to work as two opposed STL maps. A bimap between a collection `X` and a collection `Y` can be viewed as a map from `X` to `Y` (this view will be called the ['left map view]) or as a map from `Y` to `X` (known as the ['right map view]). Additionally, the bimap can also be viewed as a set of relations between `X` and `Y` (named the ['collection of relations view]).
  13. The following code creates an empty bimap container:
  14. typedef bimap<X,Y> bm_type;
  15. bm_type bm;
  16. Given this code, the following is the complete description of the resulting bimap.
  17. [footnote A type is ['signature-compatible] with other type if it has the same
  18. signature for functions and metadata. Preconditions, postconditions and the order
  19. of operations need not be the same.
  20. ]
  21. * `bm.left` is signature-compatible with `std::map<X,Y>`
  22. * `bm.right` is signature-compatible with `std::map<Y,X>`
  23. * `bm` is signature-compatible with `std::set< relation<X,Y> >`
  24. __SIMPLE_BIMAP__
  25. You can see how a bimap container offers three views over the same collection of bidirectional relations.
  26. If we have any generic function that work with maps
  27. template< class MapType >
  28. void print_map(const MapType & m)
  29. {
  30. typedef typename MapType::const_iterator const_iterator;
  31. for( const_iterator iter = m.begin(), iend = m.end(); iter != iend; ++iter )
  32. {
  33. std::cout << iter->first << "-->" << iter->second << std::endl;
  34. }
  35. }
  36. We can use the ['left map view] and the ['right map view] with it
  37. bimap< int, std::string > bm;
  38. ...
  39. print_map( bm.left );
  40. print_map( bm.right );
  41. And the output will be
  42. [pre
  43. [^1 --> one]
  44. [^2 --> two]
  45. ...
  46. [^one --> 1]
  47. [^two --> 2]
  48. ...
  49. ]
  50. [heading Layout of the relation and the pairs of a bimap]
  51. The `relation` class represents two related elements. The two values are
  52. named left and right to express the symmetry of this type.
  53. The bimap pair classes are signature-compatible with `std::pairs`.
  54. __RELATION_AND_PAIR__
  55. [heading Step by step]
  56. [import ../example/step_by_step.cpp]
  57. A convenience header is available in the boost directory:
  58. #include <boost/bimap.hpp>
  59. Lets define a bidirectional map between integers and strings:
  60. [code_step_by_step_definition]
  61. [heading The collection of relations view]
  62. Remember that `bm` alone can be used as a set of relations.
  63. We can insert elements or iterate over them using this view.
  64. [code_step_by_step_set_of_relations_view]
  65. [heading The left map view]
  66. `bm.left` works like a `std::map< int, std::string >`. We use it
  67. in the same way we will use a standard map.
  68. [code_step_by_step_left_map_view]
  69. [heading The right map view]
  70. `bm.right` works like a `std::map< std::string, int >`. It is
  71. important to note that the key is the first type and the data
  72. is the second one, exactly as with standard maps.
  73. [code_step_by_step_right_map_view]
  74. [heading Differences with std::map]
  75. The main difference between bimap views and their standard containers counterparts
  76. is that, because of the bidirectional nature of a bimap, the values stored in
  77. it can not be modified directly using iterators.
  78. For example, when a `std::map<X,Y>` iterator is dereferenced the return type is
  79. `std::pair<const X, Y>`, so the following code is valid:
  80. `m.begin()->second = new_value;`.
  81. However dereferencing a `bimap<X,Y>::left_iterator` returns a type that is
  82. ['signature-compatible] with a `std::pair<const X, const Y>`
  83. bm.left.find(1)->second = "1"; // Compilation error
  84. If you insert `(1,"one")` and `(1,"1")` in a `std::map<int,std::string>` the second insertion will have no effect. In a `bimap<X,Y>` both keys have to remain unique. The insertion may fail in other situations too. Lets see an example
  85. bm.clear();
  86. bm.insert( bm_type::value_type( 1, "one" ) );
  87. bm.insert( bm_type::value_type( 1, "1" ) ); // No effect!
  88. bm.insert( bm_type::value_type( 2, "one" ) ); // No effect!
  89. assert( bm.size() == 1 );
  90. [heading A simple example]
  91. Look how you can reuse code that is intend to be used with std::maps, like the
  92. print_map function in this example.
  93. [@../../example/simple_bimap.cpp Go to source code]
  94. [code_simple_bimap]
  95. The output of this program will be the following:
  96. [pre
  97. [^The number of countries is 4]
  98. [^The winner is Argentina]
  99. [^Countries names ordered by their final position:]
  100. [^1) Argentina]
  101. [^2) Spain]
  102. [^3) Germany]
  103. [^4) France]
  104. [^Countries names ordered alphabetically along with their final position:]
  105. [^Argentina ends in position 1]
  106. [^France ends in position 4]
  107. [^Germany ends in position 3]
  108. [^Spain ends in position 2]
  109. ]
  110. [heading Continuing the journey]
  111. For information on function signatures, see any standard library
  112. documentation or read the [link boost_bimap.reference reference] section of
  113. this documentation.
  114. [caution
  115. Be aware that a bidirectional map is only signature-compatible with standard
  116. containers. Some functions may give different results, such as in the case of
  117. inserting a pair into the left map where the second value conflicts with a
  118. stored relation in the container. The functions may be slower in a bimap
  119. because of the duplicated constraints. It is strongly recommended that
  120. you read [link boost_bimap.the_tutorial The full tutorial] if you intend to
  121. use a bimap in a serious project.
  122. ]
  123. [endsect]