Add void to Switch
This commit is contained in:
parent
eaddebf1e5
commit
e15d520cfa
2 changed files with 34 additions and 14 deletions
|
@ -20,4 +20,11 @@ auto main() -> int {
|
|||
[] {
|
||||
return 42;
|
||||
}) == 42);
|
||||
static_assert([] {
|
||||
int response{};
|
||||
utempl::Switch(utempl::Tuple{2, 1, 0}, utempl::Tuple{0, 1, 2}, 0, [&](int value) {
|
||||
response = value + 1;
|
||||
});
|
||||
return response;
|
||||
}() == 3);
|
||||
};
|
||||
|
|
|
@ -644,11 +644,14 @@ constexpr auto Enumerate(Tuple&& tuple) {
|
|||
};
|
||||
|
||||
template <typename T>
|
||||
requires requires { T{}; }
|
||||
requires std::same_as<T, void> || requires { T{}; }
|
||||
constexpr auto kDefaultCreator = [] {
|
||||
return T{};
|
||||
};
|
||||
|
||||
template <>
|
||||
constexpr auto kDefaultCreator<void> = [] {};
|
||||
|
||||
namespace impl {
|
||||
|
||||
template <typename Key, typename KeysTuple>
|
||||
|
@ -657,21 +660,30 @@ concept ComparableSwitchConcept = decltype(Unpack(std::declval<KeysTuple>(), []<
|
|||
}))::kValue;
|
||||
|
||||
template <typename F, typename ValuesTuple, typename R>
|
||||
concept CallableSwitchConcept = decltype(Unpack(std::declval<ValuesTuple>(), []<typename... Ts>(Ts&&...) {
|
||||
concept CallableSwitchConcept = std::same_as<R, void> || decltype(Unpack(std::declval<ValuesTuple>(), []<typename... Ts>(Ts&&...) {
|
||||
return kWrapper<(std::convertible_to<std::invoke_result_t<F, Ts>, std::optional<R>> && ...)>;
|
||||
}))::kValue;
|
||||
}))::kValue;
|
||||
|
||||
} // namespace impl
|
||||
|
||||
template <std::move_constructible R,
|
||||
template <typename R = void,
|
||||
TupleLike KeysTuple,
|
||||
TupleLike ValuesTuple,
|
||||
impl::ComparableSwitchConcept<KeysTuple> Key,
|
||||
impl::CallableSwitchConcept<ValuesTuple, R> F,
|
||||
std::invocable Default = decltype(kDefaultCreator<R>)>
|
||||
constexpr auto Switch(KeysTuple&& keysTuple, ValuesTuple&& valuesTuple, Key&& key, F&& f, Default&& def = {}) {
|
||||
constexpr auto Switch(KeysTuple&& keysTuple, ValuesTuple&& valuesTuple, Key&& key, F&& f, Default&& def = {}) -> R
|
||||
requires std::move_constructible<R> || std::same_as<R, void>
|
||||
{
|
||||
return Unpack(std::forward<KeysTuple>(keysTuple), [&]<typename... Keys>(Keys&&... keys) {
|
||||
return Unpack(std::forward<ValuesTuple>(valuesTuple), [&]<typename... Values>(Values&&... values) {
|
||||
if constexpr(std::same_as<R, void>) {
|
||||
FirstOf(Tuple{[&] {
|
||||
return std::forward<Keys>(keys) == std::forward<Key>(key) ? (std::forward<F>(f)(std::forward<Values>(values)), true)
|
||||
: false;
|
||||
}...},
|
||||
false);
|
||||
} else {
|
||||
return *FirstOf(Tuple{[&] {
|
||||
return std::forward<Keys>(keys) == std::forward<Key>(key) ? std::forward<F>(f)(std::forward<Values>(values))
|
||||
: std::optional<R>{};
|
||||
|
@ -680,6 +692,7 @@ constexpr auto Switch(KeysTuple&& keysTuple, ValuesTuple&& valuesTuple, Key&& ke
|
|||
.or_else([&] -> std::optional<R> {
|
||||
return std::forward<Default>(def)();
|
||||
});
|
||||
};
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue