Fix Safe Check and tuple
This commit is contained in:
parent
d3602dc2dd
commit
5a1fced36d
2 changed files with 33 additions and 17 deletions
|
@ -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>
|
||||||
|
|
|
@ -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(
|
||||||
|
|
Loading…
Reference in a new issue