Boost.Hana  1.0.2
Your standard library for metaprogramming
boost::hana::map< Pairs > Struct Template Reference

Description

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 that 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 only a shortcut for

decltype(hana::make_pair(std::declval<Pairs>()...))

which is not something that can be pattern-matched on during template argument deduction, for example.

Modeled concepts

  1. Comparable
    Two maps are equal iff all their keys are equal and are associated to equal values.
    // Copyright Louis Dionne 2013-2016
    // Distributed under the Boost Software License, Version 1.0.
    // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
    #include <string>
    namespace hana = boost::hana;
    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)
    )
    );
    }
  2. 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.
    // Copyright Louis Dionne 2013-2016
    // Distributed under the Boost Software License, Version 1.0.
    // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
    namespace hana = boost::hana;
    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'), "");
    BOOST_HANA_CONSTANT_CHECK(hana::find(m, hana::type_c<void>) == hana::nothing);
    BOOST_HANA_CONSTANT_CHECK(hana::find(m, hana::int_c<3>) == hana::nothing);
    // operator[] is equivalent to at_key
    static_assert(m[hana::type_c<int>] == 'i', "");
    static_assert(m[hana::type_c<float>] == 'f', "");
    int main() { }
  3. 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.
    // Copyright Louis Dionne 2013-2016
    // Distributed under the Boost Software License, Version 1.0.
    // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
    namespace hana = boost::hana;
    int main() {
    // Given a map of (key, value) pairs, returns a map of (value, key) pairs.
    // This requires both the keys and the values to be compile-time Comparable.
    auto invert = [](auto map) {
    return hana::fold_left(map, hana::make_map(), [](auto map, auto pair) {
    return hana::insert(map, hana::make_pair(hana::second(pair), hana::first(pair)));
    });
    };
    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 Products 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.

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <string>
namespace hana = boost::hana;
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

// Copyright Louis Dionne 2016
// Distributed under the Boost Software License, Version 1.0.
#include <functional>
#include <string>
#include <vector>
namespace hana = boost::hana;
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) {
auto is_known_event = hana::contains(map_, e);
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 {
auto is_known_event = hana::contains(map_, e);
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"));
BOOST_HANA_RUNTIME_CHECK(triggered_events == std::vector<std::string>{
"foo:1", "foo:2", "bar:1", "baz:1"
});
}

Synopsis of associated functions

template<>
constexpr auto make< map_tag >
 Function object for creating a hana::map. More...
 
constexpr auto make_map = make<map_tag>
 Alias to make<map_tag>; provided for convenience. More...
 
constexpr auto to_map = to<map_tag>
 Equivalent to to<map_tag>; provided for convenience. More...
 
constexpr auto keys
 Returns a Sequence of the keys of the map, in unspecified order. More...
 
constexpr auto values
 Returns a Sequence of the values of the map, in unspecified order. More...
 
constexpr auto insert
 Inserts a new key/value pair in a map. More...
 
constexpr auto erase_key
 Removes a key/value pair from a map. More...
 

Friends

template<typename X , typename Y >
constexpr auto operator== (X &&x, Y &&y)
 Equivalent to hana::equal
 
template<typename X , typename Y >
constexpr auto operator!= (X &&x, Y &&y)
 Equivalent to hana::not_equal
 

Public Member Functions

constexpr map ()=default
 Default-construct a map. This constructor only exists when all the elements of the map are default-constructible.
 
constexpr map (map const &other)=default
 Copy-construct a map from another map. This constructor only exists when all the elements of the map are copy-constructible.
 
constexpr map (map &&other)=default
 Move-construct a map from another map. This constructor only exists when all the elements of the map are move-constructible.
 
template<typename... P>
constexpr map (P &&...pairs)
 Construct the map from the provided pairs. P... must be pairs of the same type (modulo ref and cv-qualifiers), and in the same order, as those appearing in Pairs.... The pairs provided to this constructor are emplaced into the map's storage using perfect forwarding.
 
template<typename Key >
decltype(auto) constexpr operator[] (Key &&key)
 Equivalent to hana::at_key
 

Associated functions

template<typename... Pairs>
template<>
constexpr auto make< map_tag >
related
Initial value:
= [](auto&& ...pairs) {
return map<implementation_defined>{forwarded(pairs)...};
}

Function object for creating a hana::map.

Given zero or more Products representing key/value associations, make<map_tag> returns a hana::map associating these keys to these values.

make<map_tag> requires all the keys to be unique and to have different hashes. If you need to create a map with duplicate keys or with keys whose hashes might collide, use hana::to_map or insert (key, value) pairs to an empty map successively. However, be aware that doing so will be much more compile-time intensive than using make<map_tag>, because the uniqueness of keys will have to be enforced.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <string>
namespace hana = boost::hana;
using namespace std::literals;
int main() {
hana::make_map(
hana::make_pair(hana::int_c<1>, "foobar"s),
hana::make_pair(hana::type_c<void>, 1234)
)
==
hana::make<hana::map_tag>(
hana::make_pair(hana::int_c<1>, "foobar"s),
hana::make_pair(hana::type_c<void>, 1234)
)
);
}
template<typename... Pairs>
constexpr auto make_map = make<map_tag>
related

