Skip to content

Instantly share code, notes, and snippets.

@jonwis
Created January 12, 2024 21:37
Show Gist options
  • Save jonwis/01af4d1972d974c838e1e36294eebba9 to your computer and use it in GitHub Desktop.
Save jonwis/01af4d1972d974c838e1e36294eebba9 to your computer and use it in GitHub Desktop.
Bijection support-ish?
#include <tuple>
#include <iostream>
#include <algorithm>
#include <string_view>
#include <array>
#include <stdexcept>
#include <optional>
// This is a bijection lookup helper that given an array of pairs finds the key or
// the value. The keys should be sorted.
template<typename TItems, typename TFind> constexpr auto bijection_find_key(TItems const& items, TFind const& key)
{
auto i = std::lower_bound(std::begin(items), std::end(items), key, [&](auto&& maybe, auto&& toFind)
{
return maybe.first < toFind;
});
if ((i != std::end(items)) && (i->first == key))
{
return std::optional(i->second);
}
else
{
return std::optional<decltype(i->second)>{};
}
}
template<typename TItems, typename TFind> constexpr auto bijection_find_value(TItems const& items, TFind const& value)
{
auto i = std::find_if(std::begin(items), std::end(items), [&](auto&& which) { return which.second == value; });
if (i != std::end(items))
{
return std::optional(i->first);
}
else
{
return std::optional<decltype(i->first)>{};
}
}
template<typename T> constexpr bool bijection_sorted(T const& j)
{
return std::is_sorted(std::begin(j), std::end(j), [](auto&& a, auto&& b) { return a.first < b.first; });
}
template<typename TEnum> constexpr std::wstring_view get_name(TEnum value);
template<typename TEnum> constexpr TEnum get_value(std::wstring_view name);
enum class MyValues : uint32_t
{
Unknown = 0,
Green,
Red,
Orange,
};
constexpr static std::pair<std::wstring_view, MyValues> sc_MyValuesNames[] =
{
{ L"Green", MyValues::Green },
{ L"Orange", MyValues::Orange },
{ L"Red", MyValues::Red },
{ L"Unknown", MyValues::Unknown },
};
template<> constexpr std::wstring_view get_name(MyValues v)
{
auto i = bijection_find_value(sc_MyValuesNames, v);
return i ? *i : L"";
}
template<> constexpr MyValues get_value(std::wstring_view k)
{
static_assert(bijection_sorted(sc_MyValuesNames));
auto i = bijection_find_key(sc_MyValuesNames, k);
return i ? *i : MyValues{};
}
void use2()
{
auto t = get_name(MyValues::Green);
auto q = get_value<MyValues>(L"Orange");
std::wcout << t << L" " << static_cast<uint32_t>(q);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment