| //===----------------------------------------------------------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include <__hash_table> |
| #include <algorithm> |
| #include <stdexcept> |
| #include <type_traits> |
| |
| _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wtautological-constant-out-of-range-compare") |
| |
| _LIBCPP_BEGIN_NAMESPACE_STD |
| |
| namespace { |
| |
| // handle all next_prime(i) for i in [1, 210), special case 0 |
| const unsigned small_primes[] = |
| { |
| 0, |
| 2, |
| 3, |
| 5, |
| 7, |
| 11, |
| 13, |
| 17, |
| 19, |
| 23, |
| 29, |
| 31, |
| 37, |
| 41, |
| 43, |
| 47, |
| 53, |
| 59, |
| 61, |
| 67, |
| 71, |
| 73, |
| 79, |
| 83, |
| 89, |
| 97, |
| 101, |
| 103, |
| 107, |
| 109, |
| 113, |
| 127, |
| 131, |
| 137, |
| 139, |
| 149, |
| 151, |
| 157, |
| 163, |
| 167, |
| 173, |
| 179, |
| 181, |
| 191, |
| 193, |
| 197, |
| 199, |
| 211 |
| }; |
| |
| // potential primes = 210*k + indices[i], k >= 1 |
| // these numbers are not divisible by 2, 3, 5 or 7 |
| // (or any integer 2 <= j <= 10 for that matter). |
| const unsigned indices[] = |
| { |
| 1, |
| 11, |
| 13, |
| 17, |
| 19, |
| 23, |
| 29, |
| 31, |
| 37, |
| 41, |
| 43, |
| 47, |
| 53, |
| 59, |
| 61, |
| 67, |
| 71, |
| 73, |
| 79, |
| 83, |
| 89, |
| 97, |
| 101, |
| 103, |
| 107, |
| 109, |
| 113, |
| 121, |
| 127, |
| 131, |
| 137, |
| 139, |
| 143, |
| 149, |
| 151, |
| 157, |
| 163, |
| 167, |
| 169, |
| 173, |
| 179, |
| 181, |
| 187, |
| 191, |
| 193, |
| 197, |
| 199, |
| 209 |
| }; |
| |
| } |
| |
| // Returns: If n == 0, returns 0. Else returns the lowest prime number that |
| // is greater than or equal to n. |
| // |
| // The algorithm creates a list of small primes, plus an open-ended list of |
| // potential primes. All prime numbers are potential prime numbers. However |
| // some potential prime numbers are not prime. In an ideal world, all potential |
| // prime numbers would be prime. Candidate prime numbers are chosen as the next |
| // highest potential prime. Then this number is tested for prime by dividing it |
| // by all potential prime numbers less than the sqrt of the candidate. |
| // |
| // This implementation defines potential primes as those numbers not divisible |
| // by 2, 3, 5, and 7. Other (common) implementations define potential primes |
| // as those not divisible by 2. A few other implementations define potential |
| // primes as those not divisible by 2 or 3. By raising the number of small |
| // primes which the potential prime is not divisible by, the set of potential |
| // primes more closely approximates the set of prime numbers. And thus there |
| // are fewer potential primes to search, and fewer potential primes to divide |
| // against. |
| |
| template <size_t _Sz = sizeof(size_t)> |
| inline _LIBCPP_INLINE_VISIBILITY |
| typename enable_if<_Sz == 4, void>::type |
| __check_for_overflow(size_t N) |
| { |
| if (N > 0xFFFFFFFB) |
| __throw_overflow_error("__next_prime overflow"); |
| } |
| |
| template <size_t _Sz = sizeof(size_t)> |
| inline _LIBCPP_INLINE_VISIBILITY |
| typename enable_if<_Sz == 8, void>::type |
| __check_for_overflow(size_t N) |
| { |
| if (N > 0xFFFFFFFFFFFFFFC5ull) |
| __throw_overflow_error("__next_prime overflow"); |
| } |
| |
| size_t |
| __next_prime(size_t n) |
| { |
| const size_t L = 210; |
| const size_t N = sizeof(small_primes) / sizeof(small_primes[0]); |
| // If n is small enough, search in small_primes |
| if (n <= small_primes[N-1]) |
| return *std::lower_bound(small_primes, small_primes + N, n); |
| // Else n > largest small_primes |
| // Check for overflow |
| __check_for_overflow(n); |
| // Start searching list of potential primes: L * k0 + indices[in] |
| const size_t M = sizeof(indices) / sizeof(indices[0]); |
| // Select first potential prime >= n |
| // Known a-priori n >= L |
| size_t k0 = n / L; |
| size_t in = static_cast<size_t>(std::lower_bound(indices, indices + M, n - k0 * L) |
| - indices); |
| n = L * k0 + indices[in]; |
| while (true) |
| { |
| // Divide n by all primes or potential primes (i) until: |
| // 1. The division is even, so try next potential prime. |
| // 2. The i > sqrt(n), in which case n is prime. |
| // It is known a-priori that n is not divisible by 2, 3, 5 or 7, |
| // so don't test those (j == 5 -> divide by 11 first). And the |
| // potential primes start with 211, so don't test against the last |
| // small prime. |
| for (size_t j = 5; j < N - 1; ++j) |
| { |
| const std::size_t p = small_primes[j]; |
| const std::size_t q = n / p; |
| if (q < p) |
| return n; |
| if (n == q * p) |
| goto next; |
| } |
| // n wasn't divisible by small primes, try potential primes |
| { |
| size_t i = 211; |
| while (true) |
| { |
| std::size_t q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 10; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 2; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 4; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 2; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 4; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 6; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 2; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 6; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 4; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 2; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 4; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 6; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 6; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 2; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 6; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 4; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 2; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 6; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 4; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 6; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 8; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 4; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 2; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 4; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 2; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 4; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 8; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 6; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 4; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 6; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 2; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 4; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 6; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 2; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 6; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 6; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 4; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 2; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 4; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 6; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 2; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 6; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 4; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 2; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 4; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 2; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| i += 10; |
| q = n / i; |
| if (q < i) |
| return n; |
| if (n == q * i) |
| break; |
| |
| // This will loop i to the next "plane" of potential primes |
| i += 2; |
| } |
| } |
| next: |
| // n is not prime. Increment n to next potential prime. |
| if (++in == M) |
| { |
| ++k0; |
| in = 0; |
| } |
| n = L * k0 + indices[in]; |
| } |
| } |
| |
| _LIBCPP_END_NAMESPACE_STD |