Created
January 12, 2024 21:37
-
-
Save jonwis/01af4d1972d974c838e1e36294eebba9 to your computer and use it in GitHub Desktop.
Bijection support-ish?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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