All Classes Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
algorithm.hpp
1 // The MIT License (MIT)
2 
3 // Copyright (c) 2012-2014 Danny Y., Rapptz
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 // this software and associated documentation files (the "Software"), to deal in
7 // the Software without restriction, including without limitation the rights to
8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 // the Software, and to permit persons to whom the Software is furnished to do so,
10 // subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22 #ifndef GEARS_MATH_ALGORITHM_HPP
23 #define GEARS_MATH_ALGORITHM_HPP
24 
25 #include <type_traits>
26 #include <utility>
27 
28 namespace gears {
29 namespace math {
39 template<typename T>
40 inline T fibonacci(T number) {
41  if(number < 2) {
42  return number;
43  }
44 
45  T a(1);
46  T b(0);
47  T c(0);
48 
49  while(--number) {
50  c = b;
51  b = a;
52  a = b + c;
53  }
54 
55  return a;
56 }
57 
68 template<typename T>
69 constexpr T factorial(const T& number) {
70  return number == 0 ? 1 : number * factorial(number - 1);
71 }
72 
83 template<typename T>
84 constexpr T gcd(const T& x, const T& y) {
85  return y == 0 ? x : gcd(y, x % y);
86 }
87 
101 template<typename T>
102 inline T mod_pow(T base, T exponent, const T& modulus) {
103  T result(1);
104 
105  while(exponent) {
106  if((exponent % 2) == 1) {
107  result = (base * result) % modulus;
108  }
109  exponent /= 2;
110  base = (base * base) % modulus;
111  }
112 
113  return result;
114 }
115 
127 template<typename T>
128 inline T sum_of_divisors(const T& number) noexcept {
129  T result(0);
130  for(T i(1); i * i <= number; ++i) {
131  result += (number % i) ? 0 : ((i * i == number) ? i : i + number / i);
132  }
133  return result;
134 }
135 
146 template<typename T>
147 inline bool is_prime(const T& number) noexcept {
148  if(number == 1) {
149  return false;
150  }
151 
152  if(number < 4) {
153  return true;
154  }
155 
156  if(number % 2 == 0) {
157  return false;
158  }
159 
160  if(number < 9) {
161  return true;
162  }
163 
164  if(number % 3 == 0) {
165  return false;
166  }
167 
168  const T r(std::sqrt(number));
169  T f(5);
170  while(f <= r) {
171  if(number % f == 0 || number % (f + 2) == 0) {
172  return false;
173  }
174  f += 6;
175  }
176  return true;
177 }
178 
190 template<typename T>
191 constexpr T abs(T t) {
192  return t < 0 ? -t : t;
193 }
194 
196 template<typename T>
197 constexpr T min(T&& t) {
198  return std::forward<T>(t);
199 }
200 
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);
204 }
205 
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)...));
221 }
223 
225 template<typename T>
226 constexpr T max(T&& t) {
227  return std::forward<T>(t);
228 }
229 
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);
233 }
234 
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)...));
250 }
252 } // math
253 } // gears
254 
255 #endif // GEARS_MATH_ALGORITHM_HPP