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

1591 lines
41 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 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 vector 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 using `static_cast`.
  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 zero.
  225. *
  226. * @tparam M Target number of elements.
  227. *
  228. * @return *m*-dimensional vector.
  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. /// Returns a zero vector, where every element is equal to zero.
  236. static constexpr vector zero() noexcept
  237. {
  238. return {};
  239. }
  240. /// @private
  241. template <std::size_t... I>
  242. static constexpr vector one(std::index_sequence<I...>) noexcept
  243. {
  244. //return {T{1}...};
  245. // MSVC bug workaround (I must be referenced for parameter pack expansion)
  246. return {(I ? T{1} : T{1})...};
  247. }
  248. /// Returns a vector of ones, where every element is equal to one.
  249. static constexpr vector one() noexcept
  250. {
  251. return one(std::make_index_sequence<N>{});
  252. }
  253. };
  254. /// Vector with two elements.
  255. template <typename T>
  256. using vector2 = vector<T, 2>;
  257. /// Vector with three elements.
  258. template <typename T>
  259. using vector3 = vector<T, 3>;
  260. /// Vector with four elements.
  261. template <typename T>
  262. using vector4 = vector<T, 4>;
  263. /**
  264. * Returns the absolute values of each element.
  265. *
  266. * @param x Input vector.
  267. *
  268. * @return Absolute values of input vector elements.
  269. */
  270. template <class T, std::size_t N>
  271. constexpr vector<T, N> abs(const vector<T, N>& x);
  272. /**
  273. * Adds two values.
  274. *
  275. * @param x First value.
  276. * @param y Second value.
  277. *
  278. * @return Sum of the two values.
  279. */
  280. /// @{
  281. template <class T, std::size_t N>
  282. constexpr vector<T, N> add(const vector<T, N>& x, const vector<T, N>& y) noexcept;
  283. template <class T, std::size_t N>
  284. constexpr vector<T, N> add(const vector<T, N>& x, T y) noexcept;
  285. /// @}
  286. /**
  287. * Checks if all elements of a boolean vector are `true`.
  288. *
  289. * @param x Vector to be tested for truth.
  290. *
  291. * @return `true` if all elements are `true`, `false` otherwise.
  292. */
  293. template <std::size_t N>
  294. constexpr bool all(const vector<bool, N>& x) noexcept;
  295. /**
  296. * Checks if any elements of a boolean vector are `true`.
  297. *
  298. * @param x Vector to be tested for truth.
  299. *
  300. * @return `true` if any elements are `true`, `false` otherwise.
  301. */
  302. template <std::size_t N>
  303. constexpr bool any(const vector<bool, N>& x) noexcept;
  304. /**
  305. * Performs a element-wise ceil operation.
  306. *
  307. * @param x Input vector.
  308. *
  309. * @return Component-wise ceil of input vector.
  310. */
  311. template <class T, std::size_t N>
  312. constexpr vector<T, N> ceil(const vector<T, N>& x);
  313. /**
  314. * Clamps the values of a vector's elements.
  315. *
  316. * @param x Vector to clamp.
  317. * @param min Minimum value.
  318. * @param max Maximum value.
  319. *
  320. * @return Clamped vector.
  321. */
  322. /// @{
  323. template <class T, std::size_t N>
  324. constexpr vector<T, N> clamp(const vector<T, N>& x, const vector<T, N>& min, const vector<T, N>& max);
  325. template <class T, std::size_t N>
  326. constexpr vector<T, N> clamp(const vector<T, N>& x, T min, T max);
  327. /// @}
  328. /**
  329. * Clamps the length of a vector.
  330. *
  331. * @param x Vector to clamp.
  332. * @param max_length Maximum length.
  333. *
  334. * @return Length-clamped vector.
  335. */
  336. template <class T, std::size_t N>
  337. vector<T, N> clamp_length(const vector<T, N>& x, T max_length);
  338. /**
  339. * Calculate the cross product of two vectors.
  340. *
  341. * @param x First vector.
  342. * @param y Second vector.
  343. *
  344. * @return Cross product of the two vectors.
  345. */
  346. template <class T>
  347. constexpr vector<T, 3> cross(const vector<T, 3>& x, const vector<T, 3>& y) noexcept;
  348. /**
  349. * Calculates the distance between two points.
  350. *
  351. * @param p0 First of two points.
  352. * @param p1 Second of two points.
  353. *
  354. * @return Distance between the two points.
  355. */
  356. template <class T, std::size_t N>
  357. T distance(const vector<T, N>& p0, const vector<T, N>& p1);
  358. /**
  359. * Divides a vector by a value.
  360. *
  361. * @param x First value.
  362. * @param y Second value.
  363. *
  364. * @return Result of the division.
  365. */
  366. /// @{
  367. template <class T, std::size_t N>
  368. constexpr vector<T, N> div(const vector<T, N>& x, const vector<T, N>& y) noexcept;
  369. template <class T, std::size_t N>
  370. constexpr vector<T, N> div(const vector<T, N>& x, T y) noexcept;
  371. template <class T, std::size_t N>
  372. constexpr vector<T, N> div(T x, const vector<T, N>& y) noexcept;
  373. /// @}
  374. /**
  375. * Calculates the dot product of two vectors.
  376. *
  377. * @param x First vector.
  378. * @param y Second vector.
  379. *
  380. * @return Dot product of the two vectors.
  381. */
  382. template <class T, std::size_t N>
  383. constexpr T dot(const vector<T, N>& x, const vector<T, N>& y) noexcept;
  384. /**
  385. * Compares two vectors for equality
  386. *
  387. * @param x First vector.
  388. * @param y Second vector.
  389. *
  390. * @return Boolean vector containing the result of the element comparisons.
  391. */
  392. template <class T, std::size_t N>
  393. constexpr vector<bool, N> equal(const vector<T, N>& x, const vector<T, N>& y) noexcept;
  394. /**
  395. * Performs a element-wise floor operation.
  396. *
  397. * @param x Input vector.
  398. *
  399. * @return Component-wise floor of input vector.
  400. */
  401. template <class T, std::size_t N>
  402. constexpr vector<T, N> floor(const vector<T, N>& x);
  403. /**
  404. * Performs a multiply-add operation.
  405. *
  406. * @param x Input vector
  407. * @param y Value to multiply.
  408. * @param z Value to add.
  409. *
  410. * @return Vector containing the multiply-add results.
  411. */
  412. /// @{
  413. template <class T, std::size_t N>
  414. constexpr vector<T, N> fma(const vector<T, N>& x, const vector<T, N>& y, const vector<T, N>& z);
  415. template <class T, std::size_t N>
  416. constexpr vector<T, N> fma(const vector<T, N>& x, T y, T z);
  417. /// @}
  418. /**
  419. * Returns a vector containing the fractional part of each element.
  420. *
  421. * @param x Input vector.
  422. *
  423. * @return Fractional parts of input vector.
  424. */
  425. template <class T, std::size_t N>
  426. constexpr vector<T, N> fract(const vector<T, N>& x);
  427. /**
  428. * Performs a element-wise greater-than comparison of two vectors.
  429. *
  430. * @param x First vector.
  431. * @param y Second vector.
  432. *
  433. * @return Boolean vector containing the result of the element comparisons.
  434. */
  435. template <class T, std::size_t N>
  436. constexpr vector<bool, N> greater_than(const vector<T, N>& x, const vector<T, N>& y) noexcept;
  437. /**
  438. * Performs a element-wise greater-than or equal-to comparison of two vectors.
  439. *
  440. * @param x First vector.
  441. * @param y Second vector.
  442. *
  443. * @return Boolean vector containing the result of the element comparisons.
  444. */
  445. template <class T, std::size_t N>
  446. constexpr vector<bool, N> greater_than_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept;
  447. /**
  448. * Calculates the inverse length of a vector.
  449. *
  450. * @param x Vector of which to calculate the inverse length.
  451. *
  452. * @return Inverse length of the vector.
  453. */
  454. template <class T, std::size_t N>
  455. T inv_length(const vector<T, N>& x);
  456. /**
  457. * Calculates the length of a vector.
  458. *
  459. * @param x Vector of which to calculate the length.
  460. *
  461. * @return Length of the vector.
  462. */
  463. template <class T, std::size_t N>
  464. T length(const vector<T, N>& x);
  465. /**
  466. * Performs a element-wise less-than comparison of two vectors.
  467. *
  468. * @param x First vector.
  469. * @param y Second vector.
  470. *
  471. * @return Boolean vector containing the result of the element comparisons.
  472. */
  473. template <class T, std::size_t N>
  474. constexpr vector<bool, N> less_than(const vector<T, N>& x, const vector<T, N>& y) noexcept;
  475. /**
  476. * Performs a element-wise less-than or equal-to comparison of two vectors.
  477. *
  478. * @param x First vector.
  479. * @param y Second vector.
  480. *
  481. * @return Boolean vector containing the result of the element comparisons.
  482. */
  483. template <class T, std::size_t N>
  484. constexpr vector<bool, N> less_than_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept;
  485. /**
  486. * Returns a vector containing the maximum elements of two vectors.
  487. *
  488. * @param x First vector.
  489. * @param y Second vector.
  490. *
  491. * @return Maximum elements of the two vectors.
  492. */
  493. template <class T, std::size_t N>
  494. constexpr vector<T, N> max(const vector<T, N>& x, const vector<T, N>& y);
  495. /**
  496. * Returns the value of the greatest element in a vector.
  497. *
  498. * @param x Input vector.
  499. *
  500. * @return Value of the greatest element in the input vector.
  501. */
  502. template <class T, std::size_t N>
  503. constexpr T max(const vector<T, N>& x);
  504. /**
  505. * Returns a vector containing the minimum elements of two vectors.
  506. *
  507. * @param x First vector.
  508. * @param y Second vector.
  509. *
  510. * @return Minimum elements of the two vectors.
  511. */
  512. template <class T, std::size_t N>
  513. constexpr vector<T, N> min(const vector<T, N>& x, const vector<T, N>& y);
  514. /**
  515. * Returns the value of the smallest element in a vector.
  516. *
  517. * @param x Input vector.
  518. *
  519. * @return Value of the smallest element in the input vector.
  520. */
  521. template <class T, std::size_t N>
  522. constexpr T min(const vector<T, N>& x);
  523. /**
  524. * Calculates the element-wise remainder of the division operation `x / y`.
  525. *
  526. * @param x First vector.
  527. * @param y Second vector.
  528. *
  529. * @return Remainders of `x / y`.
  530. */
  531. /// @{
  532. template <class T, std::size_t N>
  533. constexpr vector<T, N> mod(const vector<T, N>& x, const vector<T, N>& y);
  534. template <class T, std::size_t N>
  535. constexpr vector<T, N> mod(const vector<T, N>& x, T y);
  536. /// @}
  537. /**
  538. * Multiplies two values.
  539. *
  540. * @param x First value.
  541. * @param y Second value.
  542. *
  543. * @return Product of the two values.
  544. */
  545. /// @{
  546. template <class T, std::size_t N>
  547. constexpr vector<T, N> mul(const vector<T, N>& x, const vector<T, N>& y) noexcept;
  548. template <class T, std::size_t N>
  549. constexpr vector<T, N> mul(const vector<T, N>& x, T y) noexcept;
  550. /// @}
  551. /**
  552. * Negates a vector.
  553. *
  554. * @param x Vector to negate.
  555. *
  556. * @return Negated vector.
  557. */
  558. template <class T, std::size_t N>
  559. constexpr vector<T, N> negate(const vector<T, N>& x) noexcept;
  560. /**
  561. * Calculates the unit vector in the same direction as the original vector.
  562. *
  563. * @param x Vector to normalize.
  564. *
  565. * @return Normalized vector.
  566. */
  567. template <class T, std::size_t N>
  568. vector<T, N> normalize(const vector<T, N>& x);
  569. /**
  570. * Logically inverts a boolean vector.
  571. *
  572. * @param x Vector to be inverted.
  573. *
  574. * @return Logically inverted vector.
  575. */
  576. template <class T, std::size_t N>
  577. constexpr vector<bool, N> not(const vector<T, N>& x) noexcept;
  578. /**
  579. * Compares two vectors for inequality
  580. *
  581. * @param x First vector.
  582. * @param y Second vector.
  583. *
  584. * @return Boolean vector containing the result of the element comparisons.
  585. */
  586. template <class T, std::size_t N>
  587. constexpr vector<bool, N> not_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept;
  588. /**
  589. * Raises each element to a power.
  590. *
  591. * @param x Input vector
  592. * @param y Exponent.
  593. *
  594. * @return Vector with its elements raised to the given power.
  595. */
  596. /// @{
  597. template <class T, std::size_t N>
  598. vector<T, N> pow(const vector<T, N>& x, const vector<T, N>& y);
  599. template <class T, std::size_t N>
  600. vector<T, N> pow(const vector<T, N>& x, T y);
  601. /// @}
  602. /**
  603. * Performs a element-wise round operation.
  604. *
  605. * @param x Input vector
  606. *
  607. * @return Component-wise round of input vector.
  608. */
  609. template <class T, std::size_t N>
  610. constexpr vector<T, N> round(const vector<T, N>& x);
  611. /**
  612. * Returns a vector containing the signs of each element.
  613. *
  614. * @param x Input vector
  615. * @return Signs of input vector elements.
  616. */
  617. template <class T, std::size_t N>
  618. constexpr vector<T, N> sign(const vector<T, N>& x);
  619. /**
  620. * Calculates the square distance between two points. The square distance can be calculated faster than the distance because a call to `std::sqrt` is saved.
  621. *
  622. * @param p0 First of two points.
  623. * @param p1 Second of two points.
  624. *
  625. * @return Square distance between the two points.
  626. */
  627. template <class T, std::size_t N>
  628. constexpr T sqr_distance(const vector<T, N>& p0, const vector<T, N>& p1) noexcept;
  629. /**
  630. * Calculates the square length of a vector. The square length can be calculated faster than the length because a call to `std::sqrt` is saved.
  631. *
  632. * @param x Vector of which to calculate the square length.
  633. *
  634. * @return Square length of the vector.
  635. */
  636. template <class T, std::size_t N>
  637. constexpr T sqr_length(const vector<T, N>& x) noexcept;
  638. /**
  639. * Takes the square root of each element.
  640. *
  641. * @param x Input vector
  642. *
  643. * @return Square roots of the input vector elements.
  644. */
  645. template <class T, std::size_t N>
  646. vector<T, N> sqrt(const vector<T, N>& x);
  647. /**
  648. * Subtracts a value by another value.
  649. *
  650. * @param x First value.
  651. * @param y Second value.
  652. *
  653. * @return Difference between the two values.
  654. */
  655. /// @{
  656. template <class T, std::size_t N>
  657. constexpr vector<T, N> sub(const vector<T, N>& x, const vector<T, N>& y) noexcept;
  658. template <class T, std::size_t N>
  659. constexpr vector<T, N> sub(const vector<T, N>& x, T y) noexcept;
  660. template <class T, std::size_t N>
  661. constexpr vector<T, N> sub(T x, const vector<T, N>& y) noexcept;
  662. /// @}
  663. /**
  664. * Calculates the sum of all elements in a vector.
  665. *
  666. * @param x Vector to sum.
  667. * @return Sum of the vector's elements.
  668. */
  669. template <class T, std::size_t N>
  670. constexpr T sum(const vector<T, N>& x) noexcept;
  671. /**
  672. * Makes an *m*-dimensional vector by rearranging and/or duplicating elements of an *n*-dimensional vector.
  673. *
  674. * @tparam Indices List of indices of elements in @p x.
  675. * @tparam T Vector element type.
  676. * @tparam N Number of dimensions in @p x.
  677. *
  678. * @param x Vector to swizzle.
  679. *
  680. * @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.
  681. */
  682. template <std::size_t... Indices, class T, std::size_t N>
  683. constexpr vector<T, sizeof...(Indices)> swizzle(const vector<T, N>& x) noexcept;
  684. /**
  685. * Performs a element-wise trunc operation.
  686. *
  687. * @param x Input vector
  688. * @return Component-wise trunc of input vector.
  689. */
  690. template <class T, std::size_t N>
  691. constexpr vector<T, N> trunc(const vector<T, N>& x);
  692. /// @private
  693. template <class T, std::size_t N, std::size_t... I>
  694. constexpr inline vector<T, N> abs(const vector<T, N>& x, std::index_sequence<I...>)
  695. {
  696. return {std::abs(x[I])...};
  697. }
  698. template <class T, std::size_t N>
  699. constexpr inline vector<T, N> abs(const vector<T, N>& x)
  700. {
  701. return abs(x, std::make_index_sequence<N>{});
  702. }
  703. /// @private
  704. template <class T, std::size_t N, std::size_t... I>
  705. constexpr inline vector<T, N> add(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
  706. {
  707. return {(x[I] + y[I])...};
  708. }
  709. template <class T, std::size_t N>
  710. constexpr inline vector<T, N> add(const vector<T, N>& x, const vector<T, N>& y) noexcept
  711. {
  712. return add(x, y, std::make_index_sequence<N>{});
  713. }
  714. /// @private
  715. template <class T, std::size_t N, std::size_t... I>
  716. constexpr inline vector<T, N> add(const vector<T, N>& x, T y, std::index_sequence<I...>) noexcept
  717. {
  718. return {(x[I] + y)...};
  719. }
  720. template <class T, std::size_t N>
  721. constexpr inline vector<T, N> add(const vector<T, N>& x, T y) noexcept
  722. {
  723. return add(x, y, std::make_index_sequence<N>{});
  724. }
  725. /// @private
  726. template <std::size_t N, std::size_t... I>
  727. constexpr inline bool all(const vector<bool, N>& x, std::index_sequence<I...>) noexcept
  728. {
  729. return (x[I] && ...);
  730. }
  731. template <std::size_t N>
  732. constexpr inline bool all(const vector<bool, N>& x) noexcept
  733. {
  734. return all(x, std::make_index_sequence<N>{});
  735. }
  736. /// @private
  737. template <std::size_t N, std::size_t... I>
  738. constexpr inline bool any(const vector<bool, N>& x, std::index_sequence<I...>) noexcept
  739. {
  740. return (x[I] || ...);
  741. }
  742. template <std::size_t N>
  743. constexpr inline bool any(const vector<bool, N>& x) noexcept
  744. {
  745. return any(x, std::make_index_sequence<N>{});
  746. }
  747. /// @private
  748. template <class T, std::size_t N, std::size_t... I>
  749. constexpr inline vector<T, N> ceil(const vector<T, N>& x, std::index_sequence<I...>)
  750. {
  751. static_assert(std::is_floating_point<T>::value);
  752. return {std::ceil(x[I])...};
  753. }
  754. template <class T, std::size_t N>
  755. constexpr inline vector<T, N> ceil(const vector<T, N>& x)
  756. {
  757. return ceil(x, std::make_index_sequence<N>{});
  758. }
  759. /// @private
  760. template <class T, std::size_t N, std::size_t... I>
  761. 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...>)
  762. {
  763. return {std::min<T>(max_val[I], std::max<T>(min_val[I], x[I]))...};
  764. }
  765. template <class T, std::size_t N>
  766. constexpr inline vector<T, N> clamp(const vector<T, N>& x, const vector<T, N>& min, const vector<T, N>& max)
  767. {
  768. return clamp(x, min, max, std::make_index_sequence<N>{});
  769. }
  770. /// @private
  771. template <class T, std::size_t N, std::size_t... I>
  772. constexpr inline vector<T, N> clamp(const vector<T, N>& x, T min, T max, std::index_sequence<I...>)
  773. {
  774. return {std::min<T>(max, std::max<T>(min, x[I]))...};
  775. }
  776. template <class T, std::size_t N>
  777. constexpr inline vector<T, N> clamp(const vector<T, N>& x, T min, T max)
  778. {
  779. return clamp(x, min, max, std::make_index_sequence<N>{});
  780. }
  781. template <class T, std::size_t N>
  782. vector<T, N> clamp_length(const vector<T, N>& x, T max_length)
  783. {
  784. static_assert(std::is_floating_point<T>::value);
  785. T length2 = sqr_length(x);
  786. return (length2 > max_length * max_length) ? (x * (max_length / std::sqrt(length2))) : x;
  787. }
  788. template <class T>
  789. constexpr inline vector<T, 3> cross(const vector<T, 3>& x, const vector<T, 3>& y) noexcept
  790. {
  791. return
  792. {
  793. x[1] * y[2] - y[1] * x[2],
  794. x[2] * y[0] - y[2] * x[0],
  795. x[0] * y[1] - y[0] * x[1]
  796. };
  797. }
  798. template <class T, std::size_t N>
  799. inline T distance(const vector<T, N>& p0, const vector<T, N>& p1)
  800. {
  801. return length(sub(p0, p1));
  802. }
  803. /// @private
  804. template <class T, std::size_t N, std::size_t... I>
  805. constexpr inline vector<T, N> div(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
  806. {
  807. return {(x[I] / y[I])...};
  808. }
  809. template <class T, std::size_t N>
  810. constexpr inline vector<T, N> div(const vector<T, N>& x, const vector<T, N>& y) noexcept
  811. {
  812. return div(x, y, std::make_index_sequence<N>{});
  813. }
  814. /// @private
  815. template <class T, std::size_t N, std::size_t... I>
  816. constexpr inline vector<T, N> div(const vector<T, N>& x, T y, std::index_sequence<I...>) noexcept
  817. {
  818. return {(x[I] / y)...};
  819. }
  820. template <class T, std::size_t N>
  821. constexpr inline vector<T, N> div(const vector<T, N>& x, T y) noexcept
  822. {
  823. return div(x, y, std::make_index_sequence<N>{});
  824. }
  825. /// @private
  826. template <class T, std::size_t N, std::size_t... I>
  827. constexpr inline vector<T, N> div(T x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
  828. {
  829. return {(x / y[I])...};
  830. }
  831. template <class T, std::size_t N>
  832. constexpr inline vector<T, N> div(T x, const vector<T, N>& y) noexcept
  833. {
  834. return div(x, y, std::make_index_sequence<N>{});
  835. }
  836. /// @private
  837. template <class T, std::size_t N, std::size_t... I>
  838. constexpr inline T dot(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
  839. {
  840. return ((x[I] * y[I]) + ...);
  841. }
  842. template <class T, std::size_t N>
  843. constexpr inline T dot(const vector<T, N>& x, const vector<T, N>& y) noexcept
  844. {
  845. return dot(x, y, std::make_index_sequence<N>{});
  846. }
  847. /// @private
  848. template <class T, std::size_t N, std::size_t... I>
  849. constexpr inline vector<bool, N> equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
  850. {
  851. return {(x[I] == y[I])...};
  852. }
  853. template <class T, std::size_t N>
  854. constexpr inline vector<bool, N> equal(const vector<T, N>& x, const vector<T, N>& y) noexcept
  855. {
  856. return equal(x, y, std::make_index_sequence<N>{});
  857. }
  858. /// @private
  859. template <class T, std::size_t N, std::size_t... I>
  860. constexpr inline vector<T, N> floor(const vector<T, N>& x, std::index_sequence<I...>)
  861. {
  862. static_assert(std::is_floating_point<T>::value);
  863. return {std::floor(x[I])...};
  864. }
  865. template <class T, std::size_t N>
  866. constexpr inline vector<T, N> floor(const vector<T, N>& x)
  867. {
  868. return floor(x, std::make_index_sequence<N>{});
  869. }
  870. /// @private
  871. template <class T, std::size_t N, std::size_t... I>
  872. 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...>)
  873. {
  874. static_assert(std::is_floating_point<T>::value);
  875. return {std::fma(x[I], y[I], z[I])...};
  876. }
  877. template <class T, std::size_t N>
  878. constexpr inline vector<T, N> fma(const vector<T, N>& x, const vector<T, N>& y, const vector<T, N>& z)
  879. {
  880. return fma(x, y, z, std::make_index_sequence<N>{});
  881. }
  882. /// @private
  883. template <class T, std::size_t N, std::size_t... I>
  884. constexpr inline vector<T, N> fma(const vector<T, N>& x, T y, T z, std::index_sequence<I...>)
  885. {
  886. static_assert(std::is_floating_point<T>::value);
  887. return {std::fma(x[I], y, z)...};
  888. }
  889. template <class T, std::size_t N>
  890. constexpr inline vector<T, N> fma(const vector<T, N>& x, T y, T z)
  891. {
  892. return fma(x, y, z, std::make_index_sequence<N>{});
  893. }
  894. /// @private
  895. template <class T, std::size_t N, std::size_t... I>
  896. constexpr inline vector<T, N> fract(const vector<T, N>& x, std::index_sequence<I...>)
  897. {
  898. static_assert(std::is_floating_point<T>::value);
  899. return {x[I] - std::floor(x[I])...};
  900. }
  901. template <class T, std::size_t N>
  902. constexpr inline vector<T, N> fract(const vector<T, N>& x)
  903. {
  904. return fract(x, std::make_index_sequence<N>{});
  905. }
  906. /// @private
  907. template <class T, std::size_t N, std::size_t... I>
  908. constexpr inline vector<bool, N> greater_than(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
  909. {
  910. return {(x[I] > y[I])...};
  911. }
  912. template <class T, std::size_t N>
  913. constexpr inline vector<bool, N> greater_than(const vector<T, N>& x, const vector<T, N>& y) noexcept
  914. {
  915. return greater_than(x, y, std::make_index_sequence<N>{});
  916. }
  917. /// @private
  918. template <class T, std::size_t N, std::size_t... I>
  919. constexpr inline vector<bool, N> greater_than_equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
  920. {
  921. return {(x[I] >= y[I])...};
  922. }
  923. template <class T, std::size_t N>
  924. constexpr inline vector<bool, N> greater_than_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept
  925. {
  926. return greater_than_equal(x, y, std::make_index_sequence<N>{});
  927. }
  928. template <class T, std::size_t N>
  929. inline T inv_length(const vector<T, N>& x)
  930. {
  931. return T{1} / length(x);
  932. }
  933. template <class T, std::size_t N>
  934. inline T length(const vector<T, N>& x)
  935. {
  936. static_assert(std::is_floating_point<T>::value);
  937. return std::sqrt(sqr_length(x));
  938. }
  939. /// @private
  940. template <class T, std::size_t N, std::size_t... I>
  941. constexpr inline vector<bool, N> less_than(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
  942. {
  943. return {(x[I] < y[I])...};
  944. }
  945. template <class T, std::size_t N>
  946. constexpr inline vector<bool, N> less_than(const vector<T, N>& x, const vector<T, N>& y) noexcept
  947. {
  948. return less_than(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<bool, N> less_than_equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
  953. {
  954. return {(x[I] <= y[I])...};
  955. }
  956. template <class T, std::size_t N>
  957. constexpr inline vector<bool, N> less_than_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept
  958. {
  959. return less_than_equal(x, y, std::make_index_sequence<N>{});
  960. }
  961. /// @private
  962. template <class T, std::size_t N, std::size_t... I>
  963. constexpr inline vector<T, N> max(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
  964. {
  965. return {std::max<T>(x[I], y[I])...};
  966. }
  967. template <class T, std::size_t N>
  968. constexpr vector<T, N> max(const vector<T, N>& x, const vector<T, N>& y)
  969. {
  970. return max(x, y, std::make_index_sequence<N>{});
  971. }
  972. template <class T, std::size_t N>
  973. constexpr inline T max(const vector<T, N>& x)
  974. {
  975. return *std::max_element(x.elements, x.elements + N);
  976. }
  977. /// @private
  978. template <class T, std::size_t N, std::size_t... I>
  979. constexpr inline vector<T, N> min(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
  980. {
  981. return {std::min<T>(x[I], y[I])...};
  982. }
  983. template <class T, std::size_t N>
  984. constexpr vector<T, N> min(const vector<T, N>& x, const vector<T, N>& y)
  985. {
  986. return min(x, y, std::make_index_sequence<N>{});
  987. }
  988. template <class T, std::size_t N>
  989. constexpr inline T min(const vector<T, N>& x)
  990. {
  991. return *std::min_element(x.elements, x.elements + N);
  992. }
  993. /// @private
  994. template <class T, std::size_t N, std::size_t... I>
  995. constexpr inline vector<T, N> mod(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
  996. {
  997. static_assert(std::is_floating_point<T>::value);
  998. return {std::fmod(x[I], y[I])...};
  999. }
  1000. template <class T, std::size_t N>
  1001. constexpr inline vector<T, N> mod(const vector<T, N>& x, const vector<T, N>& y)
  1002. {
  1003. return mod(x, y, std::make_index_sequence<N>{});
  1004. }
  1005. /// @private
  1006. template <class T, std::size_t N, std::size_t... I>
  1007. constexpr inline vector<T, N> mod(const vector<T, N>& x, T y, std::index_sequence<I...>)
  1008. {
  1009. static_assert(std::is_floating_point<T>::value);
  1010. return {std::fmod(x[I], y)...};
  1011. }
  1012. template <class T, std::size_t N>
  1013. constexpr inline vector<T, N> mod(const vector<T, N>& x, T y)
  1014. {
  1015. return mod(x, y, std::make_index_sequence<N>{});
  1016. }
  1017. /// @private
  1018. template <class T, std::size_t N, std::size_t... I>
  1019. constexpr inline vector<T, N> mul(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
  1020. {
  1021. return {(x[I] * y[I])...};
  1022. }
  1023. template <class T, std::size_t N>
  1024. constexpr inline vector<T, N> mul(const vector<T, N>& x, const vector<T, N>& y) noexcept
  1025. {
  1026. return mul(x, y, std::make_index_sequence<N>{});
  1027. }
  1028. /// @private
  1029. template <class T, std::size_t N, std::size_t... I>
  1030. constexpr inline vector<T, N> mul(const vector<T, N>& x, T y, std::index_sequence<I...>) noexcept
  1031. {
  1032. return {(x[I] * y)...};
  1033. }
  1034. template <class T, std::size_t N>
  1035. constexpr inline vector<T, N> mul(const vector<T, N>& x, T y) noexcept
  1036. {
  1037. return mul(x, y, std::make_index_sequence<N>{});
  1038. }
  1039. /// @private
  1040. template <class T, std::size_t N, std::size_t... I>
  1041. constexpr inline vector<T, N> negate(const vector<T, N>& x, std::index_sequence<I...>) noexcept
  1042. {
  1043. return {(-x[I])...};
  1044. }
  1045. template <class T, std::size_t N>
  1046. constexpr inline vector<T, N> negate(const vector<T, N>& x) noexcept
  1047. {
  1048. return negate(x, std::make_index_sequence<N>{});
  1049. }
  1050. template <class T, std::size_t N>
  1051. inline vector<T, N> normalize(const vector<T, N>& x)
  1052. {
  1053. return mul(x, inv_length(x));
  1054. }
  1055. /// @private
  1056. template <class T, std::size_t N, std::size_t... I>
  1057. constexpr inline vector<bool, N> not(const vector<T, N>& x, std::index_sequence<I...>) noexcept
  1058. {
  1059. return {!x[I]...};
  1060. }
  1061. template <class T, std::size_t N>
  1062. constexpr inline vector<bool, N> not(const vector<T, N>& x) noexcept
  1063. {
  1064. return not(x, std::make_index_sequence<N>{});
  1065. }
  1066. /// @private
  1067. template <class T, std::size_t N, std::size_t... I>
  1068. constexpr inline vector<bool, N> not_equal(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
  1069. {
  1070. return {(x[I] != y[I])...};
  1071. }
  1072. template <class T, std::size_t N>
  1073. constexpr inline vector<bool, N> not_equal(const vector<T, N>& x, const vector<T, N>& y) noexcept
  1074. {
  1075. return not_equal(x, y, std::make_index_sequence<N>{});
  1076. }
  1077. /// @private
  1078. template <class T, std::size_t N, std::size_t... I>
  1079. inline vector<T, N> pow(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>)
  1080. {
  1081. static_assert(std::is_floating_point<T>::value);
  1082. return {std::pow(x[I], y[I])...};
  1083. }
  1084. template <class T, std::size_t N>
  1085. inline vector<T, N> pow(const vector<T, N>& x, const vector<T, N>& y)
  1086. {
  1087. return pow(x, y, std::make_index_sequence<N>{});
  1088. }
  1089. /// @private
  1090. template <class T, std::size_t N, std::size_t... I>
  1091. inline vector<T, N> pow(const vector<T, N>& x, T y, std::index_sequence<I...>)
  1092. {
  1093. static_assert(std::is_floating_point<T>::value);
  1094. return {std::pow(x[I], y)...};
  1095. }
  1096. template <class T, std::size_t N>
  1097. inline vector<T, N> pow(const vector<T, N>& x, T y)
  1098. {
  1099. return pow(x, y, std::make_index_sequence<N>{});
  1100. }
  1101. /// @private
  1102. template <class T, std::size_t N, std::size_t... I>
  1103. constexpr inline vector<T, N> round(const vector<T, N>& x, std::index_sequence<I...>)
  1104. {
  1105. static_assert(std::is_floating_point<T>::value);
  1106. return {std::round(x[I])...};
  1107. }
  1108. template <class T, std::size_t N>
  1109. constexpr inline vector<T, N> round(const vector<T, N>& x)
  1110. {
  1111. return round(x, std::make_index_sequence<N>{});
  1112. }
  1113. /// @private
  1114. template <class T, std::size_t N, std::size_t... I>
  1115. constexpr inline vector<T, N> sign(const vector<T, N>& x, std::index_sequence<I...>)
  1116. {
  1117. static_assert(std::is_floating_point<T>::value);
  1118. return {std::copysign(T{1}, x[I])...};
  1119. }
  1120. template <class T, std::size_t N>
  1121. constexpr inline vector<T, N> sign(const vector<T, N>& x)
  1122. {
  1123. return sign(x, std::make_index_sequence<N>{});
  1124. }
  1125. template <class T, std::size_t N>
  1126. constexpr inline T sqr_distance(const vector<T, N>& p0, const vector<T, N>& p1) noexcept
  1127. {
  1128. return sqr_length(sub(p0, p1));
  1129. }
  1130. template <class T, std::size_t N>
  1131. constexpr inline T sqr_length(const vector<T, N>& x) noexcept
  1132. {
  1133. return dot(x, x);
  1134. }
  1135. /// @private
  1136. template <class T, std::size_t N, std::size_t... I>
  1137. inline vector<T, N> sqrt(const vector<T, N>& x, std::index_sequence<I...>)
  1138. {
  1139. static_assert(std::is_floating_point<T>::value);
  1140. return {std::sqrt(x[I])...};
  1141. }
  1142. template <class T, std::size_t N>
  1143. inline vector<T, N> sqrt(const vector<T, N>& x, const vector<T, N>& y)
  1144. {
  1145. return sqrt(x, std::make_index_sequence<N>{});
  1146. }
  1147. /// @private
  1148. template <class T, std::size_t N, std::size_t... I>
  1149. constexpr inline vector<T, N> sub(const vector<T, N>& x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
  1150. {
  1151. return {(x[I] - y[I])...};
  1152. }
  1153. template <class T, std::size_t N>
  1154. constexpr inline vector<T, N> sub(const vector<T, N>& x, const vector<T, N>& y) noexcept
  1155. {
  1156. return sub(x, y, std::make_index_sequence<N>{});
  1157. }
  1158. /// @private
  1159. template <class T, std::size_t N, std::size_t... I>
  1160. constexpr inline vector<T, N> sub(const vector<T, N>& x, T y, std::index_sequence<I...>) noexcept
  1161. {
  1162. return {(x[I] - y)...};
  1163. }
  1164. template <class T, std::size_t N>
  1165. constexpr inline vector<T, N> sub(const vector<T, N>& x, T y) noexcept
  1166. {
  1167. return sub(x, y, std::make_index_sequence<N>{});
  1168. }
  1169. /// @private
  1170. template <class T, std::size_t N, std::size_t... I>
  1171. constexpr inline vector<T, N> sub(T x, const vector<T, N>& y, std::index_sequence<I...>) noexcept
  1172. {
  1173. return {(x - y[I])...};
  1174. }
  1175. template <class T, std::size_t N>
  1176. constexpr inline vector<T, N> sub(T x, const vector<T, N>& y) noexcept
  1177. {
  1178. return sub(x, y, std::make_index_sequence<N>{});
  1179. }
  1180. /// @private
  1181. template <class T, std::size_t N, std::size_t... I>
  1182. constexpr inline T sum(const vector<T, N>& x, std::index_sequence<I...>) noexcept
  1183. {
  1184. return (x[I] + ...);
  1185. }
  1186. template <class T, std::size_t N>
  1187. constexpr inline T sum(const vector<T, N>& x) noexcept
  1188. {
  1189. return sum(x, std::make_index_sequence<N>{});
  1190. }
  1191. template <std::size_t... Indices, class T, std::size_t N>
  1192. constexpr inline vector<T, sizeof...(Indices)> swizzle(const vector<T, N>& x) noexcept
  1193. {
  1194. return {x[Indices]...};
  1195. }
  1196. /// @private
  1197. template <class T, std::size_t N, std::size_t... I>
  1198. constexpr inline vector<T, N> trunc(const vector<T, N>& x, std::index_sequence<I...>)
  1199. {
  1200. static_assert(std::is_floating_point<T>::value);
  1201. return {std::trunc(x[I])...};
  1202. }
  1203. template <class T, std::size_t N>
  1204. constexpr inline vector<T, N> trunc(const vector<T, N>& x)
  1205. {
  1206. return trunc(x, std::make_index_sequence<N>{});
  1207. }
  1208. namespace operators {
  1209. /// @copydoc add(const vector<T, N>&, const vector<T, N>&)
  1210. template <class T, std::size_t N>
  1211. constexpr inline vector<T, N> operator+(const vector<T, N>& x, const vector<T, N>& y) noexcept
  1212. {
  1213. return add(x, y);
  1214. }
  1215. /// @copydoc add(const vector<T, N>&, T)
  1216. /// @{
  1217. template <class T, std::size_t N>
  1218. constexpr inline vector<T, N> operator+(const vector<T, N>& x, T y) noexcept
  1219. {
  1220. return add(x, y);
  1221. }
  1222. template <class T, std::size_t N>
  1223. constexpr inline vector<T, N> operator+(T x, const vector<T, N>& y) noexcept
  1224. {
  1225. return add(y, x);
  1226. }
  1227. /// @}
  1228. /// @copydoc div(const vector<T, N>&, const vector<T, N>&)
  1229. template <class T, std::size_t N>
  1230. constexpr inline vector<T, N> operator/(const vector<T, N>& x, const vector<T, N>& y) noexcept
  1231. {
  1232. return div(x, y);
  1233. }
  1234. /// @copydoc div(const vector<T, N>&, T)
  1235. template <class T, std::size_t N>
  1236. constexpr inline vector<T, N> operator/(const vector<T, N>& x, T y) noexcept
  1237. {
  1238. return div(x, y);
  1239. }
  1240. /// @copydoc div(T, const vector<T, N>&)
  1241. template <class T, std::size_t N>
  1242. constexpr inline vector<T, N> operator/(T x, const vector<T, N>& y) noexcept
  1243. {
  1244. return div(x, y);
  1245. }
  1246. /// @copydoc mul(const vector<T, N>&, const vector<T, N>&)
  1247. template <class T, std::size_t N>
  1248. constexpr inline vector<T, N> operator*(const vector<T, N>& x, const vector<T, N>& y) noexcept
  1249. {
  1250. return mul(x, y);
  1251. }
  1252. /// @copydoc mul(const vector<T, N>&, T)
  1253. /// @{
  1254. template <class T, std::size_t N>
  1255. constexpr inline vector<T, N> operator*(const vector<T, N>& x, T y) noexcept
  1256. {
  1257. return mul(x, y);
  1258. }
  1259. template <class T, std::size_t N>
  1260. constexpr inline vector<T, N> operator*(T x, const vector<T, N>& y) noexcept
  1261. {
  1262. return mul(y, x);
  1263. }
  1264. /// @}
  1265. /// @copydoc negate(const vector<T, N>&)
  1266. template <class T, std::size_t N>
  1267. constexpr inline vector<T, N> operator-(const vector<T, N>& x) noexcept
  1268. {
  1269. return negate(x);
  1270. }
  1271. /// @copydoc sub(const vector<T, N>&, const vector<T, N>&)
  1272. template <class T, std::size_t N>
  1273. constexpr inline vector<T, N> operator-(const vector<T, N>& x, const vector<T, N>& y) noexcept
  1274. {
  1275. return sub(x, y);
  1276. }
  1277. /// @copydoc sub(const vector<T, N>&, T)
  1278. template <class T, std::size_t N>
  1279. constexpr inline vector<T, N> operator-(const vector<T, N>& x, T y) noexcept
  1280. {
  1281. return sub(x, y);
  1282. }
  1283. /// @copydoc sub(T, const vector<T, N>&)
  1284. template <class T, std::size_t N>
  1285. constexpr inline vector<T, N> operator-(T x, const vector<T, N>& y) noexcept
  1286. {
  1287. return sub(x, y);
  1288. }
  1289. /**
  1290. * Adds two values and stores the result in the first value.
  1291. *
  1292. * @param x First value.
  1293. * @param y Second value.
  1294. *
  1295. * @return Reference to the first value.
  1296. */
  1297. /// @{
  1298. template <class T, std::size_t N>
  1299. constexpr inline vector<T, N>& operator+=(vector<T, N>& x, const vector<T, N>& y) noexcept
  1300. {
  1301. return (x = x + y);
  1302. }
  1303. template <class T, std::size_t N>
  1304. constexpr inline vector<T, N>& operator+=(vector<T, N>& x, T y) noexcept
  1305. {
  1306. return (x = x + y);
  1307. }
  1308. /// @}
  1309. /**
  1310. * Subtracts the first value by the second value and stores the result in the first value.
  1311. *
  1312. * @param x First value.
  1313. * @param y Second value.
  1314. *
  1315. * @return Reference to the first value.
  1316. */
  1317. /// @{
  1318. template <class T, std::size_t N>
  1319. constexpr inline vector<T, N>& operator-=(vector<T, N>& x, const vector<T, N>& y) noexcept
  1320. {
  1321. return (x = x - y);
  1322. }
  1323. template <class T, std::size_t N>
  1324. constexpr inline vector<T, N>& operator-=(vector<T, N>& x, T y) noexcept
  1325. {
  1326. return (x = x - y);
  1327. }
  1328. /// @}
  1329. /**
  1330. * Multiplies two values and stores the result in the first value.
  1331. *
  1332. * @param x First value.
  1333. * @param y Second value.
  1334. *
  1335. * @return Reference to the first value.
  1336. */
  1337. /// @{
  1338. template <class T, std::size_t N>
  1339. constexpr inline vector<T, N>& operator*=(vector<T, N>& x, const vector<T, N>& y) noexcept
  1340. {
  1341. return (x = x * y);
  1342. }
  1343. template <class T, std::size_t N>
  1344. constexpr inline vector<T, N>& operator*=(vector<T, N>& x, T y) noexcept
  1345. {
  1346. return (x = x * y);
  1347. }
  1348. /// @}
  1349. /**
  1350. * Divides the first value by the second value and stores the result in the first value.
  1351. *
  1352. * @param x First value.
  1353. * @param y Second value.
  1354. *
  1355. * @return Reference to the first value.
  1356. */
  1357. /// @{
  1358. template <class T, std::size_t N>
  1359. constexpr inline vector<T, N>& operator/=(vector<T, N>& x, const vector<T, N>& y) noexcept
  1360. {
  1361. return (x = x / y);
  1362. }
  1363. template <class T, std::size_t N>
  1364. constexpr inline vector<T, N>& operator/=(vector<T, N>& x, T y) noexcept
  1365. {
  1366. return (x = x / y);
  1367. }
  1368. /// @}
  1369. /**
  1370. * Writes the elements of a vector to an output stream, with each element delimeted by a space.
  1371. *
  1372. * @param os Output stream.
  1373. * @param x Vector.
  1374. *
  1375. * @return Output stream.
  1376. */
  1377. template <class T, std::size_t N>
  1378. std::ostream& operator<<(std::ostream& os, const vector<T, N>& x)
  1379. {
  1380. for (std::size_t i = 0; i < N; ++i)
  1381. {
  1382. if (i)
  1383. os << ' ';
  1384. os << x[i];
  1385. }
  1386. return os;
  1387. }
  1388. /**
  1389. * Reads the elements of a vector from an input stream, with each element delimeted by a space.
  1390. *
  1391. * @param is Input stream.
  1392. * @param x Vector.
  1393. *
  1394. * @return Input stream.
  1395. */
  1396. template <class T, std::size_t N>
  1397. std::istream& operator>>(std::istream& is, vector<T, N>& x)
  1398. {
  1399. for (std::size_t i = 0; i < N; ++i)
  1400. is >> x[i];
  1401. return is;
  1402. }
  1403. } // namespace operators
  1404. } // namespace math
  1405. using namespace math::operators;
  1406. #endif // ANTKEEPER_MATH_VECTOR_HPP