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>
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;
};
@ -48,7 +40,7 @@ inline constexpr auto Get(const Tuple<Ts...>& tuple) -> const auto& requires (I
};
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...>{}));
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...> {
template <typename... TTs>
inline constexpr Tuple(TTs&&... args) :
impl::TupleHelper<std::index_sequence_for<Ts...>, Ts...>(std::forward<TTs>(args)...) {};
inline constexpr Tuple(Ts... args) :
impl::TupleHelper<std::index_sequence_for<Ts...>, Ts...>(std::move(args)...) {};
impl::TupleHelper<std::index_sequence_for<Ts...>, Ts...>{{std::forward<TTs>(args)}...} {};
inline constexpr Tuple(const Ts&... 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(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...>() {};
template <typename... TTs>
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);
};
};
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 {
template <typename T>

View file

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