diff --git a/include/utempl/tuple.hpp b/include/utempl/tuple.hpp index 487adb0..7b819f9 100644 --- a/include/utempl/tuple.hpp +++ b/include/utempl/tuple.hpp @@ -19,14 +19,6 @@ struct TupleHelper; template struct TupleHelper, Ts...> : public TupleLeaf... { - template - inline constexpr TupleHelper(TTs&&... args) : - TupleLeaf{std::forward(args)}... {}; - inline constexpr TupleHelper(const TupleHelper&) = default; - inline constexpr TupleHelper(TupleHelper&) = default; - inline constexpr TupleHelper(TupleHelper&&) = default; - inline constexpr TupleHelper() : - TupleLeaf{}... {}; inline constexpr bool operator==(const TupleHelper&) const = default; }; @@ -48,7 +40,7 @@ inline constexpr auto Get(const Tuple& tuple) -> const auto& requires (I }; template -inline constexpr auto Get(Tuple&& tuple) -> auto&& requires (I < sizeof...(Ts)) { +inline constexpr auto Get(Tuple&& tuple) -> decltype(auto) requires (I < sizeof...(Ts)) { using Type = decltype(Get(TypeList{})); return std::move(static_cast&&>(tuple).value); }; @@ -62,13 +54,19 @@ template struct Tuple : public impl::TupleHelper, Ts...> { template inline constexpr Tuple(TTs&&... args) : - impl::TupleHelper, Ts...>(std::forward(args)...) {}; - inline constexpr Tuple(Ts... args) : - impl::TupleHelper, Ts...>(std::move(args)...) {}; + impl::TupleHelper, Ts...>{{std::forward(args)}...} {}; + inline constexpr Tuple(const Ts&... args) : + impl::TupleHelper, Ts...>{{args}...} {}; + inline constexpr Tuple(Ts&... args) : + impl::TupleHelper, Ts...>{{args}...} {}; + inline constexpr Tuple(Ts&&... args) : + impl::TupleHelper, Ts...>{{std::move(args)}...} {}; + inline constexpr Tuple(const Ts&&... args) : + impl::TupleHelper, 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, Ts...>() {}; template inline constexpr bool operator==(const Tuple& other) const @@ -95,6 +93,18 @@ struct Tuple : public impl::TupleHelper, Ts...> { return Get(*this); }; }; + +template <> +struct Tuple<> { + template + inline constexpr auto operator+(const Tuple& other) const -> Tuple { + return other; + }; + inline constexpr auto operator==(const Tuple<>&) const { + return true; + }; +}; + namespace impl { template diff --git a/include/utempl/utils.hpp b/include/utempl/utils.hpp index 0bfcc66..004d903 100644 --- a/include/utempl/utils.hpp +++ b/include/utempl/utils.hpp @@ -92,13 +92,13 @@ namespace impl { template struct Getter { - friend consteval auto Magic(Getter); + friend consteval bool Magic(Getter); }; template struct Inserter { - friend consteval auto Magic(Getter) {return 42;}; + friend consteval bool Magic(Getter) {return true;}; }; @@ -117,9 +117,15 @@ consteval auto TrueF(auto&&...) { template inline constexpr const SafeTupleChecker kSafeTupleChecker; +template +struct IsSafeTuple { + static constexpr auto value = true; +}; template -concept IsSafeTuple = TrueF(Get<0>(std::move(MakeTuple(0, kSafeTupleChecker)))) && !requires{Magic(Getter{});}; +struct IsSafeTuple(MakeTuple(0, kSafeTupleChecker))) && !Magic(Getter>{})) ? false : false> { + static constexpr bool value = false; +}; } // namespace impl @@ -128,7 +134,7 @@ concept IsSafeTuple = TrueF(Get<0>(std::move(MakeTuple(0, kSafeTupleChecker -concept TupleLike = impl::IsSafeTuple; +concept TupleLike = requires{Get<0>(MakeTuple(42));} && impl::IsSafeTuple::value; template concept IsTypeList = Overloaded(