22 #ifndef GEARS_MATH_ALGORITHM_HPP
23 #define GEARS_MATH_ALGORITHM_HPP
25 #include <type_traits>
70 return number == 0 ? 1 : number *
factorial(number - 1);
84 constexpr T
gcd(
const T& x,
const T& y) {
85 return y == 0 ? x :
gcd(y, x % y);
106 if((exponent % 2) == 1) {
107 result = (base * result) % modulus;
110 base = (base * base) % modulus;
130 for(T i(1); i * i <= number; ++i) {
131 result += (number % i) ? 0 : ((i * i == number) ? i : i + number / i);
156 if(number % 2 == 0) {
164 if(number % 3 == 0) {
168 const T r(std::sqrt(number));
171 if(number % f == 0 || number % (f + 2) == 0) {
192 return t < 0 ? -t : t;
197 constexpr T
min(T&& t) {
198 return std::forward<T>(t);
201 template<
typename T,
typename U>
202 constexpr
typename std::common_type<T, U>::type
min(T&& t, U&& u) {
203 return u < t ? std::forward<U>(u) : std::forward<T>(t);
218 template<
typename T,
typename U,
typename... Args>
219 constexpr
typename std::common_type<T, U, Args...>::type
min(T&& t, U&& u, Args&&... args) {
220 return min(
min(std::forward<T>(t), std::forward<U>(u)),
min(std::forward<Args>(args)...));
226 constexpr T
max(T&& t) {
227 return std::forward<T>(t);
230 template<
typename T,
typename U>
231 constexpr
typename std::common_type<T, U>::type
max(T&& t, U&& u) {
232 return u < t ? std::forward<T>(t) : std::forward<U>(u);
247 template<
typename T,
typename U,
typename... Args>
248 constexpr
typename std::common_type<T, U, Args...>::type
max(T&& t, U&& u, Args&&... args) {
249 return max(
max(std::forward<T>(t), std::forward<U>(u)),
max(std::forward<Args>(args)...));
255 #endif // GEARS_MATH_ALGORITHM_HPP