Path: blob/main/system/lib/libcxx/src/hash.cpp
6175 views
//===----------------------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include <__hash_table>9#include <algorithm>10#include <stdexcept>1112_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wtautological-constant-out-of-range-compare")1314_LIBCPP_BEGIN_NAMESPACE_STD1516namespace {1718// handle all next_prime(i) for i in [1, 210), special case 019const unsigned small_primes[] = {200, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47,2153, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127,22131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211};2324// potential primes = 210*k + indices[i], k >= 125// these numbers are not divisible by 2, 3, 5 or 726// (or any integer 2 <= j <= 10 for that matter).27const unsigned indices[] = {281, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67,2971, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 121, 127, 131, 137, 139,30143, 149, 151, 157, 163, 167, 169, 173, 179, 181, 187, 191, 193, 197, 199, 209};3132} // namespace3334// Returns: If n == 0, returns 0. Else returns the lowest prime number that35// is greater than or equal to n.36//37// The algorithm creates a list of small primes, plus an open-ended list of38// potential primes. All prime numbers are potential prime numbers. However39// some potential prime numbers are not prime. In an ideal world, all potential40// prime numbers would be prime. Candidate prime numbers are chosen as the next41// highest potential prime. Then this number is tested for prime by dividing it42// by all potential prime numbers less than the sqrt of the candidate.43//44// This implementation defines potential primes as those numbers not divisible45// by 2, 3, 5, and 7. Other (common) implementations define potential primes46// as those not divisible by 2. A few other implementations define potential47// primes as those not divisible by 2 or 3. By raising the number of small48// primes which the potential prime is not divisible by, the set of potential49// primes more closely approximates the set of prime numbers. And thus there50// are fewer potential primes to search, and fewer potential primes to divide51// against.5253inline void __check_for_overflow(size_t N) {54if constexpr (sizeof(size_t) == 4) {55if (N > 0xFFFFFFFB)56std::__throw_overflow_error("__next_prime overflow");57} else {58if (N > 0xFFFFFFFFFFFFFFC5ull)59std::__throw_overflow_error("__next_prime overflow");60}61}6263size_t __next_prime(size_t n) {64const size_t L = 210;65const size_t N = sizeof(small_primes) / sizeof(small_primes[0]);66// If n is small enough, search in small_primes67if (n <= small_primes[N - 1])68return *std::lower_bound(small_primes, small_primes + N, n);69// Else n > largest small_primes70// Check for overflow71__check_for_overflow(n);72// Start searching list of potential primes: L * k0 + indices[in]73const size_t M = sizeof(indices) / sizeof(indices[0]);74// Select first potential prime >= n75// Known a-priori n >= L76size_t k0 = n / L;77size_t in = static_cast<size_t>(std::lower_bound(indices, indices + M, n - k0 * L) - indices);78n = L * k0 + indices[in];79while (true) {80// Divide n by all primes or potential primes (i) until:81// 1. The division is even, so try next potential prime.82// 2. The i > sqrt(n), in which case n is prime.83// It is known a-priori that n is not divisible by 2, 3, 5 or 7,84// so don't test those (j == 5 -> divide by 11 first). And the85// potential primes start with 211, so don't test against the last86// small prime.87for (size_t j = 5; j < N - 1; ++j) {88const std::size_t p = small_primes[j];89const std::size_t q = n / p;90if (q < p)91return n;92if (n == q * p)93goto next;94}95// n wasn't divisible by small primes, try potential primes96{97size_t i = 211;98while (true) {99std::size_t q = n / i;100if (q < i)101return n;102if (n == q * i)103break;104105i += 10;106q = n / i;107if (q < i)108return n;109if (n == q * i)110break;111112i += 2;113q = n / i;114if (q < i)115return n;116if (n == q * i)117break;118119i += 4;120q = n / i;121if (q < i)122return n;123if (n == q * i)124break;125126i += 2;127q = n / i;128if (q < i)129return n;130if (n == q * i)131break;132133i += 4;134q = n / i;135if (q < i)136return n;137if (n == q * i)138break;139140i += 6;141q = n / i;142if (q < i)143return n;144if (n == q * i)145break;146147i += 2;148q = n / i;149if (q < i)150return n;151if (n == q * i)152break;153154i += 6;155q = n / i;156if (q < i)157return n;158if (n == q * i)159break;160161i += 4;162q = n / i;163if (q < i)164return n;165if (n == q * i)166break;167168i += 2;169q = n / i;170if (q < i)171return n;172if (n == q * i)173break;174175i += 4;176q = n / i;177if (q < i)178return n;179if (n == q * i)180break;181182i += 6;183q = n / i;184if (q < i)185return n;186if (n == q * i)187break;188189i += 6;190q = n / i;191if (q < i)192return n;193if (n == q * i)194break;195196i += 2;197q = n / i;198if (q < i)199return n;200if (n == q * i)201break;202203i += 6;204q = n / i;205if (q < i)206return n;207if (n == q * i)208break;209210i += 4;211q = n / i;212if (q < i)213return n;214if (n == q * i)215break;216217i += 2;218q = n / i;219if (q < i)220return n;221if (n == q * i)222break;223224i += 6;225q = n / i;226if (q < i)227return n;228if (n == q * i)229break;230231i += 4;232q = n / i;233if (q < i)234return n;235if (n == q * i)236break;237238i += 6;239q = n / i;240if (q < i)241return n;242if (n == q * i)243break;244245i += 8;246q = n / i;247if (q < i)248return n;249if (n == q * i)250break;251252i += 4;253q = n / i;254if (q < i)255return n;256if (n == q * i)257break;258259i += 2;260q = n / i;261if (q < i)262return n;263if (n == q * i)264break;265266i += 4;267q = n / i;268if (q < i)269return n;270if (n == q * i)271break;272273i += 2;274q = n / i;275if (q < i)276return n;277if (n == q * i)278break;279280i += 4;281q = n / i;282if (q < i)283return n;284if (n == q * i)285break;286287i += 8;288q = n / i;289if (q < i)290return n;291if (n == q * i)292break;293294i += 6;295q = n / i;296if (q < i)297return n;298if (n == q * i)299break;300301i += 4;302q = n / i;303if (q < i)304return n;305if (n == q * i)306break;307308i += 6;309q = n / i;310if (q < i)311return n;312if (n == q * i)313break;314315i += 2;316q = n / i;317if (q < i)318return n;319if (n == q * i)320break;321322i += 4;323q = n / i;324if (q < i)325return n;326if (n == q * i)327break;328329i += 6;330q = n / i;331if (q < i)332return n;333if (n == q * i)334break;335336i += 2;337q = n / i;338if (q < i)339return n;340if (n == q * i)341break;342343i += 6;344q = n / i;345if (q < i)346return n;347if (n == q * i)348break;349350i += 6;351q = n / i;352if (q < i)353return n;354if (n == q * i)355break;356357i += 4;358q = n / i;359if (q < i)360return n;361if (n == q * i)362break;363364i += 2;365q = n / i;366if (q < i)367return n;368if (n == q * i)369break;370371i += 4;372q = n / i;373if (q < i)374return n;375if (n == q * i)376break;377378i += 6;379q = n / i;380if (q < i)381return n;382if (n == q * i)383break;384385i += 2;386q = n / i;387if (q < i)388return n;389if (n == q * i)390break;391392i += 6;393q = n / i;394if (q < i)395return n;396if (n == q * i)397break;398399i += 4;400q = n / i;401if (q < i)402return n;403if (n == q * i)404break;405406i += 2;407q = n / i;408if (q < i)409return n;410if (n == q * i)411break;412413i += 4;414q = n / i;415if (q < i)416return n;417if (n == q * i)418break;419420i += 2;421q = n / i;422if (q < i)423return n;424if (n == q * i)425break;426427i += 10;428q = n / i;429if (q < i)430return n;431if (n == q * i)432break;433434// This will loop i to the next "plane" of potential primes435i += 2;436}437}438next:439// n is not prime. Increment n to next potential prime.440if (++in == M) {441++k0;442in = 0;443}444n = L * k0 + indices[in];445}446}447448_LIBCPP_END_NAMESPACE_STD449450451