2** EPITECH PROJECT, 2025
5** VecBase.tpp, CRTP base vector class implementation
11** Copyright (c) 2025 Robin Toillon
13** Permission is hereby granted, free of charge, to any person obtaining
14** a copy of this software and associated documentation files (the
15** "Software"), to deal in the Software without restriction, including
16** without limitation the rights to use, copy, modify, merge, publish,
17** distribute, sublicense, and/or sell copies of the Software, and to
18** permit persons to whom the Software is furnished to do so, subject to
19** the following conditions:
21** The above copyright notice and this permission notice shall be
22** included in all copies or substantial portions of the Software.
24** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30** SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 * @brief Implementation of the CRTP base vector class.
36 * @author Robin Toillon
41 ///////////////////////////////////////////////////////////////////////////
43 ///////////////////////////////////////////////////////////////////////////
45 template <Numeric T, std::size_t N>
46 template <typename Self>
47 constexpr auto VecBase<T, N>::squaredDistance(this const Self &self,
48 const std::remove_cvref_t<Self> &other) noexcept
53 for (std::size_t i = 0; i < N; ++i) {
54 T diff = self[i] - other[i];
61 template <Numeric T, std::size_t N>
62 template <typename Self>
63 constexpr auto VecBase<T, N>::distance(this const Self &self,
64 const std::remove_cvref_t<Self> &other) noexcept
67 return static_cast<RealT>(std::sqrt(self.squaredDistance(other)));
70 template <Numeric T, std::size_t N>
71 template <typename Self>
72 constexpr auto VecBase<T, N>::squaredLength(this const Self &self) noexcept
77 for (std::size_t i = 0; i < N; ++i)
78 sum += self[i] * self[i];
83 template <Numeric T, std::size_t N>
84 template <typename Self>
85 constexpr auto VecBase<T, N>::length(this const Self &self) noexcept
88 return static_cast<RealT>(std::sqrt(self.squaredLength()));
91 template <Numeric T, std::size_t N>
92 template <typename Self>
93 constexpr auto VecBase<T, N>::normalize(this Self &self) noexcept
95 requires std::floating_point<T>
97 T len = self.length();
100 for (std::size_t i = 0; i < N; ++i)
106 template <Numeric T, std::size_t N>
107 template <typename Self>
108 constexpr auto VecBase<T, N>::normalized(this const Self &self) noexcept
109 -> std::remove_cvref_t<Self>
110 requires std::floating_point<T>
112 std::remove_cvref_t<Self> copy = self;
113 return copy.normalize();
116 template <Numeric T, std::size_t N>
117 template <typename Self>
118 constexpr auto VecBase<T, N>::dot(this const Self &self,
119 const std::remove_cvref_t<Self>
125 for (std::size_t i = 0; i < N; ++i)
126 result += self[i] * other[i];
131 template <Numeric T, std::size_t N>
132 template <typename Self>
133 constexpr auto VecBase<T, N>::project(this const Self &self,
134 const std::remove_cvref_t<Self> &other) noexcept
135 -> std::remove_cvref_t<Self>
136 requires std::floating_point<T>
138 using VecType = std::remove_cvref_t<Self>;
140 T otherSquaredLength = other.squaredLength();
141 if (otherSquaredLength == T{0})
144 T scalar = self.dot(other) / otherSquaredLength;
146 for (std::size_t i = 0; i < N; ++i)
147 result[i] = other[i] * scalar;
152 ///////////////////////////////////////////////////////////////////////////
153 // Vector & Vector operations (Member Operators)
154 ///////////////////////////////////////////////////////////////////////////
156 template <Numeric T, std::size_t N>
157 template <typename Self>
158 constexpr auto &VecBase<T, N>::operator+=(this Self &self,
159 const std::remove_cvref_t<Self> &other) noexcept
161 for (std::size_t i = 0; i < N; ++i)
166 template <Numeric T, std::size_t N>
167 template <typename Self>
168 constexpr auto &VecBase<T, N>::operator-=(this Self &self,
169 const std::remove_cvref_t<Self> &other) noexcept
171 for (std::size_t i = 0; i < N; ++i)
176 template <Numeric T, std::size_t N>
177 template <typename Self>
178 constexpr auto &VecBase<T, N>::operator*=(this Self &self,
179 const std::remove_cvref_t<Self> &other) noexcept
181 for (std::size_t i = 0; i < N; ++i)
186 template <Numeric T, std::size_t N>
187 template <typename Self>
188 constexpr auto &VecBase<T, N>::operator/=(this Self &self,
189 const std::remove_cvref_t<Self> &other) noexcept
191 for (std::size_t i = 0; i < N; ++i)
196 ///////////////////////////////////////////////////////////////////////////
197 // Vector & Scalar operations (Member Operators)
198 ///////////////////////////////////////////////////////////////////////////
200 template <Numeric T, std::size_t N>
201 template <typename Self>
202 constexpr auto &VecBase<T, N>::operator+=(this Self &self, T scalar) noexcept
204 for (std::size_t i = 0; i < N; ++i)
209 template <Numeric T, std::size_t N>
210 template <typename Self>
211 constexpr auto &VecBase<T, N>::operator-=(this Self &self, T scalar) noexcept
213 for (std::size_t i = 0; i < N; ++i)
218 template <Numeric T, std::size_t N>
219 template <typename Self>
220 constexpr auto &VecBase<T, N>::operator*=(this Self &self, T scalar) noexcept
222 for (std::size_t i = 0; i < N; ++i)
227 template <Numeric T, std::size_t N>
228 template <typename Self>
229 constexpr auto &VecBase<T, N>::operator/=(this Self &self, T scalar) noexcept
231 for (std::size_t i = 0; i < N; ++i)