Iros
 
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& requires(concepts::CopyAssignable<Types>&&...) {
56 Base::static_assign(util::forward_as_base<Tuple&, Base>(*this), other);
57 return *this;
58 }
59
60 constexpr auto operator=(Tuple const& other) const -> Tuple const&
62 {
63 Base::static_assign(util::forward_as_base<Tuple const&, Base>(*this), other);
64 return *this;
65 }
66
67 constexpr auto operator=(Tuple&& other) -> Tuple& requires(concepts::MoveAssignable<Types>&&...) {
68 Base::static_assign(util::forward_as_base<Tuple&, Base>(*this), util::move(other));
69 return *this;
70 }
71
72 constexpr auto operator=(Tuple&& other) const -> Tuple const&
74 {
75 Base::static_assign(util::forward_as_base<Tuple const&, Base>(*this), util::move(other));
76 return *this;
77 }
78
79 template<concepts::TupleLike Tup>
81 requires(Base& self, Tup&& other) { Base::static_assign(self, util::forward<Tup>(other)); })
82 constexpr auto operator=(Tup&& other) -> Tuple& {
83 Base::static_assign(util::forward_as_base<Tuple&, Base>(*this), util::forward<Tup>(other));
84 return *this;
85 }
86
87 template<concepts::TupleLike Tup>
89 requires(Base const& self, Tup&& other) { Base::static_assign(self, util::forward<Tup>(other)); })
90 constexpr auto operator=(Tup&& other) const -> Tuple const& {
91 Base::static_assign(util::forward_as_base<Tuple const&, Base>(*this), util::forward<Tup>(other));
92 return *this;
93 }
94
95private:
96 template<typename... Other>
97 requires(sizeof...(Types) == sizeof...(Other) &&
98 requires { requires(concepts::EqualityComparableWith<Types, Other> && ...); })
99 constexpr friend auto operator==(Tuple const& a, Tuple<Other...> const& b) -> bool {
100 return function::unpack<meta::MakeIndexSequence<sizeof...(Types)>>(
101 [&]<size_t... indices>(meta::ListV<indices...>) {
102 return ((util::get<indices>(a) == util::get<indices>(b)) && ...);
103 });
104 }
105
106 template<typename... Other>
107 requires(sizeof...(Types) == sizeof...(Other) &&
108 requires { requires(concepts::ThreeWayComparableWith<Types, Other> && ...); })
109 constexpr friend auto operator<=>(Tuple const& a, Tuple<Other...> const& b)
111 if constexpr (sizeof...(Types) == 0) {
112 return di::strong_ordering::equal;
113 } else {
114 auto process = function::ycombinator([&]<size_t index>(auto& self, Constexpr<index>) {
115 if (auto result = util::get<index>(a) <=> util::get<index>(b); result != 0) {
116 return result;
117 }
118 if constexpr (index == sizeof...(Types) - 1) {
119 return di::strong_ordering::equal;
120 } else {
121 return self(c_<index + 1>);
122 }
123 });
124 return process(c_<0ZU>);
125 }
126 }
127
128 template<concepts::DerivedFrom<Tuple> Self = Tuple>
130 return sizeof...(Types);
131 }
132
133 using TypeList = meta::List<Types...>;
134
135 template<types::size_t index, concepts::DerivedFrom<Tuple> Self = Tuple>
140
141 template<types::size_t index, concepts::DerivedFrom<Tuple> Self = Tuple>
146
147 template<types::size_t index, typename Self>
148 requires(index < sizeof...(Types) && concepts::DerivedFrom<meta::Decay<Self>, Tuple>)
149 constexpr friend auto tag_invoke(types::Tag<util::get_in_place>, Constexpr<index>, Self&& self)
151 using Impl = detail::TupleImplBase<index, meta::IndexSequenceFor<Types...>, Types...>::Type;
153 Impl::static_get(util::forward_as_base<Self, Impl>(self)));
154 }
155
156 template<typename T, typename Self = Tuple>
158 constexpr friend auto tag_invoke(types::Tag<util::get_in_place>, InPlaceType<T>, Self&& self)
160 constexpr auto index = meta::Lookup<T, meta::List<Types...>>;
161 using Impl = detail::TupleImplBase<index, meta::IndexSequenceFor<Types...>, Types...>::Type;
163 Impl::static_get(util::forward_as_base<Self, Impl>(self)));
164 }
165};
166
167template<typename... Types>
168Tuple(Types...) -> Tuple<Types...>;
169}
170
171namespace di {
172namespace detail {
173 template<typename...>
174 constexpr inline bool has_common_type_helper = false;
175
176 template<typename T, concepts::CommonWith<T> U>
177 constexpr inline bool has_common_type_helper<T, U> = true;
178
180 template<typename... Types>
182 };
183
184 template<typename...>
185 constexpr inline bool has_common_reference_helper = false;
186
187 template<typename T, concepts::CommonWith<T> U>
188 constexpr inline bool has_common_reference_helper<T, U> = true;
189
191 template<typename... Types>
193 };
194}
195
196template<concepts::TupleLike A, concepts::TupleLike B>
204
205template<concepts::TupleLike A, concepts::TupleLike B, template<typename> typename AQual,
206 template<typename> typename BQual>
217}
Definition tuple_impl.h:24
Definition tuple_forward_declaration.h:5
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:149
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:67
constexpr friend auto tag_invoke(types::Tag< tuple_size >, types::InPlaceType< Self >) -> types::size_t
Definition tuple.h:129
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:142
constexpr friend auto operator<=>(Tuple const &a, Tuple< Other... > const &b) -> meta::CommonComparisonCategory< meta::CompareThreeWayResult< Types, Other >... >
Definition tuple.h:109
constexpr auto operator=(Tuple &&other) const -> Tuple const &requires(concepts::AssignableFrom< Types const &, Types > &&...)
Definition tuple.h:72
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:136
constexpr Tuple(Tuple const &)=default
constexpr auto operator=(Tuple const &other) const -> Tuple const &requires(concepts::CopyAssignable< Types const > &&...)
Definition tuple.h:60
constexpr friend auto tag_invoke(types::Tag< util::get_in_place >, InPlaceType< T >, Self &&self) -> meta::Like< Self, T > &&
Definition tuple.h:158
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:116
constexpr auto unpack
Definition unpack.h:24
constexpr auto ycombinator
Definition ycombinator.h:63
Definition json_deserializer.h:532
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:285
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:288
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 zstring_parser.h:9
constexpr auto c_
A value of type Constexpr<val>.
Definition constexpr.h:252
Definition tuple.h:190
Constexpr< has_common_reference_helper< Types... > > Invoke
Definition tuple.h:192
Definition tuple.h:179
Constexpr< has_common_type_helper< Types... > > Invoke
Definition tuple.h:181
A wrapper for a constexpr value.
Definition core.h:77
Definition common.h:65
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:213
Definition common.h:13
meta::AsTuple< meta::Transform< meta::Zip< meta::TupleElements< A >, meta::TupleElements< B > >, meta::Uncurry< meta::Quote< meta::CommonType > > > > Type
Definition tuple.h:201
Definition core.h:8
Definition core.h:5
Definition function.h:30
Definition function.h:58
Definition in_place_type.h:5
Definition tuple_impl.h:28
constexpr bool has_common_reference_helper
Definition tuple.h:185
constexpr bool has_common_type_helper
Definition tuple.h:174