map.hpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*!
  2. @file
  3. Forward declares `boost::hana::map`.
  4. @copyright Louis Dionne 2013-2016
  5. Distributed under the Boost Software License, Version 1.0.
  6. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  7. */
  8. #ifndef BOOST_HANA_FWD_MAP_HPP
  9. #define BOOST_HANA_FWD_MAP_HPP
  10. #include <boost/hana/config.hpp>
  11. #include <boost/hana/fwd/core/to.hpp>
  12. #include <boost/hana/fwd/core/make.hpp>
  13. #include <boost/hana/fwd/erase_key.hpp>
  14. #include <boost/hana/fwd/insert.hpp>
  15. #include <boost/hana/fwd/keys.hpp>
  16. BOOST_HANA_NAMESPACE_BEGIN
  17. //! @ingroup group-datatypes
  18. //! Basic associative container requiring unique, `Comparable` and
  19. //! `Hashable` keys.
  20. //!
  21. //! The order of the elements of the map is unspecified. Also, all the
  22. //! keys must be `Hashable`, and any two keys with equal hashes must be
  23. //! `Comparable` with each other at compile-time.
  24. //!
  25. //! @note
  26. //! The actual representation of a `hana::map` is implementation-defined.
  27. //! In particular, one should not take for granted the order of the
  28. //! template parameters and the presence of any additional constructors
  29. //! or assignment operators than what is documented. The canonical way of
  30. //! creating a `hana::map` is through `hana::make_map`.
  31. //!
  32. //!
  33. //! Modeled concepts
  34. //! ----------------
  35. //! 1. `Comparable`\n
  36. //! Two maps are equal iff all their keys are equal and are associated
  37. //! to equal values.
  38. //! @include example/map/comparable.cpp
  39. //!
  40. //! 2. `Searchable`\n
  41. //! A map can be searched by its keys with a predicate yielding a
  42. //! compile-time `Logical`. Also note that `operator[]` can be used
  43. //! instead of `at_key`.
  44. //! @include example/map/searchable.cpp
  45. //!
  46. //! 3. `Foldable`\n
  47. //! Folding a map is equivalent to folding a list of the key/value pairs
  48. //! it contains. In particular, since that list is not guaranteed to be
  49. //! in any specific order, folding a map with an operation that is not
  50. //! both commutative and associative will yield non-deterministic behavior.
  51. //! @include example/map/foldable.cpp
  52. //!
  53. //!
  54. //! Conversion from any `Foldable`
  55. //! ------------------------------
  56. //! Any `Foldable` of `Product`s can be converted to a `hana::map` with
  57. //! `hana::to<hana::map_tag>` or, equivalently, `hana::to_map`. If the
  58. //! `Foldable` contains duplicate keys, only the value associated to the
  59. //! first occurence of each key is kept.
  60. //! @include example/map/to.cpp
  61. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  62. template <typename implementation_defined>
  63. struct map {
  64. //! Default-construct a map. This constructor only exists when all the
  65. //! elements of the map are default-constructible.
  66. constexpr map() = default;
  67. //! Copy-construct a map from another map. This constructor only
  68. //! exists when all the elements of the map are copy-constructible.
  69. constexpr map(map const& other) = default;
  70. //! Move-construct a map from another map. This constructor only
  71. //! exists when all the elements of the map are move-constructible.
  72. constexpr map(map&& other) = default;
  73. //! Equivalent to `hana::equal`
  74. template <typename X, typename Y>
  75. friend constexpr auto operator==(X&& x, Y&& y);
  76. //! Equivalent to `hana::not_equal`
  77. template <typename X, typename Y>
  78. friend constexpr auto operator!=(X&& x, Y&& y);
  79. //! Equivalent to `hana::at_key`
  80. template <typename Key>
  81. constexpr decltype(auto) operator[](Key&& key);
  82. };
  83. #else
  84. template <typename HashTable, typename Storage>
  85. struct map;
  86. #endif
  87. //! Tag representing `hana::map`s.
  88. //! @relates hana::map
  89. struct map_tag { };
  90. //! Function object for creating a `hana::map`.
  91. //! @relates hana::map
  92. //!
  93. //! Given zero or more `Product`s representing key/value associations,
  94. //! `make<map_tag>` returns a `hana::map` associating these keys to these
  95. //! values.
  96. //!
  97. //! `make<map_tag>` requires all the keys to be unique and to have
  98. //! different hashes. If you need to create a map with duplicate keys
  99. //! or with keys whose hashes might collide, use `hana::to_map` or
  100. //! insert `(key, value)` pairs to an empty map successively. However,
  101. //! be aware that doing so will be much more compile-time intensive than
  102. //! using `make<map_tag>`, because the uniqueness of keys will have to be
  103. //! enforced.
  104. //!
  105. //!
  106. //! Example
  107. //! -------
  108. //! @include example/map/make.cpp
  109. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  110. template <>
  111. constexpr auto make<map_tag> = [](auto&& ...pairs) {
  112. return map<implementation_defined>{forwarded(pairs)...};
  113. };
  114. #endif
  115. //! Alias to `make<map_tag>`; provided for convenience.
  116. //! @relates hana::map
  117. //!
  118. //!
  119. //! Example
  120. //! -------
  121. //! @include example/map/make.cpp
  122. constexpr auto make_map = make<map_tag>;
  123. //! Equivalent to `to<map_tag>`; provided for convenience.
  124. //! @relates hana::map
  125. constexpr auto to_map = to<map_tag>;
  126. //! Returns a `Sequence` of the keys of the map, in unspecified order.
  127. //! @relates hana::map
  128. //!
  129. //!
  130. //! Example
  131. //! -------
  132. //! @include example/map/keys.cpp
  133. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  134. constexpr auto keys = [](auto&& map) {
  135. return implementation_defined;
  136. };
  137. #endif
  138. //! Returns a `Sequence` of the values of the map, in unspecified order.
  139. //! @relates hana::map
  140. //!
  141. //!
  142. //! Example
  143. //! -------
  144. //! @include example/map/values.cpp
  145. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  146. constexpr auto values = [](auto&& map) -> decltype(auto) {
  147. return implementation_defined;
  148. };
  149. #else
  150. struct values_t {
  151. template <typename Map>
  152. constexpr decltype(auto) operator()(Map&& map) const;
  153. };
  154. constexpr values_t values{};
  155. #endif
  156. //! Inserts a new key/value pair in a map.
  157. //! @relates hana::map
  158. //!
  159. //! Given a `(key, value)` pair, `insert` inserts this new pair into a
  160. //! map. If the map already contains this key, nothing is done and the
  161. //! map is returned as-is.
  162. //!
  163. //!
  164. //! @param map
  165. //! The map in which to insert a `(key,value)` pair.
  166. //!
  167. //! @param pair
  168. //! An arbitrary `Product` representing a `(key, value)` pair to insert
  169. //! in the map. The `key` must be compile-time `Comparable`.
  170. //!
  171. //!
  172. //! Example
  173. //! -------
  174. //! @include example/map/insert.cpp
  175. //!
  176. //!
  177. //! Benchmarks
  178. //! ----------
  179. //! <div class="benchmark-chart"
  180. //! style="min-width: 310px; height: 400px; margin: 0 auto"
  181. //! data-dataset="benchmark.insert.compile.json">
  182. //! </div>
  183. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  184. constexpr auto insert = [](auto&& map, auto&& pair) {
  185. return tag-dispatched;
  186. };
  187. #endif
  188. //! Removes a key/value pair from a map.
  189. //! @relates hana::map
  190. //!
  191. //! Returns a new `hana::map` containing all the elements of the original,
  192. //! except for the `(key, value)` pair whose `key` compares `equal`
  193. //! to the given key. If the map does not contain such an element,
  194. //! a new map equal to the original is returned.
  195. //!
  196. //!
  197. //! @param map
  198. //! The map in which to erase a `key`.
  199. //!
  200. //! @param key
  201. //! A key to remove from the map. It must be compile-time `Comparable`.
  202. //!
  203. //!
  204. //! Example
  205. //! -------
  206. //! @include example/map/erase_key.cpp
  207. #ifdef BOOST_HANA_DOXYGEN_INVOKED
  208. constexpr auto erase_key = [](auto&& map, auto&& key) {
  209. return tag-dispatched;
  210. };
  211. #endif
  212. BOOST_HANA_NAMESPACE_END
  213. #endif // !BOOST_HANA_FWD_MAP_HPP