Add call def if not found and def not default value
This commit is contained in:
parent
e15d520cfa
commit
ce44168333
1 changed files with 33 additions and 8 deletions
|
@ -317,9 +317,12 @@ concept UnpackConcept = []<std::size_t... Is>(std::index_sequence<Is...>) {
|
||||||
|
|
||||||
template <typename F, typename Tuple>
|
template <typename F, typename Tuple>
|
||||||
concept TransformConcept = []<std::size_t... Is>(std::index_sequence<Is...>) {
|
concept TransformConcept = []<std::size_t... Is>(std::index_sequence<Is...>) {
|
||||||
return ((std::invocable<F, decltype(Get<Is>(std::declval<Tuple>()))> &&
|
return ([] {
|
||||||
!std::same_as<std::invoke_result_t<F, decltype(Get<Is>(std::declval<Tuple>()))>, void>) &&
|
if constexpr(std::invocable<F, decltype(Get<Is>(std::declval<Tuple>()))>) {
|
||||||
...);
|
return !std::same_as<std::invoke_result_t<F, decltype(Get<Is>(std::declval<Tuple>()))>, void>;
|
||||||
|
};
|
||||||
|
return false;
|
||||||
|
}() && ...);
|
||||||
}(std::make_index_sequence<kTupleSize<Tuple>>());
|
}(std::make_index_sequence<kTupleSize<Tuple>>());
|
||||||
|
|
||||||
template <typename F, typename Tuple>
|
template <typename F, typename Tuple>
|
||||||
|
@ -422,7 +425,12 @@ struct LeftFold<T, F> {
|
||||||
|
|
||||||
template <typename F, typename T, typename Tuple>
|
template <typename F, typename T, typename Tuple>
|
||||||
concept LeftFoldConcept = decltype(Unpack(std::declval<Tuple>(), []<typename... Ts>(Ts&&...) {
|
concept LeftFoldConcept = decltype(Unpack(std::declval<Tuple>(), []<typename... Ts>(Ts&&...) {
|
||||||
return kWrapper<(std::convertible_to<std::invoke_result_t<F, T, Ts>, T> && ...)>;
|
return kWrapper<([] {
|
||||||
|
if constexpr(std::invocable<F, T, Ts>) {
|
||||||
|
return std::convertible_to<std::invoke_result_t<F, T, Ts>, T>;
|
||||||
|
};
|
||||||
|
return false;
|
||||||
|
}() && ...)>;
|
||||||
}))::kValue;
|
}))::kValue;
|
||||||
|
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
|
@ -518,7 +526,11 @@ namespace impl {
|
||||||
|
|
||||||
template <typename F, typename Tuple>
|
template <typename F, typename Tuple>
|
||||||
concept FilterConcept = decltype(Unpack(std::declval<Tuple>(), []<typename... Ts>(Ts&&...) {
|
concept FilterConcept = decltype(Unpack(std::declval<Tuple>(), []<typename... Ts>(Ts&&...) {
|
||||||
return kWrapper<((std::invocable<F, Ts> && std::convertible_to<std::invoke_result_t<F, Ts>, bool>) && ...)>;
|
return kWrapper<([] {
|
||||||
|
if constexpr(std::invocable<F, Ts>) {
|
||||||
|
return std::convertible_to<std::invoke_result_t<F, Ts>, bool>;
|
||||||
|
};
|
||||||
|
}() && ...)>;
|
||||||
}))::kValue;
|
}))::kValue;
|
||||||
|
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
|
@ -661,7 +673,14 @@ concept ComparableSwitchConcept = decltype(Unpack(std::declval<KeysTuple>(), []<
|
||||||
|
|
||||||
template <typename F, typename ValuesTuple, typename R>
|
template <typename F, typename ValuesTuple, typename R>
|
||||||
concept CallableSwitchConcept = std::same_as<R, void> || 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>> && ...)>;
|
return kWrapper<([] {
|
||||||
|
if constexpr(std::invocable<F, Ts>) {
|
||||||
|
if constexpr(!std::same_as<std::invoke_result_t<F, Ts>, void>) {
|
||||||
|
return std::convertible_to<std::invoke_result_t<F, Ts>, std::optional<R>>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return false;
|
||||||
|
}() && ...)>;
|
||||||
}))::kValue;
|
}))::kValue;
|
||||||
|
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
|
@ -673,7 +692,7 @@ template <typename R = void,
|
||||||
impl::CallableSwitchConcept<ValuesTuple, R> F,
|
impl::CallableSwitchConcept<ValuesTuple, R> F,
|
||||||
std::invocable Default = decltype(kDefaultCreator<R>)>
|
std::invocable Default = decltype(kDefaultCreator<R>)>
|
||||||
constexpr auto Switch(KeysTuple&& keysTuple, ValuesTuple&& valuesTuple, Key&& key, F&& f, Default&& def = {}) -> R
|
constexpr auto Switch(KeysTuple&& keysTuple, ValuesTuple&& valuesTuple, Key&& key, F&& f, Default&& def = {}) -> R
|
||||||
requires std::move_constructible<R> || std::same_as<R, void>
|
requires(std::move_constructible<R> || std::same_as<R, void>) && (kTupleSize<KeysTuple> == kTupleSize<ValuesTuple>)
|
||||||
{
|
{
|
||||||
return Unpack(std::forward<KeysTuple>(keysTuple), [&]<typename... Keys>(Keys&&... keys) {
|
return Unpack(std::forward<KeysTuple>(keysTuple), [&]<typename... Keys>(Keys&&... keys) {
|
||||||
return Unpack(std::forward<ValuesTuple>(valuesTuple), [&]<typename... Values>(Values&&... values) {
|
return Unpack(std::forward<ValuesTuple>(valuesTuple), [&]<typename... Values>(Values&&... values) {
|
||||||
|
@ -682,7 +701,13 @@ constexpr auto Switch(KeysTuple&& keysTuple, ValuesTuple&& valuesTuple, Key&& ke
|
||||||
return std::forward<Keys>(keys) == std::forward<Key>(key) ? (std::forward<F>(f)(std::forward<Values>(values)), true)
|
return std::forward<Keys>(keys) == std::forward<Key>(key) ? (std::forward<F>(f)(std::forward<Values>(values)), true)
|
||||||
: false;
|
: false;
|
||||||
}...},
|
}...},
|
||||||
false);
|
false)
|
||||||
|
? void(std::ignore)
|
||||||
|
: [&] {
|
||||||
|
if constexpr(!std::same_as<Default, decltype(kDefaultCreator<R>)>) {
|
||||||
|
std::forward<Default>(def)();
|
||||||
|
};
|
||||||
|
}();
|
||||||
} else {
|
} else {
|
||||||
return *FirstOf(Tuple{[&] {
|
return *FirstOf(Tuple{[&] {
|
||||||
return std::forward<Keys>(keys) == std::forward<Key>(key) ? std::forward<F>(f)(std::forward<Values>(values))
|
return std::forward<Keys>(keys) == std::forward<Key>(key) ? std::forward<F>(f)(std::forward<Values>(values))
|
||||||
|
|
Loading…
Reference in a new issue