Add Function and ImplicitConvertible concepts
This commit is contained in:
parent
570d087f05
commit
93783671cf
1 changed files with 17 additions and 31 deletions
|
@ -40,6 +40,19 @@ struct kSeq {
|
||||||
|
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
|
|
||||||
|
template <typename From, typename To>
|
||||||
|
concept ImplicitConvertibleTo = std::same_as<From, To> || requires(From from) { [](To) {}(from); };
|
||||||
|
|
||||||
|
template <typename F, typename Sig>
|
||||||
|
concept Function = []<typename R, typename... Ts>(TypeList<R(Ts...)>) {
|
||||||
|
if constexpr(std::invocable<F, Ts...>) {
|
||||||
|
return std::same_as<R, void> || ImplicitConvertibleTo<std::invoke_result_t<F, Ts...>, R>;
|
||||||
|
};
|
||||||
|
return false;
|
||||||
|
}(kType<Sig>);
|
||||||
|
|
||||||
|
static_assert(Function<decltype([]() {}), void()>);
|
||||||
|
|
||||||
template <std::size_t N>
|
template <std::size_t N>
|
||||||
inline constexpr impl::kSeq<N> kSeq;
|
inline constexpr impl::kSeq<N> kSeq;
|
||||||
|
|
||||||
|
@ -425,12 +438,7 @@ 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<([] {
|
return kWrapper<(Function<F, T(T, Ts)> && ...)>;
|
||||||
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
|
||||||
|
@ -526,11 +534,7 @@ 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<([] {
|
return kWrapper<(Function<F, bool(Ts)> && ...)>;
|
||||||
if constexpr(std::invocable<F, Ts>) {
|
|
||||||
return std::convertible_to<std::invoke_result_t<F, Ts>, bool>;
|
|
||||||
};
|
|
||||||
}() && ...)>;
|
|
||||||
}))::kValue;
|
}))::kValue;
|
||||||
|
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
|
@ -673,27 +677,9 @@ 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<([] {
|
return kWrapper<(Function<F, std::optional<R>(Ts)> && ...)>;
|
||||||
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;
|
||||||
|
|
||||||
template <typename F, typename R>
|
|
||||||
concept DefaultSwitchConcept = [] {
|
|
||||||
if constexpr(std::invocable<F>) {
|
|
||||||
if constexpr(!std::same_as<R, void>) {
|
|
||||||
return std::convertible_to<std::invoke_result_t<F>, std::optional<R>>;
|
|
||||||
};
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
return false;
|
|
||||||
}();
|
|
||||||
|
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
|
|
||||||
template <typename R = void,
|
template <typename R = void,
|
||||||
|
@ -701,7 +687,7 @@ template <typename R = void,
|
||||||
TupleLike ValuesTuple,
|
TupleLike ValuesTuple,
|
||||||
impl::ComparableSwitchConcept<KeysTuple> Key,
|
impl::ComparableSwitchConcept<KeysTuple> Key,
|
||||||
impl::CallableSwitchConcept<ValuesTuple, R> F,
|
impl::CallableSwitchConcept<ValuesTuple, R> F,
|
||||||
impl::DefaultSwitchConcept<R> Default = decltype(kDefaultCreator<R>)>
|
Function<R()> 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>) && (kTupleSize<KeysTuple> == kTupleSize<ValuesTuple>)
|
requires(std::move_constructible<R> || std::same_as<R, void>) && (kTupleSize<KeysTuple> == kTupleSize<ValuesTuple>)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue