di 0.1.0
Loading...
Searching...
No Matches
vec.h
Go to the documentation of this file.
1#pragma once
2
9#include "di/meta/compare.h"
10#include "di/meta/core.h"
11#include "di/meta/operations.h"
12#include "di/types/integers.h"
14#include "di/util/forward.h"
17
19namespace detail {
20 struct NoopMixin {};
21
22 template<typename T>
23 struct MixinHelper : meta::TypeConstant<NoopMixin> {};
24
25 template<typename T>
26 requires(requires { typename T::Mixin; })
27 struct MixinHelper<T> : meta::TypeConstant<typename T::Mixin> {};
28
29 template<typename T>
30 using Mixin = meta::Type<MixinHelper<T>>;
31
32 template<typename T>
33 concept Tag = requires {
34 typename T::Type;
35 typename Constexpr<T::extent>;
36 } && concepts::SameAs<decltype(T::extent), usize const>;
37
38 template<Tag T>
39 constexpr inline auto extent = T::extent;
40
41 template<typename T>
42 struct SignedTHelper : meta::TypeConstant<meta::MakeSigned<meta::Type<T>>> {};
43
44 template<typename T>
45 requires(requires { typename T::SignedT; })
46 struct SignedTHelper<T> : meta::TypeConstant<typename T::SignedT> {};
47
48 template<Tag T>
49 using SignedT = meta::Type<SignedTHelper<T>>;
50}
51
52template<detail::Tag Tag>
53class Vec
54 : public detail::Mixin<Tag>
55 , public util::AddMemberGet<Vec<Tag>> {
56private:
57 using T = meta::Type<Tag>;
58 using SignedT = detail::SignedT<Tag>;
59 constexpr static auto extent = detail::extent<Tag>;
60
61 using Storage = di::Array<T, extent>;
62
63public:
66 = default;
67
68 template<concepts::ConvertibleTo<T>... Ts>
69 requires(sizeof...(Ts) == extent)
70 constexpr Vec(Ts&&... values) : m_values { T(di::forward<Ts>(values))... } {}
71
72 constexpr auto values() -> Storage& { return m_values; }
73 constexpr auto values() const -> Storage const& { return m_values; }
74
75 constexpr auto begin() { return values().begin(); }
76 constexpr auto begin() const { return values().begin(); }
77
78 constexpr auto end() { return values().end(); }
79 constexpr auto end() const { return values().end(); }
80
81 constexpr auto operator+=(Vec const& other) -> Vec& {
82 for (auto [a, b] : di::zip(*this, other)) {
83 a += b;
84 }
85 return *this;
86 }
87 constexpr auto operator+=(T const& value) -> Vec& {
88 for (auto& x : *this) {
89 x += value;
90 }
91 return *this;
92 }
93 constexpr auto operator+=(SignedT const& value) -> Vec&
94 requires(!di::SameAs<SignedT, T>)
95 {
96 for (auto& x : *this) {
97 x += value;
98 }
99 return *this;
100 }
101
102 constexpr auto operator-=(Vec const& other) -> Vec& {
103 for (auto [a, b] : di::zip(*this, other)) {
104 a -= b;
105 }
106 return *this;
107 }
108 constexpr auto operator-=(T const& value) -> Vec& {
109 for (auto& x : *this) {
110 x -= value;
111 }
112 return *this;
113 }
114 constexpr auto operator-=(SignedT const& value) -> Vec&
115 requires(!di::SameAs<SignedT, T>)
116 {
117 for (auto& x : *this) {
118 x -= value;
119 }
120 return *this;
121 }
122
123 constexpr auto operator*=(T const& value) -> Vec& {
124 for (auto& x : *this) {
125 x *= value;
126 }
127 return *this;
128 }
129
130 constexpr auto operator/=(T const& value) -> Vec& {
131 for (auto& x : *this) {
132 x /= value;
133 }
134 return *this;
135 }
136
137 constexpr friend auto operator==(Vec const& a, Vec const& b) -> bool
139 {
140 return a.values() == b.values();
141 }
142 constexpr friend auto operator<=>(Vec const& a, Vec const& b)
144 {
145 return a.values() <=> b.values();
146 }
147
148private:
149 constexpr friend auto operator+(Vec const& a, Vec const& b) -> Vec
150 requires(concepts::Copyable<T>)
151 {
152 auto result = a;
153 result += b;
154 return result;
155 }
156 constexpr friend auto operator+(Vec const& a, T const& b) -> Vec
157 requires(concepts::Copyable<T>)
158 {
159 auto result = a;
160 result += b;
161 return result;
162 }
163 constexpr friend auto operator+(Vec const& a, SignedT const& b) -> Vec
164 requires(concepts::Copyable<T> && !di::SameAs<T, SignedT>)
165 {
166 auto result = a;
167 result += b;
168 return result;
169 }
170 constexpr friend auto operator+(T const& b, Vec const& a) -> Vec
171 requires(concepts::Copyable<T>)
172 {
173 auto result = a;
174 result += b;
175 return result;
176 }
177 constexpr friend auto operator+(SignedT const& b, Vec const& a) -> Vec
178 requires(concepts::Copyable<T> && !di::SameAs<T, SignedT>)
179 {
180 auto result = a;
181 result += b;
182 return result;
183 }
184
185 constexpr friend auto operator-(Vec const& a, Vec const& b) -> Vec
186 requires(concepts::Copyable<T>)
187 {
188 auto result = a;
189 result -= b;
190 return result;
191 }
192 constexpr friend auto operator-(Vec const& a, T const& b) -> Vec
193 requires(concepts::Copyable<T>)
194 {
195 auto result = a;
196 result -= b;
197 return result;
198 }
199 constexpr friend auto operator-(Vec const& a, SignedT const& b) -> Vec
200 requires(concepts::Copyable<T> && !di::SameAs<T, SignedT>)
201 {
202 auto result = a;
203 result -= b;
204 return result;
205 }
206 constexpr friend auto operator-(T const& b, Vec const& a) -> Vec
207 requires(concepts::Copyable<T>)
208 {
209 auto result = a;
210 result -= b;
211 return result;
212 }
213 constexpr friend auto operator-(SignedT const& b, Vec const& a) -> Vec
214 requires(concepts::Copyable<T> && !di::SameAs<T, SignedT>)
215 {
216 auto result = a;
217 result -= b;
218 return result;
219 }
220
221 constexpr friend auto operator*(Vec const& a, T const& b) -> Vec {
222 auto result = a;
223 a *= b;
224 return a;
225 }
226 constexpr friend auto operator*(T const& b, Vec& a) -> Vec {
227 auto result = a;
228 a *= b;
229 return a;
230 }
231
232 constexpr friend auto operator/(Vec const& a, T const& b) -> Vec {
233 auto result = a;
234 a /= b;
235 return a;
236 }
237 constexpr friend auto operator/(T const& b, Vec& a) -> Vec {
238 auto result = a;
239 a /= b;
240 return a;
241 }
242
243 auto tag_invoke(di::Tag<di::size>, Vec const& self) { return self.values().size(); }
244
245 constexpr friend auto tag_invoke(di::Tag<vocab::tuple_size>, di::InPlaceType<Vec>) { return extent; }
246
247 template<usize index>
248 requires(index < extent)
253
254 template<usize index>
255 requires(index < extent)
260
261 template<concepts::DecaySameAs<Vec> Self, usize index>
262 requires(index < extent)
263 constexpr friend auto tag_invoke(di::Tag<util::get_in_place>, Constexpr<index>, Self&& self) -> decltype(auto) {
264 return di::forward_like<Self>(self.values()[index]);
265 }
266
267 di::Array<T, extent> m_values {};
268};
269}
Definition vec.h:55
constexpr friend auto operator+(Vec const &a, T const &b) -> Vec requires(concepts::Copyable< T >)
Definition vec.h:156
constexpr friend auto operator*(T const &b, Vec &a) -> Vec
Definition vec.h:226
constexpr auto values() const -> Storage const &
Definition vec.h:73
constexpr friend auto operator-(Vec const &a, T const &b) -> Vec requires(concepts::Copyable< T >)
Definition vec.h:192
constexpr auto operator/=(T const &value) -> Vec &
Definition vec.h:130
constexpr auto operator+=(SignedT const &value) -> Vec &requires(!di::SameAs< SignedT, T >)
Definition vec.h:93
constexpr auto operator-=(Vec const &other) -> Vec &
Definition vec.h:102
constexpr friend auto operator+(T const &b, Vec const &a) -> Vec requires(concepts::Copyable< T >)
Definition vec.h:170
constexpr friend auto operator-(SignedT const &b, Vec const &a) -> Vec requires(concepts::Copyable< T > &&!di::SameAs< T, SignedT >)
Definition vec.h:213
constexpr auto operator+=(T const &value) -> Vec &
Definition vec.h:87
constexpr friend auto tag_invoke(di::Tag< vocab::tuple_element >, di::InPlaceType< Vec const >, Constexpr< index >) -> InPlaceType< T const >
Definition vec.h:256
constexpr friend auto operator==(Vec const &a, Vec const &b) -> bool requires(concepts::EqualityComparable< T >)
Definition vec.h:137
constexpr friend auto operator+(SignedT const &b, Vec const &a) -> Vec requires(concepts::Copyable< T > &&!di::SameAs< T, SignedT >)
Definition vec.h:177
constexpr auto begin() const
Definition vec.h:76
constexpr auto operator*=(T const &value) -> Vec &
Definition vec.h:123
constexpr auto operator+=(Vec const &other) -> Vec &
Definition vec.h:81
constexpr auto operator-=(SignedT const &value) -> Vec &requires(!di::SameAs< SignedT, T >)
Definition vec.h:114
constexpr friend auto operator+(Vec const &a, SignedT const &b) -> Vec requires(concepts::Copyable< T > &&!di::SameAs< T, SignedT >)
Definition vec.h:163
constexpr auto begin()
Definition vec.h:75
constexpr auto end()
Definition vec.h:78
constexpr friend auto tag_invoke(di::Tag< util::get_in_place >, Constexpr< index >, Self &&self) -> decltype(auto)
Definition vec.h:263
constexpr friend auto operator-(Vec const &a, SignedT const &b) -> Vec requires(concepts::Copyable< T > &&!di::SameAs< T, SignedT >)
Definition vec.h:199
constexpr friend auto operator*(Vec const &a, T const &b) -> Vec
Definition vec.h:221
constexpr friend auto tag_invoke(di::Tag< vocab::tuple_size >, di::InPlaceType< Vec >)
Definition vec.h:245
constexpr friend auto operator-(T const &b, Vec const &a) -> Vec requires(concepts::Copyable< T >)
Definition vec.h:206
constexpr friend auto operator/(T const &b, Vec &a) -> Vec
Definition vec.h:237
constexpr friend auto operator+(Vec const &a, Vec const &b) -> Vec requires(concepts::Copyable< T >)
Definition vec.h:149
constexpr friend auto tag_invoke(di::Tag< vocab::tuple_element >, di::InPlaceType< Vec >, Constexpr< index >) -> InPlaceType< T >
Definition vec.h:249
constexpr friend auto operator-(Vec const &a, Vec const &b) -> Vec requires(concepts::Copyable< T >)
Definition vec.h:185
constexpr Vec(Ts &&... values)
Definition vec.h:70
constexpr auto values() -> Storage &
Definition vec.h:72
constexpr auto end() const
Definition vec.h:79
constexpr friend auto operator/(Vec const &a, T const &b) -> Vec
Definition vec.h:232
constexpr friend auto operator<=>(Vec const &a, Vec const &b)
Definition vec.h:142
constexpr auto operator-=(T const &value) -> Vec &
Definition vec.h:108
Definition operations.h:40
Definition operations.h:27
Definition compare.h:82
Definition core.h:114
Definition compare.h:91
Definition vec.h:18
T::Type Type
Definition core.h:26
size_t usize
Definition integers.h:33
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
constexpr tag_invoke_detail::TagInvokeFn tag_invoke
Definition tag_invoke.h:22
constexpr auto forward_like(U &&value) -> decltype(auto)
Definition forward_like.h:8
A wrapper for a constexpr value.
Definition constexpr.h:36
Definition core.h:18
Definition in_place_type.h:5
Definition add_member_get.h:10
Definition array.h:27