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

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