Fix Safe Check and tuple

This commit is contained in:
sha512sum 2024-03-01 00:24:13 +00:00
parent d3602dc2dd
commit 5a1fced36d
2 changed files with 33 additions and 17 deletions

View file

@ -19,14 +19,6 @@ struct TupleHelper;
template <std::size_t... Is, typename... Ts> template <std::size_t... Is, typename... Ts>
struct TupleHelper<std::index_sequence<Is...>, Ts...> : public TupleLeaf<Is, Ts>... { struct TupleHelper<std::index_sequence<Is...>, Ts...> : public TupleLeaf<Is, Ts>... {
template <typename... TTs>
inline constexpr TupleHelper(TTs&&... args) :
TupleLeaf<Is, Ts>{std::forward<TTs>(args)}... {};
inline constexpr TupleHelper(const TupleHelper&) = default;
inline constexpr TupleHelper(TupleHelper&) = default;
inline constexpr TupleHelper(TupleHelper&&) = default;
inline constexpr TupleHelper() :
TupleLeaf<Is, Ts>{}... {};
inline constexpr bool operator==(const TupleHelper&) const = default; inline constexpr bool operator==(const TupleHelper&) const = default;
}; };
@ -48,7 +40,7 @@ inline constexpr auto Get(const Tuple<Ts...>& tuple) -> const auto& requires (I
}; };
template <std::size_t I, typename... Ts> template <std::size_t I, typename... Ts>
inline constexpr auto Get(Tuple<Ts...>&& tuple) -> auto&& requires (I < sizeof...(Ts)) { inline constexpr auto Get(Tuple<Ts...>&& tuple) -> decltype(auto) requires (I < sizeof...(Ts)) {
using Type = decltype(Get<I>(TypeList<Ts...>{})); using Type = decltype(Get<I>(TypeList<Ts...>{}));
return std::move(static_cast<impl::TupleLeaf<I, Type>&&>(tuple).value); return std::move(static_cast<impl::TupleLeaf<I, Type>&&>(tuple).value);
}; };
@ -62,13 +54,19 @@ template <typename... Ts>
struct Tuple : public impl::TupleHelper<std::index_sequence_for<Ts...>, Ts...> { struct Tuple : public impl::TupleHelper<std::index_sequence_for<Ts...>, Ts...> {
template <typename... TTs> template <typename... TTs>
inline constexpr Tuple(TTs&&... args) : inline constexpr Tuple(TTs&&... args) :
impl::TupleHelper<std::index_sequence_for<Ts...>, Ts...>(std::forward<TTs>(args)...) {}; impl::TupleHelper<std::index_sequence_for<Ts...>, Ts...>{{std::forward<TTs>(args)}...} {};
inline constexpr Tuple(Ts... args) : inline constexpr Tuple(const Ts&... args) :
impl::TupleHelper<std::index_sequence_for<Ts...>, Ts...>(std::move(args)...) {}; impl::TupleHelper<std::index_sequence_for<Ts...>, Ts...>{{args}...} {};
inline constexpr Tuple(Ts&... args) :
impl::TupleHelper<std::index_sequence_for<Ts...>, Ts...>{{args}...} {};
inline constexpr Tuple(Ts&&... args) :
impl::TupleHelper<std::index_sequence_for<Ts...>, Ts...>{{std::move(args)}...} {};
inline constexpr Tuple(const Ts&&... args) :
impl::TupleHelper<std::index_sequence_for<Ts...>, Ts...>{{args}...} {};
inline constexpr Tuple(const Tuple&) = default; inline constexpr Tuple(const Tuple&) = default;
inline constexpr Tuple(Tuple&&) = default; inline constexpr Tuple(Tuple&&) = default;
inline constexpr Tuple(Tuple&) = default; inline constexpr Tuple(Tuple&) = default;
inline constexpr Tuple() requires (sizeof...(Ts) != 0) : inline constexpr Tuple() :
impl::TupleHelper<std::index_sequence_for<Ts...>, Ts...>() {}; impl::TupleHelper<std::index_sequence_for<Ts...>, Ts...>() {};
template <typename... TTs> template <typename... TTs>
inline constexpr bool operator==(const Tuple<TTs...>& other) const inline constexpr bool operator==(const Tuple<TTs...>& other) const
@ -95,6 +93,18 @@ struct Tuple : public impl::TupleHelper<std::index_sequence_for<Ts...>, Ts...> {
return Get<I>(*this); return Get<I>(*this);
}; };
}; };
template <>
struct Tuple<> {
template <typename... Ts>
inline constexpr auto operator+(const Tuple<Ts...>& other) const -> Tuple<Ts...> {
return other;
};
inline constexpr auto operator==(const Tuple<>&) const {
return true;
};
};
namespace impl { namespace impl {
template <typename T> template <typename T>

View file

@ -92,13 +92,13 @@ namespace impl {
template <typename T> template <typename T>
struct Getter { struct Getter {
friend consteval auto Magic(Getter<T>); friend consteval bool Magic(Getter<T>);
}; };
template <typename T> template <typename T>
struct Inserter { struct Inserter {
friend consteval auto Magic(Getter<T>) {return 42;}; friend consteval bool Magic(Getter<T>) {return true;};
}; };
@ -117,9 +117,15 @@ consteval auto TrueF(auto&&...) {
template <typename T> template <typename T>
inline constexpr const SafeTupleChecker<T> kSafeTupleChecker; inline constexpr const SafeTupleChecker<T> kSafeTupleChecker;
template <typename T, bool = false>
struct IsSafeTuple {
static constexpr auto value = true;
};
template <typename T> template <typename T>
concept IsSafeTuple = TrueF(Get<0>(std::move(MakeTuple<T>(0, kSafeTupleChecker<T>)))) && !requires{Magic(Getter<T>{});}; struct IsSafeTuple<T, bool(TrueF(Get<0>(MakeTuple<T>(0, kSafeTupleChecker<T>))) && !Magic(Getter<SafeTupleChecker<T>>{})) ? false : false> {
static constexpr bool value = false;
};
} // namespace impl } // namespace impl
@ -128,7 +134,7 @@ concept IsSafeTuple = TrueF(Get<0>(std::move(MakeTuple<T>(0, kSafeTupleChecker<T
template <typename T> template <typename T>
concept TupleLike = impl::IsSafeTuple<T>; concept TupleLike = requires{Get<0>(MakeTuple<T>(42));} && impl::IsSafeTuple<T>::value;
template <typename T> template <typename T>
concept IsTypeList = Overloaded( concept IsTypeList = Overloaded(