utils: add helpers for assoc-pairs

Add some unit-test, too.
This commit is contained in:
Dirk-Jan C. Binnema 2022-09-28 22:36:57 +03:00
parent ca04ae4d65
commit 9e60ebb683
2 changed files with 72 additions and 1 deletions

View File

@ -326,7 +326,7 @@ typename Sequence::const_iterator seq_find_if(const Sequence& seq, UnaryPredicat
}
/**
* Is at least pred(element) true for at least one element of sequence
* Is pred(element) true for at least one element of sequence?
*
* @param seq sequence
* @param pred a predicate
@ -391,6 +391,49 @@ void seq_for_each(const Sequence& seq, UnaryOp op) {
std::for_each(seq.cbegin(), seq.cend(), op);
}
/**
* array of associated pair elements -- like an alist
* but based on std::array and thus can be constexpr
*/
template<typename T1, typename T2, std::size_t N>
using AssocPairs = std::array<std::pair<T1, T2>, N>;
/**
* Get the first value of the pair where the second element is @param s.
*
* @param p AssocPairs
* @param s some second pair value
*
* @return the matching first pair value, or Nothing if not found.
*/
template<typename P>
constexpr Option<typename P::value_type::first_type>
to_first(const P& p, typename P::value_type::second_type s)
{
for (const auto& item: p)
if (item.second == s)
return item.first;
return Nothing;
}
/**
* Get the second value of the pair where the first element is @param f.
*
* @param p AssocPairs
* @param f some first pair value
*
* @return the matching second pair value, or Nothing if not found.
*/
template<typename P>
constexpr Option<typename P::value_type::second_type>
to_second(const P& p, typename P::value_type::first_type f)
{
for (const auto& item: p)
if (item.first == f)
return item.second;
return Nothing;
}
/**
* Convert string view in something printable with %*s

View File

@ -298,6 +298,33 @@ test_error()
g_clear_error(&err);
}
enum struct TestEnum { A, B, C };
constexpr AssocPairs<TestEnum, std::string_view, 3>
test_epairs = {{
{TestEnum::A, "a"},
{TestEnum::B, "b"},
{TestEnum::C, "c"},
}};
static constexpr Option<std::string_view>
to_name(TestEnum te)
{
return to_second(test_epairs, te);
}
static constexpr Option<TestEnum>
to_type(std::string_view name)
{
return to_first(test_epairs, name);
}
static void
test_enum_pairs(void)
{
assert_equal(to_name(TestEnum::A).value(), "a");
g_assert_true(to_type("c").value() == TestEnum::C);
}
int
main(int argc, char* argv[])
@ -317,6 +344,7 @@ main(int argc, char* argv[])
g_test_add_func("/utils/to-from-lexnum", test_to_from_lexnum);
g_test_add_func("/utils/locale-workaround", test_locale_workaround);
g_test_add_func("/utils/error", test_error);
g_test_add_func("/utils/enum-pairs", test_enum_pairs);
return g_test_run();
}