Add safe check to tuple
This commit is contained in:
parent
a3f060b5c3
commit
609835991a
1 changed files with 51 additions and 16 deletions
|
@ -75,17 +75,8 @@ template <template <typename, std::size_t> typename Array, typename T, std::size
|
||||||
inline constexpr std::size_t kTupleSize<Array<T, N>> = N;
|
inline constexpr std::size_t kTupleSize<Array<T, N>> = N;
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
concept TupleLike = kTupleSize<T> == 0 || requires(T t){Get<0>(t);};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T = Tuple<>, typename... Args>
|
||||||
concept IsTypeList = Overloaded(
|
|
||||||
[]<typename... Ts>(TypeList<TypeList<Ts...>>) {return true;},
|
|
||||||
[](auto&&) {return false;}
|
|
||||||
)(kType<std::remove_cvref_t<T>>);
|
|
||||||
|
|
||||||
|
|
||||||
template <TupleLike T = Tuple<>, typename... Args>
|
|
||||||
inline constexpr auto MakeTuple(Args&&... args) {
|
inline constexpr auto MakeTuple(Args&&... args) {
|
||||||
return Overloaded(
|
return Overloaded(
|
||||||
[&]<template <typename...> typename M, typename... Ts>(TypeList<M<Ts...>>){
|
[&]<template <typename...> typename M, typename... Ts>(TypeList<M<Ts...>>){
|
||||||
|
@ -97,6 +88,55 @@ inline constexpr auto MakeTuple(Args&&... args) {
|
||||||
)(kType<std::remove_cvref_t<T>>);
|
)(kType<std::remove_cvref_t<T>>);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace impl {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Getter {
|
||||||
|
friend consteval auto Magic(Getter<T>);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Inserter {
|
||||||
|
friend consteval auto Magic(Getter<T>) {return 42;};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct SafeTupleChecker {
|
||||||
|
consteval SafeTupleChecker(SafeTupleChecker&&) {
|
||||||
|
std::ignore = Inserter<SafeTupleChecker<T>>{};
|
||||||
|
};
|
||||||
|
consteval SafeTupleChecker(const SafeTupleChecker&) = default;
|
||||||
|
consteval SafeTupleChecker() = default;
|
||||||
|
};
|
||||||
|
consteval auto TrueF(auto&&...) {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline constexpr const SafeTupleChecker<T> kSafeTupleChecker;
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept IsSafeTuple = TrueF(Get<0>(std::move(MakeTuple<T>(0, kSafeTupleChecker<T>)))) && !requires{Magic(Getter<T>{});};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace impl
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept TupleLike = impl::IsSafeTuple<T>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept IsTypeList = Overloaded(
|
||||||
|
[]<typename... Ts>(TypeList<TypeList<Ts...>>) {return true;},
|
||||||
|
[](auto&&) {return false;}
|
||||||
|
)(kType<std::remove_cvref_t<T>>);
|
||||||
|
|
||||||
|
|
||||||
template <TupleLike Tuple>
|
template <TupleLike Tuple>
|
||||||
inline constexpr auto Transform(Tuple&& container, auto&& f) {
|
inline constexpr auto Transform(Tuple&& container, auto&& f) {
|
||||||
return [&]<auto... Is>(std::index_sequence<Is...>){
|
return [&]<auto... Is>(std::index_sequence<Is...>){
|
||||||
|
@ -225,12 +265,7 @@ template <typename F, typename... Ts>
|
||||||
struct Curryer {
|
struct Curryer {
|
||||||
F f;
|
F f;
|
||||||
Tuple<Ts...> data;
|
Tuple<Ts...> data;
|
||||||
inline constexpr operator decltype(f(std::declval<Ts>()...))() && {
|
inline constexpr operator std::invoke_result_t<F, Ts...>() const {
|
||||||
return [&]<auto... Is>(std::index_sequence<Is...>){
|
|
||||||
return this->f(std::move(Get<Is>(this->data))...);
|
|
||||||
}(std::index_sequence_for<Ts...>());
|
|
||||||
};
|
|
||||||
inline constexpr operator decltype(f(std::declval<Ts>()...))() const {
|
|
||||||
return [&]<auto... Is>(std::index_sequence<Is...>){
|
return [&]<auto... Is>(std::index_sequence<Is...>){
|
||||||
return this->f(Get<Is>(this->data)...);
|
return this->f(Get<Is>(this->data)...);
|
||||||
}(std::index_sequence_for<Ts...>());
|
}(std::index_sequence_for<Ts...>());
|
||||||
|
|
Loading…
Reference in a new issue