opynsim
Unofficial C++ Documentation
Loading...
Searching...
No Matches
vector.h
Go to the documentation of this file.
1#pragma once
2
4
5#include <array>
6#include <compare>
7#include <concepts>
8#include <cstddef>
9#include <cstdint>
10#include <format>
11#include <ostream>
12#include <ranges>
13#include <span>
14#include <string_view>
15#include <tuple>
16#include <type_traits>
17
18namespace osc
19{
20 // Implementation details: downstream code shouldn't use this.
21 namespace detail
22 {
23 // Satisfied if `R` has a size/extent greater than or equal to `Max`.
24 template<typename R, size_t N>
26 (
27 requires { std::remove_cvref_t<R>::extent; } and
28 std::remove_cvref_t<R>::extent >= N and
29 std::remove_cvref_t<R>::extent != std::dynamic_extent
30 )
31 or
32 (
33 requires { typename std::tuple_size <std::remove_cvref_t<R>>; } and
34 std::tuple_size<std::remove_cvref_t<R>>::value >= N
35 );
36
37 // Satisfied if `R` has a size/extent equal to `N`.
38 template<typename R, size_t N>
40 (
41 requires { std::remove_cvref_t<R>::extent; } and
42 std::remove_cvref_t<R>::extent == N and
43 std::remove_cvref_t<R>::extent != std::dynamic_extent
44 )
45 or
46 (
47 requires { typename std::tuple_size<std::remove_cvref_t<R>>; } and
48 std::tuple_size<std::remove_cvref_t<R>>::value == N
49 );
50
51 template<typename T, size_t N>
52 requires (N != std::dynamic_extent)
53 constexpr size_t compile_time_size(std::span<T, N>) { return N; }
54
55 // Satisfied if `T` can be written to a `std::ostream`
56 template<typename T>
57 concept OutputStreamable = requires (std::ostream& out, const T& v) { out << v; };
58 }
59
60 // Represents a contiguous range of `N` instances of `T`.
61 template<typename T, size_t N>
62 requires (N > 0)
63 class Vector final {
64 public:
65 using value_type = T;
70 using pointer = T*;
71 using const_pointer = const T*;
72 using iterator = T*;
73 using const_iterator = const T*;
74
75 // Constructs a `Vector` with value-initialized `T`s.
76 constexpr Vector() = default;
77
78 constexpr Vector(const Vector&) = default;
79 constexpr Vector(Vector&&) = default;
80
81 // Constructs a `Vector` with `value` assigned to all elements.
82 explicit constexpr Vector(const T& value) :
83 Vector(value, std::make_index_sequence<N>{})
84 {}
85
86 // Constructs a `Vector` element-by-element.
87 template<typename... Elements>
88 requires (
89 (sizeof...(Elements) == N) and
90 (std::constructible_from<T, Elements> and ...)
91 )
92 explicit (not (std::convertible_to<Elements, T> and ...))
93 constexpr Vector(Elements&&... elements) :
94 data_{static_cast<T>(std::forward<Elements>(elements))...}
95 {}
96
97 // Constructs a `Vector` from the first `N` elements of the given fixed-size contiguous range.
98 template<std::ranges::contiguous_range R>
99 requires (
100 detail::CompileTimeSizeGreaterThanOrEqualTo<R, N> and
101 std::constructible_from<T, typename std::remove_cvref_t<R>::value_type>
102 )
103 explicit (not std::convertible_to<typename std::remove_cvref_t<R>::value_type, T>)
104 constexpr Vector(R&& r) :
105 Vector{std::forward<R>(r), std::make_index_sequence<N>{}}
106 {}
107
108 // Constructs a `Vector` by extending a smaller one.
109 template<typename U, size_t M, typename... Elements>
110 requires (
111 M < N and
112 ((M + sizeof...(Elements)) == N) and
113 std::constructible_from<T, U> and
114 (std::constructible_from<T, Elements> and ...)
115 )
116 constexpr Vector(const Vector<U, M>& v, Elements&&... elements) :
117 Vector{v, std::make_index_sequence<M>{}, std::forward<Elements>(elements)...}
118 {}
119
121
124
125 // Assigns the first `N` elements of a given fixed-size contiguous range to `*this`.
126 template<std::ranges::contiguous_range R>
127 requires (
128 detail::CompileTimeSizeGreaterThanOrEqualTo<R, N> and
130 )
132 {
133 copy_or_move_assign(std::forward<R>(r), std::make_index_sequence<N>{});
134 return *this;
135 }
136
137 // Returns the number of elements in `*this`.
138 constexpr size_type size() const { return N; }
139
140 // Returns a pointer to the underlying array serving as element storage.
141 constexpr pointer data() { return data_.data(); }
142 constexpr const_pointer data() const { return data_.data(); }
143
144 // Returns an iterator to the first element of `*this`.
145 constexpr iterator begin() { return data(); }
146 constexpr const_iterator begin() const { return data(); }
147
148 // Returns an iterator past the last element of `*this`.
149 constexpr iterator end() { return data() + size(); }
150 constexpr const_iterator end() const { return data() + size(); }
151
152 // Returns a reference to the element at specified position `pos`.
153 constexpr reference operator[](size_type pos) { return begin()[pos]; }
154 constexpr const_reference operator[](size_type pos) const { return begin()[pos]; }
155
157 constexpr reference x() requires (N > 0) { return (*this)[0]; }
159 constexpr const_reference x() const requires (N > 0) { return (*this)[0]; }
160
162 constexpr reference y() requires (N > 1) { return (*this)[1]; }
164 constexpr const_reference y() const requires (N > 1) { return (*this)[1]; }
165
167 constexpr reference z() requires (N > 2) { return (*this)[2]; }
169 constexpr const_reference z() const requires (N > 2) { return (*this)[2]; }
170
172 constexpr reference w() requires (N > 3) { return (*this)[3]; }
174 constexpr const_reference w() const requires (N > 3) { return (*this)[3]; }
175
177 constexpr Vector<T, 2> xy() const requires (N > 1) { return {x(), y()}; }
178
180 constexpr Vector<T, 2> xz() const requires (N > 2) { return {x(), z()}; }
181
183 constexpr Vector<T, 2> yx() const requires (N > 1) { return {y(), x()}; }
184
186 constexpr Vector<T, 2> yz() const requires (N > 2) { return {y(), z()}; }
187
189 constexpr Vector<T, 2> zx() const requires (N > 2) { return {z(), x()}; }
190
192 constexpr Vector<T, 2> zy() const requires (N > 2) { return {z(), y()}; }
193
194 friend constexpr bool operator== (const Vector&, const Vector&) = default;
195 friend constexpr auto operator<=>(const Vector&, const Vector&) = default;
196
197 constexpr operator std::span< T, N>() { return {data(), size()}; }
198 constexpr operator std::span<const T, N>() const { return {data(), size()}; }
199
200 // Adds `rhs` to each element of `*this`.
201 template<typename U>
202 requires (requires (T& lhs, const U& rhs) { lhs += rhs; })
203 constexpr Vector& operator+=(const U& rhs)
204 {
205 [&]<size_t... Is>(std::index_sequence<Is...>)
206 {
207 ((data_[Is] += rhs), ...); // fold over +=
208 }(std::make_index_sequence<N>{});
209 return *this;
210 }
211
212 // Adds each element of `rhs` to each element of `*this` pairwise.
213 template<std::ranges::contiguous_range R>
214 requires (
216 requires (T& lhs, const R& rhs) { lhs += rhs[0]; }
217 )
218 constexpr Vector& operator+=(const R& rhs)
219 {
220 [&]<size_t... Is>(std::index_sequence<Is...>)
221 {
222 ((data_[Is] += rhs[Is]), ...); // fold over +=
223 }(std::make_index_sequence<N>{});
224 return *this;
225 }
226
227 // Subtracts `rhs` from each element of `*this`.
228 template<typename U>
229 requires (requires (T& lhs, const U& rhs) { lhs -= rhs; })
230 constexpr Vector& operator-=(const U& rhs)
231 {
232 [&]<size_t... Is>(std::index_sequence<Is...>)
233 {
234 ((data_[Is] -= rhs), ...); // fold over -=
235 }(std::make_index_sequence<N>{});
236 return *this;
237 }
238
239 // Subtracts each element of `rhs` from each element of `*this` pairwise.
240 template<std::ranges::contiguous_range R>
241 requires (
243 requires (T& lhs, const R& rhs) { lhs -= rhs[0]; }
244 )
245 constexpr Vector& operator-=(const R& rhs)
246 {
247 [&]<size_t... Is>(std::index_sequence<Is...>)
248 {
249 ((data_[Is] -= rhs[Is]), ...); // fold over -=
250 }(std::make_index_sequence<N>{});
251 return *this;
252 }
253
254 // Multiplies each element of `*this` by `rhs`.
255 template<typename U>
256 requires (requires (T& lhs, const U& rhs) { lhs *= rhs; })
257 constexpr Vector& operator*=(const U& rhs)
258 {
259 [&]<size_t... Is>(std::index_sequence<Is...>)
260 {
261 ((data_[Is] *= rhs), ...); // fold over *=
262 }(std::make_index_sequence<N>{});
263 return *this;
264 }
265
266 // Multiplies each element of `rhs` with each element of `*this` pairwise.
267 template<std::ranges::contiguous_range R>
268 requires (
270 requires (T& lhs, const R& rhs) { lhs *= rhs[0]; }
271 )
272 constexpr Vector& operator*=(const R& rhs)
273 {
274 [&]<size_t... Is>(std::index_sequence<Is...>)
275 {
276 ((data_[Is] *= rhs[Is]), ...); // fold over *=
277 }(std::make_index_sequence<N>{});
278 return *this;
279 }
280
281 // Divides each element of `*this` by `rhs`.
282 template<typename U>
283 requires (requires (T& lhs, const U& rhs) { lhs /= rhs; })
284 constexpr Vector& operator/=(const U& rhs)
285 {
286 [&]<size_t... Is>(std::index_sequence<Is...>)
287 {
288 ((data_[Is] /= rhs), ...); // fold over /=
289 }(std::make_index_sequence<N>{});
290 return *this;
291 }
292
293 // Divides each element of `rhs` by each element of `*this` pairwise.
294 template<std::ranges::contiguous_range R>
295 requires (
297 requires (T& lhs, const R& rhs) { lhs /= rhs[0]; }
298 )
299 constexpr Vector& operator/=(const R& rhs)
300 {
301 [&]<size_t... Is>(std::index_sequence<Is...>)
302 {
303 ((data_[Is] /= rhs[Is]), ...); // fold over /=
304 }(std::make_index_sequence<N>{});
305 return *this;
306 }
307
308 // Increments each element of `*this` and then returns `*this`.
309 constexpr Vector& operator++()
310 requires (requires(T& t) { ++t; })
311 {
312 [this]<size_t... Is>(std::index_sequence<Is...>)
313 {
314 (++data_[Is], ...); // fold over ++
315 }(std::make_index_sequence<N>{});
316 return *this;
317 }
318
319 // Decrements each element of `*this` and then returns `*this`.
320 constexpr Vector& operator--()
321 requires (requires(T& t) { --t; })
322 {
323 [this]<size_t... Is>(std::index_sequence<Is...>)
324 {
325 (--data_[Is], ...); // fold over --
326 }(std::make_index_sequence<N>{});
327 return *this;
328 }
329
330 // Creates a copy of `*this` increments `*this`, and then returns the copy (postfix).
331 constexpr Vector operator++(int)
332 requires (requires(T& t) { ++t; })
333 {
334 Vector copy{*this};
335 ++(*this);
336 return copy;
337 }
338
339 // Creates a copy of `*this` decrements `*this`, and then returns the copy (postfix).
340 constexpr Vector operator--(int)
341 requires (requires(T& t) { --t; })
342 {
343 Vector copy{*this};
344 --(*this);
345 return copy;
346 }
347
348 // Returns a copy of `*this`, but with `value` used to construct the element at `pos`.
349 template<typename U>
350 requires std::constructible_from<T, U>
351 constexpr Vector with_element(size_type pos, U value) const
352 {
353 Vector copy{*this};
354 copy[pos] = static_cast<T>(value);
355 return copy;
356 }
357
358 private:
359 // Helper constructor that assigns `value` to all elements in `data_`
360 template<size_t... Is>
361 constexpr Vector(const T& value, std::index_sequence<Is...>) :
362 data_{ (static_cast<void>(Is), value)... }
363 {}
364
365 // Helper function that forwards an element in a range.
366 template<class R, class U>
367 static constexpr decltype(auto) forward_range_element(U&& x)
368 {
369 if constexpr (std::is_rvalue_reference_v<R&&>) {
370 return std::move(x);
371 }
372 else {
373 return std::forward<U>(x);
374 }
375 }
376
377 // Helper constructor that perfectly forwards range elements into `data_`
378 template<std::ranges::contiguous_range R, size_t... Is>
379 constexpr Vector(R&& r, std::index_sequence<Is...>) :
380 data_{ static_cast<T>(forward_range_element<R>(r[Is]))... }
381 {}
382
383 // Helper constructor that copies from a smaller `Vector` and extends it with `elements`
384 template<typename U, size_t M, size_t... Is, typename... Elements>
385 constexpr Vector(const Vector<U, M>& v, std::index_sequence<Is...>, Elements&&... elements) :
386 data_{static_cast<T>(v[Is])..., static_cast<T>(std::forward<Elements>(elements))...}
387 {}
388
389 template<std::ranges::contiguous_range R, size_t... Is>
390 constexpr void copy_or_move_assign(R&& r, std::index_sequence<Is...>)
391 {
392 ((data_[Is] = static_cast<T>(forward_range_element<R>(r[Is]))), ...);
393 }
394
395 std::array<T, N> data_{};
396 };
397
398 // Returns a copy of `vec` with each element copied and promoted via unary `+`.
399 template<typename T, size_t N>
400 requires (requires (const Vector<T, N>& v) { +v[0]; })
401 constexpr auto operator+(const Vector<T, N>& vec)
402 {
403 return [&]<size_t... Is>(std::index_sequence<Is...>)
404 {
405 return Vector<std::remove_cvref_t<decltype(+vec[0])>, N>{+vec[Is]...}; // fold over unary `+`
406 }(std::make_index_sequence<N>{});
407 }
408
409 // Returns a copy of `vec` with each element copied and promoted via unary `-`.
410 template<typename T, size_t N>
411 requires (requires (const Vector<T, N>& v) { -v[0]; })
412 constexpr auto operator-(const Vector<T, N>& vec)
413 {
414 return [&]<size_t... Is>(std::index_sequence<Is...>)
415 {
416 return Vector<std::remove_cvref_t<decltype(-vec[0])>, N>{-vec[Is]...}; // fold over unary `-`
417 }(std::make_index_sequence<N>{});
418 }
419
420 // Returns a copy of `vec` with each element copied and logically NOTed (!)
421 template<typename T, size_t N>
422 requires (requires (const Vector<T, N>& v) { !v[0]; })
423 constexpr auto operator!(const Vector<T, N>& vec)
424 {
425 return [&]<size_t... Is>(std::index_sequence<Is...>)
426 {
427 return Vector<std::remove_cvref_t<decltype(!vec[0])>, N>{!vec[Is]...}; // fold over unary `!`
428 }(std::make_index_sequence<N>{});
429 }
430
431 // Returns a copy of `lhs` with `rhs` added to each element.
432 template<typename T, size_t N, typename U>
433 requires (
434 requires (const Vector<T, N>& v, const U& rhs) { v[0] + rhs; }
435 )
436 constexpr auto operator+(const Vector<T, N>& lhs, const U& rhs)
437 {
438 return [&]<size_t... Is>(std::index_sequence<Is...>)
439 {
440 return Vector<std::remove_cvref_t<decltype(lhs[0] + rhs)>, N>{(lhs[Is] + rhs)...};
441 }(std::make_index_sequence<N>{});
442 }
443
444 // Returns a copy of `rhs` with `lhs` added to each element.
445 template<typename T, typename U, size_t N>
446 requires (
447 requires (const T& lhs, const Vector<U, N>& rhs) { lhs + rhs[0]; }
448 )
449 constexpr auto operator+(const T& lhs, const Vector<U, N>& rhs)
450 {
451 return [&]<size_t... Is>(std::index_sequence<Is...>)
452 {
453 return Vector<std::remove_cvref_t<decltype(lhs + rhs[0])>, N>{(lhs + rhs[Is])...};
454 }(std::make_index_sequence<N>{});
455 }
456
457 // Returns a `Vector` containing `lhs[i] + rhs[i]` for each `i` in `[0, N)`.
458 template<typename T, typename U, size_t N>
459 requires (requires (const Vector<T, N>& lhs, const Vector<U, N>& rhs) { lhs[0] + rhs[0]; })
460 constexpr auto operator+(const Vector<T, N>& lhs, const Vector<U, N>& rhs)
461 {
462 return [&]<size_t... Is>(std::index_sequence<Is...>)
463 {
464 return Vector<std::remove_cvref_t<decltype(lhs[0] + rhs[0])>, N>{(lhs[Is] + rhs[Is])...};
465 }(std::make_index_sequence<N>{});
466 }
467
468 // Returns a copy of `lhs` with `rhs` subtracted from each element.
469 template<typename T, size_t N, typename U>
470 requires (requires (const Vector<T, N>& v, const U& rhs) { v[0] - rhs; })
471 constexpr auto operator-(const Vector<T, N>& lhs, const U& rhs)
472 {
473 return [&]<size_t... Is>(std::index_sequence<Is...>)
474 {
475 return Vector<std::remove_cvref_t<decltype(lhs[0] - rhs)>, N>{(lhs[Is] - rhs)...};
476 }(std::make_index_sequence<N>{});
477 }
478
479 // Returns a copy of `rhs` with `lhs` subtracted from each element.
480 template<typename T, typename U, size_t N>
481 requires (requires (const T& lhs, const Vector<U, N>& rhs) { lhs - rhs[0]; })
482 constexpr auto operator-(const T& lhs, const Vector<U, N>& rhs)
483 {
484 return [&]<size_t... Is>(std::index_sequence<Is...>)
485 {
486 return Vector<std::remove_cvref_t<decltype(lhs - rhs[0])>, N>{(lhs - rhs[Is])...};
487 }(std::make_index_sequence<N>{});
488 }
489
490 // Returns a `Vector` containing `lhs[i] - rhs[i]` for each `i` in `[0, N)`.
491 template<typename T, typename U, size_t N>
492 requires (requires (const Vector<T, N>& lhs, const Vector<U, N>& rhs) { lhs[0] - rhs[0]; })
493 constexpr auto operator-(const Vector<T, N>& lhs, const Vector<U, N>& rhs)
494 {
495 return [&]<size_t... Is>(std::index_sequence<Is...>)
496 {
497 return Vector<std::remove_cvref_t<decltype(lhs[0] - rhs[0])>, N>{(lhs[Is] - rhs[Is])...};
498 }(std::make_index_sequence<N>{});
499 }
500
501 // Returns a copy of `lhs` with each element multiplied by `rhs`.
502 template<typename T, size_t N, typename U>
503 requires (requires (const Vector<T, N>& v, const U& rhs) { v[0] * rhs; })
504 constexpr auto operator*(const Vector<T, N>& lhs, const U& rhs)
505 {
506 return [&]<size_t... Is>(std::index_sequence<Is...>)
507 {
508 return Vector<std::remove_cvref_t<decltype(lhs[0] * rhs)>, N>{(lhs[Is] * rhs)...};
509 }(std::make_index_sequence<N>{});
510 }
511
512 // Returns a copy of `rhs` with each element multiplied by `lhs`.
513 template<typename T, typename U, size_t N>
514 requires (requires (const T& lhs, const Vector<U, N>& rhs) { U(lhs * rhs[0]); })
515 constexpr auto operator*(const T& lhs, const Vector<U, N>& rhs)
516 {
517 return [&]<size_t... Is>(std::index_sequence<Is...>)
518 {
519 return Vector<std::remove_cvref_t<decltype(lhs * rhs[0])>, N>{(lhs * rhs[Is])...};
520 }(std::make_index_sequence<N>{});
521 }
522
523 // Returns a `Vector` containing `lhs[i] * rhs[i]` for each `i` in `[0, N)`.
524 template<typename T, typename U, size_t N>
525 requires (requires (const Vector<T, N>& lhs, const Vector<U, N>& rhs) { lhs[0] * rhs[0]; })
526 constexpr auto operator*(const Vector<T, N>& lhs, const Vector<U, N>& rhs)
527 {
528 return [&]<size_t... Is>(std::index_sequence<Is...>)
529 {
530 return Vector<std::remove_cvref_t<decltype(lhs[0] * rhs[0])>, N>{(lhs[Is] * rhs[Is])...};
531 }(std::make_index_sequence<N>{});
532 }
533
534 // Returns a copy of `lhs` with each element divided by `rhs`.
535 template<typename T, size_t N, typename U>
536 requires (requires (const Vector<T, N>& v, const U& rhs) { v[0] / rhs; })
537 constexpr auto operator/(const Vector<T, N>& lhs, const U& rhs)
538 {
539 return [&]<size_t... Is>(std::index_sequence<Is...>)
540 {
541 return Vector<std::remove_cvref_t<decltype(lhs[0] / rhs)>, N>{(lhs[Is] / rhs)...};
542 }(std::make_index_sequence<N>{});
543 }
544
545 // Returns a copy of `rhs` with each element divided by `lhs`.
546 template<typename T, typename U, size_t N>
547 requires (requires (const T& lhs, const Vector<U, N>& rhs) { lhs / rhs[0]; })
548 constexpr auto operator/(const T& lhs, const Vector<U, N>& rhs)
549 {
550 return [&]<size_t... Is>(std::index_sequence<Is...>)
551 {
552 return Vector<std::remove_cvref_t<decltype(lhs / rhs[0])>, N>{(lhs / rhs[Is])...};
553 }(std::make_index_sequence<N>{});
554 }
555
556 // Returns a `Vector` containing `lhs[i] / rhs[i]` for each `i` in `[0, N)`.
557 template<typename T, typename U, size_t N>
558 requires (requires (const Vector<T, N>& lhs, const Vector<U, N>& rhs) { lhs[0] / rhs[0]; })
559 constexpr auto operator/(const Vector<T, N>& lhs, const Vector<U, N>& rhs)
560 {
561 return [&]<size_t... Is>(std::index_sequence<Is...>)
562 {
563 return Vector<std::remove_cvref_t<decltype(lhs[0] / rhs[0])>, N>{(lhs[Is] / rhs[Is])...};
564 }(std::make_index_sequence<N>{});
565 }
566
567 // Formats the vector to the given output stream as `VectorN(el, el, el)`
568 template<detail::OutputStreamable T, size_t N>
569 std::ostream& operator<<(std::ostream& out, const Vector<T, N>& v)
570 {
571 return out << std::format("{}", v);
572 }
573
574 // Returns the `I`th element of `v` (structured binding support)
575 template<size_t I, typename T, size_t N>
576 constexpr const T& get(const Vector<T, N>& v) { return v[I]; }
577
578 // Returns the `I`th element of `v` (structured binding support)
579 template<size_t I, typename T, size_t N>
580 constexpr T& get(Vector<T, N>& v) { return v[I]; }
581
582 // Returns the `I`th element of `v` (structured binding support)
583 template<size_t I, typename T, size_t N>
584 constexpr T&& get(Vector<T, N>&& v) { return std::move(v[I]); }
585
586 // Returns the `I`th element of `v` (structured binding support)
587 template<size_t I, typename T, size_t N>
588 constexpr const T&& get(const Vector<T, N>&& v) { return std::move(v[I]); }
589}
590
591// A `std::formatter` that pretty-prints the `Vector`. The format string applies to
592// each element of the `Vector`.
593template<typename T, size_t N>
594struct std::formatter<osc::Vector<T, N>> {
595 template<class ParseCtx>
596 constexpr typename ParseCtx::iterator parse(ParseCtx& ctx) { return inner_.parse(ctx); }
597
598 template<class FmtCtx>
599 typename FmtCtx::iterator format(const osc::Vector<T, N>& v, FmtCtx& ctx) const
600 {
601 auto it = std::ranges::copy(std::string_view{"Vector("}, ctx.out()).out;
602 std::string_view delimeter;
603 for (const auto& el : v) {
604 it = std::ranges::copy(delimeter, it).out;
605 ctx.advance_to(it);
606 it = inner_.format(el, ctx);
607 delimeter = ", ";
608 }
609 *it++ = ')';
610 return it;
611 }
612private:
613 std::formatter<T> inner_;
614};
615
616// Returns the number of elements in a `Vector` at compile-time (`std::tuple_size_v` and structured binding support)
617template<typename T, size_t N>
618struct std::tuple_size<osc::Vector<T, N>> : std::integral_constant<size_t, N> {};
619
620// Returns the type of the element of a vector (`std::get` and structured binding support)
621template<size_t I, typename T, size_t N>
622requires (I < N)
623struct std::tuple_element<I, osc::Vector<T, N>> { using type = T; };
624
625template<typename T, size_t N>
626struct std::hash<osc::Vector<T, N>> final {
627 size_t operator()(const osc::Vector<T, N>& vec) const noexcept(noexcept(osc::hash_range(vec)))
628 {
629 return osc::hash_range(vec);
630 }
631};
632
633// `Vector` aliases
634namespace osc
635{
643
651
659}
Definition vector.h:63
constexpr reference x()
Returns (*this)[0]
Definition vector.h:157
constexpr reference z()
Returns (*this)[2]
Definition vector.h:167
value_type & reference
Definition vector.h:68
const value_type & const_reference
Definition vector.h:69
constexpr Vector(Vector &&)=default
constexpr reference w()
Returns (*this)[3]
Definition vector.h:172
constexpr Vector & operator--()
Definition vector.h:320
constexpr const_iterator end() const
Definition vector.h:150
constexpr Vector & operator++()
Definition vector.h:309
constexpr const_pointer data() const
Definition vector.h:142
ptrdiff_t difference_type
Definition vector.h:67
constexpr const_iterator begin() const
Definition vector.h:146
constexpr Vector operator++(int)
Definition vector.h:331
constexpr Vector< T, 2 > yx() const
Returns Vector<T, 2>{y(), x()}
Definition vector.h:183
T value_type
Definition vector.h:65
friend constexpr auto operator<=>(const Vector &, const Vector &)=default
constexpr const_reference y() const
Returns (*this)[0]
Definition vector.h:164
constexpr const_reference z() const
Returns (*this)[0]
Definition vector.h:169
constexpr reference y()
Returns (*this)[1]
Definition vector.h:162
constexpr const_reference operator[](size_type pos) const
Definition vector.h:154
constexpr reference operator[](size_type pos)
Definition vector.h:153
constexpr Vector(const Vector< U, M > &v, Elements &&... elements)
Definition vector.h:116
const T * const_pointer
Definition vector.h:71
constexpr pointer data()
Definition vector.h:141
constexpr Vector with_element(size_type pos, U value) const
Definition vector.h:351
T * iterator
Definition vector.h:72
constexpr iterator begin()
Definition vector.h:145
~Vector() noexcept=default
constexpr Vector< T, 2 > yz() const
Returns {y(), z()}
Definition vector.h:186
T * pointer
Definition vector.h:70
not std::convertible_to< typename std::remove_cvref_t< R >::value_type, T > constexpr Vector(R &&r)
Definition vector.h:104
constexpr Vector< T, 2 > zx() const
Returns {z(), x()}
Definition vector.h:189
constexpr Vector()=default
constexpr Vector operator--(int)
Definition vector.h:340
constexpr iterator end()
Definition vector.h:149
constexpr const_reference x() const
Returns (*this)[0]
Definition vector.h:159
constexpr Vector< T, 2 > xz() const
Returns Vector<T, 2>{x(), z()}
Definition vector.h:180
constexpr Vector(const Vector &)=default
size_t size_type
Definition vector.h:66
constexpr const_reference w() const
Returns (*this)[0]
Definition vector.h:174
constexpr Vector< T, 2 > zy() const
Returns {z(), y()}
Definition vector.h:192
constexpr Vector< T, 2 > xy() const
Returns Vector<T, 2>{x(), y()}
Definition vector.h:177
constexpr Vector(const T &value)
Definition vector.h:82
const T * const_iterator
Definition vector.h:73
constexpr size_type size() const
Definition vector.h:138
Definition vector.h:57
constexpr size_t compile_time_size(std::span< T, N >)
Definition vector.h:53
Definition custom_decoration_generator.h:5
bool operator==(const Class &, const Class &)
constexpr const T & get(const Rgb< T > &v)
Definition rgb.h:88
constexpr U to(T &&value)
Definition conversion.h:56
and
Definition algorithms.h:158
size_t hash_range(const Range &range) noexcept(noexcept(hash_combine(0, *std::ranges::begin(range))))
Definition hash_helpers.h:36
FmtCtx::iterator format(const osc::Vector< T, N > &v, FmtCtx &ctx) const
Definition vector.h:599
constexpr ParseCtx::iterator parse(ParseCtx &ctx)
Definition vector.h:596
size_t operator()(const osc::Vector< T, N > &vec) const noexcept(noexcept(osc::hash_range(vec)))
Definition vector.h:627