| 1 | //===----------------------------------------------------------------------===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #include <__hash_table> |
| 10 | #include <algorithm> |
| 11 | #include <stdexcept> |
| 12 | |
| 13 | _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wtautological-constant-out-of-range-compare" ) |
| 14 | |
| 15 | _LIBCPP_BEGIN_NAMESPACE_STD |
| 16 | |
| 17 | namespace { |
| 18 | |
| 19 | // handle all next_prime(i) for i in [1, 210), special case 0 |
| 20 | const unsigned small_primes[] = { |
| 21 | 0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, |
| 22 | 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, |
| 23 | 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211}; |
| 24 | |
| 25 | // potential primes = 210*k + indices[i], k >= 1 |
| 26 | // these numbers are not divisible by 2, 3, 5 or 7 |
| 27 | // (or any integer 2 <= j <= 10 for that matter). |
| 28 | const unsigned indices[] = { |
| 29 | 1, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, |
| 30 | 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 121, 127, 131, 137, 139, |
| 31 | 143, 149, 151, 157, 163, 167, 169, 173, 179, 181, 187, 191, 193, 197, 199, 209}; |
| 32 | |
| 33 | // These are the amount we increment by when checking for potential |
| 34 | // primes in the loop in __next_prime. |
| 35 | const uint8_t increments[] = { |
| 36 | 0, 10, 2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2, 6, 4, 6, 8, 4, 2, |
| 37 | 4, 2, 4, 8, 6, 4, 6, 2, 4, 6, 2, 6, 6, 4, 2, 4, 6, 2, 6, 4, 2, 4, 2, 10, |
| 38 | }; |
| 39 | |
| 40 | } // namespace |
| 41 | |
| 42 | // Returns: If n == 0, returns 0. Else returns the lowest prime number that |
| 43 | // is greater than or equal to n. |
| 44 | // |
| 45 | // The algorithm creates a list of small primes, plus an open-ended list of |
| 46 | // potential primes. All prime numbers are potential prime numbers. However |
| 47 | // some potential prime numbers are not prime. In an ideal world, all potential |
| 48 | // prime numbers would be prime. Candidate prime numbers are chosen as the next |
| 49 | // highest potential prime. Then this number is tested for prime by dividing it |
| 50 | // by all potential prime numbers less than the sqrt of the candidate. |
| 51 | // |
| 52 | // This implementation defines potential primes as those numbers not divisible |
| 53 | // by 2, 3, 5, and 7. Other (common) implementations define potential primes |
| 54 | // as those not divisible by 2. A few other implementations define potential |
| 55 | // primes as those not divisible by 2 or 3. By raising the number of small |
| 56 | // primes which the potential prime is not divisible by, the set of potential |
| 57 | // primes more closely approximates the set of prime numbers. And thus there |
| 58 | // are fewer potential primes to search, and fewer potential primes to divide |
| 59 | // against. |
| 60 | |
| 61 | inline void __check_for_overflow(size_t N) { |
| 62 | if constexpr (sizeof(size_t) == 4) { |
| 63 | if (N > 0xFFFFFFFB) |
| 64 | std::__throw_overflow_error(msg: "__next_prime overflow" ); |
| 65 | } else { |
| 66 | if (N > 0xFFFFFFFFFFFFFFC5ull) |
| 67 | std::__throw_overflow_error(msg: "__next_prime overflow" ); |
| 68 | } |
| 69 | } |
| 70 | |
| 71 | size_t __next_prime(size_t n) { |
| 72 | const size_t L = 210; |
| 73 | const size_t N = sizeof(small_primes) / sizeof(small_primes[0]); |
| 74 | // If n is small enough, search in small_primes |
| 75 | if (n <= small_primes[N - 1]) |
| 76 | return *std::lower_bound(first: small_primes, last: small_primes + N, value: n); |
| 77 | // Else n > largest small_primes |
| 78 | // Check for overflow |
| 79 | __check_for_overflow(N: n); |
| 80 | // Start searching list of potential primes: L * k0 + indices[in] |
| 81 | const size_t M = sizeof(indices) / sizeof(indices[0]); |
| 82 | // Select first potential prime >= n |
| 83 | // Known a-priori n >= L |
| 84 | size_t k0 = n / L; |
| 85 | size_t in = static_cast<size_t>(std::lower_bound(first: indices, last: indices + M, value: n - k0 * L) - indices); |
| 86 | n = L * k0 + indices[in]; |
| 87 | while (true) { |
| 88 | // Divide n by all primes or potential primes (i) until: |
| 89 | // 1. The division is even, so try next potential prime. |
| 90 | // 2. The i > sqrt(n), in which case n is prime. |
| 91 | // It is known a-priori that n is not divisible by 2, 3, 5 or 7, |
| 92 | // so don't test those (j == 5 -> divide by 11 first). And the |
| 93 | // potential primes start with 211, so don't test against the last |
| 94 | // small prime. |
| 95 | for (size_t j = 5; j < N - 1; ++j) { |
| 96 | const std::size_t p = small_primes[j]; |
| 97 | const std::size_t q = n / p; |
| 98 | if (q < p) |
| 99 | return n; |
| 100 | if (n == q * p) |
| 101 | goto next; |
| 102 | } |
| 103 | // n wasn't divisible by small primes, try potential primes |
| 104 | { |
| 105 | size_t i = 211; |
| 106 | while (true) { |
| 107 | for (auto inc : increments) { |
| 108 | i += inc; |
| 109 | std::size_t q = n / i; |
| 110 | if (q < i) |
| 111 | return n; |
| 112 | if (n == q * i) |
| 113 | goto next; |
| 114 | } |
| 115 | |
| 116 | // This will loop i to the next "plane" of potential primes |
| 117 | i += 2; |
| 118 | } |
| 119 | } |
| 120 | next: |
| 121 | // n is not prime. Increment n to next potential prime. |
| 122 | if (++in == M) { |
| 123 | ++k0; |
| 124 | in = 0; |
| 125 | } |
| 126 | n = L * k0 + indices[in]; |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | _LIBCPP_END_NAMESPACE_STD |
| 131 | |