xref: /openbsd/gnu/llvm/libcxx/src/hash.cpp (revision 4bdff4be)
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