di 0.1.0
Loading...
Searching...
No Matches
tuple.h
Go to the documentation of this file.
1#pragma once
2
5#include "di/meta/algorithm.h"
6#include "di/meta/common.h"
7#include "di/meta/compare.h"
8#include "di/meta/constexpr.h"
9#include "di/meta/core.h"
10#include "di/meta/language.h"
11#include "di/meta/list.h"
12#include "di/meta/operations.h"
13#include "di/meta/util.h"
17#include "di/util/swap.h"
22
23namespace di::vocab {
24template<typename... Types>
25class Tuple
26 : public TupleImpl<meta::IndexSequenceFor<Types...>, Types...>
27 , public util::AddMemberGet<Tuple<Types...>> {
28private:
29 using Base = TupleImpl<meta::IndexSequenceFor<Types...>, Types...>;
30
31public:
32 constexpr Tuple()
34 = default;
35
36 constexpr Tuple(Tuple const&) = default;
37 constexpr Tuple(Tuple&&) = default;
38
39 constexpr Tuple(Types const&... args)
40 requires(sizeof...(Types) > 0 && (concepts::CopyConstructible<Types> && ...))
41 : Base(construct_tuple_impl_valuewise, args...) {}
42
43 template<typename... Args>
44 requires(sizeof...(Types) == sizeof...(Args) && sizeof...(Types) > 0 &&
46 constexpr Tuple(Args&&... args) : Base(construct_tuple_impl_valuewise, util::forward<Args>(args)...) {}
47
48 template<typename Tup>
51 constexpr Tuple(Tup&& value) : Base(construct_tuple_impl_from_tuplelike, util::forward<Tup>(value)) {}
52
53 constexpr ~Tuple() = default;
54
55 constexpr auto operator=(Tuple const& other) -> Tuple&
56 requires(concepts::CopyAssignable<Types> && ...)
57 {
58 Base::static_assign(util::forward_as_base<Tuple&, Base>(*this), other);
59 return *this;
60 }
61
62 constexpr auto operator=(Tuple const& other) const -> Tuple const&
64 {
65 Base::static_assign(util::forward_as_base<Tuple const&, Base>(*this), other);
66 return *this;
67 }
68
69 constexpr auto operator=(Tuple&& other) -> Tuple&
70 requires(concepts::MoveAssignable<Types> && ...)
71 {
72 Base::static_assign(util::forward_as_base<Tuple&, Base>(*this), util::move(other));
73 return *this;
74 }
75
76 constexpr auto operator=(Tuple&& other) const -> Tuple const&
78 {
79 Base::static_assign(util::forward_as_base<Tuple const&, Base>(*this), util::move(other));
80 return *this;
81 }
82
83 template<concepts::TupleLike Tup>
85 requires(Base& self, Tup&& other) { Base::static_assign(self, util::forward<Tup>(other)); })
86 constexpr auto operator=(Tup&& other) -> Tuple& {
87 Base::static_assign(util::forward_as_base<Tuple&, Base>(*this), util::forward<Tup>(other));
88 return *this;
89 }
90
91 template<concepts::TupleLike Tup>
93 requires(Base const& self, Tup&& other) { Base::static_assign(self, util::forward<Tup>(other)); })
94 constexpr auto operator=(Tup&& other) const -> Tuple const& {
95 Base::static_assign(util::forward_as_base<Tuple const&, Base>(*this), util::forward<Tup>(other));
96 return *this;
97 }
98
99private:
100 template<typename... Other>
101 requires(sizeof...(Types) == sizeof...(Other) &&
102 requires { requires(concepts::EqualityComparableWith<Types, Other> && ...); })
103 constexpr friend auto operator==(Tuple const& a, Tuple<Other...> const& b) -> bool {
104 return function::unpack<meta::MakeIndexSequence<sizeof...(Types)>>(
105 [&]<size_t... indices>(meta::ListV<indices...>) {
106 return ((util::get<indices>(a) == util::get<indices>(b)) && ...);
107 });
108 }
109
110 template<typename... Other>
111 requires(sizeof...(Types) == sizeof...(Other) &&
112 requires { requires(concepts::ThreeWayComparableWith<Types, Other> && ...); })
113 constexpr friend auto operator<=>(Tuple const& a, Tuple<Other...> const& b)
115 if constexpr (sizeof...(Types) == 0) {
116 return di::strong_ordering::equal;
117 } else {
118 auto process = function::ycombinator([&]<size_t index>(auto& self, Constexpr<index>) {
119 if (auto result = util::get<index>(a) <=> util::get<index>(b); result != 0) {
120 return result;
121 }
122 if constexpr (index == sizeof...(Types) - 1) {
123 return di::strong_ordering::equal;
124 } else {
125 return self(c_<index + 1>);
126 }
127 });
128 return process(c_<0ZU>);
129 }
130 }
131
132 template<concepts::DerivedFrom<Tuple> Self = Tuple>
134 return sizeof...(Types);
135 }
136
137 using TypeList = meta::List<Types...>;
138
139 template<types::size_t index, concepts::DerivedFrom<Tuple> Self = Tuple>
144
145 template<types::size_t index, concepts::DerivedFrom<Tuple> Self = Tuple>
150
151 template<types::size_t index, typename Self>
152 requires(index < sizeof...(Types) && concepts::DerivedFrom<meta::Decay<Self>, Tuple>)
153 constexpr friend auto tag_invoke(types::Tag<util::get_in_place>, Constexpr<index>, Self&& self)
155 using Impl = detail::TupleImplBase<index, meta::IndexSequenceFor<Types...>, Types...>::Type;
157 Impl::static_get(util::forward_as_base<Self, Impl>(self)));
158 }
159
160 template<typename T, typename Self = Tuple>
162 constexpr friend auto tag_invoke(types::Tag<util::get_in_place>, InPlaceType<T>, Self&& self)
164 constexpr auto index = meta::Lookup<T, meta::List<Types...>>;
165 using Impl = detail::TupleImplBase<index, meta::IndexSequenceFor<Types...>, Types...>::Type;
167 Impl::static_get(util::forward_as_base<Self, Impl>(self)));
168 }
169};
170
171template<typename... Types>
172Tuple(Types...) -> Tuple<Types...>;
173}
174
175namespace di {
176namespace detail {
177 template<typename...>
178 constexpr inline bool has_common_type_helper = false;
179
180 template<typename T, concepts::CommonWith<T> U>
181 constexpr inline bool has_common_type_helper<T, U> = true;
182
183 struct HasCommonType {
184 template<typename... Types>
185 using Invoke = Constexpr<has_common_type_helper<Types...>>;
186 };
187
188 template<typename...>
189 constexpr inline bool has_common_reference_helper = false;
190
191 template<typename T, concepts::CommonWith<T> U>
192 constexpr inline bool has_common_reference_helper<T, U> = true;
193
194 struct HasCommonReference {
195 template<typename... Types>
196 using Invoke = Constexpr<has_common_reference_helper<Types...>>;
197 };
198}
199
200template<concepts::TupleLike A, concepts::TupleLike B>
208
209template<concepts::TupleLike A, concepts::TupleLike B, template<typename> typename AQual,
210 template<typename> typename BQual>
221}
constexpr Tuple()=default
Definition tuple.h:27
constexpr friend auto tag_invoke(types::Tag< util::get_in_place >, Constexpr< index >, Self &&self) -> meta::Like< Self, meta::TupleElement< Self, index > > &&
Definition tuple.h:153
constexpr Tuple(Tuple &&)=default
constexpr auto operator=(Tuple const &other) -> Tuple &requires(concepts::CopyAssignable< Types > &&...)
Definition tuple.h:55
constexpr auto operator=(Tuple &&other) -> Tuple &requires(concepts::MoveAssignable< Types > &&...)
Definition tuple.h:69
constexpr friend auto tag_invoke(types::Tag< tuple_size >, types::InPlaceType< Self >) -> types::size_t
Definition tuple.h:133
constexpr ~Tuple()=default
constexpr Tuple(Types const &... args)
Definition tuple.h:39
constexpr Tuple(Tup &&value)
Definition tuple.h:51
constexpr friend auto tag_invoke(types::Tag< tuple_element >, types::InPlaceType< Self const >, Constexpr< index >) -> InPlaceType< meta::At< TypeList, index > const >
Definition tuple.h:146
constexpr friend auto operator<=>(Tuple const &a, Tuple< Other... > const &b) -> meta::CommonComparisonCategory< meta::CompareThreeWayResult< Types, Other >... >
Definition tuple.h:113
constexpr auto operator=(Tuple &&other) const -> Tuple const &requires(concepts::AssignableFrom< Types const &, Types > &&...)
Definition tuple.h:76
constexpr Tuple()=default
constexpr friend auto tag_invoke(types::Tag< tuple_element >, types::InPlaceType< Self >, Constexpr< index >) -> InPlaceType< meta::At< TypeList, index > >
Definition tuple.h:140
constexpr Tuple(Tuple const &)=default
constexpr auto operator=(Tuple const &other) const -> Tuple const &requires(concepts::CopyAssignable< Types const > &&...)
Definition tuple.h:62
constexpr friend auto tag_invoke(types::Tag< util::get_in_place >, InPlaceType< T >, Self &&self) -> meta::Like< Self, T > &&
Definition tuple.h:162
Definition operations.h:19
Definition operations.h:11
Definition operations.h:37
Definition operations.h:34
Definition util.h:59
Definition operations.h:24
Definition operations.h:114
Definition core.h:139
Definition operations.h:46
Definition list.h:124
constexpr auto unpack
Definition unpack.h:24
constexpr auto ycombinator
Definition ycombinator.h:63
constexpr bool All
Definition algorithm.h:20
constexpr auto TupleSize
Definition tuple_size.h:23
Type< detail::LikeHelper< T, U > > Like
Definition language.h:468
meta::Transform< meta::AsList< meta::MakeIndexSequence< meta::TupleSize< Tup > > >, detail::GetElement< Tup > > TupleElements
Definition tuple_elements.h:23
MakeIntegerSequence< usize, count > MakeIndexSequence
Definition algorithm.h:333
Type< detail::CommonComparisonCategoryHelper< Types... > > CommonComparisonCategory
Definition compare.h:31
AsTemplate< vocab::Tuple, T > AsTuple
Definition algorithm.h:63
detail::TransformHelper< List, Function >::Type Transform
Definition algorithm.h:186
MakeIndexSequence< sizeof...(Types)> IndexSequenceFor
Definition algorithm.h:339
std::size_t size_t
Definition size_t.h:12
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
Definition vocab.h:96
constexpr auto get(T &&value) -> decltype(auto)
Definition get.h:8
constexpr auto forward_as_base(meta::RemoveReference< Derived > &derived) -> meta::Like< meta::RemoveReference< Derived > &, Base > &&
Definition forward_as_base.h:12
Definition lazy.h:165
constexpr auto construct_tuple_impl_from_tuplelike
Definition tuple_impl.h:21
Tuple(Types...) -> Tuple< Types... >
constexpr auto construct_tuple_impl_valuewise
Definition tuple_impl.h:17
Definition any_storable.h:9
constexpr auto c_
A value of type Constexpr<val>.
Definition constexpr.h:252
A wrapper for a constexpr value.
Definition constexpr.h:36
meta::AsTuple< meta::Transform< meta::Zip< meta::Transform< meta::TupleElements< A >, meta::Quote< AQual > >, meta::Transform< meta::TupleElements< B >, meta::Quote< BQual > > >, meta::Uncurry< meta::Quote< meta::CommonReference > > > > Type
Definition tuple.h:217
Definition common.h:65
meta::AsTuple< meta::Transform< meta::Zip< meta::TupleElements< A >, meta::TupleElements< B > >, meta::Uncurry< meta::Quote< meta::CommonType > > > > Type
Definition tuple.h:205
Definition common.h:13
Definition core.h:8
Definition core.h:5
Definition function.h:30
Definition function.h:58
Definition in_place_type.h:5
Definition add_member_get.h:10
constexpr bool has_common_reference_helper
Definition tuple.h:189
constexpr bool has_common_type_helper
Definition tuple.h:178