Gamedev Framework (gf) 1.2.0
A C++17 framework for 2D games
Vector.h
1/*
2 * Gamedev Framework (gf)
3 * Copyright (C) 2016-2022 Julien Bernard
4 *
5 * This software is provided 'as-is', without any express or implied
6 * warranty. In no event will the authors be held liable for any damages
7 * arising from the use of this software.
8 *
9 * Permission is granted to anyone to use this software for any purpose,
10 * including commercial applications, and to alter it and redistribute it
11 * freely, subject to the following restrictions:
12 *
13 * 1. The origin of this software must not be misrepresented; you must not
14 * claim that you wrote the original software. If you use this software
15 * in a product, an acknowledgment in the product documentation would be
16 * appreciated but is not required.
17 * 2. Altered source versions must be plainly marked as such, and must not be
18 * misrepresented as being the original software.
19 * 3. This notice may not be removed or altered from any source distribution.
20 */
21#ifndef GF_VECTOR_H
22#define GF_VECTOR_H
23
24#include <cstddef>
25#include <cstdint>
26
27#include <algorithm>
28#include <initializer_list>
29#include <type_traits>
30
31#include "CoreApi.h"
32#include "Types.h"
33
34namespace gf {
35#ifndef DOXYGEN_SHOULD_SKIP_THIS
36inline namespace v1 {
37#endif
38
60 template<typename T, std::size_t N>
61 struct Vector {
62 #ifndef DOXYGEN_SHOULD_SKIP_THIS
63 static_assert(N > 0, "N must be strictly positive");
64 #endif
65
72 Vector() = default;
73
77 constexpr Vector(ZeroType) noexcept
78 {
79 zero();
80 }
81
95 explicit Vector(T val) noexcept
96 {
97 std::fill_n(data, N, val);
98 }
99
113 explicit Vector(const T *array)
114 {
115 std::copy_n(array, N, data);
116 }
117
131 Vector(std::initializer_list<T> list) noexcept
132 {
133 std::copy_n(list.begin(), std::min(list.size(), N), data);
134 }
135
144 Vector(const Vector& other) = default;
145
146
152 template<typename U>
153 Vector(const Vector<U, N>& other) noexcept
154 {
155 static_assert(std::is_convertible<U,T>::value, "Non-convertible types");
156 std::transform(data, data + N, other.data, [](U val) { return static_cast<T>(val); });
157 }
158
165 Vector& operator=(const Vector& other) = default;
166
178 constexpr T operator[](std::size_t i) const {
179 return data[i];
180 }
181
193 constexpr T& operator[](std::size_t i) {
194 return data[i];
195 }
196
197
203 T *begin() {
204 return &data[0];
205 }
206
212 T *end() {
213 return &data[N];
214 }
215
221 const T *begin() const {
222 return &data[0];
223 }
224
231 const T *end() const {
232 return &data[N];
233 }
234
240 const T *cbegin() const {
241 return &data[0];
242 }
243
250 const T *cend() const {
251 return &data[N];
252 }
253
257 constexpr void zero() noexcept {
258 for (std::size_t i = 0; i < N; ++i) {
259 data[i] = T{};
260 }
261 }
262
270 T data[N];
271 };
272
315 template <typename T>
316 struct Vector<T, 2> {
323 Vector() = default;
324
328 constexpr Vector(ZeroType) noexcept
329 : x(T(0))
330 , y(T(0))
331 {
332 }
333
347 explicit constexpr Vector(T val) noexcept
348 : x(val)
349 , y(val)
350 {
351 }
352
366 explicit constexpr Vector(const T *array)
367 : x(array[0])
368 , y(array[1])
369 {
370 }
371
378 constexpr Vector(T first, T second) noexcept
379 : x(first)
380 , y(second)
381 {
382 }
383
392 Vector(const Vector& other) = default;
393
399 template<typename U>
400 Vector(const Vector<U, 2>& other) noexcept
401 : x(static_cast<T>(other.x))
402 , y(static_cast<T>(other.y))
403 {
404 static_assert(std::is_convertible<U,T>::value, "Non-convertible types");
405 }
406
413 Vector& operator=(const Vector& other) = default;
414
426 constexpr T operator[](std::size_t i) const {
427 const T *data[] = { &x, &y };
428 return *data[i];
429 }
430
442 constexpr T& operator[](std::size_t i) {
443 T *data[] = { &x, &y };
444 return *data[i];
445 }
446
447
453 T *begin() {
454 return &x;
455 }
456
462 T *end() {
463 return &x + 2;
464 }
465
471 const T *begin() const {
472 return &x;
473 }
474
481 const T *end() const {
482 return &x + 2;
483 }
489 const T *cbegin() const {
490 return &x;
491 }
492
499 const T *cend() const {
500 return &x + 2;
501 }
502
506 constexpr void zero() noexcept {
507 x = y = T{};
508 }
509
513 union {
514 T x;
515 T u;
516 T s;
519 };
520
524 union {
525 T y;
526 T v;
527 T t;
530 };
531 };
532
569 template <typename T>
570 struct Vector<T, 3> {
577 Vector() = default;
578
582 constexpr Vector(ZeroType) noexcept
583 {
584 zero();
585 }
586
600 explicit constexpr Vector(T val) noexcept
601 : x(val)
602 , y(val)
603 , z(val)
604 {
605 }
606
620 explicit constexpr Vector(const T *array)
621 : x(array[0])
622 , y(array[1])
623 , z(array[2])
624 {
625 }
626
634 constexpr Vector(T first, T second, T third) noexcept
635 : x(first)
636 , y(second)
637 , z(third)
638 {
639 }
640
647 constexpr Vector(Vector<T, 2> xy, T third)
648 : x(xy.x)
649 , y(xy.y)
650 , z(third)
651 {
652 }
653
662 Vector(const Vector& other) = default;
663
669 template<typename U>
670 Vector(const Vector<U, 3>& other) noexcept
671 : x(static_cast<T>(other.x))
672 , y(static_cast<T>(other.y))
673 , z(static_cast<T>(other.z))
674 {
675 static_assert(std::is_convertible<U,T>::value, "Non-convertible types");
676 }
677
684 Vector& operator=(const Vector& other) = default;
685
697 constexpr T operator[](std::size_t i) const {
698 const T *data[] = { &x, &y, &z };
699 return *data[i];
700 }
701
713 constexpr T& operator[](std::size_t i) {
714 T *data[] = { &x, &y, &z };
715 return *data[i];
716 }
717
718
724 T *begin() {
725 return &x;
726 }
727
733 T *end() {
734 return &x + 3;
735 }
736
742 const T *begin() const {
743 return &x;
744 }
745
752 const T *end() const {
753 return &x + 3;
754 }
755
761 const T *cbegin() const {
762 return &x;
763 }
764
771 const T *cend() const {
772 return &x + 3;
773 }
774
778 constexpr void zero() noexcept {
779 x = y = z = T{};
780 }
781
785 constexpr Vector<T, 2> xy() const {
786 return { x, y };
787 }
788
789
793 union {
794 T x;
795 T r;
796 };
797
801 union {
802 T y;
803 T g;
804 };
805
809 union {
810 T z;
811 T b;
812 };
813 };
814
851 template <typename T>
852 struct Vector<T, 4> {
859 Vector() = default;
860
864 constexpr Vector(ZeroType) noexcept
865 {
866 zero();
867 }
868
882 explicit constexpr Vector(T val) noexcept
883 : x(val)
884 , y(val)
885 , z(val)
886 , w(val)
887 {
888 }
889
903 explicit constexpr Vector(const T *array)
904 : x(array[0])
905 , y(array[1])
906 , z(array[2])
907 , w(array[3])
908 {
909 }
910
919 constexpr Vector(T first, T second, T third, T fourth) noexcept
920 : x(first)
921 , y(second)
922 , z(third)
923 , w(fourth)
924 {
925 }
926
935 Vector(const Vector& other) = default;
936
942 template<typename U>
943 Vector(const Vector<U, 4>& other) noexcept
944 : x(static_cast<T>(other.x))
945 , y(static_cast<T>(other.y))
946 , z(static_cast<T>(other.z))
947 , w(static_cast<T>(other.w))
948 {
949 static_assert(std::is_convertible<U,T>::value, "Non-convertible types");
950 }
951
958 Vector& operator=(const Vector& other) = default;
959
971 constexpr T operator[](std::size_t i) const {
972 const T *data[] = { &x, &y, &z, &w };
973 return *data[i];
974 }
975
987 constexpr T& operator[](std::size_t i) {
988 T *data[] = { &x, &y, &z, &w };
989 return *data[i];
990 }
991
992
998 T *begin() {
999 return &x;
1000 }
1001
1007 T *end() {
1008 return &x + 4;
1009 }
1010
1016 const T *begin() const {
1017 return &x;
1018 }
1019
1026 const T *end() const {
1027 return &x + 4;
1028 }
1029
1035 const T *cbegin() const {
1036 return &x;
1037 }
1038
1045 const T *cend() const {
1046 return &x + 4;
1047 }
1048
1052 constexpr void zero() noexcept {
1053 x = y = z = w = T{};
1054 }
1055
1059 constexpr Vector<T, 2> xy() const {
1060 return { x, y };
1061 }
1062
1066 constexpr Vector<T, 3> xyz() const {
1067 return { x, y, z };
1068 }
1069
1073 constexpr Vector<T, 3> rgb() const {
1074 return { r, g, b };
1075 }
1076
1077
1081 union {
1084 };
1085
1089 union {
1092 };
1093
1097 union {
1100 };
1101
1105 union {
1108 };
1109 };
1110
1118
1126
1134
1142
1150
1158
1166
1174
1182
1190
1198
1206
1214
1222
1230
1238
1246
1254
1261 template<typename T>
1263
1270 template<typename T>
1272
1280
1288
1296
1304
1312
1320
1321
1322
1323// MSVC does not like extern template
1324#ifndef _MSC_VER
1325 extern template struct GF_CORE_API Vector<float, 2>;
1326 extern template struct GF_CORE_API Vector<float, 3>;
1327 extern template struct GF_CORE_API Vector<float, 4>;
1328
1329 extern template struct GF_CORE_API Vector<double, 2>;
1330 extern template struct GF_CORE_API Vector<double, 3>;
1331 extern template struct GF_CORE_API Vector<double, 4>;
1332
1333 extern template struct GF_CORE_API Vector<int, 2>;
1334 extern template struct GF_CORE_API Vector<int, 3>;
1335 extern template struct GF_CORE_API Vector<int, 4>;
1336
1337 extern template struct GF_CORE_API Vector<unsigned, 2>;
1338 extern template struct GF_CORE_API Vector<unsigned, 3>;
1339 extern template struct GF_CORE_API Vector<unsigned, 4>;
1340
1341 extern template struct GF_CORE_API Vector<bool, 2>;
1342 extern template struct GF_CORE_API Vector<bool, 3>;
1343 extern template struct GF_CORE_API Vector<bool, 4>;
1344
1345 extern template struct GF_CORE_API Vector<uint8_t, 3>;
1346 extern template struct GF_CORE_API Vector<uint8_t, 4>;
1347#endif
1348
1366 template<typename T, std::size_t N>
1368
1375 template<typename T>
1377
1384 template<typename T>
1386
1387
1392 template<typename T, std::size_t N>
1393 inline
1394 void swap(Vector<T,N>& lhs, Vector<T,N>& rhs) noexcept {
1395 std::swap_ranges(lhs.begin(), lhs.end(), rhs.begin());
1396 }
1397
1405 template<typename ... Types>
1406 constexpr
1407 auto vec(Types... values) -> Vector<std::common_type_t<Types...>, sizeof...(Types)> {
1408 static_assert(sizeof...(Types) > 0, "Vectors must have at least one coordinate");
1409 return { static_cast<std::common_type_t<Types...>>(values)... };
1410 }
1411
1412#ifndef DOXYGEN_SHOULD_SKIP_THIS
1413}
1414#endif
1415}
1416
1417#endif // GAME_VECTOR_H
constexpr Vector2f transform(const Matrix3f &mat, Vector2f point)
Apply an affine transformation to a 2D point.
Definition: Transform.h:326
Distance< T, 2 > Distance2
A distance function for 2D vectors.
Definition: Vector.h:1376
Distance< T, 3 > Distance3
A distance function for 3D vectors.
Definition: Vector.h:1385
T(*)(Vector< T, N >, Vector< T, N >) Distance
A distance function.
Definition: Vector.h:1367
The namespace for gf classes.
A 2D vector.
Definition: Vector.h:316
const T * cbegin() const
Iterator.on the first element (const version).
Definition: Vector.h:489
constexpr T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:426
T * end()
Iterator to the element after the last one.
Definition: Vector.h:462
T row
Second coordinate in the indices representation.
Definition: Vector.h:529
Vector()=default
Default constructor.
T * begin()
Iterator.to the first element.
Definition: Vector.h:453
T height
Second coordinate in the size representation.
Definition: Vector.h:528
constexpr Vector(const T *array)
Constructor that takes an array.
Definition: Vector.h:366
T s
First coordinate in the (s,t) representation.
Definition: Vector.h:516
const T * begin() const
Iterator.to the first element (const version).
Definition: Vector.h:471
T v
Second coordinate in the (u,v) representation.
Definition: Vector.h:526
constexpr Vector(T val) noexcept
Constructor that fills the vector with a value.
Definition: Vector.h:347
T width
First coordinate in the size representation.
Definition: Vector.h:517
const T * end() const
Iterator on the element after the last one (const version).
Definition: Vector.h:481
constexpr Vector(ZeroType) noexcept
Constructor that zero the vector out.
Definition: Vector.h:328
constexpr Vector(T first, T second) noexcept
Constructor that takes 2 components.
Definition: Vector.h:378
const T * cend() const
Iterator on the element after the last one (const version).
Definition: Vector.h:499
T t
Second coordinate in the (s,t) representation.
Definition: Vector.h:527
T y
Second coordinate in the (x,y) representation.
Definition: Vector.h:525
Vector & operator=(const Vector &other)=default
Default copy assignment.
Vector(const Vector< U, 2 > &other) noexcept
Converting copy constructor.
Definition: Vector.h:400
constexpr T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:442
constexpr void zero() noexcept
Zero out the vector.
Definition: Vector.h:506
T col
First coordinate in the indices representation.
Definition: Vector.h:518
Vector(const Vector &other)=default
Default copy constructor.
T x
First coordinate in the (x,y) representation.
Definition: Vector.h:514
T u
First coordinate in the (u,v) representation.
Definition: Vector.h:515
A 3D vector.
Definition: Vector.h:570
const T * cbegin() const
Iterator.on the first element (const version).
Definition: Vector.h:761
T b
Third coordinate in the (r,g,b) representation.
Definition: Vector.h:811
constexpr Vector(const T *array)
Constructor that takes an array.
Definition: Vector.h:620
const T * cend() const
Iterator on the element after the last one (const version).
Definition: Vector.h:771
constexpr T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:713
constexpr Vector< T, 2 > xy() const
Swizzle to get the first two coordinates as a 2D vector.
Definition: Vector.h:785
const T * begin() const
Iterator.to the first element (const version).
Definition: Vector.h:742
T x
First coordinate in the (x,y,z) representation.
Definition: Vector.h:794
Vector & operator=(const Vector &other)=default
Default copy assignment.
T * end()
Iterator to the element after the last one.
Definition: Vector.h:733
Vector(const Vector &other)=default
Default copy constructor.
const T * end() const
Iterator on the element after the last one (const version).
Definition: Vector.h:752
T r
First coordinate in the (r,g,b) representation.
Definition: Vector.h:795
constexpr void zero() noexcept
Zero out the vector.
Definition: Vector.h:778
Vector()=default
Default constructor.
T * begin()
Iterator.to the first element.
Definition: Vector.h:724
T z
Third coordinate in the (x,y,z) representation.
Definition: Vector.h:810
Vector(const Vector< U, 3 > &other) noexcept
Converting copy constructor.
Definition: Vector.h:670
constexpr Vector(ZeroType) noexcept
Constructor that zero the vector out.
Definition: Vector.h:582
constexpr Vector(Vector< T, 2 > xy, T third)
Constructor that takes a 2D vector and a z component.
Definition: Vector.h:647
constexpr Vector(T val) noexcept
Constructor that fills the vector with a value.
Definition: Vector.h:600
T y
Second coordinate in the (x,y,z) representation.
Definition: Vector.h:802
constexpr T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:697
constexpr Vector(T first, T second, T third) noexcept
Constructor that takes 3 components.
Definition: Vector.h:634
T g
Second coordinate in the (r,g,b) representation.
Definition: Vector.h:803
A 4D vector.
Definition: Vector.h:852
constexpr Vector(const T *array)
Constructor that takes an array.
Definition: Vector.h:903
constexpr Vector(T first, T second, T third, T fourth) noexcept
Constructor that takes 4 components.
Definition: Vector.h:919
Vector(const Vector &other)=default
Default copy constructor.
Vector(const Vector< U, 4 > &other) noexcept
Converting copy constructor.
Definition: Vector.h:943
T z
Third coordinate in the (x,y,z,w) representation.
Definition: Vector.h:1098
Vector()=default
Default constructor.
const T * cbegin() const
Iterator.on the first element (const version).
Definition: Vector.h:1035
T w
Fourth coordinate in the (x,y,z,w) representation.
Definition: Vector.h:1106
T b
Third coordinate in the (r,g,b,a) representation.
Definition: Vector.h:1099
T y
Second coordinate in the (x,y,z,w) representation.
Definition: Vector.h:1090
constexpr Vector(ZeroType) noexcept
Constructor that zero the vector out.
Definition: Vector.h:864
T a
Fourth coordinate in the (r,g,b,a) representation.
Definition: Vector.h:1107
constexpr Vector(T val) noexcept
Constructor that fills the vector with a value.
Definition: Vector.h:882
constexpr Vector< T, 2 > xy() const
Swizzle to get the first two coordinates as a 2D vector.
Definition: Vector.h:1059
T x
First coordinate in the (x,y,z,w) representation.
Definition: Vector.h:1082
const T * begin() const
Iterator.to the first element (const version).
Definition: Vector.h:1016
T * begin()
Iterator.to the first element.
Definition: Vector.h:998
constexpr T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:987
T * end()
Iterator to the element after the last one.
Definition: Vector.h:1007
const T * cend() const
Iterator on the element after the last one (const version).
Definition: Vector.h:1045
constexpr Vector< T, 3 > xyz() const
Swizzle to get the first three coordinates as a 3D vector.
Definition: Vector.h:1066
constexpr void zero() noexcept
Zero out the vector.
Definition: Vector.h:1052
const T * end() const
Iterator on the element after the last one (const version).
Definition: Vector.h:1026
Vector & operator=(const Vector &other)=default
Default copy assignment.
T g
Second coordinate in the (r,g,b,a) representation.
Definition: Vector.h:1091
constexpr Vector< T, 3 > rgb() const
Swizzle to get the first three coordinates as a RGB color.
Definition: Vector.h:1073
T r
First coordinate in the (r,g,b,a) representation.
Definition: Vector.h:1083
constexpr T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:971
General purpose math vector.
Definition: Vector.h:61
Vector(const T *array)
Constructor that takes an array.
Definition: Vector.h:113
Vector()=default
Default constructor.
Vector & operator=(const Vector &other)=default
Default copy assignment.
void swap(Vector< T, N > &lhs, Vector< T, N > &rhs) noexcept
Swap two vectors.
Definition: Vector.h:1394
const T * begin() const
Iterator.to the first element (const version).
Definition: Vector.h:221
constexpr T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:178
T * begin()
Iterator.to the first element.
Definition: Vector.h:203
constexpr auto vec(Types... values) -> Vector< std::common_type_t< Types... >, sizeof...(Types)>
Universal vector factory.
Definition: Vector.h:1407
constexpr Vector(ZeroType) noexcept
Constructor that zero the vector out.
Definition: Vector.h:77
const T * end() const
Iterator on the element after the last one (const version).
Definition: Vector.h:231
Vector(std::initializer_list< T > list) noexcept
Constructor that takes an initializer list.
Definition: Vector.h:131
constexpr void zero() noexcept
Zero out the vector.
Definition: Vector.h:257
T * end()
Iterator to the element after the last one.
Definition: Vector.h:212
constexpr T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:193
Vector(T val) noexcept
Constructor that fills the vector with a value.
Definition: Vector.h:95
Vector(const Vector< U, N > &other) noexcept
Converting copy constructor.
Definition: Vector.h:153
const T * cbegin() const
Iterator.on the first element (const version).
Definition: Vector.h:240
const T * cend() const
Iterator on the element after the last one (const version).
Definition: Vector.h:250
Vector(const Vector &other)=default
Default copy constructor.
Semantic type to represent "zero".
Definition: Types.h:85