💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

136 lines
5.0 KiB

  1. /*
  2. * Copyright (C) 2021 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef ANTKEEPER_MATH_VECTOR_TYPE_HPP
  20. #define ANTKEEPER_MATH_VECTOR_TYPE_HPP
  21. #include <array>
  22. #include <cstddef>
  23. namespace math {
  24. /**
  25. * An `N`-dimensional Euclidean vector.
  26. *
  27. * @tparam T Vector component type.
  28. * @tparam N Number of dimensions.
  29. */
  30. template <typename T, std::size_t N>
  31. struct vector
  32. {
  33. typedef T scalar_type;
  34. typedef std::array<T, N> array_type;
  35. scalar_type components[N];
  36. inline constexpr scalar_type& operator[](std::size_t i) noexcept { return components[i]; }
  37. inline constexpr const scalar_type& operator[](std::size_t i) const noexcept { return components[i]; }
  38. inline constexpr operator array_type&() noexcept { return reinterpret_cast<array_type&>(components[0]); }
  39. inline constexpr operator const array_type&() const noexcept { return reinterpret_cast<const array_type&>(components[0]); }
  40. inline constexpr const scalar_type* data() const noexcept { return components; };
  41. inline constexpr scalar_type* data() noexcept { return components; };
  42. inline constexpr std::size_t size() const noexcept { return N; };
  43. };
  44. template <typename T>
  45. struct vector<T, 1>
  46. {
  47. typedef T scalar_type;
  48. typedef std::array<T, 1> array_type;
  49. scalar_type x;
  50. inline constexpr scalar_type& operator[](std::size_t i) noexcept { return *((&x) + i); }
  51. inline constexpr const scalar_type& operator[](std::size_t i) const noexcept { return *((&x) + i); }
  52. inline constexpr operator array_type&() noexcept { return reinterpret_cast<array_type&>(x); }
  53. inline constexpr operator const array_type&() const noexcept { return reinterpret_cast<const array_type&>(x); }
  54. inline constexpr const scalar_type* data() const noexcept { return &x; };
  55. inline constexpr scalar_type* data() noexcept { return &x; };
  56. inline constexpr std::size_t size() const noexcept { return 1; };
  57. };
  58. template <typename T>
  59. struct vector<T, 2>
  60. {
  61. typedef T scalar_type;
  62. typedef std::array<T, 2> array_type;
  63. scalar_type x;
  64. scalar_type y;
  65. inline constexpr scalar_type& operator[](std::size_t i) noexcept { return *((&x) + i); }
  66. inline constexpr const scalar_type& operator[](std::size_t i) const noexcept { return *((&x) + i); }
  67. inline constexpr operator array_type&() noexcept { return reinterpret_cast<array_type&>(x); }
  68. inline constexpr operator const array_type&() const noexcept { return reinterpret_cast<const array_type&>(x); }
  69. inline constexpr const scalar_type* data() const noexcept { return &x; };
  70. inline constexpr scalar_type* data() noexcept { return &x; };
  71. inline constexpr std::size_t size() const noexcept { return 2; };
  72. };
  73. template <typename T>
  74. struct vector<T, 3>
  75. {
  76. typedef T scalar_type;
  77. typedef std::array<T, 3> array_type;
  78. scalar_type x;
  79. scalar_type y;
  80. scalar_type z;
  81. inline constexpr scalar_type& operator[](std::size_t i) noexcept { return *((&x) + i); }
  82. inline constexpr const scalar_type& operator[](std::size_t i) const noexcept { return *((&x) + i); }
  83. inline constexpr operator array_type&() noexcept { return reinterpret_cast<array_type&>(x); }
  84. inline constexpr operator const array_type&() const noexcept { return reinterpret_cast<const array_type&>(x); }
  85. inline constexpr const scalar_type* data() const noexcept { return &x; };
  86. inline constexpr scalar_type* data() noexcept { return &x; };
  87. inline constexpr std::size_t size() const noexcept { return 3; };
  88. };
  89. template <typename T>
  90. struct vector<T, 4>
  91. {
  92. typedef T scalar_type;
  93. typedef std::array<T, 4> array_type;
  94. scalar_type x;
  95. scalar_type y;
  96. scalar_type z;
  97. scalar_type w;
  98. inline constexpr scalar_type& operator[](std::size_t i) noexcept { return *((&x) + i); }
  99. inline constexpr const scalar_type& operator[](std::size_t i) const noexcept { return *((&x) + i); }
  100. inline constexpr operator array_type&() noexcept { return reinterpret_cast<array_type&>(x); }
  101. inline constexpr operator const array_type&() const noexcept { return reinterpret_cast<const array_type&>(x); }
  102. inline constexpr const scalar_type* data() const noexcept { return &x; };
  103. inline constexpr scalar_type* data() noexcept { return &x; };
  104. inline constexpr std::size_t size() const noexcept { return 4; };
  105. };
  106. /// 2D vector.
  107. template <typename T>
  108. using vector2 = vector<T, 2>;
  109. /// 3D vector.
  110. template <typename T>
  111. using vector3 = vector<T, 3>;
  112. /// 4D vector.
  113. template <typename T>
  114. using vector4 = vector<T, 4>;
  115. } // namespace math
  116. #endif // ANTKEEPER_MATH_VECTOR_TYPE_HPP