Gamedev Framework (gf)  0.17.0
A C++14 framework for 2D games
Vector.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016-2019 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  : 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;
518  T col;
519  };
520 
524  union {
525  T y;
526  T v;
527  T t;
529  T row;
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 {
1082  T x;
1083  T r;
1084  };
1085 
1089  union {
1090  T y;
1091  T g;
1092  };
1093 
1097  union {
1098  T z;
1099  T b;
1100  };
1101 
1105  union {
1106  T w;
1107  T a;
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_API Vector<float, 2>;
1326  extern template struct GF_API Vector<float, 3>;
1327  extern template struct GF_API Vector<float, 4>;
1328 
1329  extern template struct GF_API Vector<double, 2>;
1330  extern template struct GF_API Vector<double, 3>;
1331  extern template struct GF_API Vector<double, 4>;
1332 
1333  extern template struct GF_API Vector<int, 2>;
1334  extern template struct GF_API Vector<int, 3>;
1335  extern template struct GF_API Vector<int, 4>;
1336 
1337  extern template struct GF_API Vector<unsigned, 2>;
1338  extern template struct GF_API Vector<unsigned, 3>;
1339  extern template struct GF_API Vector<unsigned, 4>;
1340 
1341  extern template struct GF_API Vector<bool, 2>;
1342  extern template struct GF_API Vector<bool, 3>;
1343  extern template struct GF_API Vector<bool, 4>;
1344 
1345  extern template struct GF_API Vector<uint8_t, 3>;
1346  extern template struct GF_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 Vector(T first, T second, T third) noexcept
Constructor that takes 3 components.
Definition: Vector.h:634
T x
First coordinate in the (x,y) representation.
Definition: Vector.h:514
T g
Second coordinate in the (r,g,b) representation.
Definition: Vector.h:803
constexpr Vector< T, 3 > xyz() const
Swizzle to get the first three coordinates as a 3D vector.
Definition: Vector.h:1066
const T * cbegin() const
Iterator.on the first element (const version).
Definition: Vector.h:1035
const T * cend() const
Iterator on the element after the last one (const version).
Definition: Vector.h:1045
constexpr Vector(ZeroType) noexcept
Constructor that zero the vector out.
Definition: Vector.h:582
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:442
constexpr T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:713
const T * end() const
Iterator on the element after the last one (const version).
Definition: Vector.h:752
Distance< T, 2 > Distance2
A distance function for 2D vectors.
Definition: Vector.h:1376
constexpr Vector2f transform(const Matrix3f &mat, Vector2f point)
Apply an affine transformation to a 2D point.
Definition: Transform.h:323
T z
Third coordinate in the (x,y,z,w) representation.
Definition: Vector.h:1098
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:771
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:971
constexpr Vector< T, 2 > xy() const
Swizzle to get the first two coordinates as a 2D vector.
Definition: Vector.h:1059
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:1107
T * begin()
Iterator.to the first element.
Definition: Vector.h:724
constexpr T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:426
T v
Second coordinate in the (u,v) representation.
Definition: Vector.h:526
T y
Second coordinate in the (x,y) representation.
Definition: Vector.h:525
T x
First coordinate in the (x,y,z) representation.
Definition: Vector.h:794
const T * begin() const
Iterator.to the first element (const version).
Definition: Vector.h:471
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:1026
T s
First coordinate in the (s,t) representation.
Definition: Vector.h:516
constexpr Vector(const T *array)
Constructor that takes an array.
Definition: Vector.h:620
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:864
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:499
T height
Second coordinate in the size representation.
Definition: Vector.h:528
T * end()
Iterator to the element after the last one.
Definition: Vector.h:733
constexpr Vector(T val) noexcept
Constructor that fills the vector with a value.
Definition: Vector.h:600
const T * end() const
Iterator on the element after the last one (const version).
Definition: Vector.h:481
constexpr void zero() noexcept
Zero out the vector.
Definition: Vector.h:506
Distance< T, 3 > Distance3
A distance function for 3D vectors.
Definition: Vector.h:1385
The namespace for gf classes.
Definition: Action.h:35
T g
Second coordinate in the (r,g,b,a) representation.
Definition: Vector.h:1091
T x
First coordinate in the (x,y,z,w) representation.
Definition: Vector.h:1082
constexpr Vector(Vector< T, 2 > xy, T third)
Constructor that takes a 2D vector and a z component.
Definition: Vector.h:647
constexpr auto vec(Types... values) -> Vector< std::common_type_t< Types... >, sizeof...(Types)>
Universal vector factory.
Definition: Vector.h:1407
constexpr void zero() noexcept
Zero out the vector.
Definition: Vector.h:1052
A 4D vector.
Definition: Vector.h:852
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:795
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:489
constexpr Vector(const T *array)
Constructor that takes an array.
Definition: Vector.h:903
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:1099
void swap(Vector< T, N > &lhs, Vector< T, N > &rhs) noexcept
Swap two vectors.
Definition: Vector.h:1394
T col
First coordinate in the indices representation.
Definition: Vector.h:518
const T * cbegin() const
Iterator.on the first element (const version).
Definition: Vector.h:761
const T * begin() const
Iterator.to the first element (const version).
Definition: Vector.h:1016
T * end()
Iterator to the element after the last one.
Definition: Vector.h:1007
A 2D vector.
Definition: Vector.h:316
T y
Second coordinate in the (x,y,z) representation.
Definition: Vector.h:802
constexpr ArrayRef< T > array(const T *data, std::size_t size)
Create a constant reference to an array.
Definition: ArrayRef.h:204
constexpr Vector(T val) noexcept
Constructor that fills the vector with a value.
Definition: Vector.h:347
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:778
T y
Second coordinate in the (x,y,z,w) representation.
Definition: Vector.h:1090
T u
First coordinate in the (u,v) representation.
Definition: Vector.h:515
T b
Third coordinate in the (r,g,b) representation.
Definition: Vector.h:811
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:697
constexpr Vector< T, 3 > rgb() const
Swizzle to get the first three coordinates as a RGB color.
Definition: Vector.h:1073
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:453
A 3D vector.
Definition: Vector.h:570
T r
First coordinate in the (r,g,b,a) representation.
Definition: Vector.h:1083
General purpose math vector.
Definition: Vector.h:61
T w
Fourth coordinate in the (x,y,z,w) representation.
Definition: Vector.h:1106
const T * begin() const
Iterator.to the first element (const version).
Definition: Vector.h:742
T z
Third coordinate in the (x,y,z) representation.
Definition: Vector.h:810
Vector(const Vector< U, 2 > &other) noexcept
Converting copy constructor.
Definition: Vector.h:400
T(*)(Vector< T, N >, Vector< T, N >) Distance
A distance function.
Definition: Vector.h:1367
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:943
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:919
T t
Second coordinate in the (s,t) representation.
Definition: Vector.h:527
constexpr Vector< T, 2 > xy() const
Swizzle to get the first two coordinates as a 2D vector.
Definition: Vector.h:785
T * begin()
Iterator.to the first element.
Definition: Vector.h:998
T row
Second coordinate in the indices representation.
Definition: Vector.h:529
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:882
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:462
constexpr Vector(T first, T second) noexcept
Constructor that takes 2 components.
Definition: Vector.h:378
Semantic type to represent "zero".
Definition: Types.h:85