💿🐜 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.

131 lines
4.9 KiB

  1. /*
  2. * Copyright (C) 2020 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. /// @addtogroup vector
  25. /// @{
  26. /**
  27. * An `N`-dimensional Euclidean vector.
  28. *
  29. * @tparam T Vector component type.
  30. * @tparam N Number of dimensions.
  31. */
  32. template <typename T, std::size_t N>
  33. struct vector
  34. {
  35. typedef T scalar_type;
  36. typedef std::array<T, N> array_type;
  37. scalar_type components[N];
  38. inline constexpr scalar_type& operator[](std::size_t i) noexcept { return components[i]; }
  39. inline constexpr const scalar_type& operator[](std::size_t i) const noexcept { return components[i]; }
  40. inline constexpr operator array_type&() noexcept { return reinterpret_cast<array_type&>(components[0]); }
  41. inline constexpr operator const array_type&() const noexcept { return reinterpret_cast<const array_type&>(components[0]); }
  42. inline constexpr const scalar_type* data() const noexcept { return components; };
  43. inline constexpr scalar_type* data() noexcept { return components; };
  44. inline constexpr std::size_t size() const noexcept { return N; };
  45. };
  46. template <typename T>
  47. struct vector<T, 1>
  48. {
  49. typedef T scalar_type;
  50. typedef std::array<T, 1> array_type;
  51. scalar_type x;
  52. inline constexpr scalar_type& operator[](std::size_t i) noexcept { return *((&x) + i); }
  53. inline constexpr const scalar_type& operator[](std::size_t i) const noexcept { return *((&x) + i); }
  54. inline constexpr operator array_type&() noexcept { return reinterpret_cast<array_type&>(x); }
  55. inline constexpr operator const array_type&() const noexcept { return reinterpret_cast<const array_type&>(x); }
  56. inline constexpr const scalar_type* data() const noexcept { return &x; };
  57. inline constexpr scalar_type* data() noexcept { return &x; };
  58. inline constexpr std::size_t size() const noexcept { return 1; };
  59. };
  60. template <typename T>
  61. struct vector<T, 2>
  62. {
  63. typedef T scalar_type;
  64. typedef std::array<T, 2> array_type;
  65. scalar_type x;
  66. scalar_type y;
  67. inline constexpr scalar_type& operator[](std::size_t i) noexcept { return *((&x) + i); }
  68. inline constexpr const scalar_type& operator[](std::size_t i) const noexcept { return *((&x) + i); }
  69. inline constexpr operator array_type&() noexcept { return reinterpret_cast<array_type&>(x); }
  70. inline constexpr operator const array_type&() const noexcept { return reinterpret_cast<const array_type&>(x); }
  71. inline constexpr const scalar_type* data() const noexcept { return &x; };
  72. inline constexpr scalar_type* data() noexcept { return &x; };
  73. inline constexpr std::size_t size() const noexcept { return 2; };
  74. };
  75. template <typename T>
  76. struct vector<T, 3>
  77. {
  78. typedef T scalar_type;
  79. typedef std::array<T, 3> array_type;
  80. scalar_type x;
  81. scalar_type y;
  82. scalar_type z;
  83. inline constexpr scalar_type& operator[](std::size_t i) noexcept { return *((&x) + i); }
  84. inline constexpr const scalar_type& operator[](std::size_t i) const noexcept { return *((&x) + i); }
  85. inline constexpr operator array_type&() noexcept { return reinterpret_cast<array_type&>(x); }
  86. inline constexpr operator const array_type&() const noexcept { return reinterpret_cast<const array_type&>(x); }
  87. inline constexpr const scalar_type* data() const noexcept { return &x; };
  88. inline constexpr scalar_type* data() noexcept { return &x; };
  89. inline constexpr std::size_t size() const noexcept { return 3; };
  90. };
  91. template <typename T>
  92. struct vector<T, 4>
  93. {
  94. typedef T scalar_type;
  95. typedef std::array<T, 4> array_type;
  96. scalar_type x;
  97. scalar_type y;
  98. scalar_type z;
  99. scalar_type w;
  100. inline constexpr scalar_type& operator[](std::size_t i) noexcept { return *((&x) + i); }
  101. inline constexpr const scalar_type& operator[](std::size_t i) const noexcept { return *((&x) + i); }
  102. inline constexpr operator array_type&() noexcept { return reinterpret_cast<array_type&>(x); }
  103. inline constexpr operator const array_type&() const noexcept { return reinterpret_cast<const array_type&>(x); }
  104. inline constexpr const scalar_type* data() const noexcept { return &x; };
  105. inline constexpr scalar_type* data() noexcept { return &x; };
  106. inline constexpr std::size_t size() const noexcept { return 4; };
  107. };
  108. static_assert(std::is_trivial<vector<float, 4>>::value);
  109. /// @}
  110. } // namespace math
  111. #endif // ANTKEEPER_MATH_VECTOR_TYPE_HPP