1*4bdff4beSrobert //===----------------------------------------------------------------------===//
246035553Spatrick //
346035553Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
446035553Spatrick // See https://llvm.org/LICENSE.txt for license information.
546035553Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
646035553Spatrick //
746035553Spatrick //===----------------------------------------------------------------------===//
846035553Spatrick
9*4bdff4beSrobert #include <__hash_table>
10*4bdff4beSrobert #include <algorithm>
11*4bdff4beSrobert #include <stdexcept>
12*4bdff4beSrobert #include <type_traits>
1346035553Spatrick
14*4bdff4beSrobert _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wtautological-constant-out-of-range-compare")
1546035553Spatrick
1646035553Spatrick _LIBCPP_BEGIN_NAMESPACE_STD
1746035553Spatrick
1846035553Spatrick namespace {
1946035553Spatrick
2046035553Spatrick // handle all next_prime(i) for i in [1, 210), special case 0
2146035553Spatrick const unsigned small_primes[] =
2246035553Spatrick {
2346035553Spatrick 0,
2446035553Spatrick 2,
2546035553Spatrick 3,
2646035553Spatrick 5,
2746035553Spatrick 7,
2846035553Spatrick 11,
2946035553Spatrick 13,
3046035553Spatrick 17,
3146035553Spatrick 19,
3246035553Spatrick 23,
3346035553Spatrick 29,
3446035553Spatrick 31,
3546035553Spatrick 37,
3646035553Spatrick 41,
3746035553Spatrick 43,
3846035553Spatrick 47,
3946035553Spatrick 53,
4046035553Spatrick 59,
4146035553Spatrick 61,
4246035553Spatrick 67,
4346035553Spatrick 71,
4446035553Spatrick 73,
4546035553Spatrick 79,
4646035553Spatrick 83,
4746035553Spatrick 89,
4846035553Spatrick 97,
4946035553Spatrick 101,
5046035553Spatrick 103,
5146035553Spatrick 107,
5246035553Spatrick 109,
5346035553Spatrick 113,
5446035553Spatrick 127,
5546035553Spatrick 131,
5646035553Spatrick 137,
5746035553Spatrick 139,
5846035553Spatrick 149,
5946035553Spatrick 151,
6046035553Spatrick 157,
6146035553Spatrick 163,
6246035553Spatrick 167,
6346035553Spatrick 173,
6446035553Spatrick 179,
6546035553Spatrick 181,
6646035553Spatrick 191,
6746035553Spatrick 193,
6846035553Spatrick 197,
6946035553Spatrick 199,
7046035553Spatrick 211
7146035553Spatrick };
7246035553Spatrick
7346035553Spatrick // potential primes = 210*k + indices[i], k >= 1
7446035553Spatrick // these numbers are not divisible by 2, 3, 5 or 7
7546035553Spatrick // (or any integer 2 <= j <= 10 for that matter).
7646035553Spatrick const unsigned indices[] =
7746035553Spatrick {
7846035553Spatrick 1,
7946035553Spatrick 11,
8046035553Spatrick 13,
8146035553Spatrick 17,
8246035553Spatrick 19,
8346035553Spatrick 23,
8446035553Spatrick 29,
8546035553Spatrick 31,
8646035553Spatrick 37,
8746035553Spatrick 41,
8846035553Spatrick 43,
8946035553Spatrick 47,
9046035553Spatrick 53,
9146035553Spatrick 59,
9246035553Spatrick 61,
9346035553Spatrick 67,
9446035553Spatrick 71,
9546035553Spatrick 73,
9646035553Spatrick 79,
9746035553Spatrick 83,
9846035553Spatrick 89,
9946035553Spatrick 97,
10046035553Spatrick 101,
10146035553Spatrick 103,
10246035553Spatrick 107,
10346035553Spatrick 109,
10446035553Spatrick 113,
10546035553Spatrick 121,
10646035553Spatrick 127,
10746035553Spatrick 131,
10846035553Spatrick 137,
10946035553Spatrick 139,
11046035553Spatrick 143,
11146035553Spatrick 149,
11246035553Spatrick 151,
11346035553Spatrick 157,
11446035553Spatrick 163,
11546035553Spatrick 167,
11646035553Spatrick 169,
11746035553Spatrick 173,
11846035553Spatrick 179,
11946035553Spatrick 181,
12046035553Spatrick 187,
12146035553Spatrick 191,
12246035553Spatrick 193,
12346035553Spatrick 197,
12446035553Spatrick 199,
12546035553Spatrick 209
12646035553Spatrick };
12746035553Spatrick
12846035553Spatrick }
12946035553Spatrick
13046035553Spatrick // Returns: If n == 0, returns 0. Else returns the lowest prime number that
13146035553Spatrick // is greater than or equal to n.
13246035553Spatrick //
13346035553Spatrick // The algorithm creates a list of small primes, plus an open-ended list of
13446035553Spatrick // potential primes. All prime numbers are potential prime numbers. However
13546035553Spatrick // some potential prime numbers are not prime. In an ideal world, all potential
13646035553Spatrick // prime numbers would be prime. Candidate prime numbers are chosen as the next
13746035553Spatrick // highest potential prime. Then this number is tested for prime by dividing it
13846035553Spatrick // by all potential prime numbers less than the sqrt of the candidate.
13946035553Spatrick //
14046035553Spatrick // This implementation defines potential primes as those numbers not divisible
14146035553Spatrick // by 2, 3, 5, and 7. Other (common) implementations define potential primes
14246035553Spatrick // as those not divisible by 2. A few other implementations define potential
14346035553Spatrick // primes as those not divisible by 2 or 3. By raising the number of small
14446035553Spatrick // primes which the potential prime is not divisible by, the set of potential
14546035553Spatrick // primes more closely approximates the set of prime numbers. And thus there
14646035553Spatrick // are fewer potential primes to search, and fewer potential primes to divide
14746035553Spatrick // against.
14846035553Spatrick
14946035553Spatrick template <size_t _Sz = sizeof(size_t)>
15046035553Spatrick inline _LIBCPP_INLINE_VISIBILITY
15146035553Spatrick typename enable_if<_Sz == 4, void>::type
__check_for_overflow(size_t N)15246035553Spatrick __check_for_overflow(size_t N)
15346035553Spatrick {
15446035553Spatrick if (N > 0xFFFFFFFB)
15546035553Spatrick __throw_overflow_error("__next_prime overflow");
15646035553Spatrick }
15746035553Spatrick
15846035553Spatrick template <size_t _Sz = sizeof(size_t)>
15946035553Spatrick inline _LIBCPP_INLINE_VISIBILITY
16046035553Spatrick typename enable_if<_Sz == 8, void>::type
__check_for_overflow(size_t N)16146035553Spatrick __check_for_overflow(size_t N)
16246035553Spatrick {
16346035553Spatrick if (N > 0xFFFFFFFFFFFFFFC5ull)
16446035553Spatrick __throw_overflow_error("__next_prime overflow");
16546035553Spatrick }
16646035553Spatrick
16746035553Spatrick size_t
__next_prime(size_t n)16846035553Spatrick __next_prime(size_t n)
16946035553Spatrick {
17046035553Spatrick const size_t L = 210;
17146035553Spatrick const size_t N = sizeof(small_primes) / sizeof(small_primes[0]);
17246035553Spatrick // If n is small enough, search in small_primes
17346035553Spatrick if (n <= small_primes[N-1])
17446035553Spatrick return *std::lower_bound(small_primes, small_primes + N, n);
17546035553Spatrick // Else n > largest small_primes
17646035553Spatrick // Check for overflow
17746035553Spatrick __check_for_overflow(n);
17846035553Spatrick // Start searching list of potential primes: L * k0 + indices[in]
17946035553Spatrick const size_t M = sizeof(indices) / sizeof(indices[0]);
18046035553Spatrick // Select first potential prime >= n
18146035553Spatrick // Known a-priori n >= L
18246035553Spatrick size_t k0 = n / L;
18346035553Spatrick size_t in = static_cast<size_t>(std::lower_bound(indices, indices + M, n - k0 * L)
18446035553Spatrick - indices);
18546035553Spatrick n = L * k0 + indices[in];
18646035553Spatrick while (true)
18746035553Spatrick {
18846035553Spatrick // Divide n by all primes or potential primes (i) until:
18946035553Spatrick // 1. The division is even, so try next potential prime.
19046035553Spatrick // 2. The i > sqrt(n), in which case n is prime.
19146035553Spatrick // It is known a-priori that n is not divisible by 2, 3, 5 or 7,
19246035553Spatrick // so don't test those (j == 5 -> divide by 11 first). And the
19346035553Spatrick // potential primes start with 211, so don't test against the last
19446035553Spatrick // small prime.
19546035553Spatrick for (size_t j = 5; j < N - 1; ++j)
19646035553Spatrick {
19746035553Spatrick const std::size_t p = small_primes[j];
19846035553Spatrick const std::size_t q = n / p;
19946035553Spatrick if (q < p)
20046035553Spatrick return n;
20146035553Spatrick if (n == q * p)
20246035553Spatrick goto next;
20346035553Spatrick }
20446035553Spatrick // n wasn't divisible by small primes, try potential primes
20546035553Spatrick {
20646035553Spatrick size_t i = 211;
20746035553Spatrick while (true)
20846035553Spatrick {
20946035553Spatrick std::size_t q = n / i;
21046035553Spatrick if (q < i)
21146035553Spatrick return n;
21246035553Spatrick if (n == q * i)
21346035553Spatrick break;
21446035553Spatrick
21546035553Spatrick i += 10;
21646035553Spatrick q = n / i;
21746035553Spatrick if (q < i)
21846035553Spatrick return n;
21946035553Spatrick if (n == q * i)
22046035553Spatrick break;
22146035553Spatrick
22246035553Spatrick i += 2;
22346035553Spatrick q = n / i;
22446035553Spatrick if (q < i)
22546035553Spatrick return n;
22646035553Spatrick if (n == q * i)
22746035553Spatrick break;
22846035553Spatrick
22946035553Spatrick i += 4;
23046035553Spatrick q = n / i;
23146035553Spatrick if (q < i)
23246035553Spatrick return n;
23346035553Spatrick if (n == q * i)
23446035553Spatrick break;
23546035553Spatrick
23646035553Spatrick i += 2;
23746035553Spatrick q = n / i;
23846035553Spatrick if (q < i)
23946035553Spatrick return n;
24046035553Spatrick if (n == q * i)
24146035553Spatrick break;
24246035553Spatrick
24346035553Spatrick i += 4;
24446035553Spatrick q = n / i;
24546035553Spatrick if (q < i)
24646035553Spatrick return n;
24746035553Spatrick if (n == q * i)
24846035553Spatrick break;
24946035553Spatrick
25046035553Spatrick i += 6;
25146035553Spatrick q = n / i;
25246035553Spatrick if (q < i)
25346035553Spatrick return n;
25446035553Spatrick if (n == q * i)
25546035553Spatrick break;
25646035553Spatrick
25746035553Spatrick i += 2;
25846035553Spatrick q = n / i;
25946035553Spatrick if (q < i)
26046035553Spatrick return n;
26146035553Spatrick if (n == q * i)
26246035553Spatrick break;
26346035553Spatrick
26446035553Spatrick i += 6;
26546035553Spatrick q = n / i;
26646035553Spatrick if (q < i)
26746035553Spatrick return n;
26846035553Spatrick if (n == q * i)
26946035553Spatrick break;
27046035553Spatrick
27146035553Spatrick i += 4;
27246035553Spatrick q = n / i;
27346035553Spatrick if (q < i)
27446035553Spatrick return n;
27546035553Spatrick if (n == q * i)
27646035553Spatrick break;
27746035553Spatrick
27846035553Spatrick i += 2;
27946035553Spatrick q = n / i;
28046035553Spatrick if (q < i)
28146035553Spatrick return n;
28246035553Spatrick if (n == q * i)
28346035553Spatrick break;
28446035553Spatrick
28546035553Spatrick i += 4;
28646035553Spatrick q = n / i;
28746035553Spatrick if (q < i)
28846035553Spatrick return n;
28946035553Spatrick if (n == q * i)
29046035553Spatrick break;
29146035553Spatrick
29246035553Spatrick i += 6;
29346035553Spatrick q = n / i;
29446035553Spatrick if (q < i)
29546035553Spatrick return n;
29646035553Spatrick if (n == q * i)
29746035553Spatrick break;
29846035553Spatrick
29946035553Spatrick i += 6;
30046035553Spatrick q = n / i;
30146035553Spatrick if (q < i)
30246035553Spatrick return n;
30346035553Spatrick if (n == q * i)
30446035553Spatrick break;
30546035553Spatrick
30646035553Spatrick i += 2;
30746035553Spatrick q = n / i;
30846035553Spatrick if (q < i)
30946035553Spatrick return n;
31046035553Spatrick if (n == q * i)
31146035553Spatrick break;
31246035553Spatrick
31346035553Spatrick i += 6;
31446035553Spatrick q = n / i;
31546035553Spatrick if (q < i)
31646035553Spatrick return n;
31746035553Spatrick if (n == q * i)
31846035553Spatrick break;
31946035553Spatrick
32046035553Spatrick i += 4;
32146035553Spatrick q = n / i;
32246035553Spatrick if (q < i)
32346035553Spatrick return n;
32446035553Spatrick if (n == q * i)
32546035553Spatrick break;
32646035553Spatrick
32746035553Spatrick i += 2;
32846035553Spatrick q = n / i;
32946035553Spatrick if (q < i)
33046035553Spatrick return n;
33146035553Spatrick if (n == q * i)
33246035553Spatrick break;
33346035553Spatrick
33446035553Spatrick i += 6;
33546035553Spatrick q = n / i;
33646035553Spatrick if (q < i)
33746035553Spatrick return n;
33846035553Spatrick if (n == q * i)
33946035553Spatrick break;
34046035553Spatrick
34146035553Spatrick i += 4;
34246035553Spatrick q = n / i;
34346035553Spatrick if (q < i)
34446035553Spatrick return n;
34546035553Spatrick if (n == q * i)
34646035553Spatrick break;
34746035553Spatrick
34846035553Spatrick i += 6;
34946035553Spatrick q = n / i;
35046035553Spatrick if (q < i)
35146035553Spatrick return n;
35246035553Spatrick if (n == q * i)
35346035553Spatrick break;
35446035553Spatrick
35546035553Spatrick i += 8;
35646035553Spatrick q = n / i;
35746035553Spatrick if (q < i)
35846035553Spatrick return n;
35946035553Spatrick if (n == q * i)
36046035553Spatrick break;
36146035553Spatrick
36246035553Spatrick i += 4;
36346035553Spatrick q = n / i;
36446035553Spatrick if (q < i)
36546035553Spatrick return n;
36646035553Spatrick if (n == q * i)
36746035553Spatrick break;
36846035553Spatrick
36946035553Spatrick i += 2;
37046035553Spatrick q = n / i;
37146035553Spatrick if (q < i)
37246035553Spatrick return n;
37346035553Spatrick if (n == q * i)
37446035553Spatrick break;
37546035553Spatrick
37646035553Spatrick i += 4;
37746035553Spatrick q = n / i;
37846035553Spatrick if (q < i)
37946035553Spatrick return n;
38046035553Spatrick if (n == q * i)
38146035553Spatrick break;
38246035553Spatrick
38346035553Spatrick i += 2;
38446035553Spatrick q = n / i;
38546035553Spatrick if (q < i)
38646035553Spatrick return n;
38746035553Spatrick if (n == q * i)
38846035553Spatrick break;
38946035553Spatrick
39046035553Spatrick i += 4;
39146035553Spatrick q = n / i;
39246035553Spatrick if (q < i)
39346035553Spatrick return n;
39446035553Spatrick if (n == q * i)
39546035553Spatrick break;
39646035553Spatrick
39746035553Spatrick i += 8;
39846035553Spatrick q = n / i;
39946035553Spatrick if (q < i)
40046035553Spatrick return n;
40146035553Spatrick if (n == q * i)
40246035553Spatrick break;
40346035553Spatrick
40446035553Spatrick i += 6;
40546035553Spatrick q = n / i;
40646035553Spatrick if (q < i)
40746035553Spatrick return n;
40846035553Spatrick if (n == q * i)
40946035553Spatrick break;
41046035553Spatrick
41146035553Spatrick i += 4;
41246035553Spatrick q = n / i;
41346035553Spatrick if (q < i)
41446035553Spatrick return n;
41546035553Spatrick if (n == q * i)
41646035553Spatrick break;
41746035553Spatrick
41846035553Spatrick i += 6;
41946035553Spatrick q = n / i;
42046035553Spatrick if (q < i)
42146035553Spatrick return n;
42246035553Spatrick if (n == q * i)
42346035553Spatrick break;
42446035553Spatrick
42546035553Spatrick i += 2;
42646035553Spatrick q = n / i;
42746035553Spatrick if (q < i)
42846035553Spatrick return n;
42946035553Spatrick if (n == q * i)
43046035553Spatrick break;
43146035553Spatrick
43246035553Spatrick i += 4;
43346035553Spatrick q = n / i;
43446035553Spatrick if (q < i)
43546035553Spatrick return n;
43646035553Spatrick if (n == q * i)
43746035553Spatrick break;
43846035553Spatrick
43946035553Spatrick i += 6;
44046035553Spatrick q = n / i;
44146035553Spatrick if (q < i)
44246035553Spatrick return n;
44346035553Spatrick if (n == q * i)
44446035553Spatrick break;
44546035553Spatrick
44646035553Spatrick i += 2;
44746035553Spatrick q = n / i;
44846035553Spatrick if (q < i)
44946035553Spatrick return n;
45046035553Spatrick if (n == q * i)
45146035553Spatrick break;
45246035553Spatrick
45346035553Spatrick i += 6;
45446035553Spatrick q = n / i;
45546035553Spatrick if (q < i)
45646035553Spatrick return n;
45746035553Spatrick if (n == q * i)
45846035553Spatrick break;
45946035553Spatrick
46046035553Spatrick i += 6;
46146035553Spatrick q = n / i;
46246035553Spatrick if (q < i)
46346035553Spatrick return n;
46446035553Spatrick if (n == q * i)
46546035553Spatrick break;
46646035553Spatrick
46746035553Spatrick i += 4;
46846035553Spatrick q = n / i;
46946035553Spatrick if (q < i)
47046035553Spatrick return n;
47146035553Spatrick if (n == q * i)
47246035553Spatrick break;
47346035553Spatrick
47446035553Spatrick i += 2;
47546035553Spatrick q = n / i;
47646035553Spatrick if (q < i)
47746035553Spatrick return n;
47846035553Spatrick if (n == q * i)
47946035553Spatrick break;
48046035553Spatrick
48146035553Spatrick i += 4;
48246035553Spatrick q = n / i;
48346035553Spatrick if (q < i)
48446035553Spatrick return n;
48546035553Spatrick if (n == q * i)
48646035553Spatrick break;
48746035553Spatrick
48846035553Spatrick i += 6;
48946035553Spatrick q = n / i;
49046035553Spatrick if (q < i)
49146035553Spatrick return n;
49246035553Spatrick if (n == q * i)
49346035553Spatrick break;
49446035553Spatrick
49546035553Spatrick i += 2;
49646035553Spatrick q = n / i;
49746035553Spatrick if (q < i)
49846035553Spatrick return n;
49946035553Spatrick if (n == q * i)
50046035553Spatrick break;
50146035553Spatrick
50246035553Spatrick i += 6;
50346035553Spatrick q = n / i;
50446035553Spatrick if (q < i)
50546035553Spatrick return n;
50646035553Spatrick if (n == q * i)
50746035553Spatrick break;
50846035553Spatrick
50946035553Spatrick i += 4;
51046035553Spatrick q = n / i;
51146035553Spatrick if (q < i)
51246035553Spatrick return n;
51346035553Spatrick if (n == q * i)
51446035553Spatrick break;
51546035553Spatrick
51646035553Spatrick i += 2;
51746035553Spatrick q = n / i;
51846035553Spatrick if (q < i)
51946035553Spatrick return n;
52046035553Spatrick if (n == q * i)
52146035553Spatrick break;
52246035553Spatrick
52346035553Spatrick i += 4;
52446035553Spatrick q = n / i;
52546035553Spatrick if (q < i)
52646035553Spatrick return n;
52746035553Spatrick if (n == q * i)
52846035553Spatrick break;
52946035553Spatrick
53046035553Spatrick i += 2;
53146035553Spatrick q = n / i;
53246035553Spatrick if (q < i)
53346035553Spatrick return n;
53446035553Spatrick if (n == q * i)
53546035553Spatrick break;
53646035553Spatrick
53746035553Spatrick i += 10;
53846035553Spatrick q = n / i;
53946035553Spatrick if (q < i)
54046035553Spatrick return n;
54146035553Spatrick if (n == q * i)
54246035553Spatrick break;
54346035553Spatrick
54446035553Spatrick // This will loop i to the next "plane" of potential primes
54546035553Spatrick i += 2;
54646035553Spatrick }
54746035553Spatrick }
54846035553Spatrick next:
54946035553Spatrick // n is not prime. Increment n to next potential prime.
55046035553Spatrick if (++in == M)
55146035553Spatrick {
55246035553Spatrick ++k0;
55346035553Spatrick in = 0;
55446035553Spatrick }
55546035553Spatrick n = L * k0 + indices[in];
55646035553Spatrick }
55746035553Spatrick }
55846035553Spatrick
55946035553Spatrick _LIBCPP_END_NAMESPACE_STD
560