-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprimality.cc
59 lines (49 loc) · 1.64 KB
/
primality.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// from http://efesx.com/2010/01/27/compile-time-primality-test/
#include <iostream>
using number = uintmax_t;
// square root computation, using binary search
template <number num, number begin = 0, number end = num> class Sqrt {
private:
const static number mid = (begin + end) / 2;
const static number midsqr = mid * mid;
public:
const static number res = Sqrt < num, (midsqr < num) ? mid + 1 : begin,
(midsqr < num) ? end : mid > ::res;
};
// specialization for base case
template <number num, number lim> struct Sqrt<num, lim, lim> {
const static number res = lim;
};
// check for divisors
template <number num, number begin = 2, number end = Sqrt<num>::res>
struct has_any_divs {
const static bool res =
!(num % begin) || has_any_divs<num, begin + 1, end>::res;
};
// base case for divisors
template <number num, number lim> struct has_any_divs<num, lim, lim> {
const static bool res = !(num % lim);
};
// primality check (trial division)
template <number num> struct is_prime {
const static bool res = !has_any_divs<num>::res;
};
// specializations for base cases
template <> struct is_prime<2> {
const static bool res = true;
};
template <> struct is_prime<1> {
const static bool res = false;
};
template <> struct is_prime<0> {
const static bool res = false;
};
int main() {
std::cout << std::boolalpha;
std ::cout << "Is 65537 prime? " << is_prime<65537>::res << std::endl;
std ::cout << "Is 65549 prime? " << is_prime<65549>::res << std::endl;
// static assertions re: primality
static_assert(is_prime<17>::res, "17 IS NOT (?) prime");
static_assert(!is_prime<57>::res, "57 IS (?) prime");
return 0;
}