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

1492 lines
40 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_HPP
  20. #define ANTKEEPER_MATH_VECTOR_HPP
  21. #include <algorithm>
  22. #include <cstddef>
  23. #include <cmath>
  24. #include <istream>
  25. #include <iterator>
  26. #include <ostream>
  27. #include <type_traits>
  28. #include <utility>
  29. namespace math {
  30. /**
  31. * *n*-dimensional Euclidean vector.
  32. *
  33. * @tparam T Element type.
  34. * @tparam N Number of elements.
  35. */
  36. template <typename T, std::size_t N>
  37. struct vector
  38. {
  39. /// Vector element data type.
  40. typedef T element_type;
  41. /// Number of elements.
  42. static constexpr std::size_t element_count = N;
  43. /// Array of vector elements.
  44. element_type elements[N];
  45. /**
  46. * Returns a reference to the element at a given index.
  47. *
  48. * @param i Index of an element.
  49. *
  50. * @return Reference to the element at index @p i.
  51. */
  52. /// @{
  53. constexpr inline element_type& operator[](std::size_t i) noexcept
  54. {
  55. return elements[i];
  56. }
  57. constexpr inline const element_type& operator[](std::size_t i) const noexcept
  58. {
  59. return elements[i];
  60. }
  61. /// @}
  62. /// Returns a reference to the first element.
  63. /// @{
  64. constexpr inline element_type& front() noexcept
  65. {
  66. return elements[0];
  67. }
  68. constexpr inline const element_type& front() const noexcept
  69. {
  70. return elements[0];
  71. }
  72. /// @}
  73. /// Returns a reference to the last element.
  74. /// @{
  75. constexpr inline element_type& back() noexcept
  76. {
  77. return elements[N - 1];
  78. }
  79. constexpr inline const element_type& back() const noexcept
  80. {
  81. return elements[N - 1];
  82. }
  83. /// @}
  84. /// Returns a reference to the first element.
  85. /// @{
  86. constexpr inline element_type& x() noexcept
  87. {
  88. static_assert(N > 0, "Vector does not contain an x element.");
  89. return elements[0];
  90. }
  91. constexpr inline const element_type& x() const noexcept
  92. {
  93. static_assert(N > 0, "Vector does not contain an x element.");
  94. return elements[0];
  95. }
  96. /// @}
  97. /// Returns a reference to the second element.
  98. /// @{
  99. constexpr inline element_type& y() noexcept
  100. {
  101. static_assert(N > 1, "Vector does not contain a y element.");
  102. return elements[1];
  103. }
  104. constexpr inline const element_type& y() const noexcept
  105. {
  106. static_assert(N > 1, "Vector does not contain a y element.");
  107. return elements[1];
  108. }
  109. /// @}
  110. /// Returns a reference to the third element.
  111. /// @{
  112. constexpr inline element_type& z() noexcept
  113. {
  114. static_assert(N > 2, "Vector does not contain a z element.");
  115. return elements[2];
  116. }
  117. constexpr inline const element_type& z() const noexcept
  118. {
  119. static_assert(N > 2, "Vector does not contain a z element.");
  120. return elements[2];
  121. }
  122. /// @}
  123. /// Returns a pointer to the element array.
  124. /// @{
  125. constexpr inline element_type* data() noexcept
  126. {
  127. return elements;
  128. };
  129. constexpr inline const element_type* data() const noexcept
  130. {
  131. return elements;
  132. };
  133. /// @}
  134. /// Returns an iterator to the first element.
  135. /// @{
  136. constexpr inline element_type* begin() noexcept
  137. {
  138. return elements;
  139. }
  140. constexpr inline const element_type* begin() const noexcept
  141. {
  142. return elements;
  143. }
  144. constexpr inline const element_type* cbegin() const noexcept
  145. {
  146. return elements;
  147. }
  148. /// @}
  149. /// Returns an iterator to the element following the last element.
  150. /// @{
  151. constexpr inline element_type* end() noexcept
  152. {
  153. return elements + N;
  154. }
  155. constexpr inline const element_type* end() const noexcept
  156. {
  157. return elements + N;
  158. }
  159. constexpr inline const element_type* cend() const noexcept
  160. {
  161. return elements + N;
  162. }
  163. /// @}
  164. /// Returns a reverse iterator to the first element of the reversed vector.
  165. /// @{
  166. constexpr inline std::reverse_iterator<element_type*> rbegin() noexcept
  167. {
  168. return std::reverse_iterator<element_type*>(elements + N);
  169. }
  170. constexpr inline std::reverse_iterator<const element_type*> rbegin() const noexcept
  171. {
  172. return std::reverse_iterator<const element_type*>(elements + N);
  173. }
  174. constexpr inline std::reverse_iterator<const element_type*> crbegin() const noexcept
  175. {
  176. return std::reverse_iterator<const element_type*>(elements + N);
  177. }
  178. /// @}
  179. /// Returns a reverse iterator to the element following the last element of the reversed vector.
  180. /// @{
  181. constexpr inline std::reverse_iterator<element_type*> rend() noexcept
  182. {
  183. return std::reverse_iterator<element_type*>(elements);
  184. }
  185. constexpr inline std::reverse_iterator<const element_type*> rend() const noexcept
  186. {
  187. return std::reverse_iterator<const element_type*>(elements);
  188. }
  189. constexpr inline std::reverse_iterator<const element_type*> crend() const noexcept
  190. {
  191. return std::reverse_iterator<const element_type*>(elements);
  192. }
  193. /// @}
  194. /// Returns the number of elements in the vector.
  195. constexpr inline std::size_t size() const noexcept
  196. {
  197. return N;
  198. };
  199. /// @private
  200. template <class U, std::size_t... I>
  201. constexpr inline vector<U, N> type_cast(std::index_sequence<I...>) const noexcept
  202. {
  203. return {static_cast<U>(elements[I])...};
  204. }
  205. /**
  206. * Type-casts the elements of this vector.
  207. *
  208. * @tparam U Target element type.
  209. *
  210. * @return Vector containing the type-casted elements.
  211. */
  212. template <class U>
  213. constexpr inline explicit operator vector<U, N>() const noexcept
  214. {
  215. return type_cast<U>(std::make_index_sequence<N>{});
  216. }
  217. /// @private
  218. template <std::size_t M, std::size_t... I>
  219. constexpr inline vector<T, M> size_cast(std::index_sequence<I...>) const noexcept
  220. {
  221. return {(I < N) ? elements[I] : T{0} ...};
  222. }
  223. /**
  224. * Size-casts this vector to a vector with a different number of elements. Casting to a greater number of elements causes new elements to be set to `0`.
  225. *
  226. * @tparam M Target number of elements.
  227. *
  228. * @return Vector containing the type-casted elements.
  229. */
  230. template <std::size_t M>
  231. constexpr inline explicit operator vector<T, M>() const noexcept
  232. {
  233. return size_cast<M>(std::make_index_sequence<M>{});
  234. }
  235. };
  236. // Ensure vector is a POD type
  237. static_assert(std::is_standard_layout<vector<float, 3>>::value, "Vector is not a standard-layout type.");
  238. static_assert(std::is_trivial<vector<float, 3>>::value, "Vector is not a trivial type.");
  239. static_assert(sizeof(vector<float, 3>) == sizeof(float) * 3, "Vector size is greater than the size of its elements.");
  240. /// Vector with two elements.
  241. template <typename T>
  242. using vector2 = vector<T, 2>;
  243. /// Vector with three elements.
  244. template <typename T>
  245. using vector3 = vector<T, 3>;
  246. /// Vector with four elements.
  247. template <typename T>
  248. using vector4 = vector<T, 4>;
  249. /**
  250. * Returns the absolute values of each element.
  251. *
  252. * @param x Input vector
  253. * @return Absolute values of input vector elements.
  254. */
  255. template <class T, std::size_t N>
  256. constexpr vector<T, N> abs(const vector<T, N>& x);
  257. /**
  258. * Adds two values.
  259. *
  260. * @param x First value.
  261. * @param y Second value.
  262. * @return Sum of the two values.
  263. */
  264. /// @{
  265. template <class T, std::size_t N>
  266. constexpr vector<T, N> add(const vector<T, N>& x, const vector<T, N>& y);
  267. template <class T, std::size_t N>
  268. constexpr vector<T, N> add(const vector<T, N>& x, T y);
  269. /// @}
  270. /**
  271. * Checks if all elements of a boolean vector are `true`.
  272. *
  273. * @param x Vector to be tested for truth.
  274. * @return `true` if all elements are `true`, `false` otherwise.
  275. */
  276. template <std::size_t N>
  277. constexpr bool all(const vector<bool, N>& x);
  278. /**
  279. * Checks if any elements of a boolean vector are `true`.
  280. *
  281. * @param x Vector to be tested for truth.
  282. * @return `true` if any elements are `true`, `false` otherwise.
  283. */
  284. template <std::size_t N>
  285. constexpr bool any(const vector<bool, N>& x);
  286. /**
  287. * Reinterprets data as an *n*-dimensional vector of type `T`.
  288. *
  289. * @param data Data to reinterpret.
  290. */
  291. template <std::size_t N, typename T>
  292. constexpr vector<T, N>& as_vector(T& data);
  293. /**
  294. * Performs a element-wise ceil operation.
  295. *
  296. * @param x Input vector
  297. * @return Component-wise ceil of input vector.
  298. */
  299. template <class T, std::size_t N>
  300. constexpr vector<T, N> ceil(const vector<T, N>& x);
  301. /**
  302. * Clamps the values of a vector's elements.
  303. *
  304. * @param x Vector to clamp.
  305. * @param min_val Minimum value.
  306. * @param max_val Maximum value.
  307. * @return Clamped vector.
  308. */
  309. /// @{
  310. template <class T, std::size_t N>
  311. constexpr vector<T, N> clamp(const vector<T, N>& x, const vector<T, N>& min_val, const vector<T, N>& max_val);
  312. template <class T, std::size_t N>
  313. constexpr vector<T, N> clamp(const vector<T, N>& x, T min_val, T max_val);
  314. /// @}
  315. /**
  316. * Clamps the length of a vector.
  317. *
  318. * @param x Vector to clamp.
  319. * @param max_length Maximum length.
  320. * @return Length-clamped vector.
  321. */
  322. template <class T, std::size_t N>
  323. vector<T, N> clamp_length(const vector<T, N>& x, T max_length);
  324. /**
  325. * Calculate the cross product of two vectors.
  326. *
  327. * @param x First vector.
  328. * @param y Second vector.
  329. * @return Cross product of the two vectors.
  330. */
  331. template <class T>
  332. constexpr vector<T, 3> cross(const vector<T, 3>& x, const vector<T, 3>& y);
  333. /**
  334. * Calculates the distance between two points.
  335. *
  336. * @param p0 First of two points.
  337. * @param p1 Second of two points.
  338. * @return Distance between the two points.
  339. */
  340. template <class T, std::size_t N>
  341. T distance(const vector<T, N>& p0, const vector<T, N>& p1);
  342. /**
  343. * Calculates the squared distance between two points. The squared distance can be calculated faster than the distance because a call to `std::sqrt` is saved.
  344. *
  345. * @param p0 First of two points.
  346. * @param p1 Second of two points.
  347. * @return Squared distance between the two points.
  348. */
  349. template <class T, std::size_t N>
  350. constexpr T distance_squared(const vector<T, N>& p0, const vector<T, N>& p1);
  351. /**
  352. * Divides a vector by a value.
  353. *
  354. * @param x First value.
  355. * @param y Second value.
  356. * @return Result of the division.
  357. */
  358. /// @{
  359. template <class T, std::size_t N>
  360. constexpr vector<T, N> div(const vector<T, N>& x, const vector<T, N>& y);
  361. template <class T, std::size_t N>
  362. constexpr vector<T, N> div(const vector<T, N>& x, T y);
  363. /// @}
  364. /**
  365. * Calculates the dot product of two vectors.
  366. *
  367. * @param x First vector.
  368. * @param y Second vector.
  369. * @return Dot product of the two vectors.
  370. */
  371. template <class T, std::size_t N>
  372. constexpr T dot(const vector<T, N>& x, const vector<T, N>& y);
  373. /**
  374. * Compares two vectors for equality
  375. *
  376. * @param x First vector.
  377. * @param y Second vector.
  378. * @return Boolean vector containing the result of the element comparisons.
  379. */
  380. template <class T, std::size_t N>
  381. constexpr vector<bool, N> equal(const vector<T, N>& x, const vector<T, N>& y);
  382. /**
  383. * Performs a element-wise floor operation.
  384. *
  385. * @param x Input vector
  386. * @return Component-wise floor of input vector.
  387. */
  388. template <class T, std::size_t N>
  389. constexpr vector<T, N> floor(const vector<T, N>& x);
  390. /**
  391. * Performs a multiply-add operation.
  392. *
  393. * @param x Input vector
  394. * @param y Value to multiply.
  395. * @param z Value to add.
  396. *
  397. * @return Vector containing the multiply-add results.
  398. */
  399. /// @{
  400. template <class T, std::size_t N>
  401. constexpr vector<T, N> fma(const vector<T, N>& x, const vector<T, N>& y, const vector<T, N>& z);
  402. template <class T, std::size_t N>
  403. constexpr vector<T, N> fma(const vector<T, N>& x, T y, T z);
  404. /// @}
  405. /**
  406. * Returns a vector containing the fractional part of each element.
  407. *
  408. * @param x Input vector
  409. * @return Fractional parts of input vector.
  410. */
  411. template <class T, std::size_t N>
  412. constexpr vector<T, N> fract(const vector<T, N>& x);
  413. /**
  414. * Performs a element-wise greater-than comparison of two vectors.
  415. *
  416. * @param x First vector.
  417. * @param y Second vector.
  418. * @return Boolean vector containing the result of the element comparisons.
  419. */
  420. template <class T, std::size_t N>
  421. constexpr vector<bool, N> greater_than(const vector<T, N>& x, const vector<T, N>& y);
  422. /**
  423. * Performs a element-wise greater-than or equal-to comparison of two vectors.
  424. *
  425. * @param x First vector.
  426. * @param y Second vector.
  427. * @return Boolean vector containing the result of the element comparisons.
  428. */
  429. template <class T, std::size_t N>
  430. constexpr vector<bool, N> greater_than_equal(const vector<T, N>& x, const vector<T, N>& y);
  431. /**
  432. * Calculates the length of a vector.
  433. *
  434. * @param x Vector of which to calculate the length.
  435. * @return Length of the vector.
  436. */
  437. template <class T, std::size_t N>
  438. T length(const vector<T, N>& x);
  439. /**
  440. * Calculates the squared length of a vector. The squared length can be calculated faster than the length because a call to `std::sqrt` is saved.
  441. *
  442. * @param x Vector of which to calculate the squared length.
  443. * @return Squared length of the vector.
  444. */
  445. template <class T, std::size_t N>
  446. constexpr T length_squared(const vector<T, N>& x);
  447. /**
  448. * Performs a element-wise less-than comparison of two vectors.
  449. *
  450. * @param x First vector.
  451. * @param y Second vector.
  452. * @return Boolean vector containing the result of the element comparisons.
  453. */
  454. template <class T, std::size_t N>
  455. constexpr vector<bool, N> less_than(const vector<T, N>& x, const vector<T, N>& y);
  456. /**
  457. * Performs a element-wise less-than or equal-to comparison of two vectors.
  458. *
  459. * @param x First vector.
  460. * @param y Second vector.
  461. * @return Boolean vector containing the result of the element comparisons.
  462. */
  463. template <class T, std::size_t N>
  464. constexpr vector<bool, N> less_than_equal(const vector<T, N>& x, const vector<T, N>& y);
  465. /**
  466. * Returns the value of the greatest element in a vector.
  467. *
  468. * @param x Input vector.
  469. *
  470. * @return Value of the greatest element in the input vector.
  471. */
  472. template <class T, std::size_t N>
  473. constexpr T max(const vector<T, N>& x);
  474. /**
  475. * Returns the value of the smallest element in a vector.
  476. *
  477. * @param x Input vector.
  478. *
  479. * @return Value of the smallest element in the input vector.
  480. */
  481. template <class T, std::size_t N>
  482. constexpr T min(const vector<T, N>& x);
  483. /**
  484. * Calculates the element-wise remainder of the division operation `x / y`.
  485. *
  486. * @param x First vector.
  487. * @param y Second vector.
  488. * @return Remainders of `x / y`.
  489. */
  490. /// @{
  491. template <class T, std::size_t N>
  492. constexpr vector<T, N> mod(const vector<T, N>& x, const vector<T, N>& y);
  493. template <class T, std::size_t N>
  494. constexpr vector<T, N> mod(const vector<T, N>& x, T y);
  495. /// @}
  496. /**
  497. * Multiplies two values.
  498. *
  499. * @param x First value.
  500. * @param y Second value.
  501. * @return Product of the two values.
  502. */
  503. /// @{
  504. template <class T, std::size_t N>
  505. constexpr vector<T, N> mul(const vector<T, N>& x, const vector<T, N>& y);
  506. template <class T, std::size_t N>
  507. constexpr vector<T, N> mul(const vector<T, N>& x, T y);
  508. /// @}
  509. /**
  510. * Negates a vector.
  511. *
  512. * @param x Vector to negate.
  513. * @return Negated vector.
  514. */
  515. template <class T, std::size_t N>
  516. constexpr vector<T, N> negate(const vector<T, N>& x);
  517. /**
  518. * Calculates the unit vector in the same direction as the original vector.
  519. *
  520. * @param x Vector to normalize.
  521. * @return Normalized vector.
  522. */
  523. template <class T, std::size_t N>
  524. vector<T, N> normalize(const vector<T, N>& x);
  525. /**
  526. * Logically inverts a boolean vector.
  527. *
  528. * @param x Vector to be inverted.
  529. * @return Logically inverted vector.
  530. */
  531. template <class T, std::size_t N>
  532. constexpr vector<bool, N> not(const vector<T, N>& x);
  533. /**
  534. * Compares two vectors for inequality
  535. *
  536. * @param x First vector.
  537. * @param y Second vector.
  538. * @return Boolean vector containing the result of the element comparisons.
  539. */
  540. template <class T, std::size_t N>
  541. constexpr vector<bool, N> not_equal(const vector<T, N>& x, const vector<T, N>& y);
  542. /**
  543. * Resizes a vector. Any new elements will be set to `0`.
  544. *
  545. * @tparam M Target number of elements.
  546. *
  547. * @param x Vector to resize.
  548. *
  549. * @return Resized vector.
  550. */
  551. template <std::size_t M, class T, std::size_t N>
  552. constexpr vector<T, M> resize(const vector<T, N>& x);
  553. /**
  554. * Performs a element-wise round operation.
  555. *
  556. * @param x Input vector
  557. * @return Component-wise round of input vector.
  558. */
  559. template <class T, std::size_t N>
  560. constexpr vector<T, N> round(const vector<T, N>& x);
  561. /**
  562. * Returns a vector containing the signs of each element.
  563. *
  564. * @param x Input vector
  565. * @return Signs of input vector elements.
  566. */
  567. template <class T, std::size_t N>
  568. constexpr vector<T, N> sign(const vector<T, N>& x);
  569. /**
  570. * Subtracts a value by another value.
  571. *
  572. * @param x First value.
  573. * @param y Second value.
  574. * @return Difference between the two values.
  575. */
  576. /// @{
  577. template <class T, std::size_t N>
  578. constexpr vector<T, N> sub(const vector<T, N>& x, const vector<T, N>& y);
  579. template <class T, std::size_t N>
  580. constexpr vector<T, N> sub(const vector<T, N>& x, T y);
  581. /// @}
  582. /**
  583. * Calculates the sum of all elements in a vector.
  584. *
  585. * @param x Vector to sum.
  586. * @return Sum of the vector's elements.
  587. */
  588. template <class T, std::size_t N>
  589. constexpr T sum(const vector<T, N>& x);
  590. /**
  591. * Makes an *m*-dimensional vector by rearranging and/or duplicating elements of an *n*-dimensional vector.
  592. *
  593. * @tparam Indices List of indices of elements in @p x.
  594. * @tparam T Vector element type.
  595. * @tparam N Number of dimensions in @p x.
  596. *
  597. * @param x Vector to swizzle.
  598. *
  599. * @return Vector containing elements from @p x in the order specified by @p Indices. The size of the returned vector is equivalent to the number of indices in @p Indices.
  600. */
  601. template <std::size_t... Indices, class T, std::size_t N>
  602. constexpr vector<T, sizeof...(Indices)> swizzle(const vector<T, N>& x);
  603. /**
  604. * Performs a element-wise trunc operation.
  605. *
  606. * @param x Input vector
  607. * @return Component-wise trunc of input vector.
  608. */
  609. template <class T, std::size_t N>
  610. constexpr vector<T, N> trunc(const vector<T, N>& x);
  611. /**
  612. * Types casts each vector element and returns a vector of the casted type.
  613. *
  614. * @tparam U Target vector element type.
  615. * @tparam T Source vector element type.
  616. * @tparam N Number of dimensions.
  617. * @param x Vector to type cast.
  618. *
  619. * @return Type-casted vector.
  620. */
  621. template <class U, class T, std::size_t N>
  622. constexpr vector<U, N> type_cast(const vector<T, N>& x);
  623. /// @private
  624. template <class T, std::size_t N, std::size_t... I>
  625. constexpr inline vector<T, N> abs(const vector<T, N>& x, std::index_sequence<I...>)
  626. {
  627. return {std::abs(x[I])...};
  628. }
  629. template <class T, std::size_t N>
  630. constexpr inline vector<T, N> abs(const vector<T, N>& x)
  631. {
  632. return abs(x, std::make_index_sequence<N>{});
  633. }
  634. /// @private
  635. template <class T, std::size_t N, std::size_t... I>
  636. constexpr inline vector<T, N> add(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
  637. {
  638. return {(x[I] + y[I])...};
  639. }
  640. template <class T, std::size_t N>
  641. constexpr inline vector<T, N> add(const vector<T, N>& x, const vector<T, N>& y)
  642. {
  643. return add(x, y, std::make_index_sequence<N>{});
  644. }
  645. /// @private
  646. template <class T, std::size_t N, std::size_t... I>
  647. constexpr inline vector<T, N> add(const vector<T, N>& x, T y, std::index_sequence<I...>)
  648. {
  649. return {(x[I] + y)...};
  650. }
  651. template <class T, std::size_t N>
  652. constexpr inline vector<T, N> add(const vector<T, N>& x, T y)
  653. {
  654. return add(x, y, std::make_index_sequence<N>{});
  655. }
  656. /// @private
  657. template <std::size_t N, std::size_t... I>
  658. constexpr inline bool all(const vector<bool, N>& x, std::index_sequence<I...>)
  659. {
  660. return (x[I] && ...);
  661. }
  662. template <std::size_t N>
  663. constexpr inline bool all(const vector<bool, N>& x)
  664. {
  665. return all(x, std::make_index_sequence<N>{});
  666. }
  667. /// @private
  668. template <std::size_t N, std::size_t... I>
  669. constexpr inline bool any(const vector<bool, N>& x, std::index_sequence<I...>)
  670. {
  671. return (x[I] || ...);
  672. }
  673. template <std::size_t N>
  674. constexpr inline bool any(const vector<bool, N>& x)
  675. {
  676. return any(x, std::make_index_sequence<N>{});
  677. }
  678. template <std::size_t N, typename T>
  679. constexpr inline vector<T, N>& as_vector(T& data)
  680. {
  681. static_assert(std::is_pod<vector<T, N>>::value);
  682. return reinterpret_cast<vector<T, N>&>(data);
  683. }
  684. /// @private
  685. template <class T, std::size_t N, std::size_t... I>
  686. constexpr inline vector<T, N> ceil(const vector<T, N>& x, std::index_sequence<I...>)
  687. {
  688. return {std::ceil(x[I])...};
  689. }
  690. template <class T, std::size_t N>
  691. constexpr inline vector<T, N> ceil(const vector<T, N>& x)
  692. {
  693. static_assert(std::is_floating_point<T>::value);
  694. return ceil(x, std::make_index_sequence<N>{});
  695. }
  696. /// @private
  697. template <class T, std::size_t N, std::size_t... I>
  698. constexpr inline vector<T, N> clamp(const vector<T, N>& x, const vector<T, N>& min_val, const vector<T, N>& max_val, std::index_sequence<I...>)
  699. {
  700. return {std::min<T>(max_val[I], std::max<T>(min_val[I], x[I]))...};
  701. }
  702. template <class T, std::size_t N>
  703. constexpr inline vector<T, N> clamp(const vector<T, N>& x, const vector<T, N>& min_val, const vector<T, N>& max_val)
  704. {
  705. return clamp(x, min_val, max_val, std::make_index_sequence<N>{});
  706. }
  707. /// @private
  708. template <class T, std::size_t N, std::size_t... I>
  709. constexpr inline vector<T, N> clamp(const vector<T, N>& x, T min_val, T max_val, std::index_sequence<I...>)
  710. {
  711. return {std::min<T>(max_val, std::max<T>(min_val, x[I]))...};
  712. }
  713. template <class T, std::size_t N>
  714. constexpr inline vector<T, N> clamp(const vector<T, N>& x, T min_val, T max_val)
  715. {
  716. return clamp(x, min_val, max_val, std::make_index_sequence<N>{});
  717. }
  718. template <class T, std::size_t N>
  719. vector<T, N> clamp_length(const vector<T, N>& x, T max_length)
  720. {
  721. static_assert(std::is_floating_point<T>::value);
  722. T length2 = length_squared(x);
  723. return (length2 > max_length * max_length) ? (x * max_length / std::sqrt(length2)) : x;
  724. }
  725. template <class T>
  726. constexpr inline vector<T, 3> cross(const vector<T, 3>& x, const vector<T, 3>& y)
  727. {
  728. return
  729. {
  730. x[1] * y[2] - y[1] * x[2],
  731. x[2] * y[0] - y[2] * x[0],
  732. x[0] * y[1] - y[0] * x[1]
  733. };
  734. }
  735. template <class T, std::size_t N>
  736. inline T distance(const vector<T, N>& p0, const vector<T, N>& p1)
  737. {
  738. static_assert(std::is_floating_point<T>::value);
  739. return length(sub(p0, p1));
  740. }
  741. template <class T, std::size_t N>
  742. constexpr inline T distance_squared(const vector<T, N>& p0, const vector<T, N>& p1)
  743. {
  744. static_assert(std::is_floating_point<T>::value);
  745. return length_squared(sub(p0, p1));
  746. }
  747. /// @private
  748. template <class T, std::size_t N, std::size_t... I>
  749. constexpr inline vector<T, N> div(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
  750. {
  751. return {(x[I] / y[I])...};
  752. }
  753. template <class T, std::size_t N>
  754. constexpr inline vector<T, N> div(const vector<T, N>& x, const vector<T, N>& y)
  755. {
  756. return div(x, y, std::make_index_sequence<N>{});
  757. }
  758. /// @private
  759. template <class T, std::size_t N, std::size_t... I>
  760. constexpr inline vector<T, N> div(const vector<T, N>& x, T y, std::index_sequence<I...>)
  761. {
  762. return {(x[I] / y)...};
  763. }
  764. template <class T, std::size_t N>
  765. constexpr inline vector<T, N> div(const vector<T, N>& x, T y)
  766. {
  767. return div(x, y, std::make_index_sequence<N>{});
  768. }
  769. /// @private
  770. template <class T, std::size_t N, std::size_t... I>
  771. constexpr inline T dot(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
  772. {
  773. return ((x[I] * y[I]) + ...);
  774. }
  775. template <class T, std::size_t N>
  776. constexpr inline T dot(const vector<T, N>& x, const vector<T, N>& y)
  777. {
  778. return dot(x, y, std::make_index_sequence<N>{});
  779. }
  780. /// @private
  781. template <class T, std::size_t N, std::size_t... I>
  782. constexpr inline vector<bool, N> equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
  783. {
  784. return {(x[I] == y[I])...};
  785. }
  786. template <class T, std::size_t N>
  787. constexpr inline vector<bool, N> equal(const vector<T, N>& x, const vector<T, N>& y)
  788. {
  789. return equal(x, y, std::make_index_sequence<N>{});
  790. }
  791. /// @private
  792. template <class T, std::size_t N, std::size_t... I>
  793. constexpr inline vector<T, N> floor(const vector<T, N>& x, std::index_sequence<I...>)
  794. {
  795. return {std::floor(x[I])...};
  796. }
  797. template <class T, std::size_t N>
  798. constexpr inline vector<T, N> floor(const vector<T, N>& x)
  799. {
  800. static_assert(std::is_floating_point<T>::value);
  801. return floor(x, std::make_index_sequence<N>{});
  802. }
  803. /// @private
  804. template <class T, std::size_t N, std::size_t... I>
  805. constexpr inline vector<T, N> fma(const vector<T, N>& x, const vector<T, N>& y, const vector<T, N>& z, std::index_sequence<I...>)
  806. {
  807. return {std::fma(x[I], y[I], z[I])...};
  808. }
  809. template <class T, std::size_t N>
  810. constexpr inline vector<T, N> fma(const vector<T, N>& x, const vector<T, N>& y, const vector<T, N>& z)
  811. {
  812. static_assert(std::is_floating_point<T>::value);
  813. return fma(x, y, z, std::make_index_sequence<N>{});
  814. }
  815. /// @private
  816. template <class T, std::size_t N, std::size_t... I>
  817. constexpr inline vector<T, N> fma(const vector<T, N>& x, T y, T z, std::index_sequence<I...>)
  818. {
  819. return {std::fma(x[I], y, z)...};
  820. }
  821. template <class T, std::size_t N>
  822. constexpr inline vector<T, N> fma(const vector<T, N>& x, T y, T z)
  823. {
  824. static_assert(std::is_floating_point<T>::value);
  825. return fma(x, y, z, std::make_index_sequence<N>{});
  826. }
  827. /// @private
  828. template <class T, std::size_t N, std::size_t... I>
  829. constexpr inline vector<T, N> fract(const vector<T, N>& x, std::index_sequence<I...>)
  830. {
  831. return {x[I] - std::floor(x[I])...};
  832. }
  833. template <class T, std::size_t N>
  834. constexpr inline vector<T, N> fract(const vector<T, N>& x)
  835. {
  836. static_assert(std::is_floating_point<T>::value);
  837. return fract(x, std::make_index_sequence<N>{});
  838. }
  839. /// @private
  840. template <class T, std::size_t N, std::size_t... I>
  841. constexpr inline vector<bool, N> greater_than(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
  842. {
  843. return {(x[I] > y[I])...};
  844. }
  845. template <class T, std::size_t N>
  846. constexpr inline vector<bool, N> greater_than(const vector<T, N>& x, const vector<T, N>& y)
  847. {
  848. return greater_than(x, y, std::make_index_sequence<N>{});
  849. }
  850. /// @private
  851. template <class T, std::size_t N, std::size_t... I>
  852. constexpr inline vector<bool, N> greater_than_equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
  853. {
  854. return {(x[I] >= y[I])...};
  855. }
  856. template <class T, std::size_t N>
  857. constexpr inline vector<bool, N> greater_than_equal(const vector<T, N>& x, const vector<T, N>& y)
  858. {
  859. return greater_than_equal(x, y, std::make_index_sequence<N>{});
  860. }
  861. template <class T, std::size_t N>
  862. inline T length(const vector<T, N>& x)
  863. {
  864. static_assert(std::is_floating_point<T>::value);
  865. return std::sqrt(dot(x, x));
  866. }
  867. template <class T, std::size_t N>
  868. constexpr inline T length_squared(const vector<T, N>& x)
  869. {
  870. return dot(x, x);
  871. }
  872. /// @private
  873. template <class T, std::size_t N, std::size_t... I>
  874. constexpr inline vector<bool, N> less_than(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
  875. {
  876. return {(x[I] < y[I])...};
  877. }
  878. template <class T, std::size_t N>
  879. constexpr inline vector<bool, N> less_than(const vector<T, N>& x, const vector<T, N>& y)
  880. {
  881. return less_than(x, y, std::make_index_sequence<N>{});
  882. }
  883. /// @private
  884. template <class T, std::size_t N, std::size_t... I>
  885. constexpr inline vector<bool, N> less_than_equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
  886. {
  887. return {(x[I] <= y[I])...};
  888. }
  889. template <class T, std::size_t N>
  890. constexpr inline vector<bool, N> less_than_equal(const vector<T, N>& x, const vector<T, N>& y)
  891. {
  892. return less_than_equal(x, y, std::make_index_sequence<N>{});
  893. }
  894. template <class T, std::size_t N>
  895. constexpr inline T max(const vector<T, N>& x)
  896. {
  897. return *std::max_element(x.elements, x.elements + N);
  898. }
  899. template <class T, std::size_t N>
  900. constexpr inline T min(const vector<T, N>& x)
  901. {
  902. return *std::min_element(x.elements, x.elements + N);
  903. }
  904. /// @private
  905. template <class T, std::size_t N, std::size_t... I>
  906. constexpr inline vector<T, N> mod(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
  907. {
  908. return {std::fmod(x[I], y[I])...};
  909. }
  910. template <class T, std::size_t N>
  911. constexpr inline vector<T, N> mod(const vector<T, N>& x, const vector<T, N>& y)
  912. {
  913. static_assert(std::is_floating_point<T>::value);
  914. return mod(x, y, std::make_index_sequence<N>{});
  915. }
  916. /// @private
  917. template <class T, std::size_t N, std::size_t... I>
  918. constexpr inline vector<T, N> mod(const vector<T, N>& x, T y, std::index_sequence<I...>)
  919. {
  920. return {std::fmod(x[I], y)...};
  921. }
  922. template <class T, std::size_t N>
  923. constexpr inline vector<T, N> mod(const vector<T, N>& x, T y)
  924. {
  925. static_assert(std::is_floating_point<T>::value);
  926. return mod(x, y, std::make_index_sequence<N>{});
  927. }
  928. /// @private
  929. template <class T, std::size_t N, std::size_t... I>
  930. constexpr inline vector<T, N> mul(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
  931. {
  932. return {(x[I] * y[I])...};
  933. }
  934. template <class T, std::size_t N>
  935. constexpr inline vector<T, N> mul(const vector<T, N>& x, const vector<T, N>& y)
  936. {
  937. return mul(x, y, std::make_index_sequence<N>{});
  938. }
  939. /// @private
  940. template <class T, std::size_t N, std::size_t... I>
  941. constexpr inline vector<T, N> mul(const vector<T, N>& x, T y, std::index_sequence<I...>)
  942. {
  943. return {(x[I] * y)...};
  944. }
  945. template <class T, std::size_t N>
  946. constexpr inline vector<T, N> mul(const vector<T, N>& x, T y)
  947. {
  948. return mul(x, y, std::make_index_sequence<N>{});
  949. }
  950. /// @private
  951. template <class T, std::size_t N, std::size_t... I>
  952. constexpr inline vector<T, N> negate(const vector<T, N>& x, std::index_sequence<I...>)
  953. {
  954. return {(-x[I])...};
  955. }
  956. template <class T, std::size_t N>
  957. constexpr inline vector<T, N> negate(const vector<T, N>& x)
  958. {
  959. return negate(x, std::make_index_sequence<N>{});
  960. }
  961. template <class T, std::size_t N>
  962. inline vector<T, N> normalize(const vector<T, N>& x)
  963. {
  964. static_assert(std::is_floating_point<T>::value);
  965. return mul(x, T(1) / length(x));
  966. }
  967. /// @private
  968. template <class T, std::size_t N, std::size_t... I>
  969. constexpr inline vector<bool, N> not(const vector<T, N>& x, std::index_sequence<I...>)
  970. {
  971. return {!x[I]...};
  972. }
  973. template <class T, std::size_t N>
  974. constexpr inline vector<bool, N> not(const vector<T, N>& x)
  975. {
  976. return not(x, std::make_index_sequence<N>{});
  977. }
  978. /// @private
  979. template <class T, std::size_t N, std::size_t... I>
  980. constexpr inline vector<bool, N> not_equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
  981. {
  982. return {(x[I] != y[I])...};
  983. }
  984. template <class T, std::size_t N>
  985. constexpr inline vector<bool, N> not_equal(const vector<T, N>& x, const vector<T, N>& y)
  986. {
  987. return not_equal(x, y, std::make_index_sequence<N>{});
  988. }
  989. /// @private
  990. template <std::size_t M, class T, std::size_t N, std::size_t... I>
  991. constexpr inline vector<T, M> resize(const vector<T, N>& x, std::index_sequence<I...>)
  992. {
  993. return {(I < N) ? x[I] : T{0} ...};
  994. }
  995. template <std::size_t M, class T, std::size_t N>
  996. constexpr inline vector<T, M> resize(const vector<T, N>& x)
  997. {
  998. return resize<M>(x, std::make_index_sequence<M>{});
  999. }
  1000. /// @private
  1001. template <class T, std::size_t N, std::size_t... I>
  1002. constexpr inline vector<T, N> round(const vector<T, N>& x, std::index_sequence<I...>)
  1003. {
  1004. return {std::round(x[I])...};
  1005. }
  1006. template <class T, std::size_t N>
  1007. constexpr inline vector<T, N> round(const vector<T, N>& x)
  1008. {
  1009. static_assert(std::is_floating_point<T>::value);
  1010. return round(x, std::make_index_sequence<N>{});
  1011. }
  1012. /// @private
  1013. template <class T, std::size_t N, std::size_t... I>
  1014. constexpr inline vector<T, N> sign(const vector<T, N>& x, std::index_sequence<I...>)
  1015. {
  1016. return {std::copysign(T{1}, x[I])...};
  1017. }
  1018. template <class T, std::size_t N>
  1019. constexpr inline vector<T, N> sign(const vector<T, N>& x)
  1020. {
  1021. static_assert(std::is_floating_point<T>::value);
  1022. return sign(x, std::make_index_sequence<N>{});
  1023. }
  1024. /// @private
  1025. template <class T, std::size_t N, std::size_t... I>
  1026. constexpr inline vector<T, N> sub(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
  1027. {
  1028. return {(x[I] - y[I])...};
  1029. }
  1030. template <class T, std::size_t N>
  1031. constexpr inline vector<T, N> sub(const vector<T, N>& x, const vector<T, N>& y)
  1032. {
  1033. return sub(x, y, std::make_index_sequence<N>{});
  1034. }
  1035. /// @private
  1036. template <class T, std::size_t N, std::size_t... I>
  1037. constexpr inline vector<T, N> sub(const vector<T, N>& x, T y, std::index_sequence<I...>)
  1038. {
  1039. return {(x[I] - y)...};
  1040. }
  1041. template <class T, std::size_t N>
  1042. constexpr inline vector<T, N> sub(const vector<T, N>& x, T y)
  1043. {
  1044. return sub(x, y, std::make_index_sequence<N>{});
  1045. }
  1046. /// @private
  1047. template <class T, std::size_t N, std::size_t... I>
  1048. constexpr inline T sum(const vector<T, N>& x, std::index_sequence<I...>)
  1049. {
  1050. return (x[I] + ...);
  1051. }
  1052. template <class T, std::size_t N>
  1053. constexpr inline T sum(const vector<T, N>& x)
  1054. {
  1055. return sum(x, std::make_index_sequence<N>{});
  1056. }
  1057. template <std::size_t... Indices, class T, std::size_t N>
  1058. constexpr inline vector<T, sizeof...(Indices)> swizzle(const vector<T, N>& x)
  1059. {
  1060. return {x[Indices]...};
  1061. }
  1062. /// @private
  1063. template <class T, std::size_t N, std::size_t... I>
  1064. constexpr inline vector<T, N> trunc(const vector<T, N>& x, std::index_sequence<I...>)
  1065. {
  1066. return {std::trunc(x[I])...};
  1067. }
  1068. template <class T, std::size_t N>
  1069. constexpr inline vector<T, N> trunc(const vector<T, N>& x)
  1070. {
  1071. static_assert(std::is_floating_point<T>::value);
  1072. return trunc(x, std::make_index_sequence<N>{});
  1073. }
  1074. /// @private
  1075. template <class U, class T, std::size_t N, std::size_t... I>
  1076. constexpr inline vector<U, N> type_cast(const vector<T, N>& x, std::index_sequence<I...>)
  1077. {
  1078. return {static_cast<U>(x[I])...};
  1079. }
  1080. template <class U, class T, std::size_t N>
  1081. constexpr inline vector<U, N> type_cast(const vector<T, N>& x)
  1082. {
  1083. return type_cast<U>(x, std::make_index_sequence<N>{});
  1084. }
  1085. } // namespace math
  1086. /// @copydoc math::add(const math::vector<T, N>&, const math::vector<T, N>&)
  1087. template <class T, std::size_t N>
  1088. constexpr math::vector<T, N> operator+(const math::vector<T, N>& x, const math::vector<T, N>& y);
  1089. /// @copydoc math::add(const math::vector<T, N>&, T)
  1090. /// @{
  1091. template <class T, std::size_t N>
  1092. constexpr math::vector<T, N> operator+(const math::vector<T, N>& x, T y);
  1093. template <class T, std::size_t N>
  1094. constexpr math::vector<T, N> operator+(T x, const math::vector<T, N>& y);
  1095. /// @}
  1096. /// @copydoc math::div(const math::vector<T, N>&, const math::vector<T, N>&)
  1097. template <class T, std::size_t N>
  1098. constexpr math::vector<T, N> operator/(const math::vector<T, N>& x, const math::vector<T, N>& y);
  1099. /// @copydoc math::div(const math::vector<T, N>&, T y)
  1100. template <class T, std::size_t N>
  1101. constexpr math::vector<T, N> operator/(const math::vector<T, N>& x, T y);
  1102. /// @copydoc math::mul(const math::vector<T, N>&, const math::vector<T, N>&)
  1103. template <class T, std::size_t N>
  1104. constexpr math::vector<T, N> operator*(const math::vector<T, N>& x, const math::vector<T, N>& y);
  1105. /// @copydoc math::mul(const math::vector<T, N>&, T)
  1106. /// @{
  1107. template <class T, std::size_t N>
  1108. constexpr math::vector<T, N> operator*(const math::vector<T, N>& x, T y);
  1109. template <class T, std::size_t N>
  1110. constexpr math::vector<T, N> operator*(T x, const math::vector<T, N>& y);
  1111. /// @}
  1112. /// @copydoc math::negate(const math::vector<T, N>&)
  1113. template <class T, std::size_t N>
  1114. constexpr math::vector<T, N> operator-(const math::vector<T, N>& x);
  1115. /// @copydoc math::sub(const math::vector<T, N>&, const math::vector<T, N>&)
  1116. template <class T, std::size_t N>
  1117. constexpr math::vector<T, N> operator-(const math::vector<T, N>& x, const math::vector<T, N>& y);
  1118. /// @copydoc math::sub(const math::vector<T, N>&, T)
  1119. template <class T, std::size_t N>
  1120. constexpr math::vector<T, N> operator-(const math::vector<T, N>& x, T y);
  1121. /**
  1122. * Adds two values and stores the result in the first value.
  1123. *
  1124. * @param x First value.
  1125. * @param y Second value.
  1126. * @return Reference to the first value.
  1127. */
  1128. /// @{
  1129. template <class T, std::size_t N>
  1130. constexpr math::vector<T, N>& operator+=(math::vector<T, N>& x, const math::vector<T, N>& y);
  1131. template <class T, std::size_t N>
  1132. constexpr math::vector<T, N>& operator+=(math::vector<T, N>& x, T y);
  1133. /// @}
  1134. /**
  1135. * Subtracts the first value by the second value and stores the result in the first value.
  1136. *
  1137. * @param x First value.
  1138. * @param y Second value.
  1139. * @return Reference to the first value.
  1140. */
  1141. /// @{
  1142. template <class T, std::size_t N>
  1143. constexpr math::vector<T, N>& operator-=(math::vector<T, N>& x, const math::vector<T, N>& y);
  1144. template <class T, std::size_t N>
  1145. constexpr math::vector<T, N>& operator-=(math::vector<T, N>& x, T y);
  1146. /// @}
  1147. /**
  1148. * Multiplies two values and stores the result in the first value.
  1149. *
  1150. * @param x First value.
  1151. * @param y Second value.
  1152. * @return Reference to the first value.
  1153. */
  1154. /// @{
  1155. template <class T, std::size_t N>
  1156. constexpr math::vector<T, N>& operator*=(math::vector<T, N>& x, const math::vector<T, N>& y);
  1157. template <class T, std::size_t N>
  1158. constexpr math::vector<T, N>& operator*=(math::vector<T, N>& x, T y);
  1159. /// @}
  1160. /**
  1161. * Divides the first value by the second value and stores the result in the first value.
  1162. *
  1163. * @param x First value.
  1164. * @param y Second value.
  1165. * @return Reference to the first value.
  1166. */
  1167. /// @{
  1168. template <class T, std::size_t N>
  1169. constexpr math::vector<T, N>& operator/=(math::vector<T, N>& x, const math::vector<T, N>& y);
  1170. template <class T, std::size_t N>
  1171. constexpr math::vector<T, N>& operator/=(math::vector<T, N>& x, T y);
  1172. /// @}
  1173. /**
  1174. * Writes the elements of a vector to an output stream, with each element delimeted by a space.
  1175. *
  1176. * @param os Output stream.
  1177. * @param x Vector.
  1178. *
  1179. * @return Output stream.
  1180. */
  1181. template <class T, std::size_t N>
  1182. std::ostream& operator<<(std::ostream& os, const math::vector<T, N>& x);
  1183. /**
  1184. * Reads the elements of a vector from an input stream, with each element delimeted by a space.
  1185. *
  1186. * @param is Input stream.
  1187. * @param x Vector.
  1188. *
  1189. * @return Input stream.
  1190. */
  1191. template <class T, std::size_t N>
  1192. std::istream& operator>>(std::istream& is, math::vector<T, N>& v);
  1193. template <class T, std::size_t N>
  1194. constexpr inline math::vector<T, N> operator+(const math::vector<T, N>& x, const math::vector<T, N>& y)
  1195. {
  1196. return add(x, y);
  1197. }
  1198. template <class T, std::size_t N>
  1199. constexpr inline math::vector<T, N> operator+(const math::vector<T, N>& x, T y)
  1200. {
  1201. return add(x, y);
  1202. }
  1203. template <class T, std::size_t N>
  1204. constexpr inline math::vector<T, N> operator+(T x, const math::vector<T, N>& y)
  1205. {
  1206. return add(y, x);
  1207. }
  1208. template <class T, std::size_t N>
  1209. constexpr inline math::vector<T, N> operator-(const math::vector<T, N>& x)
  1210. {
  1211. return negate(x);
  1212. }
  1213. template <class T, std::size_t N>
  1214. constexpr inline math::vector<T, N> operator-(const math::vector<T, N>& x, const math::vector<T, N>& y)
  1215. {
  1216. return sub(x, y);
  1217. }
  1218. template <class T, std::size_t N>
  1219. constexpr inline math::vector<T, N> operator-(const math::vector<T, N>& x, T y)
  1220. {
  1221. return sub(x, y);
  1222. }
  1223. template <class T, std::size_t N>
  1224. constexpr inline math::vector<T, N> operator*(const math::vector<T, N>& x, const math::vector<T, N>& y)
  1225. {
  1226. return mul(x, y);
  1227. }
  1228. template <class T, std::size_t N>
  1229. constexpr inline math::vector<T, N> operator*(const math::vector<T, N>& x, T y)
  1230. {
  1231. return mul(x, y);
  1232. }
  1233. template <class T, std::size_t N>
  1234. constexpr inline math::vector<T, N> operator*(T x, const math::vector<T, N>& y)
  1235. {
  1236. return mul(y, x);
  1237. }
  1238. template <class T, std::size_t N>
  1239. constexpr inline math::vector<T, N> operator/(const math::vector<T, N>& x, const math::vector<T, N>& y)
  1240. {
  1241. return div(x, y);
  1242. }
  1243. template <class T, std::size_t N>
  1244. constexpr inline math::vector<T, N> operator/(const math::vector<T, N>& x, T y)
  1245. {
  1246. return div(x, y);
  1247. }
  1248. template <class T, std::size_t N>
  1249. constexpr inline math::vector<T, N>& operator+=(math::vector<T, N>& x, const math::vector<T, N>& y)
  1250. {
  1251. return (x = x + y);
  1252. }
  1253. template <class T, std::size_t N>
  1254. constexpr inline math::vector<T, N>& operator+=(math::vector<T, N>& x, T y)
  1255. {
  1256. return (x = x + y);
  1257. }
  1258. template <class T, std::size_t N>
  1259. constexpr inline math::vector<T, N>& operator-=(math::vector<T, N>& x, const math::vector<T, N>& y)
  1260. {
  1261. return (x = x - y);
  1262. }
  1263. template <class T, std::size_t N>
  1264. constexpr inline math::vector<T, N>& operator-=(math::vector<T, N>& x, T y)
  1265. {
  1266. return (x = x - y);
  1267. }
  1268. template <class T, std::size_t N>
  1269. constexpr inline math::vector<T, N>& operator*=(math::vector<T, N>& x, const math::vector<T, N>& y)
  1270. {
  1271. return (x = x * y);
  1272. }
  1273. template <class T, std::size_t N>
  1274. constexpr inline math::vector<T, N>& operator*=(math::vector<T, N>& x, T y)
  1275. {
  1276. return (x = x * y);
  1277. }
  1278. template <class T, std::size_t N>
  1279. constexpr inline math::vector<T, N>& operator/=(math::vector<T, N>& x, const math::vector<T, N>& y)
  1280. {
  1281. return (x = x / y);
  1282. }
  1283. template <class T, std::size_t N>
  1284. constexpr inline math::vector<T, N>& operator/=(math::vector<T, N>& x, T y)
  1285. {
  1286. return (x = x / y);
  1287. }
  1288. template <class T, std::size_t N>
  1289. std::ostream& operator<<(std::ostream& os, const math::vector<T, N>& x)
  1290. {
  1291. for (std::size_t i = 0; i < N; ++i)
  1292. {
  1293. if (i)
  1294. os << ' ';
  1295. os << x[i];
  1296. }
  1297. return os;
  1298. }
  1299. template <class T, std::size_t N>
  1300. std::istream& operator>>(std::istream& is, math::vector<T, N>& x)
  1301. {
  1302. for (std::size_t i = 0; i < N; ++i)
  1303. is >> x[i];
  1304. return is;
  1305. }
  1306. #endif // ANTKEEPER_MATH_VECTOR_HPP