Path: blob/main/contrib/llvm-project/libcxx/src/hash.cpp
35147 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>11#include <type_traits>1213_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wtautological-constant-out-of-range-compare")1415_LIBCPP_BEGIN_NAMESPACE_STD1617namespace {1819// handle all next_prime(i) for i in [1, 210), special case 020const unsigned small_primes[] = {210, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47,2253, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127,23131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211};2425// potential primes = 210*k + indices[i], k >= 126// these numbers are not divisible by 2, 3, 5 or 727// (or any integer 2 <= j <= 10 for that matter).28const unsigned indices[] = {291, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67,3071, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 121, 127, 131, 137, 139,31143, 149, 151, 157, 163, 167, 169, 173, 179, 181, 187, 191, 193, 197, 199, 209};3233} // namespace3435// Returns: If n == 0, returns 0. Else returns the lowest prime number that36// is greater than or equal to n.37//38// The algorithm creates a list of small primes, plus an open-ended list of39// potential primes. All prime numbers are potential prime numbers. However40// some potential prime numbers are not prime. In an ideal world, all potential41// prime numbers would be prime. Candidate prime numbers are chosen as the next42// highest potential prime. Then this number is tested for prime by dividing it43// by all potential prime numbers less than the sqrt of the candidate.44//45// This implementation defines potential primes as those numbers not divisible46// by 2, 3, 5, and 7. Other (common) implementations define potential primes47// as those not divisible by 2. A few other implementations define potential48// primes as those not divisible by 2 or 3. By raising the number of small49// primes which the potential prime is not divisible by, the set of potential50// primes more closely approximates the set of prime numbers. And thus there51// are fewer potential primes to search, and fewer potential primes to divide52// against.5354template <size_t _Sz = sizeof(size_t)>55inline _LIBCPP_HIDE_FROM_ABI typename enable_if<_Sz == 4, void>::type __check_for_overflow(size_t N) {56if (N > 0xFFFFFFFB)57__throw_overflow_error("__next_prime overflow");58}5960template <size_t _Sz = sizeof(size_t)>61inline _LIBCPP_HIDE_FROM_ABI typename enable_if<_Sz == 8, void>::type __check_for_overflow(size_t N) {62if (N > 0xFFFFFFFFFFFFFFC5ull)63__throw_overflow_error("__next_prime overflow");64}6566size_t __next_prime(size_t n) {67const size_t L = 210;68const size_t N = sizeof(small_primes) / sizeof(small_primes[0]);69// If n is small enough, search in small_primes70if (n <= small_primes[N - 1])71return *std::lower_bound(small_primes, small_primes + N, n);72// Else n > largest small_primes73// Check for overflow74__check_for_overflow(n);75// Start searching list of potential primes: L * k0 + indices[in]76const size_t M = sizeof(indices) / sizeof(indices[0]);77// Select first potential prime >= n78// Known a-priori n >= L79size_t k0 = n / L;80size_t in = static_cast<size_t>(std::lower_bound(indices, indices + M, n - k0 * L) - indices);81n = L * k0 + indices[in];82while (true) {83// Divide n by all primes or potential primes (i) until:84// 1. The division is even, so try next potential prime.85// 2. The i > sqrt(n), in which case n is prime.86// It is known a-priori that n is not divisible by 2, 3, 5 or 7,87// so don't test those (j == 5 -> divide by 11 first). And the88// potential primes start with 211, so don't test against the last89// small prime.90for (size_t j = 5; j < N - 1; ++j) {91const std::size_t p = small_primes[j];92const std::size_t q = n / p;93if (q < p)94return n;95if (n == q * p)96goto next;97}98// n wasn't divisible by small primes, try potential primes99{100size_t i = 211;101while (true) {102std::size_t q = n / i;103if (q < i)104return n;105if (n == q * i)106break;107108i += 10;109q = n / i;110if (q < i)111return n;112if (n == q * i)113break;114115i += 2;116q = n / i;117if (q < i)118return n;119if (n == q * i)120break;121122i += 4;123q = n / i;124if (q < i)125return n;126if (n == q * i)127break;128129i += 2;130q = n / i;131if (q < i)132return n;133if (n == q * i)134break;135136i += 4;137q = n / i;138if (q < i)139return n;140if (n == q * i)141break;142143i += 6;144q = n / i;145if (q < i)146return n;147if (n == q * i)148break;149150i += 2;151q = n / i;152if (q < i)153return n;154if (n == q * i)155break;156157i += 6;158q = n / i;159if (q < i)160return n;161if (n == q * i)162break;163164i += 4;165q = n / i;166if (q < i)167return n;168if (n == q * i)169break;170171i += 2;172q = n / i;173if (q < i)174return n;175if (n == q * i)176break;177178i += 4;179q = n / i;180if (q < i)181return n;182if (n == q * i)183break;184185i += 6;186q = n / i;187if (q < i)188return n;189if (n == q * i)190break;191192i += 6;193q = n / i;194if (q < i)195return n;196if (n == q * i)197break;198199i += 2;200q = n / i;201if (q < i)202return n;203if (n == q * i)204break;205206i += 6;207q = n / i;208if (q < i)209return n;210if (n == q * i)211break;212213i += 4;214q = n / i;215if (q < i)216return n;217if (n == q * i)218break;219220i += 2;221q = n / i;222if (q < i)223return n;224if (n == q * i)225break;226227i += 6;228q = n / i;229if (q < i)230return n;231if (n == q * i)232break;233234i += 4;235q = n / i;236if (q < i)237return n;238if (n == q * i)239break;240241i += 6;242q = n / i;243if (q < i)244return n;245if (n == q * i)246break;247248i += 8;249q = n / i;250if (q < i)251return n;252if (n == q * i)253break;254255i += 4;256q = n / i;257if (q < i)258return n;259if (n == q * i)260break;261262i += 2;263q = n / i;264if (q < i)265return n;266if (n == q * i)267break;268269i += 4;270q = n / i;271if (q < i)272return n;273if (n == q * i)274break;275276i += 2;277q = n / i;278if (q < i)279return n;280if (n == q * i)281break;282283i += 4;284q = n / i;285if (q < i)286return n;287if (n == q * i)288break;289290i += 8;291q = n / i;292if (q < i)293return n;294if (n == q * i)295break;296297i += 6;298q = n / i;299if (q < i)300return n;301if (n == q * i)302break;303304i += 4;305q = n / i;306if (q < i)307return n;308if (n == q * i)309break;310311i += 6;312q = n / i;313if (q < i)314return n;315if (n == q * i)316break;317318i += 2;319q = n / i;320if (q < i)321return n;322if (n == q * i)323break;324325i += 4;326q = n / i;327if (q < i)328return n;329if (n == q * i)330break;331332i += 6;333q = n / i;334if (q < i)335return n;336if (n == q * i)337break;338339i += 2;340q = n / i;341if (q < i)342return n;343if (n == q * i)344break;345346i += 6;347q = n / i;348if (q < i)349return n;350if (n == q * i)351break;352353i += 6;354q = n / i;355if (q < i)356return n;357if (n == q * i)358break;359360i += 4;361q = n / i;362if (q < i)363return n;364if (n == q * i)365break;366367i += 2;368q = n / i;369if (q < i)370return n;371if (n == q * i)372break;373374i += 4;375q = n / i;376if (q < i)377return n;378if (n == q * i)379break;380381i += 6;382q = n / i;383if (q < i)384return n;385if (n == q * i)386break;387388i += 2;389q = n / i;390if (q < i)391return n;392if (n == q * i)393break;394395i += 6;396q = n / i;397if (q < i)398return n;399if (n == q * i)400break;401402i += 4;403q = n / i;404if (q < i)405return n;406if (n == q * i)407break;408409i += 2;410q = n / i;411if (q < i)412return n;413if (n == q * i)414break;415416i += 4;417q = n / i;418if (q < i)419return n;420if (n == q * i)421break;422423i += 2;424q = n / i;425if (q < i)426return n;427if (n == q * i)428break;429430i += 10;431q = n / i;432if (q < i)433return n;434if (n == q * i)435break;436437// This will loop i to the next "plane" of potential primes438i += 2;439}440}441next:442// n is not prime. Increment n to next potential prime.443if (++in == M) {444++k0;445in = 0;446}447n = L * k0 + indices[in];448}449}450451_LIBCPP_END_NAMESPACE_STD452453454