template<typename... Pairs>
struct boost::hana::map< Pairs >
Basic associative container requiring unique, Comparable
and Hashable
keys.
The order of the elements of the map is unspecified. Also, all the keys must be Hashable
, and any two keys with equal hashes must be Comparable
with each other at compile-time.
- Note
- The actual representation of a
hana::map
is an implementation detail. As such, one should not assume anything more than what is explicitly documented as being part of the interface of a map, such as:
- the presence of additional constructors
- the presence of additional assignment operators
- the fact that
hana::map<Pairs...>
is, or is not, a dependent type
In particular, the last point is very important; hana::map<Pairs...>
is basically equivalent to decltype(hana::make_pair(std::declval<Pairs>()...))
which is not something that can be pattern-matched on during template argument deduction, for example. More details in the tutorial.
Modeled concepts
Comparable
Two maps are equal iff all their keys are equal and are associated to equal values. #include <string>
using namespace std::literals;
int main() {
hana::make_map(
hana::make_pair(hana::char_c<'a'>, "foobar"s),
hana::make_pair(hana::type_c<int&&>, nullptr)
)
==
hana::make_map(
hana::make_pair(hana::type_c<int&&>, (void*)0),
hana::make_pair(hana::char_c<'a'>, "foobar"s)
)
);
}
Searchable
A map can be searched by its keys with a predicate yielding a compile-time Logical
. Also note that operator[]
can be used instead of at_key
. constexpr auto m = hana::make_map(
hana::make_pair(hana::type_c<int>, 'i'),
hana::make_pair(hana::type_c<float>, 'f')
);
static_assert(
hana::find(m, hana::type_c<int>) == hana::just(
'i'),
"");
static_assert(
hana::find(m, hana::type_c<float>) == hana::just(
'f'),
"");
static_assert(m[hana::type_c<int>] == 'i', "");
static_assert(m[hana::type_c<float>] == 'f', "");
int main() { }
Foldable
Folding a map is equivalent to folding a list of the key/value pairs it contains. In particular, since that list is not guaranteed to be in any specific order, folding a map with an operation that is not both commutative and associative will yield non-deterministic behavior. int main() {
auto invert = [](
auto map) {
});
};
auto m = hana::make_map(
hana::make_pair(hana::type_c<int>, hana::int_c<1>),
hana::make_pair(hana::type_c<float>, hana::int_c<2>),
hana::make_pair(hana::int_c<3>, hana::type_c<void>)
);
hana::make_map(
hana::make_pair(hana::int_c<1>, hana::type_c<int>),
hana::make_pair(hana::int_c<2>, hana::type_c<float>),
hana::make_pair(hana::type_c<void>, hana::int_c<3>)
)
);
}
Conversion from any Foldable
Any Foldable
of Product
s can be converted to a hana::map
with hana::to<hana::map_tag>
or, equivalently, hana::to_map
. If the Foldable
contains duplicate keys, only the value associated to the first occurence of each key is kept.
#include <string>
using namespace std::literals;
int main() {
auto xs = hana::make_tuple(
hana::make_pair(hana::type_c<int>, "abcd"s),
hana::make_pair(hana::type_c<void>, 1234),
hana::make_pair(hana::type_c<int>, nullptr)
);
hana::to<hana::map_tag>(xs) == hana::make_map(
hana::make_pair(hana::type_c<int>, "abcd"s),
hana::make_pair(hana::type_c<void>, 1234)
)
);
}
Example
#include <functional>
#include <string>
#include <vector>
template <typename ...Events>
struct event_system {
using Callback = std::function<void()>;
hana::map<hana::pair<Events, std::vector<Callback>>...> map_;
template <typename Event, typename F>
void on(Event e, F handler) {
static_assert(is_known_event,
"trying to add a handler to an unknown event");
map_[e].push_back(handler);
}
template <typename Event>
void trigger(Event e) const {
static_assert(is_known_event,
"trying to trigger an unknown event");
for (auto& handler : this->map_[e])
handler();
}
};
template <typename ...Events>
event_system<Events...> make_event_system(Events ...events) {
return {};
}
int main() {
auto events = make_event_system(
BOOST_HANA_STRING("foo"),
BOOST_HANA_STRING("bar"),
BOOST_HANA_STRING("baz")
);
std::vector<std::string> triggered_events;
events.on(BOOST_HANA_STRING("foo"), [&] {
triggered_events.push_back("foo:1");
});
events.on(BOOST_HANA_STRING("foo"), [&] {
triggered_events.push_back("foo:2");
});
events.on(BOOST_HANA_STRING("bar"), [&] {
triggered_events.push_back("bar:1");
});
events.on(BOOST_HANA_STRING("baz"), [&] {
triggered_events.push_back("baz:1");
});
events.trigger(BOOST_HANA_STRING("foo"));
events.trigger(BOOST_HANA_STRING("bar"));
events.trigger(BOOST_HANA_STRING("baz"));
"foo:1", "foo:2", "bar:1", "baz:1"
});
}