15namespace sequoia::maths
17 template<auto Num, auto Den>
20 template<auto Num, auto Den>
21 requires std::integral<
decltype(Num)> && std::integral<
decltype(Den)>
24 using num_type = std::remove_cv_t<
decltype(Num)>;
25 using den_type = std::remove_cv_t<
decltype(Den)>;
27 constexpr static auto divisor{std::gcd(Num, Den)};
28 constexpr static auto num{Num/divisor};
29 constexpr static auto den{Den/divisor};
32 template<auto Num, auto Den>
34 && (std::floating_point<
decltype(Num)> || std::floating_point<
decltype(Den)>)
37 using num_type = std::remove_cv_t<
decltype(Num)>;
38 using den_type = std::remove_cv_t<
decltype(Den)>;
42 constexpr static bool is_identity_v{Num == Den};
43 constexpr static auto num{is_identity_v ? num_type(1) : Num};
44 constexpr static auto den{is_identity_v ? den_type(1) : Den};
48 inline constexpr bool defines_ratio_v{
53 requires arithmetic<
decltype(T::num)>;
54 requires arithmetic<
decltype(T::den)>;
58 enum class allow_ratio_fp_conversion :
bool { no, yes };
63 template<allow_ratio_fp_conversion,
class...>
66 template<allow_ratio_fp_conversion Relaxed,
class T,
class U>
69 template<allow_ratio_fp_conversion Relaxed, auto Num1, auto Den1, auto Num2, auto Den2>
81 template<auto M, auto N>
82 constexpr static auto product() {
83 if constexpr ((M == 1) && (N == 1))
85 if constexpr (std::floating_point<
decltype(M)> || std::floating_point<
decltype(N)>)
86 return std::intmax_t{1};
88 return std::common_type_t<std::remove_cv_t<
decltype(M)>, std::remove_cv_t<
decltype(N)>>{1};
90 else if constexpr (M == 1)
92 else if constexpr (N == 1)
96 using common_t = std::common_type_t<std::remove_cv_t<
decltype(M)>, std::remove_cv_t<
decltype(N)>>;
97 constexpr static bool overflow{std::numeric_limits<common_t>::max() / M < N};
98 if constexpr((Relaxed == allow_ratio_fp_conversion::no) || (!overflow))
104 if constexpr(std::integral<common_t>)
106 if constexpr(std::is_signed_v<common_t> && (
sizeof(common_t) <
sizeof(std::intmax_t)))
110 else if constexpr(!std::is_signed_v<common_t> && (
sizeof(common_t) <
sizeof(std::size_t)))
116 return static_cast<long double>(M) *
static_cast<long double>(N);
121 return static_cast<long double>(M) *
static_cast<long double>(N);
133 template<allow_ratio_fp_conversion Relaxed, auto Num1, auto Den1, std::
intmax_t Num2, std::
intmax_t Den2>
136 :
ratio_product<Relaxed, ratio<Num1, Den1>, ratio<Num2, Den2>>
140 template<allow_ratio_fp_conversion Relaxed, std::
intmax_t Num1, std::
intmax_t Den1, auto Num2, auto Den2>
143 :
ratio_product<Relaxed, ratio<Num1, Den1>, ratio<Num2, Den2>>
148 template<allow_ratio_fp_conversion Relaxed, std::
intmax_t Num1, std::
intmax_t Den1, std::
intmax_t Num2, std::
intmax_t Den2>
150 :
ratio_product<Relaxed, ratio<Num1, Den1>, ratio<Num2, Den2>>
155 template<
class T,
class U, allow_ratio_fp_conversion Relaxed=allow_ratio_fp_conversion::no>
156 requires defines_ratio_v<T> && defines_ratio_v<U>
157 using ratio_multiply = impl::ratio_product_t<Relaxed, T, U>;
159 template<
class T,
class U, allow_ratio_fp_conversion Relaxed=allow_ratio_fp_conversion::no>
160 requires defines_ratio_v<T> && defines_ratio_v<U>
161 using ratio_divide = impl::ratio_product_t<Relaxed, T, ratio<U::den, U::num>>;
\brieft A concept for arithmetic types
Definition: Concepts.hpp:81
Definition: PhysicalValues.hpp:950