]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/hana/fwd/map.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / hana / fwd / map.hpp
1 /*!
2 @file
3 Forward declares `boost::hana::map`.
4
5 @copyright Louis Dionne 2013-2017
6 Distributed under the Boost Software License, Version 1.0.
7 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
8 */
9
10 #ifndef BOOST_HANA_FWD_MAP_HPP
11 #define BOOST_HANA_FWD_MAP_HPP
12
13 #include <boost/hana/config.hpp>
14 #include <boost/hana/fwd/core/to.hpp>
15 #include <boost/hana/fwd/core/make.hpp>
16 #include <boost/hana/fwd/erase_key.hpp>
17 #include <boost/hana/fwd/insert.hpp>
18 #include <boost/hana/fwd/keys.hpp>
19
20
21 BOOST_HANA_NAMESPACE_BEGIN
22 //! Tag representing `hana::map`s.
23 //! @relates hana::map
24 struct map_tag { };
25
26 namespace detail {
27 template <typename ...Pairs>
28 struct make_map_type;
29 }
30
31 //! @ingroup group-datatypes
32 //! Basic associative container requiring unique, `Comparable` and
33 //! `Hashable` keys.
34 //!
35 //! The order of the elements of the map is unspecified. Also, all the
36 //! keys must be `Hashable`, and any two keys with equal hashes must be
37 //! `Comparable` with each other at compile-time.
38 //!
39 //! Note that the actual representation of a `hana::map` is an implementation
40 //! detail. As such, one should not assume anything more than what is
41 //! explicitly documented as being part of the interface of a map,
42 //! such as:
43 //! - the presence of additional constructors
44 //! - the presence of additional assignment operators
45 //! - the fact that `hana::map<Pairs...>` is, or is not, a dependent type
46 //!
47 //! In particular, the last point is very important; `hana::map<Pairs...>`
48 //! is basically equivalent to
49 //! @code
50 //! decltype(hana::make_pair(std::declval<Pairs>()...))
51 //! @endcode
52 //! which is not something that can be pattern-matched on during template
53 //! argument deduction, for example.
54 //!
55 //!
56 //! Modeled concepts
57 //! ----------------
58 //! 1. `Comparable`\n
59 //! Two maps are equal iff all their keys are equal and are associated
60 //! to equal values.
61 //! @include example/map/comparable.cpp
62 //!
63 //! 2. `Searchable`\n
64 //! A map can be searched by its keys with a predicate yielding a
65 //! compile-time `Logical`. Also note that `operator[]` can be used
66 //! instead of `at_key`.
67 //! @include example/map/searchable.cpp
68 //!
69 //! 3. `Foldable`\n
70 //! Folding a map is equivalent to folding a list of the key/value pairs
71 //! it contains. In particular, since that list is not guaranteed to be
72 //! in any specific order, folding a map with an operation that is not
73 //! both commutative and associative will yield non-deterministic behavior.
74 //! @include example/map/foldable.cpp
75 //!
76 //!
77 //! Conversion from any `Foldable`
78 //! ------------------------------
79 //! Any `Foldable` of `Product`s can be converted to a `hana::map` with
80 //! `hana::to<hana::map_tag>` or, equivalently, `hana::to_map`. If the
81 //! `Foldable` contains duplicate keys, only the value associated to the
82 //! first occurence of each key is kept.
83 //! @include example/map/to.cpp
84 //!
85 //!
86 //! Example
87 //! -------
88 //! @include example/map/map.cpp
89 #ifdef BOOST_HANA_DOXYGEN_INVOKED
90 template <typename ...Pairs>
91 struct map {
92 //! Default-construct a map. This constructor only exists when all the
93 //! elements of the map are default-constructible.
94 constexpr map() = default;
95
96 //! Copy-construct a map from another map. This constructor only
97 //! exists when all the elements of the map are copy-constructible.
98 constexpr map(map const& other) = default;
99
100 //! Move-construct a map from another map. This constructor only
101 //! exists when all the elements of the map are move-constructible.
102 constexpr map(map&& other) = default;
103
104 //! Construct the map from the provided pairs. `P...` must be pairs of
105 //! the same type (modulo ref and cv-qualifiers), and in the same order,
106 //! as those appearing in `Pairs...`. The pairs provided to this
107 //! constructor are emplaced into the map's storage using perfect
108 //! forwarding.
109 template <typename ...P>
110 explicit constexpr map(P&& ...pairs);
111
112 //! Assign a map to another map __with the exact same type__. Only
113 //! exists when all the elements of the map are copy-assignable.
114 constexpr map& operator=(map const& other);
115
116 //! Move-assign a map to another map __with the exact same type__.
117 //! Only exists when all the elements of the map are move-assignable.
118 constexpr map& operator=(map&& other);
119
120 //! Equivalent to `hana::equal`
121 template <typename X, typename Y>
122 friend constexpr auto operator==(X&& x, Y&& y);
123
124 //! Equivalent to `hana::not_equal`
125 template <typename X, typename Y>
126 friend constexpr auto operator!=(X&& x, Y&& y);
127
128 //! Equivalent to `hana::at_key`
129 template <typename Key>
130 constexpr decltype(auto) operator[](Key&& key);
131 };
132 #else
133 template <typename ...Pairs>
134 using map = typename detail::make_map_type<Pairs...>::type;
135 #endif
136
137 //! Function object for creating a `hana::map`.
138 //! @relates hana::map
139 //!
140 //! Given zero or more `Product`s representing key/value associations,
141 //! `make<map_tag>` returns a `hana::map` associating these keys to these
142 //! values.
143 //!
144 //! `make<map_tag>` requires all the keys to be unique and to have
145 //! different hashes. If you need to create a map with duplicate keys
146 //! or with keys whose hashes might collide, use `hana::to_map` or
147 //! insert `(key, value)` pairs to an empty map successively. However,
148 //! be aware that doing so will be much more compile-time intensive than
149 //! using `make<map_tag>`, because the uniqueness of keys will have to be
150 //! enforced.
151 //!
152 //!
153 //! Example
154 //! -------
155 //! @include example/map/make.cpp
156 #ifdef BOOST_HANA_DOXYGEN_INVOKED
157 template <>
158 constexpr auto make<map_tag> = [](auto&& ...pairs) {
159 return map<implementation_defined>{forwarded(pairs)...};
160 };
161 #endif
162
163 //! Alias to `make<map_tag>`; provided for convenience.
164 //! @relates hana::map
165 //!
166 //!
167 //! Example
168 //! -------
169 //! @include example/map/make.cpp
170 constexpr auto make_map = make<map_tag>;
171
172 //! Equivalent to `to<map_tag>`; provided for convenience.
173 //! @relates hana::map
174 constexpr auto to_map = to<map_tag>;
175
176 //! Returns a `Sequence` of the keys of the map, in unspecified order.
177 //! @relates hana::map
178 //!
179 //!
180 //! Example
181 //! -------
182 //! @include example/map/keys.cpp
183 #ifdef BOOST_HANA_DOXYGEN_INVOKED
184 constexpr auto keys = [](auto&& map) {
185 return implementation_defined;
186 };
187 #endif
188
189 //! Returns a `Sequence` of the values of the map, in unspecified order.
190 //! @relates hana::map
191 //!
192 //!
193 //! Example
194 //! -------
195 //! @include example/map/values.cpp
196 #ifdef BOOST_HANA_DOXYGEN_INVOKED
197 constexpr auto values = [](auto&& map) -> decltype(auto) {
198 return implementation_defined;
199 };
200 #else
201 struct values_t {
202 template <typename Map>
203 constexpr decltype(auto) operator()(Map&& map) const;
204 };
205
206 constexpr values_t values{};
207 #endif
208
209 //! Inserts a new key/value pair in a map.
210 //! @relates hana::map
211 //!
212 //! Given a `(key, value)` pair, `insert` inserts this new pair into a
213 //! map. If the map already contains this key, nothing is done and the
214 //! map is returned as-is.
215 //!
216 //!
217 //! @param map
218 //! The map in which to insert a `(key,value)` pair.
219 //!
220 //! @param pair
221 //! An arbitrary `Product` representing a `(key, value)` pair to insert
222 //! in the map. The `key` must be compile-time `Comparable`.
223 //!
224 //!
225 //! Example
226 //! -------
227 //! @include example/map/insert.cpp
228 #ifdef BOOST_HANA_DOXYGEN_INVOKED
229 constexpr auto insert = [](auto&& map, auto&& pair) {
230 return tag-dispatched;
231 };
232 #endif
233
234 //! Removes a key/value pair from a map.
235 //! @relates hana::map
236 //!
237 //! Returns a new `hana::map` containing all the elements of the original,
238 //! except for the `(key, value)` pair whose `key` compares `equal`
239 //! to the given key. If the map does not contain such an element,
240 //! a new map equal to the original is returned.
241 //!
242 //!
243 //! @param map
244 //! The map in which to erase a `key`.
245 //!
246 //! @param key
247 //! A key to remove from the map. It must be compile-time `Comparable`.
248 //!
249 //!
250 //! Example
251 //! -------
252 //! @include example/map/erase_key.cpp
253 #ifdef BOOST_HANA_DOXYGEN_INVOKED
254 constexpr auto erase_key = [](auto&& map, auto&& key) {
255 return tag-dispatched;
256 };
257 #endif
258
259 //! Returns the union of two maps.
260 //! @relates hana::map
261 //!
262 //! Given two maps `xs` and `ys`, `hana::union_(xs, ys)` is a new map
263 //! containing all the elements of `xs` and all the elements of `ys`,
264 //! without duplicates. If both `xs` and `ys` contain an element with the
265 //! same `key`, the one in `ys` is taken. Functionally,
266 //! `hana::union_(xs, ys)` is equivalent to
267 //! @code
268 //! hana::fold_left(xs, ys, hana::insert)
269 //! @endcode
270 //!
271 //! @param xs, ys
272 //! The two maps to compute the union of.
273 //!
274 //!
275 //! Example
276 //! -------
277 //! @include example/map/union.cpp
278 #ifdef BOOST_HANA_DOXYGEN_INVOKED
279 constexpr auto union_ = [](auto&& xs, auto&& ys) {
280 return tag-dispatched;
281 };
282 #endif
283
284 //! Returns the intersection of two maps.
285 //! @relates hana::map
286 //!
287 //! Given two maps `xs` and `ys`, `intersection(xs, ys)` is a new map
288 //! containing exactly those (key, value) pairs from xs, for which key
289 //! is present in `ys`.
290 //! In other words, the following holds for any object `pair(k, v)`:
291 //! @code
292 //! pair(k, v) ^in^ intersection(xs, ys) if and only if (k, v) ^in^ xs && k ^in^ keys(ys)
293 //! @endcode
294 //!
295 //!
296 //! @note
297 //! This function is not commutative, i.e. `intersection(xs, ys)` is not
298 //! necessarily the same as `intersection(ys, xs)`. Indeed, the set of keys
299 //! in `intersection(xs, ys)` is always the same as the set of keys in
300 //! `intersection(ys, xs)`, but the value associated to each key may be
301 //! different. `intersection(xs, ys)` contains values present in `xs`, and
302 //! `intersection(ys, xs)` contains values present in `ys`.
303 //!
304 //!
305 //! @param xs, ys
306 //! Two maps to intersect.
307 //!
308 //!
309 //! Example
310 //! -------
311 //! @include example/map/intersection.cpp
312 #ifdef BOOST_HANA_DOXYGEN_INVOKED
313 constexpr auto intersection = [](auto&& xs, auto&& ys) {
314 return tag-dispatched;
315 };
316 #endif
317
318 //! Returns the difference of two maps.
319 //! @relates hana::map
320 //!
321 //! Given two maps `xs` and `ys`, `difference(xs, ys)` is a new map
322 //! containing exactly those (key, value) pairs from xs, for which key
323 //! is not present in `keys(ys)`.
324 //! In other words, the following holds for any object `pair(k, v)`:
325 //! @code
326 //! pair(k, v) ^in^ difference(xs, ys) if and only if (k, v) ^in^ xs && k ^not in^ keys(ys)
327 //! @endcode
328 //!
329 //!
330 //! @note
331 //! This function is not commutative, i.e. `difference(xs, ys)` is not
332 //! necessarily the same as `difference(ys, xs)`.
333 //! Indeed, consider the case where `xs` is empty and `ys` isn't.
334 //! In that case, `difference(xs, ys)` is empty, but `difference(ys, xs)`
335 //! is equal to `ys`.
336 //! For symmetric version of this operation, see `symmetric_difference`.
337 //!
338 //!
339 //! @param xs, ys
340 //! Two maps to compute the difference of.
341 //!
342 //!
343 //! Example
344 //! -------
345 //! @include example/map/intersection.cpp
346 #ifdef BOOST_HANA_DOXYGEN_INVOKED
347 constexpr auto difference = [](auto&& xs, auto&& ys) {
348 return tag-dispatched;
349 };
350 #endif
351
352 //! Returns the symmetric set-theoretic difference of two maps.
353 //! @relates hana::map
354 //!
355 //! Given two sets `xs` and `ys`, `symmetric_difference(xs, ys)` is a new
356 //! map containing all the elements of `xs` whose keys are not contained in `keys(ys)`,
357 //! and all the elements of `ys` whose keys are not contained in `keys(xs)`. The
358 //! symmetric difference of two maps satisfies the following:
359 //! @code
360 //! symmetric_difference(xs, ys) == union_(difference(xs, ys), difference(ys, xs))
361 //! @endcode
362 //!
363 //!
364 //! @param xs, ys
365 //! Two maps to compute the symmetric difference of.
366 //!
367 //!
368 //! Example
369 //! -------
370 //! @include example/map/symmetric_difference.cpp
371 #ifdef BOOST_HANA_DOXYGEN_INVOKED
372 constexpr auto symmetric_difference = [](auto&& xs, auto&& ys) {
373 return tag-dispatched;
374 };
375 #endif
376
377
378 BOOST_HANA_NAMESPACE_END
379
380 #endif // !BOOST_HANA_FWD_MAP_HPP