Alias to make<map_tag>; provided for convenience.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <string>
namespace hana = boost::hana;
using namespace std::literals;
int main() {
hana::make_map(
hana::make_pair(hana::int_c<1>, "foobar"s),
hana::make_pair(hana::type_c<void>, 1234)
)
==
hana::make<hana::map_tag>(
hana::make_pair(hana::int_c<1>, "foobar"s),
hana::make_pair(hana::type_c<void>, 1234)
)
);
}
template<typename... Pairs>
constexpr auto to_map = to<map_tag>
related

Equivalent to to<map_tag>; provided for convenience.

template<typename... Pairs>
constexpr auto keys
related
Initial value:
= [](auto&& map) {
return implementation_defined;
}

Returns a Sequence of the keys of the map, in unspecified order.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <string>
namespace hana = boost::hana;
using namespace std::literals;
int main() {
auto m = hana::make_map(
hana::make_pair(hana::int_c<1>, "foobar"s),
hana::make_pair(hana::type_c<void>, 1234)
);
// The order of the keys is unspecified.
hana::keys(m) ^hana::in^ hana::permutations(hana::make_tuple(hana::int_c<1>, hana::type_c<void>))
);
}
template<typename... Pairs>
constexpr auto values
related
Initial value:
= [](auto&& map) -> decltype(auto) {
return implementation_defined;
}

Returns a Sequence of the values of the map, in unspecified order.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <string>
namespace hana = boost::hana;
using namespace std::literals;
int main() {
auto m = hana::make_map(
hana::make_pair(hana::int_c<1>, "foobar"s),
hana::make_pair(hana::type_c<void>, 1234)
);
// The order of the values is unspecified.
hana::values(m) ^hana::in^ hana::permutations(hana::make_tuple("foobar"s, 1234))
);
}
template<typename... Pairs>
constexpr auto insert
related
Initial value:
= [](auto&& map, auto&& pair) {
return tag-dispatched;
}

Inserts a new key/value pair in a map.

Given a (key, value) pair, insert inserts this new pair into a map. If the map already contains this key, nothing is done and the map is returned as-is.

Parameters
mapThe map in which to insert a (key,value) pair.
pairAn arbitrary Product representing a (key, value) pair to insert in the map. The key must be compile-time Comparable.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <string>
namespace hana = boost::hana;
using namespace std::literals;
int main() {
auto m = hana::make_map(
hana::make_pair(hana::type_c<int>, "abcd"s),
hana::make_pair(hana::type_c<void>, 1234)
);
hana::insert(m, hana::make_pair(hana::type_c<float>, 'x')) ==
hana::make_map(
hana::make_pair(hana::type_c<int>, "abcd"s),
hana::make_pair(hana::type_c<void>, 1234),
hana::make_pair(hana::type_c<float>, 'x')
)
);
BOOST_HANA_RUNTIME_CHECK(hana::insert(m, hana::make_pair(hana::type_c<void>, 'x')) == m);
}
template<typename... Pairs>
constexpr auto erase_key
related
Initial value:
= [](auto&& map, auto&& key) {
return tag-dispatched;
}

Removes a key/value pair from a map.

Returns a new hana::map containing all the elements of the original, except for the (key, value) pair whose key compares equal to the given key. If the map does not contain such an element, a new map equal to the original is returned.

Parameters
mapThe map in which to erase a key.
keyA key to remove from the map. It must be compile-time Comparable.

Example

// Copyright Louis Dionne 2013-2016
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <string>
namespace hana = boost::hana;
using namespace std::literals;
int main() {
auto m = hana::make_map(
hana::make_pair(hana::type_c<int>, "abcd"s),
hana::make_pair(hana::type_c<void>, 1234),
hana::make_pair(BOOST_HANA_STRING("foobar!"), hana::type_c<char>)
);
hana::erase_key(m, BOOST_HANA_STRING("foobar!")) ==
hana::make_map(
hana::make_pair(hana::type_c<int>, "abcd"s),
hana::make_pair(hana::type_c<void>, 1234)
)
);
BOOST_HANA_RUNTIME_CHECK(hana::erase_key(m, hana::type_c<char>) == m);
}