mirror of
https://github.com/opnsense/src.git
synced 2026-02-16 09:08:51 -05:00
C++14 support[1], adds more C++1z features[2], and fixes the following
LWG issues[3]:
1450: Contradiction in regex_constants
2003: String exception inconsistency in erase.
2075: Progress guarantees, lock-free property, and scheduling
assumptions
2104: unique_lock move-assignment should not be noexcept
2112: User-defined classes that cannot be derived from
2132: std::function ambiguity
2135: Unclear requirement for exceptions thrown in
condition_variable::wait()
2142: packaged_task::operator() synchronization too broad?
2182: Container::[const_]reference types are misleadingly specified
2186: Incomplete action on async/launch::deferred
2188: Reverse iterator does not fully support targets that overload
operator&
2193: Default constructors for standard library containers are explicit
2205: Problematic postconditions of regex_match and regex_search
2213: Return value of std::regex_replace
2240: Probable misuse of term "function scope" in [thread.condition]
2252: Strong guarantee on vector::push_back() still broken with C++11?
2257: Simplify container requirements with the new algorithms
2258: a.erase(q1, q2) unable to directly return q2
2263: Comparing iterators and allocator pointers with different
const-character
2268: Setting a default argument in the declaration of a member
function assign of std::basic_string
2271: regex_traits::lookup_classname specification unclear
2272: quoted should use char_traits::eq for character comparison
2278: User-defined literals for Standard Library types
2280: begin / end for arrays should be constexpr and noexcept
2285: make_reverse_iterator
2288: Inconsistent requirements for shared mutexes
2291: std::hash is vulnerable to collision DoS attack
2293: Wrong facet used by num_put::do_put
2299: Effects of inaccessible key_compare::is_transparent type are not
clear
2301: Why is std::tie not constexpr?
2304: Complexity of count in unordered associative containers
2306: match_results::reference should be value_type&, not const
value_type&
2308: Clarify container destructor requirements w.r.t. std::array
2313: tuple_size should always derive from integral_constant<size_t, N>
2314: apply() should return decltype(auto) and use decay_t before
tuple_size
2315: weak_ptr should be movable
2316: weak_ptr::lock() should be atomic
2317: The type property queries should be UnaryTypeTraits returning
size_t
2320: select_on_container_copy_construction() takes allocators, not
containers
2322: Associative(initializer_list, stuff) constructors are
underspecified
2323: vector::resize(n, t)'s specification should be simplified
2324: Insert iterator constructors should use addressof()
2329: regex_match()/regex_search() with match_results should forbid
temporary strings
2330: regex("meow", regex::icase) is technically forbidden but should
be permitted
2332: regex_iterator/regex_token_iterator should forbid temporary
regexes
2339: Wording issue in nth_element
2341: Inconsistency between basic_ostream::seekp(pos) and
basic_ostream::seekp(off, dir)
2344: quoted()'s interaction with padding is unclear
2346: integral_constant's member functions should be marked noexcept
2350: min, max, and minmax should be constexpr
2356: Stability of erasure in unordered associative containers
2357: Remaining "Assignable" requirement
2359: How does regex_constants::nosubs affect basic_regex::mark_count()?
2360: reverse_iterator::operator*() is unimplementable
[1] http://libcxx.llvm.org/cxx1y_status.html
[2] http://libcxx.llvm.org/cxx1z_status.html
[3] http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html
Exp-run: antoine
MFC after: 1 month
570 lines
13 KiB
C++
570 lines
13 KiB
C++
//===-------------------------- hash.cpp ----------------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is dual licensed under the MIT and the University of Illinois Open
|
|
// Source Licenses. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "__hash_table"
|
|
#include "algorithm"
|
|
#include "stdexcept"
|
|
#include "type_traits"
|
|
|
|
#ifdef __clang__
|
|
#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare"
|
|
#endif
|
|
|
|
_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)
|
|
{
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
if (N > 0xFFFFFFFB)
|
|
throw overflow_error("__next_prime overflow");
|
|
#else
|
|
(void)N;
|
|
#endif
|
|
}
|
|
|
|
template <size_t _Sz = sizeof(size_t)>
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
|
typename enable_if<_Sz == 8, void>::type
|
|
__check_for_overflow(size_t N)
|
|
{
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
if (N > 0xFFFFFFFFFFFFFFC5ull)
|
|
throw overflow_error("__next_prime overflow");
|
|
#else
|
|
(void)N;
|
|
#endif
|
|
}
|
|
|
|
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
|