Migrated from the original repository
Original issue: serge-sans-paille/frozen#145
Originally reported by: @RazielXYZ
In a lot of use cases for frozen, such as enum-to-string mappings, it feels like it would be very useful to have the option for looking up values from either side.
Obviously, one could do this by manually making another map with the keys and values swapped, or even use a macro or code generator to do so, but those solutions tend to be either annoying to implement and use, or relatively fickle.
That in mind, I've implemented a quick and "simple" bimap on top of frozen::unordered_map, which can handle constexpr elements, and looks something like this:
template <typename T1, typename T2>
struct swappedPair {
constexpr std::pair<T2, T1> operator()(const std::pair<T1, T2>& inPair) {
return {inPair.second, inPair.first};
}
};
template <typename K, typename V, std::size_t N>
struct FrozenBimap {
const frozen::unordered_map<K, V, N> left;
const frozen::unordered_map<V, K, N> right;
constexpr std::array<std::pair<V, K>, N> makeR(std::pair<K, V> const (&items)[N]) {
return [] <std::size_t... I>(std::pair<K, V> const (&s)[N], std::index_sequence<I...>) -> std::array<std::pair<V, K>, N> {
return {swappedPair<K, V>{}(s[I]) ...};
}(std::forward<std::pair<K, V> const[N]>(items), std::make_index_sequence<N>{});
}
constexpr FrozenBimap() = delete;
constexpr FrozenBimap(std::pair<K, V> const (&items)[N]) :
left(frozen::unordered_map<K, V, N>{items}),
right(makeR(items)) {
}
constexpr FrozenBimap(std::array<std::pair<K, V>, N> const& items) :
left(frozen::unordered_map<K, V, N>{items}),
right(makeR(items)) {
}
};
Would something like this be useful as a part of frozen proper? I could try to further refine it then do a PR. Note that this version only works with C++20, but I'm pretty sure C++14 would be doable, although not quite as clean on the makeR method's implementation.
Also, obviously because the values are keys for the second map, this would likely be limited to both keys and values being immutable.
In a lot of use cases for frozen, such as enum-to-string mappings, it feels like it would be very useful to have the option for looking up values from either side.
Obviously, one could do this by manually making another map with the keys and values swapped, or even use a macro or code generator to do so, but those solutions tend to be either annoying to implement and use, or relatively fickle.
That in mind, I've implemented a quick and "simple" bimap on top of
frozen::unordered_map, which can handle constexpr elements, and looks something like this:Would something like this be useful as a part of frozen proper? I could try to further refine it then do a PR. Note that this version only works with C++20, but I'm pretty sure C++14 would be doable, although not quite as clean on the
makeRmethod's implementation.Also, obviously because the values are keys for the second map, this would likely be limited to both keys and values being immutable.