MT Core (C++)
Core library for replacing C++ standard in project usage
Loading...
Searching...
No Matches
templates.hpp
Go to the documentation of this file.
1/*
2
3Copyright 2025 Matthew Tolman
4
5Licensed under the Apache License, Version 2.0 (the "License");
6you may not use this file except in compliance with the License.
7You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11Unless required by applicable law or agreed to in writing, software
12distributed under the License is distributed on an "AS IS" BASIS,
13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14See the License for the specific language governing permissions and
15limitations under the License.
16
17*/
18
19#ifndef MTCORE_MATH_TEMPLATES_H
20#define MTCORE_MATH_TEMPLATES_H
21
22#include "mtcore/math/core.hpp"
23#include "mtcore/meta/base.hpp"
24
25#include <ratio>
26
27namespace mtcore::math {
34 template<intmax_t A, intmax_t B>
35 struct GCD;
36
37 template<intmax_t A>
38 struct GCD<A, 0> {
39 static constexpr auto value = A;
40 };
41
42 template<intmax_t A, intmax_t B>
43 struct GCD {
44 static constexpr auto t = B;
45 static constexpr auto b = math::mod(A, B);
46 static constexpr auto a = t;
47 static constexpr auto value = GCD<a, b>::value;
48 };
49
56 template<intmax_t A, intmax_t B>
57 struct LCM {
58 static constexpr auto value = math::abs(A) * (math::abs(B) / GCD<A, B>::value);
59 };
60
69 template<typename T1, typename T2>
70 struct MultRatios;
71
72 template<intmax_t N1, intmax_t D1, intmax_t N2, intmax_t D2>
73 struct MultRatios<std::ratio<N1, D1>, std::ratio<N2, D2>> {
74 static constexpr auto NRaw = N1 * N2;
75 static constexpr auto DRaw = D1 * D2;
76 static constexpr auto Gcd = math::gcd(NRaw, DRaw);
77 static constexpr auto N = NRaw / Gcd;
78 static constexpr auto D = DRaw / Gcd;
79
80 using T = std::ratio<N, D>;
81 };
82
83 static_assert(std::same_as<MultRatios<std::ratio<2, 3>, std::ratio<2, 3>>::T, std::ratio<4, 9>>);
84
93 template<typename T1, typename T2>
94 struct AddRatios;
95
96 template<intmax_t N1, intmax_t D1, intmax_t N2, intmax_t D2>
97 struct AddRatios<std::ratio<N1, D1>, std::ratio<N2, D2>> {
98 static constexpr auto NewDenom = math::lcm(D1, D2);
99 static constexpr auto M1 = NewDenom / math::gcd(D1, NewDenom);
100 static constexpr auto M2 = NewDenom / math::gcd(D2, NewDenom);
101 static constexpr auto NN1 = N1 * M1;
102 static constexpr auto NN2 = N2 * M2;
103 static constexpr auto NN = NN1 + NN2;
104 static constexpr auto NG = math::gcd(NN, NewDenom);
105
106 using T = std::ratio<NN / NG, NewDenom / NG>;
107 };
108
109 static_assert(std::same_as<AddRatios<std::ratio<2, 15>, std::ratio<1, 5>>::T, std::ratio<1, 3>>);
110
116 template<typename T>
118
119 template<intmax_t Num, intmax_t Den>
120 struct RatioParts<std::ratio<Num, Den>> {
121 static constexpr intmax_t Numerator = Num;
122 static constexpr intmax_t Denominator = Den;
123 };
124
125 static_assert(RatioParts<std::ratio<2, 15>>::Numerator == 2);
126 static_assert(RatioParts<std::ratio<2, 15>>::Denominator == 15);
127
133 template<typename T>
135
136 template<intmax_t Num, intmax_t Den>
137 struct InvertRatio<std::ratio<Num, Den>> {
138 using T = std::ratio<Den, Num>;
139 };
140
146 template<typename T>
148
149 template<intmax_t Num, intmax_t Den>
150 struct NegateRatio<std::ratio<Num, Den>> {
151 using T = std::ratio<-Num, Den>;
152 };
153
159 template<typename T, int Pow, bool Odd, bool Neg, bool Z>
161
162 template<intmax_t N, intmax_t D>
163 struct IntPowRatioImpl<std::ratio<N, D>, 0, false, false, true> {
164 using T = std::ratio<1>;
165 };
166
167 template<intmax_t N, intmax_t D, int Pow, bool Odd>
168 struct IntPowRatioImpl<std::ratio<N, D>, Pow, Odd, true, false> {
169 using T = typename IntPowRatioImpl<std::ratio<D, N>, -Pow, (-Pow) % 2 == 1, false, false>::T;
170 };
171
172 template<intmax_t N, intmax_t D, int Pow>
173 struct IntPowRatioImpl<std::ratio<N, D>, Pow, false, false, false> {
174 using R = std::ratio<N, D>;
175 static constexpr auto PN = Pow / 2;
176 using T = typename IntPowRatioImpl<typename MultRatios<R, R>::T, PN, PN % 2 == 1, false, PN == 0>::T;
177 };
178
179 template<intmax_t N, intmax_t D, int Pow>
180 struct IntPowRatioImpl<std::ratio<N, D>, Pow, true, false, false> {
181 using R = std::ratio<N, D>;
182 using T = typename meta::If<
183 Pow == 1, R, typename MultRatios<R, typename IntPowRatioImpl<R, Pow - 1, false, false, Pow - 1 == 0>::T>::T>::T;
184 };
185
186 template<typename R, int Pow>
187 struct IntPowRatio {
188 using T = typename IntPowRatioImpl < R, Pow, Pow % 2 == 1, Pow<0, Pow == 0>::T;
189 };
190
191 static_assert(std::same_as<std::ratio<4, 9>, IntPowRatio<std::ratio<2, 3>, 2>::T>);
192
193 static_assert(std::same_as<std::ratio<8, 27>, IntPowRatio<std::ratio<2, 3>, 3>::T>);
194} // namespace mtcore::math
195
196#endif // MTCORE_MATH_TEMPLATES_H
constexpr Res mod(L left, R right) noexcept
Calculates the mathematical mod of two numbers.
constexpr T lcm(T a, T b)
Calculates the LCM (Least Common Multiple) of two integer numbers.
constexpr L abs(L l)
Gets absolute value of a number.
constexpr T gcd(T a, T b)
Calculates the GCD (Greatest Common Divisor) of two integer numbers.
Math utilities, often with constexpr support.
Template to add two std::ratio numbers.
Definition templates.hpp:94
static constexpr auto value
Definition templates.hpp:39
Template to get GCD of numbers.
Definition templates.hpp:43
static constexpr auto b
Definition templates.hpp:45
static constexpr auto t
Definition templates.hpp:44
static constexpr auto a
Definition templates.hpp:46
static constexpr auto value
Definition templates.hpp:47
typename IntPowRatioImpl< std::ratio< D, N >, -Pow,(-Pow) % 2==1, false, false >::T T
typename IntPowRatioImpl< typename MultRatios< R, R >::T, PN, PN % 2==1, false, PN==0 >::T T
typename meta::If< Pow==1, R, typename MultRatios< R, typename IntPowRatioImpl< R, Pow - 1, false, false, Pow - 1==0 >::T >::T >::T T
Template to get the integer power (positive or negative) of a ratio.
typename IntPowRatioImpl< R, Pow, Pow % 2==1, Pow< 0, Pow==0 >::T T
Template to invert a ratio number.
Template to get LCM of numbers.
Definition templates.hpp:57
static constexpr auto value
Definition templates.hpp:58
Template to multiply two std::ratio numbers.
Definition templates.hpp:70
Template to negate the power of a ratio.
Template to get the Numerator and Denominator of a std::ratio.
Switches types based on a condition.
Definition meta/base.hpp:39