Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 09:53:04

0001 /*!
0002 @file
0003 Forward declares `boost::hana::map`.
0004 
0005 Copyright Louis Dionne 2013-2022
0006 Distributed under the Boost Software License, Version 1.0.
0007 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
0008  */
0009 
0010 #ifndef BOOST_HANA_FWD_MAP_HPP
0011 #define BOOST_HANA_FWD_MAP_HPP
0012 
0013 #include <boost/hana/config.hpp>
0014 #include <boost/hana/fwd/core/to.hpp>
0015 #include <boost/hana/fwd/core/make.hpp>
0016 #include <boost/hana/fwd/erase_key.hpp>
0017 #include <boost/hana/fwd/insert.hpp>
0018 #include <boost/hana/fwd/keys.hpp>
0019 
0020 
0021 namespace boost { namespace hana {
0022     //! Tag representing `hana::map`s.
0023     //! @relates hana::map
0024     struct map_tag { };
0025 
0026     namespace detail {
0027         template <typename ...Pairs>
0028         struct make_map_type;
0029     }
0030 
0031     //! @ingroup group-datatypes
0032     //! Basic associative container requiring unique, `Comparable` and
0033     //! `Hashable` keys.
0034     //!
0035     //! The order of the elements of the map is unspecified. Also, all the
0036     //! keys must be `Hashable`, and any two keys with equal hashes must be
0037     //! `Comparable` with each other at compile-time.
0038     //!
0039     //! @note
0040     //! The actual representation of a `hana::map` is an implementation
0041     //! detail. As such, one should not assume anything more than what is
0042     //! explicitly documented as being part of the interface of a map,
0043     //! such as:
0044     //! - the presence of additional constructors
0045     //! - the presence of additional assignment operators
0046     //! - the fact that `hana::map<Pairs...>` is, or is not, a dependent type
0047     //! .
0048     //! In particular, the last point is very important; `hana::map<Pairs...>`
0049     //! is basically equivalent to
0050     //! @code
0051     //!     decltype(hana::make_pair(std::declval<Pairs>()...))
0052     //! @endcode
0053     //! which is not something that can be pattern-matched on during template
0054     //! argument deduction, for example. More details [in the tutorial]
0055     //! (@ref tutorial-containers-types).
0056     //!
0057     //!
0058     //! Modeled concepts
0059     //! ----------------
0060     //! 1. `Comparable`\n
0061     //! Two maps are equal iff all their keys are equal and are associated
0062     //! to equal values.
0063     //! @include example/map/comparable.cpp
0064     //!
0065     //! 2. `Searchable`\n
0066     //! A map can be searched by its keys with a predicate yielding a
0067     //! compile-time `Logical`. Also note that `operator[]` can be used
0068     //! instead of `at_key`.
0069     //! @include example/map/searchable.cpp
0070     //!
0071     //! 3. `Foldable`\n
0072     //! Folding a map is equivalent to folding a list of the key/value pairs
0073     //! it contains. In particular, since that list is not guaranteed to be
0074     //! in any specific order, folding a map with an operation that is not
0075     //! both commutative and associative will yield non-deterministic behavior.
0076     //! @include example/map/foldable.cpp
0077     //!
0078     //!
0079     //! Conversion from any `Foldable`
0080     //! ------------------------------
0081     //! Any `Foldable` of `Product`s can be converted to a `hana::map` with
0082     //! `hana::to<hana::map_tag>` or, equivalently, `hana::to_map`. If the
0083     //! `Foldable` contains duplicate keys, only the value associated to the
0084     //! first occurence of each key is kept.
0085     //! @include example/map/to.cpp
0086     //!
0087     //!
0088     //! Example
0089     //! -------
0090     //! @include example/map/map.cpp
0091 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0092     template <typename ...Pairs>
0093     struct map {
0094         //! Default-construct a map. This constructor only exists when all the
0095         //! elements of the map are default-constructible.
0096         constexpr map() = default;
0097 
0098         //! Copy-construct a map from another map. This constructor only
0099         //! exists when all the elements of the map are copy-constructible.
0100         constexpr map(map const& other) = default;
0101 
0102         //! Move-construct a map from another map. This constructor only
0103         //! exists when all the elements of the map are move-constructible.
0104         constexpr map(map&& other) = default;
0105 
0106         //! Construct the map from the provided pairs. `P...` must be pairs of
0107         //! the same type (modulo ref and cv-qualifiers), and in the same order,
0108         //! as those appearing in `Pairs...`. The pairs provided to this
0109         //! constructor are emplaced into the map's storage using perfect
0110         //! forwarding.
0111         template <typename ...P>
0112         explicit constexpr map(P&& ...pairs);
0113 
0114         //! Assign a map to another map __with the exact same type__. Only
0115         //! exists when all the elements of the map are copy-assignable.
0116         constexpr map& operator=(map const& other);
0117 
0118         //! Move-assign a map to another map __with the exact same type__.
0119         //! Only exists when all the elements of the map are move-assignable.
0120         constexpr map& operator=(map&& other);
0121 
0122         //! Equivalent to `hana::equal`
0123         template <typename X, typename Y>
0124         friend constexpr auto operator==(X&& x, Y&& y);
0125 
0126         //! Equivalent to `hana::not_equal`
0127         template <typename X, typename Y>
0128         friend constexpr auto operator!=(X&& x, Y&& y);
0129 
0130         //! Equivalent to `hana::at_key`
0131         template <typename Key>
0132         constexpr decltype(auto) operator[](Key&& key);
0133     };
0134 #else
0135     template <typename ...Pairs>
0136     using map = typename detail::make_map_type<Pairs...>::type;
0137 #endif
0138 
0139     //! Function object for creating a `hana::map`.
0140     //! @relates hana::map
0141     //!
0142     //! Given zero or more `Product`s representing key/value associations,
0143     //! `make<map_tag>` returns a `hana::map` associating these keys to these
0144     //! values.
0145     //!
0146     //! `make<map_tag>` requires all the keys to be unique and to have
0147     //! different hashes. If you need to create a map with duplicate keys
0148     //! or with keys whose hashes might collide, use `hana::to_map` or
0149     //! insert `(key, value)` pairs to an empty map successively. However,
0150     //! be aware that doing so will be much more compile-time intensive than
0151     //! using `make<map_tag>`, because the uniqueness of keys will have to be
0152     //! enforced.
0153     //!
0154     //!
0155     //! Example
0156     //! -------
0157     //! @include example/map/make.cpp
0158 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0159     template <>
0160     constexpr auto make<map_tag> = [](auto&& ...pairs) {
0161         return map<implementation_defined>{forwarded(pairs)...};
0162     };
0163 #endif
0164 
0165     //! Alias to `make<map_tag>`; provided for convenience.
0166     //! @relates hana::map
0167     //!
0168     //!
0169     //! Example
0170     //! -------
0171     //! @include example/map/make.cpp
0172     BOOST_HANA_INLINE_VARIABLE constexpr auto make_map = make<map_tag>;
0173 
0174     //! Equivalent to `to<map_tag>`; provided for convenience.
0175     //! @relates hana::map
0176     BOOST_HANA_INLINE_VARIABLE constexpr auto to_map = to<map_tag>;
0177 
0178     //! Returns a `Sequence` of the keys of the map, in unspecified order.
0179     //! @relates hana::map
0180     //!
0181     //!
0182     //! Example
0183     //! -------
0184     //! @include example/map/keys.cpp
0185 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0186     constexpr auto keys = [](auto&& map) {
0187         return implementation_defined;
0188     };
0189 #endif
0190 
0191     //! Returns a `Sequence` of the values of the map, in unspecified order.
0192     //! @relates hana::map
0193     //!
0194     //!
0195     //! Example
0196     //! -------
0197     //! @include example/map/values.cpp
0198 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0199     constexpr auto values = [](auto&& map) -> decltype(auto) {
0200         return implementation_defined;
0201     };
0202 #else
0203     struct values_t {
0204         template <typename Map>
0205         constexpr decltype(auto) operator()(Map&& map) const;
0206     };
0207 
0208     BOOST_HANA_INLINE_VARIABLE constexpr values_t values{};
0209 #endif
0210 
0211     //! Inserts a new key/value pair in a map.
0212     //! @relates hana::map
0213     //!
0214     //! Given a `(key, value)` pair, `insert` inserts this new pair into a
0215     //! map. If the map already contains this key, nothing is done and the
0216     //! map is returned as-is.
0217     //!
0218     //!
0219     //! @param map
0220     //! The map in which to insert a `(key,value)` pair.
0221     //!
0222     //! @param pair
0223     //! An arbitrary `Product` representing a `(key, value)` pair to insert
0224     //! in the map. The `key` must be compile-time `Comparable`.
0225     //!
0226     //!
0227     //! Example
0228     //! -------
0229     //! @include example/map/insert.cpp
0230 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0231     constexpr auto insert = [](auto&& map, auto&& pair) {
0232         return tag-dispatched;
0233     };
0234 #endif
0235 
0236     //! Removes a key/value pair from a map.
0237     //! @relates hana::map
0238     //!
0239     //! Returns a new `hana::map` containing all the elements of the original,
0240     //! except for the `(key, value)` pair whose `key` compares `equal`
0241     //! to the given key. If the map does not contain such an element,
0242     //! a new map equal to the original is returned.
0243     //!
0244     //!
0245     //! @param map
0246     //! The map in which to erase a `key`.
0247     //!
0248     //! @param key
0249     //! A key to remove from the map. It must be compile-time `Comparable`.
0250     //!
0251     //!
0252     //! Example
0253     //! -------
0254     //! @include example/map/erase_key.cpp
0255 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0256     constexpr auto erase_key = [](auto&& map, auto&& key) {
0257         return tag-dispatched;
0258     };
0259 #endif
0260 
0261     //! Returns the union of two maps.
0262     //! @relates hana::map
0263     //!
0264     //! Given two maps `xs` and `ys`, `hana::union_(xs, ys)` is a new map
0265     //! containing all the elements of `xs` and all the elements of `ys`,
0266     //! without duplicates. If both `xs` and `ys` contain an element with the
0267     //! same `key`, the one in `ys` is taken. Functionally,
0268     //! `hana::union_(xs, ys)` is equivalent to
0269     //! @code
0270     //! hana::fold_left(xs, ys, hana::insert)
0271     //! @endcode
0272     //!
0273     //! @param xs, ys
0274     //! The two maps to compute the union of.
0275     //!
0276     //!
0277     //! Example
0278     //! -------
0279     //! @include example/map/union.cpp
0280 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0281     constexpr auto union_ = [](auto&& xs, auto&& ys) {
0282         return tag-dispatched;
0283     };
0284 #endif
0285 
0286     //! Returns the intersection of two maps.
0287     //! @relates hana::map
0288     //!
0289     //! Given two maps `xs` and `ys`, `intersection(xs, ys)` is a new map
0290     //! containing exactly those (key, value) pairs from xs, for which key
0291     //! is present in `ys`.
0292     //! In other words, the following holds for any object `pair(k, v)`:
0293     //! @code
0294     //!     pair(k, v) ^in^ intersection(xs, ys) if and only if (k, v) ^in^ xs && k ^in^ keys(ys)
0295     //! @endcode
0296     //!
0297     //!
0298     //! @note
0299     //! This function is not commutative, i.e. `intersection(xs, ys)` is not
0300     //! necessarily the same as `intersection(ys, xs)`. Indeed, the set of keys
0301     //! in `intersection(xs, ys)` is always the same as the set of keys in
0302     //! `intersection(ys, xs)`, but the value associated to each key may be
0303     //! different. `intersection(xs, ys)` contains values present in `xs`, and
0304     //! `intersection(ys, xs)` contains values present in `ys`.
0305     //!
0306     //!
0307     //! @param xs, ys
0308     //! Two maps to intersect.
0309     //!
0310     //!
0311     //! Example
0312     //! -------
0313     //! @include example/map/intersection.cpp
0314 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0315     constexpr auto intersection = [](auto&& xs, auto&& ys) {
0316         return tag-dispatched;
0317     };
0318 #endif
0319 
0320     //! Returns the difference of two maps.
0321     //! @relates hana::map
0322     //!
0323     //! Given two maps `xs` and `ys`, `difference(xs, ys)` is a new map
0324     //! containing exactly those (key, value) pairs from xs, for which key
0325     //! is not present in `keys(ys)`.
0326     //! In other words, the following holds for any object `pair(k, v)`:
0327     //! @code
0328     //!     pair(k, v) ^in^ difference(xs, ys) if and only if (k, v) ^in^ xs && k ^not in^ keys(ys)
0329     //! @endcode
0330     //!
0331     //!
0332     //! @note
0333     //! This function is not commutative, i.e. `difference(xs, ys)` is not
0334     //! necessarily the same as `difference(ys, xs)`.
0335     //! Indeed, consider the case where `xs` is empty and `ys` isn't.
0336     //! In that case, `difference(xs, ys)` is empty, but `difference(ys, xs)`
0337     //! is equal to `ys`.
0338     //! For symmetric version of this operation, see `symmetric_difference`.
0339     //!
0340     //!
0341     //! @param xs, ys
0342     //! Two maps to compute the difference of.
0343     //!
0344     //!
0345     //! Example
0346     //! -------
0347     //! @include example/map/intersection.cpp
0348 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0349     constexpr auto difference = [](auto&& xs, auto&& ys) {
0350         return tag-dispatched;
0351     };
0352 #endif
0353 
0354     //! Returns the symmetric set-theoretic difference of two maps.
0355     //! @relates hana::map
0356     //!
0357     //! Given two sets `xs` and `ys`, `symmetric_difference(xs, ys)` is a new
0358     //! map containing all the elements of `xs` whose keys are not contained in `keys(ys)`,
0359     //! and all the elements of `ys` whose keys are not contained in `keys(xs)`. The
0360     //! symmetric difference of two maps satisfies the following:
0361     //! @code
0362     //!     symmetric_difference(xs, ys) == union_(difference(xs, ys), difference(ys, xs))
0363     //! @endcode
0364     //!
0365     //!
0366     //! @param xs, ys
0367     //! Two maps to compute the symmetric difference of.
0368     //!
0369     //!
0370     //! Example
0371     //! -------
0372     //! @include example/map/symmetric_difference.cpp
0373 #ifdef BOOST_HANA_DOXYGEN_INVOKED
0374 constexpr auto symmetric_difference = [](auto&& xs, auto&& ys) {
0375         return tag-dispatched;
0376     };
0377 #endif
0378 
0379 
0380 }} // end namespace boost::hana
0381 
0382 #endif // !BOOST_HANA_FWD_MAP_HPP