6#include <Common/assertion.h>
14template<
typename Derived,
typename T, std::
size_t N>
20template<
typename Derived,
typename T, std::
size_t N>
25template<
typename Derived,
typename T, std::
size_t N>
29 return Derived(
static_cast<const Derived&
>(*
this)).addLocal(rhs);
32template<
typename Derived,
typename T, std::
size_t N>
36 return Derived(
static_cast<const Derived&
>(*
this)).addLocal(rhs);
39template<
typename Derived,
typename T, std::
size_t N>
43 for(std::size_t i = 0; i < N; ++i)
45 m[i] += rhs.Self::m[i];
47 return static_cast<Derived&
>(*this);
50template<
typename Derived,
typename T, std::
size_t N>
54 for(std::size_t i = 0; i < N; ++i)
58 return static_cast<Derived&
>(*this);
61template<
typename Derived,
typename T, std::
size_t N>
65 return Derived(
static_cast<const Derived&
>(*
this)).subLocal(rhs);
68template<
typename Derived,
typename T, std::
size_t N>
72 return Derived(
static_cast<const Derived&
>(*
this)).subLocal(rhs);
75template<
typename Derived,
typename T, std::
size_t N>
79 for(std::size_t i = 0; i < N; ++i)
81 m[i] -= rhs.Self::m[i];
83 return static_cast<Derived&
>(*this);
86template<
typename Derived,
typename T, std::
size_t N>
90 for(std::size_t i = 0; i < N; ++i)
94 return static_cast<Derived&
>(*this);
97template<
typename Derived,
typename T, std::
size_t N>
101 return Derived(
static_cast<const Derived&
>(*
this)).mulLocal(rhs);
104template<
typename Derived,
typename T, std::
size_t N>
108 return Derived(
static_cast<const Derived&
>(*
this)).mulLocal(rhs);
111template<
typename Derived,
typename T, std::
size_t N>
115 for(std::size_t i = 0; i < N; ++i)
117 m[i] *= rhs.Self::m[i];
119 return static_cast<Derived&
>(*this);
122template<
typename Derived,
typename T, std::
size_t N>
126 for(std::size_t i = 0; i < N; ++i)
130 return static_cast<Derived&
>(*this);
133template<
typename Derived,
typename T, std::
size_t N>
137 return Derived(
static_cast<const Derived&
>(*
this)).divLocal(rhs);
140template<
typename Derived,
typename T, std::
size_t N>
144 return Derived(
static_cast<const Derived&
>(*
this)).divLocal(rhs);
147template<
typename Derived,
typename T, std::
size_t N>
151 for(std::size_t i = 0; i < N; ++i)
153 m[i] /= rhs.Self::m[i];
155 return static_cast<Derived&
>(*this);
158template<
typename Derived,
typename T, std::
size_t N>
162 for(std::size_t i = 0; i < N; ++i)
166 return static_cast<Derived&
>(*this);
169template<
typename Derived,
typename T, std::
size_t N>
174 return Derived(
static_cast<const Derived&
>(*
this)).powLocal(exponent);
177template<
typename Derived,
typename T, std::
size_t N>
182 for(std::size_t i = 0; i < N; ++i)
184 m[i] =
static_cast<T
>(std::pow(m[i], exponent));
186 return static_cast<Derived&
>(*this);
189template<
typename Derived,
typename T, std::
size_t N>
193 return Derived(
static_cast<const Derived&
>(*
this)).powLocal(exponent);
196template<
typename Derived,
typename T, std::
size_t N>
200 for(std::size_t i = 0; i < N; ++i)
202 m[i] =
static_cast<T
>(std::pow(m[i], exponent.Self::m[i]));
204 return static_cast<Derived&
>(*this);
207template<
typename Derived,
typename T, std::
size_t N>
212 return Derived(
static_cast<const Derived&
>(*
this)).expLocal(exponent);
215template<
typename Derived,
typename T, std::
size_t N>
220 for(std::size_t i = 0; i < N; ++i)
222 m[i] =
static_cast<T
>(std::exp(exponent));
224 return static_cast<Derived&
>(*this);
227template<
typename Derived,
typename T, std::
size_t N>
231 return Derived(
static_cast<const Derived&
>(*
this)).expLocal(exponent);
234template<
typename Derived,
typename T, std::
size_t N>
238 for(std::size_t i = 0; i < N; ++i)
240 m[i] =
static_cast<T
>(std::exp(exponent.Self::m[i]));
242 return static_cast<Derived&
>(*this);
245template<
typename Derived,
typename T, std::
size_t N>
249 return Derived(
static_cast<const Derived&
>(*
this)).sqrtLocal();
252template<
typename Derived,
typename T, std::
size_t N>
256 for(std::size_t i = 0; i < N; ++i)
258 m[i] =
static_cast<T
>(std::sqrt(m[i]));
260 return static_cast<Derived&
>(*this);
263template<
typename Derived,
typename T, std::
size_t N>
267 return Derived(
static_cast<const Derived&
>(*
this)).clampLocal(lowerBound, upperBound);
270template<
typename Derived,
typename T, std::
size_t N>
274 for(std::size_t i = 0; i < N; ++i)
278 return static_cast<Derived&
>(*this);
281template<
typename Derived,
typename T, std::
size_t N>
285 return Derived(
static_cast<const Derived&
>(*
this)).clampLocal(lowerBound, upperBound);
288template<
typename Derived,
typename T, std::
size_t N>
292 for(std::size_t i = 0; i < N; ++i)
296 return static_cast<Derived&
>(*this);
299template<
typename Derived,
typename T, std::
size_t N>
303 return Derived(
static_cast<const Derived&
>(*
this)).safeClampLocal(lowerBound, upperBound);
306template<
typename Derived,
typename T, std::
size_t N>
310 for(std::size_t i = 0; i < N; ++i)
314 return static_cast<Derived&
>(*this);
317template<
typename Derived,
typename T, std::
size_t N>
321 return Derived(
static_cast<const Derived&
>(*
this)).safeClampLocal(lowerBound, upperBound);
324template<
typename Derived,
typename T, std::
size_t N>
328 for(std::size_t i = 0; i < N; ++i)
332 return static_cast<Derived&
>(*this);
335template<
typename Derived,
typename T, std::
size_t N>
338 return ::ph::math::summation(m);
341template<
typename Derived,
typename T, std::
size_t N>
344 if constexpr(std::is_floating_point_v<T>)
347 constexpr T rcpN =
static_cast<T
>(1) /
static_cast<T
>(N);
353 return sum() /
static_cast<T
>(N);
357template<
typename Derived,
typename T, std::
size_t N>
360 return ::ph::math::product(m);
363template<
typename Derived,
typename T, std::
size_t N>
366 return m[minIndex()];
369template<
typename Derived,
typename T, std::
size_t N>
373 Derived result(
static_cast<const Derived&
>(*
this));
374 for(std::size_t i = 0; i < N; ++i)
376 result.Self::m[i] = std::min(m[i], other.Self::m[i]);
381template<
typename Derived,
typename T, std::
size_t N>
384 std::size_t result = 0;
385 for(std::size_t i = 1; i < N; ++i)
395template<
typename Derived,
typename T, std::
size_t N>
398 return m[maxIndex()];
401template<
typename Derived,
typename T, std::
size_t N>
405 Derived result(
static_cast<const Derived&
>(*
this));
406 for(std::size_t i = 0; i < N; ++i)
408 result.Self::m[i] = std::max(m[i], other.Self::m[i]);
413template<
typename Derived,
typename T, std::
size_t N>
416 std::size_t result = 0;
417 for(std::size_t i = 1; i < N; ++i)
427template<
typename Derived,
typename T, std::
size_t N>
431 if constexpr(std::is_floating_point_v<T>)
433 Derived result(
static_cast<const Derived&
>(*
this));
434 for(std::size_t i = 0; i < N; ++i)
436 result.Self::m[i] =
static_cast<T
>(std::ceil(m[i]));
442 return static_cast<const Derived&
>(*this);
446template<
typename Derived,
typename T, std::
size_t N>
450 if constexpr(std::is_floating_point_v<T>)
452 Derived result(
static_cast<const Derived&
>(*
this));
453 for(std::size_t i = 0; i < N; ++i)
455 result.Self::m[i] =
static_cast<T
>(std::floor(m[i]));
461 return static_cast<const Derived&
>(*this);
465template<
typename Derived,
typename T, std::
size_t N>
469 return Derived(
static_cast<const Derived&
>(*
this)).absLocal();
472template<
typename Derived,
typename T, std::
size_t N>
476 for(std::size_t i = 0; i < N; ++i)
478 m[i] = std::abs(m[i]);
480 return static_cast<Derived&
>(*this);
483template<
typename Derived,
typename T, std::
size_t N>
487 return Derived(
static_cast<const Derived&
>(*
this)).rcpLocal();
490template<
typename Derived,
typename T, std::
size_t N>
494 for(std::size_t i = 0; i < N; ++i)
496 m[i] =
static_cast<T
>(1) / m[i];
498 return static_cast<Derived&
>(*this);
501template<
typename Derived,
typename T, std::
size_t N>
505 return Derived(
static_cast<const Derived&
>(*
this)).complementLocal();
508template<
typename Derived,
typename T, std::
size_t N>
512 for(std::size_t i = 0; i < N; ++i)
514 m[i] =
static_cast<T
>(1) - m[i];
516 return static_cast<Derived&
>(*this);
519template<
typename Derived,
typename T, std::
size_t N>
522requires
std::is_signed_v<T>
524 return Derived(
static_cast<const Derived&
>(*
this)).negateLocal();
527template<
typename Derived,
typename T, std::
size_t N>
530requires std::is_signed_v<T>
532 return mulLocal(
static_cast<T
>(-1));
535template<
typename Derived,
typename T, std::
size_t N>
540 Derived result(
static_cast<const Derived&
>(*
this));
541 for(std::size_t i = 0; i < N; ++i)
543 result.m[i] = m[i] * (
static_cast<U
>(1) - factor) + rhs.m[i] * factor;
548template<
typename Derived,
typename T, std::
size_t N>
554 for(std::size_t i = 0; i < N; ++i)
556 if(m[i] !=
static_cast<T
>(0))
564template<
typename Derived,
typename T, std::
size_t N>
567 if constexpr(std::is_unsigned_v<T>)
573 for(std::size_t i = 0; i < N; ++i)
584template<
typename Derived,
typename T, std::
size_t N>
587 for(std::size_t i = 0; i < N; ++i)
589 if(!std::isfinite(m[i]))
597template<
typename Derived,
typename T, std::
size_t N>
603template<
typename Derived,
typename T, std::
size_t N>
608 return static_cast<Derived&
>(*this);
611template<
typename Derived,
typename T, std::
size_t N>
615 PH_ASSERT_LT(index, N);
618 return static_cast<Derived&
>(*this);
621template<
typename Derived,
typename T, std::
size_t N>
626 return static_cast<Derived&
>(*this);
629template<
typename Derived,
typename T, std::
size_t N>
632 PH_ASSERT_LT(index, N);
637template<
typename Derived,
typename T, std::
size_t N>
640 PH_ASSERT_LT(index, N);
645template<
typename Derived,
typename T, std::
size_t N>
648 return m == other.Self::m;
651template<
typename Derived,
typename T, std::
size_t N>
654 for(std::size_t i = 0; i < N; ++i)
656 if(std::abs(m[i] - other.Self::m[i]) > margin)
664template<
typename Derived,
typename T, std::
size_t N>
667 return isEqual(other);
670template<
typename Derived,
typename T, std::
size_t N>
673 return !isEqual(other);
676template<
typename Derived,
typename T, std::
size_t N>
683template<
typename Derived,
typename T, std::
size_t N>
690template<
typename Derived,
typename T, std::
size_t N>
697template<
typename Derived,
typename T, std::
size_t N>
704template<
typename Derived,
typename T, std::
size_t N>
711template<
typename Derived,
typename T, std::
size_t N>
718template<
typename Derived,
typename T, std::
size_t N>
725template<
typename Derived,
typename T, std::
size_t N>
732template<
typename Derived,
typename T, std::
size_t N>
736 return addLocal(rhs);
739template<
typename Derived,
typename T, std::
size_t N>
743 return addLocal(rhs);
746template<
typename Derived,
typename T, std::
size_t N>
750 return subLocal(rhs);
753template<
typename Derived,
typename T, std::
size_t N>
757 return subLocal(rhs);
760template<
typename Derived,
typename T, std::
size_t N>
764 return mulLocal(rhs);
767template<
typename Derived,
typename T, std::
size_t N>
771 return mulLocal(rhs);
774template<
typename Derived,
typename T, std::
size_t N>
778 return divLocal(rhs);
781template<
typename Derived,
typename T, std::
size_t N>
785 return divLocal(rhs);
788template<
typename Derived,
typename T, std::
size_t N>
791requires
std::is_signed_v<T>
796template<
typename Derived,
typename T, std::
size_t N>
798-> typename
std::array<T, N>::iterator
803template<
typename Derived,
typename T, std::
size_t N>
805-> typename
std::array<T, N>::const_iterator
810template<
typename Derived,
typename T, std::
size_t N>
812-> typename
std::array<T, N>::iterator
817template<
typename Derived,
typename T, std::
size_t N>
819-> typename
std::array<T, N>::const_iterator
824template<
typename Derived,
typename T, std::
size_t N>
830 std::string result(
"[");
831 result += std::to_string(m[0]);
832 for(std::size_t i = 1; i < N; ++i)
834 result +=
", " + std::to_string(m[i]);
841template<
typename Derived,
typename T, std::
size_t N>
845 std::vector<T> vector(N);
846 for(std::size_t i = 0; i < N; ++i)
854template<
typename Derived,
typename T, std::
size_t N>
861template<
typename Derived,
typename T, std::
size_t N>
868template<
typename Derived,
typename T, std::
size_t N>
auto begin() noexcept -> typename std::array< T, N >::iterator
Definition TArithmeticArrayBase.ipp:797
Derived exp(U exponent) const
Sets the array to .
bool isZero() const
Definition TArithmeticArrayBase.ipp:549
T sum() const
Definition TArithmeticArrayBase.ipp:336
Derived mul(const Derived &rhs) const
Definition TArithmeticArrayBase.ipp:98
bool operator!=(const Derived &other) const
Definition TArithmeticArrayBase.ipp:671
Derived operator*(const Derived &rhs) const
Definition TArithmeticArrayBase.ipp:705
Derived & operator+=(const Derived &rhs)
Definition TArithmeticArrayBase.ipp:733
Derived pow(U exponent) const
Derived sqrt() const
Definition TArithmeticArrayBase.ipp:246
std::vector< T > toVector() const
Definition TArithmeticArrayBase.ipp:842
T avg() const
Definition TArithmeticArrayBase.ipp:342
Derived complement() const
Complements the array's elements. Effectively performing 1 - (*this)[i] for each element.
Definition TArithmeticArrayBase.ipp:502
Derived floor() const
Definition TArithmeticArrayBase.ipp:447
std::array< T, N > toArray() const
Definition TArithmeticArrayBase.ipp:855
T product() const
Definition TArithmeticArrayBase.ipp:358
Derived & sqrtLocal()
Definition TArithmeticArrayBase.ipp:253
Derived & safeClampLocal(T lowerBound, T upperBound)
Definition TArithmeticArrayBase.ipp:307
Derived & expLocal(U exponent)
Derived safeClamp(T lowerBound, T upperBound) const
Clamps current array's elements to specific range. If a floating-point value is non-finite (e....
Definition TArithmeticArrayBase.ipp:300
TSpanView< T, N > toView() const
Definition TArithmeticArrayBase.ipp:869
Derived & divLocal(const Derived &rhs)
Definition TArithmeticArrayBase.ipp:148
Derived & set(T value)
Definition TArithmeticArrayBase.ipp:604
T & operator[](std::size_t index)
Definition TArithmeticArrayBase.ipp:630
auto end() noexcept -> typename std::array< T, N >::iterator
Definition TArithmeticArrayBase.ipp:811
Derived operator+(const Derived &rhs) const
Definition TArithmeticArrayBase.ipp:677
Derived & absLocal()
Definition TArithmeticArrayBase.ipp:473
Derived clamp(T lowerBound, T upperBound) const
Clamps current array's elements to specific range. None of value, lowerBound and upperBound can be Na...
Definition TArithmeticArrayBase.ipp:264
Derived operator/(const Derived &rhs) const
Definition TArithmeticArrayBase.ipp:719
Derived & addLocal(const Derived &rhs)
Definition TArithmeticArrayBase.ipp:40
Derived lerp(const Derived &rhs, U factor) const
Derived & operator-=(const Derived &rhs)
Definition TArithmeticArrayBase.ipp:747
Derived sub(const Derived &rhs) const
Definition TArithmeticArrayBase.ipp:62
Derived div(const Derived &rhs) const
Definition TArithmeticArrayBase.ipp:134
std::string toString() const
Definition TArithmeticArrayBase.ipp:825
Derived operator-() const
Definition TArithmeticArrayBase.ipp:789
Derived & negateLocal()
Definition TArithmeticArrayBase.ipp:528
Derived & rcpLocal()
Definition TArithmeticArrayBase.ipp:491
T min() const
Definition TArithmeticArrayBase.ipp:364
Derived abs() const
Definition TArithmeticArrayBase.ipp:466
bool isFinite() const
Definition TArithmeticArrayBase.ipp:585
std::size_t maxIndex() const
Definition TArithmeticArrayBase.ipp:414
Derived negate() const
Applies a negative sign to the array's elements. These methods is only defined for signed element typ...
Definition TArithmeticArrayBase.ipp:520
Derived & mulLocal(const Derived &rhs)
Definition TArithmeticArrayBase.ipp:112
TSpan< T, N > toSpan()
Definition TArithmeticArrayBase.ipp:862
bool isNear(const Derived &other, T margin) const
Definition TArithmeticArrayBase.ipp:652
std::size_t minIndex() const
Definition TArithmeticArrayBase.ipp:382
TArithmeticArrayBase(T value)
Definition TArithmeticArrayBase.ipp:15
T max() const
Definition TArithmeticArrayBase.ipp:396
bool isNonNegative() const
Definition TArithmeticArrayBase.ipp:565
Derived & clampLocal(T lowerBound, T upperBound)
Definition TArithmeticArrayBase.ipp:271
Derived add(const Derived &rhs) const
Definition TArithmeticArrayBase.ipp:26
Derived & subLocal(const Derived &rhs)
Definition TArithmeticArrayBase.ipp:76
constexpr std::size_t size() const noexcept
Number of elements of the array.
Definition TArithmeticArrayBase.ipp:598
bool isEqual(const Derived &other) const
Definition TArithmeticArrayBase.ipp:646
Derived & powLocal(U exponent)
std::array< T, N > Elements
Definition TArithmeticArrayBase.h:25
bool operator==(const Derived &other) const
Definition TArithmeticArrayBase.ipp:665
Derived ceil() const
Definition TArithmeticArrayBase.ipp:428
Derived & complementLocal()
Definition TArithmeticArrayBase.ipp:509
Derived & operator/=(const Derived &rhs)
Definition TArithmeticArrayBase.ipp:775
Derived rcp() const
Definition TArithmeticArrayBase.ipp:484
Derived & operator*=(const Derived &rhs)
Definition TArithmeticArrayBase.ipp:761
Miscellaneous math utilities.
Math functions and utilities.
Definition TransformInfo.h:10
T safe_clamp(const T value, const T lowerBound, const T upperBound)
Clamps a value to [lowerBound, upperBound], fallback to lowerBound. If a floating-point value is non-...
Definition math.h:98
T clamp(const T value, const T lowerBound, const T upperBound)
Clamps a value to [lowerBound, upperBound]. None of value, lowerBound and upperBound can be NaN,...
Definition math.h:77
std::span< const T, EXTENT > TSpanView
Same as TSpan, except that the objects are const-qualified. Note that for pointer types,...
Definition TSpan.h:19
std::span< T, EXTENT > TSpan
A contiguous sequence of objects of type T. Effectively the same as std::span.
Definition TSpan.h:12