24#ifndef STELLARLIB_LIN_MATRIX_HPP
25#define STELLARLIB_LIN_MATRIX_HPP
37namespace stellarlib::lin::internal
39template <
typename T, std::
size_t M, std::
size_t N>
40requires (std::is_arithmetic_v<T> &&
static_cast<bool>(M * N))
41class matrix
final : public std::array<T, M * N>
45 constexpr matrix() noexcept = default;
49 explicit constexpr matrix(const U elem) noexcept
50 requires (std::is_convertible_v<U, T> && M == N)
52 for (
const auto i : std::views::iota(std::size_t{}, M * N)) {
53 std::array<T, M * N>::operator[](i) = i % (N + 1) ? 0 : static_cast<T>(elem);
57 template <
typename ...Args>
59 explicit constexpr matrix(Args &&...args)
noexcept
60 requires ((std::is_convertible_v<Args, T> && ...) &&
sizeof...(Args) == M * N)
61 : std::array<T, M * N>{
static_cast<T
>(std::forward<Args>(args))...}
65 explicit constexpr matrix(
const std::array<T, M * N> &elems) noexcept
66 : std::array<T, M * N>{elems}
71 explicit constexpr matrix(
const std::array<U, M * N> &elems)
noexcept
73 for (
const auto [lhs, rhs] : std::views::zip(*
this, elems)) {
79 explicit constexpr matrix(
const matrix<T, N, M> &other)
noexcept
80 requires (M == 1 || N == 1)
81 : std::array<T, M * N>{other}
86 explicit constexpr matrix(
const matrix<U, N, M> &other)
noexcept
87 requires (M == 1 || N == 1)
89 for (
const auto [lhs, rhs] : std::views::zip(*
this, other)) {
95 constexpr matrix(
const matrix &)
noexcept =
default;
98 constexpr matrix(matrix &&) noexcept = default;
100 template <typename Arg>
101 constexpr auto operator=(Arg &&arg) noexcept
104 std::destroy_at(
this);
105 std::construct_at(
this, std::forward<Arg>(arg));
109 constexpr auto operator=(
const matrix &)
noexcept
110 -> matrix & =
default;
112 constexpr auto operator=(matrix &&) noexcept
113 -> matrix & = default;
115 constexpr ~matrix() noexcept = default;
117 template <typename U>
119 explicit constexpr operator U() noexcept
120 requires (std::is_convertible_v<T, U> && M * N == 1)
122 return std::array<T, M * N>::front();
125#define STELLARLIB_LIN_MATRIX_ACCESSOR_SINGLE_IMPL(expr, i)\
127 constexpr auto expr() const noexcept\
133 constexpr auto expr() noexcept\
139#define STELLARLIB_LIN_MATRIX_ACCESSOR_DOUBLE_IMPL(expr1, expr2, i)\
140 STELLARLIB_LIN_MATRIX_ACCESSOR_SINGLE_IMPL(expr1, i);\
141 STELLARLIB_LIN_MATRIX_ACCESSOR_SINGLE_IMPL(expr2, i);
143#define STELLARLIB_LIN_MATRIX_SWIZZLE_SINGLE_IMPL(expr, ...)\
145 constexpr auto expr() const noexcept\
147 return swizzle<__VA_ARGS__>();\
150#define STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(expr1, expr2, ...)\
151 STELLARLIB_LIN_MATRIX_SWIZZLE_SINGLE_IMPL(expr1, __VA_ARGS__);\
152 STELLARLIB_LIN_MATRIX_SWIZZLE_SINGLE_IMPL(expr2, __VA_ARGS__);
154 STELLARLIB_LIN_MATRIX_ACCESSOR_DOUBLE_IMPL(x, r, 0);
155 STELLARLIB_LIN_MATRIX_ACCESSOR_DOUBLE_IMPL(y, g, 1);
156 STELLARLIB_LIN_MATRIX_ACCESSOR_DOUBLE_IMPL(z, b, 2);
157 STELLARLIB_LIN_MATRIX_ACCESSOR_DOUBLE_IMPL(w, a, 3);
160 constexpr auto operator[](
const std::size_t n)
const noexcept
161 requires (M == 1 || N == 1)
163 return std::array<T, M * N>::operator[](n);
167 constexpr auto operator[](
const std::size_t n)
noexcept
169 requires (M == 1 || N == 1)
171 return std::array<T, M * N>::operator[](n);
174 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xx, rr, 0, 0);
175 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xy, rg, 0, 1);
176 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xz, rb, 0, 2);
177 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xw, ra, 0, 3);
178 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yx, gr, 1, 0);
179 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yy, gg, 1, 1);
180 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yz, gb, 1, 2);
181 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yw, ga, 1, 3);
182 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zx, br, 2, 0);
183 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zy, bg, 2, 1);
184 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zz, bb, 2, 2);
185 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zw, ba, 2, 3);
186 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wx, ar, 3, 0);
187 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wy, ag, 3, 1);
188 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wz, ab, 3, 2);
189 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ww, aa, 3, 3);
190 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxx, rrr, 0, 0, 0);
191 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxy, rrg, 0, 0, 1);
192 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxz, rrb, 0, 0, 2);
193 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxw, rra, 0, 0, 3);
194 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xyx, rgr, 0, 1, 0);
195 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xyy, rgg, 0, 1, 1);
196 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xyz, rgb, 0, 1, 2);
197 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xyw, rga, 0, 1, 3);
198 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzx, rbr, 0, 2, 0);
199 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzy, rbg, 0, 2, 1);
200 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzz, rbb, 0, 2, 2);
201 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzw, rba, 0, 2, 3);
202 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwx, rar, 0, 3, 0);
203 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwy, rag, 0, 3, 1);
204 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwz, rab, 0, 3, 2);
205 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xww, raa, 0, 3, 3);
206 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxx, grr, 1, 0, 0);
207 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxy, grg, 1, 0, 1);
208 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxz, grb, 1, 0, 2);
209 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxw, gra, 1, 0, 3);
210 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yyx, ggr, 1, 1, 0);
211 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yyy, ggg, 1, 1, 1);
212 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yyz, ggb, 1, 1, 2);
213 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yyw, gga, 1, 1, 3);
214 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzx, gbr, 1, 2, 0);
215 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzy, gbg, 1, 2, 1);
216 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzz, gbb, 1, 2, 2);
217 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzw, gba, 1, 2, 3);
218 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywx, gar, 1, 3, 0);
219 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywy, gag, 1, 3, 1);
220 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywz, gab, 1, 3, 2);
221 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yww, gaa, 1, 3, 3);
222 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxx, brr, 2, 0, 0);
223 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxy, brg, 2, 0, 1);
224 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxz, brb, 2, 0, 2);
225 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxw, bra, 2, 0, 3);
226 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zyx, bgr, 2, 1, 0);
227 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zyy, bgg, 2, 1, 1);
228 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zyz, bgb, 2, 1, 2);
229 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zyw, bga, 2, 1, 3);
230 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzx, bbr, 2, 2, 0);
231 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzy, bbg, 2, 2, 1);
232 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzz, bbb, 2, 2, 2);
233 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzw, bba, 2, 2, 3);
234 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwx, bar, 2, 3, 0);
235 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwy, bag, 2, 3, 1);
236 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwz, bab, 2, 3, 2);
237 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zww, baa, 2, 3, 3);
238 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxx, arr, 3, 0, 0);
239 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxy, arg, 3, 0, 1);
240 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxz, arb, 3, 0, 2);
241 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxw, ara, 3, 0, 3);
242 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wyx, agr, 3, 1, 0);
243 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wyy, agg, 3, 1, 1);
244 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wyz, agb, 3, 1, 2);
245 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wyw, aga, 3, 1, 3);
246 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzx, abr, 3, 2, 0);
247 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzy, abg, 3, 2, 1);
248 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzz, abb, 3, 2, 2);
249 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzw, aba, 3, 2, 3);
250 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwx, aar, 3, 3, 0);
251 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwy, aag, 3, 3, 1);
252 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwz, aab, 3, 3, 2);
253 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(www, aaa, 3, 3, 3);
254 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxxx, rrrr, 0, 0, 0, 0);
255 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxxy, rrrg, 0, 0, 0, 1);
256 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxxz, rrrb, 0, 0, 0, 2);
257 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxxw, rrra, 0, 0, 0, 3);
258 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxyx, rrgr, 0, 0, 1, 0);
259 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxyy, rrgg, 0, 0, 1, 1);
260 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxyz, rrgb, 0, 0, 1, 2);
261 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxyw, rrga, 0, 0, 1, 3);
262 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxzx, rrbr, 0, 0, 2, 0);
263 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxzy, rrbg, 0, 0, 2, 1);
264 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxzz, rrbb, 0, 0, 2, 2);
265 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxzw, rrba, 0, 0, 2, 3);
266 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxwx, rrar, 0, 0, 3, 0);
267 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxwy, rrag, 0, 0, 3, 1);
268 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxwz, rrab, 0, 0, 3, 2);
269 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xxww, rraa, 0, 0, 3, 3);
270 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xyxx, rgrr, 0, 1, 0, 0);
271 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xyxy, rgrg, 0, 1, 0, 1);
272 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xyxz, rgrb, 0, 1, 0, 2);
273 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xyxw, rgra, 0, 1, 0, 3);
274 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xyyx, rggr, 0, 1, 1, 0);
275 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xyyy, rggg, 0, 1, 1, 1);
276 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xyyz, rggb, 0, 1, 1, 2);
277 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xyyw, rgga, 0, 1, 1, 3);
278 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xyzx, rgbr, 0, 1, 2, 0);
279 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xyzy, rgbg, 0, 1, 2, 1);
280 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xyzz, rgbb, 0, 1, 2, 2);
281 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xyzw, rgba, 0, 1, 2, 3);
282 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xywx, rgar, 0, 1, 3, 0);
283 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xywy, rgag, 0, 1, 3, 1);
284 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xywz, rgab, 0, 1, 3, 2);
285 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xyww, rgaa, 0, 1, 3, 3);
286 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzxx, rbrr, 0, 2, 0, 0);
287 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzxy, rbrg, 0, 2, 0, 1);
288 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzxz, rbrb, 0, 2, 0, 2);
289 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzxw, rbra, 0, 2, 0, 3);
290 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzyx, rbgr, 0, 2, 1, 0);
291 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzyy, rbgg, 0, 2, 1, 1);
292 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzyz, rbgb, 0, 2, 1, 2);
293 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzyw, rbga, 0, 2, 1, 3);
294 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzzx, rbbr, 0, 2, 2, 0);
295 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzzy, rbbg, 0, 2, 2, 1);
296 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzzz, rbbb, 0, 2, 2, 2);
297 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzzw, rbba, 0, 2, 2, 3);
298 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzwx, rbar, 0, 2, 3, 0);
299 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzwy, rbag, 0, 2, 3, 1);
300 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzwz, rbab, 0, 2, 3, 2);
301 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xzww, rbaa, 0, 2, 3, 3);
302 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwxx, rarr, 0, 3, 0, 0);
303 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwxy, rarg, 0, 3, 0, 1);
304 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwxz, rarb, 0, 3, 0, 2);
305 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwxw, rara, 0, 3, 0, 3);
306 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwyx, ragr, 0, 3, 1, 0);
307 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwyy, ragg, 0, 3, 1, 1);
308 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwyz, ragb, 0, 3, 1, 2);
309 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwyw, raga, 0, 3, 1, 3);
310 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwzx, rabr, 0, 3, 2, 0);
311 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwzy, rabg, 0, 3, 2, 1);
312 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwzz, rabb, 0, 3, 2, 2);
313 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwzw, raba, 0, 3, 2, 3);
314 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwwx, raar, 0, 3, 3, 0);
315 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwwy, raag, 0, 3, 3, 1);
316 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwwz, raab, 0, 3, 3, 2);
317 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(xwww, raaa, 0, 3, 3, 3);
318 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxxx, grrr, 1, 0, 0, 0);
319 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxxy, grrg, 1, 0, 0, 1);
320 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxxz, grrb, 1, 0, 0, 2);
321 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxxw, grra, 1, 0, 0, 3);
322 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxyx, grgr, 1, 0, 1, 0);
323 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxyy, grgg, 1, 0, 1, 1);
324 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxyz, grgb, 1, 0, 1, 2);
325 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxyw, grga, 1, 0, 1, 3);
326 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxzx, grbr, 1, 0, 2, 0);
327 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxzy, grbg, 1, 0, 2, 1);
328 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxzz, grbb, 1, 0, 2, 2);
329 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxzw, grba, 1, 0, 2, 3);
330 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxwx, grar, 1, 0, 3, 0);
331 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxwy, grag, 1, 0, 3, 1);
332 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxwz, grab, 1, 0, 3, 2);
333 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yxww, graa, 1, 0, 3, 3);
334 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yyxx, ggrr, 1, 1, 0, 0);
335 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yyxy, ggrg, 1, 1, 0, 1);
336 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yyxz, ggrb, 1, 1, 0, 2);
337 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yyxw, ggra, 1, 1, 0, 3);
338 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yyyx, gggr, 1, 1, 1, 0);
339 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yyyy, gggg, 1, 1, 1, 1);
340 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yyyz, gggb, 1, 1, 1, 2);
341 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yyyw, ggga, 1, 1, 1, 3);
342 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yyzx, ggbr, 1, 1, 2, 0);
343 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yyzy, ggbg, 1, 1, 2, 1);
344 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yyzz, ggbb, 1, 1, 2, 2);
345 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yyzw, ggba, 1, 1, 2, 3);
346 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yywx, ggar, 1, 1, 3, 0);
347 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yywy, ggag, 1, 1, 3, 1);
348 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yywz, ggab, 1, 1, 3, 2);
349 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yyww, ggaa, 1, 1, 3, 3);
350 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzxx, gbrr, 1, 2, 0, 0);
351 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzxy, gbrg, 1, 2, 0, 1);
352 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzxz, gbrb, 1, 2, 0, 2);
353 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzxw, gbra, 1, 2, 0, 3);
354 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzyx, gbgr, 1, 2, 1, 0);
355 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzyy, gbgg, 1, 2, 1, 1);
356 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzyz, gbgb, 1, 2, 1, 2);
357 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzyw, gbga, 1, 2, 1, 3);
358 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzzx, gbbr, 1, 2, 2, 0);
359 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzzy, gbbg, 1, 2, 2, 1);
360 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzzz, gbbb, 1, 2, 2, 2);
361 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzzw, gbba, 1, 2, 2, 3);
362 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzwx, gbar, 1, 2, 3, 0);
363 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzwy, gbag, 1, 2, 3, 1);
364 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzwz, gbab, 1, 2, 3, 2);
365 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(yzww, gbaa, 1, 2, 3, 3);
366 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywxx, garr, 1, 3, 0, 0);
367 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywxy, garg, 1, 3, 0, 1);
368 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywxz, garb, 1, 3, 0, 2);
369 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywxw, gara, 1, 3, 0, 3);
370 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywyx, gagr, 1, 3, 1, 0);
371 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywyy, gagg, 1, 3, 1, 1);
372 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywyz, gagb, 1, 3, 1, 2);
373 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywyw, gaga, 1, 3, 1, 3);
374 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywzx, gabr, 1, 3, 2, 0);
375 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywzy, gabg, 1, 3, 2, 1);
376 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywzz, gabb, 1, 3, 2, 2);
377 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywzw, gaba, 1, 3, 2, 3);
378 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywwx, gaar, 1, 3, 3, 0);
379 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywwy, gaag, 1, 3, 3, 1);
380 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywwz, gaab, 1, 3, 3, 2);
381 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(ywww, gaaa, 1, 3, 3, 3);
382 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxxx, brrr, 2, 0, 0, 0);
383 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxxy, brrg, 2, 0, 0, 1);
384 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxxz, brrb, 2, 0, 0, 2);
385 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxxw, brra, 2, 0, 0, 3);
386 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxyx, brgr, 2, 0, 1, 0);
387 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxyy, brgg, 2, 0, 1, 1);
388 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxyz, brgb, 2, 0, 1, 2);
389 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxyw, brga, 2, 0, 1, 3);
390 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxzx, brbr, 2, 0, 2, 0);
391 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxzy, brbg, 2, 0, 2, 1);
392 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxzz, brbb, 2, 0, 2, 2);
393 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxzw, brba, 2, 0, 2, 3);
394 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxwx, brar, 2, 0, 3, 0);
395 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxwy, brag, 2, 0, 3, 1);
396 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxwz, brab, 2, 0, 3, 2);
397 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zxww, braa, 2, 0, 3, 3);
398 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zyxx, bgrr, 2, 1, 0, 0);
399 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zyxy, bgrg, 2, 1, 0, 1);
400 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zyxz, bgrb, 2, 1, 0, 2);
401 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zyxw, bgra, 2, 1, 0, 3);
402 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zyyx, bggr, 2, 1, 1, 0);
403 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zyyy, bggg, 2, 1, 1, 1);
404 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zyyz, bggb, 2, 1, 1, 2);
405 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zyyw, bgga, 2, 1, 1, 3);
406 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zyzx, bgbr, 2, 1, 2, 0);
407 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zyzy, bgbg, 2, 1, 2, 1);
408 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zyzz, bgbb, 2, 1, 2, 2);
409 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zyzw, bgba, 2, 1, 2, 3);
410 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zywx, bgar, 2, 1, 3, 0);
411 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zywy, bgag, 2, 1, 3, 1);
412 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zywz, bgab, 2, 1, 3, 2);
413 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zyww, bgaa, 2, 1, 3, 3);
414 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzxx, bbrr, 2, 2, 0, 0);
415 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzxy, bbrg, 2, 2, 0, 1);
416 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzxz, bbrb, 2, 2, 0, 2);
417 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzxw, bbra, 2, 2, 0, 3);
418 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzyx, bbgr, 2, 2, 1, 0);
419 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzyy, bbgg, 2, 2, 1, 1);
420 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzyz, bbgb, 2, 2, 1, 2);
421 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzyw, bbga, 2, 2, 1, 3);
422 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzzx, bbbr, 2, 2, 2, 0);
423 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzzy, bbbg, 2, 2, 2, 1);
424 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzzz, bbbb, 2, 2, 2, 2);
425 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzzw, bbba, 2, 2, 2, 3);
426 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzwx, bbar, 2, 2, 3, 0);
427 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzwy, bbag, 2, 2, 3, 1);
428 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzwz, bbab, 2, 2, 3, 2);
429 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zzww, bbaa, 2, 2, 3, 3);
430 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwxx, barr, 2, 3, 0, 0);
431 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwxy, barg, 2, 3, 0, 1);
432 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwxz, barb, 2, 3, 0, 2);
433 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwxw, bara, 2, 3, 0, 3);
434 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwyx, bagr, 2, 3, 1, 0);
435 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwyy, bagg, 2, 3, 1, 1);
436 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwyz, bagb, 2, 3, 1, 2);
437 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwyw, baga, 2, 3, 1, 3);
438 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwzx, babr, 2, 3, 2, 0);
439 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwzy, babg, 2, 3, 2, 1);
440 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwzz, babb, 2, 3, 2, 2);
441 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwzw, baba, 2, 3, 2, 3);
442 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwwx, baar, 2, 3, 3, 0);
443 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwwy, baag, 2, 3, 3, 1);
444 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwwz, baab, 2, 3, 3, 2);
445 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(zwww, baaa, 2, 3, 3, 3);
446 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxxx, arrr, 3, 0, 0, 0);
447 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxxy, arrg, 3, 0, 0, 1);
448 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxxz, arrb, 3, 0, 0, 2);
449 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxxw, arra, 3, 0, 0, 3);
450 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxyx, argr, 3, 0, 1, 0);
451 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxyy, argg, 3, 0, 1, 1);
452 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxyz, argb, 3, 0, 1, 2);
453 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxyw, arga, 3, 0, 1, 3);
454 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxzx, arbr, 3, 0, 2, 0);
455 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxzy, arbg, 3, 0, 2, 1);
456 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxzz, arbb, 3, 0, 2, 2);
457 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxzw, arba, 3, 0, 2, 3);
458 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxwx, arar, 3, 0, 3, 0);
459 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxwy, arag, 3, 0, 3, 1);
460 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxwz, arab, 3, 0, 3, 2);
461 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wxww, araa, 3, 0, 3, 3);
462 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wyxx, agrr, 3, 1, 0, 0);
463 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wyxy, agrg, 3, 1, 0, 1);
464 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wyxz, agrb, 3, 1, 0, 2);
465 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wyxw, agra, 3, 1, 0, 3);
466 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wyyx, aggr, 3, 1, 1, 0);
467 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wyyy, aggg, 3, 1, 1, 1);
468 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wyyz, aggb, 3, 1, 1, 2);
469 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wyyw, agga, 3, 1, 1, 3);
470 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wyzx, agbr, 3, 1, 2, 0);
471 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wyzy, agbg, 3, 1, 2, 1);
472 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wyzz, agbb, 3, 1, 2, 2);
473 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wyzw, agba, 3, 1, 2, 3);
474 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wywx, agar, 3, 1, 3, 0);
475 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wywy, agag, 3, 1, 3, 1);
476 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wywz, agab, 3, 1, 3, 2);
477 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wyww, agaa, 3, 1, 3, 3);
478 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzxx, abrr, 3, 2, 0, 0);
479 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzxy, abrg, 3, 2, 0, 1);
480 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzxz, abrb, 3, 2, 0, 2);
481 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzxw, abra, 3, 2, 0, 3);
482 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzyx, abgr, 3, 2, 1, 0);
483 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzyy, abgg, 3, 2, 1, 1);
484 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzyz, abgb, 3, 2, 1, 2);
485 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzyw, abga, 3, 2, 1, 3);
486 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzzx, abbr, 3, 2, 2, 0);
487 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzzy, abbg, 3, 2, 2, 1);
488 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzzz, abbb, 3, 2, 2, 2);
489 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzzw, abba, 3, 2, 2, 3);
490 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzwx, abar, 3, 2, 3, 0);
491 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzwy, abag, 3, 2, 3, 1);
492 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzwz, abab, 3, 2, 3, 2);
493 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wzww, abaa, 3, 2, 3, 3);
494 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwxx, aarr, 3, 3, 0, 0);
495 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwxy, aarg, 3, 3, 0, 1);
496 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwxz, aarb, 3, 3, 0, 2);
497 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwxw, aara, 3, 3, 0, 3);
498 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwyx, aagr, 3, 3, 1, 0);
499 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwyy, aagg, 3, 3, 1, 1);
500 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwyz, aagb, 3, 3, 1, 2);
501 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwyw, aaga, 3, 3, 1, 3);
502 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwzx, aabr, 3, 3, 2, 0);
503 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwzy, aabg, 3, 3, 2, 1);
504 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwzz, aabb, 3, 3, 2, 2);
505 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwzw, aaba, 3, 3, 2, 3);
506 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwwx, aaar, 3, 3, 3, 0);
507 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwwy, aaag, 3, 3, 3, 1);
508 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwwz, aaab, 3, 3, 3, 2);
509 STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL(wwww, aaaa, 3, 3, 3, 3);
512 constexpr auto operator[](
const std::size_t m)
const noexcept
514 requires (M != 1 && N != 1)
516 using row [[gnu::may_alias]] = matrix<T, 1, N>;
517 return *
reinterpret_cast<const row *
>(std::addressof(std::array<T, M * N>::operator[](m * N)));
521 constexpr auto operator[](
const std::size_t m)
noexcept
523 requires (M != 1 && N != 1)
525 using row [[gnu::may_alias]] = matrix<T, 1, N>;
526 return *
reinterpret_cast<row *
>(std::addressof(std::array<T, M * N>::operator[](m * N)));
530 template <std::
size_t I>
532 constexpr auto elem() const noexcept
533 requires ((M == 1 || N == 1) && I < M * N)
535 return std::array<T, M * N>::operator[](I);
538 template <std::
size_t I>
540 constexpr auto elem() noexcept
542 requires ((M == 1 || N == 1) && I < M * N)
544 return std::array<T, M * N>::operator[](I);
547 template <std::size_t ...I>
549 constexpr auto swizzle() const noexcept
551 return matrix<T, 1,
sizeof...(I)>{elem<I>()...};
555#define STELLARLIB_LIN_MATRIX_PREFIX_POSTFIX_OPERATOR_IMPL(op)\
556template <typename T, std::size_t M, std::size_t N>\
557constexpr auto operator op (matrix<T, M, N> &self) noexcept\
560 for (auto &elem : self) {\
567template <typename T, std::size_t M, std::size_t N>\
568constexpr auto operator op (matrix<T, M, N> &self, int) noexcept\
571 const auto res{self};\
576#define STELLARLIB_LIN_MATRIX_UNARY_OPERATOR_IMPL(op)\
577template <typename T, std::size_t M, std::size_t N>\
579constexpr auto operator op (const matrix<T, M, N> &self) noexcept\
582 matrix<T, M, N> res;\
584 for (const auto [res, elem] : std::views::zip(res, self)) {\
585 res = static_cast<T>(op elem);\
591#define STELLARLIB_LIN_MATRIX_BINARY_OPERATOR_IMPL(op)\
592template <typename T, std::size_t M, std::size_t N, typename U>\
593constexpr auto operator op##= (matrix<T, M, N> &lhs, const U rhs) noexcept\
595 requires (std::is_arithmetic_v<U>)\
597 for (auto &lhs : lhs) {\
604template <typename T, std::size_t M, std::size_t N, typename U>\
606constexpr auto operator op (const matrix<T, M, N> &lhs, const U rhs) noexcept\
607 -> matrix<std::common_type_t<T, U>, M, N>\
608 requires (std::is_arithmetic_v<U>)\
615template <typename T, typename U, std::size_t M, std::size_t N>\
617constexpr auto operator op (const T lhs, const matrix<U, M, N> &rhs) noexcept\
618 -> matrix<std::common_type_t<T, U>, M, N>\
619 requires (std::is_arithmetic_v<T>)\
621 matrix<std::common_type_t<T, U>, M, N> res;\
623 for (const auto [res, rhs] : std::views::zip(res, rhs)) {\
624 res = static_cast<std::common_type_t<T, U>>(lhs op rhs);\
630template <typename T, std::size_t M1, std::size_t N1, typename U, std::size_t M2, std::size_t N2>\
631constexpr auto operator op##= (matrix<T, M1, N1> &lhs, const matrix<U, M2, N2> &rhs) noexcept\
633 requires ((M1 == 1 || N1 == 1) && (M2 == 1 || N2 == 1) && M1 * N1 == M2 * N2 || M1 == M2 && N1 == N2)\
635 for (const auto [lhs, rhs] : std::views::zip(lhs, rhs)) {\
642template <typename T, std::size_t M1, std::size_t N1, typename U, std::size_t M2, std::size_t N2>\
644constexpr auto operator op (const matrix<T, M1, N1> &lhs, const matrix<U, M2, N2> &rhs) noexcept\
645 -> matrix<std::common_type_t<T, U>, M1, N1>\
646 requires ((M1 == 1 || N1 == 1) && (M2 == 1 || N2 == 1) && M1 * N1 == M2 * N2 || M1 == M2 && N1 == N2)\
653#define STELLARLIB_LIN_MATRIX_BOOLEAN_OPERATOR_IMPL(op)\
654template <typename T, std::size_t M, std::size_t N, typename U>\
656constexpr auto operator op (const matrix<T, M, N> &lhs, const U rhs) noexcept\
657 -> matrix<bool, M, N>\
658 requires (std::is_arithmetic_v<U>)\
660 matrix<bool, M, N> res;\
662 for (const auto [res, lhs] : std::views::zip(res, lhs)) {\
669template <typename T, typename U, std::size_t M, std::size_t N>\
671constexpr auto operator op (const T lhs, const matrix<U, M, N> &rhs) noexcept\
672 -> matrix<bool, M, N>\
673 requires (std::is_arithmetic_v<T>)\
675 matrix<bool, M, N> res;\
677 for (const auto [res, rhs] : std::views::zip(res, rhs)) {\
684template <typename T, std::size_t M1, std::size_t N1, typename U, std::size_t M2, std::size_t N2>\
686constexpr auto operator op (const matrix<T, M1, N1> &lhs, const matrix<U, M2, N2> &rhs) noexcept\
687 -> matrix<bool, M1, N1>\
688 requires ((M1 == 1 || N1 == 1) && (M2 == 1 || N2 == 1) && M1 * N1 == M2 * N2 || M1 == M2 && N1 == N2)\
690 matrix<bool, M1, N1> res;\
692 for (const auto [res, lhs, rhs] : std::views::zip(res, lhs, rhs)) {\
699STELLARLIB_LIN_MATRIX_PREFIX_POSTFIX_OPERATOR_IMPL(++);
700STELLARLIB_LIN_MATRIX_PREFIX_POSTFIX_OPERATOR_IMPL(--);
702template <
typename T, std::
size_t M, std::
size_t N>
704constexpr auto operator+(
const matrix<T, M, N> &self)
noexcept
709STELLARLIB_LIN_MATRIX_UNARY_OPERATOR_IMPL(-);
710STELLARLIB_LIN_MATRIX_UNARY_OPERATOR_IMPL(!);
711STELLARLIB_LIN_MATRIX_UNARY_OPERATOR_IMPL(~);
712STELLARLIB_LIN_MATRIX_BINARY_OPERATOR_IMPL(*);
713STELLARLIB_LIN_MATRIX_BINARY_OPERATOR_IMPL(/);
714STELLARLIB_LIN_MATRIX_BINARY_OPERATOR_IMPL(%);
715STELLARLIB_LIN_MATRIX_BINARY_OPERATOR_IMPL(+);
716STELLARLIB_LIN_MATRIX_BINARY_OPERATOR_IMPL(-);
717STELLARLIB_LIN_MATRIX_BINARY_OPERATOR_IMPL(<<);
718STELLARLIB_LIN_MATRIX_BINARY_OPERATOR_IMPL(>>);
719STELLARLIB_LIN_MATRIX_BOOLEAN_OPERATOR_IMPL(<);
720STELLARLIB_LIN_MATRIX_BOOLEAN_OPERATOR_IMPL(<=);
721STELLARLIB_LIN_MATRIX_BOOLEAN_OPERATOR_IMPL(>);
722STELLARLIB_LIN_MATRIX_BOOLEAN_OPERATOR_IMPL(>=);
723STELLARLIB_LIN_MATRIX_BOOLEAN_OPERATOR_IMPL(==);
724STELLARLIB_LIN_MATRIX_BOOLEAN_OPERATOR_IMPL(!=);
725STELLARLIB_LIN_MATRIX_BINARY_OPERATOR_IMPL(&);
726STELLARLIB_LIN_MATRIX_BINARY_OPERATOR_IMPL(^);
727STELLARLIB_LIN_MATRIX_BINARY_OPERATOR_IMPL(|);
728STELLARLIB_LIN_MATRIX_BOOLEAN_OPERATOR_IMPL(&&);
729STELLARLIB_LIN_MATRIX_BOOLEAN_OPERATOR_IMPL(||);
731template <
typename T, std::
size_t M, std::
size_t N>
732constexpr auto operator<<(std::ostream &os,
const matrix<T, M, N> &self)
734 requires (M == 1 || N == 1)
736 os <<
'[' << self.front();
738 for (
const auto elem : std::ranges::subrange{self.begin() + 1, self.end()}) {
746template <
typename T, std::
size_t M, std::
size_t N>
747constexpr auto operator<<(std::ostream &os,
const matrix<T, M, N> &self)
750 os <<
'[' << self[0];
752 for (
const auto m : std::views::iota(std::size_t{1}, M)) {
753 os <<
", " << self[m];
761template <
typename T, std::
size_t M, std::
size_t N>
762struct std::formatter<stellarlib::lin::internal::matrix<T, M, N>> final
765 constexpr auto parse(
const std::format_parse_context &ctx)
const noexcept
771 constexpr auto format(
const stellarlib::lin::internal::matrix<T, M, N> &matrix, std::format_context &ctx)
const
773 std::ostringstream out{};
775 return std::format_to(ctx.out(),
"{}", out.view());
779#undef STELLARLIB_LIN_MATRIX_BOOLEAN_OPERATOR_IMPL
780#undef STELLARLIB_LIN_MATRIX_BINARY_OPERATOR_IMPL
781#undef STELLARLIB_LIN_MATRIX_UNARY_OPERATOR_IMPL
782#undef STELLARLIB_LIN_MATRIX_PREFIX_POSTFIX_OPERATOR_IMPL
783#undef STELLARLIB_LIN_MATRIX_SWIZZLE_DOUBLE_IMPL
784#undef STELLARLIB_LIN_MATRIX_SWIZZLE_SINGLE_IMPL
785#undef STELLARLIB_LIN_MATRIX_ACCESSOR_DOUBLE_IMPL
786#undef STELLARLIB_LIN_MATRIX_ACCESSOR_SINGLE_IMPL
internal::matrix< T, M, N > matrix
Generic M*N matrix with per-component operations.
Definition lin.hpp:48