Gamedev Framework (gf)  0.10.0
A C++14 framework for 2D games
Vector.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2018 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 "Portability.h"
32 #include "Types.h"
33 
34 namespace gf {
35 #ifndef DOXYGEN_SHOULD_SKIP_THIS
36 inline 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  {
330  zero();
331  }
332 
346  explicit constexpr Vector(T val) noexcept
347  : x(val)
348  , y(val)
349  {
350 
351  }
352 
366  explicit constexpr Vector(const T *array)
367  : x(array[0])
368  , y(array[1])
369  {
370 
371  }
372 
379  constexpr Vector(T first, T second) noexcept
380  : x(first)
381  , y(second)
382  {
383 
384  }
385 
394  Vector(const Vector& other) = default;
395 
396 
402  template<typename U>
403  Vector(const Vector<U, 2>& other) noexcept
404  : x(static_cast<T>(other.x))
405  , y(static_cast<T>(other.y))
406  {
407  static_assert(std::is_convertible<U,T>::value, "Non-convertible types");
408  }
409 
421  constexpr T operator[](std::size_t i) const {
422  const T *data[] = { &x, &y };
423  return *data[i];
424  }
425 
437  constexpr T& operator[](std::size_t i) {
438  T *data[] = { &x, &y };
439  return *data[i];
440  }
441 
442 
448  T *begin() {
449  return &x;
450  }
451 
457  T *end() {
458  return &x + 2;
459  }
460 
466  const T *begin() const {
467  return &x;
468  }
469 
476  const T *end() const {
477  return &x + 2;
478  }
484  const T *cbegin() const {
485  return &x;
486  }
487 
494  const T *cend() const {
495  return &x + 2;
496  }
497 
501  constexpr void zero() noexcept {
502  x = y = T{};
503  }
504 
508  union {
509  T x;
510  T u;
511  T s;
513  T col;
514  };
515 
519  union {
520  T y;
521  T v;
522  T t;
524  T row;
525  };
526  };
527 
564  template <typename T>
565  struct Vector<T, 3> {
572  Vector() = default;
573 
577  constexpr Vector(ZeroType) noexcept
578  {
579  zero();
580  }
581 
595  explicit constexpr Vector(T val) noexcept
596  : x(val)
597  , y(val)
598  , z(val)
599  {
600 
601  }
602 
616  explicit constexpr Vector(const T *array)
617  : x(array[0])
618  , y(array[1])
619  , z(array[2])
620  {
621 
622  }
623 
631  constexpr Vector(T first, T second, T third) noexcept
632  : x(first)
633  , y(second)
634  , z(third)
635  {
636 
637  }
638 
645  constexpr Vector(Vector<T, 2> xy, T third)
646  : x(xy.x)
647  , y(xy.y)
648  , z(third)
649  {
650 
651  }
652 
661  Vector(const Vector& other) = default;
662 
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 
689  constexpr T operator[](std::size_t i) const {
690  const T *data[] = { &x, &y, &z };
691  return *data[i];
692  }
693 
705  constexpr T& operator[](std::size_t i) {
706  T *data[] = { &x, &y, &z };
707  return *data[i];
708  }
709 
710 
716  T *begin() {
717  return &x;
718  }
719 
725  T *end() {
726  return &x + 3;
727  }
728 
734  const T *begin() const {
735  return &x;
736  }
737 
744  const T *end() const {
745  return &x + 3;
746  }
747 
753  const T *cbegin() const {
754  return &x;
755  }
756 
763  const T *cend() const {
764  return &x + 3;
765  }
766 
770  constexpr void zero() noexcept {
771  x = y = z = T{};
772  }
773 
777  constexpr Vector<T, 2> xy() const {
778  return { x, y };
779  }
780 
781 
785  union {
786  T x;
787  T r;
788  };
789 
793  union {
794  T y;
795  T g;
796  };
797 
801  union {
802  T z;
803  T b;
804  };
805 
806  };
807 
844  template <typename T>
845  struct Vector<T, 4> {
852  Vector() = default;
853 
857  constexpr Vector(ZeroType) noexcept
858  {
859  zero();
860  }
861 
875  explicit constexpr Vector(T val) noexcept
876  : x(val)
877  , y(val)
878  , z(val)
879  , w(val)
880  {
881 
882  }
883 
897  explicit constexpr Vector(const T *array)
898  : x(array[0])
899  , y(array[1])
900  , z(array[2])
901  , w(array[3])
902  {
903 
904  }
905 
914  constexpr Vector(T first, T second, T third, T fourth) noexcept
915  : x(first)
916  , y(second)
917  , z(third)
918  , w(fourth)
919  {
920 
921  }
922 
931  Vector(const Vector& other) = default;
932 
933 
939  template<typename U>
940  Vector(const Vector<U, 4>& other) noexcept
941  : x(static_cast<T>(other.x))
942  , y(static_cast<T>(other.y))
943  , z(static_cast<T>(other.z))
944  , w(static_cast<T>(other.w))
945  {
946  static_assert(std::is_convertible<U,T>::value, "Non-convertible types");
947  }
948 
960  constexpr T operator[](std::size_t i) const {
961  const T *data[] = { &x, &y, &z, &w };
962  return *data[i];
963  }
964 
976  constexpr T& operator[](std::size_t i) {
977  T *data[] = { &x, &y, &z, &w };
978  return *data[i];
979  }
980 
981 
987  T *begin() {
988  return &x;
989  }
990 
996  T *end() {
997  return &x + 4;
998  }
999 
1005  const T *begin() const {
1006  return &x;
1007  }
1008 
1015  const T *end() const {
1016  return &x + 4;
1017  }
1018 
1024  const T *cbegin() const {
1025  return &x;
1026  }
1027 
1034  const T *cend() const {
1035  return &x + 4;
1036  }
1037 
1041  constexpr void zero() noexcept {
1042  x = y = z = w = T{};
1043  }
1044 
1048  constexpr Vector<T, 2> xy() const {
1049  return { x, y };
1050  }
1051 
1055  constexpr Vector<T, 3> xyz() const {
1056  return { x, y, z };
1057  }
1058 
1062  constexpr Vector<T, 3> rgb() const {
1063  return { r, g, b };
1064  }
1065 
1066 
1070  union {
1071  T x;
1072  T r;
1073  };
1074 
1078  union {
1079  T y;
1080  T g;
1081  };
1082 
1086  union {
1087  T z;
1088  T b;
1089  };
1090 
1094  union {
1095  T w;
1096  T a;
1097  };
1098 
1099  };
1100 
1108 
1116 
1124 
1132 
1140 
1148 
1156 
1164 
1172 
1180 
1188 
1196 
1204 
1212 
1220 
1228 
1236 
1244 
1252 
1260 
1268 
1276 
1277 // MSVC does not like extern template
1278 #ifndef _MSC_VER
1279  extern template struct Vector<float, 2>;
1280  extern template struct Vector<float, 3>;
1281  extern template struct Vector<float, 4>;
1282 
1283  extern template struct Vector<double, 2>;
1284  extern template struct Vector<double, 3>;
1285  extern template struct Vector<double, 4>;
1286 
1287  extern template struct Vector<int, 2>;
1288  extern template struct Vector<int, 3>;
1289  extern template struct Vector<int, 4>;
1290 
1291  extern template struct Vector<unsigned, 2>;
1292  extern template struct Vector<unsigned, 3>;
1293  extern template struct Vector<unsigned, 4>;
1294 
1295  extern template struct Vector<bool, 2>;
1296  extern template struct Vector<bool, 3>;
1297  extern template struct Vector<bool, 4>;
1298 
1299  extern template struct Vector<uint8_t, 3>;
1300  extern template struct Vector<uint8_t, 4>;
1301 #endif
1302 
1320  template<typename T, std::size_t N>
1322 
1329  template<typename T>
1331 
1338  template<typename T>
1340 
1341 #ifndef DOXYGEN_SHOULD_SKIP_THIS
1342 }
1343 #endif
1344 }
1345 
1346 #endif // GAME_VECTOR_H
constexpr Vector(T first, T second, T third) noexcept
Constructor that takes 3 components.
Definition: Vector.h:631
T x
First coordinate in the (x,y) representation.
Definition: Vector.h:509
T g
Second coordinate in the (r,g,b) representation.
Definition: Vector.h:795
constexpr Vector< T, 3 > xyz() const
Swizzle to get the first three coordinates as a 3D vector.
Definition: Vector.h:1055
const T * cbegin() const
Iterator.on the first element (const version).
Definition: Vector.h:1024
const T * cend() const
Iterator on the element after the last one (const version).
Definition: Vector.h:1034
constexpr Vector(ZeroType) noexcept
Constructor that zero the vector out.
Definition: Vector.h:577
Vector(const Vector< U, 3 > &other) noexcept
Converting copy constructor.
Definition: Vector.h:670
constexpr T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:437
constexpr T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:705
const T * end() const
Iterator on the element after the last one (const version).
Definition: Vector.h:744
Distance< T, 2 > Distance2
A distance function for 2D vectors.
Definition: Vector.h:1330
constexpr Vector2f transform(const Matrix3f &mat, Vector2f point)
Apply an affine transformation to a 2D point.
Definition: Transform.h:331
T z
Third coordinate in the (x,y,z,w) representation.
Definition: Vector.h:1087
T * end()
Iterator to the element after the last one.
Definition: Vector.h:212
constexpr T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:178
const T * cend() const
Iterator on the element after the last one (const version).
Definition: Vector.h:763
constexpr Vector(ZeroType) noexcept
Constructor that zero the vector out.
Definition: Vector.h:328
constexpr T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:960
constexpr Vector< T, 2 > xy() const
Swizzle to get the first two coordinates as a 2D vector.
Definition: Vector.h:1048
constexpr Vector(ZeroType) noexcept
Constructor that zero the vector out.
Definition: Vector.h:77
T * begin()
Iterator.to the first element.
Definition: Vector.h:203
T a
Fourth coordinate in the (r,g,b,a) representation.
Definition: Vector.h:1096
T * begin()
Iterator.to the first element.
Definition: Vector.h:716
constexpr T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:421
T v
Second coordinate in the (u,v) representation.
Definition: Vector.h:521
T y
Second coordinate in the (x,y) representation.
Definition: Vector.h:520
T x
First coordinate in the (x,y,z) representation.
Definition: Vector.h:786
const T * begin() const
Iterator.to the first element (const version).
Definition: Vector.h:466
T width
First coordinate in the size representation.
Definition: Vector.h:512
const T * end() const
Iterator on the element after the last one (const version).
Definition: Vector.h:1015
T s
First coordinate in the (s,t) representation.
Definition: Vector.h:511
constexpr Vector(const T *array)
Constructor that takes an array.
Definition: Vector.h:616
Vector(const Vector< U, N > &other) noexcept
Converting copy constructor.
Definition: Vector.h:153
constexpr Vector(ZeroType) noexcept
Constructor that zero the vector out.
Definition: Vector.h:857
T data[N]
The internal representation of the vector.
Definition: Vector.h:270
const T * cend() const
Iterator on the element after the last one (const version).
Definition: Vector.h:494
T height
Second coordinate in the size representation.
Definition: Vector.h:523
T * end()
Iterator to the element after the last one.
Definition: Vector.h:725
constexpr Vector(T val) noexcept
Constructor that fills the vector with a value.
Definition: Vector.h:595
const T * end() const
Iterator on the element after the last one (const version).
Definition: Vector.h:476
constexpr void zero() noexcept
Zero out the vector.
Definition: Vector.h:501
Distance< T, 3 > Distance3
A distance function for 3D vectors.
Definition: Vector.h:1339
The namespace for gf classes.
Definition: Action.h:34
T g
Second coordinate in the (r,g,b,a) representation.
Definition: Vector.h:1080
T x
First coordinate in the (x,y,z,w) representation.
Definition: Vector.h:1071
constexpr Vector(Vector< T, 2 > xy, T third)
Constructor that takes a 2D vector and a z component.
Definition: Vector.h:645
constexpr void zero() noexcept
Zero out the vector.
Definition: Vector.h:1041
Vector(const T *array)
Constructor that takes an array.
Definition: Vector.h:113
T r
First coordinate in the (r,g,b) representation.
Definition: Vector.h:787
Vector(T val) noexcept
Constructor that fills the vector with a value.
Definition: Vector.h:95
const T * cend() const
Iterator on the element after the last one (const version).
Definition: Vector.h:250
const T * cbegin() const
Iterator.on the first element (const version).
Definition: Vector.h:484
constexpr Vector(const T *array)
Constructor that takes an array.
Definition: Vector.h:897
constexpr void zero() noexcept
Zero out the vector.
Definition: Vector.h:257
T b
Third coordinate in the (r,g,b,a) representation.
Definition: Vector.h:1088
T col
First coordinate in the indices representation.
Definition: Vector.h:513
const T * cbegin() const
Iterator.on the first element (const version).
Definition: Vector.h:753
const T * begin() const
Iterator.to the first element (const version).
Definition: Vector.h:1005
T * end()
Iterator to the element after the last one.
Definition: Vector.h:996
A 2D vector.
Definition: Vector.h:316
T y
Second coordinate in the (x,y,z) representation.
Definition: Vector.h:794
constexpr Vector(T val) noexcept
Constructor that fills the vector with a value.
Definition: Vector.h:346
const T * end() const
Iterator on the element after the last one (const version).
Definition: Vector.h:231
constexpr void zero() noexcept
Zero out the vector.
Definition: Vector.h:770
T y
Second coordinate in the (x,y,z,w) representation.
Definition: Vector.h:1079
T u
First coordinate in the (u,v) representation.
Definition: Vector.h:510
T b
Third coordinate in the (r,g,b) representation.
Definition: Vector.h:803
constexpr T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:193
constexpr T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:689
constexpr Vector< T, 3 > rgb() const
Swizzle to get the first three coordinates as a RGB color.
Definition: Vector.h:1062
const T * cbegin() const
Iterator.on the first element (const version).
Definition: Vector.h:240
T * begin()
Iterator.to the first element.
Definition: Vector.h:448
A 3D vector.
Definition: Vector.h:565
T r
First coordinate in the (r,g,b,a) representation.
Definition: Vector.h:1072
General purpose math vector.
Definition: Vector.h:61
T w
Fourth coordinate in the (x,y,z,w) representation.
Definition: Vector.h:1095
const T * begin() const
Iterator.to the first element (const version).
Definition: Vector.h:734
T z
Third coordinate in the (x,y,z) representation.
Definition: Vector.h:802
Vector(const Vector< U, 2 > &other) noexcept
Converting copy constructor.
Definition: Vector.h:403
T(*)(Vector< T, N >, Vector< T, N >) Distance
A distance function.
Definition: Vector.h:1321
const T * begin() const
Iterator.to the first element (const version).
Definition: Vector.h:221
Vector(const Vector< U, 4 > &other) noexcept
Converting copy constructor.
Definition: Vector.h:940
constexpr Vector(const T *array)
Constructor that takes an array.
Definition: Vector.h:366
constexpr Vector(T first, T second, T third, T fourth) noexcept
Constructor that takes 4 components.
Definition: Vector.h:914
T t
Second coordinate in the (s,t) representation.
Definition: Vector.h:522
constexpr Vector< T, 2 > xy() const
Swizzle to get the first two coordinates as a 2D vector.
Definition: Vector.h:777
T * begin()
Iterator.to the first element.
Definition: Vector.h:987
T row
Second coordinate in the indices representation.
Definition: Vector.h:524
Vector(std::initializer_list< T > list) noexcept
Constructor that takes an initializer list.
Definition: Vector.h:131
constexpr Vector(T val) noexcept
Constructor that fills the vector with a value.
Definition: Vector.h:875
constexpr T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:976
T * end()
Iterator to the element after the last one.
Definition: Vector.h:457
constexpr Vector(T first, T second) noexcept
Constructor that takes 2 components.
Definition: Vector.h:379
Semantic type to represent "zero".
Definition: Types.h:69