aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/abseil-cpp/absl/random
diff options
context:
space:
mode:
authoranastasy888 <anastasy888@yandex-team.ru>2022-02-10 16:45:55 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:55 +0300
commit3a7a498715ef1b66f5054455421b845e45e3a653 (patch)
tree1a2c5ffcf89eb53ecd79dbc9bc0a195c27404d0c /contrib/restricted/abseil-cpp/absl/random
parent49f765d71da452ea93138a25559dfa68dd76c7f3 (diff)
downloadydb-3a7a498715ef1b66f5054455421b845e45e3a653.tar.gz
Restoring authorship annotation for <anastasy888@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/restricted/abseil-cpp/absl/random')
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/absl_random_distributions/ya.make58
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/bernoulli_distribution.h396
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/beta_distribution.h850
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/discrete_distribution.cc192
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/discrete_distribution.h490
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/distributions.h856
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/exponential_distribution.h326
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.cc204
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.h542
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/absl_random_internal_distribution_test_util/ya.make70
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/chi_square.cc460
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/chi_square.h170
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/distribution_caller.h78
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.cc832
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.h222
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/explicit_seed_seq.h172
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/fast_uniform_bits.h322
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/fastmath.h104
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/generate_real.h276
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/iostream_state_saver.h482
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/nanobenchmark.h336
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/nonsecure_base.h296
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/pcg_engine.h604
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/platform.h342
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.cc496
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.h258
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg/ya.make80
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/randen.cc176
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/randen.h198
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/randen/ya.make58
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.cc434
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.h58
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/randen_detect/ya.make54
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/randen_engine.h450
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.cc736
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.h90
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes/ya.make46
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.cc304
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.h70
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/randen_slow/ya.make46
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/randen_traits.h110
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/salted_seed_seq.h330
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/seed_material.cc408
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/seed_material.h204
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/seed_material/ya.make58
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/sequence_urbg.h112
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/traits.h198
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/uniform_helper.h352
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/internal/wide_multiply.h206
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/log_uniform_int_distribution.h500
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/poisson_distribution.h512
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/random.h372
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.cc88
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.h102
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/seed_gen_exception/ya.make46
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/seed_sequences.cc54
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/seed_sequences.h216
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/seed_sequences/ya.make82
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/uniform_int_distribution.h544
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/uniform_real_distribution.h400
-rw-r--r--contrib/restricted/abseil-cpp/absl/random/zipf_distribution.h538
61 files changed, 8833 insertions, 8833 deletions
diff --git a/contrib/restricted/abseil-cpp/absl/random/absl_random_distributions/ya.make b/contrib/restricted/abseil-cpp/absl/random/absl_random_distributions/ya.make
index 37bdf88c98..73d9caa424 100644
--- a/contrib/restricted/abseil-cpp/absl/random/absl_random_distributions/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/random/absl_random_distributions/ya.make
@@ -1,41 +1,41 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
WITHOUT_LICENSE_TEXTS()
-OWNER(g:cpp-contrib)
-
-LICENSE(Apache-2.0)
-
-PEERDIR(
- contrib/restricted/abseil-cpp/absl/base
- contrib/restricted/abseil-cpp/absl/base/internal/raw_logging
- contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait
- contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate
- contrib/restricted/abseil-cpp/absl/base/log_severity
- contrib/restricted/abseil-cpp/absl/numeric
+OWNER(g:cpp-contrib)
+
+LICENSE(Apache-2.0)
+
+PEERDIR(
+ contrib/restricted/abseil-cpp/absl/base
+ contrib/restricted/abseil-cpp/absl/base/internal/raw_logging
+ contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait
+ contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate
+ contrib/restricted/abseil-cpp/absl/base/log_severity
+ contrib/restricted/abseil-cpp/absl/numeric
contrib/restricted/abseil-cpp/absl/strings
contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal
-)
-
-ADDINCL(
- GLOBAL contrib/restricted/abseil-cpp
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
+)
+
+ADDINCL(
+ GLOBAL contrib/restricted/abseil-cpp
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
CFLAGS(
-DNOMINMAX
)
SRCDIR(contrib/restricted/abseil-cpp/absl/random)
-SRCS(
+SRCS(
discrete_distribution.cc
gaussian_distribution.cc
-)
-
-END()
+)
+
+END()
diff --git a/contrib/restricted/abseil-cpp/absl/random/bernoulli_distribution.h b/contrib/restricted/abseil-cpp/absl/random/bernoulli_distribution.h
index 6c4d28dbb9..25bd0d5ca4 100644
--- a/contrib/restricted/abseil-cpp/absl/random/bernoulli_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/bernoulli_distribution.h
@@ -1,200 +1,200 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_BERNOULLI_DISTRIBUTION_H_
-#define ABSL_RANDOM_BERNOULLI_DISTRIBUTION_H_
-
-#include <cstdint>
-#include <istream>
-#include <limits>
-
-#include "absl/base/optimization.h"
-#include "absl/random/internal/fast_uniform_bits.h"
-#include "absl/random/internal/iostream_state_saver.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_BERNOULLI_DISTRIBUTION_H_
+#define ABSL_RANDOM_BERNOULLI_DISTRIBUTION_H_
+
+#include <cstdint>
+#include <istream>
+#include <limits>
+
+#include "absl/base/optimization.h"
+#include "absl/random/internal/fast_uniform_bits.h"
+#include "absl/random/internal/iostream_state_saver.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-
-// absl::bernoulli_distribution is a drop in replacement for
-// std::bernoulli_distribution. It guarantees that (given a perfect
-// UniformRandomBitGenerator) the acceptance probability is *exactly* equal to
-// the given double.
-//
-// The implementation assumes that double is IEEE754
-class bernoulli_distribution {
- public:
- using result_type = bool;
-
- class param_type {
- public:
- using distribution_type = bernoulli_distribution;
-
- explicit param_type(double p = 0.5) : prob_(p) {
- assert(p >= 0.0 && p <= 1.0);
- }
-
- double p() const { return prob_; }
-
- friend bool operator==(const param_type& p1, const param_type& p2) {
- return p1.p() == p2.p();
- }
- friend bool operator!=(const param_type& p1, const param_type& p2) {
- return p1.p() != p2.p();
- }
-
- private:
- double prob_;
- };
-
- bernoulli_distribution() : bernoulli_distribution(0.5) {}
-
- explicit bernoulli_distribution(double p) : param_(p) {}
-
- explicit bernoulli_distribution(param_type p) : param_(p) {}
-
- // no-op
- void reset() {}
-
- template <typename URBG>
- bool operator()(URBG& g) { // NOLINT(runtime/references)
- return Generate(param_.p(), g);
- }
-
- template <typename URBG>
- bool operator()(URBG& g, // NOLINT(runtime/references)
- const param_type& param) {
- return Generate(param.p(), g);
- }
-
- param_type param() const { return param_; }
- void param(const param_type& param) { param_ = param; }
-
- double p() const { return param_.p(); }
-
- result_type(min)() const { return false; }
- result_type(max)() const { return true; }
-
- friend bool operator==(const bernoulli_distribution& d1,
- const bernoulli_distribution& d2) {
- return d1.param_ == d2.param_;
- }
-
- friend bool operator!=(const bernoulli_distribution& d1,
- const bernoulli_distribution& d2) {
- return d1.param_ != d2.param_;
- }
-
- private:
- static constexpr uint64_t kP32 = static_cast<uint64_t>(1) << 32;
-
- template <typename URBG>
- static bool Generate(double p, URBG& g); // NOLINT(runtime/references)
-
- param_type param_;
-};
-
-template <typename CharT, typename Traits>
-std::basic_ostream<CharT, Traits>& operator<<(
- std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
- const bernoulli_distribution& x) {
- auto saver = random_internal::make_ostream_state_saver(os);
- os.precision(random_internal::stream_precision_helper<double>::kPrecision);
- os << x.p();
- return os;
-}
-
-template <typename CharT, typename Traits>
-std::basic_istream<CharT, Traits>& operator>>(
- std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
- bernoulli_distribution& x) { // NOLINT(runtime/references)
- auto saver = random_internal::make_istream_state_saver(is);
- auto p = random_internal::read_floating_point<double>(is);
- if (!is.fail()) {
- x.param(bernoulli_distribution::param_type(p));
- }
- return is;
-}
-
-template <typename URBG>
-bool bernoulli_distribution::Generate(double p,
- URBG& g) { // NOLINT(runtime/references)
- random_internal::FastUniformBits<uint32_t> fast_u32;
-
- while (true) {
- // There are two aspects of the definition of `c` below that are worth
- // commenting on. First, because `p` is in the range [0, 1], `c` is in the
- // range [0, 2^32] which does not fit in a uint32_t and therefore requires
- // 64 bits.
- //
- // Second, `c` is constructed by first casting explicitly to a signed
- // integer and then converting implicitly to an unsigned integer of the same
- // size. This is done because the hardware conversion instructions produce
- // signed integers from double; if taken as a uint64_t the conversion would
- // be wrong for doubles greater than 2^63 (not relevant in this use-case).
- // If converted directly to an unsigned integer, the compiler would end up
- // emitting code to handle such large values that are not relevant due to
- // the known bounds on `c`. To avoid these extra instructions this
- // implementation converts first to the signed type and then use the
- // implicit conversion to unsigned (which is a no-op).
- const uint64_t c = static_cast<int64_t>(p * kP32);
- const uint32_t v = fast_u32(g);
- // FAST PATH: this path fails with probability 1/2^32. Note that simply
- // returning v <= c would approximate P very well (up to an absolute error
- // of 1/2^32); the slow path (taken in that range of possible error, in the
- // case of equality) eliminates the remaining error.
- if (ABSL_PREDICT_TRUE(v != c)) return v < c;
-
- // It is guaranteed that `q` is strictly less than 1, because if `q` were
- // greater than or equal to 1, the same would be true for `p`. Certainly `p`
- // cannot be greater than 1, and if `p == 1`, then the fast path would
- // necessary have been taken already.
- const double q = static_cast<double>(c) / kP32;
-
- // The probability of acceptance on the fast path is `q` and so the
- // probability of acceptance here should be `p - q`.
- //
- // Note that `q` is obtained from `p` via some shifts and conversions, the
- // upshot of which is that `q` is simply `p` with some of the
- // least-significant bits of its mantissa set to zero. This means that the
- // difference `p - q` will not have any rounding errors. To see why, pretend
- // that double has 10 bits of resolution and q is obtained from `p` in such
- // a way that the 4 least-significant bits of its mantissa are set to zero.
- // For example:
- // p = 1.1100111011 * 2^-1
- // q = 1.1100110000 * 2^-1
- // p - q = 1.011 * 2^-8
- // The difference `p - q` has exactly the nonzero mantissa bits that were
- // "lost" in `q` producing a number which is certainly representable in a
- // double.
- const double left = p - q;
-
- // By construction, the probability of being on this slow path is 1/2^32, so
- // P(accept in slow path) = P(accept| in slow path) * P(slow path),
- // which means the probability of acceptance here is `1 / (left * kP32)`:
- const double here = left * kP32;
-
- // The simplest way to compute the result of this trial is to repeat the
- // whole algorithm with the new probability. This terminates because even
- // given arbitrarily unfriendly "random" bits, each iteration either
- // multiplies a tiny probability by 2^32 (if c == 0) or strips off some
- // number of nonzero mantissa bits. That process is bounded.
- if (here == 0) return false;
- p = here;
- }
-}
-
+
+// absl::bernoulli_distribution is a drop in replacement for
+// std::bernoulli_distribution. It guarantees that (given a perfect
+// UniformRandomBitGenerator) the acceptance probability is *exactly* equal to
+// the given double.
+//
+// The implementation assumes that double is IEEE754
+class bernoulli_distribution {
+ public:
+ using result_type = bool;
+
+ class param_type {
+ public:
+ using distribution_type = bernoulli_distribution;
+
+ explicit param_type(double p = 0.5) : prob_(p) {
+ assert(p >= 0.0 && p <= 1.0);
+ }
+
+ double p() const { return prob_; }
+
+ friend bool operator==(const param_type& p1, const param_type& p2) {
+ return p1.p() == p2.p();
+ }
+ friend bool operator!=(const param_type& p1, const param_type& p2) {
+ return p1.p() != p2.p();
+ }
+
+ private:
+ double prob_;
+ };
+
+ bernoulli_distribution() : bernoulli_distribution(0.5) {}
+
+ explicit bernoulli_distribution(double p) : param_(p) {}
+
+ explicit bernoulli_distribution(param_type p) : param_(p) {}
+
+ // no-op
+ void reset() {}
+
+ template <typename URBG>
+ bool operator()(URBG& g) { // NOLINT(runtime/references)
+ return Generate(param_.p(), g);
+ }
+
+ template <typename URBG>
+ bool operator()(URBG& g, // NOLINT(runtime/references)
+ const param_type& param) {
+ return Generate(param.p(), g);
+ }
+
+ param_type param() const { return param_; }
+ void param(const param_type& param) { param_ = param; }
+
+ double p() const { return param_.p(); }
+
+ result_type(min)() const { return false; }
+ result_type(max)() const { return true; }
+
+ friend bool operator==(const bernoulli_distribution& d1,
+ const bernoulli_distribution& d2) {
+ return d1.param_ == d2.param_;
+ }
+
+ friend bool operator!=(const bernoulli_distribution& d1,
+ const bernoulli_distribution& d2) {
+ return d1.param_ != d2.param_;
+ }
+
+ private:
+ static constexpr uint64_t kP32 = static_cast<uint64_t>(1) << 32;
+
+ template <typename URBG>
+ static bool Generate(double p, URBG& g); // NOLINT(runtime/references)
+
+ param_type param_;
+};
+
+template <typename CharT, typename Traits>
+std::basic_ostream<CharT, Traits>& operator<<(
+ std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
+ const bernoulli_distribution& x) {
+ auto saver = random_internal::make_ostream_state_saver(os);
+ os.precision(random_internal::stream_precision_helper<double>::kPrecision);
+ os << x.p();
+ return os;
+}
+
+template <typename CharT, typename Traits>
+std::basic_istream<CharT, Traits>& operator>>(
+ std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
+ bernoulli_distribution& x) { // NOLINT(runtime/references)
+ auto saver = random_internal::make_istream_state_saver(is);
+ auto p = random_internal::read_floating_point<double>(is);
+ if (!is.fail()) {
+ x.param(bernoulli_distribution::param_type(p));
+ }
+ return is;
+}
+
+template <typename URBG>
+bool bernoulli_distribution::Generate(double p,
+ URBG& g) { // NOLINT(runtime/references)
+ random_internal::FastUniformBits<uint32_t> fast_u32;
+
+ while (true) {
+ // There are two aspects of the definition of `c` below that are worth
+ // commenting on. First, because `p` is in the range [0, 1], `c` is in the
+ // range [0, 2^32] which does not fit in a uint32_t and therefore requires
+ // 64 bits.
+ //
+ // Second, `c` is constructed by first casting explicitly to a signed
+ // integer and then converting implicitly to an unsigned integer of the same
+ // size. This is done because the hardware conversion instructions produce
+ // signed integers from double; if taken as a uint64_t the conversion would
+ // be wrong for doubles greater than 2^63 (not relevant in this use-case).
+ // If converted directly to an unsigned integer, the compiler would end up
+ // emitting code to handle such large values that are not relevant due to
+ // the known bounds on `c`. To avoid these extra instructions this
+ // implementation converts first to the signed type and then use the
+ // implicit conversion to unsigned (which is a no-op).
+ const uint64_t c = static_cast<int64_t>(p * kP32);
+ const uint32_t v = fast_u32(g);
+ // FAST PATH: this path fails with probability 1/2^32. Note that simply
+ // returning v <= c would approximate P very well (up to an absolute error
+ // of 1/2^32); the slow path (taken in that range of possible error, in the
+ // case of equality) eliminates the remaining error.
+ if (ABSL_PREDICT_TRUE(v != c)) return v < c;
+
+ // It is guaranteed that `q` is strictly less than 1, because if `q` were
+ // greater than or equal to 1, the same would be true for `p`. Certainly `p`
+ // cannot be greater than 1, and if `p == 1`, then the fast path would
+ // necessary have been taken already.
+ const double q = static_cast<double>(c) / kP32;
+
+ // The probability of acceptance on the fast path is `q` and so the
+ // probability of acceptance here should be `p - q`.
+ //
+ // Note that `q` is obtained from `p` via some shifts and conversions, the
+ // upshot of which is that `q` is simply `p` with some of the
+ // least-significant bits of its mantissa set to zero. This means that the
+ // difference `p - q` will not have any rounding errors. To see why, pretend
+ // that double has 10 bits of resolution and q is obtained from `p` in such
+ // a way that the 4 least-significant bits of its mantissa are set to zero.
+ // For example:
+ // p = 1.1100111011 * 2^-1
+ // q = 1.1100110000 * 2^-1
+ // p - q = 1.011 * 2^-8
+ // The difference `p - q` has exactly the nonzero mantissa bits that were
+ // "lost" in `q` producing a number which is certainly representable in a
+ // double.
+ const double left = p - q;
+
+ // By construction, the probability of being on this slow path is 1/2^32, so
+ // P(accept in slow path) = P(accept| in slow path) * P(slow path),
+ // which means the probability of acceptance here is `1 / (left * kP32)`:
+ const double here = left * kP32;
+
+ // The simplest way to compute the result of this trial is to repeat the
+ // whole algorithm with the new probability. This terminates because even
+ // given arbitrarily unfriendly "random" bits, each iteration either
+ // multiplies a tiny probability by 2^32 (if c == 0) or strips off some
+ // number of nonzero mantissa bits. That process is bounded.
+ if (here == 0) return false;
+ p = here;
+ }
+}
+
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_BERNOULLI_DISTRIBUTION_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_BERNOULLI_DISTRIBUTION_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/beta_distribution.h b/contrib/restricted/abseil-cpp/absl/random/beta_distribution.h
index 1d302f8b98..c154066fb8 100644
--- a/contrib/restricted/abseil-cpp/absl/random/beta_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/beta_distribution.h
@@ -1,427 +1,427 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_BETA_DISTRIBUTION_H_
-#define ABSL_RANDOM_BETA_DISTRIBUTION_H_
-
-#include <cassert>
-#include <cmath>
-#include <istream>
-#include <limits>
-#include <ostream>
-#include <type_traits>
-
-#include "absl/meta/type_traits.h"
-#include "absl/random/internal/fast_uniform_bits.h"
-#include "absl/random/internal/fastmath.h"
-#include "absl/random/internal/generate_real.h"
-#include "absl/random/internal/iostream_state_saver.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_BETA_DISTRIBUTION_H_
+#define ABSL_RANDOM_BETA_DISTRIBUTION_H_
+
+#include <cassert>
+#include <cmath>
+#include <istream>
+#include <limits>
+#include <ostream>
+#include <type_traits>
+
+#include "absl/meta/type_traits.h"
+#include "absl/random/internal/fast_uniform_bits.h"
+#include "absl/random/internal/fastmath.h"
+#include "absl/random/internal/generate_real.h"
+#include "absl/random/internal/iostream_state_saver.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-
-// absl::beta_distribution:
-// Generate a floating-point variate conforming to a Beta distribution:
-// pdf(x) \propto x^(alpha-1) * (1-x)^(beta-1),
-// where the params alpha and beta are both strictly positive real values.
-//
-// The support is the open interval (0, 1), but the return value might be equal
-// to 0 or 1, due to numerical errors when alpha and beta are very different.
-//
-// Usage note: One usage is that alpha and beta are counts of number of
-// successes and failures. When the total number of trials are large, consider
-// approximating a beta distribution with a Gaussian distribution with the same
-// mean and variance. One could use the skewness, which depends only on the
-// smaller of alpha and beta when the number of trials are sufficiently large,
-// to quantify how far a beta distribution is from the normal distribution.
-template <typename RealType = double>
-class beta_distribution {
- public:
- using result_type = RealType;
-
- class param_type {
- public:
- using distribution_type = beta_distribution;
-
- explicit param_type(result_type alpha, result_type beta)
- : alpha_(alpha), beta_(beta) {
- assert(alpha >= 0);
- assert(beta >= 0);
- assert(alpha <= (std::numeric_limits<result_type>::max)());
- assert(beta <= (std::numeric_limits<result_type>::max)());
- if (alpha == 0 || beta == 0) {
- method_ = DEGENERATE_SMALL;
- x_ = (alpha >= beta) ? 1 : 0;
- return;
- }
- // a_ = min(beta, alpha), b_ = max(beta, alpha).
- if (beta < alpha) {
- inverted_ = true;
- a_ = beta;
- b_ = alpha;
- } else {
- inverted_ = false;
- a_ = alpha;
- b_ = beta;
- }
- if (a_ <= 1 && b_ >= ThresholdForLargeA()) {
- method_ = DEGENERATE_SMALL;
- x_ = inverted_ ? result_type(1) : result_type(0);
- return;
- }
- // For threshold values, see also:
- // Evaluation of Beta Generation Algorithms, Ying-Chao Hung, et. al.
- // February, 2009.
- if ((b_ < 1.0 && a_ + b_ <= 1.2) || a_ <= ThresholdForSmallA()) {
- // Choose Joehnk over Cheng when it's faster or when Cheng encounters
- // numerical issues.
- method_ = JOEHNK;
- a_ = result_type(1) / alpha_;
- b_ = result_type(1) / beta_;
- if (std::isinf(a_) || std::isinf(b_)) {
- method_ = DEGENERATE_SMALL;
- x_ = inverted_ ? result_type(1) : result_type(0);
- }
- return;
- }
- if (a_ >= ThresholdForLargeA()) {
- method_ = DEGENERATE_LARGE;
- // Note: on PPC for long double, evaluating
- // `std::numeric_limits::max() / ThresholdForLargeA` results in NaN.
- result_type r = a_ / b_;
- x_ = (inverted_ ? result_type(1) : r) / (1 + r);
- return;
- }
- x_ = a_ + b_;
- log_x_ = std::log(x_);
- if (a_ <= 1) {
- method_ = CHENG_BA;
- y_ = result_type(1) / a_;
- gamma_ = a_ + a_;
- return;
- }
- method_ = CHENG_BB;
- result_type r = (a_ - 1) / (b_ - 1);
- y_ = std::sqrt((1 + r) / (b_ * r * 2 - r + 1));
- gamma_ = a_ + result_type(1) / y_;
- }
-
- result_type alpha() const { return alpha_; }
- result_type beta() const { return beta_; }
-
- friend bool operator==(const param_type& a, const param_type& b) {
- return a.alpha_ == b.alpha_ && a.beta_ == b.beta_;
- }
-
- friend bool operator!=(const param_type& a, const param_type& b) {
- return !(a == b);
- }
-
- private:
- friend class beta_distribution;
-
-#ifdef _MSC_VER
- // MSVC does not have constexpr implementations for std::log and std::exp
- // so they are computed at runtime.
-#define ABSL_RANDOM_INTERNAL_LOG_EXP_CONSTEXPR
-#else
-#define ABSL_RANDOM_INTERNAL_LOG_EXP_CONSTEXPR constexpr
-#endif
-
- // The threshold for whether std::exp(1/a) is finite.
- // Note that this value is quite large, and a smaller a_ is NOT abnormal.
- static ABSL_RANDOM_INTERNAL_LOG_EXP_CONSTEXPR result_type
- ThresholdForSmallA() {
- return result_type(1) /
- std::log((std::numeric_limits<result_type>::max)());
- }
-
- // The threshold for whether a * std::log(a) is finite.
- static ABSL_RANDOM_INTERNAL_LOG_EXP_CONSTEXPR result_type
- ThresholdForLargeA() {
- return std::exp(
- std::log((std::numeric_limits<result_type>::max)()) -
- std::log(std::log((std::numeric_limits<result_type>::max)())) -
- ThresholdPadding());
- }
-
-#undef ABSL_RANDOM_INTERNAL_LOG_EXP_CONSTEXPR
-
- // Pad the threshold for large A for long double on PPC. This is done via a
- // template specialization below.
- static constexpr result_type ThresholdPadding() { return 0; }
-
- enum Method {
- JOEHNK, // Uses algorithm Joehnk
- CHENG_BA, // Uses algorithm BA in Cheng
- CHENG_BB, // Uses algorithm BB in Cheng
-
- // Note: See also:
- // Hung et al. Evaluation of beta generation algorithms. Communications
- // in Statistics-Simulation and Computation 38.4 (2009): 750-770.
- // especially:
- // Zechner, Heinz, and Ernst Stadlober. Generating beta variates via
- // patchwork rejection. Computing 50.1 (1993): 1-18.
-
- DEGENERATE_SMALL, // a_ is abnormally small.
- DEGENERATE_LARGE, // a_ is abnormally large.
- };
-
- result_type alpha_;
- result_type beta_;
-
- result_type a_; // the smaller of {alpha, beta}, or 1.0/alpha_ in JOEHNK
- result_type b_; // the larger of {alpha, beta}, or 1.0/beta_ in JOEHNK
- result_type x_; // alpha + beta, or the result in degenerate cases
- result_type log_x_; // log(x_)
- result_type y_; // "beta" in Cheng
- result_type gamma_; // "gamma" in Cheng
-
- Method method_;
-
- // Placing this last for optimal alignment.
- // Whether alpha_ != a_, i.e. true iff alpha_ > beta_.
- bool inverted_;
-
- static_assert(std::is_floating_point<RealType>::value,
- "Class-template absl::beta_distribution<> must be "
- "parameterized using a floating-point type.");
- };
-
- beta_distribution() : beta_distribution(1) {}
-
- explicit beta_distribution(result_type alpha, result_type beta = 1)
- : param_(alpha, beta) {}
-
- explicit beta_distribution(const param_type& p) : param_(p) {}
-
- void reset() {}
-
- // Generating functions
- template <typename URBG>
- result_type operator()(URBG& g) { // NOLINT(runtime/references)
- return (*this)(g, param_);
- }
-
- template <typename URBG>
- result_type operator()(URBG& g, // NOLINT(runtime/references)
- const param_type& p);
-
- param_type param() const { return param_; }
- void param(const param_type& p) { param_ = p; }
-
- result_type(min)() const { return 0; }
- result_type(max)() const { return 1; }
-
- result_type alpha() const { return param_.alpha(); }
- result_type beta() const { return param_.beta(); }
-
- friend bool operator==(const beta_distribution& a,
- const beta_distribution& b) {
- return a.param_ == b.param_;
- }
- friend bool operator!=(const beta_distribution& a,
- const beta_distribution& b) {
- return a.param_ != b.param_;
- }
-
- private:
- template <typename URBG>
- result_type AlgorithmJoehnk(URBG& g, // NOLINT(runtime/references)
- const param_type& p);
-
- template <typename URBG>
- result_type AlgorithmCheng(URBG& g, // NOLINT(runtime/references)
- const param_type& p);
-
- template <typename URBG>
- result_type DegenerateCase(URBG& g, // NOLINT(runtime/references)
- const param_type& p) {
- if (p.method_ == param_type::DEGENERATE_SMALL && p.alpha_ == p.beta_) {
- // Returns 0 or 1 with equal probability.
- random_internal::FastUniformBits<uint8_t> fast_u8;
- return static_cast<result_type>((fast_u8(g) & 0x10) !=
- 0); // pick any single bit.
- }
- return p.x_;
- }
-
- param_type param_;
- random_internal::FastUniformBits<uint64_t> fast_u64_;
-};
-
-#if defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \
- defined(__ppc__) || defined(__PPC__)
-// PPC needs a more stringent boundary for long double.
-template <>
-constexpr long double
-beta_distribution<long double>::param_type::ThresholdPadding() {
- return 10;
-}
-#endif
-
-template <typename RealType>
-template <typename URBG>
-typename beta_distribution<RealType>::result_type
-beta_distribution<RealType>::AlgorithmJoehnk(
- URBG& g, // NOLINT(runtime/references)
- const param_type& p) {
- using random_internal::GeneratePositiveTag;
- using random_internal::GenerateRealFromBits;
- using real_type =
- absl::conditional_t<std::is_same<RealType, float>::value, float, double>;
-
- // Based on Joehnk, M. D. Erzeugung von betaverteilten und gammaverteilten
- // Zufallszahlen. Metrika 8.1 (1964): 5-15.
- // This method is described in Knuth, Vol 2 (Third Edition), pp 134.
-
- result_type u, v, x, y, z;
- for (;;) {
- u = GenerateRealFromBits<real_type, GeneratePositiveTag, false>(
- fast_u64_(g));
- v = GenerateRealFromBits<real_type, GeneratePositiveTag, false>(
- fast_u64_(g));
-
- // Direct method. std::pow is slow for float, so rely on the optimizer to
- // remove the std::pow() path for that case.
- if (!std::is_same<float, result_type>::value) {
- x = std::pow(u, p.a_);
- y = std::pow(v, p.b_);
- z = x + y;
- if (z > 1) {
- // Reject if and only if `x + y > 1.0`
- continue;
- }
- if (z > 0) {
- // When both alpha and beta are small, x and y are both close to 0, so
- // divide by (x+y) directly may result in nan.
- return x / z;
- }
- }
-
- // Log transform.
- // x = log( pow(u, p.a_) ), y = log( pow(v, p.b_) )
- // since u, v <= 1.0, x, y < 0.
- x = std::log(u) * p.a_;
- y = std::log(v) * p.b_;
- if (!std::isfinite(x) || !std::isfinite(y)) {
- continue;
- }
- // z = log( pow(u, a) + pow(v, b) )
- z = x > y ? (x + std::log(1 + std::exp(y - x)))
- : (y + std::log(1 + std::exp(x - y)));
- // Reject iff log(x+y) > 0.
- if (z > 0) {
- continue;
- }
- return std::exp(x - z);
- }
-}
-
-template <typename RealType>
-template <typename URBG>
-typename beta_distribution<RealType>::result_type
-beta_distribution<RealType>::AlgorithmCheng(
- URBG& g, // NOLINT(runtime/references)
- const param_type& p) {
- using random_internal::GeneratePositiveTag;
- using random_internal::GenerateRealFromBits;
- using real_type =
- absl::conditional_t<std::is_same<RealType, float>::value, float, double>;
-
- // Based on Cheng, Russell CH. Generating beta variates with nonintegral
- // shape parameters. Communications of the ACM 21.4 (1978): 317-322.
- // (https://dl.acm.org/citation.cfm?id=359482).
- static constexpr result_type kLogFour =
- result_type(1.3862943611198906188344642429163531361); // log(4)
- static constexpr result_type kS =
- result_type(2.6094379124341003746007593332261876); // 1+log(5)
-
- const bool use_algorithm_ba = (p.method_ == param_type::CHENG_BA);
- result_type u1, u2, v, w, z, r, s, t, bw_inv, lhs;
- for (;;) {
- u1 = GenerateRealFromBits<real_type, GeneratePositiveTag, false>(
- fast_u64_(g));
- u2 = GenerateRealFromBits<real_type, GeneratePositiveTag, false>(
- fast_u64_(g));
- v = p.y_ * std::log(u1 / (1 - u1));
- w = p.a_ * std::exp(v);
- bw_inv = result_type(1) / (p.b_ + w);
- r = p.gamma_ * v - kLogFour;
- s = p.a_ + r - w;
- z = u1 * u1 * u2;
- if (!use_algorithm_ba && s + kS >= 5 * z) {
- break;
- }
- t = std::log(z);
- if (!use_algorithm_ba && s >= t) {
- break;
- }
- lhs = p.x_ * (p.log_x_ + std::log(bw_inv)) + r;
- if (lhs >= t) {
- break;
- }
- }
- return p.inverted_ ? (1 - w * bw_inv) : w * bw_inv;
-}
-
-template <typename RealType>
-template <typename URBG>
-typename beta_distribution<RealType>::result_type
-beta_distribution<RealType>::operator()(URBG& g, // NOLINT(runtime/references)
- const param_type& p) {
- switch (p.method_) {
- case param_type::JOEHNK:
- return AlgorithmJoehnk(g, p);
- case param_type::CHENG_BA:
- ABSL_FALLTHROUGH_INTENDED;
- case param_type::CHENG_BB:
- return AlgorithmCheng(g, p);
- default:
- return DegenerateCase(g, p);
- }
-}
-
-template <typename CharT, typename Traits, typename RealType>
-std::basic_ostream<CharT, Traits>& operator<<(
- std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
- const beta_distribution<RealType>& x) {
- auto saver = random_internal::make_ostream_state_saver(os);
- os.precision(random_internal::stream_precision_helper<RealType>::kPrecision);
- os << x.alpha() << os.fill() << x.beta();
- return os;
-}
-
-template <typename CharT, typename Traits, typename RealType>
-std::basic_istream<CharT, Traits>& operator>>(
- std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
- beta_distribution<RealType>& x) { // NOLINT(runtime/references)
- using result_type = typename beta_distribution<RealType>::result_type;
- using param_type = typename beta_distribution<RealType>::param_type;
- result_type alpha, beta;
-
- auto saver = random_internal::make_istream_state_saver(is);
- alpha = random_internal::read_floating_point<result_type>(is);
- if (is.fail()) return is;
- beta = random_internal::read_floating_point<result_type>(is);
- if (!is.fail()) {
- x.param(param_type(alpha, beta));
- }
- return is;
-}
-
+
+// absl::beta_distribution:
+// Generate a floating-point variate conforming to a Beta distribution:
+// pdf(x) \propto x^(alpha-1) * (1-x)^(beta-1),
+// where the params alpha and beta are both strictly positive real values.
+//
+// The support is the open interval (0, 1), but the return value might be equal
+// to 0 or 1, due to numerical errors when alpha and beta are very different.
+//
+// Usage note: One usage is that alpha and beta are counts of number of
+// successes and failures. When the total number of trials are large, consider
+// approximating a beta distribution with a Gaussian distribution with the same
+// mean and variance. One could use the skewness, which depends only on the
+// smaller of alpha and beta when the number of trials are sufficiently large,
+// to quantify how far a beta distribution is from the normal distribution.
+template <typename RealType = double>
+class beta_distribution {
+ public:
+ using result_type = RealType;
+
+ class param_type {
+ public:
+ using distribution_type = beta_distribution;
+
+ explicit param_type(result_type alpha, result_type beta)
+ : alpha_(alpha), beta_(beta) {
+ assert(alpha >= 0);
+ assert(beta >= 0);
+ assert(alpha <= (std::numeric_limits<result_type>::max)());
+ assert(beta <= (std::numeric_limits<result_type>::max)());
+ if (alpha == 0 || beta == 0) {
+ method_ = DEGENERATE_SMALL;
+ x_ = (alpha >= beta) ? 1 : 0;
+ return;
+ }
+ // a_ = min(beta, alpha), b_ = max(beta, alpha).
+ if (beta < alpha) {
+ inverted_ = true;
+ a_ = beta;
+ b_ = alpha;
+ } else {
+ inverted_ = false;
+ a_ = alpha;
+ b_ = beta;
+ }
+ if (a_ <= 1 && b_ >= ThresholdForLargeA()) {
+ method_ = DEGENERATE_SMALL;
+ x_ = inverted_ ? result_type(1) : result_type(0);
+ return;
+ }
+ // For threshold values, see also:
+ // Evaluation of Beta Generation Algorithms, Ying-Chao Hung, et. al.
+ // February, 2009.
+ if ((b_ < 1.0 && a_ + b_ <= 1.2) || a_ <= ThresholdForSmallA()) {
+ // Choose Joehnk over Cheng when it's faster or when Cheng encounters
+ // numerical issues.
+ method_ = JOEHNK;
+ a_ = result_type(1) / alpha_;
+ b_ = result_type(1) / beta_;
+ if (std::isinf(a_) || std::isinf(b_)) {
+ method_ = DEGENERATE_SMALL;
+ x_ = inverted_ ? result_type(1) : result_type(0);
+ }
+ return;
+ }
+ if (a_ >= ThresholdForLargeA()) {
+ method_ = DEGENERATE_LARGE;
+ // Note: on PPC for long double, evaluating
+ // `std::numeric_limits::max() / ThresholdForLargeA` results in NaN.
+ result_type r = a_ / b_;
+ x_ = (inverted_ ? result_type(1) : r) / (1 + r);
+ return;
+ }
+ x_ = a_ + b_;
+ log_x_ = std::log(x_);
+ if (a_ <= 1) {
+ method_ = CHENG_BA;
+ y_ = result_type(1) / a_;
+ gamma_ = a_ + a_;
+ return;
+ }
+ method_ = CHENG_BB;
+ result_type r = (a_ - 1) / (b_ - 1);
+ y_ = std::sqrt((1 + r) / (b_ * r * 2 - r + 1));
+ gamma_ = a_ + result_type(1) / y_;
+ }
+
+ result_type alpha() const { return alpha_; }
+ result_type beta() const { return beta_; }
+
+ friend bool operator==(const param_type& a, const param_type& b) {
+ return a.alpha_ == b.alpha_ && a.beta_ == b.beta_;
+ }
+
+ friend bool operator!=(const param_type& a, const param_type& b) {
+ return !(a == b);
+ }
+
+ private:
+ friend class beta_distribution;
+
+#ifdef _MSC_VER
+ // MSVC does not have constexpr implementations for std::log and std::exp
+ // so they are computed at runtime.
+#define ABSL_RANDOM_INTERNAL_LOG_EXP_CONSTEXPR
+#else
+#define ABSL_RANDOM_INTERNAL_LOG_EXP_CONSTEXPR constexpr
+#endif
+
+ // The threshold for whether std::exp(1/a) is finite.
+ // Note that this value is quite large, and a smaller a_ is NOT abnormal.
+ static ABSL_RANDOM_INTERNAL_LOG_EXP_CONSTEXPR result_type
+ ThresholdForSmallA() {
+ return result_type(1) /
+ std::log((std::numeric_limits<result_type>::max)());
+ }
+
+ // The threshold for whether a * std::log(a) is finite.
+ static ABSL_RANDOM_INTERNAL_LOG_EXP_CONSTEXPR result_type
+ ThresholdForLargeA() {
+ return std::exp(
+ std::log((std::numeric_limits<result_type>::max)()) -
+ std::log(std::log((std::numeric_limits<result_type>::max)())) -
+ ThresholdPadding());
+ }
+
+#undef ABSL_RANDOM_INTERNAL_LOG_EXP_CONSTEXPR
+
+ // Pad the threshold for large A for long double on PPC. This is done via a
+ // template specialization below.
+ static constexpr result_type ThresholdPadding() { return 0; }
+
+ enum Method {
+ JOEHNK, // Uses algorithm Joehnk
+ CHENG_BA, // Uses algorithm BA in Cheng
+ CHENG_BB, // Uses algorithm BB in Cheng
+
+ // Note: See also:
+ // Hung et al. Evaluation of beta generation algorithms. Communications
+ // in Statistics-Simulation and Computation 38.4 (2009): 750-770.
+ // especially:
+ // Zechner, Heinz, and Ernst Stadlober. Generating beta variates via
+ // patchwork rejection. Computing 50.1 (1993): 1-18.
+
+ DEGENERATE_SMALL, // a_ is abnormally small.
+ DEGENERATE_LARGE, // a_ is abnormally large.
+ };
+
+ result_type alpha_;
+ result_type beta_;
+
+ result_type a_; // the smaller of {alpha, beta}, or 1.0/alpha_ in JOEHNK
+ result_type b_; // the larger of {alpha, beta}, or 1.0/beta_ in JOEHNK
+ result_type x_; // alpha + beta, or the result in degenerate cases
+ result_type log_x_; // log(x_)
+ result_type y_; // "beta" in Cheng
+ result_type gamma_; // "gamma" in Cheng
+
+ Method method_;
+
+ // Placing this last for optimal alignment.
+ // Whether alpha_ != a_, i.e. true iff alpha_ > beta_.
+ bool inverted_;
+
+ static_assert(std::is_floating_point<RealType>::value,
+ "Class-template absl::beta_distribution<> must be "
+ "parameterized using a floating-point type.");
+ };
+
+ beta_distribution() : beta_distribution(1) {}
+
+ explicit beta_distribution(result_type alpha, result_type beta = 1)
+ : param_(alpha, beta) {}
+
+ explicit beta_distribution(const param_type& p) : param_(p) {}
+
+ void reset() {}
+
+ // Generating functions
+ template <typename URBG>
+ result_type operator()(URBG& g) { // NOLINT(runtime/references)
+ return (*this)(g, param_);
+ }
+
+ template <typename URBG>
+ result_type operator()(URBG& g, // NOLINT(runtime/references)
+ const param_type& p);
+
+ param_type param() const { return param_; }
+ void param(const param_type& p) { param_ = p; }
+
+ result_type(min)() const { return 0; }
+ result_type(max)() const { return 1; }
+
+ result_type alpha() const { return param_.alpha(); }
+ result_type beta() const { return param_.beta(); }
+
+ friend bool operator==(const beta_distribution& a,
+ const beta_distribution& b) {
+ return a.param_ == b.param_;
+ }
+ friend bool operator!=(const beta_distribution& a,
+ const beta_distribution& b) {
+ return a.param_ != b.param_;
+ }
+
+ private:
+ template <typename URBG>
+ result_type AlgorithmJoehnk(URBG& g, // NOLINT(runtime/references)
+ const param_type& p);
+
+ template <typename URBG>
+ result_type AlgorithmCheng(URBG& g, // NOLINT(runtime/references)
+ const param_type& p);
+
+ template <typename URBG>
+ result_type DegenerateCase(URBG& g, // NOLINT(runtime/references)
+ const param_type& p) {
+ if (p.method_ == param_type::DEGENERATE_SMALL && p.alpha_ == p.beta_) {
+ // Returns 0 or 1 with equal probability.
+ random_internal::FastUniformBits<uint8_t> fast_u8;
+ return static_cast<result_type>((fast_u8(g) & 0x10) !=
+ 0); // pick any single bit.
+ }
+ return p.x_;
+ }
+
+ param_type param_;
+ random_internal::FastUniformBits<uint64_t> fast_u64_;
+};
+
+#if defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \
+ defined(__ppc__) || defined(__PPC__)
+// PPC needs a more stringent boundary for long double.
+template <>
+constexpr long double
+beta_distribution<long double>::param_type::ThresholdPadding() {
+ return 10;
+}
+#endif
+
+template <typename RealType>
+template <typename URBG>
+typename beta_distribution<RealType>::result_type
+beta_distribution<RealType>::AlgorithmJoehnk(
+ URBG& g, // NOLINT(runtime/references)
+ const param_type& p) {
+ using random_internal::GeneratePositiveTag;
+ using random_internal::GenerateRealFromBits;
+ using real_type =
+ absl::conditional_t<std::is_same<RealType, float>::value, float, double>;
+
+ // Based on Joehnk, M. D. Erzeugung von betaverteilten und gammaverteilten
+ // Zufallszahlen. Metrika 8.1 (1964): 5-15.
+ // This method is described in Knuth, Vol 2 (Third Edition), pp 134.
+
+ result_type u, v, x, y, z;
+ for (;;) {
+ u = GenerateRealFromBits<real_type, GeneratePositiveTag, false>(
+ fast_u64_(g));
+ v = GenerateRealFromBits<real_type, GeneratePositiveTag, false>(
+ fast_u64_(g));
+
+ // Direct method. std::pow is slow for float, so rely on the optimizer to
+ // remove the std::pow() path for that case.
+ if (!std::is_same<float, result_type>::value) {
+ x = std::pow(u, p.a_);
+ y = std::pow(v, p.b_);
+ z = x + y;
+ if (z > 1) {
+ // Reject if and only if `x + y > 1.0`
+ continue;
+ }
+ if (z > 0) {
+ // When both alpha and beta are small, x and y are both close to 0, so
+ // divide by (x+y) directly may result in nan.
+ return x / z;
+ }
+ }
+
+ // Log transform.
+ // x = log( pow(u, p.a_) ), y = log( pow(v, p.b_) )
+ // since u, v <= 1.0, x, y < 0.
+ x = std::log(u) * p.a_;
+ y = std::log(v) * p.b_;
+ if (!std::isfinite(x) || !std::isfinite(y)) {
+ continue;
+ }
+ // z = log( pow(u, a) + pow(v, b) )
+ z = x > y ? (x + std::log(1 + std::exp(y - x)))
+ : (y + std::log(1 + std::exp(x - y)));
+ // Reject iff log(x+y) > 0.
+ if (z > 0) {
+ continue;
+ }
+ return std::exp(x - z);
+ }
+}
+
+template <typename RealType>
+template <typename URBG>
+typename beta_distribution<RealType>::result_type
+beta_distribution<RealType>::AlgorithmCheng(
+ URBG& g, // NOLINT(runtime/references)
+ const param_type& p) {
+ using random_internal::GeneratePositiveTag;
+ using random_internal::GenerateRealFromBits;
+ using real_type =
+ absl::conditional_t<std::is_same<RealType, float>::value, float, double>;
+
+ // Based on Cheng, Russell CH. Generating beta variates with nonintegral
+ // shape parameters. Communications of the ACM 21.4 (1978): 317-322.
+ // (https://dl.acm.org/citation.cfm?id=359482).
+ static constexpr result_type kLogFour =
+ result_type(1.3862943611198906188344642429163531361); // log(4)
+ static constexpr result_type kS =
+ result_type(2.6094379124341003746007593332261876); // 1+log(5)
+
+ const bool use_algorithm_ba = (p.method_ == param_type::CHENG_BA);
+ result_type u1, u2, v, w, z, r, s, t, bw_inv, lhs;
+ for (;;) {
+ u1 = GenerateRealFromBits<real_type, GeneratePositiveTag, false>(
+ fast_u64_(g));
+ u2 = GenerateRealFromBits<real_type, GeneratePositiveTag, false>(
+ fast_u64_(g));
+ v = p.y_ * std::log(u1 / (1 - u1));
+ w = p.a_ * std::exp(v);
+ bw_inv = result_type(1) / (p.b_ + w);
+ r = p.gamma_ * v - kLogFour;
+ s = p.a_ + r - w;
+ z = u1 * u1 * u2;
+ if (!use_algorithm_ba && s + kS >= 5 * z) {
+ break;
+ }
+ t = std::log(z);
+ if (!use_algorithm_ba && s >= t) {
+ break;
+ }
+ lhs = p.x_ * (p.log_x_ + std::log(bw_inv)) + r;
+ if (lhs >= t) {
+ break;
+ }
+ }
+ return p.inverted_ ? (1 - w * bw_inv) : w * bw_inv;
+}
+
+template <typename RealType>
+template <typename URBG>
+typename beta_distribution<RealType>::result_type
+beta_distribution<RealType>::operator()(URBG& g, // NOLINT(runtime/references)
+ const param_type& p) {
+ switch (p.method_) {
+ case param_type::JOEHNK:
+ return AlgorithmJoehnk(g, p);
+ case param_type::CHENG_BA:
+ ABSL_FALLTHROUGH_INTENDED;
+ case param_type::CHENG_BB:
+ return AlgorithmCheng(g, p);
+ default:
+ return DegenerateCase(g, p);
+ }
+}
+
+template <typename CharT, typename Traits, typename RealType>
+std::basic_ostream<CharT, Traits>& operator<<(
+ std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
+ const beta_distribution<RealType>& x) {
+ auto saver = random_internal::make_ostream_state_saver(os);
+ os.precision(random_internal::stream_precision_helper<RealType>::kPrecision);
+ os << x.alpha() << os.fill() << x.beta();
+ return os;
+}
+
+template <typename CharT, typename Traits, typename RealType>
+std::basic_istream<CharT, Traits>& operator>>(
+ std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
+ beta_distribution<RealType>& x) { // NOLINT(runtime/references)
+ using result_type = typename beta_distribution<RealType>::result_type;
+ using param_type = typename beta_distribution<RealType>::param_type;
+ result_type alpha, beta;
+
+ auto saver = random_internal::make_istream_state_saver(is);
+ alpha = random_internal::read_floating_point<result_type>(is);
+ if (is.fail()) return is;
+ beta = random_internal::read_floating_point<result_type>(is);
+ if (!is.fail()) {
+ x.param(param_type(alpha, beta));
+ }
+ return is;
+}
+
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_BETA_DISTRIBUTION_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_BETA_DISTRIBUTION_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.cc b/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.cc
index 03ca2a2b0b..081accee52 100644
--- a/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.cc
+++ b/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.cc
@@ -1,98 +1,98 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/random/discrete_distribution.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/random/discrete_distribution.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// Initializes the distribution table for Walker's Aliasing algorithm, described
-// in Knuth, Vol 2. as well as in https://en.wikipedia.org/wiki/Alias_method
-std::vector<std::pair<double, size_t>> InitDiscreteDistribution(
- std::vector<double>* probabilities) {
- // The empty-case should already be handled by the constructor.
- assert(probabilities);
- assert(!probabilities->empty());
-
- // Step 1. Normalize the input probabilities to 1.0.
- double sum = std::accumulate(std::begin(*probabilities),
- std::end(*probabilities), 0.0);
- if (std::fabs(sum - 1.0) > 1e-6) {
- // Scale `probabilities` only when the sum is too far from 1.0. Scaling
- // unconditionally will alter the probabilities slightly.
- for (double& item : *probabilities) {
- item = item / sum;
- }
- }
-
- // Step 2. At this point `probabilities` is set to the conditional
- // probabilities of each element which sum to 1.0, to within reasonable error.
- // These values are used to construct the proportional probability tables for
- // the selection phases of Walker's Aliasing algorithm.
- //
- // To construct the table, pick an element which is under-full (i.e., an
- // element for which `(*probabilities)[i] < 1.0/n`), and pair it with an
- // element which is over-full (i.e., an element for which
- // `(*probabilities)[i] > 1.0/n`). The smaller value can always be retired.
- // The larger may still be greater than 1.0/n, or may now be less than 1.0/n,
- // and put back onto the appropriate collection.
- const size_t n = probabilities->size();
- std::vector<std::pair<double, size_t>> q;
- q.reserve(n);
-
- std::vector<size_t> over;
- std::vector<size_t> under;
- size_t idx = 0;
- for (const double item : *probabilities) {
- assert(item >= 0);
- const double v = item * n;
- q.emplace_back(v, 0);
- if (v < 1.0) {
- under.push_back(idx++);
- } else {
- over.push_back(idx++);
- }
- }
- while (!over.empty() && !under.empty()) {
- auto lo = under.back();
- under.pop_back();
- auto hi = over.back();
- over.pop_back();
-
- q[lo].second = hi;
- const double r = q[hi].first - (1.0 - q[lo].first);
- q[hi].first = r;
- if (r < 1.0) {
- under.push_back(hi);
- } else {
- over.push_back(hi);
- }
- }
-
- // Due to rounding errors, there may be un-paired elements in either
- // collection; these should all be values near 1.0. For these values, set `q`
- // to 1.0 and set the alternate to the identity.
- for (auto i : over) {
- q[i] = {1.0, i};
- }
- for (auto i : under) {
- q[i] = {1.0, i};
- }
- return q;
-}
-
-} // namespace random_internal
+namespace random_internal {
+
+// Initializes the distribution table for Walker's Aliasing algorithm, described
+// in Knuth, Vol 2. as well as in https://en.wikipedia.org/wiki/Alias_method
+std::vector<std::pair<double, size_t>> InitDiscreteDistribution(
+ std::vector<double>* probabilities) {
+ // The empty-case should already be handled by the constructor.
+ assert(probabilities);
+ assert(!probabilities->empty());
+
+ // Step 1. Normalize the input probabilities to 1.0.
+ double sum = std::accumulate(std::begin(*probabilities),
+ std::end(*probabilities), 0.0);
+ if (std::fabs(sum - 1.0) > 1e-6) {
+ // Scale `probabilities` only when the sum is too far from 1.0. Scaling
+ // unconditionally will alter the probabilities slightly.
+ for (double& item : *probabilities) {
+ item = item / sum;
+ }
+ }
+
+ // Step 2. At this point `probabilities` is set to the conditional
+ // probabilities of each element which sum to 1.0, to within reasonable error.
+ // These values are used to construct the proportional probability tables for
+ // the selection phases of Walker's Aliasing algorithm.
+ //
+ // To construct the table, pick an element which is under-full (i.e., an
+ // element for which `(*probabilities)[i] < 1.0/n`), and pair it with an
+ // element which is over-full (i.e., an element for which
+ // `(*probabilities)[i] > 1.0/n`). The smaller value can always be retired.
+ // The larger may still be greater than 1.0/n, or may now be less than 1.0/n,
+ // and put back onto the appropriate collection.
+ const size_t n = probabilities->size();
+ std::vector<std::pair<double, size_t>> q;
+ q.reserve(n);
+
+ std::vector<size_t> over;
+ std::vector<size_t> under;
+ size_t idx = 0;
+ for (const double item : *probabilities) {
+ assert(item >= 0);
+ const double v = item * n;
+ q.emplace_back(v, 0);
+ if (v < 1.0) {
+ under.push_back(idx++);
+ } else {
+ over.push_back(idx++);
+ }
+ }
+ while (!over.empty() && !under.empty()) {
+ auto lo = under.back();
+ under.pop_back();
+ auto hi = over.back();
+ over.pop_back();
+
+ q[lo].second = hi;
+ const double r = q[hi].first - (1.0 - q[lo].first);
+ q[hi].first = r;
+ if (r < 1.0) {
+ under.push_back(hi);
+ } else {
+ over.push_back(hi);
+ }
+ }
+
+ // Due to rounding errors, there may be un-paired elements in either
+ // collection; these should all be values near 1.0. For these values, set `q`
+ // to 1.0 and set the alternate to the identity.
+ for (auto i : over) {
+ q[i] = {1.0, i};
+ }
+ for (auto i : under) {
+ q[i] = {1.0, i};
+ }
+ return q;
+}
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
+} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.h b/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.h
index 8a390fde21..171aa11a1e 100644
--- a/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/discrete_distribution.h
@@ -1,247 +1,247 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_DISCRETE_DISTRIBUTION_H_
-#define ABSL_RANDOM_DISCRETE_DISTRIBUTION_H_
-
-#include <cassert>
-#include <cmath>
-#include <istream>
-#include <limits>
-#include <numeric>
-#include <type_traits>
-#include <utility>
-#include <vector>
-
-#include "absl/random/bernoulli_distribution.h"
-#include "absl/random/internal/iostream_state_saver.h"
-#include "absl/random/uniform_int_distribution.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_DISCRETE_DISTRIBUTION_H_
+#define ABSL_RANDOM_DISCRETE_DISTRIBUTION_H_
+
+#include <cassert>
+#include <cmath>
+#include <istream>
+#include <limits>
+#include <numeric>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "absl/random/bernoulli_distribution.h"
+#include "absl/random/internal/iostream_state_saver.h"
+#include "absl/random/uniform_int_distribution.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-
-// absl::discrete_distribution
-//
-// A discrete distribution produces random integers i, where 0 <= i < n
-// distributed according to the discrete probability function:
-//
-// P(i|p0,...,pn−1)=pi
-//
-// This class is an implementation of discrete_distribution (see
-// [rand.dist.samp.discrete]).
-//
-// The algorithm used is Walker's Aliasing algorithm, described in Knuth, Vol 2.
-// absl::discrete_distribution takes O(N) time to precompute the probabilities
-// (where N is the number of possible outcomes in the distribution) at
-// construction, and then takes O(1) time for each variate generation. Many
-// other implementations also take O(N) time to construct an ordered sequence of
-// partial sums, plus O(log N) time per variate to binary search.
-//
-template <typename IntType = int>
-class discrete_distribution {
- public:
- using result_type = IntType;
-
- class param_type {
- public:
- using distribution_type = discrete_distribution;
-
- param_type() { init(); }
-
- template <typename InputIterator>
- explicit param_type(InputIterator begin, InputIterator end)
- : p_(begin, end) {
- init();
- }
-
- explicit param_type(std::initializer_list<double> weights) : p_(weights) {
- init();
- }
-
- template <class UnaryOperation>
- explicit param_type(size_t nw, double xmin, double xmax,
- UnaryOperation fw) {
- if (nw > 0) {
- p_.reserve(nw);
- double delta = (xmax - xmin) / static_cast<double>(nw);
- assert(delta > 0);
- double t = delta * 0.5;
- for (size_t i = 0; i < nw; ++i) {
- p_.push_back(fw(xmin + i * delta + t));
- }
- }
- init();
- }
-
- const std::vector<double>& probabilities() const { return p_; }
- size_t n() const { return p_.size() - 1; }
-
- friend bool operator==(const param_type& a, const param_type& b) {
- return a.probabilities() == b.probabilities();
- }
-
- friend bool operator!=(const param_type& a, const param_type& b) {
- return !(a == b);
- }
-
- private:
- friend class discrete_distribution;
-
- void init();
-
- std::vector<double> p_; // normalized probabilities
- std::vector<std::pair<double, size_t>> q_; // (acceptance, alternate) pairs
-
- static_assert(std::is_integral<result_type>::value,
- "Class-template absl::discrete_distribution<> must be "
- "parameterized using an integral type.");
- };
-
- discrete_distribution() : param_() {}
-
- explicit discrete_distribution(const param_type& p) : param_(p) {}
-
- template <typename InputIterator>
- explicit discrete_distribution(InputIterator begin, InputIterator end)
- : param_(begin, end) {}
-
- explicit discrete_distribution(std::initializer_list<double> weights)
- : param_(weights) {}
-
- template <class UnaryOperation>
- explicit discrete_distribution(size_t nw, double xmin, double xmax,
- UnaryOperation fw)
- : param_(nw, xmin, xmax, std::move(fw)) {}
-
- void reset() {}
-
- // generating functions
- template <typename URBG>
- result_type operator()(URBG& g) { // NOLINT(runtime/references)
- return (*this)(g, param_);
- }
-
- template <typename URBG>
- result_type operator()(URBG& g, // NOLINT(runtime/references)
- const param_type& p);
-
- const param_type& param() const { return param_; }
- void param(const param_type& p) { param_ = p; }
-
- result_type(min)() const { return 0; }
- result_type(max)() const {
- return static_cast<result_type>(param_.n());
- } // inclusive
-
- // NOTE [rand.dist.sample.discrete] returns a std::vector<double> not a
- // const std::vector<double>&.
- const std::vector<double>& probabilities() const {
- return param_.probabilities();
- }
-
- friend bool operator==(const discrete_distribution& a,
- const discrete_distribution& b) {
- return a.param_ == b.param_;
- }
- friend bool operator!=(const discrete_distribution& a,
- const discrete_distribution& b) {
- return a.param_ != b.param_;
- }
-
- private:
- param_type param_;
-};
-
-// --------------------------------------------------------------------------
-// Implementation details only below
-// --------------------------------------------------------------------------
-
-namespace random_internal {
-
-// Using the vector `*probabilities`, whose values are the weights or
-// probabilities of an element being selected, constructs the proportional
-// probabilities used by the discrete distribution. `*probabilities` will be
-// scaled, if necessary, so that its entries sum to a value sufficiently close
-// to 1.0.
-std::vector<std::pair<double, size_t>> InitDiscreteDistribution(
- std::vector<double>* probabilities);
-
-} // namespace random_internal
-
-template <typename IntType>
-void discrete_distribution<IntType>::param_type::init() {
- if (p_.empty()) {
- p_.push_back(1.0);
- q_.emplace_back(1.0, 0);
- } else {
- assert(n() <= (std::numeric_limits<IntType>::max)());
- q_ = random_internal::InitDiscreteDistribution(&p_);
- }
-}
-
-template <typename IntType>
-template <typename URBG>
-typename discrete_distribution<IntType>::result_type
-discrete_distribution<IntType>::operator()(
- URBG& g, // NOLINT(runtime/references)
- const param_type& p) {
- const auto idx = absl::uniform_int_distribution<result_type>(0, p.n())(g);
- const auto& q = p.q_[idx];
- const bool selected = absl::bernoulli_distribution(q.first)(g);
- return selected ? idx : static_cast<result_type>(q.second);
-}
-
-template <typename CharT, typename Traits, typename IntType>
-std::basic_ostream<CharT, Traits>& operator<<(
- std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
- const discrete_distribution<IntType>& x) {
- auto saver = random_internal::make_ostream_state_saver(os);
- const auto& probabilities = x.param().probabilities();
- os << probabilities.size();
-
- os.precision(random_internal::stream_precision_helper<double>::kPrecision);
- for (const auto& p : probabilities) {
- os << os.fill() << p;
- }
- return os;
-}
-
-template <typename CharT, typename Traits, typename IntType>
-std::basic_istream<CharT, Traits>& operator>>(
- std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
- discrete_distribution<IntType>& x) { // NOLINT(runtime/references)
- using param_type = typename discrete_distribution<IntType>::param_type;
- auto saver = random_internal::make_istream_state_saver(is);
-
- size_t n;
- std::vector<double> p;
-
- is >> n;
- if (is.fail()) return is;
- if (n > 0) {
- p.reserve(n);
- for (IntType i = 0; i < n && !is.fail(); ++i) {
- auto tmp = random_internal::read_floating_point<double>(is);
- if (is.fail()) return is;
- p.push_back(tmp);
- }
- }
- x.param(param_type(p.begin(), p.end()));
- return is;
-}
-
+
+// absl::discrete_distribution
+//
+// A discrete distribution produces random integers i, where 0 <= i < n
+// distributed according to the discrete probability function:
+//
+// P(i|p0,...,pn−1)=pi
+//
+// This class is an implementation of discrete_distribution (see
+// [rand.dist.samp.discrete]).
+//
+// The algorithm used is Walker's Aliasing algorithm, described in Knuth, Vol 2.
+// absl::discrete_distribution takes O(N) time to precompute the probabilities
+// (where N is the number of possible outcomes in the distribution) at
+// construction, and then takes O(1) time for each variate generation. Many
+// other implementations also take O(N) time to construct an ordered sequence of
+// partial sums, plus O(log N) time per variate to binary search.
+//
+template <typename IntType = int>
+class discrete_distribution {
+ public:
+ using result_type = IntType;
+
+ class param_type {
+ public:
+ using distribution_type = discrete_distribution;
+
+ param_type() { init(); }
+
+ template <typename InputIterator>
+ explicit param_type(InputIterator begin, InputIterator end)
+ : p_(begin, end) {
+ init();
+ }
+
+ explicit param_type(std::initializer_list<double> weights) : p_(weights) {
+ init();
+ }
+
+ template <class UnaryOperation>
+ explicit param_type(size_t nw, double xmin, double xmax,
+ UnaryOperation fw) {
+ if (nw > 0) {
+ p_.reserve(nw);
+ double delta = (xmax - xmin) / static_cast<double>(nw);
+ assert(delta > 0);
+ double t = delta * 0.5;
+ for (size_t i = 0; i < nw; ++i) {
+ p_.push_back(fw(xmin + i * delta + t));
+ }
+ }
+ init();
+ }
+
+ const std::vector<double>& probabilities() const { return p_; }
+ size_t n() const { return p_.size() - 1; }
+
+ friend bool operator==(const param_type& a, const param_type& b) {
+ return a.probabilities() == b.probabilities();
+ }
+
+ friend bool operator!=(const param_type& a, const param_type& b) {
+ return !(a == b);
+ }
+
+ private:
+ friend class discrete_distribution;
+
+ void init();
+
+ std::vector<double> p_; // normalized probabilities
+ std::vector<std::pair<double, size_t>> q_; // (acceptance, alternate) pairs
+
+ static_assert(std::is_integral<result_type>::value,
+ "Class-template absl::discrete_distribution<> must be "
+ "parameterized using an integral type.");
+ };
+
+ discrete_distribution() : param_() {}
+
+ explicit discrete_distribution(const param_type& p) : param_(p) {}
+
+ template <typename InputIterator>
+ explicit discrete_distribution(InputIterator begin, InputIterator end)
+ : param_(begin, end) {}
+
+ explicit discrete_distribution(std::initializer_list<double> weights)
+ : param_(weights) {}
+
+ template <class UnaryOperation>
+ explicit discrete_distribution(size_t nw, double xmin, double xmax,
+ UnaryOperation fw)
+ : param_(nw, xmin, xmax, std::move(fw)) {}
+
+ void reset() {}
+
+ // generating functions
+ template <typename URBG>
+ result_type operator()(URBG& g) { // NOLINT(runtime/references)
+ return (*this)(g, param_);
+ }
+
+ template <typename URBG>
+ result_type operator()(URBG& g, // NOLINT(runtime/references)
+ const param_type& p);
+
+ const param_type& param() const { return param_; }
+ void param(const param_type& p) { param_ = p; }
+
+ result_type(min)() const { return 0; }
+ result_type(max)() const {
+ return static_cast<result_type>(param_.n());
+ } // inclusive
+
+ // NOTE [rand.dist.sample.discrete] returns a std::vector<double> not a
+ // const std::vector<double>&.
+ const std::vector<double>& probabilities() const {
+ return param_.probabilities();
+ }
+
+ friend bool operator==(const discrete_distribution& a,
+ const discrete_distribution& b) {
+ return a.param_ == b.param_;
+ }
+ friend bool operator!=(const discrete_distribution& a,
+ const discrete_distribution& b) {
+ return a.param_ != b.param_;
+ }
+
+ private:
+ param_type param_;
+};
+
+// --------------------------------------------------------------------------
+// Implementation details only below
+// --------------------------------------------------------------------------
+
+namespace random_internal {
+
+// Using the vector `*probabilities`, whose values are the weights or
+// probabilities of an element being selected, constructs the proportional
+// probabilities used by the discrete distribution. `*probabilities` will be
+// scaled, if necessary, so that its entries sum to a value sufficiently close
+// to 1.0.
+std::vector<std::pair<double, size_t>> InitDiscreteDistribution(
+ std::vector<double>* probabilities);
+
+} // namespace random_internal
+
+template <typename IntType>
+void discrete_distribution<IntType>::param_type::init() {
+ if (p_.empty()) {
+ p_.push_back(1.0);
+ q_.emplace_back(1.0, 0);
+ } else {
+ assert(n() <= (std::numeric_limits<IntType>::max)());
+ q_ = random_internal::InitDiscreteDistribution(&p_);
+ }
+}
+
+template <typename IntType>
+template <typename URBG>
+typename discrete_distribution<IntType>::result_type
+discrete_distribution<IntType>::operator()(
+ URBG& g, // NOLINT(runtime/references)
+ const param_type& p) {
+ const auto idx = absl::uniform_int_distribution<result_type>(0, p.n())(g);
+ const auto& q = p.q_[idx];
+ const bool selected = absl::bernoulli_distribution(q.first)(g);
+ return selected ? idx : static_cast<result_type>(q.second);
+}
+
+template <typename CharT, typename Traits, typename IntType>
+std::basic_ostream<CharT, Traits>& operator<<(
+ std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
+ const discrete_distribution<IntType>& x) {
+ auto saver = random_internal::make_ostream_state_saver(os);
+ const auto& probabilities = x.param().probabilities();
+ os << probabilities.size();
+
+ os.precision(random_internal::stream_precision_helper<double>::kPrecision);
+ for (const auto& p : probabilities) {
+ os << os.fill() << p;
+ }
+ return os;
+}
+
+template <typename CharT, typename Traits, typename IntType>
+std::basic_istream<CharT, Traits>& operator>>(
+ std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
+ discrete_distribution<IntType>& x) { // NOLINT(runtime/references)
+ using param_type = typename discrete_distribution<IntType>::param_type;
+ auto saver = random_internal::make_istream_state_saver(is);
+
+ size_t n;
+ std::vector<double> p;
+
+ is >> n;
+ if (is.fail()) return is;
+ if (n > 0) {
+ p.reserve(n);
+ for (IntType i = 0; i < n && !is.fail(); ++i) {
+ auto tmp = random_internal::read_floating_point<double>(is);
+ if (is.fail()) return is;
+ p.push_back(tmp);
+ }
+ }
+ x.param(param_type(p.begin(), p.end()));
+ return is;
+}
+
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_DISCRETE_DISTRIBUTION_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_DISCRETE_DISTRIBUTION_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/distributions.h b/contrib/restricted/abseil-cpp/absl/random/distributions.h
index ee33d64416..31c79694e5 100644
--- a/contrib/restricted/abseil-cpp/absl/random/distributions.h
+++ b/contrib/restricted/abseil-cpp/absl/random/distributions.h
@@ -1,452 +1,452 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// -----------------------------------------------------------------------------
-// File: distributions.h
-// -----------------------------------------------------------------------------
-//
-// This header defines functions representing distributions, which you use in
-// combination with an Abseil random bit generator to produce random values
-// according to the rules of that distribution.
-//
-// The Abseil random library defines the following distributions within this
-// file:
-//
-// * `absl::Uniform` for uniform (constant) distributions having constant
-// probability
-// * `absl::Bernoulli` for discrete distributions having exactly two outcomes
-// * `absl::Beta` for continuous distributions parameterized through two
-// free parameters
-// * `absl::Exponential` for discrete distributions of events occurring
-// continuously and independently at a constant average rate
-// * `absl::Gaussian` (also known as "normal distributions") for continuous
-// distributions using an associated quadratic function
-// * `absl::LogUniform` for continuous uniform distributions where the log
-// to the given base of all values is uniform
-// * `absl::Poisson` for discrete probability distributions that express the
-// probability of a given number of events occurring within a fixed interval
-// * `absl::Zipf` for discrete probability distributions commonly used for
-// modelling of rare events
-//
-// Prefer use of these distribution function classes over manual construction of
-// your own distribution classes, as it allows library maintainers greater
-// flexibility to change the underlying implementation in the future.
-
-#ifndef ABSL_RANDOM_DISTRIBUTIONS_H_
-#define ABSL_RANDOM_DISTRIBUTIONS_H_
-
-#include <algorithm>
-#include <cmath>
-#include <limits>
-#include <random>
-#include <type_traits>
-
-#include "absl/base/internal/inline_variable.h"
-#include "absl/random/bernoulli_distribution.h"
-#include "absl/random/beta_distribution.h"
-#include "absl/random/exponential_distribution.h"
-#include "absl/random/gaussian_distribution.h"
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// -----------------------------------------------------------------------------
+// File: distributions.h
+// -----------------------------------------------------------------------------
+//
+// This header defines functions representing distributions, which you use in
+// combination with an Abseil random bit generator to produce random values
+// according to the rules of that distribution.
+//
+// The Abseil random library defines the following distributions within this
+// file:
+//
+// * `absl::Uniform` for uniform (constant) distributions having constant
+// probability
+// * `absl::Bernoulli` for discrete distributions having exactly two outcomes
+// * `absl::Beta` for continuous distributions parameterized through two
+// free parameters
+// * `absl::Exponential` for discrete distributions of events occurring
+// continuously and independently at a constant average rate
+// * `absl::Gaussian` (also known as "normal distributions") for continuous
+// distributions using an associated quadratic function
+// * `absl::LogUniform` for continuous uniform distributions where the log
+// to the given base of all values is uniform
+// * `absl::Poisson` for discrete probability distributions that express the
+// probability of a given number of events occurring within a fixed interval
+// * `absl::Zipf` for discrete probability distributions commonly used for
+// modelling of rare events
+//
+// Prefer use of these distribution function classes over manual construction of
+// your own distribution classes, as it allows library maintainers greater
+// flexibility to change the underlying implementation in the future.
+
+#ifndef ABSL_RANDOM_DISTRIBUTIONS_H_
+#define ABSL_RANDOM_DISTRIBUTIONS_H_
+
+#include <algorithm>
+#include <cmath>
+#include <limits>
+#include <random>
+#include <type_traits>
+
+#include "absl/base/internal/inline_variable.h"
+#include "absl/random/bernoulli_distribution.h"
+#include "absl/random/beta_distribution.h"
+#include "absl/random/exponential_distribution.h"
+#include "absl/random/gaussian_distribution.h"
#include "absl/random/internal/distribution_caller.h" // IWYU pragma: export
-#include "absl/random/internal/uniform_helper.h" // IWYU pragma: export
-#include "absl/random/log_uniform_int_distribution.h"
-#include "absl/random/poisson_distribution.h"
-#include "absl/random/uniform_int_distribution.h"
-#include "absl/random/uniform_real_distribution.h"
-#include "absl/random/zipf_distribution.h"
-
-namespace absl {
+#include "absl/random/internal/uniform_helper.h" // IWYU pragma: export
+#include "absl/random/log_uniform_int_distribution.h"
+#include "absl/random/poisson_distribution.h"
+#include "absl/random/uniform_int_distribution.h"
+#include "absl/random/uniform_real_distribution.h"
+#include "absl/random/zipf_distribution.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-
-ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalClosedClosedTag, IntervalClosedClosed,
- {});
-ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalClosedClosedTag, IntervalClosed, {});
-ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalClosedOpenTag, IntervalClosedOpen, {});
-ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalOpenOpenTag, IntervalOpenOpen, {});
-ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalOpenOpenTag, IntervalOpen, {});
-ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalOpenClosedTag, IntervalOpenClosed, {});
-
-// -----------------------------------------------------------------------------
-// absl::Uniform<T>(tag, bitgen, lo, hi)
-// -----------------------------------------------------------------------------
-//
-// `absl::Uniform()` produces random values of type `T` uniformly distributed in
-// a defined interval {lo, hi}. The interval `tag` defines the type of interval
-// which should be one of the following possible values:
-//
-// * `absl::IntervalOpenOpen`
-// * `absl::IntervalOpenClosed`
-// * `absl::IntervalClosedOpen`
-// * `absl::IntervalClosedClosed`
-//
-// where "open" refers to an exclusive value (excluded) from the output, while
-// "closed" refers to an inclusive value (included) from the output.
-//
-// In the absence of an explicit return type `T`, `absl::Uniform()` will deduce
-// the return type based on the provided endpoint arguments {A lo, B hi}.
-// Given these endpoints, one of {A, B} will be chosen as the return type, if
-// a type can be implicitly converted into the other in a lossless way. The
-// lack of any such implicit conversion between {A, B} will produce a
-// compile-time error
-//
-// See https://en.wikipedia.org/wiki/Uniform_distribution_(continuous)
-//
-// Example:
-//
-// absl::BitGen bitgen;
-//
-// // Produce a random float value between 0.0 and 1.0, inclusive
-// auto x = absl::Uniform(absl::IntervalClosedClosed, bitgen, 0.0f, 1.0f);
-//
-// // The most common interval of `absl::IntervalClosedOpen` is available by
-// // default:
-//
-// auto x = absl::Uniform(bitgen, 0.0f, 1.0f);
-//
-// // Return-types are typically inferred from the arguments, however callers
-// // can optionally provide an explicit return-type to the template.
-//
-// auto x = absl::Uniform<float>(bitgen, 0, 1);
-//
-template <typename R = void, typename TagType, typename URBG>
-typename absl::enable_if_t<!std::is_same<R, void>::value, R> //
-Uniform(TagType tag,
- URBG&& urbg, // NOLINT(runtime/references)
- R lo, R hi) {
- using gen_t = absl::decay_t<URBG>;
- using distribution_t = random_internal::UniformDistributionWrapper<R>;
-
- auto a = random_internal::uniform_lower_bound(tag, lo, hi);
- auto b = random_internal::uniform_upper_bound(tag, lo, hi);
+
+ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalClosedClosedTag, IntervalClosedClosed,
+ {});
+ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalClosedClosedTag, IntervalClosed, {});
+ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalClosedOpenTag, IntervalClosedOpen, {});
+ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalOpenOpenTag, IntervalOpenOpen, {});
+ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalOpenOpenTag, IntervalOpen, {});
+ABSL_INTERNAL_INLINE_CONSTEXPR(IntervalOpenClosedTag, IntervalOpenClosed, {});
+
+// -----------------------------------------------------------------------------
+// absl::Uniform<T>(tag, bitgen, lo, hi)
+// -----------------------------------------------------------------------------
+//
+// `absl::Uniform()` produces random values of type `T` uniformly distributed in
+// a defined interval {lo, hi}. The interval `tag` defines the type of interval
+// which should be one of the following possible values:
+//
+// * `absl::IntervalOpenOpen`
+// * `absl::IntervalOpenClosed`
+// * `absl::IntervalClosedOpen`
+// * `absl::IntervalClosedClosed`
+//
+// where "open" refers to an exclusive value (excluded) from the output, while
+// "closed" refers to an inclusive value (included) from the output.
+//
+// In the absence of an explicit return type `T`, `absl::Uniform()` will deduce
+// the return type based on the provided endpoint arguments {A lo, B hi}.
+// Given these endpoints, one of {A, B} will be chosen as the return type, if
+// a type can be implicitly converted into the other in a lossless way. The
+// lack of any such implicit conversion between {A, B} will produce a
+// compile-time error
+//
+// See https://en.wikipedia.org/wiki/Uniform_distribution_(continuous)
+//
+// Example:
+//
+// absl::BitGen bitgen;
+//
+// // Produce a random float value between 0.0 and 1.0, inclusive
+// auto x = absl::Uniform(absl::IntervalClosedClosed, bitgen, 0.0f, 1.0f);
+//
+// // The most common interval of `absl::IntervalClosedOpen` is available by
+// // default:
+//
+// auto x = absl::Uniform(bitgen, 0.0f, 1.0f);
+//
+// // Return-types are typically inferred from the arguments, however callers
+// // can optionally provide an explicit return-type to the template.
+//
+// auto x = absl::Uniform<float>(bitgen, 0, 1);
+//
+template <typename R = void, typename TagType, typename URBG>
+typename absl::enable_if_t<!std::is_same<R, void>::value, R> //
+Uniform(TagType tag,
+ URBG&& urbg, // NOLINT(runtime/references)
+ R lo, R hi) {
+ using gen_t = absl::decay_t<URBG>;
+ using distribution_t = random_internal::UniformDistributionWrapper<R>;
+
+ auto a = random_internal::uniform_lower_bound(tag, lo, hi);
+ auto b = random_internal::uniform_upper_bound(tag, lo, hi);
if (!random_internal::is_uniform_range_valid(a, b)) return lo;
-
- return random_internal::DistributionCaller<gen_t>::template Call<
+
+ return random_internal::DistributionCaller<gen_t>::template Call<
distribution_t>(&urbg, tag, lo, hi);
-}
-
-// absl::Uniform<T>(bitgen, lo, hi)
-//
-// Overload of `Uniform()` using the default closed-open interval of [lo, hi),
-// and returning values of type `T`
-template <typename R = void, typename URBG>
-typename absl::enable_if_t<!std::is_same<R, void>::value, R> //
-Uniform(URBG&& urbg, // NOLINT(runtime/references)
- R lo, R hi) {
- using gen_t = absl::decay_t<URBG>;
- using distribution_t = random_internal::UniformDistributionWrapper<R>;
+}
+
+// absl::Uniform<T>(bitgen, lo, hi)
+//
+// Overload of `Uniform()` using the default closed-open interval of [lo, hi),
+// and returning values of type `T`
+template <typename R = void, typename URBG>
+typename absl::enable_if_t<!std::is_same<R, void>::value, R> //
+Uniform(URBG&& urbg, // NOLINT(runtime/references)
+ R lo, R hi) {
+ using gen_t = absl::decay_t<URBG>;
+ using distribution_t = random_internal::UniformDistributionWrapper<R>;
constexpr auto tag = absl::IntervalClosedOpen;
-
- auto a = random_internal::uniform_lower_bound(tag, lo, hi);
- auto b = random_internal::uniform_upper_bound(tag, lo, hi);
+
+ auto a = random_internal::uniform_lower_bound(tag, lo, hi);
+ auto b = random_internal::uniform_upper_bound(tag, lo, hi);
if (!random_internal::is_uniform_range_valid(a, b)) return lo;
-
- return random_internal::DistributionCaller<gen_t>::template Call<
+
+ return random_internal::DistributionCaller<gen_t>::template Call<
distribution_t>(&urbg, lo, hi);
-}
-
-// absl::Uniform(tag, bitgen, lo, hi)
-//
-// Overload of `Uniform()` using different (but compatible) lo, hi types. Note
-// that a compile-error will result if the return type cannot be deduced
-// correctly from the passed types.
-template <typename R = void, typename TagType, typename URBG, typename A,
- typename B>
-typename absl::enable_if_t<std::is_same<R, void>::value,
- random_internal::uniform_inferred_return_t<A, B>>
-Uniform(TagType tag,
- URBG&& urbg, // NOLINT(runtime/references)
- A lo, B hi) {
- using gen_t = absl::decay_t<URBG>;
- using return_t = typename random_internal::uniform_inferred_return_t<A, B>;
- using distribution_t = random_internal::UniformDistributionWrapper<return_t>;
-
- auto a = random_internal::uniform_lower_bound<return_t>(tag, lo, hi);
- auto b = random_internal::uniform_upper_bound<return_t>(tag, lo, hi);
+}
+
+// absl::Uniform(tag, bitgen, lo, hi)
+//
+// Overload of `Uniform()` using different (but compatible) lo, hi types. Note
+// that a compile-error will result if the return type cannot be deduced
+// correctly from the passed types.
+template <typename R = void, typename TagType, typename URBG, typename A,
+ typename B>
+typename absl::enable_if_t<std::is_same<R, void>::value,
+ random_internal::uniform_inferred_return_t<A, B>>
+Uniform(TagType tag,
+ URBG&& urbg, // NOLINT(runtime/references)
+ A lo, B hi) {
+ using gen_t = absl::decay_t<URBG>;
+ using return_t = typename random_internal::uniform_inferred_return_t<A, B>;
+ using distribution_t = random_internal::UniformDistributionWrapper<return_t>;
+
+ auto a = random_internal::uniform_lower_bound<return_t>(tag, lo, hi);
+ auto b = random_internal::uniform_upper_bound<return_t>(tag, lo, hi);
if (!random_internal::is_uniform_range_valid(a, b)) return lo;
-
- return random_internal::DistributionCaller<gen_t>::template Call<
+
+ return random_internal::DistributionCaller<gen_t>::template Call<
distribution_t>(&urbg, tag, static_cast<return_t>(lo),
- static_cast<return_t>(hi));
-}
-
-// absl::Uniform(bitgen, lo, hi)
-//
-// Overload of `Uniform()` using different (but compatible) lo, hi types and the
-// default closed-open interval of [lo, hi). Note that a compile-error will
-// result if the return type cannot be deduced correctly from the passed types.
-template <typename R = void, typename URBG, typename A, typename B>
-typename absl::enable_if_t<std::is_same<R, void>::value,
- random_internal::uniform_inferred_return_t<A, B>>
-Uniform(URBG&& urbg, // NOLINT(runtime/references)
- A lo, B hi) {
- using gen_t = absl::decay_t<URBG>;
- using return_t = typename random_internal::uniform_inferred_return_t<A, B>;
- using distribution_t = random_internal::UniformDistributionWrapper<return_t>;
-
- constexpr auto tag = absl::IntervalClosedOpen;
- auto a = random_internal::uniform_lower_bound<return_t>(tag, lo, hi);
- auto b = random_internal::uniform_upper_bound<return_t>(tag, lo, hi);
+ static_cast<return_t>(hi));
+}
+
+// absl::Uniform(bitgen, lo, hi)
+//
+// Overload of `Uniform()` using different (but compatible) lo, hi types and the
+// default closed-open interval of [lo, hi). Note that a compile-error will
+// result if the return type cannot be deduced correctly from the passed types.
+template <typename R = void, typename URBG, typename A, typename B>
+typename absl::enable_if_t<std::is_same<R, void>::value,
+ random_internal::uniform_inferred_return_t<A, B>>
+Uniform(URBG&& urbg, // NOLINT(runtime/references)
+ A lo, B hi) {
+ using gen_t = absl::decay_t<URBG>;
+ using return_t = typename random_internal::uniform_inferred_return_t<A, B>;
+ using distribution_t = random_internal::UniformDistributionWrapper<return_t>;
+
+ constexpr auto tag = absl::IntervalClosedOpen;
+ auto a = random_internal::uniform_lower_bound<return_t>(tag, lo, hi);
+ auto b = random_internal::uniform_upper_bound<return_t>(tag, lo, hi);
if (!random_internal::is_uniform_range_valid(a, b)) return lo;
-
- return random_internal::DistributionCaller<gen_t>::template Call<
+
+ return random_internal::DistributionCaller<gen_t>::template Call<
distribution_t>(&urbg, static_cast<return_t>(lo),
- static_cast<return_t>(hi));
-}
-
-// absl::Uniform<unsigned T>(bitgen)
-//
-// Overload of Uniform() using the minimum and maximum values of a given type
-// `T` (which must be unsigned), returning a value of type `unsigned T`
-template <typename R, typename URBG>
-typename absl::enable_if_t<!std::is_signed<R>::value, R> //
-Uniform(URBG&& urbg) { // NOLINT(runtime/references)
- using gen_t = absl::decay_t<URBG>;
- using distribution_t = random_internal::UniformDistributionWrapper<R>;
-
- return random_internal::DistributionCaller<gen_t>::template Call<
+ static_cast<return_t>(hi));
+}
+
+// absl::Uniform<unsigned T>(bitgen)
+//
+// Overload of Uniform() using the minimum and maximum values of a given type
+// `T` (which must be unsigned), returning a value of type `unsigned T`
+template <typename R, typename URBG>
+typename absl::enable_if_t<!std::is_signed<R>::value, R> //
+Uniform(URBG&& urbg) { // NOLINT(runtime/references)
+ using gen_t = absl::decay_t<URBG>;
+ using distribution_t = random_internal::UniformDistributionWrapper<R>;
+
+ return random_internal::DistributionCaller<gen_t>::template Call<
distribution_t>(&urbg);
-}
-
-// -----------------------------------------------------------------------------
-// absl::Bernoulli(bitgen, p)
-// -----------------------------------------------------------------------------
-//
-// `absl::Bernoulli` produces a random boolean value, with probability `p`
-// (where 0.0 <= p <= 1.0) equaling `true`.
-//
-// Prefer `absl::Bernoulli` to produce boolean values over other alternatives
-// such as comparing an `absl::Uniform()` value to a specific output.
-//
-// See https://en.wikipedia.org/wiki/Bernoulli_distribution
-//
-// Example:
-//
-// absl::BitGen bitgen;
-// ...
-// if (absl::Bernoulli(bitgen, 1.0/3721.0)) {
-// std::cout << "Asteroid field navigation successful.";
-// }
-//
-template <typename URBG>
-bool Bernoulli(URBG&& urbg, // NOLINT(runtime/references)
- double p) {
- using gen_t = absl::decay_t<URBG>;
- using distribution_t = absl::bernoulli_distribution;
-
- return random_internal::DistributionCaller<gen_t>::template Call<
+}
+
+// -----------------------------------------------------------------------------
+// absl::Bernoulli(bitgen, p)
+// -----------------------------------------------------------------------------
+//
+// `absl::Bernoulli` produces a random boolean value, with probability `p`
+// (where 0.0 <= p <= 1.0) equaling `true`.
+//
+// Prefer `absl::Bernoulli` to produce boolean values over other alternatives
+// such as comparing an `absl::Uniform()` value to a specific output.
+//
+// See https://en.wikipedia.org/wiki/Bernoulli_distribution
+//
+// Example:
+//
+// absl::BitGen bitgen;
+// ...
+// if (absl::Bernoulli(bitgen, 1.0/3721.0)) {
+// std::cout << "Asteroid field navigation successful.";
+// }
+//
+template <typename URBG>
+bool Bernoulli(URBG&& urbg, // NOLINT(runtime/references)
+ double p) {
+ using gen_t = absl::decay_t<URBG>;
+ using distribution_t = absl::bernoulli_distribution;
+
+ return random_internal::DistributionCaller<gen_t>::template Call<
distribution_t>(&urbg, p);
-}
-
-// -----------------------------------------------------------------------------
-// absl::Beta<T>(bitgen, alpha, beta)
-// -----------------------------------------------------------------------------
-//
-// `absl::Beta` produces a floating point number distributed in the closed
-// interval [0,1] and parameterized by two values `alpha` and `beta` as per a
-// Beta distribution. `T` must be a floating point type, but may be inferred
-// from the types of `alpha` and `beta`.
-//
-// See https://en.wikipedia.org/wiki/Beta_distribution.
-//
-// Example:
-//
-// absl::BitGen bitgen;
-// ...
-// double sample = absl::Beta(bitgen, 3.0, 2.0);
-//
-template <typename RealType, typename URBG>
-RealType Beta(URBG&& urbg, // NOLINT(runtime/references)
- RealType alpha, RealType beta) {
- static_assert(
- std::is_floating_point<RealType>::value,
- "Template-argument 'RealType' must be a floating-point type, in "
- "absl::Beta<RealType, URBG>(...)");
-
- using gen_t = absl::decay_t<URBG>;
- using distribution_t = typename absl::beta_distribution<RealType>;
-
- return random_internal::DistributionCaller<gen_t>::template Call<
+}
+
+// -----------------------------------------------------------------------------
+// absl::Beta<T>(bitgen, alpha, beta)
+// -----------------------------------------------------------------------------
+//
+// `absl::Beta` produces a floating point number distributed in the closed
+// interval [0,1] and parameterized by two values `alpha` and `beta` as per a
+// Beta distribution. `T` must be a floating point type, but may be inferred
+// from the types of `alpha` and `beta`.
+//
+// See https://en.wikipedia.org/wiki/Beta_distribution.
+//
+// Example:
+//
+// absl::BitGen bitgen;
+// ...
+// double sample = absl::Beta(bitgen, 3.0, 2.0);
+//
+template <typename RealType, typename URBG>
+RealType Beta(URBG&& urbg, // NOLINT(runtime/references)
+ RealType alpha, RealType beta) {
+ static_assert(
+ std::is_floating_point<RealType>::value,
+ "Template-argument 'RealType' must be a floating-point type, in "
+ "absl::Beta<RealType, URBG>(...)");
+
+ using gen_t = absl::decay_t<URBG>;
+ using distribution_t = typename absl::beta_distribution<RealType>;
+
+ return random_internal::DistributionCaller<gen_t>::template Call<
distribution_t>(&urbg, alpha, beta);
-}
-
-// -----------------------------------------------------------------------------
-// absl::Exponential<T>(bitgen, lambda = 1)
-// -----------------------------------------------------------------------------
-//
+}
+
+// -----------------------------------------------------------------------------
+// absl::Exponential<T>(bitgen, lambda = 1)
+// -----------------------------------------------------------------------------
+//
// `absl::Exponential` produces a floating point number representing the
// distance (time) between two consecutive events in a point process of events
// occurring continuously and independently at a constant average rate. `T` must
// be a floating point type, but may be inferred from the type of `lambda`.
-//
-// See https://en.wikipedia.org/wiki/Exponential_distribution.
-//
-// Example:
-//
-// absl::BitGen bitgen;
-// ...
-// double call_length = absl::Exponential(bitgen, 7.0);
-//
-template <typename RealType, typename URBG>
-RealType Exponential(URBG&& urbg, // NOLINT(runtime/references)
- RealType lambda = 1) {
- static_assert(
- std::is_floating_point<RealType>::value,
- "Template-argument 'RealType' must be a floating-point type, in "
- "absl::Exponential<RealType, URBG>(...)");
-
- using gen_t = absl::decay_t<URBG>;
- using distribution_t = typename absl::exponential_distribution<RealType>;
-
- return random_internal::DistributionCaller<gen_t>::template Call<
+//
+// See https://en.wikipedia.org/wiki/Exponential_distribution.
+//
+// Example:
+//
+// absl::BitGen bitgen;
+// ...
+// double call_length = absl::Exponential(bitgen, 7.0);
+//
+template <typename RealType, typename URBG>
+RealType Exponential(URBG&& urbg, // NOLINT(runtime/references)
+ RealType lambda = 1) {
+ static_assert(
+ std::is_floating_point<RealType>::value,
+ "Template-argument 'RealType' must be a floating-point type, in "
+ "absl::Exponential<RealType, URBG>(...)");
+
+ using gen_t = absl::decay_t<URBG>;
+ using distribution_t = typename absl::exponential_distribution<RealType>;
+
+ return random_internal::DistributionCaller<gen_t>::template Call<
distribution_t>(&urbg, lambda);
-}
-
-// -----------------------------------------------------------------------------
-// absl::Gaussian<T>(bitgen, mean = 0, stddev = 1)
-// -----------------------------------------------------------------------------
-//
-// `absl::Gaussian` produces a floating point number selected from the Gaussian
-// (ie. "Normal") distribution. `T` must be a floating point type, but may be
-// inferred from the types of `mean` and `stddev`.
-//
-// See https://en.wikipedia.org/wiki/Normal_distribution
-//
-// Example:
-//
-// absl::BitGen bitgen;
-// ...
-// double giraffe_height = absl::Gaussian(bitgen, 16.3, 3.3);
-//
-template <typename RealType, typename URBG>
-RealType Gaussian(URBG&& urbg, // NOLINT(runtime/references)
- RealType mean = 0, RealType stddev = 1) {
- static_assert(
- std::is_floating_point<RealType>::value,
- "Template-argument 'RealType' must be a floating-point type, in "
- "absl::Gaussian<RealType, URBG>(...)");
-
- using gen_t = absl::decay_t<URBG>;
- using distribution_t = typename absl::gaussian_distribution<RealType>;
-
- return random_internal::DistributionCaller<gen_t>::template Call<
+}
+
+// -----------------------------------------------------------------------------
+// absl::Gaussian<T>(bitgen, mean = 0, stddev = 1)
+// -----------------------------------------------------------------------------
+//
+// `absl::Gaussian` produces a floating point number selected from the Gaussian
+// (ie. "Normal") distribution. `T` must be a floating point type, but may be
+// inferred from the types of `mean` and `stddev`.
+//
+// See https://en.wikipedia.org/wiki/Normal_distribution
+//
+// Example:
+//
+// absl::BitGen bitgen;
+// ...
+// double giraffe_height = absl::Gaussian(bitgen, 16.3, 3.3);
+//
+template <typename RealType, typename URBG>
+RealType Gaussian(URBG&& urbg, // NOLINT(runtime/references)
+ RealType mean = 0, RealType stddev = 1) {
+ static_assert(
+ std::is_floating_point<RealType>::value,
+ "Template-argument 'RealType' must be a floating-point type, in "
+ "absl::Gaussian<RealType, URBG>(...)");
+
+ using gen_t = absl::decay_t<URBG>;
+ using distribution_t = typename absl::gaussian_distribution<RealType>;
+
+ return random_internal::DistributionCaller<gen_t>::template Call<
distribution_t>(&urbg, mean, stddev);
-}
-
-// -----------------------------------------------------------------------------
-// absl::LogUniform<T>(bitgen, lo, hi, base = 2)
-// -----------------------------------------------------------------------------
-//
-// `absl::LogUniform` produces random values distributed where the log to a
-// given base of all values is uniform in a closed interval [lo, hi]. `T` must
-// be an integral type, but may be inferred from the types of `lo` and `hi`.
-//
-// I.e., `LogUniform(0, n, b)` is uniformly distributed across buckets
-// [0], [1, b-1], [b, b^2-1] .. [b^(k-1), (b^k)-1] .. [b^floor(log(n, b)), n]
-// and is uniformly distributed within each bucket.
-//
-// The resulting probability density is inversely related to bucket size, though
-// values in the final bucket may be more likely than previous values. (In the
-// extreme case where n = b^i the final value will be tied with zero as the most
-// probable result.
-//
-// If `lo` is nonzero then this distribution is shifted to the desired interval,
-// so LogUniform(lo, hi, b) is equivalent to LogUniform(0, hi-lo, b)+lo.
-//
-// See http://ecolego.facilia.se/ecolego/show/Log-Uniform%20Distribution
-//
-// Example:
-//
-// absl::BitGen bitgen;
-// ...
-// int v = absl::LogUniform(bitgen, 0, 1000);
-//
-template <typename IntType, typename URBG>
-IntType LogUniform(URBG&& urbg, // NOLINT(runtime/references)
- IntType lo, IntType hi, IntType base = 2) {
- static_assert(std::is_integral<IntType>::value,
- "Template-argument 'IntType' must be an integral type, in "
- "absl::LogUniform<IntType, URBG>(...)");
-
- using gen_t = absl::decay_t<URBG>;
- using distribution_t = typename absl::log_uniform_int_distribution<IntType>;
-
- return random_internal::DistributionCaller<gen_t>::template Call<
+}
+
+// -----------------------------------------------------------------------------
+// absl::LogUniform<T>(bitgen, lo, hi, base = 2)
+// -----------------------------------------------------------------------------
+//
+// `absl::LogUniform` produces random values distributed where the log to a
+// given base of all values is uniform in a closed interval [lo, hi]. `T` must
+// be an integral type, but may be inferred from the types of `lo` and `hi`.
+//
+// I.e., `LogUniform(0, n, b)` is uniformly distributed across buckets
+// [0], [1, b-1], [b, b^2-1] .. [b^(k-1), (b^k)-1] .. [b^floor(log(n, b)), n]
+// and is uniformly distributed within each bucket.
+//
+// The resulting probability density is inversely related to bucket size, though
+// values in the final bucket may be more likely than previous values. (In the
+// extreme case where n = b^i the final value will be tied with zero as the most
+// probable result.
+//
+// If `lo` is nonzero then this distribution is shifted to the desired interval,
+// so LogUniform(lo, hi, b) is equivalent to LogUniform(0, hi-lo, b)+lo.
+//
+// See http://ecolego.facilia.se/ecolego/show/Log-Uniform%20Distribution
+//
+// Example:
+//
+// absl::BitGen bitgen;
+// ...
+// int v = absl::LogUniform(bitgen, 0, 1000);
+//
+template <typename IntType, typename URBG>
+IntType LogUniform(URBG&& urbg, // NOLINT(runtime/references)
+ IntType lo, IntType hi, IntType base = 2) {
+ static_assert(std::is_integral<IntType>::value,
+ "Template-argument 'IntType' must be an integral type, in "
+ "absl::LogUniform<IntType, URBG>(...)");
+
+ using gen_t = absl::decay_t<URBG>;
+ using distribution_t = typename absl::log_uniform_int_distribution<IntType>;
+
+ return random_internal::DistributionCaller<gen_t>::template Call<
distribution_t>(&urbg, lo, hi, base);
-}
-
-// -----------------------------------------------------------------------------
-// absl::Poisson<T>(bitgen, mean = 1)
-// -----------------------------------------------------------------------------
-//
-// `absl::Poisson` produces discrete probabilities for a given number of events
-// occurring within a fixed interval within the closed interval [0, max]. `T`
-// must be an integral type.
-//
-// See https://en.wikipedia.org/wiki/Poisson_distribution
-//
-// Example:
-//
-// absl::BitGen bitgen;
-// ...
-// int requests_per_minute = absl::Poisson<int>(bitgen, 3.2);
-//
-template <typename IntType, typename URBG>
-IntType Poisson(URBG&& urbg, // NOLINT(runtime/references)
- double mean = 1.0) {
- static_assert(std::is_integral<IntType>::value,
- "Template-argument 'IntType' must be an integral type, in "
- "absl::Poisson<IntType, URBG>(...)");
-
- using gen_t = absl::decay_t<URBG>;
- using distribution_t = typename absl::poisson_distribution<IntType>;
-
- return random_internal::DistributionCaller<gen_t>::template Call<
+}
+
+// -----------------------------------------------------------------------------
+// absl::Poisson<T>(bitgen, mean = 1)
+// -----------------------------------------------------------------------------
+//
+// `absl::Poisson` produces discrete probabilities for a given number of events
+// occurring within a fixed interval within the closed interval [0, max]. `T`
+// must be an integral type.
+//
+// See https://en.wikipedia.org/wiki/Poisson_distribution
+//
+// Example:
+//
+// absl::BitGen bitgen;
+// ...
+// int requests_per_minute = absl::Poisson<int>(bitgen, 3.2);
+//
+template <typename IntType, typename URBG>
+IntType Poisson(URBG&& urbg, // NOLINT(runtime/references)
+ double mean = 1.0) {
+ static_assert(std::is_integral<IntType>::value,
+ "Template-argument 'IntType' must be an integral type, in "
+ "absl::Poisson<IntType, URBG>(...)");
+
+ using gen_t = absl::decay_t<URBG>;
+ using distribution_t = typename absl::poisson_distribution<IntType>;
+
+ return random_internal::DistributionCaller<gen_t>::template Call<
distribution_t>(&urbg, mean);
-}
-
-// -----------------------------------------------------------------------------
-// absl::Zipf<T>(bitgen, hi = max, q = 2, v = 1)
-// -----------------------------------------------------------------------------
-//
-// `absl::Zipf` produces discrete probabilities commonly used for modelling of
-// rare events over the closed interval [0, hi]. The parameters `v` and `q`
-// determine the skew of the distribution. `T` must be an integral type, but
-// may be inferred from the type of `hi`.
-//
-// See http://mathworld.wolfram.com/ZipfDistribution.html
-//
-// Example:
-//
-// absl::BitGen bitgen;
-// ...
-// int term_rank = absl::Zipf<int>(bitgen);
-//
-template <typename IntType, typename URBG>
-IntType Zipf(URBG&& urbg, // NOLINT(runtime/references)
- IntType hi = (std::numeric_limits<IntType>::max)(), double q = 2.0,
- double v = 1.0) {
- static_assert(std::is_integral<IntType>::value,
- "Template-argument 'IntType' must be an integral type, in "
- "absl::Zipf<IntType, URBG>(...)");
-
- using gen_t = absl::decay_t<URBG>;
- using distribution_t = typename absl::zipf_distribution<IntType>;
-
- return random_internal::DistributionCaller<gen_t>::template Call<
+}
+
+// -----------------------------------------------------------------------------
+// absl::Zipf<T>(bitgen, hi = max, q = 2, v = 1)
+// -----------------------------------------------------------------------------
+//
+// `absl::Zipf` produces discrete probabilities commonly used for modelling of
+// rare events over the closed interval [0, hi]. The parameters `v` and `q`
+// determine the skew of the distribution. `T` must be an integral type, but
+// may be inferred from the type of `hi`.
+//
+// See http://mathworld.wolfram.com/ZipfDistribution.html
+//
+// Example:
+//
+// absl::BitGen bitgen;
+// ...
+// int term_rank = absl::Zipf<int>(bitgen);
+//
+template <typename IntType, typename URBG>
+IntType Zipf(URBG&& urbg, // NOLINT(runtime/references)
+ IntType hi = (std::numeric_limits<IntType>::max)(), double q = 2.0,
+ double v = 1.0) {
+ static_assert(std::is_integral<IntType>::value,
+ "Template-argument 'IntType' must be an integral type, in "
+ "absl::Zipf<IntType, URBG>(...)");
+
+ using gen_t = absl::decay_t<URBG>;
+ using distribution_t = typename absl::zipf_distribution<IntType>;
+
+ return random_internal::DistributionCaller<gen_t>::template Call<
distribution_t>(&urbg, hi, q, v);
-}
-
+}
+
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_DISTRIBUTIONS_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_DISTRIBUTIONS_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/exponential_distribution.h b/contrib/restricted/abseil-cpp/absl/random/exponential_distribution.h
index aff1c481f0..b5caf8a1e1 100644
--- a/contrib/restricted/abseil-cpp/absl/random/exponential_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/exponential_distribution.h
@@ -1,165 +1,165 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_EXPONENTIAL_DISTRIBUTION_H_
-#define ABSL_RANDOM_EXPONENTIAL_DISTRIBUTION_H_
-
-#include <cassert>
-#include <cmath>
-#include <istream>
-#include <limits>
-#include <type_traits>
-
-#include "absl/meta/type_traits.h"
-#include "absl/random/internal/fast_uniform_bits.h"
-#include "absl/random/internal/generate_real.h"
-#include "absl/random/internal/iostream_state_saver.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_EXPONENTIAL_DISTRIBUTION_H_
+#define ABSL_RANDOM_EXPONENTIAL_DISTRIBUTION_H_
+
+#include <cassert>
+#include <cmath>
+#include <istream>
+#include <limits>
+#include <type_traits>
+
+#include "absl/meta/type_traits.h"
+#include "absl/random/internal/fast_uniform_bits.h"
+#include "absl/random/internal/generate_real.h"
+#include "absl/random/internal/iostream_state_saver.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-
-// absl::exponential_distribution:
-// Generates a number conforming to an exponential distribution and is
-// equivalent to the standard [rand.dist.pois.exp] distribution.
-template <typename RealType = double>
-class exponential_distribution {
- public:
- using result_type = RealType;
-
- class param_type {
- public:
- using distribution_type = exponential_distribution;
-
- explicit param_type(result_type lambda = 1) : lambda_(lambda) {
- assert(lambda > 0);
- neg_inv_lambda_ = -result_type(1) / lambda_;
- }
-
- result_type lambda() const { return lambda_; }
-
- friend bool operator==(const param_type& a, const param_type& b) {
- return a.lambda_ == b.lambda_;
- }
-
- friend bool operator!=(const param_type& a, const param_type& b) {
- return !(a == b);
- }
-
- private:
- friend class exponential_distribution;
-
- result_type lambda_;
- result_type neg_inv_lambda_;
-
- static_assert(
- std::is_floating_point<RealType>::value,
- "Class-template absl::exponential_distribution<> must be parameterized "
- "using a floating-point type.");
- };
-
- exponential_distribution() : exponential_distribution(1) {}
-
- explicit exponential_distribution(result_type lambda) : param_(lambda) {}
-
- explicit exponential_distribution(const param_type& p) : param_(p) {}
-
- void reset() {}
-
- // Generating functions
- template <typename URBG>
- result_type operator()(URBG& g) { // NOLINT(runtime/references)
- return (*this)(g, param_);
- }
-
- template <typename URBG>
- result_type operator()(URBG& g, // NOLINT(runtime/references)
- const param_type& p);
-
- param_type param() const { return param_; }
- void param(const param_type& p) { param_ = p; }
-
- result_type(min)() const { return 0; }
- result_type(max)() const {
- return std::numeric_limits<result_type>::infinity();
- }
-
- result_type lambda() const { return param_.lambda(); }
-
- friend bool operator==(const exponential_distribution& a,
- const exponential_distribution& b) {
- return a.param_ == b.param_;
- }
- friend bool operator!=(const exponential_distribution& a,
- const exponential_distribution& b) {
- return a.param_ != b.param_;
- }
-
- private:
- param_type param_;
- random_internal::FastUniformBits<uint64_t> fast_u64_;
-};
-
-// --------------------------------------------------------------------------
-// Implementation details follow
-// --------------------------------------------------------------------------
-
-template <typename RealType>
-template <typename URBG>
-typename exponential_distribution<RealType>::result_type
-exponential_distribution<RealType>::operator()(
- URBG& g, // NOLINT(runtime/references)
- const param_type& p) {
- using random_internal::GenerateNegativeTag;
- using random_internal::GenerateRealFromBits;
- using real_type =
- absl::conditional_t<std::is_same<RealType, float>::value, float, double>;
-
- const result_type u = GenerateRealFromBits<real_type, GenerateNegativeTag,
- false>(fast_u64_(g)); // U(-1, 0)
-
- // log1p(-x) is mathematically equivalent to log(1 - x) but has more
- // accuracy for x near zero.
- return p.neg_inv_lambda_ * std::log1p(u);
-}
-
-template <typename CharT, typename Traits, typename RealType>
-std::basic_ostream<CharT, Traits>& operator<<(
- std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
- const exponential_distribution<RealType>& x) {
- auto saver = random_internal::make_ostream_state_saver(os);
- os.precision(random_internal::stream_precision_helper<RealType>::kPrecision);
- os << x.lambda();
- return os;
-}
-
-template <typename CharT, typename Traits, typename RealType>
-std::basic_istream<CharT, Traits>& operator>>(
- std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
- exponential_distribution<RealType>& x) { // NOLINT(runtime/references)
- using result_type = typename exponential_distribution<RealType>::result_type;
- using param_type = typename exponential_distribution<RealType>::param_type;
- result_type lambda;
-
- auto saver = random_internal::make_istream_state_saver(is);
- lambda = random_internal::read_floating_point<result_type>(is);
- if (!is.fail()) {
- x.param(param_type(lambda));
- }
- return is;
-}
-
+
+// absl::exponential_distribution:
+// Generates a number conforming to an exponential distribution and is
+// equivalent to the standard [rand.dist.pois.exp] distribution.
+template <typename RealType = double>
+class exponential_distribution {
+ public:
+ using result_type = RealType;
+
+ class param_type {
+ public:
+ using distribution_type = exponential_distribution;
+
+ explicit param_type(result_type lambda = 1) : lambda_(lambda) {
+ assert(lambda > 0);
+ neg_inv_lambda_ = -result_type(1) / lambda_;
+ }
+
+ result_type lambda() const { return lambda_; }
+
+ friend bool operator==(const param_type& a, const param_type& b) {
+ return a.lambda_ == b.lambda_;
+ }
+
+ friend bool operator!=(const param_type& a, const param_type& b) {
+ return !(a == b);
+ }
+
+ private:
+ friend class exponential_distribution;
+
+ result_type lambda_;
+ result_type neg_inv_lambda_;
+
+ static_assert(
+ std::is_floating_point<RealType>::value,
+ "Class-template absl::exponential_distribution<> must be parameterized "
+ "using a floating-point type.");
+ };
+
+ exponential_distribution() : exponential_distribution(1) {}
+
+ explicit exponential_distribution(result_type lambda) : param_(lambda) {}
+
+ explicit exponential_distribution(const param_type& p) : param_(p) {}
+
+ void reset() {}
+
+ // Generating functions
+ template <typename URBG>
+ result_type operator()(URBG& g) { // NOLINT(runtime/references)
+ return (*this)(g, param_);
+ }
+
+ template <typename URBG>
+ result_type operator()(URBG& g, // NOLINT(runtime/references)
+ const param_type& p);
+
+ param_type param() const { return param_; }
+ void param(const param_type& p) { param_ = p; }
+
+ result_type(min)() const { return 0; }
+ result_type(max)() const {
+ return std::numeric_limits<result_type>::infinity();
+ }
+
+ result_type lambda() const { return param_.lambda(); }
+
+ friend bool operator==(const exponential_distribution& a,
+ const exponential_distribution& b) {
+ return a.param_ == b.param_;
+ }
+ friend bool operator!=(const exponential_distribution& a,
+ const exponential_distribution& b) {
+ return a.param_ != b.param_;
+ }
+
+ private:
+ param_type param_;
+ random_internal::FastUniformBits<uint64_t> fast_u64_;
+};
+
+// --------------------------------------------------------------------------
+// Implementation details follow
+// --------------------------------------------------------------------------
+
+template <typename RealType>
+template <typename URBG>
+typename exponential_distribution<RealType>::result_type
+exponential_distribution<RealType>::operator()(
+ URBG& g, // NOLINT(runtime/references)
+ const param_type& p) {
+ using random_internal::GenerateNegativeTag;
+ using random_internal::GenerateRealFromBits;
+ using real_type =
+ absl::conditional_t<std::is_same<RealType, float>::value, float, double>;
+
+ const result_type u = GenerateRealFromBits<real_type, GenerateNegativeTag,
+ false>(fast_u64_(g)); // U(-1, 0)
+
+ // log1p(-x) is mathematically equivalent to log(1 - x) but has more
+ // accuracy for x near zero.
+ return p.neg_inv_lambda_ * std::log1p(u);
+}
+
+template <typename CharT, typename Traits, typename RealType>
+std::basic_ostream<CharT, Traits>& operator<<(
+ std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
+ const exponential_distribution<RealType>& x) {
+ auto saver = random_internal::make_ostream_state_saver(os);
+ os.precision(random_internal::stream_precision_helper<RealType>::kPrecision);
+ os << x.lambda();
+ return os;
+}
+
+template <typename CharT, typename Traits, typename RealType>
+std::basic_istream<CharT, Traits>& operator>>(
+ std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
+ exponential_distribution<RealType>& x) { // NOLINT(runtime/references)
+ using result_type = typename exponential_distribution<RealType>::result_type;
+ using param_type = typename exponential_distribution<RealType>::param_type;
+ result_type lambda;
+
+ auto saver = random_internal::make_istream_state_saver(is);
+ lambda = random_internal::read_floating_point<result_type>(is);
+ if (!is.fail()) {
+ x.param(param_type(lambda));
+ }
+ return is;
+}
+
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_EXPONENTIAL_DISTRIBUTION_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_EXPONENTIAL_DISTRIBUTION_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.cc b/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.cc
index 4d1ba4d893..c7a72cb2f6 100644
--- a/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.cc
+++ b/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.cc
@@ -1,104 +1,104 @@
-// BEGIN GENERATED CODE; DO NOT EDIT
-// clang-format off
-
-#include "absl/random/gaussian_distribution.h"
-
-namespace absl {
+// BEGIN GENERATED CODE; DO NOT EDIT
+// clang-format off
+
+#include "absl/random/gaussian_distribution.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-const gaussian_distribution_base::Tables
- gaussian_distribution_base::zg_ = {
- {3.7130862467425505, 3.442619855899000214, 3.223084984581141565,
- 3.083228858216868318, 2.978696252647779819, 2.894344007021528942,
- 2.82312535054891045, 2.761169372387176857, 2.706113573121819549,
- 2.656406411261359679, 2.610972248431847387, 2.56903362592493778,
- 2.530009672388827457, 2.493454522095372106, 2.459018177411830486,
- 2.426420645533749809, 2.395434278011062457, 2.365871370117638595,
- 2.337575241339236776, 2.310413683698762988, 2.284274059677471769,
- 2.25905957386919809, 2.234686395590979036, 2.21108140887870297,
- 2.188180432076048731, 2.165926793748921497, 2.144270182360394905,
- 2.123165708673976138, 2.102573135189237608, 2.082456237992015957,
- 2.062782274508307978, 2.043521536655067194, 2.02464697337738464,
- 2.006133869963471206, 1.987959574127619033, 1.970103260854325633,
- 1.952545729553555764, 1.935269228296621957, 1.918257300864508963,
- 1.901494653105150423, 1.884967035707758143, 1.868661140994487768,
- 1.852564511728090002, 1.836665460258444904, 1.820952996596124418,
- 1.805416764219227366, 1.790046982599857506, 1.77483439558606837,
- 1.759770224899592339, 1.744846128113799244, 1.730054160563729182,
- 1.71538674071366648, 1.700836618569915748, 1.686396846779167014,
- 1.6720607540975998, 1.657821920954023254, 1.643674156862867441,
- 1.629611479470633562, 1.615628095043159629, 1.601718380221376581,
- 1.587876864890574558, 1.574098216022999264, 1.560377222366167382,
- 1.546708779859908844, 1.533087877674041755, 1.519509584765938559,
- 1.505969036863201937, 1.492461423781352714, 1.478981976989922842,
- 1.465525957342709296, 1.452088642889222792, 1.438665316684561546,
- 1.425251254514058319, 1.411841712447055919, 1.398431914131003539,
- 1.385017037732650058, 1.371592202427340812, 1.358152454330141534,
- 1.34469275175354519, 1.331207949665625279, 1.317692783209412299,
- 1.304141850128615054, 1.290549591926194894, 1.27691027356015363,
- 1.263217961454619287, 1.249466499573066436, 1.23564948326336066,
- 1.221760230539994385, 1.207791750415947662, 1.193736707833126465,
- 1.17958738466398616, 1.165335636164750222, 1.150972842148865416,
- 1.136489852013158774, 1.121876922582540237, 1.107123647534034028,
- 1.092218876907275371, 1.077150624892893482, 1.061905963694822042,
- 1.046470900764042922, 1.030830236068192907, 1.014967395251327842,
- 0.9988642334929808131, 0.9825008035154263464, 0.9658550794011470098,
- 0.9489026255113034436, 0.9316161966151479401, 0.9139652510230292792,
- 0.8959153525809346874, 0.8774274291129204872, 0.8584568431938099931,
- 0.8389522142975741614, 0.8188539067003538507, 0.7980920606440534693,
- 0.7765839878947563557, 0.7542306644540520688, 0.7309119106424850631,
- 0.7064796113354325779, 0.6807479186691505202, 0.6534786387399710295,
- 0.6243585973360461505, 0.5929629424714434327, 0.5586921784081798625,
- 0.5206560387620546848, 0.4774378372966830431, 0.4265479863554152429,
- 0.3628714310970211909, 0.2723208648139477384, 0},
- {0.001014352564120377413, 0.002669629083880922793, 0.005548995220771345792,
- 0.008624484412859888607, 0.01183947865788486861, 0.01516729801054656976,
- 0.01859210273701129151, 0.02210330461592709475, 0.02569329193593428151,
- 0.02935631744000685023, 0.03308788614622575758, 0.03688438878665621645,
- 0.04074286807444417458, 0.04466086220049143157, 0.04863629585986780496,
- 0.05266740190305100461, 0.05675266348104984759, 0.06089077034804041277,
- 0.06508058521306804567, 0.06932111739357792179, 0.07361150188411341722,
- 0.07795098251397346301, 0.08233889824223575293, 0.08677467189478028919,
- 0.09125780082683036809, 0.095787849121731522, 0.1003644410286559929,
- 0.1049872554094214289, 0.1096560210148404546, 0.1143705124488661323,
- 0.1191305467076509556, 0.1239359802028679736, 0.1287867061959434012,
- 0.1336826525834396151, 0.1386237799845948804, 0.1436100800906280339,
- 0.1486415742423425057, 0.1537183122081819397, 0.1588403711394795748,
- 0.1640078546834206341, 0.1692208922373653057, 0.1744796383307898324,
- 0.1797842721232958407, 0.1851349970089926078, 0.1905320403191375633,
- 0.1959756531162781534, 0.2014661100743140865, 0.2070037094399269362,
- 0.2125887730717307134, 0.2182216465543058426, 0.2239026993850088965,
- 0.229632325232116602, 0.2354109422634795556, 0.2412389935454402889,
- 0.2471169475123218551, 0.2530452985073261551, 0.2590245673962052742,
- 0.2650553022555897087, 0.271138079138385224, 0.2772735029191887857,
- 0.2834622082232336471, 0.2897048604429605656, 0.2960021568469337061,
- 0.3023548277864842593, 0.3087636380061818397, 0.3152293880650116065,
- 0.3217529158759855901, 0.3283350983728509642, 0.3349768533135899506,
- 0.3416791412315512977, 0.3484429675463274756, 0.355269384847918035,
- 0.3621594953693184626, 0.3691144536644731522, 0.376135469510563536,
- 0.3832238110559021416, 0.3903808082373155797, 0.3976078564938743676,
- 0.404906420807223999, 0.4122780401026620578, 0.4197243320495753771,
- 0.4272469983049970721, 0.4348478302499918513, 0.4425287152754694975,
- 0.4502916436820402768, 0.458138716267873114, 0.4660721526894572309,
- 0.4740943006930180559, 0.4822076463294863724, 0.4904148252838453348,
- 0.4987186354709807201, 0.5071220510755701794, 0.5156282382440030565,
- 0.5242405726729852944, 0.5329626593838373561, 0.5417983550254266145,
- 0.5507517931146057588, 0.5598274127040882009, 0.5690299910679523787,
- 0.5783646811197646898, 0.5878370544347081283, 0.5974531509445183408,
- 0.6072195366251219584, 0.6171433708188825973, 0.6272324852499290282,
- 0.6374954773350440806, 0.6479418211102242475, 0.6585820000500898219,
- 0.6694276673488921414, 0.6804918409973358395, 0.6917891434366769676,
- 0.7033360990161600101, 0.7151515074105005976, 0.7272569183441868201,
- 0.7396772436726493094, 0.7524415591746134169, 0.7655841738977066102,
- 0.7791460859296898134, 0.7931770117713072832, 0.8077382946829627652,
- 0.8229072113814113187, 0.8387836052959920519, 0.8555006078694531446,
- 0.873243048910072206, 0.8922816507840289901, 0.9130436479717434217,
- 0.9362826816850632339, 0.9635996931270905952, 1}};
-
-} // namespace random_internal
+namespace random_internal {
+
+const gaussian_distribution_base::Tables
+ gaussian_distribution_base::zg_ = {
+ {3.7130862467425505, 3.442619855899000214, 3.223084984581141565,
+ 3.083228858216868318, 2.978696252647779819, 2.894344007021528942,
+ 2.82312535054891045, 2.761169372387176857, 2.706113573121819549,
+ 2.656406411261359679, 2.610972248431847387, 2.56903362592493778,
+ 2.530009672388827457, 2.493454522095372106, 2.459018177411830486,
+ 2.426420645533749809, 2.395434278011062457, 2.365871370117638595,
+ 2.337575241339236776, 2.310413683698762988, 2.284274059677471769,
+ 2.25905957386919809, 2.234686395590979036, 2.21108140887870297,
+ 2.188180432076048731, 2.165926793748921497, 2.144270182360394905,
+ 2.123165708673976138, 2.102573135189237608, 2.082456237992015957,
+ 2.062782274508307978, 2.043521536655067194, 2.02464697337738464,
+ 2.006133869963471206, 1.987959574127619033, 1.970103260854325633,
+ 1.952545729553555764, 1.935269228296621957, 1.918257300864508963,
+ 1.901494653105150423, 1.884967035707758143, 1.868661140994487768,
+ 1.852564511728090002, 1.836665460258444904, 1.820952996596124418,
+ 1.805416764219227366, 1.790046982599857506, 1.77483439558606837,
+ 1.759770224899592339, 1.744846128113799244, 1.730054160563729182,
+ 1.71538674071366648, 1.700836618569915748, 1.686396846779167014,
+ 1.6720607540975998, 1.657821920954023254, 1.643674156862867441,
+ 1.629611479470633562, 1.615628095043159629, 1.601718380221376581,
+ 1.587876864890574558, 1.574098216022999264, 1.560377222366167382,
+ 1.546708779859908844, 1.533087877674041755, 1.519509584765938559,
+ 1.505969036863201937, 1.492461423781352714, 1.478981976989922842,
+ 1.465525957342709296, 1.452088642889222792, 1.438665316684561546,
+ 1.425251254514058319, 1.411841712447055919, 1.398431914131003539,
+ 1.385017037732650058, 1.371592202427340812, 1.358152454330141534,
+ 1.34469275175354519, 1.331207949665625279, 1.317692783209412299,
+ 1.304141850128615054, 1.290549591926194894, 1.27691027356015363,
+ 1.263217961454619287, 1.249466499573066436, 1.23564948326336066,
+ 1.221760230539994385, 1.207791750415947662, 1.193736707833126465,
+ 1.17958738466398616, 1.165335636164750222, 1.150972842148865416,
+ 1.136489852013158774, 1.121876922582540237, 1.107123647534034028,
+ 1.092218876907275371, 1.077150624892893482, 1.061905963694822042,
+ 1.046470900764042922, 1.030830236068192907, 1.014967395251327842,
+ 0.9988642334929808131, 0.9825008035154263464, 0.9658550794011470098,
+ 0.9489026255113034436, 0.9316161966151479401, 0.9139652510230292792,
+ 0.8959153525809346874, 0.8774274291129204872, 0.8584568431938099931,
+ 0.8389522142975741614, 0.8188539067003538507, 0.7980920606440534693,
+ 0.7765839878947563557, 0.7542306644540520688, 0.7309119106424850631,
+ 0.7064796113354325779, 0.6807479186691505202, 0.6534786387399710295,
+ 0.6243585973360461505, 0.5929629424714434327, 0.5586921784081798625,
+ 0.5206560387620546848, 0.4774378372966830431, 0.4265479863554152429,
+ 0.3628714310970211909, 0.2723208648139477384, 0},
+ {0.001014352564120377413, 0.002669629083880922793, 0.005548995220771345792,
+ 0.008624484412859888607, 0.01183947865788486861, 0.01516729801054656976,
+ 0.01859210273701129151, 0.02210330461592709475, 0.02569329193593428151,
+ 0.02935631744000685023, 0.03308788614622575758, 0.03688438878665621645,
+ 0.04074286807444417458, 0.04466086220049143157, 0.04863629585986780496,
+ 0.05266740190305100461, 0.05675266348104984759, 0.06089077034804041277,
+ 0.06508058521306804567, 0.06932111739357792179, 0.07361150188411341722,
+ 0.07795098251397346301, 0.08233889824223575293, 0.08677467189478028919,
+ 0.09125780082683036809, 0.095787849121731522, 0.1003644410286559929,
+ 0.1049872554094214289, 0.1096560210148404546, 0.1143705124488661323,
+ 0.1191305467076509556, 0.1239359802028679736, 0.1287867061959434012,
+ 0.1336826525834396151, 0.1386237799845948804, 0.1436100800906280339,
+ 0.1486415742423425057, 0.1537183122081819397, 0.1588403711394795748,
+ 0.1640078546834206341, 0.1692208922373653057, 0.1744796383307898324,
+ 0.1797842721232958407, 0.1851349970089926078, 0.1905320403191375633,
+ 0.1959756531162781534, 0.2014661100743140865, 0.2070037094399269362,
+ 0.2125887730717307134, 0.2182216465543058426, 0.2239026993850088965,
+ 0.229632325232116602, 0.2354109422634795556, 0.2412389935454402889,
+ 0.2471169475123218551, 0.2530452985073261551, 0.2590245673962052742,
+ 0.2650553022555897087, 0.271138079138385224, 0.2772735029191887857,
+ 0.2834622082232336471, 0.2897048604429605656, 0.2960021568469337061,
+ 0.3023548277864842593, 0.3087636380061818397, 0.3152293880650116065,
+ 0.3217529158759855901, 0.3283350983728509642, 0.3349768533135899506,
+ 0.3416791412315512977, 0.3484429675463274756, 0.355269384847918035,
+ 0.3621594953693184626, 0.3691144536644731522, 0.376135469510563536,
+ 0.3832238110559021416, 0.3903808082373155797, 0.3976078564938743676,
+ 0.404906420807223999, 0.4122780401026620578, 0.4197243320495753771,
+ 0.4272469983049970721, 0.4348478302499918513, 0.4425287152754694975,
+ 0.4502916436820402768, 0.458138716267873114, 0.4660721526894572309,
+ 0.4740943006930180559, 0.4822076463294863724, 0.4904148252838453348,
+ 0.4987186354709807201, 0.5071220510755701794, 0.5156282382440030565,
+ 0.5242405726729852944, 0.5329626593838373561, 0.5417983550254266145,
+ 0.5507517931146057588, 0.5598274127040882009, 0.5690299910679523787,
+ 0.5783646811197646898, 0.5878370544347081283, 0.5974531509445183408,
+ 0.6072195366251219584, 0.6171433708188825973, 0.6272324852499290282,
+ 0.6374954773350440806, 0.6479418211102242475, 0.6585820000500898219,
+ 0.6694276673488921414, 0.6804918409973358395, 0.6917891434366769676,
+ 0.7033360990161600101, 0.7151515074105005976, 0.7272569183441868201,
+ 0.7396772436726493094, 0.7524415591746134169, 0.7655841738977066102,
+ 0.7791460859296898134, 0.7931770117713072832, 0.8077382946829627652,
+ 0.8229072113814113187, 0.8387836052959920519, 0.8555006078694531446,
+ 0.873243048910072206, 0.8922816507840289901, 0.9130436479717434217,
+ 0.9362826816850632339, 0.9635996931270905952, 1}};
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-// clang-format on
-// END GENERATED CODE
+} // namespace absl
+
+// clang-format on
+// END GENERATED CODE
diff --git a/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.h b/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.h
index ed0d99bd9d..4b07a5c0af 100644
--- a/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/gaussian_distribution.h
@@ -1,275 +1,275 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_GAUSSIAN_DISTRIBUTION_H_
-#define ABSL_RANDOM_GAUSSIAN_DISTRIBUTION_H_
-
-// absl::gaussian_distribution implements the Ziggurat algorithm
-// for generating random gaussian numbers.
-//
-// Implementation based on "The Ziggurat Method for Generating Random Variables"
-// by George Marsaglia and Wai Wan Tsang: http://www.jstatsoft.org/v05/i08/
-//
-
-#include <cmath>
-#include <cstdint>
-#include <istream>
-#include <limits>
-#include <type_traits>
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_GAUSSIAN_DISTRIBUTION_H_
+#define ABSL_RANDOM_GAUSSIAN_DISTRIBUTION_H_
+
+// absl::gaussian_distribution implements the Ziggurat algorithm
+// for generating random gaussian numbers.
+//
+// Implementation based on "The Ziggurat Method for Generating Random Variables"
+// by George Marsaglia and Wai Wan Tsang: http://www.jstatsoft.org/v05/i08/
+//
+
+#include <cmath>
+#include <cstdint>
+#include <istream>
+#include <limits>
+#include <type_traits>
+
#include "absl/base/config.h"
-#include "absl/random/internal/fast_uniform_bits.h"
-#include "absl/random/internal/generate_real.h"
-#include "absl/random/internal/iostream_state_saver.h"
-
-namespace absl {
+#include "absl/random/internal/fast_uniform_bits.h"
+#include "absl/random/internal/generate_real.h"
+#include "absl/random/internal/iostream_state_saver.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// absl::gaussian_distribution_base implements the underlying ziggurat algorithm
-// using the ziggurat tables generated by the gaussian_distribution_gentables
-// binary.
-//
-// The specific algorithm has some of the improvements suggested by the
-// 2005 paper, "An Improved Ziggurat Method to Generate Normal Random Samples",
-// Jurgen A Doornik. (https://www.doornik.com/research/ziggurat.pdf)
+namespace random_internal {
+
+// absl::gaussian_distribution_base implements the underlying ziggurat algorithm
+// using the ziggurat tables generated by the gaussian_distribution_gentables
+// binary.
+//
+// The specific algorithm has some of the improvements suggested by the
+// 2005 paper, "An Improved Ziggurat Method to Generate Normal Random Samples",
+// Jurgen A Doornik. (https://www.doornik.com/research/ziggurat.pdf)
class ABSL_DLL gaussian_distribution_base {
- public:
- template <typename URBG>
- inline double zignor(URBG& g); // NOLINT(runtime/references)
-
- private:
- friend class TableGenerator;
-
- template <typename URBG>
- inline double zignor_fallback(URBG& g, // NOLINT(runtime/references)
- bool neg);
-
- // Constants used for the gaussian distribution.
- static constexpr double kR = 3.442619855899; // Start of the tail.
- static constexpr double kRInv = 0.29047645161474317; // ~= (1.0 / kR) .
- static constexpr double kV = 9.91256303526217e-3;
- static constexpr uint64_t kMask = 0x07f;
-
- // The ziggurat tables store the pdf(f) and inverse-pdf(x) for equal-area
- // points on one-half of the normal distribution, where the pdf function,
- // pdf = e ^ (-1/2 *x^2), assumes that the mean = 0 & stddev = 1.
- //
- // These tables are just over 2kb in size; larger tables might improve the
- // distributions, but also lead to more cache pollution.
- //
- // x = {3.71308, 3.44261, 3.22308, ..., 0}
- // f = {0.00101, 0.00266, 0.00554, ..., 1}
- struct Tables {
- double x[kMask + 2];
- double f[kMask + 2];
- };
- static const Tables zg_;
- random_internal::FastUniformBits<uint64_t> fast_u64_;
-};
-
-} // namespace random_internal
-
-// absl::gaussian_distribution:
-// Generates a number conforming to a Gaussian distribution.
-template <typename RealType = double>
-class gaussian_distribution : random_internal::gaussian_distribution_base {
- public:
- using result_type = RealType;
-
- class param_type {
- public:
- using distribution_type = gaussian_distribution;
-
- explicit param_type(result_type mean = 0, result_type stddev = 1)
- : mean_(mean), stddev_(stddev) {}
-
- // Returns the mean distribution parameter. The mean specifies the location
- // of the peak. The default value is 0.0.
- result_type mean() const { return mean_; }
-
- // Returns the deviation distribution parameter. The default value is 1.0.
- result_type stddev() const { return stddev_; }
-
- friend bool operator==(const param_type& a, const param_type& b) {
- return a.mean_ == b.mean_ && a.stddev_ == b.stddev_;
- }
-
- friend bool operator!=(const param_type& a, const param_type& b) {
- return !(a == b);
- }
-
- private:
- result_type mean_;
- result_type stddev_;
-
- static_assert(
- std::is_floating_point<RealType>::value,
- "Class-template absl::gaussian_distribution<> must be parameterized "
- "using a floating-point type.");
- };
-
- gaussian_distribution() : gaussian_distribution(0) {}
-
- explicit gaussian_distribution(result_type mean, result_type stddev = 1)
- : param_(mean, stddev) {}
-
- explicit gaussian_distribution(const param_type& p) : param_(p) {}
-
- void reset() {}
-
- // Generating functions
- template <typename URBG>
- result_type operator()(URBG& g) { // NOLINT(runtime/references)
- return (*this)(g, param_);
- }
-
- template <typename URBG>
- result_type operator()(URBG& g, // NOLINT(runtime/references)
- const param_type& p);
-
- param_type param() const { return param_; }
- void param(const param_type& p) { param_ = p; }
-
- result_type(min)() const {
- return -std::numeric_limits<result_type>::infinity();
- }
- result_type(max)() const {
- return std::numeric_limits<result_type>::infinity();
- }
-
- result_type mean() const { return param_.mean(); }
- result_type stddev() const { return param_.stddev(); }
-
- friend bool operator==(const gaussian_distribution& a,
- const gaussian_distribution& b) {
- return a.param_ == b.param_;
- }
- friend bool operator!=(const gaussian_distribution& a,
- const gaussian_distribution& b) {
- return a.param_ != b.param_;
- }
-
- private:
- param_type param_;
-};
-
-// --------------------------------------------------------------------------
-// Implementation details only below
-// --------------------------------------------------------------------------
-
-template <typename RealType>
-template <typename URBG>
-typename gaussian_distribution<RealType>::result_type
-gaussian_distribution<RealType>::operator()(
- URBG& g, // NOLINT(runtime/references)
- const param_type& p) {
- return p.mean() + p.stddev() * static_cast<result_type>(zignor(g));
-}
-
-template <typename CharT, typename Traits, typename RealType>
-std::basic_ostream<CharT, Traits>& operator<<(
- std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
- const gaussian_distribution<RealType>& x) {
- auto saver = random_internal::make_ostream_state_saver(os);
- os.precision(random_internal::stream_precision_helper<RealType>::kPrecision);
- os << x.mean() << os.fill() << x.stddev();
- return os;
-}
-
-template <typename CharT, typename Traits, typename RealType>
-std::basic_istream<CharT, Traits>& operator>>(
- std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
- gaussian_distribution<RealType>& x) { // NOLINT(runtime/references)
- using result_type = typename gaussian_distribution<RealType>::result_type;
- using param_type = typename gaussian_distribution<RealType>::param_type;
-
- auto saver = random_internal::make_istream_state_saver(is);
- auto mean = random_internal::read_floating_point<result_type>(is);
- if (is.fail()) return is;
- auto stddev = random_internal::read_floating_point<result_type>(is);
- if (!is.fail()) {
- x.param(param_type(mean, stddev));
- }
- return is;
-}
-
-namespace random_internal {
-
-template <typename URBG>
-inline double gaussian_distribution_base::zignor_fallback(URBG& g, bool neg) {
- using random_internal::GeneratePositiveTag;
- using random_internal::GenerateRealFromBits;
-
- // This fallback path happens approximately 0.05% of the time.
- double x, y;
- do {
- // kRInv = 1/r, U(0, 1)
- x = kRInv *
- std::log(GenerateRealFromBits<double, GeneratePositiveTag, false>(
- fast_u64_(g)));
- y = -std::log(
- GenerateRealFromBits<double, GeneratePositiveTag, false>(fast_u64_(g)));
- } while ((y + y) < (x * x));
- return neg ? (x - kR) : (kR - x);
-}
-
-template <typename URBG>
-inline double gaussian_distribution_base::zignor(
- URBG& g) { // NOLINT(runtime/references)
- using random_internal::GeneratePositiveTag;
- using random_internal::GenerateRealFromBits;
- using random_internal::GenerateSignedTag;
-
- while (true) {
- // We use a single uint64_t to generate both a double and a strip.
- // These bits are unused when the generated double is > 1/2^5.
- // This may introduce some bias from the duplicated low bits of small
- // values (those smaller than 1/2^5, which all end up on the left tail).
- uint64_t bits = fast_u64_(g);
- int i = static_cast<int>(bits & kMask); // pick a random strip
- double j = GenerateRealFromBits<double, GenerateSignedTag, false>(
- bits); // U(-1, 1)
- const double x = j * zg_.x[i];
-
- // Retangular box. Handles >97% of all cases.
- // For any given box, this handles between 75% and 99% of values.
- // Equivalent to U(01) < (x[i+1] / x[i]), and when i == 0, ~93.5%
- if (std::abs(x) < zg_.x[i + 1]) {
- return x;
- }
-
- // i == 0: Base box. Sample using a ratio of uniforms.
- if (i == 0) {
- // This path happens about 0.05% of the time.
- return zignor_fallback(g, j < 0);
- }
-
- // i > 0: Wedge samples using precomputed values.
- double v = GenerateRealFromBits<double, GeneratePositiveTag, false>(
- fast_u64_(g)); // U(0, 1)
- if ((zg_.f[i + 1] + v * (zg_.f[i] - zg_.f[i + 1])) <
- std::exp(-0.5 * x * x)) {
- return x;
- }
-
- // The wedge was missed; reject the value and try again.
- }
-}
-
-} // namespace random_internal
+ public:
+ template <typename URBG>
+ inline double zignor(URBG& g); // NOLINT(runtime/references)
+
+ private:
+ friend class TableGenerator;
+
+ template <typename URBG>
+ inline double zignor_fallback(URBG& g, // NOLINT(runtime/references)
+ bool neg);
+
+ // Constants used for the gaussian distribution.
+ static constexpr double kR = 3.442619855899; // Start of the tail.
+ static constexpr double kRInv = 0.29047645161474317; // ~= (1.0 / kR) .
+ static constexpr double kV = 9.91256303526217e-3;
+ static constexpr uint64_t kMask = 0x07f;
+
+ // The ziggurat tables store the pdf(f) and inverse-pdf(x) for equal-area
+ // points on one-half of the normal distribution, where the pdf function,
+ // pdf = e ^ (-1/2 *x^2), assumes that the mean = 0 & stddev = 1.
+ //
+ // These tables are just over 2kb in size; larger tables might improve the
+ // distributions, but also lead to more cache pollution.
+ //
+ // x = {3.71308, 3.44261, 3.22308, ..., 0}
+ // f = {0.00101, 0.00266, 0.00554, ..., 1}
+ struct Tables {
+ double x[kMask + 2];
+ double f[kMask + 2];
+ };
+ static const Tables zg_;
+ random_internal::FastUniformBits<uint64_t> fast_u64_;
+};
+
+} // namespace random_internal
+
+// absl::gaussian_distribution:
+// Generates a number conforming to a Gaussian distribution.
+template <typename RealType = double>
+class gaussian_distribution : random_internal::gaussian_distribution_base {
+ public:
+ using result_type = RealType;
+
+ class param_type {
+ public:
+ using distribution_type = gaussian_distribution;
+
+ explicit param_type(result_type mean = 0, result_type stddev = 1)
+ : mean_(mean), stddev_(stddev) {}
+
+ // Returns the mean distribution parameter. The mean specifies the location
+ // of the peak. The default value is 0.0.
+ result_type mean() const { return mean_; }
+
+ // Returns the deviation distribution parameter. The default value is 1.0.
+ result_type stddev() const { return stddev_; }
+
+ friend bool operator==(const param_type& a, const param_type& b) {
+ return a.mean_ == b.mean_ && a.stddev_ == b.stddev_;
+ }
+
+ friend bool operator!=(const param_type& a, const param_type& b) {
+ return !(a == b);
+ }
+
+ private:
+ result_type mean_;
+ result_type stddev_;
+
+ static_assert(
+ std::is_floating_point<RealType>::value,
+ "Class-template absl::gaussian_distribution<> must be parameterized "
+ "using a floating-point type.");
+ };
+
+ gaussian_distribution() : gaussian_distribution(0) {}
+
+ explicit gaussian_distribution(result_type mean, result_type stddev = 1)
+ : param_(mean, stddev) {}
+
+ explicit gaussian_distribution(const param_type& p) : param_(p) {}
+
+ void reset() {}
+
+ // Generating functions
+ template <typename URBG>
+ result_type operator()(URBG& g) { // NOLINT(runtime/references)
+ return (*this)(g, param_);
+ }
+
+ template <typename URBG>
+ result_type operator()(URBG& g, // NOLINT(runtime/references)
+ const param_type& p);
+
+ param_type param() const { return param_; }
+ void param(const param_type& p) { param_ = p; }
+
+ result_type(min)() const {
+ return -std::numeric_limits<result_type>::infinity();
+ }
+ result_type(max)() const {
+ return std::numeric_limits<result_type>::infinity();
+ }
+
+ result_type mean() const { return param_.mean(); }
+ result_type stddev() const { return param_.stddev(); }
+
+ friend bool operator==(const gaussian_distribution& a,
+ const gaussian_distribution& b) {
+ return a.param_ == b.param_;
+ }
+ friend bool operator!=(const gaussian_distribution& a,
+ const gaussian_distribution& b) {
+ return a.param_ != b.param_;
+ }
+
+ private:
+ param_type param_;
+};
+
+// --------------------------------------------------------------------------
+// Implementation details only below
+// --------------------------------------------------------------------------
+
+template <typename RealType>
+template <typename URBG>
+typename gaussian_distribution<RealType>::result_type
+gaussian_distribution<RealType>::operator()(
+ URBG& g, // NOLINT(runtime/references)
+ const param_type& p) {
+ return p.mean() + p.stddev() * static_cast<result_type>(zignor(g));
+}
+
+template <typename CharT, typename Traits, typename RealType>
+std::basic_ostream<CharT, Traits>& operator<<(
+ std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
+ const gaussian_distribution<RealType>& x) {
+ auto saver = random_internal::make_ostream_state_saver(os);
+ os.precision(random_internal::stream_precision_helper<RealType>::kPrecision);
+ os << x.mean() << os.fill() << x.stddev();
+ return os;
+}
+
+template <typename CharT, typename Traits, typename RealType>
+std::basic_istream<CharT, Traits>& operator>>(
+ std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
+ gaussian_distribution<RealType>& x) { // NOLINT(runtime/references)
+ using result_type = typename gaussian_distribution<RealType>::result_type;
+ using param_type = typename gaussian_distribution<RealType>::param_type;
+
+ auto saver = random_internal::make_istream_state_saver(is);
+ auto mean = random_internal::read_floating_point<result_type>(is);
+ if (is.fail()) return is;
+ auto stddev = random_internal::read_floating_point<result_type>(is);
+ if (!is.fail()) {
+ x.param(param_type(mean, stddev));
+ }
+ return is;
+}
+
+namespace random_internal {
+
+template <typename URBG>
+inline double gaussian_distribution_base::zignor_fallback(URBG& g, bool neg) {
+ using random_internal::GeneratePositiveTag;
+ using random_internal::GenerateRealFromBits;
+
+ // This fallback path happens approximately 0.05% of the time.
+ double x, y;
+ do {
+ // kRInv = 1/r, U(0, 1)
+ x = kRInv *
+ std::log(GenerateRealFromBits<double, GeneratePositiveTag, false>(
+ fast_u64_(g)));
+ y = -std::log(
+ GenerateRealFromBits<double, GeneratePositiveTag, false>(fast_u64_(g)));
+ } while ((y + y) < (x * x));
+ return neg ? (x - kR) : (kR - x);
+}
+
+template <typename URBG>
+inline double gaussian_distribution_base::zignor(
+ URBG& g) { // NOLINT(runtime/references)
+ using random_internal::GeneratePositiveTag;
+ using random_internal::GenerateRealFromBits;
+ using random_internal::GenerateSignedTag;
+
+ while (true) {
+ // We use a single uint64_t to generate both a double and a strip.
+ // These bits are unused when the generated double is > 1/2^5.
+ // This may introduce some bias from the duplicated low bits of small
+ // values (those smaller than 1/2^5, which all end up on the left tail).
+ uint64_t bits = fast_u64_(g);
+ int i = static_cast<int>(bits & kMask); // pick a random strip
+ double j = GenerateRealFromBits<double, GenerateSignedTag, false>(
+ bits); // U(-1, 1)
+ const double x = j * zg_.x[i];
+
+ // Retangular box. Handles >97% of all cases.
+ // For any given box, this handles between 75% and 99% of values.
+ // Equivalent to U(01) < (x[i+1] / x[i]), and when i == 0, ~93.5%
+ if (std::abs(x) < zg_.x[i + 1]) {
+ return x;
+ }
+
+ // i == 0: Base box. Sample using a ratio of uniforms.
+ if (i == 0) {
+ // This path happens about 0.05% of the time.
+ return zignor_fallback(g, j < 0);
+ }
+
+ // i > 0: Wedge samples using precomputed values.
+ double v = GenerateRealFromBits<double, GeneratePositiveTag, false>(
+ fast_u64_(g)); // U(0, 1)
+ if ((zg_.f[i + 1] + v * (zg_.f[i] - zg_.f[i + 1])) <
+ std::exp(-0.5 * x * x)) {
+ return x;
+ }
+
+ // The wedge was missed; reject the value and try again.
+ }
+}
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_GAUSSIAN_DISTRIBUTION_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_GAUSSIAN_DISTRIBUTION_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/absl_random_internal_distribution_test_util/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/absl_random_internal_distribution_test_util/ya.make
index c19fb5333a..340d08c827 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/absl_random_internal_distribution_test_util/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/absl_random_internal_distribution_test_util/ya.make
@@ -1,42 +1,42 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
WITHOUT_LICENSE_TEXTS()
-OWNER(g:cpp-contrib)
-
-LICENSE(Apache-2.0)
-
-PEERDIR(
- contrib/restricted/abseil-cpp/absl/base
- contrib/restricted/abseil-cpp/absl/base/internal/raw_logging
- contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait
- contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate
- contrib/restricted/abseil-cpp/absl/base/log_severity
- contrib/restricted/abseil-cpp/absl/numeric
- contrib/restricted/abseil-cpp/absl/strings
+OWNER(g:cpp-contrib)
+
+LICENSE(Apache-2.0)
+
+PEERDIR(
+ contrib/restricted/abseil-cpp/absl/base
+ contrib/restricted/abseil-cpp/absl/base/internal/raw_logging
+ contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait
+ contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate
+ contrib/restricted/abseil-cpp/absl/base/log_severity
+ contrib/restricted/abseil-cpp/absl/numeric
+ contrib/restricted/abseil-cpp/absl/strings
contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal
- contrib/restricted/abseil-cpp/absl/strings/internal/str_format
-)
-
-ADDINCL(
- GLOBAL contrib/restricted/abseil-cpp
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
+ contrib/restricted/abseil-cpp/absl/strings/internal/str_format
+)
+
+ADDINCL(
+ GLOBAL contrib/restricted/abseil-cpp
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
CFLAGS(
-DNOMINMAX
)
-SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal)
-
-SRCS(
- chi_square.cc
- distribution_test_util.cc
-)
-
-END()
+SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal)
+
+SRCS(
+ chi_square.cc
+ distribution_test_util.cc
+)
+
+END()
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.cc b/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.cc
index 6796cb8db4..640d48cea6 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.cc
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.cc
@@ -1,232 +1,232 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/random/internal/chi_square.h"
-
-#include <cmath>
-
-#include "absl/random/internal/distribution_test_util.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/random/internal/chi_square.h"
+
+#include <cmath>
+
+#include "absl/random/internal/distribution_test_util.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-namespace {
-
-#if defined(__EMSCRIPTEN__)
-// Workaround __EMSCRIPTEN__ error: llvm_fma_f64 not found.
-inline double fma(double x, double y, double z) {
- return (x * y) + z;
-}
-#endif
-
-// Use Horner's method to evaluate a polynomial.
-template <typename T, unsigned N>
-inline T EvaluatePolynomial(T x, const T (&poly)[N]) {
-#if !defined(__EMSCRIPTEN__)
- using std::fma;
-#endif
- T p = poly[N - 1];
- for (unsigned i = 2; i <= N; i++) {
- p = fma(p, x, poly[N - i]);
- }
- return p;
-}
-
-static constexpr int kLargeDOF = 150;
-
-// Returns the probability of a normal z-value.
-//
-// Adapted from the POZ function in:
-// Ibbetson D, Algorithm 209
-// Collected Algorithms of the CACM 1963 p. 616
-//
-double POZ(double z) {
- static constexpr double kP1[] = {
- 0.797884560593, -0.531923007300, 0.319152932694,
- -0.151968751364, 0.059054035642, -0.019198292004,
- 0.005198775019, -0.001075204047, 0.000124818987,
- };
- static constexpr double kP2[] = {
- 0.999936657524, 0.000535310849, -0.002141268741, 0.005353579108,
- -0.009279453341, 0.011630447319, -0.010557625006, 0.006549791214,
- -0.002034254874, -0.000794620820, 0.001390604284, -0.000676904986,
- -0.000019538132, 0.000152529290, -0.000045255659,
- };
-
- const double kZMax = 6.0; // Maximum meaningful z-value.
- if (z == 0.0) {
- return 0.5;
- }
- double x;
- double y = 0.5 * std::fabs(z);
- if (y >= (kZMax * 0.5)) {
- x = 1.0;
- } else if (y < 1.0) {
- double w = y * y;
- x = EvaluatePolynomial(w, kP1) * y * 2.0;
- } else {
- y -= 2.0;
- x = EvaluatePolynomial(y, kP2);
- }
- return z > 0.0 ? ((x + 1.0) * 0.5) : ((1.0 - x) * 0.5);
-}
-
-// Approximates the survival function of the normal distribution.
-//
-// Algorithm 26.2.18, from:
-// [Abramowitz and Stegun, Handbook of Mathematical Functions,p.932]
-// http://people.math.sfu.ca/~cbm/aands/abramowitz_and_stegun.pdf
-//
-double normal_survival(double z) {
- // Maybe replace with the alternate formulation.
- // 0.5 * erfc((x - mean)/(sqrt(2) * sigma))
- static constexpr double kR[] = {
- 1.0, 0.196854, 0.115194, 0.000344, 0.019527,
- };
- double r = EvaluatePolynomial(z, kR);
- r *= r;
- return 0.5 / (r * r);
-}
-
-} // namespace
-
-// Calculates the critical chi-square value given degrees-of-freedom and a
-// p-value, usually using bisection. Also known by the name CRITCHI.
-double ChiSquareValue(int dof, double p) {
- static constexpr double kChiEpsilon =
- 0.000001; // Accuracy of the approximation.
- static constexpr double kChiMax =
- 99999.0; // Maximum chi-squared value.
-
- const double p_value = 1.0 - p;
- if (dof < 1 || p_value > 1.0) {
- return 0.0;
- }
-
- if (dof > kLargeDOF) {
- // For large degrees of freedom, use the normal approximation by
- // Wilson, E. B. and Hilferty, M. M. (1931)
- // chi^2 - mean
- // Z = --------------
- // stddev
- const double z = InverseNormalSurvival(p_value);
- const double mean = 1 - 2.0 / (9 * dof);
- const double variance = 2.0 / (9 * dof);
- // Cannot use this method if the variance is 0.
- if (variance != 0) {
- return std::pow(z * std::sqrt(variance) + mean, 3.0) * dof;
- }
- }
-
- if (p_value <= 0.0) return kChiMax;
-
- // Otherwise search for the p value by bisection
- double min_chisq = 0.0;
- double max_chisq = kChiMax;
- double current = dof / std::sqrt(p_value);
- while ((max_chisq - min_chisq) > kChiEpsilon) {
- if (ChiSquarePValue(current, dof) < p_value) {
- max_chisq = current;
- } else {
- min_chisq = current;
- }
- current = (max_chisq + min_chisq) * 0.5;
- }
- return current;
-}
-
-// Calculates the p-value (probability) of a given chi-square value
-// and degrees of freedom.
-//
-// Adapted from the POCHISQ function from:
-// Hill, I. D. and Pike, M. C. Algorithm 299
-// Collected Algorithms of the CACM 1963 p. 243
-//
-double ChiSquarePValue(double chi_square, int dof) {
- static constexpr double kLogSqrtPi =
- 0.5723649429247000870717135; // Log[Sqrt[Pi]]
- static constexpr double kInverseSqrtPi =
- 0.5641895835477562869480795; // 1/(Sqrt[Pi])
-
- // For large degrees of freedom, use the normal approximation by
- // Wilson, E. B. and Hilferty, M. M. (1931)
- // Via Wikipedia:
- // By the Central Limit Theorem, because the chi-square distribution is the
- // sum of k independent random variables with finite mean and variance, it
- // converges to a normal distribution for large k.
- if (dof > kLargeDOF) {
- // Re-scale everything.
- const double chi_square_scaled = std::pow(chi_square / dof, 1.0 / 3);
- const double mean = 1 - 2.0 / (9 * dof);
- const double variance = 2.0 / (9 * dof);
- // If variance is 0, this method cannot be used.
- if (variance != 0) {
- const double z = (chi_square_scaled - mean) / std::sqrt(variance);
- if (z > 0) {
- return normal_survival(z);
- } else if (z < 0) {
- return 1.0 - normal_survival(-z);
- } else {
- return 0.5;
- }
- }
- }
-
- // The chi square function is >= 0 for any degrees of freedom.
- // In other words, probability that the chi square function >= 0 is 1.
- if (chi_square <= 0.0) return 1.0;
-
- // If the degrees of freedom is zero, the chi square function is always 0 by
- // definition. In other words, the probability that the chi square function
- // is > 0 is zero (chi square values <= 0 have been filtered above).
- if (dof < 1) return 0;
-
- auto capped_exp = [](double x) { return x < -20 ? 0.0 : std::exp(x); };
- static constexpr double kBigX = 20;
-
- double a = 0.5 * chi_square;
- const bool even = !(dof & 1); // True if dof is an even number.
- const double y = capped_exp(-a);
- double s = even ? y : (2.0 * POZ(-std::sqrt(chi_square)));
-
- if (dof <= 2) {
- return s;
- }
-
- chi_square = 0.5 * (dof - 1.0);
- double z = (even ? 1.0 : 0.5);
- if (a > kBigX) {
- double e = (even ? 0.0 : kLogSqrtPi);
- double c = std::log(a);
- while (z <= chi_square) {
- e = std::log(z) + e;
- s += capped_exp(c * z - a - e);
- z += 1.0;
- }
- return s;
- }
-
- double e = (even ? 1.0 : (kInverseSqrtPi / std::sqrt(a)));
- double c = 0.0;
- while (z <= chi_square) {
- e = e * (a / z);
- c = c + e;
- z += 1.0;
- }
- return c * y + s;
-}
-
-} // namespace random_internal
+namespace random_internal {
+namespace {
+
+#if defined(__EMSCRIPTEN__)
+// Workaround __EMSCRIPTEN__ error: llvm_fma_f64 not found.
+inline double fma(double x, double y, double z) {
+ return (x * y) + z;
+}
+#endif
+
+// Use Horner's method to evaluate a polynomial.
+template <typename T, unsigned N>
+inline T EvaluatePolynomial(T x, const T (&poly)[N]) {
+#if !defined(__EMSCRIPTEN__)
+ using std::fma;
+#endif
+ T p = poly[N - 1];
+ for (unsigned i = 2; i <= N; i++) {
+ p = fma(p, x, poly[N - i]);
+ }
+ return p;
+}
+
+static constexpr int kLargeDOF = 150;
+
+// Returns the probability of a normal z-value.
+//
+// Adapted from the POZ function in:
+// Ibbetson D, Algorithm 209
+// Collected Algorithms of the CACM 1963 p. 616
+//
+double POZ(double z) {
+ static constexpr double kP1[] = {
+ 0.797884560593, -0.531923007300, 0.319152932694,
+ -0.151968751364, 0.059054035642, -0.019198292004,
+ 0.005198775019, -0.001075204047, 0.000124818987,
+ };
+ static constexpr double kP2[] = {
+ 0.999936657524, 0.000535310849, -0.002141268741, 0.005353579108,
+ -0.009279453341, 0.011630447319, -0.010557625006, 0.006549791214,
+ -0.002034254874, -0.000794620820, 0.001390604284, -0.000676904986,
+ -0.000019538132, 0.000152529290, -0.000045255659,
+ };
+
+ const double kZMax = 6.0; // Maximum meaningful z-value.
+ if (z == 0.0) {
+ return 0.5;
+ }
+ double x;
+ double y = 0.5 * std::fabs(z);
+ if (y >= (kZMax * 0.5)) {
+ x = 1.0;
+ } else if (y < 1.0) {
+ double w = y * y;
+ x = EvaluatePolynomial(w, kP1) * y * 2.0;
+ } else {
+ y -= 2.0;
+ x = EvaluatePolynomial(y, kP2);
+ }
+ return z > 0.0 ? ((x + 1.0) * 0.5) : ((1.0 - x) * 0.5);
+}
+
+// Approximates the survival function of the normal distribution.
+//
+// Algorithm 26.2.18, from:
+// [Abramowitz and Stegun, Handbook of Mathematical Functions,p.932]
+// http://people.math.sfu.ca/~cbm/aands/abramowitz_and_stegun.pdf
+//
+double normal_survival(double z) {
+ // Maybe replace with the alternate formulation.
+ // 0.5 * erfc((x - mean)/(sqrt(2) * sigma))
+ static constexpr double kR[] = {
+ 1.0, 0.196854, 0.115194, 0.000344, 0.019527,
+ };
+ double r = EvaluatePolynomial(z, kR);
+ r *= r;
+ return 0.5 / (r * r);
+}
+
+} // namespace
+
+// Calculates the critical chi-square value given degrees-of-freedom and a
+// p-value, usually using bisection. Also known by the name CRITCHI.
+double ChiSquareValue(int dof, double p) {
+ static constexpr double kChiEpsilon =
+ 0.000001; // Accuracy of the approximation.
+ static constexpr double kChiMax =
+ 99999.0; // Maximum chi-squared value.
+
+ const double p_value = 1.0 - p;
+ if (dof < 1 || p_value > 1.0) {
+ return 0.0;
+ }
+
+ if (dof > kLargeDOF) {
+ // For large degrees of freedom, use the normal approximation by
+ // Wilson, E. B. and Hilferty, M. M. (1931)
+ // chi^2 - mean
+ // Z = --------------
+ // stddev
+ const double z = InverseNormalSurvival(p_value);
+ const double mean = 1 - 2.0 / (9 * dof);
+ const double variance = 2.0 / (9 * dof);
+ // Cannot use this method if the variance is 0.
+ if (variance != 0) {
+ return std::pow(z * std::sqrt(variance) + mean, 3.0) * dof;
+ }
+ }
+
+ if (p_value <= 0.0) return kChiMax;
+
+ // Otherwise search for the p value by bisection
+ double min_chisq = 0.0;
+ double max_chisq = kChiMax;
+ double current = dof / std::sqrt(p_value);
+ while ((max_chisq - min_chisq) > kChiEpsilon) {
+ if (ChiSquarePValue(current, dof) < p_value) {
+ max_chisq = current;
+ } else {
+ min_chisq = current;
+ }
+ current = (max_chisq + min_chisq) * 0.5;
+ }
+ return current;
+}
+
+// Calculates the p-value (probability) of a given chi-square value
+// and degrees of freedom.
+//
+// Adapted from the POCHISQ function from:
+// Hill, I. D. and Pike, M. C. Algorithm 299
+// Collected Algorithms of the CACM 1963 p. 243
+//
+double ChiSquarePValue(double chi_square, int dof) {
+ static constexpr double kLogSqrtPi =
+ 0.5723649429247000870717135; // Log[Sqrt[Pi]]
+ static constexpr double kInverseSqrtPi =
+ 0.5641895835477562869480795; // 1/(Sqrt[Pi])
+
+ // For large degrees of freedom, use the normal approximation by
+ // Wilson, E. B. and Hilferty, M. M. (1931)
+ // Via Wikipedia:
+ // By the Central Limit Theorem, because the chi-square distribution is the
+ // sum of k independent random variables with finite mean and variance, it
+ // converges to a normal distribution for large k.
+ if (dof > kLargeDOF) {
+ // Re-scale everything.
+ const double chi_square_scaled = std::pow(chi_square / dof, 1.0 / 3);
+ const double mean = 1 - 2.0 / (9 * dof);
+ const double variance = 2.0 / (9 * dof);
+ // If variance is 0, this method cannot be used.
+ if (variance != 0) {
+ const double z = (chi_square_scaled - mean) / std::sqrt(variance);
+ if (z > 0) {
+ return normal_survival(z);
+ } else if (z < 0) {
+ return 1.0 - normal_survival(-z);
+ } else {
+ return 0.5;
+ }
+ }
+ }
+
+ // The chi square function is >= 0 for any degrees of freedom.
+ // In other words, probability that the chi square function >= 0 is 1.
+ if (chi_square <= 0.0) return 1.0;
+
+ // If the degrees of freedom is zero, the chi square function is always 0 by
+ // definition. In other words, the probability that the chi square function
+ // is > 0 is zero (chi square values <= 0 have been filtered above).
+ if (dof < 1) return 0;
+
+ auto capped_exp = [](double x) { return x < -20 ? 0.0 : std::exp(x); };
+ static constexpr double kBigX = 20;
+
+ double a = 0.5 * chi_square;
+ const bool even = !(dof & 1); // True if dof is an even number.
+ const double y = capped_exp(-a);
+ double s = even ? y : (2.0 * POZ(-std::sqrt(chi_square)));
+
+ if (dof <= 2) {
+ return s;
+ }
+
+ chi_square = 0.5 * (dof - 1.0);
+ double z = (even ? 1.0 : 0.5);
+ if (a > kBigX) {
+ double e = (even ? 0.0 : kLogSqrtPi);
+ double c = std::log(a);
+ while (z <= chi_square) {
+ e = std::log(z) + e;
+ s += capped_exp(c * z - a - e);
+ z += 1.0;
+ }
+ return s;
+ }
+
+ double e = (even ? 1.0 : (kInverseSqrtPi / std::sqrt(a)));
+ double c = 0.0;
+ while (z <= chi_square) {
+ e = e * (a / z);
+ c = c + e;
+ z += 1.0;
+ }
+ return c * y + s;
+}
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
+} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.h b/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.h
index aedeec4f11..07f4fbe522 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/chi_square.h
@@ -1,89 +1,89 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_CHI_SQUARE_H_
-#define ABSL_RANDOM_INTERNAL_CHI_SQUARE_H_
-
-// The chi-square statistic.
-//
-// Useful for evaluating if `D` independent random variables are behaving as
-// expected, or if two distributions are similar. (`D` is the degrees of
-// freedom).
-//
-// Each bucket should have an expected count of 10 or more for the chi square to
-// be meaningful.
-
-#include <cassert>
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_CHI_SQUARE_H_
+#define ABSL_RANDOM_INTERNAL_CHI_SQUARE_H_
+
+// The chi-square statistic.
+//
+// Useful for evaluating if `D` independent random variables are behaving as
+// expected, or if two distributions are similar. (`D` is the degrees of
+// freedom).
+//
+// Each bucket should have an expected count of 10 or more for the chi square to
+// be meaningful.
+
+#include <cassert>
+
#include "absl/base/config.h"
-namespace absl {
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-constexpr const char kChiSquared[] = "chi-squared";
-
-// Returns the measured chi square value, using a single expected value. This
-// assumes that the values in [begin, end) are uniformly distributed.
-template <typename Iterator>
-double ChiSquareWithExpected(Iterator begin, Iterator end, double expected) {
- // Compute the sum and the number of buckets.
- assert(expected >= 10); // require at least 10 samples per bucket.
- double chi_square = 0;
- for (auto it = begin; it != end; it++) {
- double d = static_cast<double>(*it) - expected;
- chi_square += d * d;
- }
- chi_square = chi_square / expected;
- return chi_square;
-}
-
-// Returns the measured chi square value, taking the actual value of each bucket
-// from the first set of iterators, and the expected value of each bucket from
-// the second set of iterators.
-template <typename Iterator, typename Expected>
-double ChiSquare(Iterator it, Iterator end, Expected eit, Expected eend) {
- double chi_square = 0;
- for (; it != end && eit != eend; ++it, ++eit) {
- if (*it > 0) {
- assert(*eit > 0);
- }
- double e = static_cast<double>(*eit);
- double d = static_cast<double>(*it - *eit);
- if (d != 0) {
- assert(e > 0);
- chi_square += (d * d) / e;
- }
- }
- assert(it == end && eit == eend);
- return chi_square;
-}
-
-// ======================================================================
-// The following methods can be used for an arbitrary significance level.
-//
-
-// Calculates critical chi-square values to produce the given p-value using a
-// bisection search for a value within epsilon, relying on the monotonicity of
-// ChiSquarePValue().
-double ChiSquareValue(int dof, double p);
-
-// Calculates the p-value (probability) of a given chi-square value.
-double ChiSquarePValue(double chi_square, int dof);
-
-} // namespace random_internal
+namespace random_internal {
+
+constexpr const char kChiSquared[] = "chi-squared";
+
+// Returns the measured chi square value, using a single expected value. This
+// assumes that the values in [begin, end) are uniformly distributed.
+template <typename Iterator>
+double ChiSquareWithExpected(Iterator begin, Iterator end, double expected) {
+ // Compute the sum and the number of buckets.
+ assert(expected >= 10); // require at least 10 samples per bucket.
+ double chi_square = 0;
+ for (auto it = begin; it != end; it++) {
+ double d = static_cast<double>(*it) - expected;
+ chi_square += d * d;
+ }
+ chi_square = chi_square / expected;
+ return chi_square;
+}
+
+// Returns the measured chi square value, taking the actual value of each bucket
+// from the first set of iterators, and the expected value of each bucket from
+// the second set of iterators.
+template <typename Iterator, typename Expected>
+double ChiSquare(Iterator it, Iterator end, Expected eit, Expected eend) {
+ double chi_square = 0;
+ for (; it != end && eit != eend; ++it, ++eit) {
+ if (*it > 0) {
+ assert(*eit > 0);
+ }
+ double e = static_cast<double>(*eit);
+ double d = static_cast<double>(*it - *eit);
+ if (d != 0) {
+ assert(e > 0);
+ chi_square += (d * d) / e;
+ }
+ }
+ assert(it == end && eit == eend);
+ return chi_square;
+}
+
+// ======================================================================
+// The following methods can be used for an arbitrary significance level.
+//
+
+// Calculates critical chi-square values to produce the given p-value using a
+// bisection search for a value within epsilon, relying on the monotonicity of
+// ChiSquarePValue().
+double ChiSquareValue(int dof, double p);
+
+// Calculates the p-value (probability) of a given chi-square value.
+double ChiSquarePValue(double chi_square, int dof);
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_CHI_SQUARE_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_CHI_SQUARE_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/distribution_caller.h b/contrib/restricted/abseil-cpp/absl/random/internal/distribution_caller.h
index 3e2dfed99d..fc81b787eb 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/distribution_caller.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/distribution_caller.h
@@ -1,40 +1,40 @@
-//
-// Copyright 2018 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-#ifndef ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_
-#define ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_
-
-#include <utility>
-
+//
+// Copyright 2018 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_
+#define ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_
+
+#include <utility>
+
#include "absl/base/config.h"
#include "absl/base/internal/fast_type_id.h"
#include "absl/utility/utility.h"
-namespace absl {
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// DistributionCaller provides an opportunity to overload the general
-// mechanism for calling a distribution, allowing for mock-RNG classes
-// to intercept such calls.
-template <typename URBG>
-struct DistributionCaller {
+namespace random_internal {
+
+// DistributionCaller provides an opportunity to overload the general
+// mechanism for calling a distribution, allowing for mock-RNG classes
+// to intercept such calls.
+template <typename URBG>
+struct DistributionCaller {
// SFINAE to detect whether the URBG type includes a member matching
// bool InvokeMock(base_internal::FastTypeIdType, void*, void*).
- //
+ //
// These live inside BitGenRef so that they have friend access
// to MockingBitGen. (see similar methods in DistributionCaller).
template <template <class...> class Trait, class AlwaysVoid, class... Args>
@@ -54,9 +54,9 @@ struct DistributionCaller {
template <typename DistrT, typename... Args>
static typename DistrT::result_type Impl(std::false_type, URBG* urbg,
Args&&... args) {
- DistrT dist(std::forward<Args>(args)...);
- return dist(*urbg);
- }
+ DistrT dist(std::forward<Args>(args)...);
+ return dist(*urbg);
+ }
// Mock implementation of distribution caller.
// The underlying KeyT must match the KeyT constructed by MockOverloadSet.
@@ -83,10 +83,10 @@ struct DistributionCaller {
return Impl<DistrT, Args...>(HasInvokeMock{}, urbg,
std::forward<Args>(args)...);
}
-};
-
-} // namespace random_internal
+};
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_DISTRIBUTION_CALLER_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.cc b/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.cc
index 6796322a1b..e9005658c0 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.cc
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.cc
@@ -1,418 +1,418 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/random/internal/distribution_test_util.h"
-
-#include <cassert>
-#include <cmath>
-#include <string>
-#include <vector>
-
-#include "absl/base/internal/raw_logging.h"
-#include "absl/base/macros.h"
-#include "absl/strings/str_cat.h"
-#include "absl/strings/str_format.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/random/internal/distribution_test_util.h"
+
+#include <cassert>
+#include <cmath>
+#include <string>
+#include <vector>
+
+#include "absl/base/internal/raw_logging.h"
+#include "absl/base/macros.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/str_format.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-namespace {
-
-#if defined(__EMSCRIPTEN__)
-// Workaround __EMSCRIPTEN__ error: llvm_fma_f64 not found.
-inline double fma(double x, double y, double z) { return (x * y) + z; }
-#endif
-
-} // namespace
-
-DistributionMoments ComputeDistributionMoments(
- absl::Span<const double> data_points) {
- DistributionMoments result;
-
- // Compute m1
- for (double x : data_points) {
- result.n++;
- result.mean += x;
- }
- result.mean /= static_cast<double>(result.n);
-
- // Compute m2, m3, m4
- for (double x : data_points) {
- double v = x - result.mean;
- result.variance += v * v;
- result.skewness += v * v * v;
- result.kurtosis += v * v * v * v;
- }
- result.variance /= static_cast<double>(result.n - 1);
-
- result.skewness /= static_cast<double>(result.n);
- result.skewness /= std::pow(result.variance, 1.5);
-
- result.kurtosis /= static_cast<double>(result.n);
- result.kurtosis /= std::pow(result.variance, 2.0);
- return result;
-
- // When validating the min/max count, the following confidence intervals may
- // be of use:
- // 3.291 * stddev = 99.9% CI
- // 2.576 * stddev = 99% CI
- // 1.96 * stddev = 95% CI
- // 1.65 * stddev = 90% CI
-}
-
-std::ostream& operator<<(std::ostream& os, const DistributionMoments& moments) {
- return os << absl::StrFormat("mean=%f, stddev=%f, skewness=%f, kurtosis=%f",
- moments.mean, std::sqrt(moments.variance),
- moments.skewness, moments.kurtosis);
-}
-
-double InverseNormalSurvival(double x) {
- // inv_sf(u) = -sqrt(2) * erfinv(2u-1)
- static constexpr double kSqrt2 = 1.4142135623730950488;
- return -kSqrt2 * absl::random_internal::erfinv(2 * x - 1.0);
-}
-
-bool Near(absl::string_view msg, double actual, double expected, double bound) {
- assert(bound > 0.0);
- double delta = fabs(expected - actual);
- if (delta < bound) {
- return true;
- }
-
- std::string formatted = absl::StrCat(
- msg, " actual=", actual, " expected=", expected, " err=", delta / bound);
- ABSL_RAW_LOG(INFO, "%s", formatted.c_str());
- return false;
-}
-
-// TODO(absl-team): Replace with an "ABSL_HAVE_SPECIAL_MATH" and try
-// to use std::beta(). As of this writing P0226R1 is not implemented
-// in libc++: http://libcxx.llvm.org/cxx1z_status.html
-double beta(double p, double q) {
- // Beta(x, y) = Gamma(x) * Gamma(y) / Gamma(x+y)
- double lbeta = std::lgamma(p) + std::lgamma(q) - std::lgamma(p + q);
- return std::exp(lbeta);
-}
-
-// Approximation to inverse of the Error Function in double precision.
-// (http://people.maths.ox.ac.uk/gilesm/files/gems_erfinv.pdf)
-double erfinv(double x) {
-#if !defined(__EMSCRIPTEN__)
- using std::fma;
-#endif
-
- double w = 0.0;
- double p = 0.0;
- w = -std::log((1.0 - x) * (1.0 + x));
- if (w < 6.250000) {
- w = w - 3.125000;
- p = -3.6444120640178196996e-21;
- p = fma(p, w, -1.685059138182016589e-19);
- p = fma(p, w, 1.2858480715256400167e-18);
- p = fma(p, w, 1.115787767802518096e-17);
- p = fma(p, w, -1.333171662854620906e-16);
- p = fma(p, w, 2.0972767875968561637e-17);
- p = fma(p, w, 6.6376381343583238325e-15);
- p = fma(p, w, -4.0545662729752068639e-14);
- p = fma(p, w, -8.1519341976054721522e-14);
- p = fma(p, w, 2.6335093153082322977e-12);
- p = fma(p, w, -1.2975133253453532498e-11);
- p = fma(p, w, -5.4154120542946279317e-11);
- p = fma(p, w, 1.051212273321532285e-09);
- p = fma(p, w, -4.1126339803469836976e-09);
- p = fma(p, w, -2.9070369957882005086e-08);
- p = fma(p, w, 4.2347877827932403518e-07);
- p = fma(p, w, -1.3654692000834678645e-06);
- p = fma(p, w, -1.3882523362786468719e-05);
- p = fma(p, w, 0.0001867342080340571352);
- p = fma(p, w, -0.00074070253416626697512);
- p = fma(p, w, -0.0060336708714301490533);
- p = fma(p, w, 0.24015818242558961693);
- p = fma(p, w, 1.6536545626831027356);
- } else if (w < 16.000000) {
- w = std::sqrt(w) - 3.250000;
- p = 2.2137376921775787049e-09;
- p = fma(p, w, 9.0756561938885390979e-08);
- p = fma(p, w, -2.7517406297064545428e-07);
- p = fma(p, w, 1.8239629214389227755e-08);
- p = fma(p, w, 1.5027403968909827627e-06);
- p = fma(p, w, -4.013867526981545969e-06);
- p = fma(p, w, 2.9234449089955446044e-06);
- p = fma(p, w, 1.2475304481671778723e-05);
- p = fma(p, w, -4.7318229009055733981e-05);
- p = fma(p, w, 6.8284851459573175448e-05);
- p = fma(p, w, 2.4031110387097893999e-05);
- p = fma(p, w, -0.0003550375203628474796);
- p = fma(p, w, 0.00095328937973738049703);
- p = fma(p, w, -0.0016882755560235047313);
- p = fma(p, w, 0.0024914420961078508066);
- p = fma(p, w, -0.0037512085075692412107);
- p = fma(p, w, 0.005370914553590063617);
- p = fma(p, w, 1.0052589676941592334);
- p = fma(p, w, 3.0838856104922207635);
- } else {
- w = std::sqrt(w) - 5.000000;
- p = -2.7109920616438573243e-11;
- p = fma(p, w, -2.5556418169965252055e-10);
- p = fma(p, w, 1.5076572693500548083e-09);
- p = fma(p, w, -3.7894654401267369937e-09);
- p = fma(p, w, 7.6157012080783393804e-09);
- p = fma(p, w, -1.4960026627149240478e-08);
- p = fma(p, w, 2.9147953450901080826e-08);
- p = fma(p, w, -6.7711997758452339498e-08);
- p = fma(p, w, 2.2900482228026654717e-07);
- p = fma(p, w, -9.9298272942317002539e-07);
- p = fma(p, w, 4.5260625972231537039e-06);
- p = fma(p, w, -1.9681778105531670567e-05);
- p = fma(p, w, 7.5995277030017761139e-05);
- p = fma(p, w, -0.00021503011930044477347);
- p = fma(p, w, -0.00013871931833623122026);
- p = fma(p, w, 1.0103004648645343977);
- p = fma(p, w, 4.8499064014085844221);
- }
- return p * x;
-}
-
-namespace {
-
-// Direct implementation of AS63, BETAIN()
-// https://www.jstor.org/stable/2346797?seq=3#page_scan_tab_contents.
-//
-// BETAIN(x, p, q, beta)
-// x: the value of the upper limit x.
-// p: the value of the parameter p.
-// q: the value of the parameter q.
-// beta: the value of ln B(p, q)
-//
-double BetaIncompleteImpl(const double x, const double p, const double q,
- const double beta) {
- if (p < (p + q) * x) {
- // Incomplete beta function is symmetrical, so return the complement.
- return 1. - BetaIncompleteImpl(1.0 - x, q, p, beta);
- }
-
- double psq = p + q;
- const double kErr = 1e-14;
- const double xc = 1. - x;
- const double pre =
- std::exp(p * std::log(x) + (q - 1.) * std::log(xc) - beta) / p;
-
- double term = 1.;
- double ai = 1.;
- double result = 1.;
- int ns = static_cast<int>(q + xc * psq);
-
- // Use the soper reduction forumla.
- double rx = (ns == 0) ? x : x / xc;
- double temp = q - ai;
- for (;;) {
- term = term * temp * rx / (p + ai);
- result = result + term;
- temp = std::fabs(term);
- if (temp < kErr && temp < kErr * result) {
- return result * pre;
- }
- ai = ai + 1.;
- --ns;
- if (ns >= 0) {
- temp = q - ai;
- if (ns == 0) {
- rx = x;
- }
- } else {
- temp = psq;
- psq = psq + 1.;
- }
- }
-
- // NOTE: See also TOMS Alogrithm 708.
- // http://www.netlib.org/toms/index.html
- //
- // NOTE: The NWSC library also includes BRATIO / ISUBX (p87)
- // https://archive.org/details/DTIC_ADA261511/page/n75
-}
-
-// Direct implementation of AS109, XINBTA(p, q, beta, alpha)
-// https://www.jstor.org/stable/2346798?read-now=1&seq=4#page_scan_tab_contents
-// https://www.jstor.org/stable/2346887?seq=1#page_scan_tab_contents
-//
-// XINBTA(p, q, beta, alhpa)
-// p: the value of the parameter p.
-// q: the value of the parameter q.
-// beta: the value of ln B(p, q)
-// alpha: the value of the lower tail area.
-//
-double BetaIncompleteInvImpl(const double p, const double q, const double beta,
- const double alpha) {
- if (alpha < 0.5) {
- // Inverse Incomplete beta function is symmetrical, return the complement.
- return 1. - BetaIncompleteInvImpl(q, p, beta, 1. - alpha);
- }
- const double kErr = 1e-14;
- double value = kErr;
-
- // Compute the initial estimate.
- {
- double r = std::sqrt(-std::log(alpha * alpha));
- double y =
- r - fma(r, 0.27061, 2.30753) / fma(r, fma(r, 0.04481, 0.99229), 1.0);
- if (p > 1. && q > 1.) {
- r = (y * y - 3.) / 6.;
- double s = 1. / (p + p - 1.);
- double t = 1. / (q + q - 1.);
- double h = 2. / s + t;
- double w =
- y * std::sqrt(h + r) / h - (t - s) * (r + 5. / 6. - t / (3. * h));
- value = p / (p + q * std::exp(w + w));
- } else {
- r = q + q;
- double t = 1.0 / (9. * q);
- double u = 1.0 - t + y * std::sqrt(t);
- t = r * (u * u * u);
- if (t <= 0) {
- value = 1.0 - std::exp((std::log((1.0 - alpha) * q) + beta) / q);
- } else {
- t = (4.0 * p + r - 2.0) / t;
- if (t <= 1) {
- value = std::exp((std::log(alpha * p) + beta) / p);
- } else {
- value = 1.0 - 2.0 / (t + 1.0);
- }
- }
- }
- }
-
- // Solve for x using a modified newton-raphson method using the function
- // BetaIncomplete.
- {
- value = std::max(value, kErr);
- value = std::min(value, 1.0 - kErr);
-
- const double r = 1.0 - p;
- const double t = 1.0 - q;
- double y;
- double yprev = 0;
- double sq = 1;
- double prev = 1;
- for (;;) {
- if (value < 0 || value > 1.0) {
- // Error case; value went infinite.
- return std::numeric_limits<double>::infinity();
- } else if (value == 0 || value == 1) {
- y = value;
- } else {
- y = BetaIncompleteImpl(value, p, q, beta);
- if (!std::isfinite(y)) {
- return y;
- }
- }
- y = (y - alpha) *
- std::exp(beta + r * std::log(value) + t * std::log(1.0 - value));
- if (y * yprev <= 0) {
- prev = std::max(sq, std::numeric_limits<double>::min());
- }
- double g = 1.0;
- for (;;) {
- const double adj = g * y;
- const double adj_sq = adj * adj;
- if (adj_sq >= prev) {
- g = g / 3.0;
- continue;
- }
- const double tx = value - adj;
- if (tx < 0 || tx > 1) {
- g = g / 3.0;
- continue;
- }
- if (prev < kErr) {
- return value;
- }
- if (y * y < kErr) {
- return value;
- }
- if (tx == value) {
- return value;
- }
- if (tx == 0 || tx == 1) {
- g = g / 3.0;
- continue;
- }
- value = tx;
- yprev = y;
- break;
- }
- }
- }
-
- // NOTES: See also: Asymptotic inversion of the incomplete beta function.
- // https://core.ac.uk/download/pdf/82140723.pdf
- //
- // NOTE: See the Boost library documentation as well:
- // https://www.boost.org/doc/libs/1_52_0/libs/math/doc/sf_and_dist/html/math_toolkit/special/sf_beta/ibeta_function.html
-}
-
-} // namespace
-
-double BetaIncomplete(const double x, const double p, const double q) {
- // Error cases.
- if (p < 0 || q < 0 || x < 0 || x > 1.0) {
- return std::numeric_limits<double>::infinity();
- }
- if (x == 0 || x == 1) {
- return x;
- }
- // ln(Beta(p, q))
- double beta = std::lgamma(p) + std::lgamma(q) - std::lgamma(p + q);
- return BetaIncompleteImpl(x, p, q, beta);
-}
-
-double BetaIncompleteInv(const double p, const double q, const double alpha) {
- // Error cases.
- if (p < 0 || q < 0 || alpha < 0 || alpha > 1.0) {
- return std::numeric_limits<double>::infinity();
- }
- if (alpha == 0 || alpha == 1) {
- return alpha;
- }
- // ln(Beta(p, q))
- double beta = std::lgamma(p) + std::lgamma(q) - std::lgamma(p + q);
- return BetaIncompleteInvImpl(p, q, beta, alpha);
-}
-
-// Given `num_trials` trials each with probability `p` of success, the
-// probability of no failures is `p^k`. To ensure the probability of a failure
-// is no more than `p_fail`, it must be that `p^k == 1 - p_fail`. This function
-// computes `p` from that equation.
-double RequiredSuccessProbability(const double p_fail, const int num_trials) {
- double p = std::exp(std::log(1.0 - p_fail) / static_cast<double>(num_trials));
- ABSL_ASSERT(p > 0);
- return p;
-}
-
-double ZScore(double expected_mean, const DistributionMoments& moments) {
- return (moments.mean - expected_mean) /
- (std::sqrt(moments.variance) /
- std::sqrt(static_cast<double>(moments.n)));
-}
-
-double MaxErrorTolerance(double acceptance_probability) {
- double one_sided_pvalue = 0.5 * (1.0 - acceptance_probability);
- const double max_err = InverseNormalSurvival(one_sided_pvalue);
- ABSL_ASSERT(max_err > 0);
- return max_err;
-}
-
-} // namespace random_internal
+namespace random_internal {
+namespace {
+
+#if defined(__EMSCRIPTEN__)
+// Workaround __EMSCRIPTEN__ error: llvm_fma_f64 not found.
+inline double fma(double x, double y, double z) { return (x * y) + z; }
+#endif
+
+} // namespace
+
+DistributionMoments ComputeDistributionMoments(
+ absl::Span<const double> data_points) {
+ DistributionMoments result;
+
+ // Compute m1
+ for (double x : data_points) {
+ result.n++;
+ result.mean += x;
+ }
+ result.mean /= static_cast<double>(result.n);
+
+ // Compute m2, m3, m4
+ for (double x : data_points) {
+ double v = x - result.mean;
+ result.variance += v * v;
+ result.skewness += v * v * v;
+ result.kurtosis += v * v * v * v;
+ }
+ result.variance /= static_cast<double>(result.n - 1);
+
+ result.skewness /= static_cast<double>(result.n);
+ result.skewness /= std::pow(result.variance, 1.5);
+
+ result.kurtosis /= static_cast<double>(result.n);
+ result.kurtosis /= std::pow(result.variance, 2.0);
+ return result;
+
+ // When validating the min/max count, the following confidence intervals may
+ // be of use:
+ // 3.291 * stddev = 99.9% CI
+ // 2.576 * stddev = 99% CI
+ // 1.96 * stddev = 95% CI
+ // 1.65 * stddev = 90% CI
+}
+
+std::ostream& operator<<(std::ostream& os, const DistributionMoments& moments) {
+ return os << absl::StrFormat("mean=%f, stddev=%f, skewness=%f, kurtosis=%f",
+ moments.mean, std::sqrt(moments.variance),
+ moments.skewness, moments.kurtosis);
+}
+
+double InverseNormalSurvival(double x) {
+ // inv_sf(u) = -sqrt(2) * erfinv(2u-1)
+ static constexpr double kSqrt2 = 1.4142135623730950488;
+ return -kSqrt2 * absl::random_internal::erfinv(2 * x - 1.0);
+}
+
+bool Near(absl::string_view msg, double actual, double expected, double bound) {
+ assert(bound > 0.0);
+ double delta = fabs(expected - actual);
+ if (delta < bound) {
+ return true;
+ }
+
+ std::string formatted = absl::StrCat(
+ msg, " actual=", actual, " expected=", expected, " err=", delta / bound);
+ ABSL_RAW_LOG(INFO, "%s", formatted.c_str());
+ return false;
+}
+
+// TODO(absl-team): Replace with an "ABSL_HAVE_SPECIAL_MATH" and try
+// to use std::beta(). As of this writing P0226R1 is not implemented
+// in libc++: http://libcxx.llvm.org/cxx1z_status.html
+double beta(double p, double q) {
+ // Beta(x, y) = Gamma(x) * Gamma(y) / Gamma(x+y)
+ double lbeta = std::lgamma(p) + std::lgamma(q) - std::lgamma(p + q);
+ return std::exp(lbeta);
+}
+
+// Approximation to inverse of the Error Function in double precision.
+// (http://people.maths.ox.ac.uk/gilesm/files/gems_erfinv.pdf)
+double erfinv(double x) {
+#if !defined(__EMSCRIPTEN__)
+ using std::fma;
+#endif
+
+ double w = 0.0;
+ double p = 0.0;
+ w = -std::log((1.0 - x) * (1.0 + x));
+ if (w < 6.250000) {
+ w = w - 3.125000;
+ p = -3.6444120640178196996e-21;
+ p = fma(p, w, -1.685059138182016589e-19);
+ p = fma(p, w, 1.2858480715256400167e-18);
+ p = fma(p, w, 1.115787767802518096e-17);
+ p = fma(p, w, -1.333171662854620906e-16);
+ p = fma(p, w, 2.0972767875968561637e-17);
+ p = fma(p, w, 6.6376381343583238325e-15);
+ p = fma(p, w, -4.0545662729752068639e-14);
+ p = fma(p, w, -8.1519341976054721522e-14);
+ p = fma(p, w, 2.6335093153082322977e-12);
+ p = fma(p, w, -1.2975133253453532498e-11);
+ p = fma(p, w, -5.4154120542946279317e-11);
+ p = fma(p, w, 1.051212273321532285e-09);
+ p = fma(p, w, -4.1126339803469836976e-09);
+ p = fma(p, w, -2.9070369957882005086e-08);
+ p = fma(p, w, 4.2347877827932403518e-07);
+ p = fma(p, w, -1.3654692000834678645e-06);
+ p = fma(p, w, -1.3882523362786468719e-05);
+ p = fma(p, w, 0.0001867342080340571352);
+ p = fma(p, w, -0.00074070253416626697512);
+ p = fma(p, w, -0.0060336708714301490533);
+ p = fma(p, w, 0.24015818242558961693);
+ p = fma(p, w, 1.6536545626831027356);
+ } else if (w < 16.000000) {
+ w = std::sqrt(w) - 3.250000;
+ p = 2.2137376921775787049e-09;
+ p = fma(p, w, 9.0756561938885390979e-08);
+ p = fma(p, w, -2.7517406297064545428e-07);
+ p = fma(p, w, 1.8239629214389227755e-08);
+ p = fma(p, w, 1.5027403968909827627e-06);
+ p = fma(p, w, -4.013867526981545969e-06);
+ p = fma(p, w, 2.9234449089955446044e-06);
+ p = fma(p, w, 1.2475304481671778723e-05);
+ p = fma(p, w, -4.7318229009055733981e-05);
+ p = fma(p, w, 6.8284851459573175448e-05);
+ p = fma(p, w, 2.4031110387097893999e-05);
+ p = fma(p, w, -0.0003550375203628474796);
+ p = fma(p, w, 0.00095328937973738049703);
+ p = fma(p, w, -0.0016882755560235047313);
+ p = fma(p, w, 0.0024914420961078508066);
+ p = fma(p, w, -0.0037512085075692412107);
+ p = fma(p, w, 0.005370914553590063617);
+ p = fma(p, w, 1.0052589676941592334);
+ p = fma(p, w, 3.0838856104922207635);
+ } else {
+ w = std::sqrt(w) - 5.000000;
+ p = -2.7109920616438573243e-11;
+ p = fma(p, w, -2.5556418169965252055e-10);
+ p = fma(p, w, 1.5076572693500548083e-09);
+ p = fma(p, w, -3.7894654401267369937e-09);
+ p = fma(p, w, 7.6157012080783393804e-09);
+ p = fma(p, w, -1.4960026627149240478e-08);
+ p = fma(p, w, 2.9147953450901080826e-08);
+ p = fma(p, w, -6.7711997758452339498e-08);
+ p = fma(p, w, 2.2900482228026654717e-07);
+ p = fma(p, w, -9.9298272942317002539e-07);
+ p = fma(p, w, 4.5260625972231537039e-06);
+ p = fma(p, w, -1.9681778105531670567e-05);
+ p = fma(p, w, 7.5995277030017761139e-05);
+ p = fma(p, w, -0.00021503011930044477347);
+ p = fma(p, w, -0.00013871931833623122026);
+ p = fma(p, w, 1.0103004648645343977);
+ p = fma(p, w, 4.8499064014085844221);
+ }
+ return p * x;
+}
+
+namespace {
+
+// Direct implementation of AS63, BETAIN()
+// https://www.jstor.org/stable/2346797?seq=3#page_scan_tab_contents.
+//
+// BETAIN(x, p, q, beta)
+// x: the value of the upper limit x.
+// p: the value of the parameter p.
+// q: the value of the parameter q.
+// beta: the value of ln B(p, q)
+//
+double BetaIncompleteImpl(const double x, const double p, const double q,
+ const double beta) {
+ if (p < (p + q) * x) {
+ // Incomplete beta function is symmetrical, so return the complement.
+ return 1. - BetaIncompleteImpl(1.0 - x, q, p, beta);
+ }
+
+ double psq = p + q;
+ const double kErr = 1e-14;
+ const double xc = 1. - x;
+ const double pre =
+ std::exp(p * std::log(x) + (q - 1.) * std::log(xc) - beta) / p;
+
+ double term = 1.;
+ double ai = 1.;
+ double result = 1.;
+ int ns = static_cast<int>(q + xc * psq);
+
+ // Use the soper reduction forumla.
+ double rx = (ns == 0) ? x : x / xc;
+ double temp = q - ai;
+ for (;;) {
+ term = term * temp * rx / (p + ai);
+ result = result + term;
+ temp = std::fabs(term);
+ if (temp < kErr && temp < kErr * result) {
+ return result * pre;
+ }
+ ai = ai + 1.;
+ --ns;
+ if (ns >= 0) {
+ temp = q - ai;
+ if (ns == 0) {
+ rx = x;
+ }
+ } else {
+ temp = psq;
+ psq = psq + 1.;
+ }
+ }
+
+ // NOTE: See also TOMS Alogrithm 708.
+ // http://www.netlib.org/toms/index.html
+ //
+ // NOTE: The NWSC library also includes BRATIO / ISUBX (p87)
+ // https://archive.org/details/DTIC_ADA261511/page/n75
+}
+
+// Direct implementation of AS109, XINBTA(p, q, beta, alpha)
+// https://www.jstor.org/stable/2346798?read-now=1&seq=4#page_scan_tab_contents
+// https://www.jstor.org/stable/2346887?seq=1#page_scan_tab_contents
+//
+// XINBTA(p, q, beta, alhpa)
+// p: the value of the parameter p.
+// q: the value of the parameter q.
+// beta: the value of ln B(p, q)
+// alpha: the value of the lower tail area.
+//
+double BetaIncompleteInvImpl(const double p, const double q, const double beta,
+ const double alpha) {
+ if (alpha < 0.5) {
+ // Inverse Incomplete beta function is symmetrical, return the complement.
+ return 1. - BetaIncompleteInvImpl(q, p, beta, 1. - alpha);
+ }
+ const double kErr = 1e-14;
+ double value = kErr;
+
+ // Compute the initial estimate.
+ {
+ double r = std::sqrt(-std::log(alpha * alpha));
+ double y =
+ r - fma(r, 0.27061, 2.30753) / fma(r, fma(r, 0.04481, 0.99229), 1.0);
+ if (p > 1. && q > 1.) {
+ r = (y * y - 3.) / 6.;
+ double s = 1. / (p + p - 1.);
+ double t = 1. / (q + q - 1.);
+ double h = 2. / s + t;
+ double w =
+ y * std::sqrt(h + r) / h - (t - s) * (r + 5. / 6. - t / (3. * h));
+ value = p / (p + q * std::exp(w + w));
+ } else {
+ r = q + q;
+ double t = 1.0 / (9. * q);
+ double u = 1.0 - t + y * std::sqrt(t);
+ t = r * (u * u * u);
+ if (t <= 0) {
+ value = 1.0 - std::exp((std::log((1.0 - alpha) * q) + beta) / q);
+ } else {
+ t = (4.0 * p + r - 2.0) / t;
+ if (t <= 1) {
+ value = std::exp((std::log(alpha * p) + beta) / p);
+ } else {
+ value = 1.0 - 2.0 / (t + 1.0);
+ }
+ }
+ }
+ }
+
+ // Solve for x using a modified newton-raphson method using the function
+ // BetaIncomplete.
+ {
+ value = std::max(value, kErr);
+ value = std::min(value, 1.0 - kErr);
+
+ const double r = 1.0 - p;
+ const double t = 1.0 - q;
+ double y;
+ double yprev = 0;
+ double sq = 1;
+ double prev = 1;
+ for (;;) {
+ if (value < 0 || value > 1.0) {
+ // Error case; value went infinite.
+ return std::numeric_limits<double>::infinity();
+ } else if (value == 0 || value == 1) {
+ y = value;
+ } else {
+ y = BetaIncompleteImpl(value, p, q, beta);
+ if (!std::isfinite(y)) {
+ return y;
+ }
+ }
+ y = (y - alpha) *
+ std::exp(beta + r * std::log(value) + t * std::log(1.0 - value));
+ if (y * yprev <= 0) {
+ prev = std::max(sq, std::numeric_limits<double>::min());
+ }
+ double g = 1.0;
+ for (;;) {
+ const double adj = g * y;
+ const double adj_sq = adj * adj;
+ if (adj_sq >= prev) {
+ g = g / 3.0;
+ continue;
+ }
+ const double tx = value - adj;
+ if (tx < 0 || tx > 1) {
+ g = g / 3.0;
+ continue;
+ }
+ if (prev < kErr) {
+ return value;
+ }
+ if (y * y < kErr) {
+ return value;
+ }
+ if (tx == value) {
+ return value;
+ }
+ if (tx == 0 || tx == 1) {
+ g = g / 3.0;
+ continue;
+ }
+ value = tx;
+ yprev = y;
+ break;
+ }
+ }
+ }
+
+ // NOTES: See also: Asymptotic inversion of the incomplete beta function.
+ // https://core.ac.uk/download/pdf/82140723.pdf
+ //
+ // NOTE: See the Boost library documentation as well:
+ // https://www.boost.org/doc/libs/1_52_0/libs/math/doc/sf_and_dist/html/math_toolkit/special/sf_beta/ibeta_function.html
+}
+
+} // namespace
+
+double BetaIncomplete(const double x, const double p, const double q) {
+ // Error cases.
+ if (p < 0 || q < 0 || x < 0 || x > 1.0) {
+ return std::numeric_limits<double>::infinity();
+ }
+ if (x == 0 || x == 1) {
+ return x;
+ }
+ // ln(Beta(p, q))
+ double beta = std::lgamma(p) + std::lgamma(q) - std::lgamma(p + q);
+ return BetaIncompleteImpl(x, p, q, beta);
+}
+
+double BetaIncompleteInv(const double p, const double q, const double alpha) {
+ // Error cases.
+ if (p < 0 || q < 0 || alpha < 0 || alpha > 1.0) {
+ return std::numeric_limits<double>::infinity();
+ }
+ if (alpha == 0 || alpha == 1) {
+ return alpha;
+ }
+ // ln(Beta(p, q))
+ double beta = std::lgamma(p) + std::lgamma(q) - std::lgamma(p + q);
+ return BetaIncompleteInvImpl(p, q, beta, alpha);
+}
+
+// Given `num_trials` trials each with probability `p` of success, the
+// probability of no failures is `p^k`. To ensure the probability of a failure
+// is no more than `p_fail`, it must be that `p^k == 1 - p_fail`. This function
+// computes `p` from that equation.
+double RequiredSuccessProbability(const double p_fail, const int num_trials) {
+ double p = std::exp(std::log(1.0 - p_fail) / static_cast<double>(num_trials));
+ ABSL_ASSERT(p > 0);
+ return p;
+}
+
+double ZScore(double expected_mean, const DistributionMoments& moments) {
+ return (moments.mean - expected_mean) /
+ (std::sqrt(moments.variance) /
+ std::sqrt(static_cast<double>(moments.n)));
+}
+
+double MaxErrorTolerance(double acceptance_probability) {
+ double one_sided_pvalue = 0.5 * (1.0 - acceptance_probability);
+ const double max_err = InverseNormalSurvival(one_sided_pvalue);
+ ABSL_ASSERT(max_err > 0);
+ return max_err;
+}
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
+} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.h b/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.h
index ea44666b4b..6d94cf6c97 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/distribution_test_util.h
@@ -1,113 +1,113 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_DISTRIBUTION_TEST_UTIL_H_
-#define ABSL_RANDOM_INTERNAL_DISTRIBUTION_TEST_UTIL_H_
-
-#include <cstddef>
-#include <iostream>
-#include <vector>
-
-#include "absl/strings/string_view.h"
-#include "absl/types/span.h"
-
-// NOTE: The functions in this file are test only, and are should not be used in
-// non-test code.
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_DISTRIBUTION_TEST_UTIL_H_
+#define ABSL_RANDOM_INTERNAL_DISTRIBUTION_TEST_UTIL_H_
+
+#include <cstddef>
+#include <iostream>
+#include <vector>
+
+#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
+
+// NOTE: The functions in this file are test only, and are should not be used in
+// non-test code.
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// http://webspace.ship.edu/pgmarr/Geo441/Lectures/Lec%205%20-%20Normality%20Testing.pdf
-
-// Compute the 1st to 4th standard moments:
-// mean, variance, skewness, and kurtosis.
-// http://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm
-struct DistributionMoments {
- size_t n = 0;
- double mean = 0.0;
- double variance = 0.0;
- double skewness = 0.0;
- double kurtosis = 0.0;
-};
-DistributionMoments ComputeDistributionMoments(
- absl::Span<const double> data_points);
-
-std::ostream& operator<<(std::ostream& os, const DistributionMoments& moments);
-
-// Computes the Z-score for a set of data with the given distribution moments
-// compared against `expected_mean`.
-double ZScore(double expected_mean, const DistributionMoments& moments);
-
-// Returns the probability of success required for a single trial to ensure that
-// after `num_trials` trials, the probability of at least one failure is no more
-// than `p_fail`.
-double RequiredSuccessProbability(double p_fail, int num_trials);
-
-// Computes the maximum distance from the mean tolerable, for Z-Tests that are
-// expected to pass with `acceptance_probability`. Will terminate if the
-// resulting tolerance is zero (due to passing in 0.0 for
-// `acceptance_probability` or rounding errors).
-//
-// For example,
-// MaxErrorTolerance(0.001) = 0.0
-// MaxErrorTolerance(0.5) = ~0.47
-// MaxErrorTolerance(1.0) = inf
-double MaxErrorTolerance(double acceptance_probability);
-
-// Approximation to inverse of the Error Function in double precision.
-// (http://people.maths.ox.ac.uk/gilesm/files/gems_erfinv.pdf)
-double erfinv(double x);
-
-// Beta(p, q) = Gamma(p) * Gamma(q) / Gamma(p+q)
-double beta(double p, double q);
-
-// The inverse of the normal survival function.
-double InverseNormalSurvival(double x);
-
-// Returns whether actual is "near" expected, based on the bound.
-bool Near(absl::string_view msg, double actual, double expected, double bound);
-
-// Implements the incomplete regularized beta function, AS63, BETAIN.
-// https://www.jstor.org/stable/2346797
-//
-// BetaIncomplete(x, p, q), where
-// `x` is the value of the upper limit
-// `p` is beta parameter p, `q` is beta parameter q.
-//
-// NOTE: This is a test-only function which is only accurate to within, at most,
-// 1e-13 of the actual value.
-//
-double BetaIncomplete(double x, double p, double q);
-
-// Implements the inverse of the incomplete regularized beta function, AS109,
-// XINBTA.
-// https://www.jstor.org/stable/2346798
-// https://www.jstor.org/stable/2346887
-//
-// BetaIncompleteInv(p, q, beta, alhpa)
-// `p` is beta parameter p, `q` is beta parameter q.
-// `alpha` is the value of the lower tail area.
-//
-// NOTE: This is a test-only function and, when successful, is only accurate to
-// within ~1e-6 of the actual value; there are some cases where it diverges from
-// the actual value by much more than that. The function uses Newton's method,
-// and thus the runtime is highly variable.
-double BetaIncompleteInv(double p, double q, double alpha);
-
-} // namespace random_internal
+namespace random_internal {
+
+// http://webspace.ship.edu/pgmarr/Geo441/Lectures/Lec%205%20-%20Normality%20Testing.pdf
+
+// Compute the 1st to 4th standard moments:
+// mean, variance, skewness, and kurtosis.
+// http://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm
+struct DistributionMoments {
+ size_t n = 0;
+ double mean = 0.0;
+ double variance = 0.0;
+ double skewness = 0.0;
+ double kurtosis = 0.0;
+};
+DistributionMoments ComputeDistributionMoments(
+ absl::Span<const double> data_points);
+
+std::ostream& operator<<(std::ostream& os, const DistributionMoments& moments);
+
+// Computes the Z-score for a set of data with the given distribution moments
+// compared against `expected_mean`.
+double ZScore(double expected_mean, const DistributionMoments& moments);
+
+// Returns the probability of success required for a single trial to ensure that
+// after `num_trials` trials, the probability of at least one failure is no more
+// than `p_fail`.
+double RequiredSuccessProbability(double p_fail, int num_trials);
+
+// Computes the maximum distance from the mean tolerable, for Z-Tests that are
+// expected to pass with `acceptance_probability`. Will terminate if the
+// resulting tolerance is zero (due to passing in 0.0 for
+// `acceptance_probability` or rounding errors).
+//
+// For example,
+// MaxErrorTolerance(0.001) = 0.0
+// MaxErrorTolerance(0.5) = ~0.47
+// MaxErrorTolerance(1.0) = inf
+double MaxErrorTolerance(double acceptance_probability);
+
+// Approximation to inverse of the Error Function in double precision.
+// (http://people.maths.ox.ac.uk/gilesm/files/gems_erfinv.pdf)
+double erfinv(double x);
+
+// Beta(p, q) = Gamma(p) * Gamma(q) / Gamma(p+q)
+double beta(double p, double q);
+
+// The inverse of the normal survival function.
+double InverseNormalSurvival(double x);
+
+// Returns whether actual is "near" expected, based on the bound.
+bool Near(absl::string_view msg, double actual, double expected, double bound);
+
+// Implements the incomplete regularized beta function, AS63, BETAIN.
+// https://www.jstor.org/stable/2346797
+//
+// BetaIncomplete(x, p, q), where
+// `x` is the value of the upper limit
+// `p` is beta parameter p, `q` is beta parameter q.
+//
+// NOTE: This is a test-only function which is only accurate to within, at most,
+// 1e-13 of the actual value.
+//
+double BetaIncomplete(double x, double p, double q);
+
+// Implements the inverse of the incomplete regularized beta function, AS109,
+// XINBTA.
+// https://www.jstor.org/stable/2346798
+// https://www.jstor.org/stable/2346887
+//
+// BetaIncompleteInv(p, q, beta, alhpa)
+// `p` is beta parameter p, `q` is beta parameter q.
+// `alpha` is the value of the lower tail area.
+//
+// NOTE: This is a test-only function and, when successful, is only accurate to
+// within ~1e-6 of the actual value; there are some cases where it diverges from
+// the actual value by much more than that. The function uses Newton's method,
+// and thus the runtime is highly variable.
+double BetaIncompleteInv(double p, double q, double alpha);
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_DISTRIBUTION_TEST_UTIL_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_DISTRIBUTION_TEST_UTIL_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/explicit_seed_seq.h b/contrib/restricted/abseil-cpp/absl/random/internal/explicit_seed_seq.h
index 01db58444a..25f791535f 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/explicit_seed_seq.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/explicit_seed_seq.h
@@ -1,92 +1,92 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_EXPLICIT_SEED_SEQ_H_
-#define ABSL_RANDOM_INTERNAL_EXPLICIT_SEED_SEQ_H_
-
-#include <algorithm>
-#include <cstddef>
-#include <cstdint>
-#include <initializer_list>
-#include <iterator>
-#include <vector>
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_EXPLICIT_SEED_SEQ_H_
+#define ABSL_RANDOM_INTERNAL_EXPLICIT_SEED_SEQ_H_
+
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <initializer_list>
+#include <iterator>
+#include <vector>
+
#include "absl/base/config.h"
#include "absl/base/internal/endian.h"
-namespace absl {
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// This class conforms to the C++ Standard "Seed Sequence" concept
-// [rand.req.seedseq].
-//
-// An "ExplicitSeedSeq" is meant to provide a conformant interface for
-// forwarding pre-computed seed material to the constructor of a class
-// conforming to the "Uniform Random Bit Generator" concept. This class makes no
-// attempt to mutate the state provided by its constructor, and returns it
-// directly via ExplicitSeedSeq::generate().
-//
-// If this class is asked to generate more seed material than was provided to
-// the constructor, then the remaining bytes will be filled with deterministic,
-// nonrandom data.
-class ExplicitSeedSeq {
- public:
- using result_type = uint32_t;
-
- ExplicitSeedSeq() : state_() {}
-
- // Copy and move both allowed.
- ExplicitSeedSeq(const ExplicitSeedSeq& other) = default;
- ExplicitSeedSeq& operator=(const ExplicitSeedSeq& other) = default;
- ExplicitSeedSeq(ExplicitSeedSeq&& other) = default;
- ExplicitSeedSeq& operator=(ExplicitSeedSeq&& other) = default;
-
- template <typename Iterator>
- ExplicitSeedSeq(Iterator begin, Iterator end) {
- for (auto it = begin; it != end; it++) {
- state_.push_back(*it & 0xffffffff);
- }
- }
-
- template <typename T>
- ExplicitSeedSeq(std::initializer_list<T> il)
- : ExplicitSeedSeq(il.begin(), il.end()) {}
-
- size_t size() const { return state_.size(); }
-
- template <typename OutIterator>
- void param(OutIterator out) const {
- std::copy(std::begin(state_), std::end(state_), out);
- }
-
- template <typename OutIterator>
- void generate(OutIterator begin, OutIterator end) {
- for (size_t index = 0; begin != end; begin++) {
+namespace random_internal {
+
+// This class conforms to the C++ Standard "Seed Sequence" concept
+// [rand.req.seedseq].
+//
+// An "ExplicitSeedSeq" is meant to provide a conformant interface for
+// forwarding pre-computed seed material to the constructor of a class
+// conforming to the "Uniform Random Bit Generator" concept. This class makes no
+// attempt to mutate the state provided by its constructor, and returns it
+// directly via ExplicitSeedSeq::generate().
+//
+// If this class is asked to generate more seed material than was provided to
+// the constructor, then the remaining bytes will be filled with deterministic,
+// nonrandom data.
+class ExplicitSeedSeq {
+ public:
+ using result_type = uint32_t;
+
+ ExplicitSeedSeq() : state_() {}
+
+ // Copy and move both allowed.
+ ExplicitSeedSeq(const ExplicitSeedSeq& other) = default;
+ ExplicitSeedSeq& operator=(const ExplicitSeedSeq& other) = default;
+ ExplicitSeedSeq(ExplicitSeedSeq&& other) = default;
+ ExplicitSeedSeq& operator=(ExplicitSeedSeq&& other) = default;
+
+ template <typename Iterator>
+ ExplicitSeedSeq(Iterator begin, Iterator end) {
+ for (auto it = begin; it != end; it++) {
+ state_.push_back(*it & 0xffffffff);
+ }
+ }
+
+ template <typename T>
+ ExplicitSeedSeq(std::initializer_list<T> il)
+ : ExplicitSeedSeq(il.begin(), il.end()) {}
+
+ size_t size() const { return state_.size(); }
+
+ template <typename OutIterator>
+ void param(OutIterator out) const {
+ std::copy(std::begin(state_), std::end(state_), out);
+ }
+
+ template <typename OutIterator>
+ void generate(OutIterator begin, OutIterator end) {
+ for (size_t index = 0; begin != end; begin++) {
*begin = state_.empty() ? 0 : state_[index++];
- if (index >= state_.size()) {
- index = 0;
- }
- }
- }
-
- protected:
- std::vector<uint32_t> state_;
-};
-
-} // namespace random_internal
+ if (index >= state_.size()) {
+ index = 0;
+ }
+ }
+ }
+
+ protected:
+ std::vector<uint32_t> state_;
+};
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_EXPLICIT_SEED_SEQ_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_EXPLICIT_SEED_SEQ_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/fast_uniform_bits.h b/contrib/restricted/abseil-cpp/absl/random/internal/fast_uniform_bits.h
index 3717a3904d..425aaf7d83 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/fast_uniform_bits.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/fast_uniform_bits.h
@@ -1,145 +1,145 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_FAST_UNIFORM_BITS_H_
-#define ABSL_RANDOM_INTERNAL_FAST_UNIFORM_BITS_H_
-
-#include <cstddef>
-#include <cstdint>
-#include <limits>
-#include <type_traits>
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_FAST_UNIFORM_BITS_H_
+#define ABSL_RANDOM_INTERNAL_FAST_UNIFORM_BITS_H_
+
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <type_traits>
+
#include "absl/base/config.h"
#include "absl/meta/type_traits.h"
-namespace absl {
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-// Returns true if the input value is zero or a power of two. Useful for
-// determining if the range of output values in a URBG
-template <typename UIntType>
-constexpr bool IsPowerOfTwoOrZero(UIntType n) {
- return (n == 0) || ((n & (n - 1)) == 0);
-}
-
-// Computes the length of the range of values producible by the URBG, or returns
-// zero if that would encompass the entire range of representable values in
-// URBG::result_type.
-template <typename URBG>
-constexpr typename URBG::result_type RangeSize() {
- using result_type = typename URBG::result_type;
+namespace random_internal {
+// Returns true if the input value is zero or a power of two. Useful for
+// determining if the range of output values in a URBG
+template <typename UIntType>
+constexpr bool IsPowerOfTwoOrZero(UIntType n) {
+ return (n == 0) || ((n & (n - 1)) == 0);
+}
+
+// Computes the length of the range of values producible by the URBG, or returns
+// zero if that would encompass the entire range of representable values in
+// URBG::result_type.
+template <typename URBG>
+constexpr typename URBG::result_type RangeSize() {
+ using result_type = typename URBG::result_type;
static_assert((URBG::max)() != (URBG::min)(), "URBG range cannot be 0.");
- return ((URBG::max)() == (std::numeric_limits<result_type>::max)() &&
- (URBG::min)() == std::numeric_limits<result_type>::lowest())
- ? result_type{0}
+ return ((URBG::max)() == (std::numeric_limits<result_type>::max)() &&
+ (URBG::min)() == std::numeric_limits<result_type>::lowest())
+ ? result_type{0}
: ((URBG::max)() - (URBG::min)() + result_type{1});
-}
-
-// Computes the floor of the log. (i.e., std::floor(std::log2(N));
-template <typename UIntType>
-constexpr UIntType IntegerLog2(UIntType n) {
+}
+
+// Computes the floor of the log. (i.e., std::floor(std::log2(N));
+template <typename UIntType>
+constexpr UIntType IntegerLog2(UIntType n) {
return (n <= 1) ? 0 : 1 + IntegerLog2(n >> 1);
-}
-
-// Returns the number of bits of randomness returned through
-// `PowerOfTwoVariate(urbg)`.
-template <typename URBG>
-constexpr size_t NumBits() {
- return RangeSize<URBG>() == 0
- ? std::numeric_limits<typename URBG::result_type>::digits
+}
+
+// Returns the number of bits of randomness returned through
+// `PowerOfTwoVariate(urbg)`.
+template <typename URBG>
+constexpr size_t NumBits() {
+ return RangeSize<URBG>() == 0
+ ? std::numeric_limits<typename URBG::result_type>::digits
: IntegerLog2(RangeSize<URBG>());
-}
-
-// Given a shift value `n`, constructs a mask with exactly the low `n` bits set.
-// If `n == 0`, all bits are set.
-template <typename UIntType>
+}
+
+// Given a shift value `n`, constructs a mask with exactly the low `n` bits set.
+// If `n == 0`, all bits are set.
+template <typename UIntType>
constexpr UIntType MaskFromShift(size_t n) {
- return ((n % std::numeric_limits<UIntType>::digits) == 0)
- ? ~UIntType{0}
- : (UIntType{1} << n) - UIntType{1};
-}
-
+ return ((n % std::numeric_limits<UIntType>::digits) == 0)
+ ? ~UIntType{0}
+ : (UIntType{1} << n) - UIntType{1};
+}
+
// Tags used to dispatch FastUniformBits::generate to the simple or more complex
// entropy extraction algorithm.
struct SimplifiedLoopTag {};
struct RejectionLoopTag {};
-// FastUniformBits implements a fast path to acquire uniform independent bits
-// from a type which conforms to the [rand.req.urbg] concept.
-// Parameterized by:
-// `UIntType`: the result (output) type
-//
-// The std::independent_bits_engine [rand.adapt.ibits] adaptor can be
-// instantiated from an existing generator through a copy or a move. It does
-// not, however, facilitate the production of pseudorandom bits from an un-owned
-// generator that will outlive the std::independent_bits_engine instance.
-template <typename UIntType = uint64_t>
-class FastUniformBits {
- public:
- using result_type = UIntType;
-
- static constexpr result_type(min)() { return 0; }
- static constexpr result_type(max)() {
- return (std::numeric_limits<result_type>::max)();
- }
-
- template <typename URBG>
- result_type operator()(URBG& g); // NOLINT(runtime/references)
-
- private:
- static_assert(std::is_unsigned<UIntType>::value,
- "Class-template FastUniformBits<> must be parameterized using "
- "an unsigned type.");
-
- // Generate() generates a random value, dispatched on whether
+// FastUniformBits implements a fast path to acquire uniform independent bits
+// from a type which conforms to the [rand.req.urbg] concept.
+// Parameterized by:
+// `UIntType`: the result (output) type
+//
+// The std::independent_bits_engine [rand.adapt.ibits] adaptor can be
+// instantiated from an existing generator through a copy or a move. It does
+// not, however, facilitate the production of pseudorandom bits from an un-owned
+// generator that will outlive the std::independent_bits_engine instance.
+template <typename UIntType = uint64_t>
+class FastUniformBits {
+ public:
+ using result_type = UIntType;
+
+ static constexpr result_type(min)() { return 0; }
+ static constexpr result_type(max)() {
+ return (std::numeric_limits<result_type>::max)();
+ }
+
+ template <typename URBG>
+ result_type operator()(URBG& g); // NOLINT(runtime/references)
+
+ private:
+ static_assert(std::is_unsigned<UIntType>::value,
+ "Class-template FastUniformBits<> must be parameterized using "
+ "an unsigned type.");
+
+ // Generate() generates a random value, dispatched on whether
// the underlying URBG must use rejection sampling to generate a value,
// or whether a simplified loop will suffice.
- template <typename URBG>
- result_type Generate(URBG& g, // NOLINT(runtime/references)
+ template <typename URBG>
+ result_type Generate(URBG& g, // NOLINT(runtime/references)
SimplifiedLoopTag);
-
- template <typename URBG>
- result_type Generate(URBG& g, // NOLINT(runtime/references)
+
+ template <typename URBG>
+ result_type Generate(URBG& g, // NOLINT(runtime/references)
RejectionLoopTag);
-};
-
-template <typename UIntType>
-template <typename URBG>
-typename FastUniformBits<UIntType>::result_type
-FastUniformBits<UIntType>::operator()(URBG& g) { // NOLINT(runtime/references)
- // kRangeMask is the mask used when sampling variates from the URBG when the
- // width of the URBG range is not a power of 2.
- // Y = (2 ^ kRange) - 1
- static_assert((URBG::max)() > (URBG::min)(),
- "URBG::max and URBG::min may not be equal.");
+};
+
+template <typename UIntType>
+template <typename URBG>
+typename FastUniformBits<UIntType>::result_type
+FastUniformBits<UIntType>::operator()(URBG& g) { // NOLINT(runtime/references)
+ // kRangeMask is the mask used when sampling variates from the URBG when the
+ // width of the URBG range is not a power of 2.
+ // Y = (2 ^ kRange) - 1
+ static_assert((URBG::max)() > (URBG::min)(),
+ "URBG::max and URBG::min may not be equal.");
using tag = absl::conditional_t<IsPowerOfTwoOrZero(RangeSize<URBG>()),
SimplifiedLoopTag, RejectionLoopTag>;
return Generate(g, tag{});
-}
-
-template <typename UIntType>
-template <typename URBG>
-typename FastUniformBits<UIntType>::result_type
-FastUniformBits<UIntType>::Generate(URBG& g, // NOLINT(runtime/references)
+}
+
+template <typename UIntType>
+template <typename URBG>
+typename FastUniformBits<UIntType>::result_type
+FastUniformBits<UIntType>::Generate(URBG& g, // NOLINT(runtime/references)
SimplifiedLoopTag) {
// The simplified version of FastUniformBits works only on URBGs that have
// a range that is a power of 2. In this case we simply loop and shift without
// attempting to balance the bits across calls.
static_assert(IsPowerOfTwoOrZero(RangeSize<URBG>()),
"incorrect Generate tag for URBG instance");
-
+
static constexpr size_t kResultBits =
std::numeric_limits<result_type>::digits;
static constexpr size_t kUrbgBits = NumBits<URBG>();
@@ -153,34 +153,34 @@ FastUniformBits<UIntType>::Generate(URBG& g, // NOLINT(runtime/references)
r = (r << kShift) + static_cast<result_type>(g() - kMin);
}
return r;
-}
-
-template <typename UIntType>
-template <typename URBG>
-typename FastUniformBits<UIntType>::result_type
-FastUniformBits<UIntType>::Generate(URBG& g, // NOLINT(runtime/references)
+}
+
+template <typename UIntType>
+template <typename URBG>
+typename FastUniformBits<UIntType>::result_type
+FastUniformBits<UIntType>::Generate(URBG& g, // NOLINT(runtime/references)
RejectionLoopTag) {
static_assert(!IsPowerOfTwoOrZero(RangeSize<URBG>()),
"incorrect Generate tag for URBG instance");
using urbg_result_type = typename URBG::result_type;
- // See [rand.adapt.ibits] for more details on the constants calculated below.
- //
- // It is preferable to use roughly the same number of bits from each generator
- // call, however this is only possible when the number of bits provided by the
- // URBG is a divisor of the number of bits in `result_type`. In all other
- // cases, the number of bits used cannot always be the same, but it can be
- // guaranteed to be off by at most 1. Thus we run two loops, one with a
- // smaller bit-width size (`kSmallWidth`) and one with a larger width size
- // (satisfying `kLargeWidth == kSmallWidth + 1`). The loops are run
- // `kSmallIters` and `kLargeIters` times respectively such
- // that
- //
+ // See [rand.adapt.ibits] for more details on the constants calculated below.
+ //
+ // It is preferable to use roughly the same number of bits from each generator
+ // call, however this is only possible when the number of bits provided by the
+ // URBG is a divisor of the number of bits in `result_type`. In all other
+ // cases, the number of bits used cannot always be the same, but it can be
+ // guaranteed to be off by at most 1. Thus we run two loops, one with a
+ // smaller bit-width size (`kSmallWidth`) and one with a larger width size
+ // (satisfying `kLargeWidth == kSmallWidth + 1`). The loops are run
+ // `kSmallIters` and `kLargeIters` times respectively such
+ // that
+ //
// `kResultBits == kSmallIters * kSmallBits
// + kLargeIters * kLargeBits`
- //
+ //
// where `kResultBits` is the total number of bits in `result_type`.
- //
+ //
static constexpr size_t kResultBits =
std::numeric_limits<result_type>::digits; // w
static constexpr urbg_result_type kUrbgRange = RangeSize<URBG>(); // R
@@ -210,24 +210,24 @@ FastUniformBits<UIntType>::Generate(URBG& g, // NOLINT(runtime/references)
static constexpr urbg_result_type kLargeRejection =
((kUrbgRange >> kLargeBits) << kLargeBits); // y1
- //
+ //
// Because `kLargeBits == kSmallBits + 1`, it follows that
- //
+ //
// `kResultBits == kSmallIters * kSmallBits + kLargeIters`
- //
- // and therefore
- //
- // `kLargeIters == kTotalWidth % kSmallWidth`
- //
- // Intuitively, each iteration with the large width accounts for one unit
- // of the remainder when `kTotalWidth` is divided by `kSmallWidth`. As
- // mentioned above, if the URBG width is a divisor of `kTotalWidth`, then
- // there would be no need for any large iterations (i.e., one loop would
- // suffice), and indeed, in this case, `kLargeIters` would be zero.
+ //
+ // and therefore
+ //
+ // `kLargeIters == kTotalWidth % kSmallWidth`
+ //
+ // Intuitively, each iteration with the large width accounts for one unit
+ // of the remainder when `kTotalWidth` is divided by `kSmallWidth`. As
+ // mentioned above, if the URBG width is a divisor of `kTotalWidth`, then
+ // there would be no need for any large iterations (i.e., one loop would
+ // suffice), and indeed, in this case, `kLargeIters` would be zero.
static_assert(kResultBits == kSmallIters * kSmallBits +
(kTotalIters - kSmallIters) * kLargeBits,
"Error in looping constant calculations.");
-
+
// The small shift is essentially small bits, but due to the potential
// of generating a smaller result_type from a larger urbg type, the actual
// shift might be 0.
@@ -237,32 +237,32 @@ FastUniformBits<UIntType>::Generate(URBG& g, // NOLINT(runtime/references)
static constexpr size_t kLargeShift = kLargeBits % kResultBits;
static constexpr auto kLargeMask =
MaskFromShift<urbg_result_type>(kLargeShift);
-
+
static constexpr auto kMin = (URBG::min)();
- result_type s = 0;
- for (size_t n = 0; n < kSmallIters; ++n) {
+ result_type s = 0;
+ for (size_t n = 0; n < kSmallIters; ++n) {
urbg_result_type v;
do {
v = g() - kMin;
} while (v >= kSmallRejection);
-
+
s = (s << kSmallShift) + static_cast<result_type>(v & kSmallMask);
- }
-
+ }
+
for (size_t n = kSmallIters; n < kTotalIters; ++n) {
urbg_result_type v;
do {
v = g() - kMin;
} while (v >= kLargeRejection);
-
+
s = (s << kLargeShift) + static_cast<result_type>(v & kLargeMask);
}
- return s;
-}
-
-} // namespace random_internal
+ return s;
+}
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_FAST_UNIFORM_BITS_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_FAST_UNIFORM_BITS_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/fastmath.h b/contrib/restricted/abseil-cpp/absl/random/internal/fastmath.h
index 83115715dd..963b7690f1 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/fastmath.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/fastmath.h
@@ -1,57 +1,57 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_FASTMATH_H_
-#define ABSL_RANDOM_INTERNAL_FASTMATH_H_
-
-// This file contains fast math functions (bitwise ops as well as some others)
-// which are implementation details of various absl random number distributions.
-
-#include <cassert>
-#include <cmath>
-#include <cstdint>
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_FASTMATH_H_
+#define ABSL_RANDOM_INTERNAL_FASTMATH_H_
+
+// This file contains fast math functions (bitwise ops as well as some others)
+// which are implementation details of various absl random number distributions.
+
+#include <cassert>
+#include <cmath>
+#include <cstdint>
+
#include "absl/numeric/bits.h"
-
-namespace absl {
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// Compute log2(n) using integer operations.
-// While std::log2 is more accurate than std::log(n) / std::log(2), for
-// very large numbers--those close to std::numeric_limits<uint64_t>::max() - 2,
-// for instance--std::log2 rounds up rather than down, which introduces
-// definite skew in the results.
-inline int IntLog2Floor(uint64_t n) {
+namespace random_internal {
+
+// Compute log2(n) using integer operations.
+// While std::log2 is more accurate than std::log(n) / std::log(2), for
+// very large numbers--those close to std::numeric_limits<uint64_t>::max() - 2,
+// for instance--std::log2 rounds up rather than down, which introduces
+// definite skew in the results.
+inline int IntLog2Floor(uint64_t n) {
return (n <= 1) ? 0 : (63 - countl_zero(n));
-}
-inline int IntLog2Ceil(uint64_t n) {
+}
+inline int IntLog2Ceil(uint64_t n) {
return (n <= 1) ? 0 : (64 - countl_zero(n - 1));
-}
-
-inline double StirlingLogFactorial(double n) {
- assert(n >= 1);
- // Using Stirling's approximation.
- constexpr double kLog2PI = 1.83787706640934548356;
- const double logn = std::log(n);
- const double ninv = 1.0 / static_cast<double>(n);
- return n * logn - n + 0.5 * (kLog2PI + logn) + (1.0 / 12.0) * ninv -
- (1.0 / 360.0) * ninv * ninv * ninv;
-}
-
-} // namespace random_internal
+}
+
+inline double StirlingLogFactorial(double n) {
+ assert(n >= 1);
+ // Using Stirling's approximation.
+ constexpr double kLog2PI = 1.83787706640934548356;
+ const double logn = std::log(n);
+ const double ninv = 1.0 / static_cast<double>(n);
+ return n * logn - n + 0.5 * (kLog2PI + logn) + (1.0 / 12.0) * ninv -
+ (1.0 / 360.0) * ninv * ninv * ninv;
+}
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_FASTMATH_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_FASTMATH_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/generate_real.h b/contrib/restricted/abseil-cpp/absl/random/internal/generate_real.h
index 46ff913090..d5fbb44c24 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/generate_real.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/generate_real.h
@@ -1,144 +1,144 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_
-#define ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_
-
-// This file contains some implementation details which are used by one or more
-// of the absl random number distributions.
-
-#include <cstdint>
-#include <cstring>
-#include <limits>
-#include <type_traits>
-
-#include "absl/meta/type_traits.h"
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_
+#define ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_
+
+// This file contains some implementation details which are used by one or more
+// of the absl random number distributions.
+
+#include <cstdint>
+#include <cstring>
+#include <limits>
+#include <type_traits>
+
+#include "absl/meta/type_traits.h"
#include "absl/numeric/bits.h"
-#include "absl/random/internal/fastmath.h"
-#include "absl/random/internal/traits.h"
-
-namespace absl {
+#include "absl/random/internal/fastmath.h"
+#include "absl/random/internal/traits.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// Tristate tag types controlling the output of GenerateRealFromBits.
-struct GeneratePositiveTag {};
-struct GenerateNegativeTag {};
-struct GenerateSignedTag {};
-
-// GenerateRealFromBits generates a single real value from a single 64-bit
-// `bits` with template fields controlling the output.
-//
-// The `SignedTag` parameter controls whether positive, negative,
-// or either signed/unsigned may be returned.
-// When SignedTag == GeneratePositiveTag, range is U(0, 1)
-// When SignedTag == GenerateNegativeTag, range is U(-1, 0)
-// When SignedTag == GenerateSignedTag, range is U(-1, 1)
-//
-// When the `IncludeZero` parameter is true, the function may return 0 for some
-// inputs, otherwise it never returns 0.
-//
-// When a value in U(0,1) is required, use:
-// Uniform64ToReal<double, PositiveValueT, true>;
-//
-// When a value in U(-1,1) is required, use:
-// Uniform64ToReal<double, SignedValueT, false>;
-//
-// This generates more distinct values than the mathematical equivalent
-// `U(0, 1) * 2.0 - 1.0`.
-//
-// Scaling the result by powers of 2 (and avoiding a multiply) is also possible:
-// GenerateRealFromBits<double>(..., -1); => U(0, 0.5)
-// GenerateRealFromBits<double>(..., 1); => U(0, 2)
-//
-template <typename RealType, // Real type, either float or double.
- typename SignedTag = GeneratePositiveTag, // Whether a positive,
- // negative, or signed
- // value is generated.
- bool IncludeZero = true>
-inline RealType GenerateRealFromBits(uint64_t bits, int exp_bias = 0) {
- using real_type = RealType;
- using uint_type = absl::conditional_t<std::is_same<real_type, float>::value,
- uint32_t, uint64_t>;
-
- static_assert(
- (std::is_same<double, real_type>::value ||
- std::is_same<float, real_type>::value),
- "GenerateRealFromBits must be parameterized by either float or double.");
-
- static_assert(sizeof(uint_type) == sizeof(real_type),
- "Mismatched unsinged and real types.");
-
- static_assert((std::numeric_limits<real_type>::is_iec559 &&
- std::numeric_limits<real_type>::radix == 2),
- "RealType representation is not IEEE 754 binary.");
-
- static_assert((std::is_same<SignedTag, GeneratePositiveTag>::value ||
- std::is_same<SignedTag, GenerateNegativeTag>::value ||
- std::is_same<SignedTag, GenerateSignedTag>::value),
- "");
-
- static constexpr int kExp = std::numeric_limits<real_type>::digits - 1;
- static constexpr uint_type kMask = (static_cast<uint_type>(1) << kExp) - 1u;
- static constexpr int kUintBits = sizeof(uint_type) * 8;
-
- int exp = exp_bias + int{std::numeric_limits<real_type>::max_exponent - 2};
-
- // Determine the sign bit.
- // Depending on the SignedTag, this may use the left-most bit
- // or it may be a constant value.
- uint_type sign = std::is_same<SignedTag, GenerateNegativeTag>::value
- ? (static_cast<uint_type>(1) << (kUintBits - 1))
- : 0;
- if (std::is_same<SignedTag, GenerateSignedTag>::value) {
- if (std::is_same<uint_type, uint64_t>::value) {
- sign = bits & uint64_t{0x8000000000000000};
- }
- if (std::is_same<uint_type, uint32_t>::value) {
- const uint64_t tmp = bits & uint64_t{0x8000000000000000};
- sign = static_cast<uint32_t>(tmp >> 32);
- }
- // adjust the bits and the exponent to account for removing
- // the leading bit.
- bits = bits & uint64_t{0x7FFFFFFFFFFFFFFF};
- exp++;
- }
- if (IncludeZero) {
- if (bits == 0u) return 0;
- }
-
- // Number of leading zeros is mapped to the exponent: 2^-clz
- // bits is 0..01xxxxxx. After shifting, we're left with 1xxx...0..0
+namespace random_internal {
+
+// Tristate tag types controlling the output of GenerateRealFromBits.
+struct GeneratePositiveTag {};
+struct GenerateNegativeTag {};
+struct GenerateSignedTag {};
+
+// GenerateRealFromBits generates a single real value from a single 64-bit
+// `bits` with template fields controlling the output.
+//
+// The `SignedTag` parameter controls whether positive, negative,
+// or either signed/unsigned may be returned.
+// When SignedTag == GeneratePositiveTag, range is U(0, 1)
+// When SignedTag == GenerateNegativeTag, range is U(-1, 0)
+// When SignedTag == GenerateSignedTag, range is U(-1, 1)
+//
+// When the `IncludeZero` parameter is true, the function may return 0 for some
+// inputs, otherwise it never returns 0.
+//
+// When a value in U(0,1) is required, use:
+// Uniform64ToReal<double, PositiveValueT, true>;
+//
+// When a value in U(-1,1) is required, use:
+// Uniform64ToReal<double, SignedValueT, false>;
+//
+// This generates more distinct values than the mathematical equivalent
+// `U(0, 1) * 2.0 - 1.0`.
+//
+// Scaling the result by powers of 2 (and avoiding a multiply) is also possible:
+// GenerateRealFromBits<double>(..., -1); => U(0, 0.5)
+// GenerateRealFromBits<double>(..., 1); => U(0, 2)
+//
+template <typename RealType, // Real type, either float or double.
+ typename SignedTag = GeneratePositiveTag, // Whether a positive,
+ // negative, or signed
+ // value is generated.
+ bool IncludeZero = true>
+inline RealType GenerateRealFromBits(uint64_t bits, int exp_bias = 0) {
+ using real_type = RealType;
+ using uint_type = absl::conditional_t<std::is_same<real_type, float>::value,
+ uint32_t, uint64_t>;
+
+ static_assert(
+ (std::is_same<double, real_type>::value ||
+ std::is_same<float, real_type>::value),
+ "GenerateRealFromBits must be parameterized by either float or double.");
+
+ static_assert(sizeof(uint_type) == sizeof(real_type),
+ "Mismatched unsinged and real types.");
+
+ static_assert((std::numeric_limits<real_type>::is_iec559 &&
+ std::numeric_limits<real_type>::radix == 2),
+ "RealType representation is not IEEE 754 binary.");
+
+ static_assert((std::is_same<SignedTag, GeneratePositiveTag>::value ||
+ std::is_same<SignedTag, GenerateNegativeTag>::value ||
+ std::is_same<SignedTag, GenerateSignedTag>::value),
+ "");
+
+ static constexpr int kExp = std::numeric_limits<real_type>::digits - 1;
+ static constexpr uint_type kMask = (static_cast<uint_type>(1) << kExp) - 1u;
+ static constexpr int kUintBits = sizeof(uint_type) * 8;
+
+ int exp = exp_bias + int{std::numeric_limits<real_type>::max_exponent - 2};
+
+ // Determine the sign bit.
+ // Depending on the SignedTag, this may use the left-most bit
+ // or it may be a constant value.
+ uint_type sign = std::is_same<SignedTag, GenerateNegativeTag>::value
+ ? (static_cast<uint_type>(1) << (kUintBits - 1))
+ : 0;
+ if (std::is_same<SignedTag, GenerateSignedTag>::value) {
+ if (std::is_same<uint_type, uint64_t>::value) {
+ sign = bits & uint64_t{0x8000000000000000};
+ }
+ if (std::is_same<uint_type, uint32_t>::value) {
+ const uint64_t tmp = bits & uint64_t{0x8000000000000000};
+ sign = static_cast<uint32_t>(tmp >> 32);
+ }
+ // adjust the bits and the exponent to account for removing
+ // the leading bit.
+ bits = bits & uint64_t{0x7FFFFFFFFFFFFFFF};
+ exp++;
+ }
+ if (IncludeZero) {
+ if (bits == 0u) return 0;
+ }
+
+ // Number of leading zeros is mapped to the exponent: 2^-clz
+ // bits is 0..01xxxxxx. After shifting, we're left with 1xxx...0..0
int clz = countl_zero(bits);
- bits <<= (IncludeZero ? clz : (clz & 63)); // remove 0-bits.
- exp -= clz; // set the exponent.
- bits >>= (63 - kExp);
-
- // Construct the 32-bit or 64-bit IEEE 754 floating-point value from
- // the individual fields: sign, exp, mantissa(bits).
+ bits <<= (IncludeZero ? clz : (clz & 63)); // remove 0-bits.
+ exp -= clz; // set the exponent.
+ bits >>= (63 - kExp);
+
+ // Construct the 32-bit or 64-bit IEEE 754 floating-point value from
+ // the individual fields: sign, exp, mantissa(bits).
uint_type val = sign | (static_cast<uint_type>(exp) << kExp) |
(static_cast<uint_type>(bits) & kMask);
-
- // bit_cast to the output-type
- real_type result;
- memcpy(static_cast<void*>(&result), static_cast<const void*>(&val),
- sizeof(result));
- return result;
-}
-
-} // namespace random_internal
+
+ // bit_cast to the output-type
+ real_type result;
+ memcpy(static_cast<void*>(&result), static_cast<const void*>(&val),
+ sizeof(result));
+ return result;
+}
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/iostream_state_saver.h b/contrib/restricted/abseil-cpp/absl/random/internal/iostream_state_saver.h
index aaef9f476c..e6e242ee1e 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/iostream_state_saver.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/iostream_state_saver.h
@@ -1,245 +1,245 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_IOSTREAM_STATE_SAVER_H_
-#define ABSL_RANDOM_INTERNAL_IOSTREAM_STATE_SAVER_H_
-
-#include <cmath>
-#include <iostream>
-#include <limits>
-#include <type_traits>
-
-#include "absl/meta/type_traits.h"
-#include "absl/numeric/int128.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_IOSTREAM_STATE_SAVER_H_
+#define ABSL_RANDOM_INTERNAL_IOSTREAM_STATE_SAVER_H_
+
+#include <cmath>
+#include <iostream>
+#include <limits>
+#include <type_traits>
+
+#include "absl/meta/type_traits.h"
+#include "absl/numeric/int128.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// The null_state_saver does nothing.
-template <typename T>
-class null_state_saver {
- public:
- using stream_type = T;
- using flags_type = std::ios_base::fmtflags;
-
- null_state_saver(T&, flags_type) {}
- ~null_state_saver() {}
-};
-
-// ostream_state_saver is a RAII object to save and restore the common
-// basic_ostream flags used when implementing `operator <<()` on any of
-// the absl random distributions.
-template <typename OStream>
-class ostream_state_saver {
- public:
- using ostream_type = OStream;
- using flags_type = std::ios_base::fmtflags;
- using fill_type = typename ostream_type::char_type;
- using precision_type = std::streamsize;
-
- ostream_state_saver(ostream_type& os, // NOLINT(runtime/references)
- flags_type flags, fill_type fill)
- : os_(os),
- flags_(os.flags(flags)),
- fill_(os.fill(fill)),
- precision_(os.precision()) {
- // Save state in initialized variables.
- }
-
- ~ostream_state_saver() {
- // Restore saved state.
- os_.precision(precision_);
- os_.fill(fill_);
- os_.flags(flags_);
- }
-
- private:
- ostream_type& os_;
- const flags_type flags_;
- const fill_type fill_;
- const precision_type precision_;
-};
-
-#if defined(__NDK_MAJOR__) && __NDK_MAJOR__ < 16
-#define ABSL_RANDOM_INTERNAL_IOSTREAM_HEXFLOAT 1
-#else
-#define ABSL_RANDOM_INTERNAL_IOSTREAM_HEXFLOAT 0
-#endif
-
-template <typename CharT, typename Traits>
-ostream_state_saver<std::basic_ostream<CharT, Traits>> make_ostream_state_saver(
- std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
- std::ios_base::fmtflags flags = std::ios_base::dec | std::ios_base::left |
-#if ABSL_RANDOM_INTERNAL_IOSTREAM_HEXFLOAT
- std::ios_base::fixed |
-#endif
- std::ios_base::scientific) {
- using result_type = ostream_state_saver<std::basic_ostream<CharT, Traits>>;
- return result_type(os, flags, os.widen(' '));
-}
-
-template <typename T>
-typename absl::enable_if_t<!std::is_base_of<std::ios_base, T>::value,
- null_state_saver<T>>
-make_ostream_state_saver(T& is, // NOLINT(runtime/references)
- std::ios_base::fmtflags flags = std::ios_base::dec) {
- std::cerr << "null_state_saver";
- using result_type = null_state_saver<T>;
- return result_type(is, flags);
-}
-
-// stream_precision_helper<type>::kPrecision returns the base 10 precision
-// required to stream and reconstruct a real type exact binary value through
-// a binary->decimal->binary transition.
-template <typename T>
-struct stream_precision_helper {
- // max_digits10 may be 0 on MSVC; if so, use digits10 + 3.
- static constexpr int kPrecision =
- (std::numeric_limits<T>::max_digits10 > std::numeric_limits<T>::digits10)
- ? std::numeric_limits<T>::max_digits10
- : (std::numeric_limits<T>::digits10 + 3);
-};
-
-template <>
-struct stream_precision_helper<float> {
- static constexpr int kPrecision = 9;
-};
-template <>
-struct stream_precision_helper<double> {
- static constexpr int kPrecision = 17;
-};
-template <>
-struct stream_precision_helper<long double> {
- static constexpr int kPrecision = 36; // assuming fp128
-};
-
-// istream_state_saver is a RAII object to save and restore the common
-// std::basic_istream<> flags used when implementing `operator >>()` on any of
-// the absl random distributions.
-template <typename IStream>
-class istream_state_saver {
- public:
- using istream_type = IStream;
- using flags_type = std::ios_base::fmtflags;
-
- istream_state_saver(istream_type& is, // NOLINT(runtime/references)
- flags_type flags)
- : is_(is), flags_(is.flags(flags)) {}
-
- ~istream_state_saver() { is_.flags(flags_); }
-
- private:
- istream_type& is_;
- flags_type flags_;
-};
-
-template <typename CharT, typename Traits>
-istream_state_saver<std::basic_istream<CharT, Traits>> make_istream_state_saver(
- std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
- std::ios_base::fmtflags flags = std::ios_base::dec |
- std::ios_base::scientific |
- std::ios_base::skipws) {
- using result_type = istream_state_saver<std::basic_istream<CharT, Traits>>;
- return result_type(is, flags);
-}
-
-template <typename T>
-typename absl::enable_if_t<!std::is_base_of<std::ios_base, T>::value,
- null_state_saver<T>>
-make_istream_state_saver(T& is, // NOLINT(runtime/references)
- std::ios_base::fmtflags flags = std::ios_base::dec) {
- using result_type = null_state_saver<T>;
- return result_type(is, flags);
-}
-
-// stream_format_type<T> is a helper struct to convert types which
-// basic_iostream cannot output as decimal numbers into types which
-// basic_iostream can output as decimal numbers. Specifically:
-// * signed/unsigned char-width types are converted to int.
-// * TODO(lar): __int128 => uint128, except there is no operator << yet.
-//
-template <typename T>
-struct stream_format_type
- : public std::conditional<(sizeof(T) == sizeof(char)), int, T> {};
-
-// stream_u128_helper allows us to write out either absl::uint128 or
-// __uint128_t types in the same way, which enables their use as internal
-// state of PRNG engines.
-template <typename T>
-struct stream_u128_helper;
-
-template <>
-struct stream_u128_helper<absl::uint128> {
- template <typename IStream>
- inline absl::uint128 read(IStream& in) {
- uint64_t h = 0;
- uint64_t l = 0;
- in >> h >> l;
- return absl::MakeUint128(h, l);
- }
-
- template <typename OStream>
- inline void write(absl::uint128 val, OStream& out) {
+namespace random_internal {
+
+// The null_state_saver does nothing.
+template <typename T>
+class null_state_saver {
+ public:
+ using stream_type = T;
+ using flags_type = std::ios_base::fmtflags;
+
+ null_state_saver(T&, flags_type) {}
+ ~null_state_saver() {}
+};
+
+// ostream_state_saver is a RAII object to save and restore the common
+// basic_ostream flags used when implementing `operator <<()` on any of
+// the absl random distributions.
+template <typename OStream>
+class ostream_state_saver {
+ public:
+ using ostream_type = OStream;
+ using flags_type = std::ios_base::fmtflags;
+ using fill_type = typename ostream_type::char_type;
+ using precision_type = std::streamsize;
+
+ ostream_state_saver(ostream_type& os, // NOLINT(runtime/references)
+ flags_type flags, fill_type fill)
+ : os_(os),
+ flags_(os.flags(flags)),
+ fill_(os.fill(fill)),
+ precision_(os.precision()) {
+ // Save state in initialized variables.
+ }
+
+ ~ostream_state_saver() {
+ // Restore saved state.
+ os_.precision(precision_);
+ os_.fill(fill_);
+ os_.flags(flags_);
+ }
+
+ private:
+ ostream_type& os_;
+ const flags_type flags_;
+ const fill_type fill_;
+ const precision_type precision_;
+};
+
+#if defined(__NDK_MAJOR__) && __NDK_MAJOR__ < 16
+#define ABSL_RANDOM_INTERNAL_IOSTREAM_HEXFLOAT 1
+#else
+#define ABSL_RANDOM_INTERNAL_IOSTREAM_HEXFLOAT 0
+#endif
+
+template <typename CharT, typename Traits>
+ostream_state_saver<std::basic_ostream<CharT, Traits>> make_ostream_state_saver(
+ std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
+ std::ios_base::fmtflags flags = std::ios_base::dec | std::ios_base::left |
+#if ABSL_RANDOM_INTERNAL_IOSTREAM_HEXFLOAT
+ std::ios_base::fixed |
+#endif
+ std::ios_base::scientific) {
+ using result_type = ostream_state_saver<std::basic_ostream<CharT, Traits>>;
+ return result_type(os, flags, os.widen(' '));
+}
+
+template <typename T>
+typename absl::enable_if_t<!std::is_base_of<std::ios_base, T>::value,
+ null_state_saver<T>>
+make_ostream_state_saver(T& is, // NOLINT(runtime/references)
+ std::ios_base::fmtflags flags = std::ios_base::dec) {
+ std::cerr << "null_state_saver";
+ using result_type = null_state_saver<T>;
+ return result_type(is, flags);
+}
+
+// stream_precision_helper<type>::kPrecision returns the base 10 precision
+// required to stream and reconstruct a real type exact binary value through
+// a binary->decimal->binary transition.
+template <typename T>
+struct stream_precision_helper {
+ // max_digits10 may be 0 on MSVC; if so, use digits10 + 3.
+ static constexpr int kPrecision =
+ (std::numeric_limits<T>::max_digits10 > std::numeric_limits<T>::digits10)
+ ? std::numeric_limits<T>::max_digits10
+ : (std::numeric_limits<T>::digits10 + 3);
+};
+
+template <>
+struct stream_precision_helper<float> {
+ static constexpr int kPrecision = 9;
+};
+template <>
+struct stream_precision_helper<double> {
+ static constexpr int kPrecision = 17;
+};
+template <>
+struct stream_precision_helper<long double> {
+ static constexpr int kPrecision = 36; // assuming fp128
+};
+
+// istream_state_saver is a RAII object to save and restore the common
+// std::basic_istream<> flags used when implementing `operator >>()` on any of
+// the absl random distributions.
+template <typename IStream>
+class istream_state_saver {
+ public:
+ using istream_type = IStream;
+ using flags_type = std::ios_base::fmtflags;
+
+ istream_state_saver(istream_type& is, // NOLINT(runtime/references)
+ flags_type flags)
+ : is_(is), flags_(is.flags(flags)) {}
+
+ ~istream_state_saver() { is_.flags(flags_); }
+
+ private:
+ istream_type& is_;
+ flags_type flags_;
+};
+
+template <typename CharT, typename Traits>
+istream_state_saver<std::basic_istream<CharT, Traits>> make_istream_state_saver(
+ std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
+ std::ios_base::fmtflags flags = std::ios_base::dec |
+ std::ios_base::scientific |
+ std::ios_base::skipws) {
+ using result_type = istream_state_saver<std::basic_istream<CharT, Traits>>;
+ return result_type(is, flags);
+}
+
+template <typename T>
+typename absl::enable_if_t<!std::is_base_of<std::ios_base, T>::value,
+ null_state_saver<T>>
+make_istream_state_saver(T& is, // NOLINT(runtime/references)
+ std::ios_base::fmtflags flags = std::ios_base::dec) {
+ using result_type = null_state_saver<T>;
+ return result_type(is, flags);
+}
+
+// stream_format_type<T> is a helper struct to convert types which
+// basic_iostream cannot output as decimal numbers into types which
+// basic_iostream can output as decimal numbers. Specifically:
+// * signed/unsigned char-width types are converted to int.
+// * TODO(lar): __int128 => uint128, except there is no operator << yet.
+//
+template <typename T>
+struct stream_format_type
+ : public std::conditional<(sizeof(T) == sizeof(char)), int, T> {};
+
+// stream_u128_helper allows us to write out either absl::uint128 or
+// __uint128_t types in the same way, which enables their use as internal
+// state of PRNG engines.
+template <typename T>
+struct stream_u128_helper;
+
+template <>
+struct stream_u128_helper<absl::uint128> {
+ template <typename IStream>
+ inline absl::uint128 read(IStream& in) {
+ uint64_t h = 0;
+ uint64_t l = 0;
+ in >> h >> l;
+ return absl::MakeUint128(h, l);
+ }
+
+ template <typename OStream>
+ inline void write(absl::uint128 val, OStream& out) {
uint64_t h = absl::Uint128High64(val);
uint64_t l = absl::Uint128Low64(val);
- out << h << out.fill() << l;
- }
-};
-
-#ifdef ABSL_HAVE_INTRINSIC_INT128
-template <>
-struct stream_u128_helper<__uint128_t> {
- template <typename IStream>
- inline __uint128_t read(IStream& in) {
- uint64_t h = 0;
- uint64_t l = 0;
- in >> h >> l;
- return (static_cast<__uint128_t>(h) << 64) | l;
- }
-
- template <typename OStream>
- inline void write(__uint128_t val, OStream& out) {
- uint64_t h = static_cast<uint64_t>(val >> 64u);
- uint64_t l = static_cast<uint64_t>(val);
- out << h << out.fill() << l;
- }
-};
-#endif
-
-template <typename FloatType, typename IStream>
-inline FloatType read_floating_point(IStream& is) {
- static_assert(std::is_floating_point<FloatType>::value, "");
- FloatType dest;
- is >> dest;
- // Parsing a double value may report a subnormal value as an error
- // despite being able to represent it.
- // See https://stackoverflow.com/q/52410931/3286653
- // It may also report an underflow when parsing DOUBLE_MIN as an
- // ERANGE error, as the parsed value may be smaller than DOUBLE_MIN
- // and rounded up.
- // See: https://stackoverflow.com/q/42005462
- if (is.fail() &&
- (std::fabs(dest) == (std::numeric_limits<FloatType>::min)() ||
- std::fpclassify(dest) == FP_SUBNORMAL)) {
- is.clear(is.rdstate() & (~std::ios_base::failbit));
- }
- return dest;
-}
-
-} // namespace random_internal
+ out << h << out.fill() << l;
+ }
+};
+
+#ifdef ABSL_HAVE_INTRINSIC_INT128
+template <>
+struct stream_u128_helper<__uint128_t> {
+ template <typename IStream>
+ inline __uint128_t read(IStream& in) {
+ uint64_t h = 0;
+ uint64_t l = 0;
+ in >> h >> l;
+ return (static_cast<__uint128_t>(h) << 64) | l;
+ }
+
+ template <typename OStream>
+ inline void write(__uint128_t val, OStream& out) {
+ uint64_t h = static_cast<uint64_t>(val >> 64u);
+ uint64_t l = static_cast<uint64_t>(val);
+ out << h << out.fill() << l;
+ }
+};
+#endif
+
+template <typename FloatType, typename IStream>
+inline FloatType read_floating_point(IStream& is) {
+ static_assert(std::is_floating_point<FloatType>::value, "");
+ FloatType dest;
+ is >> dest;
+ // Parsing a double value may report a subnormal value as an error
+ // despite being able to represent it.
+ // See https://stackoverflow.com/q/52410931/3286653
+ // It may also report an underflow when parsing DOUBLE_MIN as an
+ // ERANGE error, as the parsed value may be smaller than DOUBLE_MIN
+ // and rounded up.
+ // See: https://stackoverflow.com/q/42005462
+ if (is.fail() &&
+ (std::fabs(dest) == (std::numeric_limits<FloatType>::min)() ||
+ std::fpclassify(dest) == FP_SUBNORMAL)) {
+ is.clear(is.rdstate() & (~std::ios_base::failbit));
+ }
+ return dest;
+}
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_IOSTREAM_STATE_SAVER_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_IOSTREAM_STATE_SAVER_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/nanobenchmark.h b/contrib/restricted/abseil-cpp/absl/random/internal/nanobenchmark.h
index 103c05f156..a5097ba27b 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/nanobenchmark.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/nanobenchmark.h
@@ -1,172 +1,172 @@
-// Copyright 2017 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_NANOBENCHMARK_H_
-#define ABSL_RANDOM_INTERNAL_NANOBENCHMARK_H_
-
-// Benchmarks functions of a single integer argument with realistic branch
-// prediction hit rates. Uses a robust estimator to summarize the measurements.
-// The precision is about 0.2%.
-//
-// Examples: see nanobenchmark_test.cc.
-//
-// Background: Microbenchmarks such as http://github.com/google/benchmark
-// can measure elapsed times on the order of a microsecond. Shorter functions
-// are typically measured by repeating them thousands of times and dividing
-// the total elapsed time by this count. Unfortunately, repetition (especially
-// with the same input parameter!) influences the runtime. In time-critical
-// code, it is reasonable to expect warm instruction/data caches and TLBs,
-// but a perfect record of which branches will be taken is unrealistic.
-// Unless the application also repeatedly invokes the measured function with
-// the same parameter, the benchmark is measuring something very different -
-// a best-case result, almost as if the parameter were made a compile-time
-// constant. This may lead to erroneous conclusions about branch-heavy
-// algorithms outperforming branch-free alternatives.
-//
-// Our approach differs in three ways. Adding fences to the timer functions
-// reduces variability due to instruction reordering, improving the timer
-// resolution to about 40 CPU cycles. However, shorter functions must still
-// be invoked repeatedly. For more realistic branch prediction performance,
-// we vary the input parameter according to a user-specified distribution.
-// Thus, instead of VaryInputs(Measure(Repeat(func))), we change the
-// loop nesting to Measure(Repeat(VaryInputs(func))). We also estimate the
-// central tendency of the measurement samples with the "half sample mode",
-// which is more robust to outliers and skewed data than the mean or median.
-
-// NOTE: for compatibility with multiple translation units compiled with
-// distinct flags, avoid #including headers that define functions.
-
-#include <stddef.h>
-#include <stdint.h>
-
+// Copyright 2017 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_NANOBENCHMARK_H_
+#define ABSL_RANDOM_INTERNAL_NANOBENCHMARK_H_
+
+// Benchmarks functions of a single integer argument with realistic branch
+// prediction hit rates. Uses a robust estimator to summarize the measurements.
+// The precision is about 0.2%.
+//
+// Examples: see nanobenchmark_test.cc.
+//
+// Background: Microbenchmarks such as http://github.com/google/benchmark
+// can measure elapsed times on the order of a microsecond. Shorter functions
+// are typically measured by repeating them thousands of times and dividing
+// the total elapsed time by this count. Unfortunately, repetition (especially
+// with the same input parameter!) influences the runtime. In time-critical
+// code, it is reasonable to expect warm instruction/data caches and TLBs,
+// but a perfect record of which branches will be taken is unrealistic.
+// Unless the application also repeatedly invokes the measured function with
+// the same parameter, the benchmark is measuring something very different -
+// a best-case result, almost as if the parameter were made a compile-time
+// constant. This may lead to erroneous conclusions about branch-heavy
+// algorithms outperforming branch-free alternatives.
+//
+// Our approach differs in three ways. Adding fences to the timer functions
+// reduces variability due to instruction reordering, improving the timer
+// resolution to about 40 CPU cycles. However, shorter functions must still
+// be invoked repeatedly. For more realistic branch prediction performance,
+// we vary the input parameter according to a user-specified distribution.
+// Thus, instead of VaryInputs(Measure(Repeat(func))), we change the
+// loop nesting to Measure(Repeat(VaryInputs(func))). We also estimate the
+// central tendency of the measurement samples with the "half sample mode",
+// which is more robust to outliers and skewed data than the mean or median.
+
+// NOTE: for compatibility with multiple translation units compiled with
+// distinct flags, avoid #including headers that define functions.
+
+#include <stddef.h>
+#include <stdint.h>
+
#include "absl/base/config.h"
-namespace absl {
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal_nanobenchmark {
-
-// Input influencing the function being measured (e.g. number of bytes to copy).
-using FuncInput = size_t;
-
-// "Proof of work" returned by Func to ensure the compiler does not elide it.
-using FuncOutput = uint64_t;
-
-// Function to measure: either 1) a captureless lambda or function with two
-// arguments or 2) a lambda with capture, in which case the first argument
-// is reserved for use by MeasureClosure.
-using Func = FuncOutput (*)(const void*, FuncInput);
-
-// Internal parameters that determine precision/resolution/measuring time.
-struct Params {
- // For measuring timer overhead/resolution. Used in a nested loop =>
- // quadratic time, acceptable because we know timer overhead is "low".
- // constexpr because this is used to define array bounds.
- static constexpr size_t kTimerSamples = 256;
-
- // Best-case precision, expressed as a divisor of the timer resolution.
- // Larger => more calls to Func and higher precision.
- size_t precision_divisor = 1024;
-
- // Ratio between full and subset input distribution sizes. Cannot be less
- // than 2; larger values increase measurement time but more faithfully
- // model the given input distribution.
- size_t subset_ratio = 2;
-
- // Together with the estimated Func duration, determines how many times to
- // call Func before checking the sample variability. Larger values increase
- // measurement time, memory/cache use and precision.
- double seconds_per_eval = 4E-3;
-
- // The minimum number of samples before estimating the central tendency.
- size_t min_samples_per_eval = 7;
-
- // The mode is better than median for estimating the central tendency of
- // skewed/fat-tailed distributions, but it requires sufficient samples
- // relative to the width of half-ranges.
- size_t min_mode_samples = 64;
-
- // Maximum permissible variability (= median absolute deviation / center).
- double target_rel_mad = 0.002;
-
- // Abort after this many evals without reaching target_rel_mad. This
- // prevents infinite loops.
- size_t max_evals = 9;
-
- // Retry the measure loop up to this many times.
- size_t max_measure_retries = 2;
-
- // Whether to print additional statistics to stdout.
- bool verbose = true;
-};
-
-// Measurement result for each unique input.
-struct Result {
- FuncInput input;
-
- // Robust estimate (mode or median) of duration.
- float ticks;
-
- // Measure of variability (median absolute deviation relative to "ticks").
- float variability;
-};
-
-// Ensures the thread is running on the specified cpu, and no others.
-// Reduces noise due to desynchronized socket RDTSC and context switches.
-// If "cpu" is negative, pin to the currently running core.
-void PinThreadToCPU(const int cpu = -1);
-
-// Returns tick rate, useful for converting measurements to seconds. Invariant
-// means the tick counter frequency is independent of CPU throttling or sleep.
-// This call may be expensive, callers should cache the result.
-double InvariantTicksPerSecond();
-
-// Precisely measures the number of ticks elapsed when calling "func" with the
-// given inputs, shuffled to ensure realistic branch prediction hit rates.
-//
-// "func" returns a 'proof of work' to ensure its computations are not elided.
-// "arg" is passed to Func, or reserved for internal use by MeasureClosure.
-// "inputs" is an array of "num_inputs" (not necessarily unique) arguments to
-// "func". The values should be chosen to maximize coverage of "func". This
-// represents a distribution, so a value's frequency should reflect its
-// probability in the real application. Order does not matter; for example, a
-// uniform distribution over [0, 4) could be represented as {3,0,2,1}.
-// Returns how many Result were written to "results": one per unique input, or
-// zero if the measurement failed (an error message goes to stderr).
-size_t Measure(const Func func, const void* arg, const FuncInput* inputs,
- const size_t num_inputs, Result* results,
- const Params& p = Params());
-
-// Calls operator() of the given closure (lambda function).
-template <class Closure>
-static FuncOutput CallClosure(const void* f, const FuncInput input) {
- return (*reinterpret_cast<const Closure*>(f))(input);
-}
-
-// Same as Measure, except "closure" is typically a lambda function of
-// FuncInput -> FuncOutput with a capture list.
-template <class Closure>
-static inline size_t MeasureClosure(const Closure& closure,
- const FuncInput* inputs,
- const size_t num_inputs, Result* results,
- const Params& p = Params()) {
- return Measure(reinterpret_cast<Func>(&CallClosure<Closure>),
- reinterpret_cast<const void*>(&closure), inputs, num_inputs,
- results, p);
-}
-
-} // namespace random_internal_nanobenchmark
+namespace random_internal_nanobenchmark {
+
+// Input influencing the function being measured (e.g. number of bytes to copy).
+using FuncInput = size_t;
+
+// "Proof of work" returned by Func to ensure the compiler does not elide it.
+using FuncOutput = uint64_t;
+
+// Function to measure: either 1) a captureless lambda or function with two
+// arguments or 2) a lambda with capture, in which case the first argument
+// is reserved for use by MeasureClosure.
+using Func = FuncOutput (*)(const void*, FuncInput);
+
+// Internal parameters that determine precision/resolution/measuring time.
+struct Params {
+ // For measuring timer overhead/resolution. Used in a nested loop =>
+ // quadratic time, acceptable because we know timer overhead is "low".
+ // constexpr because this is used to define array bounds.
+ static constexpr size_t kTimerSamples = 256;
+
+ // Best-case precision, expressed as a divisor of the timer resolution.
+ // Larger => more calls to Func and higher precision.
+ size_t precision_divisor = 1024;
+
+ // Ratio between full and subset input distribution sizes. Cannot be less
+ // than 2; larger values increase measurement time but more faithfully
+ // model the given input distribution.
+ size_t subset_ratio = 2;
+
+ // Together with the estimated Func duration, determines how many times to
+ // call Func before checking the sample variability. Larger values increase
+ // measurement time, memory/cache use and precision.
+ double seconds_per_eval = 4E-3;
+
+ // The minimum number of samples before estimating the central tendency.
+ size_t min_samples_per_eval = 7;
+
+ // The mode is better than median for estimating the central tendency of
+ // skewed/fat-tailed distributions, but it requires sufficient samples
+ // relative to the width of half-ranges.
+ size_t min_mode_samples = 64;
+
+ // Maximum permissible variability (= median absolute deviation / center).
+ double target_rel_mad = 0.002;
+
+ // Abort after this many evals without reaching target_rel_mad. This
+ // prevents infinite loops.
+ size_t max_evals = 9;
+
+ // Retry the measure loop up to this many times.
+ size_t max_measure_retries = 2;
+
+ // Whether to print additional statistics to stdout.
+ bool verbose = true;
+};
+
+// Measurement result for each unique input.
+struct Result {
+ FuncInput input;
+
+ // Robust estimate (mode or median) of duration.
+ float ticks;
+
+ // Measure of variability (median absolute deviation relative to "ticks").
+ float variability;
+};
+
+// Ensures the thread is running on the specified cpu, and no others.
+// Reduces noise due to desynchronized socket RDTSC and context switches.
+// If "cpu" is negative, pin to the currently running core.
+void PinThreadToCPU(const int cpu = -1);
+
+// Returns tick rate, useful for converting measurements to seconds. Invariant
+// means the tick counter frequency is independent of CPU throttling or sleep.
+// This call may be expensive, callers should cache the result.
+double InvariantTicksPerSecond();
+
+// Precisely measures the number of ticks elapsed when calling "func" with the
+// given inputs, shuffled to ensure realistic branch prediction hit rates.
+//
+// "func" returns a 'proof of work' to ensure its computations are not elided.
+// "arg" is passed to Func, or reserved for internal use by MeasureClosure.
+// "inputs" is an array of "num_inputs" (not necessarily unique) arguments to
+// "func". The values should be chosen to maximize coverage of "func". This
+// represents a distribution, so a value's frequency should reflect its
+// probability in the real application. Order does not matter; for example, a
+// uniform distribution over [0, 4) could be represented as {3,0,2,1}.
+// Returns how many Result were written to "results": one per unique input, or
+// zero if the measurement failed (an error message goes to stderr).
+size_t Measure(const Func func, const void* arg, const FuncInput* inputs,
+ const size_t num_inputs, Result* results,
+ const Params& p = Params());
+
+// Calls operator() of the given closure (lambda function).
+template <class Closure>
+static FuncOutput CallClosure(const void* f, const FuncInput input) {
+ return (*reinterpret_cast<const Closure*>(f))(input);
+}
+
+// Same as Measure, except "closure" is typically a lambda function of
+// FuncInput -> FuncOutput with a capture list.
+template <class Closure>
+static inline size_t MeasureClosure(const Closure& closure,
+ const FuncInput* inputs,
+ const size_t num_inputs, Result* results,
+ const Params& p = Params()) {
+ return Measure(reinterpret_cast<Func>(&CallClosure<Closure>),
+ reinterpret_cast<const void*>(&closure), inputs, num_inputs,
+ results, p);
+}
+
+} // namespace random_internal_nanobenchmark
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_NANOBENCHMARK_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_NANOBENCHMARK_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/nonsecure_base.h b/contrib/restricted/abseil-cpp/absl/random/internal/nonsecure_base.h
index 2635b75d70..730fa2ea12 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/nonsecure_base.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/nonsecure_base.h
@@ -1,150 +1,150 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_NONSECURE_BASE_H_
-#define ABSL_RANDOM_INTERNAL_NONSECURE_BASE_H_
-
-#include <algorithm>
-#include <cstdint>
-#include <iostream>
-#include <iterator>
-#include <random>
-#include <string>
-#include <type_traits>
-#include <vector>
-
-#include "absl/base/macros.h"
-#include "absl/meta/type_traits.h"
-#include "absl/random/internal/pool_urbg.h"
-#include "absl/random/internal/salted_seed_seq.h"
-#include "absl/random/internal/seed_material.h"
-#include "absl/types/optional.h"
-#include "absl/types/span.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_NONSECURE_BASE_H_
+#define ABSL_RANDOM_INTERNAL_NONSECURE_BASE_H_
+
+#include <algorithm>
+#include <cstdint>
+#include <iostream>
+#include <iterator>
+#include <random>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#include "absl/base/macros.h"
+#include "absl/meta/type_traits.h"
+#include "absl/random/internal/pool_urbg.h"
+#include "absl/random/internal/salted_seed_seq.h"
+#include "absl/random/internal/seed_material.h"
+#include "absl/types/optional.h"
+#include "absl/types/span.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// Each instance of NonsecureURBGBase<URBG> will be seeded by variates produced
-// by a thread-unique URBG-instance.
-template <typename URBG>
-class NonsecureURBGBase {
- public:
- using result_type = typename URBG::result_type;
-
- // Default constructor
- NonsecureURBGBase() : urbg_(ConstructURBG()) {}
-
- // Copy disallowed, move allowed.
- NonsecureURBGBase(const NonsecureURBGBase&) = delete;
- NonsecureURBGBase& operator=(const NonsecureURBGBase&) = delete;
- NonsecureURBGBase(NonsecureURBGBase&&) = default;
- NonsecureURBGBase& operator=(NonsecureURBGBase&&) = default;
-
- // Constructor using a seed
- template <class SSeq, typename = typename absl::enable_if_t<
- !std::is_same<SSeq, NonsecureURBGBase>::value>>
- explicit NonsecureURBGBase(SSeq&& seq)
- : urbg_(ConstructURBG(std::forward<SSeq>(seq))) {}
-
- // Note: on MSVC, min() or max() can be interpreted as MIN() or MAX(), so we
- // enclose min() or max() in parens as (min)() and (max)().
- // Additionally, clang-format requires no space before this construction.
-
- // NonsecureURBGBase::min()
- static constexpr result_type(min)() { return (URBG::min)(); }
-
- // NonsecureURBGBase::max()
- static constexpr result_type(max)() { return (URBG::max)(); }
-
- // NonsecureURBGBase::operator()()
- result_type operator()() { return urbg_(); }
-
- // NonsecureURBGBase::discard()
- void discard(unsigned long long values) { // NOLINT(runtime/int)
- urbg_.discard(values);
- }
-
- bool operator==(const NonsecureURBGBase& other) const {
- return urbg_ == other.urbg_;
- }
-
- bool operator!=(const NonsecureURBGBase& other) const {
- return !(urbg_ == other.urbg_);
- }
-
- private:
- // Seeder is a custom seed sequence type where generate() fills the provided
- // buffer via the RandenPool entropy source.
- struct Seeder {
- using result_type = uint32_t;
-
- size_t size() { return 0; }
-
- template <typename OutIterator>
- void param(OutIterator) const {}
-
- template <typename RandomAccessIterator>
- void generate(RandomAccessIterator begin, RandomAccessIterator end) {
- if (begin != end) {
- // begin, end must be random access iterators assignable from uint32_t.
- generate_impl(
- std::integral_constant<bool, sizeof(*begin) == sizeof(uint32_t)>{},
- begin, end);
- }
- }
-
- // Commonly, generate is invoked with a pointer to a buffer which
- // can be cast to a uint32_t.
- template <typename RandomAccessIterator>
- void generate_impl(std::integral_constant<bool, true>,
- RandomAccessIterator begin, RandomAccessIterator end) {
- auto buffer = absl::MakeSpan(begin, end);
- auto target = absl::MakeSpan(reinterpret_cast<uint32_t*>(buffer.data()),
- buffer.size());
- RandenPool<uint32_t>::Fill(target);
- }
-
- // The non-uint32_t case should be uncommon, and involves an extra copy,
- // filling the uint32_t buffer and then mixing into the output.
- template <typename RandomAccessIterator>
- void generate_impl(std::integral_constant<bool, false>,
- RandomAccessIterator begin, RandomAccessIterator end) {
- const size_t n = std::distance(begin, end);
- absl::InlinedVector<uint32_t, 8> data(n, 0);
- RandenPool<uint32_t>::Fill(absl::MakeSpan(data.begin(), data.end()));
- std::copy(std::begin(data), std::end(data), begin);
- }
- };
-
- static URBG ConstructURBG() {
- Seeder seeder;
- return URBG(seeder);
- }
-
- template <typename SSeq>
- static URBG ConstructURBG(SSeq&& seq) { // NOLINT(runtime/references)
- auto salted_seq =
- random_internal::MakeSaltedSeedSeq(std::forward<SSeq>(seq));
- return URBG(salted_seq);
- }
-
- URBG urbg_;
-};
-
-} // namespace random_internal
+namespace random_internal {
+
+// Each instance of NonsecureURBGBase<URBG> will be seeded by variates produced
+// by a thread-unique URBG-instance.
+template <typename URBG>
+class NonsecureURBGBase {
+ public:
+ using result_type = typename URBG::result_type;
+
+ // Default constructor
+ NonsecureURBGBase() : urbg_(ConstructURBG()) {}
+
+ // Copy disallowed, move allowed.
+ NonsecureURBGBase(const NonsecureURBGBase&) = delete;
+ NonsecureURBGBase& operator=(const NonsecureURBGBase&) = delete;
+ NonsecureURBGBase(NonsecureURBGBase&&) = default;
+ NonsecureURBGBase& operator=(NonsecureURBGBase&&) = default;
+
+ // Constructor using a seed
+ template <class SSeq, typename = typename absl::enable_if_t<
+ !std::is_same<SSeq, NonsecureURBGBase>::value>>
+ explicit NonsecureURBGBase(SSeq&& seq)
+ : urbg_(ConstructURBG(std::forward<SSeq>(seq))) {}
+
+ // Note: on MSVC, min() or max() can be interpreted as MIN() or MAX(), so we
+ // enclose min() or max() in parens as (min)() and (max)().
+ // Additionally, clang-format requires no space before this construction.
+
+ // NonsecureURBGBase::min()
+ static constexpr result_type(min)() { return (URBG::min)(); }
+
+ // NonsecureURBGBase::max()
+ static constexpr result_type(max)() { return (URBG::max)(); }
+
+ // NonsecureURBGBase::operator()()
+ result_type operator()() { return urbg_(); }
+
+ // NonsecureURBGBase::discard()
+ void discard(unsigned long long values) { // NOLINT(runtime/int)
+ urbg_.discard(values);
+ }
+
+ bool operator==(const NonsecureURBGBase& other) const {
+ return urbg_ == other.urbg_;
+ }
+
+ bool operator!=(const NonsecureURBGBase& other) const {
+ return !(urbg_ == other.urbg_);
+ }
+
+ private:
+ // Seeder is a custom seed sequence type where generate() fills the provided
+ // buffer via the RandenPool entropy source.
+ struct Seeder {
+ using result_type = uint32_t;
+
+ size_t size() { return 0; }
+
+ template <typename OutIterator>
+ void param(OutIterator) const {}
+
+ template <typename RandomAccessIterator>
+ void generate(RandomAccessIterator begin, RandomAccessIterator end) {
+ if (begin != end) {
+ // begin, end must be random access iterators assignable from uint32_t.
+ generate_impl(
+ std::integral_constant<bool, sizeof(*begin) == sizeof(uint32_t)>{},
+ begin, end);
+ }
+ }
+
+ // Commonly, generate is invoked with a pointer to a buffer which
+ // can be cast to a uint32_t.
+ template <typename RandomAccessIterator>
+ void generate_impl(std::integral_constant<bool, true>,
+ RandomAccessIterator begin, RandomAccessIterator end) {
+ auto buffer = absl::MakeSpan(begin, end);
+ auto target = absl::MakeSpan(reinterpret_cast<uint32_t*>(buffer.data()),
+ buffer.size());
+ RandenPool<uint32_t>::Fill(target);
+ }
+
+ // The non-uint32_t case should be uncommon, and involves an extra copy,
+ // filling the uint32_t buffer and then mixing into the output.
+ template <typename RandomAccessIterator>
+ void generate_impl(std::integral_constant<bool, false>,
+ RandomAccessIterator begin, RandomAccessIterator end) {
+ const size_t n = std::distance(begin, end);
+ absl::InlinedVector<uint32_t, 8> data(n, 0);
+ RandenPool<uint32_t>::Fill(absl::MakeSpan(data.begin(), data.end()));
+ std::copy(std::begin(data), std::end(data), begin);
+ }
+ };
+
+ static URBG ConstructURBG() {
+ Seeder seeder;
+ return URBG(seeder);
+ }
+
+ template <typename SSeq>
+ static URBG ConstructURBG(SSeq&& seq) { // NOLINT(runtime/references)
+ auto salted_seq =
+ random_internal::MakeSaltedSeedSeq(std::forward<SSeq>(seq));
+ return URBG(salted_seq);
+ }
+
+ URBG urbg_;
+};
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_NONSECURE_BASE_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_NONSECURE_BASE_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/pcg_engine.h b/contrib/restricted/abseil-cpp/absl/random/internal/pcg_engine.h
index 5a8340020e..8efaf2e09a 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/pcg_engine.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/pcg_engine.h
@@ -1,308 +1,308 @@
-// Copyright 2018 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_
-#define ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_
-
-#include <type_traits>
-
-#include "absl/base/config.h"
-#include "absl/meta/type_traits.h"
+// Copyright 2018 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_
+#define ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_
+
+#include <type_traits>
+
+#include "absl/base/config.h"
+#include "absl/meta/type_traits.h"
#include "absl/numeric/bits.h"
-#include "absl/numeric/int128.h"
-#include "absl/random/internal/fastmath.h"
-#include "absl/random/internal/iostream_state_saver.h"
-
-namespace absl {
+#include "absl/numeric/int128.h"
+#include "absl/random/internal/fastmath.h"
+#include "absl/random/internal/iostream_state_saver.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// pcg_engine is a simplified implementation of Melissa O'Neil's PCG engine in
-// C++. PCG combines a linear congruential generator (LCG) with output state
-// mixing functions to generate each random variate. pcg_engine supports only a
-// single sequence (oneseq), and does not support streams.
-//
-// pcg_engine is parameterized by two types:
-// Params, which provides the multiplier and increment values;
-// Mix, which mixes the state into the result.
-//
-template <typename Params, typename Mix>
-class pcg_engine {
- static_assert(std::is_same<typename Params::state_type,
- typename Mix::state_type>::value,
- "Class-template absl::pcg_engine must be parameterized by "
- "Params and Mix with identical state_type");
-
- static_assert(std::is_unsigned<typename Mix::result_type>::value,
- "Class-template absl::pcg_engine must be parameterized by "
- "an unsigned Mix::result_type");
-
- using params_type = Params;
- using mix_type = Mix;
- using state_type = typename Mix::state_type;
-
- public:
- // C++11 URBG interface:
- using result_type = typename Mix::result_type;
-
- static constexpr result_type(min)() {
- return (std::numeric_limits<result_type>::min)();
- }
-
- static constexpr result_type(max)() {
- return (std::numeric_limits<result_type>::max)();
- }
-
- explicit pcg_engine(uint64_t seed_value = 0) { seed(seed_value); }
-
- template <class SeedSequence,
- typename = typename absl::enable_if_t<
- !std::is_same<SeedSequence, pcg_engine>::value>>
- explicit pcg_engine(SeedSequence&& seq) {
- seed(seq);
- }
-
- pcg_engine(const pcg_engine&) = default;
- pcg_engine& operator=(const pcg_engine&) = default;
- pcg_engine(pcg_engine&&) = default;
- pcg_engine& operator=(pcg_engine&&) = default;
-
- result_type operator()() {
- // Advance the LCG state, always using the new value to generate the output.
- state_ = lcg(state_);
- return Mix{}(state_);
- }
-
- void seed(uint64_t seed_value = 0) {
- state_type tmp = seed_value;
- state_ = lcg(tmp + Params::increment());
- }
-
- template <class SeedSequence>
- typename absl::enable_if_t<
- !std::is_convertible<SeedSequence, uint64_t>::value, void>
- seed(SeedSequence&& seq) {
- reseed(seq);
- }
-
- void discard(uint64_t count) { state_ = advance(state_, count); }
-
- bool operator==(const pcg_engine& other) const {
- return state_ == other.state_;
- }
-
- bool operator!=(const pcg_engine& other) const { return !(*this == other); }
-
- template <class CharT, class Traits>
- friend typename absl::enable_if_t<(sizeof(state_type) == 16),
- std::basic_ostream<CharT, Traits>&>
- operator<<(
- std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
- const pcg_engine& engine) {
- auto saver = random_internal::make_ostream_state_saver(os);
- random_internal::stream_u128_helper<state_type> helper;
- helper.write(pcg_engine::params_type::multiplier(), os);
- os << os.fill();
- helper.write(pcg_engine::params_type::increment(), os);
- os << os.fill();
- helper.write(engine.state_, os);
- return os;
- }
-
- template <class CharT, class Traits>
- friend typename absl::enable_if_t<(sizeof(state_type) <= 8),
- std::basic_ostream<CharT, Traits>&>
- operator<<(
- std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
- const pcg_engine& engine) {
- auto saver = random_internal::make_ostream_state_saver(os);
- os << pcg_engine::params_type::multiplier() << os.fill();
- os << pcg_engine::params_type::increment() << os.fill();
- os << engine.state_;
- return os;
- }
-
- template <class CharT, class Traits>
- friend typename absl::enable_if_t<(sizeof(state_type) == 16),
- std::basic_istream<CharT, Traits>&>
- operator>>(
- std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
- pcg_engine& engine) { // NOLINT(runtime/references)
- random_internal::stream_u128_helper<state_type> helper;
- auto mult = helper.read(is);
- auto inc = helper.read(is);
- auto tmp = helper.read(is);
- if (mult != pcg_engine::params_type::multiplier() ||
- inc != pcg_engine::params_type::increment()) {
- // signal failure by setting the failbit.
- is.setstate(is.rdstate() | std::ios_base::failbit);
- }
- if (!is.fail()) {
- engine.state_ = tmp;
- }
- return is;
- }
-
- template <class CharT, class Traits>
- friend typename absl::enable_if_t<(sizeof(state_type) <= 8),
- std::basic_istream<CharT, Traits>&>
- operator>>(
- std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
- pcg_engine& engine) { // NOLINT(runtime/references)
- state_type mult{}, inc{}, tmp{};
- is >> mult >> inc >> tmp;
- if (mult != pcg_engine::params_type::multiplier() ||
- inc != pcg_engine::params_type::increment()) {
- // signal failure by setting the failbit.
- is.setstate(is.rdstate() | std::ios_base::failbit);
- }
- if (!is.fail()) {
- engine.state_ = tmp;
- }
- return is;
- }
-
- private:
- state_type state_;
-
- // Returns the linear-congruential generator next state.
- static inline constexpr state_type lcg(state_type s) {
- return s * Params::multiplier() + Params::increment();
- }
-
- // Returns the linear-congruential arbitrary seek state.
- inline state_type advance(state_type s, uint64_t n) const {
- state_type mult = Params::multiplier();
- state_type inc = Params::increment();
- state_type m = 1;
- state_type i = 0;
- while (n > 0) {
- if (n & 1) {
- m *= mult;
- i = i * mult + inc;
- }
- inc = (mult + 1) * inc;
- mult *= mult;
- n >>= 1;
- }
- return m * s + i;
- }
-
- template <class SeedSequence>
- void reseed(SeedSequence& seq) {
- using sequence_result_type = typename SeedSequence::result_type;
- constexpr size_t kBufferSize =
- sizeof(state_type) / sizeof(sequence_result_type);
- sequence_result_type buffer[kBufferSize];
- seq.generate(std::begin(buffer), std::end(buffer));
- // Convert the seed output to a single state value.
- state_type tmp = buffer[0];
- for (size_t i = 1; i < kBufferSize; i++) {
- tmp <<= (sizeof(sequence_result_type) * 8);
- tmp |= buffer[i];
- }
- state_ = lcg(tmp + params_type::increment());
- }
-};
-
-// Parameterized implementation of the PCG 128-bit oneseq state.
-// This provides state_type, multiplier, and increment for pcg_engine.
-template <uint64_t kMultA, uint64_t kMultB, uint64_t kIncA, uint64_t kIncB>
-class pcg128_params {
- public:
-#if ABSL_HAVE_INTRINSIC_INT128
- using state_type = __uint128_t;
- static inline constexpr state_type make_u128(uint64_t a, uint64_t b) {
- return (static_cast<__uint128_t>(a) << 64) | b;
- }
-#else
- using state_type = absl::uint128;
- static inline constexpr state_type make_u128(uint64_t a, uint64_t b) {
- return absl::MakeUint128(a, b);
- }
-#endif
-
- static inline constexpr state_type multiplier() {
- return make_u128(kMultA, kMultB);
- }
- static inline constexpr state_type increment() {
- return make_u128(kIncA, kIncB);
- }
-};
-
-// Implementation of the PCG xsl_rr_128_64 128-bit mixing function, which
-// accepts an input of state_type and mixes it into an output of result_type.
-struct pcg_xsl_rr_128_64 {
-#if ABSL_HAVE_INTRINSIC_INT128
- using state_type = __uint128_t;
-#else
- using state_type = absl::uint128;
-#endif
- using result_type = uint64_t;
-
- inline uint64_t operator()(state_type state) {
- // This is equivalent to the xsl_rr_128_64 mixing function.
-#if ABSL_HAVE_INTRINSIC_INT128
- uint64_t rotate = static_cast<uint64_t>(state >> 122u);
- state ^= state >> 64;
- uint64_t s = static_cast<uint64_t>(state);
-#else
- uint64_t h = Uint128High64(state);
- uint64_t rotate = h >> 58u;
- uint64_t s = Uint128Low64(state) ^ h;
-#endif
+namespace random_internal {
+
+// pcg_engine is a simplified implementation of Melissa O'Neil's PCG engine in
+// C++. PCG combines a linear congruential generator (LCG) with output state
+// mixing functions to generate each random variate. pcg_engine supports only a
+// single sequence (oneseq), and does not support streams.
+//
+// pcg_engine is parameterized by two types:
+// Params, which provides the multiplier and increment values;
+// Mix, which mixes the state into the result.
+//
+template <typename Params, typename Mix>
+class pcg_engine {
+ static_assert(std::is_same<typename Params::state_type,
+ typename Mix::state_type>::value,
+ "Class-template absl::pcg_engine must be parameterized by "
+ "Params and Mix with identical state_type");
+
+ static_assert(std::is_unsigned<typename Mix::result_type>::value,
+ "Class-template absl::pcg_engine must be parameterized by "
+ "an unsigned Mix::result_type");
+
+ using params_type = Params;
+ using mix_type = Mix;
+ using state_type = typename Mix::state_type;
+
+ public:
+ // C++11 URBG interface:
+ using result_type = typename Mix::result_type;
+
+ static constexpr result_type(min)() {
+ return (std::numeric_limits<result_type>::min)();
+ }
+
+ static constexpr result_type(max)() {
+ return (std::numeric_limits<result_type>::max)();
+ }
+
+ explicit pcg_engine(uint64_t seed_value = 0) { seed(seed_value); }
+
+ template <class SeedSequence,
+ typename = typename absl::enable_if_t<
+ !std::is_same<SeedSequence, pcg_engine>::value>>
+ explicit pcg_engine(SeedSequence&& seq) {
+ seed(seq);
+ }
+
+ pcg_engine(const pcg_engine&) = default;
+ pcg_engine& operator=(const pcg_engine&) = default;
+ pcg_engine(pcg_engine&&) = default;
+ pcg_engine& operator=(pcg_engine&&) = default;
+
+ result_type operator()() {
+ // Advance the LCG state, always using the new value to generate the output.
+ state_ = lcg(state_);
+ return Mix{}(state_);
+ }
+
+ void seed(uint64_t seed_value = 0) {
+ state_type tmp = seed_value;
+ state_ = lcg(tmp + Params::increment());
+ }
+
+ template <class SeedSequence>
+ typename absl::enable_if_t<
+ !std::is_convertible<SeedSequence, uint64_t>::value, void>
+ seed(SeedSequence&& seq) {
+ reseed(seq);
+ }
+
+ void discard(uint64_t count) { state_ = advance(state_, count); }
+
+ bool operator==(const pcg_engine& other) const {
+ return state_ == other.state_;
+ }
+
+ bool operator!=(const pcg_engine& other) const { return !(*this == other); }
+
+ template <class CharT, class Traits>
+ friend typename absl::enable_if_t<(sizeof(state_type) == 16),
+ std::basic_ostream<CharT, Traits>&>
+ operator<<(
+ std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
+ const pcg_engine& engine) {
+ auto saver = random_internal::make_ostream_state_saver(os);
+ random_internal::stream_u128_helper<state_type> helper;
+ helper.write(pcg_engine::params_type::multiplier(), os);
+ os << os.fill();
+ helper.write(pcg_engine::params_type::increment(), os);
+ os << os.fill();
+ helper.write(engine.state_, os);
+ return os;
+ }
+
+ template <class CharT, class Traits>
+ friend typename absl::enable_if_t<(sizeof(state_type) <= 8),
+ std::basic_ostream<CharT, Traits>&>
+ operator<<(
+ std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
+ const pcg_engine& engine) {
+ auto saver = random_internal::make_ostream_state_saver(os);
+ os << pcg_engine::params_type::multiplier() << os.fill();
+ os << pcg_engine::params_type::increment() << os.fill();
+ os << engine.state_;
+ return os;
+ }
+
+ template <class CharT, class Traits>
+ friend typename absl::enable_if_t<(sizeof(state_type) == 16),
+ std::basic_istream<CharT, Traits>&>
+ operator>>(
+ std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
+ pcg_engine& engine) { // NOLINT(runtime/references)
+ random_internal::stream_u128_helper<state_type> helper;
+ auto mult = helper.read(is);
+ auto inc = helper.read(is);
+ auto tmp = helper.read(is);
+ if (mult != pcg_engine::params_type::multiplier() ||
+ inc != pcg_engine::params_type::increment()) {
+ // signal failure by setting the failbit.
+ is.setstate(is.rdstate() | std::ios_base::failbit);
+ }
+ if (!is.fail()) {
+ engine.state_ = tmp;
+ }
+ return is;
+ }
+
+ template <class CharT, class Traits>
+ friend typename absl::enable_if_t<(sizeof(state_type) <= 8),
+ std::basic_istream<CharT, Traits>&>
+ operator>>(
+ std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
+ pcg_engine& engine) { // NOLINT(runtime/references)
+ state_type mult{}, inc{}, tmp{};
+ is >> mult >> inc >> tmp;
+ if (mult != pcg_engine::params_type::multiplier() ||
+ inc != pcg_engine::params_type::increment()) {
+ // signal failure by setting the failbit.
+ is.setstate(is.rdstate() | std::ios_base::failbit);
+ }
+ if (!is.fail()) {
+ engine.state_ = tmp;
+ }
+ return is;
+ }
+
+ private:
+ state_type state_;
+
+ // Returns the linear-congruential generator next state.
+ static inline constexpr state_type lcg(state_type s) {
+ return s * Params::multiplier() + Params::increment();
+ }
+
+ // Returns the linear-congruential arbitrary seek state.
+ inline state_type advance(state_type s, uint64_t n) const {
+ state_type mult = Params::multiplier();
+ state_type inc = Params::increment();
+ state_type m = 1;
+ state_type i = 0;
+ while (n > 0) {
+ if (n & 1) {
+ m *= mult;
+ i = i * mult + inc;
+ }
+ inc = (mult + 1) * inc;
+ mult *= mult;
+ n >>= 1;
+ }
+ return m * s + i;
+ }
+
+ template <class SeedSequence>
+ void reseed(SeedSequence& seq) {
+ using sequence_result_type = typename SeedSequence::result_type;
+ constexpr size_t kBufferSize =
+ sizeof(state_type) / sizeof(sequence_result_type);
+ sequence_result_type buffer[kBufferSize];
+ seq.generate(std::begin(buffer), std::end(buffer));
+ // Convert the seed output to a single state value.
+ state_type tmp = buffer[0];
+ for (size_t i = 1; i < kBufferSize; i++) {
+ tmp <<= (sizeof(sequence_result_type) * 8);
+ tmp |= buffer[i];
+ }
+ state_ = lcg(tmp + params_type::increment());
+ }
+};
+
+// Parameterized implementation of the PCG 128-bit oneseq state.
+// This provides state_type, multiplier, and increment for pcg_engine.
+template <uint64_t kMultA, uint64_t kMultB, uint64_t kIncA, uint64_t kIncB>
+class pcg128_params {
+ public:
+#if ABSL_HAVE_INTRINSIC_INT128
+ using state_type = __uint128_t;
+ static inline constexpr state_type make_u128(uint64_t a, uint64_t b) {
+ return (static_cast<__uint128_t>(a) << 64) | b;
+ }
+#else
+ using state_type = absl::uint128;
+ static inline constexpr state_type make_u128(uint64_t a, uint64_t b) {
+ return absl::MakeUint128(a, b);
+ }
+#endif
+
+ static inline constexpr state_type multiplier() {
+ return make_u128(kMultA, kMultB);
+ }
+ static inline constexpr state_type increment() {
+ return make_u128(kIncA, kIncB);
+ }
+};
+
+// Implementation of the PCG xsl_rr_128_64 128-bit mixing function, which
+// accepts an input of state_type and mixes it into an output of result_type.
+struct pcg_xsl_rr_128_64 {
+#if ABSL_HAVE_INTRINSIC_INT128
+ using state_type = __uint128_t;
+#else
+ using state_type = absl::uint128;
+#endif
+ using result_type = uint64_t;
+
+ inline uint64_t operator()(state_type state) {
+ // This is equivalent to the xsl_rr_128_64 mixing function.
+#if ABSL_HAVE_INTRINSIC_INT128
+ uint64_t rotate = static_cast<uint64_t>(state >> 122u);
+ state ^= state >> 64;
+ uint64_t s = static_cast<uint64_t>(state);
+#else
+ uint64_t h = Uint128High64(state);
+ uint64_t rotate = h >> 58u;
+ uint64_t s = Uint128Low64(state) ^ h;
+#endif
return rotr(s, rotate);
- }
-};
-
-// Parameterized implementation of the PCG 64-bit oneseq state.
-// This provides state_type, multiplier, and increment for pcg_engine.
-template <uint64_t kMult, uint64_t kInc>
-class pcg64_params {
- public:
- using state_type = uint64_t;
- static inline constexpr state_type multiplier() { return kMult; }
- static inline constexpr state_type increment() { return kInc; }
-};
-
-// Implementation of the PCG xsh_rr_64_32 64-bit mixing function, which accepts
-// an input of state_type and mixes it into an output of result_type.
-struct pcg_xsh_rr_64_32 {
- using state_type = uint64_t;
- using result_type = uint32_t;
- inline uint32_t operator()(uint64_t state) {
+ }
+};
+
+// Parameterized implementation of the PCG 64-bit oneseq state.
+// This provides state_type, multiplier, and increment for pcg_engine.
+template <uint64_t kMult, uint64_t kInc>
+class pcg64_params {
+ public:
+ using state_type = uint64_t;
+ static inline constexpr state_type multiplier() { return kMult; }
+ static inline constexpr state_type increment() { return kInc; }
+};
+
+// Implementation of the PCG xsh_rr_64_32 64-bit mixing function, which accepts
+// an input of state_type and mixes it into an output of result_type.
+struct pcg_xsh_rr_64_32 {
+ using state_type = uint64_t;
+ using result_type = uint32_t;
+ inline uint32_t operator()(uint64_t state) {
return rotr(static_cast<uint32_t>(((state >> 18) ^ state) >> 27),
state >> 59);
- }
-};
-
-// Stable pcg_engine implementations:
-// This is a 64-bit generator using 128-bits of state.
-// The output sequence is equivalent to Melissa O'Neil's pcg64_oneseq.
-using pcg64_2018_engine = pcg_engine<
- random_internal::pcg128_params<0x2360ed051fc65da4ull, 0x4385df649fccf645ull,
- 0x5851f42d4c957f2d, 0x14057b7ef767814f>,
- random_internal::pcg_xsl_rr_128_64>;
-
-// This is a 32-bit generator using 64-bits of state.
-// This is equivalent to Melissa O'Neil's pcg32_oneseq.
-using pcg32_2018_engine = pcg_engine<
- random_internal::pcg64_params<0x5851f42d4c957f2dull, 0x14057b7ef767814full>,
- random_internal::pcg_xsh_rr_64_32>;
-
-} // namespace random_internal
+ }
+};
+
+// Stable pcg_engine implementations:
+// This is a 64-bit generator using 128-bits of state.
+// The output sequence is equivalent to Melissa O'Neil's pcg64_oneseq.
+using pcg64_2018_engine = pcg_engine<
+ random_internal::pcg128_params<0x2360ed051fc65da4ull, 0x4385df649fccf645ull,
+ 0x5851f42d4c957f2d, 0x14057b7ef767814f>,
+ random_internal::pcg_xsl_rr_128_64>;
+
+// This is a 32-bit generator using 64-bits of state.
+// This is equivalent to Melissa O'Neil's pcg32_oneseq.
+using pcg32_2018_engine = pcg_engine<
+ random_internal::pcg64_params<0x5851f42d4c957f2dull, 0x14057b7ef767814full>,
+ random_internal::pcg_xsh_rr_64_32>;
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/platform.h b/contrib/restricted/abseil-cpp/absl/random/internal/platform.h
index fcd5d461a7..bbdb4e6208 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/platform.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/platform.h
@@ -1,171 +1,171 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_PLATFORM_H_
-#define ABSL_RANDOM_INTERNAL_PLATFORM_H_
-
-// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate
-// symbols from arbitrary system and other headers, since it may be built
-// with different flags from other targets, using different levels of
-// optimization, potentially introducing ODR violations.
-
-// -----------------------------------------------------------------------------
-// Platform Feature Checks
-// -----------------------------------------------------------------------------
-
-// Currently supported operating systems and associated preprocessor
-// symbols:
-//
-// Linux and Linux-derived __linux__
-// Android __ANDROID__ (implies __linux__)
-// Linux (non-Android) __linux__ && !__ANDROID__
-// Darwin (macOS and iOS) __APPLE__
-// Akaros (http://akaros.org) __ros__
-// Windows _WIN32
-// NaCL __native_client__
-// AsmJS __asmjs__
-// WebAssembly __wasm__
-// Fuchsia __Fuchsia__
-//
-// Note that since Android defines both __ANDROID__ and __linux__, one
-// may probe for either Linux or Android by simply testing for __linux__.
-//
-// NOTE: For __APPLE__ platforms, we use #include <TargetConditionals.h>
-// to distinguish os variants.
-//
-// http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system
-
-#if defined(__APPLE__)
-#include <TargetConditionals.h>
-#endif
-
-// -----------------------------------------------------------------------------
-// Architecture Checks
-// -----------------------------------------------------------------------------
-
-// These preprocessor directives are trying to determine CPU architecture,
-// including necessary headers to support hardware AES.
-//
-// ABSL_ARCH_{X86/PPC/ARM} macros determine the platform.
-#if defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) || \
- defined(_M_X64)
-#define ABSL_ARCH_X86_64
-#elif defined(__i386) || defined(_M_IX86)
-#define ABSL_ARCH_X86_32
-#elif defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64)
-#define ABSL_ARCH_AARCH64
-#elif defined(__arm__) || defined(__ARMEL__) || defined(_M_ARM)
-#define ABSL_ARCH_ARM
-#elif defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \
- defined(__ppc__) || defined(__PPC__)
-#define ABSL_ARCH_PPC
-#else
-// Unsupported architecture.
-// * https://sourceforge.net/p/predef/wiki/Architectures/
-// * https://msdn.microsoft.com/en-us/library/b0084kay.aspx
-// * for gcc, clang: "echo | gcc -E -dM -"
-#endif
-
-// -----------------------------------------------------------------------------
-// Attribute Checks
-// -----------------------------------------------------------------------------
-
-// ABSL_RANDOM_INTERNAL_RESTRICT annotates whether pointers may be considered
-// to be unaliased.
-#if defined(__clang__) || defined(__GNUC__)
-#define ABSL_RANDOM_INTERNAL_RESTRICT __restrict__
-#elif defined(_MSC_VER)
-#define ABSL_RANDOM_INTERNAL_RESTRICT __restrict
-#else
-#define ABSL_RANDOM_INTERNAL_RESTRICT
-#endif
-
-// ABSL_HAVE_ACCELERATED_AES indicates whether the currently active compiler
-// flags (e.g. -maes) allow using hardware accelerated AES instructions, which
-// implies us assuming that the target platform supports them.
-#define ABSL_HAVE_ACCELERATED_AES 0
-
-#if defined(ABSL_ARCH_X86_64)
-
-#if defined(__AES__) || defined(__AVX__)
-#undef ABSL_HAVE_ACCELERATED_AES
-#define ABSL_HAVE_ACCELERATED_AES 1
-#endif
-
-#elif defined(ABSL_ARCH_PPC)
-
-// Rely on VSX and CRYPTO extensions for vcipher on PowerPC.
-#if (defined(__VEC__) || defined(__ALTIVEC__)) && defined(__VSX__) && \
- defined(__CRYPTO__)
-#undef ABSL_HAVE_ACCELERATED_AES
-#define ABSL_HAVE_ACCELERATED_AES 1
-#endif
-
-#elif defined(ABSL_ARCH_ARM) || defined(ABSL_ARCH_AARCH64)
-
-// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0053c/IHI0053C_acle_2_0.pdf
-// Rely on NEON+CRYPTO extensions for ARM.
-#if defined(__ARM_NEON) && defined(__ARM_FEATURE_CRYPTO)
-#undef ABSL_HAVE_ACCELERATED_AES
-#define ABSL_HAVE_ACCELERATED_AES 1
-#endif
-
-#endif
-
-// NaCl does not allow AES.
-#if defined(__native_client__)
-#undef ABSL_HAVE_ACCELERATED_AES
-#define ABSL_HAVE_ACCELERATED_AES 0
-#endif
-
-// ABSL_RANDOM_INTERNAL_AES_DISPATCH indicates whether the currently active
-// platform has, or should use run-time dispatch for selecting the
-// acclerated Randen implementation.
-#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0
-
-#if defined(ABSL_ARCH_X86_64)
-// Dispatch is available on x86_64
-#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
-#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
-#elif defined(__linux__) && defined(ABSL_ARCH_PPC)
-// Or when running linux PPC
-#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
-#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
-#elif defined(__linux__) && defined(ABSL_ARCH_AARCH64)
-// Or when running linux AArch64
-#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
-#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
-#elif defined(__linux__) && defined(ABSL_ARCH_ARM) && (__ARM_ARCH >= 8)
-// Or when running linux ARM v8 or higher.
-// (This captures a lot of Android configurations.)
-#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
-#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
-#endif
-
-// NaCl does not allow dispatch.
-#if defined(__native_client__)
-#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
-#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0
-#endif
-
-// iOS does not support dispatch, even on x86, since applications
-// should be bundled as fat binaries, with a different build tailored for
-// each specific supported platform/architecture.
-#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \
- (defined(TARGET_OS_IPHONE_SIMULATOR) && TARGET_OS_IPHONE_SIMULATOR)
-#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
-#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0
-#endif
-
-#endif // ABSL_RANDOM_INTERNAL_PLATFORM_H_
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_PLATFORM_H_
+#define ABSL_RANDOM_INTERNAL_PLATFORM_H_
+
+// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate
+// symbols from arbitrary system and other headers, since it may be built
+// with different flags from other targets, using different levels of
+// optimization, potentially introducing ODR violations.
+
+// -----------------------------------------------------------------------------
+// Platform Feature Checks
+// -----------------------------------------------------------------------------
+
+// Currently supported operating systems and associated preprocessor
+// symbols:
+//
+// Linux and Linux-derived __linux__
+// Android __ANDROID__ (implies __linux__)
+// Linux (non-Android) __linux__ && !__ANDROID__
+// Darwin (macOS and iOS) __APPLE__
+// Akaros (http://akaros.org) __ros__
+// Windows _WIN32
+// NaCL __native_client__
+// AsmJS __asmjs__
+// WebAssembly __wasm__
+// Fuchsia __Fuchsia__
+//
+// Note that since Android defines both __ANDROID__ and __linux__, one
+// may probe for either Linux or Android by simply testing for __linux__.
+//
+// NOTE: For __APPLE__ platforms, we use #include <TargetConditionals.h>
+// to distinguish os variants.
+//
+// http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system
+
+#if defined(__APPLE__)
+#include <TargetConditionals.h>
+#endif
+
+// -----------------------------------------------------------------------------
+// Architecture Checks
+// -----------------------------------------------------------------------------
+
+// These preprocessor directives are trying to determine CPU architecture,
+// including necessary headers to support hardware AES.
+//
+// ABSL_ARCH_{X86/PPC/ARM} macros determine the platform.
+#if defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) || \
+ defined(_M_X64)
+#define ABSL_ARCH_X86_64
+#elif defined(__i386) || defined(_M_IX86)
+#define ABSL_ARCH_X86_32
+#elif defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64)
+#define ABSL_ARCH_AARCH64
+#elif defined(__arm__) || defined(__ARMEL__) || defined(_M_ARM)
+#define ABSL_ARCH_ARM
+#elif defined(__powerpc64__) || defined(__PPC64__) || defined(__powerpc__) || \
+ defined(__ppc__) || defined(__PPC__)
+#define ABSL_ARCH_PPC
+#else
+// Unsupported architecture.
+// * https://sourceforge.net/p/predef/wiki/Architectures/
+// * https://msdn.microsoft.com/en-us/library/b0084kay.aspx
+// * for gcc, clang: "echo | gcc -E -dM -"
+#endif
+
+// -----------------------------------------------------------------------------
+// Attribute Checks
+// -----------------------------------------------------------------------------
+
+// ABSL_RANDOM_INTERNAL_RESTRICT annotates whether pointers may be considered
+// to be unaliased.
+#if defined(__clang__) || defined(__GNUC__)
+#define ABSL_RANDOM_INTERNAL_RESTRICT __restrict__
+#elif defined(_MSC_VER)
+#define ABSL_RANDOM_INTERNAL_RESTRICT __restrict
+#else
+#define ABSL_RANDOM_INTERNAL_RESTRICT
+#endif
+
+// ABSL_HAVE_ACCELERATED_AES indicates whether the currently active compiler
+// flags (e.g. -maes) allow using hardware accelerated AES instructions, which
+// implies us assuming that the target platform supports them.
+#define ABSL_HAVE_ACCELERATED_AES 0
+
+#if defined(ABSL_ARCH_X86_64)
+
+#if defined(__AES__) || defined(__AVX__)
+#undef ABSL_HAVE_ACCELERATED_AES
+#define ABSL_HAVE_ACCELERATED_AES 1
+#endif
+
+#elif defined(ABSL_ARCH_PPC)
+
+// Rely on VSX and CRYPTO extensions for vcipher on PowerPC.
+#if (defined(__VEC__) || defined(__ALTIVEC__)) && defined(__VSX__) && \
+ defined(__CRYPTO__)
+#undef ABSL_HAVE_ACCELERATED_AES
+#define ABSL_HAVE_ACCELERATED_AES 1
+#endif
+
+#elif defined(ABSL_ARCH_ARM) || defined(ABSL_ARCH_AARCH64)
+
+// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0053c/IHI0053C_acle_2_0.pdf
+// Rely on NEON+CRYPTO extensions for ARM.
+#if defined(__ARM_NEON) && defined(__ARM_FEATURE_CRYPTO)
+#undef ABSL_HAVE_ACCELERATED_AES
+#define ABSL_HAVE_ACCELERATED_AES 1
+#endif
+
+#endif
+
+// NaCl does not allow AES.
+#if defined(__native_client__)
+#undef ABSL_HAVE_ACCELERATED_AES
+#define ABSL_HAVE_ACCELERATED_AES 0
+#endif
+
+// ABSL_RANDOM_INTERNAL_AES_DISPATCH indicates whether the currently active
+// platform has, or should use run-time dispatch for selecting the
+// acclerated Randen implementation.
+#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0
+
+#if defined(ABSL_ARCH_X86_64)
+// Dispatch is available on x86_64
+#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
+#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
+#elif defined(__linux__) && defined(ABSL_ARCH_PPC)
+// Or when running linux PPC
+#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
+#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
+#elif defined(__linux__) && defined(ABSL_ARCH_AARCH64)
+// Or when running linux AArch64
+#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
+#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
+#elif defined(__linux__) && defined(ABSL_ARCH_ARM) && (__ARM_ARCH >= 8)
+// Or when running linux ARM v8 or higher.
+// (This captures a lot of Android configurations.)
+#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
+#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 1
+#endif
+
+// NaCl does not allow dispatch.
+#if defined(__native_client__)
+#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
+#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0
+#endif
+
+// iOS does not support dispatch, even on x86, since applications
+// should be bundled as fat binaries, with a different build tailored for
+// each specific supported platform/architecture.
+#if (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || \
+ (defined(TARGET_OS_IPHONE_SIMULATOR) && TARGET_OS_IPHONE_SIMULATOR)
+#undef ABSL_RANDOM_INTERNAL_AES_DISPATCH
+#define ABSL_RANDOM_INTERNAL_AES_DISPATCH 0
+#endif
+
+#endif // ABSL_RANDOM_INTERNAL_PLATFORM_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.cc b/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.cc
index a715397110..725100a415 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.cc
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.cc
@@ -1,253 +1,253 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/random/internal/pool_urbg.h"
-
-#include <algorithm>
-#include <atomic>
-#include <cstdint>
-#include <cstring>
-#include <iterator>
-
-#include "absl/base/attributes.h"
-#include "absl/base/call_once.h"
-#include "absl/base/config.h"
-#include "absl/base/internal/endian.h"
-#include "absl/base/internal/raw_logging.h"
-#include "absl/base/internal/spinlock.h"
-#include "absl/base/internal/sysinfo.h"
-#include "absl/base/internal/unaligned_access.h"
-#include "absl/base/optimization.h"
-#include "absl/random/internal/randen.h"
-#include "absl/random/internal/seed_material.h"
-#include "absl/random/seed_gen_exception.h"
-
-using absl::base_internal::SpinLock;
-using absl::base_internal::SpinLockHolder;
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/random/internal/pool_urbg.h"
+
+#include <algorithm>
+#include <atomic>
+#include <cstdint>
+#include <cstring>
+#include <iterator>
+
+#include "absl/base/attributes.h"
+#include "absl/base/call_once.h"
+#include "absl/base/config.h"
+#include "absl/base/internal/endian.h"
+#include "absl/base/internal/raw_logging.h"
+#include "absl/base/internal/spinlock.h"
+#include "absl/base/internal/sysinfo.h"
+#include "absl/base/internal/unaligned_access.h"
+#include "absl/base/optimization.h"
+#include "absl/random/internal/randen.h"
+#include "absl/random/internal/seed_material.h"
+#include "absl/random/seed_gen_exception.h"
+
+using absl::base_internal::SpinLock;
+using absl::base_internal::SpinLockHolder;
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-namespace {
-
-// RandenPoolEntry is a thread-safe pseudorandom bit generator, implementing a
-// single generator within a RandenPool<T>. It is an internal implementation
-// detail, and does not aim to conform to [rand.req.urng].
-//
-// NOTE: There are alignment issues when used on ARM, for instance.
-// See the allocation code in PoolAlignedAlloc().
-class RandenPoolEntry {
- public:
- static constexpr size_t kState = RandenTraits::kStateBytes / sizeof(uint32_t);
- static constexpr size_t kCapacity =
- RandenTraits::kCapacityBytes / sizeof(uint32_t);
-
- void Init(absl::Span<const uint32_t> data) {
- SpinLockHolder l(&mu_); // Always uncontested.
- std::copy(data.begin(), data.end(), std::begin(state_));
- next_ = kState;
- }
-
- // Copy bytes into out.
- void Fill(uint8_t* out, size_t bytes) ABSL_LOCKS_EXCLUDED(mu_);
-
- // Returns random bits from the buffer in units of T.
- template <typename T>
- inline T Generate() ABSL_LOCKS_EXCLUDED(mu_);
-
- inline void MaybeRefill() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
- if (next_ >= kState) {
- next_ = kCapacity;
- impl_.Generate(state_);
- }
- }
-
- private:
- // Randen URBG state.
- uint32_t state_[kState] ABSL_GUARDED_BY(mu_); // First to satisfy alignment.
- SpinLock mu_;
- const Randen impl_;
- size_t next_ ABSL_GUARDED_BY(mu_);
-};
-
-template <>
-inline uint8_t RandenPoolEntry::Generate<uint8_t>() {
- SpinLockHolder l(&mu_);
- MaybeRefill();
- return static_cast<uint8_t>(state_[next_++]);
-}
-
-template <>
-inline uint16_t RandenPoolEntry::Generate<uint16_t>() {
- SpinLockHolder l(&mu_);
- MaybeRefill();
- return static_cast<uint16_t>(state_[next_++]);
-}
-
-template <>
-inline uint32_t RandenPoolEntry::Generate<uint32_t>() {
- SpinLockHolder l(&mu_);
- MaybeRefill();
- return state_[next_++];
-}
-
-template <>
-inline uint64_t RandenPoolEntry::Generate<uint64_t>() {
- SpinLockHolder l(&mu_);
- if (next_ >= kState - 1) {
- next_ = kCapacity;
- impl_.Generate(state_);
- }
- auto p = state_ + next_;
- next_ += 2;
-
- uint64_t result;
- std::memcpy(&result, p, sizeof(result));
- return result;
-}
-
-void RandenPoolEntry::Fill(uint8_t* out, size_t bytes) {
- SpinLockHolder l(&mu_);
- while (bytes > 0) {
- MaybeRefill();
- size_t remaining = (kState - next_) * sizeof(state_[0]);
- size_t to_copy = std::min(bytes, remaining);
- std::memcpy(out, &state_[next_], to_copy);
- out += to_copy;
- bytes -= to_copy;
- next_ += (to_copy + sizeof(state_[0]) - 1) / sizeof(state_[0]);
- }
-}
-
-// Number of pooled urbg entries.
-static constexpr int kPoolSize = 8;
-
-// Shared pool entries.
-static absl::once_flag pool_once;
-ABSL_CACHELINE_ALIGNED static RandenPoolEntry* shared_pools[kPoolSize];
-
-// Returns an id in the range [0 ... kPoolSize), which indexes into the
-// pool of random engines.
-//
-// Each thread to access the pool is assigned a sequential ID (without reuse)
-// from the pool-id space; the id is cached in a thread_local variable.
-// This id is assigned based on the arrival-order of the thread to the
-// GetPoolID call; this has no binary, CL, or runtime stability because
-// on subsequent runs the order within the same program may be significantly
-// different. However, as other thread IDs are not assigned sequentially,
-// this is not expected to matter.
-int GetPoolID() {
- static_assert(kPoolSize >= 1,
- "At least one urbg instance is required for PoolURBG");
-
- ABSL_CONST_INIT static std::atomic<int64_t> sequence{0};
-
-#ifdef ABSL_HAVE_THREAD_LOCAL
- static thread_local int my_pool_id = -1;
- if (ABSL_PREDICT_FALSE(my_pool_id < 0)) {
- my_pool_id = (sequence++ % kPoolSize);
- }
- return my_pool_id;
-#else
- static pthread_key_t tid_key = [] {
- pthread_key_t tmp_key;
- int err = pthread_key_create(&tmp_key, nullptr);
- if (err) {
- ABSL_RAW_LOG(FATAL, "pthread_key_create failed with %d", err);
- }
- return tmp_key;
- }();
-
- // Store the value in the pthread_{get/set}specific. However an uninitialized
- // value is 0, so add +1 to distinguish from the null value.
- intptr_t my_pool_id =
- reinterpret_cast<intptr_t>(pthread_getspecific(tid_key));
- if (ABSL_PREDICT_FALSE(my_pool_id == 0)) {
- // No allocated ID, allocate the next value, cache it, and return.
- my_pool_id = (sequence++ % kPoolSize) + 1;
- int err = pthread_setspecific(tid_key, reinterpret_cast<void*>(my_pool_id));
- if (err) {
- ABSL_RAW_LOG(FATAL, "pthread_setspecific failed with %d", err);
- }
- }
- return my_pool_id - 1;
-#endif
-}
-
-// Allocate a RandenPoolEntry with at least 32-byte alignment, which is required
-// by ARM platform code.
-RandenPoolEntry* PoolAlignedAlloc() {
- constexpr size_t kAlignment =
- ABSL_CACHELINE_SIZE > 32 ? ABSL_CACHELINE_SIZE : 32;
-
- // Not all the platforms that we build for have std::aligned_alloc, however
- // since we never free these objects, we can over allocate and munge the
- // pointers to the correct alignment.
+namespace random_internal {
+namespace {
+
+// RandenPoolEntry is a thread-safe pseudorandom bit generator, implementing a
+// single generator within a RandenPool<T>. It is an internal implementation
+// detail, and does not aim to conform to [rand.req.urng].
+//
+// NOTE: There are alignment issues when used on ARM, for instance.
+// See the allocation code in PoolAlignedAlloc().
+class RandenPoolEntry {
+ public:
+ static constexpr size_t kState = RandenTraits::kStateBytes / sizeof(uint32_t);
+ static constexpr size_t kCapacity =
+ RandenTraits::kCapacityBytes / sizeof(uint32_t);
+
+ void Init(absl::Span<const uint32_t> data) {
+ SpinLockHolder l(&mu_); // Always uncontested.
+ std::copy(data.begin(), data.end(), std::begin(state_));
+ next_ = kState;
+ }
+
+ // Copy bytes into out.
+ void Fill(uint8_t* out, size_t bytes) ABSL_LOCKS_EXCLUDED(mu_);
+
+ // Returns random bits from the buffer in units of T.
+ template <typename T>
+ inline T Generate() ABSL_LOCKS_EXCLUDED(mu_);
+
+ inline void MaybeRefill() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
+ if (next_ >= kState) {
+ next_ = kCapacity;
+ impl_.Generate(state_);
+ }
+ }
+
+ private:
+ // Randen URBG state.
+ uint32_t state_[kState] ABSL_GUARDED_BY(mu_); // First to satisfy alignment.
+ SpinLock mu_;
+ const Randen impl_;
+ size_t next_ ABSL_GUARDED_BY(mu_);
+};
+
+template <>
+inline uint8_t RandenPoolEntry::Generate<uint8_t>() {
+ SpinLockHolder l(&mu_);
+ MaybeRefill();
+ return static_cast<uint8_t>(state_[next_++]);
+}
+
+template <>
+inline uint16_t RandenPoolEntry::Generate<uint16_t>() {
+ SpinLockHolder l(&mu_);
+ MaybeRefill();
+ return static_cast<uint16_t>(state_[next_++]);
+}
+
+template <>
+inline uint32_t RandenPoolEntry::Generate<uint32_t>() {
+ SpinLockHolder l(&mu_);
+ MaybeRefill();
+ return state_[next_++];
+}
+
+template <>
+inline uint64_t RandenPoolEntry::Generate<uint64_t>() {
+ SpinLockHolder l(&mu_);
+ if (next_ >= kState - 1) {
+ next_ = kCapacity;
+ impl_.Generate(state_);
+ }
+ auto p = state_ + next_;
+ next_ += 2;
+
+ uint64_t result;
+ std::memcpy(&result, p, sizeof(result));
+ return result;
+}
+
+void RandenPoolEntry::Fill(uint8_t* out, size_t bytes) {
+ SpinLockHolder l(&mu_);
+ while (bytes > 0) {
+ MaybeRefill();
+ size_t remaining = (kState - next_) * sizeof(state_[0]);
+ size_t to_copy = std::min(bytes, remaining);
+ std::memcpy(out, &state_[next_], to_copy);
+ out += to_copy;
+ bytes -= to_copy;
+ next_ += (to_copy + sizeof(state_[0]) - 1) / sizeof(state_[0]);
+ }
+}
+
+// Number of pooled urbg entries.
+static constexpr int kPoolSize = 8;
+
+// Shared pool entries.
+static absl::once_flag pool_once;
+ABSL_CACHELINE_ALIGNED static RandenPoolEntry* shared_pools[kPoolSize];
+
+// Returns an id in the range [0 ... kPoolSize), which indexes into the
+// pool of random engines.
+//
+// Each thread to access the pool is assigned a sequential ID (without reuse)
+// from the pool-id space; the id is cached in a thread_local variable.
+// This id is assigned based on the arrival-order of the thread to the
+// GetPoolID call; this has no binary, CL, or runtime stability because
+// on subsequent runs the order within the same program may be significantly
+// different. However, as other thread IDs are not assigned sequentially,
+// this is not expected to matter.
+int GetPoolID() {
+ static_assert(kPoolSize >= 1,
+ "At least one urbg instance is required for PoolURBG");
+
+ ABSL_CONST_INIT static std::atomic<int64_t> sequence{0};
+
+#ifdef ABSL_HAVE_THREAD_LOCAL
+ static thread_local int my_pool_id = -1;
+ if (ABSL_PREDICT_FALSE(my_pool_id < 0)) {
+ my_pool_id = (sequence++ % kPoolSize);
+ }
+ return my_pool_id;
+#else
+ static pthread_key_t tid_key = [] {
+ pthread_key_t tmp_key;
+ int err = pthread_key_create(&tmp_key, nullptr);
+ if (err) {
+ ABSL_RAW_LOG(FATAL, "pthread_key_create failed with %d", err);
+ }
+ return tmp_key;
+ }();
+
+ // Store the value in the pthread_{get/set}specific. However an uninitialized
+ // value is 0, so add +1 to distinguish from the null value.
+ intptr_t my_pool_id =
+ reinterpret_cast<intptr_t>(pthread_getspecific(tid_key));
+ if (ABSL_PREDICT_FALSE(my_pool_id == 0)) {
+ // No allocated ID, allocate the next value, cache it, and return.
+ my_pool_id = (sequence++ % kPoolSize) + 1;
+ int err = pthread_setspecific(tid_key, reinterpret_cast<void*>(my_pool_id));
+ if (err) {
+ ABSL_RAW_LOG(FATAL, "pthread_setspecific failed with %d", err);
+ }
+ }
+ return my_pool_id - 1;
+#endif
+}
+
+// Allocate a RandenPoolEntry with at least 32-byte alignment, which is required
+// by ARM platform code.
+RandenPoolEntry* PoolAlignedAlloc() {
+ constexpr size_t kAlignment =
+ ABSL_CACHELINE_SIZE > 32 ? ABSL_CACHELINE_SIZE : 32;
+
+ // Not all the platforms that we build for have std::aligned_alloc, however
+ // since we never free these objects, we can over allocate and munge the
+ // pointers to the correct alignment.
intptr_t x = reinterpret_cast<intptr_t>(
new char[sizeof(RandenPoolEntry) + kAlignment]);
- auto y = x % kAlignment;
+ auto y = x % kAlignment;
void* aligned = reinterpret_cast<void*>(y == 0 ? x : (x + kAlignment - y));
- return new (aligned) RandenPoolEntry();
-}
-
-// Allocate and initialize kPoolSize objects of type RandenPoolEntry.
-//
-// The initialization strategy is to initialize one object directly from
-// OS entropy, then to use that object to seed all of the individual
-// pool instances.
-void InitPoolURBG() {
- static constexpr size_t kSeedSize =
- RandenTraits::kStateBytes / sizeof(uint32_t);
- // Read the seed data from OS entropy once.
- uint32_t seed_material[kPoolSize * kSeedSize];
- if (!random_internal::ReadSeedMaterialFromOSEntropy(
- absl::MakeSpan(seed_material))) {
- random_internal::ThrowSeedGenException();
- }
- for (int i = 0; i < kPoolSize; i++) {
- shared_pools[i] = PoolAlignedAlloc();
- shared_pools[i]->Init(
- absl::MakeSpan(&seed_material[i * kSeedSize], kSeedSize));
- }
-}
-
-// Returns the pool entry for the current thread.
-RandenPoolEntry* GetPoolForCurrentThread() {
- absl::call_once(pool_once, InitPoolURBG);
- return shared_pools[GetPoolID()];
-}
-
-} // namespace
-
-template <typename T>
-typename RandenPool<T>::result_type RandenPool<T>::Generate() {
- auto* pool = GetPoolForCurrentThread();
- return pool->Generate<T>();
-}
-
-template <typename T>
-void RandenPool<T>::Fill(absl::Span<result_type> data) {
- auto* pool = GetPoolForCurrentThread();
- pool->Fill(reinterpret_cast<uint8_t*>(data.data()),
- data.size() * sizeof(result_type));
-}
-
-template class RandenPool<uint8_t>;
-template class RandenPool<uint16_t>;
-template class RandenPool<uint32_t>;
-template class RandenPool<uint64_t>;
-
-} // namespace random_internal
+ return new (aligned) RandenPoolEntry();
+}
+
+// Allocate and initialize kPoolSize objects of type RandenPoolEntry.
+//
+// The initialization strategy is to initialize one object directly from
+// OS entropy, then to use that object to seed all of the individual
+// pool instances.
+void InitPoolURBG() {
+ static constexpr size_t kSeedSize =
+ RandenTraits::kStateBytes / sizeof(uint32_t);
+ // Read the seed data from OS entropy once.
+ uint32_t seed_material[kPoolSize * kSeedSize];
+ if (!random_internal::ReadSeedMaterialFromOSEntropy(
+ absl::MakeSpan(seed_material))) {
+ random_internal::ThrowSeedGenException();
+ }
+ for (int i = 0; i < kPoolSize; i++) {
+ shared_pools[i] = PoolAlignedAlloc();
+ shared_pools[i]->Init(
+ absl::MakeSpan(&seed_material[i * kSeedSize], kSeedSize));
+ }
+}
+
+// Returns the pool entry for the current thread.
+RandenPoolEntry* GetPoolForCurrentThread() {
+ absl::call_once(pool_once, InitPoolURBG);
+ return shared_pools[GetPoolID()];
+}
+
+} // namespace
+
+template <typename T>
+typename RandenPool<T>::result_type RandenPool<T>::Generate() {
+ auto* pool = GetPoolForCurrentThread();
+ return pool->Generate<T>();
+}
+
+template <typename T>
+void RandenPool<T>::Fill(absl::Span<result_type> data) {
+ auto* pool = GetPoolForCurrentThread();
+ pool->Fill(reinterpret_cast<uint8_t*>(data.data()),
+ data.size() * sizeof(result_type));
+}
+
+template class RandenPool<uint8_t>;
+template class RandenPool<uint16_t>;
+template class RandenPool<uint32_t>;
+template class RandenPool<uint64_t>;
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
+} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.h b/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.h
index f4fd5e166a..05721929f5 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg.h
@@ -1,131 +1,131 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_POOL_URBG_H_
-#define ABSL_RANDOM_INTERNAL_POOL_URBG_H_
-
-#include <cinttypes>
-#include <limits>
-
-#include "absl/random/internal/traits.h"
-#include "absl/types/span.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_POOL_URBG_H_
+#define ABSL_RANDOM_INTERNAL_POOL_URBG_H_
+
+#include <cinttypes>
+#include <limits>
+
+#include "absl/random/internal/traits.h"
+#include "absl/types/span.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// RandenPool is a thread-safe random number generator [random.req.urbg] that
-// uses an underlying pool of Randen generators to generate values. Each thread
-// has affinity to one instance of the underlying pool generators. Concurrent
-// access is guarded by a spin-lock.
-template <typename T>
-class RandenPool {
- public:
- using result_type = T;
- static_assert(std::is_unsigned<result_type>::value,
- "RandenPool template argument must be a built-in unsigned "
- "integer type");
-
- static constexpr result_type(min)() {
- return (std::numeric_limits<result_type>::min)();
- }
-
- static constexpr result_type(max)() {
- return (std::numeric_limits<result_type>::max)();
- }
-
- RandenPool() {}
-
- // Returns a single value.
- inline result_type operator()() { return Generate(); }
-
- // Fill data with random values.
- static void Fill(absl::Span<result_type> data);
-
- protected:
- // Generate returns a single value.
- static result_type Generate();
-};
-
-extern template class RandenPool<uint8_t>;
-extern template class RandenPool<uint16_t>;
-extern template class RandenPool<uint32_t>;
-extern template class RandenPool<uint64_t>;
-
-// PoolURBG uses an underlying pool of random generators to implement a
-// thread-compatible [random.req.urbg] interface with an internal cache of
-// values.
-template <typename T, size_t kBufferSize>
-class PoolURBG {
- // Inheritance to access the protected static members of RandenPool.
- using unsigned_type = typename make_unsigned_bits<T>::type;
- using PoolType = RandenPool<unsigned_type>;
- using SpanType = absl::Span<unsigned_type>;
-
- static constexpr size_t kInitialBuffer = kBufferSize + 1;
- static constexpr size_t kHalfBuffer = kBufferSize / 2;
-
- public:
- using result_type = T;
-
- static_assert(std::is_unsigned<result_type>::value,
- "PoolURBG must be parameterized by an unsigned integer type");
-
- static_assert(kBufferSize > 1,
- "PoolURBG must be parameterized by a buffer-size > 1");
-
- static_assert(kBufferSize <= 256,
- "PoolURBG must be parameterized by a buffer-size <= 256");
-
- static constexpr result_type(min)() {
- return (std::numeric_limits<result_type>::min)();
- }
-
- static constexpr result_type(max)() {
- return (std::numeric_limits<result_type>::max)();
- }
-
- PoolURBG() : next_(kInitialBuffer) {}
-
- // copy-constructor does not copy cache.
- PoolURBG(const PoolURBG&) : next_(kInitialBuffer) {}
- const PoolURBG& operator=(const PoolURBG&) {
- next_ = kInitialBuffer;
- return *this;
- }
-
- // move-constructor does move cache.
- PoolURBG(PoolURBG&&) = default;
- PoolURBG& operator=(PoolURBG&&) = default;
-
- inline result_type operator()() {
- if (next_ >= kBufferSize) {
- next_ = (kBufferSize > 2 && next_ > kBufferSize) ? kHalfBuffer : 0;
- PoolType::Fill(SpanType(reinterpret_cast<unsigned_type*>(state_ + next_),
- kBufferSize - next_));
- }
- return state_[next_++];
- }
-
- private:
- // Buffer size.
- size_t next_; // index within state_
- result_type state_[kBufferSize];
-};
-
-} // namespace random_internal
+namespace random_internal {
+
+// RandenPool is a thread-safe random number generator [random.req.urbg] that
+// uses an underlying pool of Randen generators to generate values. Each thread
+// has affinity to one instance of the underlying pool generators. Concurrent
+// access is guarded by a spin-lock.
+template <typename T>
+class RandenPool {
+ public:
+ using result_type = T;
+ static_assert(std::is_unsigned<result_type>::value,
+ "RandenPool template argument must be a built-in unsigned "
+ "integer type");
+
+ static constexpr result_type(min)() {
+ return (std::numeric_limits<result_type>::min)();
+ }
+
+ static constexpr result_type(max)() {
+ return (std::numeric_limits<result_type>::max)();
+ }
+
+ RandenPool() {}
+
+ // Returns a single value.
+ inline result_type operator()() { return Generate(); }
+
+ // Fill data with random values.
+ static void Fill(absl::Span<result_type> data);
+
+ protected:
+ // Generate returns a single value.
+ static result_type Generate();
+};
+
+extern template class RandenPool<uint8_t>;
+extern template class RandenPool<uint16_t>;
+extern template class RandenPool<uint32_t>;
+extern template class RandenPool<uint64_t>;
+
+// PoolURBG uses an underlying pool of random generators to implement a
+// thread-compatible [random.req.urbg] interface with an internal cache of
+// values.
+template <typename T, size_t kBufferSize>
+class PoolURBG {
+ // Inheritance to access the protected static members of RandenPool.
+ using unsigned_type = typename make_unsigned_bits<T>::type;
+ using PoolType = RandenPool<unsigned_type>;
+ using SpanType = absl::Span<unsigned_type>;
+
+ static constexpr size_t kInitialBuffer = kBufferSize + 1;
+ static constexpr size_t kHalfBuffer = kBufferSize / 2;
+
+ public:
+ using result_type = T;
+
+ static_assert(std::is_unsigned<result_type>::value,
+ "PoolURBG must be parameterized by an unsigned integer type");
+
+ static_assert(kBufferSize > 1,
+ "PoolURBG must be parameterized by a buffer-size > 1");
+
+ static_assert(kBufferSize <= 256,
+ "PoolURBG must be parameterized by a buffer-size <= 256");
+
+ static constexpr result_type(min)() {
+ return (std::numeric_limits<result_type>::min)();
+ }
+
+ static constexpr result_type(max)() {
+ return (std::numeric_limits<result_type>::max)();
+ }
+
+ PoolURBG() : next_(kInitialBuffer) {}
+
+ // copy-constructor does not copy cache.
+ PoolURBG(const PoolURBG&) : next_(kInitialBuffer) {}
+ const PoolURBG& operator=(const PoolURBG&) {
+ next_ = kInitialBuffer;
+ return *this;
+ }
+
+ // move-constructor does move cache.
+ PoolURBG(PoolURBG&&) = default;
+ PoolURBG& operator=(PoolURBG&&) = default;
+
+ inline result_type operator()() {
+ if (next_ >= kBufferSize) {
+ next_ = (kBufferSize > 2 && next_ > kBufferSize) ? kHalfBuffer : 0;
+ PoolType::Fill(SpanType(reinterpret_cast<unsigned_type*>(state_ + next_),
+ kBufferSize - next_));
+ }
+ return state_[next_++];
+ }
+
+ private:
+ // Buffer size.
+ size_t next_; // index within state_
+ result_type state_[kBufferSize];
+};
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_POOL_URBG_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_POOL_URBG_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg/ya.make
index 98183380de..fd4e1c1f4d 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg/ya.make
@@ -1,48 +1,48 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
WITHOUT_LICENSE_TEXTS()
-OWNER(g:cpp-contrib)
-
-LICENSE(Apache-2.0)
-
-PEERDIR(
- contrib/restricted/abseil-cpp/absl/base
- contrib/restricted/abseil-cpp/absl/base/internal/raw_logging
- contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait
- contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate
- contrib/restricted/abseil-cpp/absl/base/log_severity
- contrib/restricted/abseil-cpp/absl/numeric
- contrib/restricted/abseil-cpp/absl/random/internal/randen
- contrib/restricted/abseil-cpp/absl/random/internal/randen_detect
- contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes
+OWNER(g:cpp-contrib)
+
+LICENSE(Apache-2.0)
+
+PEERDIR(
+ contrib/restricted/abseil-cpp/absl/base
+ contrib/restricted/abseil-cpp/absl/base/internal/raw_logging
+ contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait
+ contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate
+ contrib/restricted/abseil-cpp/absl/base/log_severity
+ contrib/restricted/abseil-cpp/absl/numeric
+ contrib/restricted/abseil-cpp/absl/random/internal/randen
+ contrib/restricted/abseil-cpp/absl/random/internal/randen_detect
+ contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes
contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys
- contrib/restricted/abseil-cpp/absl/random/internal/randen_slow
- contrib/restricted/abseil-cpp/absl/random/internal/seed_material
- contrib/restricted/abseil-cpp/absl/random/seed_gen_exception
- contrib/restricted/abseil-cpp/absl/strings
+ contrib/restricted/abseil-cpp/absl/random/internal/randen_slow
+ contrib/restricted/abseil-cpp/absl/random/internal/seed_material
+ contrib/restricted/abseil-cpp/absl/random/seed_gen_exception
+ contrib/restricted/abseil-cpp/absl/strings
contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal
- contrib/restricted/abseil-cpp/absl/types/bad_optional_access
-)
-
-ADDINCL(
- GLOBAL contrib/restricted/abseil-cpp
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
+ contrib/restricted/abseil-cpp/absl/types/bad_optional_access
+)
+
+ADDINCL(
+ GLOBAL contrib/restricted/abseil-cpp
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
CFLAGS(
-DNOMINMAX
)
-SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal)
-
-SRCS(
- pool_urbg.cc
-)
-
-END()
+SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal)
+
+SRCS(
+ pool_urbg.cc
+)
+
+END()
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen.cc b/contrib/restricted/abseil-cpp/absl/random/internal/randen.cc
index 996b489bb6..c1bc044435 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/randen.cc
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen.cc
@@ -1,91 +1,91 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/random/internal/randen.h"
-
-#include "absl/base/internal/raw_logging.h"
-#include "absl/random/internal/randen_detect.h"
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/random/internal/randen.h"
+
+#include "absl/base/internal/raw_logging.h"
+#include "absl/random/internal/randen_detect.h"
+
// RANDen = RANDom generator or beetroots in Swiss High German.
-// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
-// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
-//
-// High-level summary:
-// 1) Reverie (see "A Robust and Sponge-Like PRNG with Improved Efficiency") is
-// a sponge-like random generator that requires a cryptographic permutation.
-// It improves upon "Provably Robust Sponge-Based PRNGs and KDFs" by
-// achieving backtracking resistance with only one Permute() per buffer.
-//
-// 2) "Simpira v2: A Family of Efficient Permutations Using the AES Round
-// Function" constructs up to 1024-bit permutations using an improved
-// Generalized Feistel network with 2-round AES-128 functions. This Feistel
-// block shuffle achieves diffusion faster and is less vulnerable to
-// sliced-biclique attacks than the Type-2 cyclic shuffle.
-//
-// 3) "Improving the Generalized Feistel" and "New criterion for diffusion
-// property" extends the same kind of improved Feistel block shuffle to 16
-// branches, which enables a 2048-bit permutation.
-//
-// We combine these three ideas and also change Simpira's subround keys from
-// structured/low-entropy counters to digits of Pi.
-
-namespace absl {
+// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
+// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
+//
+// High-level summary:
+// 1) Reverie (see "A Robust and Sponge-Like PRNG with Improved Efficiency") is
+// a sponge-like random generator that requires a cryptographic permutation.
+// It improves upon "Provably Robust Sponge-Based PRNGs and KDFs" by
+// achieving backtracking resistance with only one Permute() per buffer.
+//
+// 2) "Simpira v2: A Family of Efficient Permutations Using the AES Round
+// Function" constructs up to 1024-bit permutations using an improved
+// Generalized Feistel network with 2-round AES-128 functions. This Feistel
+// block shuffle achieves diffusion faster and is less vulnerable to
+// sliced-biclique attacks than the Type-2 cyclic shuffle.
+//
+// 3) "Improving the Generalized Feistel" and "New criterion for diffusion
+// property" extends the same kind of improved Feistel block shuffle to 16
+// branches, which enables a 2048-bit permutation.
+//
+// We combine these three ideas and also change Simpira's subround keys from
+// structured/low-entropy counters to digits of Pi.
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-namespace {
-
-struct RandenState {
- const void* keys;
- bool has_crypto;
-};
-
-RandenState GetRandenState() {
- static const RandenState state = []() {
- RandenState tmp;
-#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
- // HW AES Dispatch.
- if (HasRandenHwAesImplementation() && CPUSupportsRandenHwAes()) {
- tmp.has_crypto = true;
- tmp.keys = RandenHwAes::GetKeys();
- } else {
- tmp.has_crypto = false;
- tmp.keys = RandenSlow::GetKeys();
- }
-#elif ABSL_HAVE_ACCELERATED_AES
- // HW AES is enabled.
- tmp.has_crypto = true;
- tmp.keys = RandenHwAes::GetKeys();
-#else
- // HW AES is disabled.
- tmp.has_crypto = false;
- tmp.keys = RandenSlow::GetKeys();
-#endif
- return tmp;
- }();
- return state;
-}
-
-} // namespace
-
-Randen::Randen() {
- auto tmp = GetRandenState();
- keys_ = tmp.keys;
-#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
- has_crypto_ = tmp.has_crypto;
-#endif
-}
-
-} // namespace random_internal
+namespace random_internal {
+namespace {
+
+struct RandenState {
+ const void* keys;
+ bool has_crypto;
+};
+
+RandenState GetRandenState() {
+ static const RandenState state = []() {
+ RandenState tmp;
+#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
+ // HW AES Dispatch.
+ if (HasRandenHwAesImplementation() && CPUSupportsRandenHwAes()) {
+ tmp.has_crypto = true;
+ tmp.keys = RandenHwAes::GetKeys();
+ } else {
+ tmp.has_crypto = false;
+ tmp.keys = RandenSlow::GetKeys();
+ }
+#elif ABSL_HAVE_ACCELERATED_AES
+ // HW AES is enabled.
+ tmp.has_crypto = true;
+ tmp.keys = RandenHwAes::GetKeys();
+#else
+ // HW AES is disabled.
+ tmp.has_crypto = false;
+ tmp.keys = RandenSlow::GetKeys();
+#endif
+ return tmp;
+ }();
+ return state;
+}
+
+} // namespace
+
+Randen::Randen() {
+ auto tmp = GetRandenState();
+ keys_ = tmp.keys;
+#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
+ has_crypto_ = tmp.has_crypto;
+#endif
+}
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
+} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen.h b/contrib/restricted/abseil-cpp/absl/random/internal/randen.h
index 6c2d53e210..9a3840b8f1 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/randen.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen.h
@@ -1,102 +1,102 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_RANDEN_H_
-#define ABSL_RANDOM_INTERNAL_RANDEN_H_
-
-#include <cstddef>
-
-#include "absl/random/internal/platform.h"
-#include "absl/random/internal/randen_hwaes.h"
-#include "absl/random/internal/randen_slow.h"
-#include "absl/random/internal/randen_traits.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_RANDEN_H_
+#define ABSL_RANDOM_INTERNAL_RANDEN_H_
+
+#include <cstddef>
+
+#include "absl/random/internal/platform.h"
+#include "absl/random/internal/randen_hwaes.h"
+#include "absl/random/internal/randen_slow.h"
+#include "absl/random/internal/randen_traits.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
+namespace random_internal {
+
// RANDen = RANDom generator or beetroots in Swiss High German.
-// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
-// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
-//
-// Randen implements the basic state manipulation methods.
-class Randen {
- public:
- static constexpr size_t kStateBytes = RandenTraits::kStateBytes;
- static constexpr size_t kCapacityBytes = RandenTraits::kCapacityBytes;
- static constexpr size_t kSeedBytes = RandenTraits::kSeedBytes;
-
- ~Randen() = default;
-
- Randen();
-
- // Generate updates the randen sponge. The outer portion of the sponge
- // (kCapacityBytes .. kStateBytes) may be consumed as PRNG state.
- template <typename T, size_t N>
- void Generate(T (&state)[N]) const {
- static_assert(N * sizeof(T) == kStateBytes,
- "Randen::Generate() requires kStateBytes of state");
-#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
- // HW AES Dispatch.
- if (has_crypto_) {
- RandenHwAes::Generate(keys_, state);
- } else {
- RandenSlow::Generate(keys_, state);
- }
-#elif ABSL_HAVE_ACCELERATED_AES
- // HW AES is enabled.
- RandenHwAes::Generate(keys_, state);
-#else
- // HW AES is disabled.
- RandenSlow::Generate(keys_, state);
-#endif
- }
-
- // Absorb incorporates additional seed material into the randen sponge. After
- // absorb returns, Generate must be called before the state may be consumed.
- template <typename S, size_t M, typename T, size_t N>
- void Absorb(const S (&seed)[M], T (&state)[N]) const {
- static_assert(M * sizeof(S) == RandenTraits::kSeedBytes,
- "Randen::Absorb() requires kSeedBytes of seed");
-
- static_assert(N * sizeof(T) == RandenTraits::kStateBytes,
- "Randen::Absorb() requires kStateBytes of state");
-#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
- // HW AES Dispatch.
- if (has_crypto_) {
- RandenHwAes::Absorb(seed, state);
- } else {
- RandenSlow::Absorb(seed, state);
- }
-#elif ABSL_HAVE_ACCELERATED_AES
- // HW AES is enabled.
- RandenHwAes::Absorb(seed, state);
-#else
- // HW AES is disabled.
- RandenSlow::Absorb(seed, state);
-#endif
- }
-
- private:
- const void* keys_;
-#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
- bool has_crypto_;
-#endif
-};
-
-} // namespace random_internal
+// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
+// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
+//
+// Randen implements the basic state manipulation methods.
+class Randen {
+ public:
+ static constexpr size_t kStateBytes = RandenTraits::kStateBytes;
+ static constexpr size_t kCapacityBytes = RandenTraits::kCapacityBytes;
+ static constexpr size_t kSeedBytes = RandenTraits::kSeedBytes;
+
+ ~Randen() = default;
+
+ Randen();
+
+ // Generate updates the randen sponge. The outer portion of the sponge
+ // (kCapacityBytes .. kStateBytes) may be consumed as PRNG state.
+ template <typename T, size_t N>
+ void Generate(T (&state)[N]) const {
+ static_assert(N * sizeof(T) == kStateBytes,
+ "Randen::Generate() requires kStateBytes of state");
+#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
+ // HW AES Dispatch.
+ if (has_crypto_) {
+ RandenHwAes::Generate(keys_, state);
+ } else {
+ RandenSlow::Generate(keys_, state);
+ }
+#elif ABSL_HAVE_ACCELERATED_AES
+ // HW AES is enabled.
+ RandenHwAes::Generate(keys_, state);
+#else
+ // HW AES is disabled.
+ RandenSlow::Generate(keys_, state);
+#endif
+ }
+
+ // Absorb incorporates additional seed material into the randen sponge. After
+ // absorb returns, Generate must be called before the state may be consumed.
+ template <typename S, size_t M, typename T, size_t N>
+ void Absorb(const S (&seed)[M], T (&state)[N]) const {
+ static_assert(M * sizeof(S) == RandenTraits::kSeedBytes,
+ "Randen::Absorb() requires kSeedBytes of seed");
+
+ static_assert(N * sizeof(T) == RandenTraits::kStateBytes,
+ "Randen::Absorb() requires kStateBytes of state");
+#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
+ // HW AES Dispatch.
+ if (has_crypto_) {
+ RandenHwAes::Absorb(seed, state);
+ } else {
+ RandenSlow::Absorb(seed, state);
+ }
+#elif ABSL_HAVE_ACCELERATED_AES
+ // HW AES is enabled.
+ RandenHwAes::Absorb(seed, state);
+#else
+ // HW AES is disabled.
+ RandenSlow::Absorb(seed, state);
+#endif
+ }
+
+ private:
+ const void* keys_;
+#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
+ bool has_crypto_;
+#endif
+};
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_RANDEN_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_RANDEN_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/randen/ya.make
index 22f85e42ee..150b9e0714 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/randen/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen/ya.make
@@ -1,36 +1,36 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
WITHOUT_LICENSE_TEXTS()
-OWNER(g:cpp-contrib)
-
-LICENSE(Apache-2.0)
-
-PEERDIR(
- contrib/restricted/abseil-cpp/absl/random/internal/randen_detect
- contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes
+OWNER(g:cpp-contrib)
+
+LICENSE(Apache-2.0)
+
+PEERDIR(
+ contrib/restricted/abseil-cpp/absl/random/internal/randen_detect
+ contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes
contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys
- contrib/restricted/abseil-cpp/absl/random/internal/randen_slow
-)
-
-ADDINCL(
- GLOBAL contrib/restricted/abseil-cpp
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
+ contrib/restricted/abseil-cpp/absl/random/internal/randen_slow
+)
+
+ADDINCL(
+ GLOBAL contrib/restricted/abseil-cpp
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
CFLAGS(
-DNOMINMAX
)
-SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal)
-
-SRCS(
- randen.cc
-)
-
-END()
+SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal)
+
+SRCS(
+ randen.cc
+)
+
+END()
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.cc b/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.cc
index 991512b18a..bbe7b96532 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.cc
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.cc
@@ -1,221 +1,221 @@
-// Copyright 2017 The Abseil Authors.
-//
+// Copyright 2017 The Abseil Authors.
+//
// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate
-// symbols from arbitrary system and other headers, since it may be built
-// with different flags from other targets, using different levels of
-// optimization, potentially introducing ODR violations.
-
-#include "absl/random/internal/randen_detect.h"
-
-#include <cstdint>
-#include <cstring>
-
-#include "absl/random/internal/platform.h"
-
-#if defined(ABSL_ARCH_X86_64)
-#define ABSL_INTERNAL_USE_X86_CPUID
-#elif defined(ABSL_ARCH_PPC) || defined(ABSL_ARCH_ARM) || \
- defined(ABSL_ARCH_AARCH64)
-#if defined(__ANDROID__)
-#define ABSL_INTERNAL_USE_ANDROID_GETAUXVAL
-#define ABSL_INTERNAL_USE_GETAUXVAL
-#elif defined(__linux__)
-#define ABSL_INTERNAL_USE_LINUX_GETAUXVAL
-#define ABSL_INTERNAL_USE_GETAUXVAL
-#endif
-#endif
-
-#if defined(ABSL_INTERNAL_USE_X86_CPUID)
-#if defined(_WIN32) || defined(_WIN64)
-#include <intrin.h> // NOLINT(build/include_order)
-#pragma intrinsic(__cpuid)
-#else
-// MSVC-equivalent __cpuid intrinsic function.
-static void __cpuid(int cpu_info[4], int info_type) {
- __asm__ volatile("cpuid \n\t"
- : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]),
- "=d"(cpu_info[3])
- : "a"(info_type), "c"(0));
-}
-#endif
-#endif // ABSL_INTERNAL_USE_X86_CPUID
-
-// On linux, just use the c-library getauxval call.
-#if defined(ABSL_INTERNAL_USE_LINUX_GETAUXVAL)
-
-extern "C" unsigned long getauxval(unsigned long type); // NOLINT(runtime/int)
-
-static uint32_t GetAuxval(uint32_t hwcap_type) {
- return static_cast<uint32_t>(getauxval(hwcap_type));
-}
-
-#endif
-
-// On android, probe the system's C library for getauxval().
-// This is the same technique used by the android NDK cpu features library
-// as well as the google open-source cpu_features library.
-//
-// TODO(absl-team): Consider implementing a fallback of directly reading
-// /proc/self/auxval.
-#if defined(ABSL_INTERNAL_USE_ANDROID_GETAUXVAL)
-#include <dlfcn.h>
-
-static uint32_t GetAuxval(uint32_t hwcap_type) {
- // NOLINTNEXTLINE(runtime/int)
- typedef unsigned long (*getauxval_func_t)(unsigned long);
-
- dlerror(); // Cleaning error state before calling dlopen.
- void* libc_handle = dlopen("libc.so", RTLD_NOW);
- if (!libc_handle) {
- return 0;
- }
- uint32_t result = 0;
- void* sym = dlsym(libc_handle, "getauxval");
- if (sym) {
- getauxval_func_t func;
- memcpy(&func, &sym, sizeof(func));
- result = static_cast<uint32_t>((*func)(hwcap_type));
- }
- dlclose(libc_handle);
- return result;
-}
-
-#endif
-
-namespace absl {
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate
+// symbols from arbitrary system and other headers, since it may be built
+// with different flags from other targets, using different levels of
+// optimization, potentially introducing ODR violations.
+
+#include "absl/random/internal/randen_detect.h"
+
+#include <cstdint>
+#include <cstring>
+
+#include "absl/random/internal/platform.h"
+
+#if defined(ABSL_ARCH_X86_64)
+#define ABSL_INTERNAL_USE_X86_CPUID
+#elif defined(ABSL_ARCH_PPC) || defined(ABSL_ARCH_ARM) || \
+ defined(ABSL_ARCH_AARCH64)
+#if defined(__ANDROID__)
+#define ABSL_INTERNAL_USE_ANDROID_GETAUXVAL
+#define ABSL_INTERNAL_USE_GETAUXVAL
+#elif defined(__linux__)
+#define ABSL_INTERNAL_USE_LINUX_GETAUXVAL
+#define ABSL_INTERNAL_USE_GETAUXVAL
+#endif
+#endif
+
+#if defined(ABSL_INTERNAL_USE_X86_CPUID)
+#if defined(_WIN32) || defined(_WIN64)
+#include <intrin.h> // NOLINT(build/include_order)
+#pragma intrinsic(__cpuid)
+#else
+// MSVC-equivalent __cpuid intrinsic function.
+static void __cpuid(int cpu_info[4], int info_type) {
+ __asm__ volatile("cpuid \n\t"
+ : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]),
+ "=d"(cpu_info[3])
+ : "a"(info_type), "c"(0));
+}
+#endif
+#endif // ABSL_INTERNAL_USE_X86_CPUID
+
+// On linux, just use the c-library getauxval call.
+#if defined(ABSL_INTERNAL_USE_LINUX_GETAUXVAL)
+
+extern "C" unsigned long getauxval(unsigned long type); // NOLINT(runtime/int)
+
+static uint32_t GetAuxval(uint32_t hwcap_type) {
+ return static_cast<uint32_t>(getauxval(hwcap_type));
+}
+
+#endif
+
+// On android, probe the system's C library for getauxval().
+// This is the same technique used by the android NDK cpu features library
+// as well as the google open-source cpu_features library.
+//
+// TODO(absl-team): Consider implementing a fallback of directly reading
+// /proc/self/auxval.
+#if defined(ABSL_INTERNAL_USE_ANDROID_GETAUXVAL)
+#include <dlfcn.h>
+
+static uint32_t GetAuxval(uint32_t hwcap_type) {
+ // NOLINTNEXTLINE(runtime/int)
+ typedef unsigned long (*getauxval_func_t)(unsigned long);
+
+ dlerror(); // Cleaning error state before calling dlopen.
+ void* libc_handle = dlopen("libc.so", RTLD_NOW);
+ if (!libc_handle) {
+ return 0;
+ }
+ uint32_t result = 0;
+ void* sym = dlsym(libc_handle, "getauxval");
+ if (sym) {
+ getauxval_func_t func;
+ memcpy(&func, &sym, sizeof(func));
+ result = static_cast<uint32_t>((*func)(hwcap_type));
+ }
+ dlclose(libc_handle);
+ return result;
+}
+
+#endif
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// The default return at the end of the function might be unreachable depending
-// on the configuration. Ignore that warning.
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunreachable-code-return"
-#endif
-
-// CPUSupportsRandenHwAes returns whether the CPU is a microarchitecture
-// which supports the crpyto/aes instructions or extensions necessary to use the
-// accelerated RandenHwAes implementation.
-//
-// 1. For x86 it is sufficient to use the CPUID instruction to detect whether
-// the cpu supports AES instructions. Done.
-//
-// Fon non-x86 it is much more complicated.
-//
-// 2. When ABSL_INTERNAL_USE_GETAUXVAL is defined, use getauxval() (either
-// the direct c-library version, or the android probing version which loads
-// libc), and read the hardware capability bits.
-// This is based on the technique used by boringssl uses to detect
-// cpu capabilities, and should allow us to enable crypto in the android
-// builds where it is supported.
-//
-// 3. Use the default for the compiler architecture.
-//
-
-bool CPUSupportsRandenHwAes() {
-#if defined(ABSL_INTERNAL_USE_X86_CPUID)
- // 1. For x86: Use CPUID to detect the required AES instruction set.
- int regs[4];
- __cpuid(reinterpret_cast<int*>(regs), 1);
- return regs[2] & (1 << 25); // AES
-
-#elif defined(ABSL_INTERNAL_USE_GETAUXVAL)
- // 2. Use getauxval() to read the hardware bits and determine
- // cpu capabilities.
-
-#define AT_HWCAP 16
-#define AT_HWCAP2 26
-#if defined(ABSL_ARCH_PPC)
- // For Power / PPC: Expect that the cpu supports VCRYPTO
- // See https://members.openpowerfoundation.org/document/dl/576
- // VCRYPTO should be present in POWER8 >= 2.07.
- // Uses Linux kernel constants from arch/powerpc/include/uapi/asm/cputable.h
- static const uint32_t kVCRYPTO = 0x02000000;
- const uint32_t hwcap = GetAuxval(AT_HWCAP2);
- return (hwcap & kVCRYPTO) != 0;
-
-#elif defined(ABSL_ARCH_ARM)
- // For ARM: Require crypto+neon
- // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0500f/CIHBIBBA.html
- // Uses Linux kernel constants from arch/arm64/include/asm/hwcap.h
- static const uint32_t kNEON = 1 << 12;
- uint32_t hwcap = GetAuxval(AT_HWCAP);
- if ((hwcap & kNEON) == 0) {
- return false;
- }
-
- // And use it again to detect AES.
- static const uint32_t kAES = 1 << 0;
- const uint32_t hwcap2 = GetAuxval(AT_HWCAP2);
- return (hwcap2 & kAES) != 0;
-
-#elif defined(ABSL_ARCH_AARCH64)
- // For AARCH64: Require crypto+neon
- // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0500f/CIHBIBBA.html
- static const uint32_t kNEON = 1 << 1;
- static const uint32_t kAES = 1 << 3;
- const uint32_t hwcap = GetAuxval(AT_HWCAP);
- return ((hwcap & kNEON) != 0) && ((hwcap & kAES) != 0);
-#endif
-
-#else // ABSL_INTERNAL_USE_GETAUXVAL
- // 3. By default, assume that the compiler default.
- return ABSL_HAVE_ACCELERATED_AES ? true : false;
-
-#endif
- // NOTE: There are some other techniques that may be worth trying:
- //
- // * Use an environment variable: ABSL_RANDOM_USE_HWAES
- //
- // * Rely on compiler-generated target-based dispatch.
- // Using x86/gcc it might look something like this:
- //
- // int __attribute__((target("aes"))) HasAes() { return 1; }
- // int __attribute__((target("default"))) HasAes() { return 0; }
- //
- // This does not work on all architecture/compiler combinations.
- //
- // * On Linux consider reading /proc/cpuinfo and/or /proc/self/auxv.
- // These files have lines which are easy to parse; for ARM/AARCH64 it is quite
- // easy to find the Features: line and extract aes / neon. Likewise for
- // PPC.
- //
- // * Fork a process and test for SIGILL:
- //
- // * Many architectures have instructions to read the ISA. Unfortunately
- // most of those require that the code is running in ring 0 /
- // protected-mode.
- //
- // There are several examples. e.g. Valgrind detects PPC ISA 2.07:
- // https://github.com/lu-zero/valgrind/blob/master/none/tests/ppc64/test_isa_2_07_part1.c
- //
- // MRS <Xt>, ID_AA64ISAR0_EL1 ; Read ID_AA64ISAR0_EL1 into Xt
- //
- // uint64_t val;
- // __asm __volatile("mrs %0, id_aa64isar0_el1" :"=&r" (val));
- //
- // * Use a CPUID-style heuristic database.
- //
- // * On Apple (__APPLE__), AES is available on Arm v8.
- // https://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios
-}
-
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-
-} // namespace random_internal
+namespace random_internal {
+
+// The default return at the end of the function might be unreachable depending
+// on the configuration. Ignore that warning.
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunreachable-code-return"
+#endif
+
+// CPUSupportsRandenHwAes returns whether the CPU is a microarchitecture
+// which supports the crpyto/aes instructions or extensions necessary to use the
+// accelerated RandenHwAes implementation.
+//
+// 1. For x86 it is sufficient to use the CPUID instruction to detect whether
+// the cpu supports AES instructions. Done.
+//
+// Fon non-x86 it is much more complicated.
+//
+// 2. When ABSL_INTERNAL_USE_GETAUXVAL is defined, use getauxval() (either
+// the direct c-library version, or the android probing version which loads
+// libc), and read the hardware capability bits.
+// This is based on the technique used by boringssl uses to detect
+// cpu capabilities, and should allow us to enable crypto in the android
+// builds where it is supported.
+//
+// 3. Use the default for the compiler architecture.
+//
+
+bool CPUSupportsRandenHwAes() {
+#if defined(ABSL_INTERNAL_USE_X86_CPUID)
+ // 1. For x86: Use CPUID to detect the required AES instruction set.
+ int regs[4];
+ __cpuid(reinterpret_cast<int*>(regs), 1);
+ return regs[2] & (1 << 25); // AES
+
+#elif defined(ABSL_INTERNAL_USE_GETAUXVAL)
+ // 2. Use getauxval() to read the hardware bits and determine
+ // cpu capabilities.
+
+#define AT_HWCAP 16
+#define AT_HWCAP2 26
+#if defined(ABSL_ARCH_PPC)
+ // For Power / PPC: Expect that the cpu supports VCRYPTO
+ // See https://members.openpowerfoundation.org/document/dl/576
+ // VCRYPTO should be present in POWER8 >= 2.07.
+ // Uses Linux kernel constants from arch/powerpc/include/uapi/asm/cputable.h
+ static const uint32_t kVCRYPTO = 0x02000000;
+ const uint32_t hwcap = GetAuxval(AT_HWCAP2);
+ return (hwcap & kVCRYPTO) != 0;
+
+#elif defined(ABSL_ARCH_ARM)
+ // For ARM: Require crypto+neon
+ // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0500f/CIHBIBBA.html
+ // Uses Linux kernel constants from arch/arm64/include/asm/hwcap.h
+ static const uint32_t kNEON = 1 << 12;
+ uint32_t hwcap = GetAuxval(AT_HWCAP);
+ if ((hwcap & kNEON) == 0) {
+ return false;
+ }
+
+ // And use it again to detect AES.
+ static const uint32_t kAES = 1 << 0;
+ const uint32_t hwcap2 = GetAuxval(AT_HWCAP2);
+ return (hwcap2 & kAES) != 0;
+
+#elif defined(ABSL_ARCH_AARCH64)
+ // For AARCH64: Require crypto+neon
+ // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0500f/CIHBIBBA.html
+ static const uint32_t kNEON = 1 << 1;
+ static const uint32_t kAES = 1 << 3;
+ const uint32_t hwcap = GetAuxval(AT_HWCAP);
+ return ((hwcap & kNEON) != 0) && ((hwcap & kAES) != 0);
+#endif
+
+#else // ABSL_INTERNAL_USE_GETAUXVAL
+ // 3. By default, assume that the compiler default.
+ return ABSL_HAVE_ACCELERATED_AES ? true : false;
+
+#endif
+ // NOTE: There are some other techniques that may be worth trying:
+ //
+ // * Use an environment variable: ABSL_RANDOM_USE_HWAES
+ //
+ // * Rely on compiler-generated target-based dispatch.
+ // Using x86/gcc it might look something like this:
+ //
+ // int __attribute__((target("aes"))) HasAes() { return 1; }
+ // int __attribute__((target("default"))) HasAes() { return 0; }
+ //
+ // This does not work on all architecture/compiler combinations.
+ //
+ // * On Linux consider reading /proc/cpuinfo and/or /proc/self/auxv.
+ // These files have lines which are easy to parse; for ARM/AARCH64 it is quite
+ // easy to find the Features: line and extract aes / neon. Likewise for
+ // PPC.
+ //
+ // * Fork a process and test for SIGILL:
+ //
+ // * Many architectures have instructions to read the ISA. Unfortunately
+ // most of those require that the code is running in ring 0 /
+ // protected-mode.
+ //
+ // There are several examples. e.g. Valgrind detects PPC ISA 2.07:
+ // https://github.com/lu-zero/valgrind/blob/master/none/tests/ppc64/test_isa_2_07_part1.c
+ //
+ // MRS <Xt>, ID_AA64ISAR0_EL1 ; Read ID_AA64ISAR0_EL1 into Xt
+ //
+ // uint64_t val;
+ // __asm __volatile("mrs %0, id_aa64isar0_el1" :"=&r" (val));
+ //
+ // * Use a CPUID-style heuristic database.
+ //
+ // * On Apple (__APPLE__), AES is available on Arm v8.
+ // https://stackoverflow.com/questions/45637888/how-to-determine-armv8-features-at-runtime-on-ios
+}
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
+} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.h b/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.h
index 40ca2a2860..f283f43226 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect.h
@@ -1,33 +1,33 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_
-#define ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_
+#define ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_
+
#include "absl/base/config.h"
-namespace absl {
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// Returns whether the current CPU supports RandenHwAes implementation.
-// This typically involves supporting cryptographic extensions on whichever
-// platform is currently running.
-bool CPUSupportsRandenHwAes();
-
-} // namespace random_internal
+namespace random_internal {
+
+// Returns whether the current CPU supports RandenHwAes implementation.
+// This typically involves supporting cryptographic extensions on whichever
+// platform is currently running.
+bool CPUSupportsRandenHwAes();
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_RANDEN_DETECT_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect/ya.make
index 8191995ddf..62059877ba 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_detect/ya.make
@@ -1,34 +1,34 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
WITHOUT_LICENSE_TEXTS()
-OWNER(g:cpp-contrib)
-
-LICENSE(Apache-2.0)
-
-PEERDIR(
- contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes
+OWNER(g:cpp-contrib)
+
+LICENSE(Apache-2.0)
+
+PEERDIR(
+ contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes
contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys
-)
-
-ADDINCL(
- GLOBAL contrib/restricted/abseil-cpp
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
+)
+
+ADDINCL(
+ GLOBAL contrib/restricted/abseil-cpp
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
CFLAGS(
-DNOMINMAX
)
-SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal)
-
-SRCS(
- randen_detect.cc
-)
-
-END()
+SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal)
+
+SRCS(
+ randen_detect.cc
+)
+
+END()
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_engine.h b/contrib/restricted/abseil-cpp/absl/random/internal/randen_engine.h
index 053c258550..372c3ac2bd 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_engine.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_engine.h
@@ -1,126 +1,126 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_RANDEN_ENGINE_H_
-#define ABSL_RANDOM_INTERNAL_RANDEN_ENGINE_H_
-
-#include <algorithm>
-#include <cinttypes>
-#include <cstdlib>
-#include <iostream>
-#include <iterator>
-#include <limits>
-#include <type_traits>
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_RANDEN_ENGINE_H_
+#define ABSL_RANDOM_INTERNAL_RANDEN_ENGINE_H_
+
+#include <algorithm>
+#include <cinttypes>
+#include <cstdlib>
+#include <iostream>
+#include <iterator>
+#include <limits>
+#include <type_traits>
+
#include "absl/base/internal/endian.h"
-#include "absl/meta/type_traits.h"
-#include "absl/random/internal/iostream_state_saver.h"
-#include "absl/random/internal/randen.h"
-
-namespace absl {
+#include "absl/meta/type_traits.h"
+#include "absl/random/internal/iostream_state_saver.h"
+#include "absl/random/internal/randen.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// Deterministic pseudorandom byte generator with backtracking resistance
-// (leaking the state does not compromise prior outputs). Based on Reverie
-// (see "A Robust and Sponge-Like PRNG with Improved Efficiency") instantiated
-// with an improved Simpira-like permutation.
-// Returns values of type "T" (must be a built-in unsigned integer type).
-//
-// RANDen = RANDom generator or beetroots in Swiss High German.
-// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
-// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
-template <typename T>
-class alignas(16) randen_engine {
- public:
- // C++11 URBG interface:
- using result_type = T;
- static_assert(std::is_unsigned<result_type>::value,
- "randen_engine template argument must be a built-in unsigned "
- "integer type");
-
- static constexpr result_type(min)() {
- return (std::numeric_limits<result_type>::min)();
- }
-
- static constexpr result_type(max)() {
- return (std::numeric_limits<result_type>::max)();
- }
-
- explicit randen_engine(result_type seed_value = 0) { seed(seed_value); }
-
- template <class SeedSequence,
- typename = typename absl::enable_if_t<
- !std::is_same<SeedSequence, randen_engine>::value>>
- explicit randen_engine(SeedSequence&& seq) {
- seed(seq);
- }
-
- randen_engine(const randen_engine&) = default;
-
- // Returns random bits from the buffer in units of result_type.
- result_type operator()() {
- // Refill the buffer if needed (unlikely).
- if (next_ >= kStateSizeT) {
- next_ = kCapacityT;
- impl_.Generate(state_);
- }
-
+namespace random_internal {
+
+// Deterministic pseudorandom byte generator with backtracking resistance
+// (leaking the state does not compromise prior outputs). Based on Reverie
+// (see "A Robust and Sponge-Like PRNG with Improved Efficiency") instantiated
+// with an improved Simpira-like permutation.
+// Returns values of type "T" (must be a built-in unsigned integer type).
+//
+// RANDen = RANDom generator or beetroots in Swiss High German.
+// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
+// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
+template <typename T>
+class alignas(16) randen_engine {
+ public:
+ // C++11 URBG interface:
+ using result_type = T;
+ static_assert(std::is_unsigned<result_type>::value,
+ "randen_engine template argument must be a built-in unsigned "
+ "integer type");
+
+ static constexpr result_type(min)() {
+ return (std::numeric_limits<result_type>::min)();
+ }
+
+ static constexpr result_type(max)() {
+ return (std::numeric_limits<result_type>::max)();
+ }
+
+ explicit randen_engine(result_type seed_value = 0) { seed(seed_value); }
+
+ template <class SeedSequence,
+ typename = typename absl::enable_if_t<
+ !std::is_same<SeedSequence, randen_engine>::value>>
+ explicit randen_engine(SeedSequence&& seq) {
+ seed(seq);
+ }
+
+ randen_engine(const randen_engine&) = default;
+
+ // Returns random bits from the buffer in units of result_type.
+ result_type operator()() {
+ // Refill the buffer if needed (unlikely).
+ if (next_ >= kStateSizeT) {
+ next_ = kCapacityT;
+ impl_.Generate(state_);
+ }
+
return little_endian::ToHost(state_[next_++]);
- }
-
- template <class SeedSequence>
- typename absl::enable_if_t<
- !std::is_convertible<SeedSequence, result_type>::value>
- seed(SeedSequence&& seq) {
- // Zeroes the state.
- seed();
- reseed(seq);
- }
-
- void seed(result_type seed_value = 0) {
- next_ = kStateSizeT;
- // Zeroes the inner state and fills the outer state with seed_value to
- // mimics behaviour of reseed
- std::fill(std::begin(state_), std::begin(state_) + kCapacityT, 0);
- std::fill(std::begin(state_) + kCapacityT, std::end(state_), seed_value);
- }
-
- // Inserts entropy into (part of) the state. Calling this periodically with
- // sufficient entropy ensures prediction resistance (attackers cannot predict
- // future outputs even if state is compromised).
- template <class SeedSequence>
- void reseed(SeedSequence& seq) {
- using sequence_result_type = typename SeedSequence::result_type;
- static_assert(sizeof(sequence_result_type) == 4,
- "SeedSequence::result_type must be 32-bit");
-
- constexpr size_t kBufferSize =
- Randen::kSeedBytes / sizeof(sequence_result_type);
- alignas(16) sequence_result_type buffer[kBufferSize];
-
- // Randen::Absorb XORs the seed into state, which is then mixed by a call
- // to Randen::Generate. Seeding with only the provided entropy is preferred
- // to using an arbitrary generate() call, so use [rand.req.seed_seq]
- // size as a proxy for the number of entropy units that can be generated
- // without relying on seed sequence mixing...
- const size_t entropy_size = seq.size();
- if (entropy_size < kBufferSize) {
- // ... and only request that many values, or 256-bits, when unspecified.
- const size_t requested_entropy = (entropy_size == 0) ? 8u : entropy_size;
- std::fill(std::begin(buffer) + requested_entropy, std::end(buffer), 0);
- seq.generate(std::begin(buffer), std::begin(buffer) + requested_entropy);
+ }
+
+ template <class SeedSequence>
+ typename absl::enable_if_t<
+ !std::is_convertible<SeedSequence, result_type>::value>
+ seed(SeedSequence&& seq) {
+ // Zeroes the state.
+ seed();
+ reseed(seq);
+ }
+
+ void seed(result_type seed_value = 0) {
+ next_ = kStateSizeT;
+ // Zeroes the inner state and fills the outer state with seed_value to
+ // mimics behaviour of reseed
+ std::fill(std::begin(state_), std::begin(state_) + kCapacityT, 0);
+ std::fill(std::begin(state_) + kCapacityT, std::end(state_), seed_value);
+ }
+
+ // Inserts entropy into (part of) the state. Calling this periodically with
+ // sufficient entropy ensures prediction resistance (attackers cannot predict
+ // future outputs even if state is compromised).
+ template <class SeedSequence>
+ void reseed(SeedSequence& seq) {
+ using sequence_result_type = typename SeedSequence::result_type;
+ static_assert(sizeof(sequence_result_type) == 4,
+ "SeedSequence::result_type must be 32-bit");
+
+ constexpr size_t kBufferSize =
+ Randen::kSeedBytes / sizeof(sequence_result_type);
+ alignas(16) sequence_result_type buffer[kBufferSize];
+
+ // Randen::Absorb XORs the seed into state, which is then mixed by a call
+ // to Randen::Generate. Seeding with only the provided entropy is preferred
+ // to using an arbitrary generate() call, so use [rand.req.seed_seq]
+ // size as a proxy for the number of entropy units that can be generated
+ // without relying on seed sequence mixing...
+ const size_t entropy_size = seq.size();
+ if (entropy_size < kBufferSize) {
+ // ... and only request that many values, or 256-bits, when unspecified.
+ const size_t requested_entropy = (entropy_size == 0) ? 8u : entropy_size;
+ std::fill(std::begin(buffer) + requested_entropy, std::end(buffer), 0);
+ seq.generate(std::begin(buffer), std::begin(buffer) + requested_entropy);
#ifdef ABSL_IS_BIG_ENDIAN
// Randen expects the seed buffer to be in Little Endian; reverse it on
// Big Endian platforms.
@@ -128,112 +128,112 @@ class alignas(16) randen_engine {
e = absl::little_endian::FromHost(e);
}
#endif
- // The Randen paper suggests preferentially initializing even-numbered
- // 128-bit vectors of the randen state (there are 16 such vectors).
- // The seed data is merged into the state offset by 128-bits, which
- // implies prefering seed bytes [16..31, ..., 208..223]. Since the
- // buffer is 32-bit values, we swap the corresponding buffer positions in
- // 128-bit chunks.
- size_t dst = kBufferSize;
- while (dst > 7) {
- // leave the odd bucket as-is.
- dst -= 4;
- size_t src = dst >> 1;
- // swap 128-bits into the even bucket
- std::swap(buffer[--dst], buffer[--src]);
- std::swap(buffer[--dst], buffer[--src]);
- std::swap(buffer[--dst], buffer[--src]);
- std::swap(buffer[--dst], buffer[--src]);
- }
- } else {
- seq.generate(std::begin(buffer), std::end(buffer));
- }
- impl_.Absorb(buffer, state_);
-
- // Generate will be called when operator() is called
- next_ = kStateSizeT;
- }
-
- void discard(uint64_t count) {
- uint64_t step = std::min<uint64_t>(kStateSizeT - next_, count);
- count -= step;
-
- constexpr uint64_t kRateT = kStateSizeT - kCapacityT;
- while (count > 0) {
- next_ = kCapacityT;
- impl_.Generate(state_);
- step = std::min<uint64_t>(kRateT, count);
- count -= step;
- }
- next_ += step;
- }
-
- bool operator==(const randen_engine& other) const {
- return next_ == other.next_ &&
- std::equal(std::begin(state_), std::end(state_),
- std::begin(other.state_));
- }
-
- bool operator!=(const randen_engine& other) const {
- return !(*this == other);
- }
-
- template <class CharT, class Traits>
- friend std::basic_ostream<CharT, Traits>& operator<<(
- std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
- const randen_engine<T>& engine) { // NOLINT(runtime/references)
- using numeric_type =
- typename random_internal::stream_format_type<result_type>::type;
- auto saver = random_internal::make_ostream_state_saver(os);
- for (const auto& elem : engine.state_) {
- // In the case that `elem` is `uint8_t`, it must be cast to something
- // larger so that it prints as an integer rather than a character. For
- // simplicity, apply the cast all circumstances.
+ // The Randen paper suggests preferentially initializing even-numbered
+ // 128-bit vectors of the randen state (there are 16 such vectors).
+ // The seed data is merged into the state offset by 128-bits, which
+ // implies prefering seed bytes [16..31, ..., 208..223]. Since the
+ // buffer is 32-bit values, we swap the corresponding buffer positions in
+ // 128-bit chunks.
+ size_t dst = kBufferSize;
+ while (dst > 7) {
+ // leave the odd bucket as-is.
+ dst -= 4;
+ size_t src = dst >> 1;
+ // swap 128-bits into the even bucket
+ std::swap(buffer[--dst], buffer[--src]);
+ std::swap(buffer[--dst], buffer[--src]);
+ std::swap(buffer[--dst], buffer[--src]);
+ std::swap(buffer[--dst], buffer[--src]);
+ }
+ } else {
+ seq.generate(std::begin(buffer), std::end(buffer));
+ }
+ impl_.Absorb(buffer, state_);
+
+ // Generate will be called when operator() is called
+ next_ = kStateSizeT;
+ }
+
+ void discard(uint64_t count) {
+ uint64_t step = std::min<uint64_t>(kStateSizeT - next_, count);
+ count -= step;
+
+ constexpr uint64_t kRateT = kStateSizeT - kCapacityT;
+ while (count > 0) {
+ next_ = kCapacityT;
+ impl_.Generate(state_);
+ step = std::min<uint64_t>(kRateT, count);
+ count -= step;
+ }
+ next_ += step;
+ }
+
+ bool operator==(const randen_engine& other) const {
+ return next_ == other.next_ &&
+ std::equal(std::begin(state_), std::end(state_),
+ std::begin(other.state_));
+ }
+
+ bool operator!=(const randen_engine& other) const {
+ return !(*this == other);
+ }
+
+ template <class CharT, class Traits>
+ friend std::basic_ostream<CharT, Traits>& operator<<(
+ std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
+ const randen_engine<T>& engine) { // NOLINT(runtime/references)
+ using numeric_type =
+ typename random_internal::stream_format_type<result_type>::type;
+ auto saver = random_internal::make_ostream_state_saver(os);
+ for (const auto& elem : engine.state_) {
+ // In the case that `elem` is `uint8_t`, it must be cast to something
+ // larger so that it prints as an integer rather than a character. For
+ // simplicity, apply the cast all circumstances.
os << static_cast<numeric_type>(little_endian::FromHost(elem))
<< os.fill();
- }
- os << engine.next_;
- return os;
- }
-
- template <class CharT, class Traits>
- friend std::basic_istream<CharT, Traits>& operator>>(
- std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
- randen_engine<T>& engine) { // NOLINT(runtime/references)
- using numeric_type =
- typename random_internal::stream_format_type<result_type>::type;
- result_type state[kStateSizeT];
- size_t next;
- for (auto& elem : state) {
- // It is not possible to read uint8_t from wide streams, so it is
- // necessary to read a wider type and then cast it to uint8_t.
- numeric_type value;
- is >> value;
+ }
+ os << engine.next_;
+ return os;
+ }
+
+ template <class CharT, class Traits>
+ friend std::basic_istream<CharT, Traits>& operator>>(
+ std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
+ randen_engine<T>& engine) { // NOLINT(runtime/references)
+ using numeric_type =
+ typename random_internal::stream_format_type<result_type>::type;
+ result_type state[kStateSizeT];
+ size_t next;
+ for (auto& elem : state) {
+ // It is not possible to read uint8_t from wide streams, so it is
+ // necessary to read a wider type and then cast it to uint8_t.
+ numeric_type value;
+ is >> value;
elem = little_endian::ToHost(static_cast<result_type>(value));
- }
- is >> next;
- if (is.fail()) {
- return is;
- }
- std::memcpy(engine.state_, state, sizeof(engine.state_));
- engine.next_ = next;
- return is;
- }
-
- private:
- static constexpr size_t kStateSizeT =
- Randen::kStateBytes / sizeof(result_type);
- static constexpr size_t kCapacityT =
- Randen::kCapacityBytes / sizeof(result_type);
-
- // First kCapacityT are `inner', the others are accessible random bits.
- alignas(16) result_type state_[kStateSizeT];
- size_t next_; // index within state_
- Randen impl_;
-};
-
-} // namespace random_internal
+ }
+ is >> next;
+ if (is.fail()) {
+ return is;
+ }
+ std::memcpy(engine.state_, state, sizeof(engine.state_));
+ engine.next_ = next;
+ return is;
+ }
+
+ private:
+ static constexpr size_t kStateSizeT =
+ Randen::kStateBytes / sizeof(result_type);
+ static constexpr size_t kCapacityT =
+ Randen::kCapacityBytes / sizeof(result_type);
+
+ // First kCapacityT are `inner', the others are accessible random bits.
+ alignas(16) result_type state_[kStateSizeT];
+ size_t next_; // index within state_
+ Randen impl_;
+};
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_RANDEN_ENGINE_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_RANDEN_ENGINE_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.cc b/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.cc
index 6758243a27..fee6677cb4 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.cc
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.cc
@@ -1,289 +1,289 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate
-// symbols from arbitrary system and other headers, since it may be built
-// with different flags from other targets, using different levels of
-// optimization, potentially introducing ODR violations.
-
-#include "absl/random/internal/randen_hwaes.h"
-
-#include <cstdint>
-#include <cstring>
-
-#include "absl/base/attributes.h"
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate
+// symbols from arbitrary system and other headers, since it may be built
+// with different flags from other targets, using different levels of
+// optimization, potentially introducing ODR violations.
+
+#include "absl/random/internal/randen_hwaes.h"
+
+#include <cstdint>
+#include <cstring>
+
+#include "absl/base/attributes.h"
#include "absl/numeric/int128.h"
-#include "absl/random/internal/platform.h"
+#include "absl/random/internal/platform.h"
#include "absl/random/internal/randen_traits.h"
-
-// ABSL_RANDEN_HWAES_IMPL indicates whether this file will contain
-// a hardware accelerated implementation of randen, or whether it
-// will contain stubs that exit the process.
-#if ABSL_HAVE_ACCELERATED_AES
+
+// ABSL_RANDEN_HWAES_IMPL indicates whether this file will contain
+// a hardware accelerated implementation of randen, or whether it
+// will contain stubs that exit the process.
+#if ABSL_HAVE_ACCELERATED_AES
// The following plaforms have implemented RandenHwAes.
#if defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32) || \
defined(ABSL_ARCH_PPC) || defined(ABSL_ARCH_ARM) || \
defined(ABSL_ARCH_AARCH64)
-#define ABSL_RANDEN_HWAES_IMPL 1
-#endif
-#endif
-
-#if !defined(ABSL_RANDEN_HWAES_IMPL)
-// No accelerated implementation is supported.
-// The RandenHwAes functions are stubs that print an error and exit.
-
-#include <cstdio>
-#include <cstdlib>
-
-namespace absl {
+#define ABSL_RANDEN_HWAES_IMPL 1
+#endif
+#endif
+
+#if !defined(ABSL_RANDEN_HWAES_IMPL)
+// No accelerated implementation is supported.
+// The RandenHwAes functions are stubs that print an error and exit.
+
+#include <cstdio>
+#include <cstdlib>
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// No accelerated implementation.
-bool HasRandenHwAesImplementation() { return false; }
-
-// NOLINTNEXTLINE
-const void* RandenHwAes::GetKeys() {
- // Attempted to dispatch to an unsupported dispatch target.
- const int d = ABSL_RANDOM_INTERNAL_AES_DISPATCH;
- fprintf(stderr, "AES Hardware detection failed (%d).\n", d);
- exit(1);
- return nullptr;
-}
-
-// NOLINTNEXTLINE
-void RandenHwAes::Absorb(const void*, void*) {
- // Attempted to dispatch to an unsupported dispatch target.
- const int d = ABSL_RANDOM_INTERNAL_AES_DISPATCH;
- fprintf(stderr, "AES Hardware detection failed (%d).\n", d);
- exit(1);
-}
-
-// NOLINTNEXTLINE
-void RandenHwAes::Generate(const void*, void*) {
- // Attempted to dispatch to an unsupported dispatch target.
- const int d = ABSL_RANDOM_INTERNAL_AES_DISPATCH;
- fprintf(stderr, "AES Hardware detection failed (%d).\n", d);
- exit(1);
-}
-
-} // namespace random_internal
+namespace random_internal {
+
+// No accelerated implementation.
+bool HasRandenHwAesImplementation() { return false; }
+
+// NOLINTNEXTLINE
+const void* RandenHwAes::GetKeys() {
+ // Attempted to dispatch to an unsupported dispatch target.
+ const int d = ABSL_RANDOM_INTERNAL_AES_DISPATCH;
+ fprintf(stderr, "AES Hardware detection failed (%d).\n", d);
+ exit(1);
+ return nullptr;
+}
+
+// NOLINTNEXTLINE
+void RandenHwAes::Absorb(const void*, void*) {
+ // Attempted to dispatch to an unsupported dispatch target.
+ const int d = ABSL_RANDOM_INTERNAL_AES_DISPATCH;
+ fprintf(stderr, "AES Hardware detection failed (%d).\n", d);
+ exit(1);
+}
+
+// NOLINTNEXTLINE
+void RandenHwAes::Generate(const void*, void*) {
+ // Attempted to dispatch to an unsupported dispatch target.
+ const int d = ABSL_RANDOM_INTERNAL_AES_DISPATCH;
+ fprintf(stderr, "AES Hardware detection failed (%d).\n", d);
+ exit(1);
+}
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#else // defined(ABSL_RANDEN_HWAES_IMPL)
-//
-// Accelerated implementations are supported.
-// We need the per-architecture includes and defines.
-//
+} // namespace absl
+
+#else // defined(ABSL_RANDEN_HWAES_IMPL)
+//
+// Accelerated implementations are supported.
+// We need the per-architecture includes and defines.
+//
namespace {
-
+
using absl::random_internal::RandenTraits;
-
+
} // namespace
-// TARGET_CRYPTO defines a crypto attribute for each architecture.
-//
-// NOTE: Evaluate whether we should eliminate ABSL_TARGET_CRYPTO.
-#if (defined(__clang__) || defined(__GNUC__))
-#if defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32)
-#define ABSL_TARGET_CRYPTO __attribute__((target("aes")))
-#elif defined(ABSL_ARCH_PPC)
-#define ABSL_TARGET_CRYPTO __attribute__((target("crypto")))
-#else
-#define ABSL_TARGET_CRYPTO
-#endif
-#else
-#define ABSL_TARGET_CRYPTO
-#endif
-
-#if defined(ABSL_ARCH_PPC)
-// NOTE: Keep in mind that PPC can operate in little-endian or big-endian mode,
-// however the PPC altivec vector registers (and thus the AES instructions)
-// always operate in big-endian mode.
-
-#include <altivec.h>
-// <altivec.h> #defines vector __vector; in C++, this is bad form.
-#undef vector
+// TARGET_CRYPTO defines a crypto attribute for each architecture.
+//
+// NOTE: Evaluate whether we should eliminate ABSL_TARGET_CRYPTO.
+#if (defined(__clang__) || defined(__GNUC__))
+#if defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32)
+#define ABSL_TARGET_CRYPTO __attribute__((target("aes")))
+#elif defined(ABSL_ARCH_PPC)
+#define ABSL_TARGET_CRYPTO __attribute__((target("crypto")))
+#else
+#define ABSL_TARGET_CRYPTO
+#endif
+#else
+#define ABSL_TARGET_CRYPTO
+#endif
+
+#if defined(ABSL_ARCH_PPC)
+// NOTE: Keep in mind that PPC can operate in little-endian or big-endian mode,
+// however the PPC altivec vector registers (and thus the AES instructions)
+// always operate in big-endian mode.
+
+#include <altivec.h>
+// <altivec.h> #defines vector __vector; in C++, this is bad form.
+#undef vector
#undef bool
-
-// Rely on the PowerPC AltiVec vector operations for accelerated AES
-// instructions. GCC support of the PPC vector types is described in:
-// https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/PowerPC-AltiVec_002fVSX-Built-in-Functions.html
-//
-// Already provides operator^=.
-using Vector128 = __vector unsigned long long; // NOLINT(runtime/int)
-
-namespace {
-inline ABSL_TARGET_CRYPTO Vector128 ReverseBytes(const Vector128& v) {
- // Reverses the bytes of the vector.
- const __vector unsigned char perm = {15, 14, 13, 12, 11, 10, 9, 8,
- 7, 6, 5, 4, 3, 2, 1, 0};
- return vec_perm(v, v, perm);
-}
-
-// WARNING: these load/store in native byte order. It is OK to load and then
-// store an unchanged vector, but interpreting the bits as a number or input
-// to AES will have undefined results.
-inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) {
- return vec_vsx_ld(0, reinterpret_cast<const Vector128*>(from));
-}
-
-inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) {
- vec_vsx_st(v, 0, reinterpret_cast<Vector128*>(to));
-}
-
-// One round of AES. "round_key" is a public constant for breaking the
-// symmetry of AES (ensures previously equal columns differ afterwards).
-inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state,
- const Vector128& round_key) {
- return Vector128(__builtin_crypto_vcipher(state, round_key));
-}
-
-// Enables native loads in the round loop by pre-swapping.
+
+// Rely on the PowerPC AltiVec vector operations for accelerated AES
+// instructions. GCC support of the PPC vector types is described in:
+// https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/PowerPC-AltiVec_002fVSX-Built-in-Functions.html
+//
+// Already provides operator^=.
+using Vector128 = __vector unsigned long long; // NOLINT(runtime/int)
+
+namespace {
+inline ABSL_TARGET_CRYPTO Vector128 ReverseBytes(const Vector128& v) {
+ // Reverses the bytes of the vector.
+ const __vector unsigned char perm = {15, 14, 13, 12, 11, 10, 9, 8,
+ 7, 6, 5, 4, 3, 2, 1, 0};
+ return vec_perm(v, v, perm);
+}
+
+// WARNING: these load/store in native byte order. It is OK to load and then
+// store an unchanged vector, but interpreting the bits as a number or input
+// to AES will have undefined results.
+inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) {
+ return vec_vsx_ld(0, reinterpret_cast<const Vector128*>(from));
+}
+
+inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) {
+ vec_vsx_st(v, 0, reinterpret_cast<Vector128*>(to));
+}
+
+// One round of AES. "round_key" is a public constant for breaking the
+// symmetry of AES (ensures previously equal columns differ afterwards).
+inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state,
+ const Vector128& round_key) {
+ return Vector128(__builtin_crypto_vcipher(state, round_key));
+}
+
+// Enables native loads in the round loop by pre-swapping.
inline ABSL_TARGET_CRYPTO void SwapEndian(absl::uint128* state) {
for (uint32_t block = 0; block < RandenTraits::kFeistelBlocks; ++block) {
Vector128Store(ReverseBytes(Vector128Load(state + block)), state + block);
- }
-}
-
-} // namespace
-
-#elif defined(ABSL_ARCH_ARM) || defined(ABSL_ARCH_AARCH64)
-
-// Rely on the ARM NEON+Crypto advanced simd types, defined in <arm_neon.h>.
-// uint8x16_t is the user alias for underlying __simd128_uint8_t type.
-// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0073a/IHI0073A_arm_neon_intrinsics_ref.pdf
-//
-// <arm_neon> defines the following
-//
-// typedef __attribute__((neon_vector_type(16))) uint8_t uint8x16_t;
-// typedef __attribute__((neon_vector_type(16))) int8_t int8x16_t;
-// typedef __attribute__((neon_polyvector_type(16))) int8_t poly8x16_t;
-//
-// vld1q_v
-// vst1q_v
-// vaeseq_v
-// vaesmcq_v
-#include <arm_neon.h>
-
-// Already provides operator^=.
-using Vector128 = uint8x16_t;
-
-namespace {
-
-inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) {
- return vld1q_u8(reinterpret_cast<const uint8_t*>(from));
-}
-
-inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) {
- vst1q_u8(reinterpret_cast<uint8_t*>(to), v);
-}
-
-// One round of AES. "round_key" is a public constant for breaking the
-// symmetry of AES (ensures previously equal columns differ afterwards).
-inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state,
- const Vector128& round_key) {
- // It is important to always use the full round function - omitting the
- // final MixColumns reduces security [https://eprint.iacr.org/2010/041.pdf]
- // and does not help because we never decrypt.
- //
- // Note that ARM divides AES instructions differently than x86 / PPC,
- // And we need to skip the first AddRoundKey step and add an extra
- // AddRoundKey step to the end. Lucky for us this is just XOR.
- return vaesmcq_u8(vaeseq_u8(state, uint8x16_t{})) ^ round_key;
-}
-
+ }
+}
+
+} // namespace
+
+#elif defined(ABSL_ARCH_ARM) || defined(ABSL_ARCH_AARCH64)
+
+// Rely on the ARM NEON+Crypto advanced simd types, defined in <arm_neon.h>.
+// uint8x16_t is the user alias for underlying __simd128_uint8_t type.
+// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0073a/IHI0073A_arm_neon_intrinsics_ref.pdf
+//
+// <arm_neon> defines the following
+//
+// typedef __attribute__((neon_vector_type(16))) uint8_t uint8x16_t;
+// typedef __attribute__((neon_vector_type(16))) int8_t int8x16_t;
+// typedef __attribute__((neon_polyvector_type(16))) int8_t poly8x16_t;
+//
+// vld1q_v
+// vst1q_v
+// vaeseq_v
+// vaesmcq_v
+#include <arm_neon.h>
+
+// Already provides operator^=.
+using Vector128 = uint8x16_t;
+
+namespace {
+
+inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) {
+ return vld1q_u8(reinterpret_cast<const uint8_t*>(from));
+}
+
+inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) {
+ vst1q_u8(reinterpret_cast<uint8_t*>(to), v);
+}
+
+// One round of AES. "round_key" is a public constant for breaking the
+// symmetry of AES (ensures previously equal columns differ afterwards).
+inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state,
+ const Vector128& round_key) {
+ // It is important to always use the full round function - omitting the
+ // final MixColumns reduces security [https://eprint.iacr.org/2010/041.pdf]
+ // and does not help because we never decrypt.
+ //
+ // Note that ARM divides AES instructions differently than x86 / PPC,
+ // And we need to skip the first AddRoundKey step and add an extra
+ // AddRoundKey step to the end. Lucky for us this is just XOR.
+ return vaesmcq_u8(vaeseq_u8(state, uint8x16_t{})) ^ round_key;
+}
+
inline ABSL_TARGET_CRYPTO void SwapEndian(void*) {}
-
-} // namespace
-
-#elif defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32)
-// On x86 we rely on the aesni instructions
+
+} // namespace
+
+#elif defined(ABSL_ARCH_X86_64) || defined(ABSL_ARCH_X86_32)
+// On x86 we rely on the aesni instructions
#include <immintrin.h>
-
-namespace {
-
-// Vector128 class is only wrapper for __m128i, benchmark indicates that it's
-// faster than using __m128i directly.
-class Vector128 {
- public:
- // Convert from/to intrinsics.
+
+namespace {
+
+// Vector128 class is only wrapper for __m128i, benchmark indicates that it's
+// faster than using __m128i directly.
+class Vector128 {
+ public:
+ // Convert from/to intrinsics.
inline explicit Vector128(const __m128i& v) : data_(v) {}
-
- inline __m128i data() const { return data_; }
-
- inline Vector128& operator^=(const Vector128& other) {
- data_ = _mm_xor_si128(data_, other.data());
- return *this;
- }
-
- private:
- __m128i data_;
-};
-
-inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) {
- return Vector128(_mm_load_si128(reinterpret_cast<const __m128i*>(from)));
-}
-
-inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) {
- _mm_store_si128(reinterpret_cast<__m128i*>(to), v.data());
-}
-
-// One round of AES. "round_key" is a public constant for breaking the
-// symmetry of AES (ensures previously equal columns differ afterwards).
-inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state,
- const Vector128& round_key) {
- // It is important to always use the full round function - omitting the
- // final MixColumns reduces security [https://eprint.iacr.org/2010/041.pdf]
- // and does not help because we never decrypt.
- return Vector128(_mm_aesenc_si128(state.data(), round_key.data()));
-}
-
+
+ inline __m128i data() const { return data_; }
+
+ inline Vector128& operator^=(const Vector128& other) {
+ data_ = _mm_xor_si128(data_, other.data());
+ return *this;
+ }
+
+ private:
+ __m128i data_;
+};
+
+inline ABSL_TARGET_CRYPTO Vector128 Vector128Load(const void* from) {
+ return Vector128(_mm_load_si128(reinterpret_cast<const __m128i*>(from)));
+}
+
+inline ABSL_TARGET_CRYPTO void Vector128Store(const Vector128& v, void* to) {
+ _mm_store_si128(reinterpret_cast<__m128i*>(to), v.data());
+}
+
+// One round of AES. "round_key" is a public constant for breaking the
+// symmetry of AES (ensures previously equal columns differ afterwards).
+inline ABSL_TARGET_CRYPTO Vector128 AesRound(const Vector128& state,
+ const Vector128& round_key) {
+ // It is important to always use the full round function - omitting the
+ // final MixColumns reduces security [https://eprint.iacr.org/2010/041.pdf]
+ // and does not help because we never decrypt.
+ return Vector128(_mm_aesenc_si128(state.data(), round_key.data()));
+}
+
inline ABSL_TARGET_CRYPTO void SwapEndian(void*) {}
-
-} // namespace
-
-#endif
-
-#ifdef __clang__
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunknown-pragmas"
-#endif
-
-// At this point, all of the platform-specific features have been defined /
-// implemented.
-//
-// REQUIRES: using Vector128 = ...
-// REQUIRES: Vector128 Vector128Load(void*) {...}
-// REQUIRES: void Vector128Store(Vector128, void*) {...}
-// REQUIRES: Vector128 AesRound(Vector128, Vector128) {...}
-// REQUIRES: void SwapEndian(uint64_t*) {...}
-//
-// PROVIDES: absl::random_internal::RandenHwAes::Absorb
-// PROVIDES: absl::random_internal::RandenHwAes::Generate
+
+} // namespace
+
+#endif
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunknown-pragmas"
+#endif
+
+// At this point, all of the platform-specific features have been defined /
+// implemented.
+//
+// REQUIRES: using Vector128 = ...
+// REQUIRES: Vector128 Vector128Load(void*) {...}
+// REQUIRES: void Vector128Store(Vector128, void*) {...}
+// REQUIRES: Vector128 AesRound(Vector128, Vector128) {...}
+// REQUIRES: void SwapEndian(uint64_t*) {...}
+//
+// PROVIDES: absl::random_internal::RandenHwAes::Absorb
+// PROVIDES: absl::random_internal::RandenHwAes::Generate
namespace {
-
-// Block shuffles applies a shuffle to the entire state between AES rounds.
-// Improved odd-even shuffle from "New criterion for diffusion property".
+
+// Block shuffles applies a shuffle to the entire state between AES rounds.
+// Improved odd-even shuffle from "New criterion for diffusion property".
inline ABSL_TARGET_CRYPTO void BlockShuffle(absl::uint128* state) {
static_assert(RandenTraits::kFeistelBlocks == 16,
"Expecting 16 FeistelBlocks.");
-
+
constexpr size_t shuffle[RandenTraits::kFeistelBlocks] = {
7, 2, 13, 4, 11, 8, 3, 6, 15, 0, 9, 10, 1, 14, 5, 12};
-
+
const Vector128 v0 = Vector128Load(state + shuffle[0]);
const Vector128 v1 = Vector128Load(state + shuffle[1]);
const Vector128 v2 = Vector128Load(state + shuffle[2]);
@@ -300,7 +300,7 @@ inline ABSL_TARGET_CRYPTO void BlockShuffle(absl::uint128* state) {
const Vector128 w5 = Vector128Load(state + shuffle[13]);
const Vector128 w6 = Vector128Load(state + shuffle[14]);
const Vector128 w7 = Vector128Load(state + shuffle[15]);
-
+
Vector128Store(v0, state + 0);
Vector128Store(v1, state + 1);
Vector128Store(v2, state + 2);
@@ -317,21 +317,21 @@ inline ABSL_TARGET_CRYPTO void BlockShuffle(absl::uint128* state) {
Vector128Store(w5, state + 13);
Vector128Store(w6, state + 14);
Vector128Store(w7, state + 15);
-}
-
-// Feistel round function using two AES subrounds. Very similar to F()
-// from Simpira v2, but with independent subround keys. Uses 17 AES rounds
-// per 16 bytes (vs. 10 for AES-CTR). Computing eight round functions in
-// parallel hides the 7-cycle AESNI latency on HSW. Note that the Feistel
-// XORs are 'free' (included in the second AES instruction).
+}
+
+// Feistel round function using two AES subrounds. Very similar to F()
+// from Simpira v2, but with independent subround keys. Uses 17 AES rounds
+// per 16 bytes (vs. 10 for AES-CTR). Computing eight round functions in
+// parallel hides the 7-cycle AESNI latency on HSW. Note that the Feistel
+// XORs are 'free' (included in the second AES instruction).
inline ABSL_TARGET_CRYPTO const absl::uint128* FeistelRound(
absl::uint128* state,
const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) {
static_assert(RandenTraits::kFeistelBlocks == 16,
"Expecting 16 FeistelBlocks.");
-
- // MSVC does a horrible job at unrolling loops.
- // So we unroll the loop by hand to improve the performance.
+
+ // MSVC does a horrible job at unrolling loops.
+ // So we unroll the loop by hand to improve the performance.
const Vector128 s0 = Vector128Load(state + 0);
const Vector128 s1 = Vector128Load(state + 1);
const Vector128 s2 = Vector128Load(state + 2);
@@ -348,28 +348,28 @@ inline ABSL_TARGET_CRYPTO const absl::uint128* FeistelRound(
const Vector128 s13 = Vector128Load(state + 13);
const Vector128 s14 = Vector128Load(state + 14);
const Vector128 s15 = Vector128Load(state + 15);
-
- // Encode even blocks with keys.
- const Vector128 e0 = AesRound(s0, Vector128Load(keys + 0));
- const Vector128 e2 = AesRound(s2, Vector128Load(keys + 1));
- const Vector128 e4 = AesRound(s4, Vector128Load(keys + 2));
- const Vector128 e6 = AesRound(s6, Vector128Load(keys + 3));
- const Vector128 e8 = AesRound(s8, Vector128Load(keys + 4));
- const Vector128 e10 = AesRound(s10, Vector128Load(keys + 5));
- const Vector128 e12 = AesRound(s12, Vector128Load(keys + 6));
- const Vector128 e14 = AesRound(s14, Vector128Load(keys + 7));
-
- // Encode odd blocks with even output from above.
- const Vector128 o1 = AesRound(e0, s1);
- const Vector128 o3 = AesRound(e2, s3);
- const Vector128 o5 = AesRound(e4, s5);
- const Vector128 o7 = AesRound(e6, s7);
- const Vector128 o9 = AesRound(e8, s9);
- const Vector128 o11 = AesRound(e10, s11);
- const Vector128 o13 = AesRound(e12, s13);
- const Vector128 o15 = AesRound(e14, s15);
-
- // Store odd blocks. (These will be shuffled later).
+
+ // Encode even blocks with keys.
+ const Vector128 e0 = AesRound(s0, Vector128Load(keys + 0));
+ const Vector128 e2 = AesRound(s2, Vector128Load(keys + 1));
+ const Vector128 e4 = AesRound(s4, Vector128Load(keys + 2));
+ const Vector128 e6 = AesRound(s6, Vector128Load(keys + 3));
+ const Vector128 e8 = AesRound(s8, Vector128Load(keys + 4));
+ const Vector128 e10 = AesRound(s10, Vector128Load(keys + 5));
+ const Vector128 e12 = AesRound(s12, Vector128Load(keys + 6));
+ const Vector128 e14 = AesRound(s14, Vector128Load(keys + 7));
+
+ // Encode odd blocks with even output from above.
+ const Vector128 o1 = AesRound(e0, s1);
+ const Vector128 o3 = AesRound(e2, s3);
+ const Vector128 o5 = AesRound(e4, s5);
+ const Vector128 o7 = AesRound(e6, s7);
+ const Vector128 o9 = AesRound(e8, s9);
+ const Vector128 o11 = AesRound(e10, s11);
+ const Vector128 o13 = AesRound(e12, s13);
+ const Vector128 o15 = AesRound(e14, s15);
+
+ // Store odd blocks. (These will be shuffled later).
Vector128Store(o1, state + 1);
Vector128Store(o3, state + 3);
Vector128Store(o5, state + 5);
@@ -378,149 +378,149 @@ inline ABSL_TARGET_CRYPTO const absl::uint128* FeistelRound(
Vector128Store(o11, state + 11);
Vector128Store(o13, state + 13);
Vector128Store(o15, state + 15);
-
- return keys + 8;
-}
-
-// Cryptographic permutation based via type-2 Generalized Feistel Network.
-// Indistinguishable from ideal by chosen-ciphertext adversaries using less than
-// 2^64 queries if the round function is a PRF. This is similar to the b=8 case
-// of Simpira v2, but more efficient than its generic construction for b=16.
-inline ABSL_TARGET_CRYPTO void Permute(
+
+ return keys + 8;
+}
+
+// Cryptographic permutation based via type-2 Generalized Feistel Network.
+// Indistinguishable from ideal by chosen-ciphertext adversaries using less than
+// 2^64 queries if the round function is a PRF. This is similar to the b=8 case
+// of Simpira v2, but more efficient than its generic construction for b=16.
+inline ABSL_TARGET_CRYPTO void Permute(
absl::uint128* state,
const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) {
- // (Successfully unrolled; the first iteration jumps into the second half)
-#ifdef __clang__
-#pragma clang loop unroll_count(2)
-#endif
+ // (Successfully unrolled; the first iteration jumps into the second half)
+#ifdef __clang__
+#pragma clang loop unroll_count(2)
+#endif
for (size_t round = 0; round < RandenTraits::kFeistelRounds; ++round) {
keys = FeistelRound(state, keys);
- BlockShuffle(state);
- }
-}
-
-} // namespace
-
-namespace absl {
+ BlockShuffle(state);
+ }
+}
+
+} // namespace
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-bool HasRandenHwAesImplementation() { return true; }
-
-const void* ABSL_TARGET_CRYPTO RandenHwAes::GetKeys() {
- // Round keys for one AES per Feistel round and branch.
- // The canonical implementation uses first digits of Pi.
+namespace random_internal {
+
+bool HasRandenHwAesImplementation() { return true; }
+
+const void* ABSL_TARGET_CRYPTO RandenHwAes::GetKeys() {
+ // Round keys for one AES per Feistel round and branch.
+ // The canonical implementation uses first digits of Pi.
#if defined(ABSL_ARCH_PPC)
return kRandenRoundKeysBE;
#else
return kRandenRoundKeys;
#endif
-}
-
-// NOLINTNEXTLINE
-void ABSL_TARGET_CRYPTO RandenHwAes::Absorb(const void* seed_void,
- void* state_void) {
+}
+
+// NOLINTNEXTLINE
+void ABSL_TARGET_CRYPTO RandenHwAes::Absorb(const void* seed_void,
+ void* state_void) {
static_assert(RandenTraits::kCapacityBytes / sizeof(Vector128) == 1,
"Unexpected Randen kCapacityBlocks");
static_assert(RandenTraits::kStateBytes / sizeof(Vector128) == 16,
"Unexpected Randen kStateBlocks");
-
+
auto* state = reinterpret_cast<absl::uint128 * ABSL_RANDOM_INTERNAL_RESTRICT>(
state_void);
const auto* seed =
reinterpret_cast<const absl::uint128 * ABSL_RANDOM_INTERNAL_RESTRICT>(
seed_void);
-
+
Vector128 b1 = Vector128Load(state + 1);
b1 ^= Vector128Load(seed + 0);
Vector128Store(b1, state + 1);
-
+
Vector128 b2 = Vector128Load(state + 2);
b2 ^= Vector128Load(seed + 1);
Vector128Store(b2, state + 2);
-
+
Vector128 b3 = Vector128Load(state + 3);
b3 ^= Vector128Load(seed + 2);
Vector128Store(b3, state + 3);
-
+
Vector128 b4 = Vector128Load(state + 4);
b4 ^= Vector128Load(seed + 3);
Vector128Store(b4, state + 4);
-
+
Vector128 b5 = Vector128Load(state + 5);
b5 ^= Vector128Load(seed + 4);
Vector128Store(b5, state + 5);
-
+
Vector128 b6 = Vector128Load(state + 6);
b6 ^= Vector128Load(seed + 5);
Vector128Store(b6, state + 6);
-
+
Vector128 b7 = Vector128Load(state + 7);
b7 ^= Vector128Load(seed + 6);
Vector128Store(b7, state + 7);
-
+
Vector128 b8 = Vector128Load(state + 8);
b8 ^= Vector128Load(seed + 7);
Vector128Store(b8, state + 8);
-
+
Vector128 b9 = Vector128Load(state + 9);
b9 ^= Vector128Load(seed + 8);
Vector128Store(b9, state + 9);
-
+
Vector128 b10 = Vector128Load(state + 10);
b10 ^= Vector128Load(seed + 9);
Vector128Store(b10, state + 10);
-
+
Vector128 b11 = Vector128Load(state + 11);
b11 ^= Vector128Load(seed + 10);
Vector128Store(b11, state + 11);
-
+
Vector128 b12 = Vector128Load(state + 12);
b12 ^= Vector128Load(seed + 11);
Vector128Store(b12, state + 12);
-
+
Vector128 b13 = Vector128Load(state + 13);
b13 ^= Vector128Load(seed + 12);
Vector128Store(b13, state + 13);
-
+
Vector128 b14 = Vector128Load(state + 14);
b14 ^= Vector128Load(seed + 13);
Vector128Store(b14, state + 14);
-
+
Vector128 b15 = Vector128Load(state + 15);
b15 ^= Vector128Load(seed + 14);
Vector128Store(b15, state + 15);
-}
-
-// NOLINTNEXTLINE
+}
+
+// NOLINTNEXTLINE
void ABSL_TARGET_CRYPTO RandenHwAes::Generate(const void* keys_void,
- void* state_void) {
+ void* state_void) {
static_assert(RandenTraits::kCapacityBytes == sizeof(Vector128),
"Capacity mismatch");
-
+
auto* state = reinterpret_cast<absl::uint128*>(state_void);
const auto* keys = reinterpret_cast<const absl::uint128*>(keys_void);
-
- const Vector128 prev_inner = Vector128Load(state);
-
- SwapEndian(state);
-
+
+ const Vector128 prev_inner = Vector128Load(state);
+
+ SwapEndian(state);
+
Permute(state, keys);
-
- SwapEndian(state);
-
- // Ensure backtracking resistance.
- Vector128 inner = Vector128Load(state);
- inner ^= prev_inner;
- Vector128Store(inner, state);
-}
-
-#ifdef __clang__
-#pragma clang diagnostic pop
-#endif
-
-} // namespace random_internal
+
+ SwapEndian(state);
+
+ // Ensure backtracking resistance.
+ Vector128 inner = Vector128Load(state);
+ inner ^= prev_inner;
+ Vector128Store(inner, state);
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // (ABSL_RANDEN_HWAES_IMPL)
+} // namespace absl
+
+#endif // (ABSL_RANDEN_HWAES_IMPL)
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.h b/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.h
index c56f8cad5e..71a7f69f25 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes.h
@@ -1,50 +1,50 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_
-#define ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_
+#define ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_
+
#include "absl/base/config.h"
-// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate
-// symbols from arbitrary system and other headers, since it may be built
-// with different flags from other targets, using different levels of
-// optimization, potentially introducing ODR violations.
-
-namespace absl {
+// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate
+// symbols from arbitrary system and other headers, since it may be built
+// with different flags from other targets, using different levels of
+// optimization, potentially introducing ODR violations.
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
+namespace random_internal {
+
// RANDen = RANDom generator or beetroots in Swiss High German.
-// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
-// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
-//
-// RandenHwAes implements the basic state manipulation methods.
-class RandenHwAes {
- public:
- static void Generate(const void* keys, void* state_void);
- static void Absorb(const void* seed_void, void* state_void);
- static const void* GetKeys();
-};
-
-// HasRandenHwAesImplementation returns true when there is an accelerated
-// implementation, and false otherwise. If there is no implementation,
-// then attempting to use it will abort the program.
-bool HasRandenHwAesImplementation();
-
-} // namespace random_internal
+// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
+// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
+//
+// RandenHwAes implements the basic state manipulation methods.
+class RandenHwAes {
+ public:
+ static void Generate(const void* keys, void* state_void);
+ static void Absorb(const void* seed_void, void* state_void);
+ static const void* GetKeys();
+};
+
+// HasRandenHwAesImplementation returns true when there is an accelerated
+// implementation, and false otherwise. If there is no implementation,
+// then attempting to use it will abort the program.
+bool HasRandenHwAesImplementation();
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_RANDEN_HWAES_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes/ya.make
index 14ef865fd2..267ce26c5f 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes/ya.make
@@ -1,33 +1,33 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
WITHOUT_LICENSE_TEXTS()
-OWNER(g:cpp-contrib)
-
-LICENSE(Apache-2.0)
-
+OWNER(g:cpp-contrib)
+
+LICENSE(Apache-2.0)
+
PEERDIR(
contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys
)
-ADDINCL(
- GLOBAL contrib/restricted/abseil-cpp
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
+ADDINCL(
+ GLOBAL contrib/restricted/abseil-cpp
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
CFLAGS(
-DNOMINMAX
)
-SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal)
-
-SRCS(
- randen_hwaes.cc
-)
-
-END()
+SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal)
+
+SRCS(
+ randen_hwaes.cc
+)
+
+END()
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.cc b/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.cc
index 35446ef214..9bfd2a4092 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.cc
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.cc
@@ -1,51 +1,51 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/random/internal/randen_slow.h"
-
-#include <cstddef>
-#include <cstdint>
-#include <cstring>
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/random/internal/randen_slow.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+
#include "absl/base/attributes.h"
#include "absl/base/internal/endian.h"
#include "absl/numeric/int128.h"
-#include "absl/random/internal/platform.h"
+#include "absl/random/internal/platform.h"
#include "absl/random/internal/randen_traits.h"
-
-#if ABSL_HAVE_ATTRIBUTE(always_inline) || \
- (defined(__GNUC__) && !defined(__clang__))
-#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE \
- __attribute__((always_inline))
-#elif defined(_MSC_VER)
-// We can achieve something similar to attribute((always_inline)) with MSVC by
-// using the __forceinline keyword, however this is not perfect. MSVC is
-// much less aggressive about inlining, and even with the __forceinline keyword.
-#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE __forceinline
-#else
-#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE
-#endif
-
-namespace {
-
-// AES portions based on rijndael-alg-fst.c,
+
+#if ABSL_HAVE_ATTRIBUTE(always_inline) || \
+ (defined(__GNUC__) && !defined(__clang__))
+#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE \
+ __attribute__((always_inline))
+#elif defined(_MSC_VER)
+// We can achieve something similar to attribute((always_inline)) with MSVC by
+// using the __forceinline keyword, however this is not perfect. MSVC is
+// much less aggressive about inlining, and even with the __forceinline keyword.
+#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE __forceinline
+#else
+#define ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE
+#endif
+
+namespace {
+
+// AES portions based on rijndael-alg-fst.c,
// https://fastcrypto.org/front/misc/rijndael-alg-fst.c, and modified for
// platform-endianness.
-//
-// Implementation of
-// http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf
-constexpr uint32_t te0[256] = {
+//
+// Implementation of
+// http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf
+constexpr uint32_t te0[256] = {
0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6,
0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56,
0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 0x45caca8f, 0x9d82821f,
@@ -89,9 +89,9 @@ constexpr uint32_t te0[256] = {
0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7,
0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e,
0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c,
-};
-
-constexpr uint32_t te1[256] = {
+};
+
+constexpr uint32_t te1[256] = {
0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d, 0x6b6bd6bd,
0x6f6fdeb1, 0xc5c59154, 0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d,
0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, 0xcaca8f45, 0x82821f9d,
@@ -135,9 +135,9 @@ constexpr uint32_t te1[256] = {
0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, 0xbfbf65da, 0xe6e6d731,
0x424284c6, 0x6868d0b8, 0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11,
0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a,
-};
-
-constexpr uint32_t te2[256] = {
+};
+
+constexpr uint32_t te2[256] = {
0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2, 0x6bd6bd6b,
0x6fdeb16f, 0xc59154c5, 0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b,
0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, 0xca8f45ca, 0x821f9d82,
@@ -181,9 +181,9 @@ constexpr uint32_t te2[256] = {
0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, 0xbf65dabf, 0xe6d731e6,
0x4284c642, 0x68d0b868, 0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f,
0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16,
-};
-
-constexpr uint32_t te3[256] = {
+};
+
+constexpr uint32_t te3[256] = {
0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2, 0xd6bd6b6b,
0xdeb16f6f, 0x9154c5c5, 0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b,
0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, 0x8f45caca, 0x1f9d8282,
@@ -227,31 +227,31 @@ constexpr uint32_t te3[256] = {
0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, 0x65dabfbf, 0xd731e6e6,
0x84c64242, 0xd0b86868, 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f,
0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616,
-};
-
-// Software implementation of the Vector128 class, using uint32_t
-// as an underlying vector register.
+};
+
+// Software implementation of the Vector128 class, using uint32_t
+// as an underlying vector register.
struct alignas(16) Vector128 {
- uint32_t s[4];
-};
-
-inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128
+ uint32_t s[4];
+};
+
+inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128
Vector128Load(const void* from) {
- Vector128 result;
+ Vector128 result;
std::memcpy(result.s, from, sizeof(Vector128));
- return result;
-}
-
-inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Vector128Store(
+ return result;
+}
+
+inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Vector128Store(
const Vector128& v, void* to) {
std::memcpy(to, v.s, sizeof(Vector128));
-}
-
-// One round of AES. "round_key" is a public constant for breaking the
-// symmetry of AES (ensures previously equal columns differ afterwards).
-inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128
-AesRound(const Vector128& state, const Vector128& round_key) {
- Vector128 result;
+}
+
+// One round of AES. "round_key" is a public constant for breaking the
+// symmetry of AES (ensures previously equal columns differ afterwards).
+inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE Vector128
+AesRound(const Vector128& state, const Vector128& round_key) {
+ Vector128 result;
#ifdef ABSL_IS_LITTLE_ENDIAN
result.s[0] = round_key.s[0] ^ //
te0[uint8_t(state.s[0])] ^ //
@@ -295,21 +295,21 @@ AesRound(const Vector128& state, const Vector128& round_key) {
te2[uint8_t(state.s[1] >> 16)] ^ //
te3[uint8_t(state.s[0] >> 24)];
#endif
- return result;
-}
-
+ return result;
+}
+
using ::absl::random_internal::RandenTraits;
-
-// The improved Feistel block shuffle function for 16 blocks.
-inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void BlockShuffle(
+
+// The improved Feistel block shuffle function for 16 blocks.
+inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void BlockShuffle(
absl::uint128* state) {
static_assert(RandenTraits::kFeistelBlocks == 16,
- "Feistel block shuffle only works for 16 blocks.");
-
+ "Feistel block shuffle only works for 16 blocks.");
+
constexpr size_t shuffle[RandenTraits::kFeistelBlocks] = {
7, 2, 13, 4, 11, 8, 3, 6, 15, 0, 9, 10, 1, 14, 5, 12};
-
- // The fully unrolled loop without the memcpy improves the speed by about
+
+ // The fully unrolled loop without the memcpy improves the speed by about
// 30% over the equivalent:
#if 0
absl::uint128 source[RandenTraits::kFeistelBlocks];
@@ -317,10 +317,10 @@ inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void BlockShuffle(
for (size_t i = 0; i < RandenTraits::kFeistelBlocks; i++) {
const absl::uint128 v0 = source[shuffle[i]];
state[i] = v0;
- }
+ }
return;
#endif
-
+
const absl::uint128 v0 = state[shuffle[0]];
const absl::uint128 v1 = state[shuffle[1]];
const absl::uint128 v2 = state[shuffle[2]];
@@ -337,64 +337,64 @@ inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void BlockShuffle(
const absl::uint128 w5 = state[shuffle[13]];
const absl::uint128 w6 = state[shuffle[14]];
const absl::uint128 w7 = state[shuffle[15]];
- state[0] = v0;
- state[1] = v1;
- state[2] = v2;
- state[3] = v3;
- state[4] = v4;
- state[5] = v5;
- state[6] = v6;
- state[7] = v7;
- state[8] = w0;
- state[9] = w1;
- state[10] = w2;
- state[11] = w3;
- state[12] = w4;
- state[13] = w5;
- state[14] = w6;
- state[15] = w7;
-}
-
-// Feistel round function using two AES subrounds. Very similar to F()
-// from Simpira v2, but with independent subround keys. Uses 17 AES rounds
-// per 16 bytes (vs. 10 for AES-CTR). Computing eight round functions in
-// parallel hides the 7-cycle AESNI latency on HSW. Note that the Feistel
-// XORs are 'free' (included in the second AES instruction).
+ state[0] = v0;
+ state[1] = v1;
+ state[2] = v2;
+ state[3] = v3;
+ state[4] = v4;
+ state[5] = v5;
+ state[6] = v6;
+ state[7] = v7;
+ state[8] = w0;
+ state[9] = w1;
+ state[10] = w2;
+ state[11] = w3;
+ state[12] = w4;
+ state[13] = w5;
+ state[14] = w6;
+ state[15] = w7;
+}
+
+// Feistel round function using two AES subrounds. Very similar to F()
+// from Simpira v2, but with independent subround keys. Uses 17 AES rounds
+// per 16 bytes (vs. 10 for AES-CTR). Computing eight round functions in
+// parallel hides the 7-cycle AESNI latency on HSW. Note that the Feistel
+// XORs are 'free' (included in the second AES instruction).
inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE const absl::uint128*
FeistelRound(absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT state,
const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) {
for (size_t branch = 0; branch < RandenTraits::kFeistelBlocks; branch += 4) {
const Vector128 s0 = Vector128Load(state + branch);
const Vector128 s1 = Vector128Load(state + branch + 1);
- const Vector128 f0 = AesRound(s0, Vector128Load(keys));
- keys++;
- const Vector128 o1 = AesRound(f0, s1);
+ const Vector128 f0 = AesRound(s0, Vector128Load(keys));
+ keys++;
+ const Vector128 o1 = AesRound(f0, s1);
Vector128Store(o1, state + branch + 1);
-
- // Manually unroll this loop once. about 10% better than not unrolled.
+
+ // Manually unroll this loop once. about 10% better than not unrolled.
const Vector128 s2 = Vector128Load(state + branch + 2);
const Vector128 s3 = Vector128Load(state + branch + 3);
- const Vector128 f2 = AesRound(s2, Vector128Load(keys));
- keys++;
- const Vector128 o3 = AesRound(f2, s3);
+ const Vector128 f2 = AesRound(s2, Vector128Load(keys));
+ keys++;
+ const Vector128 o3 = AesRound(f2, s3);
Vector128Store(o3, state + branch + 3);
- }
- return keys;
-}
-
-// Cryptographic permutation based via type-2 Generalized Feistel Network.
-// Indistinguishable from ideal by chosen-ciphertext adversaries using less than
-// 2^64 queries if the round function is a PRF. This is similar to the b=8 case
-// of Simpira v2, but more efficient than its generic construction for b=16.
-inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Permute(
+ }
+ return keys;
+}
+
+// Cryptographic permutation based via type-2 Generalized Feistel Network.
+// Indistinguishable from ideal by chosen-ciphertext adversaries using less than
+// 2^64 queries if the round function is a PRF. This is similar to the b=8 case
+// of Simpira v2, but more efficient than its generic construction for b=16.
+inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void Permute(
absl::uint128* state,
const absl::uint128* ABSL_RANDOM_INTERNAL_RESTRICT keys) {
for (size_t round = 0; round < RandenTraits::kFeistelRounds; ++round) {
keys = FeistelRound(state, keys);
- BlockShuffle(state);
- }
-}
-
+ BlockShuffle(state);
+ }
+}
+
// Enables native loads in the round loop by pre-swapping.
inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void SwapEndian(
absl::uint128* state) {
@@ -412,29 +412,29 @@ inline ABSL_RANDOM_INTERNAL_ATTRIBUTE_ALWAYS_INLINE void SwapEndian(
#endif
}
-} // namespace
-
-namespace absl {
+} // namespace
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-const void* RandenSlow::GetKeys() {
- // Round keys for one AES per Feistel round and branch.
- // The canonical implementation uses first digits of Pi.
+namespace random_internal {
+
+const void* RandenSlow::GetKeys() {
+ // Round keys for one AES per Feistel round and branch.
+ // The canonical implementation uses first digits of Pi.
#ifdef ABSL_IS_LITTLE_ENDIAN
return kRandenRoundKeys;
#else
return kRandenRoundKeysBE;
#endif
-}
-
-void RandenSlow::Absorb(const void* seed_void, void* state_void) {
+}
+
+void RandenSlow::Absorb(const void* seed_void, void* state_void) {
auto* state =
reinterpret_cast<uint64_t * ABSL_RANDOM_INTERNAL_RESTRICT>(state_void);
const auto* seed =
reinterpret_cast<const uint64_t * ABSL_RANDOM_INTERNAL_RESTRICT>(
seed_void);
-
+
constexpr size_t kCapacityBlocks =
RandenTraits::kCapacityBytes / sizeof(uint64_t);
static_assert(
@@ -443,29 +443,29 @@ void RandenSlow::Absorb(const void* seed_void, void* state_void) {
for (size_t i = kCapacityBlocks;
i < RandenTraits::kStateBytes / sizeof(uint64_t); ++i) {
- state[i] ^= seed[i - kCapacityBlocks];
- }
-}
-
+ state[i] ^= seed[i - kCapacityBlocks];
+ }
+}
+
void RandenSlow::Generate(const void* keys_void, void* state_void) {
static_assert(RandenTraits::kCapacityBytes == sizeof(absl::uint128),
"Capacity mismatch");
-
+
auto* state = reinterpret_cast<absl::uint128*>(state_void);
const auto* keys = reinterpret_cast<const absl::uint128*>(keys_void);
-
+
const absl::uint128 prev_inner = state[0];
-
+
SwapEndian(state);
Permute(state, keys);
-
+
SwapEndian(state);
- // Ensure backtracking resistance.
+ // Ensure backtracking resistance.
*state ^= prev_inner;
-}
-
-} // namespace random_internal
+}
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
+} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.h b/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.h
index efa9c4c144..532c3a8991 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow.h
@@ -1,40 +1,40 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_RANDEN_SLOW_H_
-#define ABSL_RANDOM_INTERNAL_RANDEN_SLOW_H_
-
-#include <cstddef>
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_RANDEN_SLOW_H_
+#define ABSL_RANDOM_INTERNAL_RANDEN_SLOW_H_
+
+#include <cstddef>
+
#include "absl/base/config.h"
-namespace absl {
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
+namespace random_internal {
+
// RANDen = RANDom generator or beetroots in Swiss High German.
-// RandenSlow implements the basic state manipulation methods for
-// architectures lacking AES hardware acceleration intrinsics.
-class RandenSlow {
- public:
- static void Generate(const void* keys, void* state_void);
- static void Absorb(const void* seed_void, void* state_void);
- static const void* GetKeys();
-};
-
-} // namespace random_internal
+// RandenSlow implements the basic state manipulation methods for
+// architectures lacking AES hardware acceleration intrinsics.
+class RandenSlow {
+ public:
+ static void Generate(const void* keys, void* state_void);
+ static void Absorb(const void* seed_void, void* state_void);
+ static const void* GetKeys();
+};
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_RANDEN_SLOW_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_RANDEN_SLOW_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow/ya.make
index a0cfde87e4..af124ae798 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_slow/ya.make
@@ -1,33 +1,33 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
WITHOUT_LICENSE_TEXTS()
-OWNER(g:cpp-contrib)
-
-LICENSE(Apache-2.0)
-
+OWNER(g:cpp-contrib)
+
+LICENSE(Apache-2.0)
+
PEERDIR(
contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys
)
-ADDINCL(
- GLOBAL contrib/restricted/abseil-cpp
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
+ADDINCL(
+ GLOBAL contrib/restricted/abseil-cpp
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
CFLAGS(
-DNOMINMAX
)
-SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal)
-
-SRCS(
- randen_slow.cc
-)
-
-END()
+SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal)
+
+SRCS(
+ randen_slow.cc
+)
+
+END()
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/randen_traits.h b/contrib/restricted/abseil-cpp/absl/random/internal/randen_traits.h
index 92b1937b3e..120022c9fb 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/randen_traits.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/randen_traits.h
@@ -1,37 +1,37 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_RANDEN_TRAITS_H_
-#define ABSL_RANDOM_INTERNAL_RANDEN_TRAITS_H_
-
-// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate
-// symbols from arbitrary system and other headers, since it may be built
-// with different flags from other targets, using different levels of
-// optimization, potentially introducing ODR violations.
-
-#include <cstddef>
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_RANDEN_TRAITS_H_
+#define ABSL_RANDOM_INTERNAL_RANDEN_TRAITS_H_
+
+// HERMETIC NOTE: The randen_hwaes target must not introduce duplicate
+// symbols from arbitrary system and other headers, since it may be built
+// with different flags from other targets, using different levels of
+// optimization, potentially introducing ODR violations.
+
+#include <cstddef>
+
#include "absl/base/config.h"
-namespace absl {
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
+namespace random_internal {
+
// RANDen = RANDom generator or beetroots in Swiss High German.
-// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
-// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
-//
+// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
+// generator, faster in some benchmarks than std::mt19937_64 and pcg64_c32.
+//
// High-level summary:
// 1) Reverie (see "A Robust and Sponge-Like PRNG with Improved Efficiency") is
// a sponge-like random generator that requires a cryptographic permutation.
@@ -51,38 +51,38 @@ namespace random_internal {
// Combine these three ideas and also change Simpira's subround keys from
// structured/low-entropy counters to digits of Pi (or other random source).
-// RandenTraits contains the basic algorithm traits, such as the size of the
-// state, seed, sponge, etc.
-struct RandenTraits {
- // Size of the entire sponge / state for the randen PRNG.
- static constexpr size_t kStateBytes = 256; // 2048-bit
-
- // Size of the 'inner' (inaccessible) part of the sponge. Larger values would
- // require more frequent calls to RandenGenerate.
- static constexpr size_t kCapacityBytes = 16; // 128-bit
-
- // Size of the default seed consumed by the sponge.
- static constexpr size_t kSeedBytes = kStateBytes - kCapacityBytes;
-
+// RandenTraits contains the basic algorithm traits, such as the size of the
+// state, seed, sponge, etc.
+struct RandenTraits {
+ // Size of the entire sponge / state for the randen PRNG.
+ static constexpr size_t kStateBytes = 256; // 2048-bit
+
+ // Size of the 'inner' (inaccessible) part of the sponge. Larger values would
+ // require more frequent calls to RandenGenerate.
+ static constexpr size_t kCapacityBytes = 16; // 128-bit
+
+ // Size of the default seed consumed by the sponge.
+ static constexpr size_t kSeedBytes = kStateBytes - kCapacityBytes;
+
// Assuming 128-bit blocks, the number of blocks in the state.
- // Largest size for which security proofs are known.
- static constexpr size_t kFeistelBlocks = 16;
-
- // Ensures SPRP security and two full subblock diffusions.
- // Must be > 4 * log2(kFeistelBlocks).
- static constexpr size_t kFeistelRounds = 16 + 1;
+ // Largest size for which security proofs are known.
+ static constexpr size_t kFeistelBlocks = 16;
+
+ // Ensures SPRP security and two full subblock diffusions.
+ // Must be > 4 * log2(kFeistelBlocks).
+ static constexpr size_t kFeistelRounds = 16 + 1;
// Size of the key. A 128-bit key block is used for every-other
// feistel block (Type-2 generalized Feistel network) in each round.
static constexpr size_t kKeyBytes = 16 * kFeistelRounds * kFeistelBlocks / 2;
-};
-
+};
+
// Randen key arrays. In randen_round_keys.cc
extern const unsigned char kRandenRoundKeys[RandenTraits::kKeyBytes];
extern const unsigned char kRandenRoundKeysBE[RandenTraits::kKeyBytes];
-} // namespace random_internal
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_RANDEN_TRAITS_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_RANDEN_TRAITS_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/salted_seed_seq.h b/contrib/restricted/abseil-cpp/absl/random/internal/salted_seed_seq.h
index 67ead19418..5953a090f8 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/salted_seed_seq.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/salted_seed_seq.h
@@ -1,167 +1,167 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_SALTED_SEED_SEQ_H_
-#define ABSL_RANDOM_INTERNAL_SALTED_SEED_SEQ_H_
-
-#include <cstdint>
-#include <cstdlib>
-#include <initializer_list>
-#include <iterator>
-#include <memory>
-#include <type_traits>
-#include <utility>
-
-#include "absl/container/inlined_vector.h"
-#include "absl/meta/type_traits.h"
-#include "absl/random/internal/seed_material.h"
-#include "absl/types/optional.h"
-#include "absl/types/span.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_SALTED_SEED_SEQ_H_
+#define ABSL_RANDOM_INTERNAL_SALTED_SEED_SEQ_H_
+
+#include <cstdint>
+#include <cstdlib>
+#include <initializer_list>
+#include <iterator>
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+#include "absl/container/inlined_vector.h"
+#include "absl/meta/type_traits.h"
+#include "absl/random/internal/seed_material.h"
+#include "absl/types/optional.h"
+#include "absl/types/span.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// This class conforms to the C++ Standard "Seed Sequence" concept
-// [rand.req.seedseq].
-//
-// A `SaltedSeedSeq` is meant to wrap an existing seed sequence and modify
-// generated sequence by mixing with extra entropy. This entropy may be
-// build-dependent or process-dependent. The implementation may change to be
-// have either or both kinds of entropy. If salt is not available sequence is
-// not modified.
-template <typename SSeq>
-class SaltedSeedSeq {
- public:
- using inner_sequence_type = SSeq;
- using result_type = typename SSeq::result_type;
-
- SaltedSeedSeq() : seq_(absl::make_unique<SSeq>()) {}
-
- template <typename Iterator>
- SaltedSeedSeq(Iterator begin, Iterator end)
- : seq_(absl::make_unique<SSeq>(begin, end)) {}
-
- template <typename T>
- SaltedSeedSeq(std::initializer_list<T> il)
- : SaltedSeedSeq(il.begin(), il.end()) {}
-
- SaltedSeedSeq(const SaltedSeedSeq&) = delete;
- SaltedSeedSeq& operator=(const SaltedSeedSeq&) = delete;
-
- SaltedSeedSeq(SaltedSeedSeq&&) = default;
- SaltedSeedSeq& operator=(SaltedSeedSeq&&) = default;
-
- template <typename RandomAccessIterator>
- void generate(RandomAccessIterator begin, RandomAccessIterator end) {
- // The common case is that generate is called with ContiguousIterators
- // to uint arrays. Such contiguous memory regions may be optimized,
- // which we detect here.
- using tag = absl::conditional_t<
- (std::is_pointer<RandomAccessIterator>::value &&
- std::is_same<absl::decay_t<decltype(*begin)>, uint32_t>::value),
- ContiguousAndUint32Tag, DefaultTag>;
- if (begin != end) {
- generate_impl(begin, end, tag{});
- }
- }
-
- template <typename OutIterator>
- void param(OutIterator out) const {
- seq_->param(out);
- }
-
- size_t size() const { return seq_->size(); }
-
- private:
- struct ContiguousAndUint32Tag {};
- struct DefaultTag {};
-
- // Generate which requires the iterators are contiguous pointers to uint32_t.
- void generate_impl(uint32_t* begin, uint32_t* end, ContiguousAndUint32Tag) {
- generate_contiguous(absl::MakeSpan(begin, end));
- }
-
- // The uncommon case for generate is that it is called with iterators over
- // some other buffer type which is assignable from a 32-bit value. In this
- // case we allocate a temporary 32-bit buffer and then copy-assign back
- // to the initial inputs.
- template <typename RandomAccessIterator>
- void generate_impl(RandomAccessIterator begin, RandomAccessIterator end,
- DefaultTag) {
- return generate_and_copy(std::distance(begin, end), begin);
- }
-
- // Fills the initial seed buffer the underlying SSeq::generate() call,
- // mixing in the salt material.
- void generate_contiguous(absl::Span<uint32_t> buffer) {
- seq_->generate(buffer.begin(), buffer.end());
- const uint32_t salt = absl::random_internal::GetSaltMaterial().value_or(0);
- MixIntoSeedMaterial(absl::MakeConstSpan(&salt, 1), buffer);
- }
-
- // Allocates a seed buffer of `n` elements, generates the seed, then
- // copies the result into the `out` iterator.
- template <typename Iterator>
- void generate_and_copy(size_t n, Iterator out) {
- // Allocate a temporary buffer, generate, and then copy.
- absl::InlinedVector<uint32_t, 8> data(n, 0);
- generate_contiguous(absl::MakeSpan(data.data(), data.size()));
- std::copy(data.begin(), data.end(), out);
- }
-
- // Because [rand.req.seedseq] is not required to be copy-constructible,
- // copy-assignable nor movable, we wrap it with unique pointer to be able
- // to move SaltedSeedSeq.
- std::unique_ptr<SSeq> seq_;
-};
-
-// is_salted_seed_seq indicates whether the type is a SaltedSeedSeq.
-template <typename T, typename = void>
-struct is_salted_seed_seq : public std::false_type {};
-
-template <typename T>
-struct is_salted_seed_seq<
- T, typename std::enable_if<std::is_same<
- T, SaltedSeedSeq<typename T::inner_sequence_type>>::value>::type>
- : public std::true_type {};
-
-// MakeSaltedSeedSeq returns a salted variant of the seed sequence.
-// When provided with an existing SaltedSeedSeq, returns the input parameter,
-// otherwise constructs a new SaltedSeedSeq which embodies the original
-// non-salted seed parameters.
-template <
- typename SSeq, //
- typename EnableIf = absl::enable_if_t<is_salted_seed_seq<SSeq>::value>>
-SSeq MakeSaltedSeedSeq(SSeq&& seq) {
- return SSeq(std::forward<SSeq>(seq));
-}
-
-template <
- typename SSeq, //
- typename EnableIf = absl::enable_if_t<!is_salted_seed_seq<SSeq>::value>>
-SaltedSeedSeq<typename std::decay<SSeq>::type> MakeSaltedSeedSeq(SSeq&& seq) {
- using sseq_type = typename std::decay<SSeq>::type;
- using result_type = typename sseq_type::result_type;
-
- absl::InlinedVector<result_type, 8> data;
- seq.param(std::back_inserter(data));
- return SaltedSeedSeq<sseq_type>(data.begin(), data.end());
-}
-
-} // namespace random_internal
+namespace random_internal {
+
+// This class conforms to the C++ Standard "Seed Sequence" concept
+// [rand.req.seedseq].
+//
+// A `SaltedSeedSeq` is meant to wrap an existing seed sequence and modify
+// generated sequence by mixing with extra entropy. This entropy may be
+// build-dependent or process-dependent. The implementation may change to be
+// have either or both kinds of entropy. If salt is not available sequence is
+// not modified.
+template <typename SSeq>
+class SaltedSeedSeq {
+ public:
+ using inner_sequence_type = SSeq;
+ using result_type = typename SSeq::result_type;
+
+ SaltedSeedSeq() : seq_(absl::make_unique<SSeq>()) {}
+
+ template <typename Iterator>
+ SaltedSeedSeq(Iterator begin, Iterator end)
+ : seq_(absl::make_unique<SSeq>(begin, end)) {}
+
+ template <typename T>
+ SaltedSeedSeq(std::initializer_list<T> il)
+ : SaltedSeedSeq(il.begin(), il.end()) {}
+
+ SaltedSeedSeq(const SaltedSeedSeq&) = delete;
+ SaltedSeedSeq& operator=(const SaltedSeedSeq&) = delete;
+
+ SaltedSeedSeq(SaltedSeedSeq&&) = default;
+ SaltedSeedSeq& operator=(SaltedSeedSeq&&) = default;
+
+ template <typename RandomAccessIterator>
+ void generate(RandomAccessIterator begin, RandomAccessIterator end) {
+ // The common case is that generate is called with ContiguousIterators
+ // to uint arrays. Such contiguous memory regions may be optimized,
+ // which we detect here.
+ using tag = absl::conditional_t<
+ (std::is_pointer<RandomAccessIterator>::value &&
+ std::is_same<absl::decay_t<decltype(*begin)>, uint32_t>::value),
+ ContiguousAndUint32Tag, DefaultTag>;
+ if (begin != end) {
+ generate_impl(begin, end, tag{});
+ }
+ }
+
+ template <typename OutIterator>
+ void param(OutIterator out) const {
+ seq_->param(out);
+ }
+
+ size_t size() const { return seq_->size(); }
+
+ private:
+ struct ContiguousAndUint32Tag {};
+ struct DefaultTag {};
+
+ // Generate which requires the iterators are contiguous pointers to uint32_t.
+ void generate_impl(uint32_t* begin, uint32_t* end, ContiguousAndUint32Tag) {
+ generate_contiguous(absl::MakeSpan(begin, end));
+ }
+
+ // The uncommon case for generate is that it is called with iterators over
+ // some other buffer type which is assignable from a 32-bit value. In this
+ // case we allocate a temporary 32-bit buffer and then copy-assign back
+ // to the initial inputs.
+ template <typename RandomAccessIterator>
+ void generate_impl(RandomAccessIterator begin, RandomAccessIterator end,
+ DefaultTag) {
+ return generate_and_copy(std::distance(begin, end), begin);
+ }
+
+ // Fills the initial seed buffer the underlying SSeq::generate() call,
+ // mixing in the salt material.
+ void generate_contiguous(absl::Span<uint32_t> buffer) {
+ seq_->generate(buffer.begin(), buffer.end());
+ const uint32_t salt = absl::random_internal::GetSaltMaterial().value_or(0);
+ MixIntoSeedMaterial(absl::MakeConstSpan(&salt, 1), buffer);
+ }
+
+ // Allocates a seed buffer of `n` elements, generates the seed, then
+ // copies the result into the `out` iterator.
+ template <typename Iterator>
+ void generate_and_copy(size_t n, Iterator out) {
+ // Allocate a temporary buffer, generate, and then copy.
+ absl::InlinedVector<uint32_t, 8> data(n, 0);
+ generate_contiguous(absl::MakeSpan(data.data(), data.size()));
+ std::copy(data.begin(), data.end(), out);
+ }
+
+ // Because [rand.req.seedseq] is not required to be copy-constructible,
+ // copy-assignable nor movable, we wrap it with unique pointer to be able
+ // to move SaltedSeedSeq.
+ std::unique_ptr<SSeq> seq_;
+};
+
+// is_salted_seed_seq indicates whether the type is a SaltedSeedSeq.
+template <typename T, typename = void>
+struct is_salted_seed_seq : public std::false_type {};
+
+template <typename T>
+struct is_salted_seed_seq<
+ T, typename std::enable_if<std::is_same<
+ T, SaltedSeedSeq<typename T::inner_sequence_type>>::value>::type>
+ : public std::true_type {};
+
+// MakeSaltedSeedSeq returns a salted variant of the seed sequence.
+// When provided with an existing SaltedSeedSeq, returns the input parameter,
+// otherwise constructs a new SaltedSeedSeq which embodies the original
+// non-salted seed parameters.
+template <
+ typename SSeq, //
+ typename EnableIf = absl::enable_if_t<is_salted_seed_seq<SSeq>::value>>
+SSeq MakeSaltedSeedSeq(SSeq&& seq) {
+ return SSeq(std::forward<SSeq>(seq));
+}
+
+template <
+ typename SSeq, //
+ typename EnableIf = absl::enable_if_t<!is_salted_seed_seq<SSeq>::value>>
+SaltedSeedSeq<typename std::decay<SSeq>::type> MakeSaltedSeedSeq(SSeq&& seq) {
+ using sseq_type = typename std::decay<SSeq>::type;
+ using result_type = typename sseq_type::result_type;
+
+ absl::InlinedVector<result_type, 8> data;
+ seq.param(std::back_inserter(data));
+ return SaltedSeedSeq<sseq_type>(data.begin(), data.end());
+}
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_SALTED_SEED_SEQ_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_SALTED_SEED_SEQ_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.cc b/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.cc
index 6457ece3df..c03cad8502 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.cc
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.cc
@@ -1,56 +1,56 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/random/internal/seed_material.h"
-
-#include <fcntl.h>
-
-#ifndef _WIN32
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-
-#include <algorithm>
-#include <cerrno>
-#include <cstdint>
-#include <cstdlib>
-#include <cstring>
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/random/internal/seed_material.h"
+
+#include <fcntl.h>
+
+#ifndef _WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
+#include <algorithm>
+#include <cerrno>
+#include <cstdint>
+#include <cstdlib>
+#include <cstring>
+
#include "absl/base/dynamic_annotations.h"
-#include "absl/base/internal/raw_logging.h"
-#include "absl/strings/ascii.h"
-#include "absl/strings/escaping.h"
-#include "absl/strings/string_view.h"
-#include "absl/strings/strip.h"
-
-#if defined(__native_client__)
-
-#include <nacl/nacl_random.h>
-#define ABSL_RANDOM_USE_NACL_SECURE_RANDOM 1
-
-#elif defined(_WIN32)
-
-#include <windows.h>
-#define ABSL_RANDOM_USE_BCRYPT 1
-#pragma comment(lib, "bcrypt.lib")
-
+#include "absl/base/internal/raw_logging.h"
+#include "absl/strings/ascii.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "absl/strings/strip.h"
+
+#if defined(__native_client__)
+
+#include <nacl/nacl_random.h>
+#define ABSL_RANDOM_USE_NACL_SECURE_RANDOM 1
+
+#elif defined(_WIN32)
+
+#include <windows.h>
+#define ABSL_RANDOM_USE_BCRYPT 1
+#pragma comment(lib, "bcrypt.lib")
+
#elif defined(__Fuchsia__)
#include <zircon/syscalls.h>
-#endif
-
+#endif
+
#if defined(__GLIBC__) && \
(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
// glibc >= 2.25 has getentropy()
@@ -63,67 +63,67 @@
#define ABSL_RANDOM_USE_GET_ENTROPY 1
#endif
-#if defined(ABSL_RANDOM_USE_BCRYPT)
-#include <bcrypt.h>
-
-#ifndef BCRYPT_SUCCESS
-#define BCRYPT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
-#endif
-// Also link bcrypt; this can be done via linker options or:
-// #pragma comment(lib, "bcrypt.lib")
-#endif
-
-namespace absl {
+#if defined(ABSL_RANDOM_USE_BCRYPT)
+#include <bcrypt.h>
+
+#ifndef BCRYPT_SUCCESS
+#define BCRYPT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
+#endif
+// Also link bcrypt; this can be done via linker options or:
+// #pragma comment(lib, "bcrypt.lib")
+#endif
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-namespace {
-
-// Read OS Entropy for random number seeds.
-// TODO(absl-team): Possibly place a cap on how much entropy may be read at a
-// time.
-
-#if defined(ABSL_RANDOM_USE_BCRYPT)
-
-// On Windows potentially use the BCRYPT CNG API to read available entropy.
-bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
- BCRYPT_ALG_HANDLE hProvider;
- NTSTATUS ret;
- ret = BCryptOpenAlgorithmProvider(&hProvider, BCRYPT_RNG_ALGORITHM,
- MS_PRIMITIVE_PROVIDER, 0);
- if (!(BCRYPT_SUCCESS(ret))) {
- ABSL_RAW_LOG(ERROR, "Failed to open crypto provider.");
- return false;
- }
- ret = BCryptGenRandom(
- hProvider, // provider
- reinterpret_cast<UCHAR*>(values.data()), // buffer
- static_cast<ULONG>(sizeof(uint32_t) * values.size()), // bytes
- 0); // flags
- BCryptCloseAlgorithmProvider(hProvider, 0);
- return BCRYPT_SUCCESS(ret);
-}
-
-#elif defined(ABSL_RANDOM_USE_NACL_SECURE_RANDOM)
-
-// On NaCL use nacl_secure_random to acquire bytes.
-bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
- auto buffer = reinterpret_cast<uint8_t*>(values.data());
- size_t buffer_size = sizeof(uint32_t) * values.size();
-
- uint8_t* output_ptr = buffer;
- while (buffer_size > 0) {
- size_t nread = 0;
- const int error = nacl_secure_random(output_ptr, buffer_size, &nread);
- if (error != 0 || nread > buffer_size) {
- ABSL_RAW_LOG(ERROR, "Failed to read secure_random seed data: %d", error);
- return false;
- }
- output_ptr += nread;
- buffer_size -= nread;
- }
- return true;
-}
-
+namespace random_internal {
+namespace {
+
+// Read OS Entropy for random number seeds.
+// TODO(absl-team): Possibly place a cap on how much entropy may be read at a
+// time.
+
+#if defined(ABSL_RANDOM_USE_BCRYPT)
+
+// On Windows potentially use the BCRYPT CNG API to read available entropy.
+bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
+ BCRYPT_ALG_HANDLE hProvider;
+ NTSTATUS ret;
+ ret = BCryptOpenAlgorithmProvider(&hProvider, BCRYPT_RNG_ALGORITHM,
+ MS_PRIMITIVE_PROVIDER, 0);
+ if (!(BCRYPT_SUCCESS(ret))) {
+ ABSL_RAW_LOG(ERROR, "Failed to open crypto provider.");
+ return false;
+ }
+ ret = BCryptGenRandom(
+ hProvider, // provider
+ reinterpret_cast<UCHAR*>(values.data()), // buffer
+ static_cast<ULONG>(sizeof(uint32_t) * values.size()), // bytes
+ 0); // flags
+ BCryptCloseAlgorithmProvider(hProvider, 0);
+ return BCRYPT_SUCCESS(ret);
+}
+
+#elif defined(ABSL_RANDOM_USE_NACL_SECURE_RANDOM)
+
+// On NaCL use nacl_secure_random to acquire bytes.
+bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
+ auto buffer = reinterpret_cast<uint8_t*>(values.data());
+ size_t buffer_size = sizeof(uint32_t) * values.size();
+
+ uint8_t* output_ptr = buffer;
+ while (buffer_size > 0) {
+ size_t nread = 0;
+ const int error = nacl_secure_random(output_ptr, buffer_size, &nread);
+ if (error != 0 || nread > buffer_size) {
+ ABSL_RAW_LOG(ERROR, "Failed to read secure_random seed data: %d", error);
+ return false;
+ }
+ output_ptr += nread;
+ buffer_size -= nread;
+ }
+ return true;
+}
+
#elif defined(__Fuchsia__)
bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
@@ -133,8 +133,8 @@ bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
return true;
}
-#else
-
+#else
+
#if defined(ABSL_RANDOM_USE_GET_ENTROPY)
// On *nix, use getentropy() if supported. Note that libc may support
// getentropy(), but the kernel may not, in which case this function will return
@@ -159,109 +159,109 @@ bool ReadSeedMaterialFromGetEntropy(absl::Span<uint32_t> values) {
}
#endif // defined(ABSL_RANDOM_GETENTROPY)
-// On *nix, read entropy from /dev/urandom.
+// On *nix, read entropy from /dev/urandom.
bool ReadSeedMaterialFromDevURandom(absl::Span<uint32_t> values) {
- const char kEntropyFile[] = "/dev/urandom";
-
- auto buffer = reinterpret_cast<uint8_t*>(values.data());
- size_t buffer_size = sizeof(uint32_t) * values.size();
-
- int dev_urandom = open(kEntropyFile, O_RDONLY);
- bool success = (-1 != dev_urandom);
- if (!success) {
- return false;
- }
-
- while (success && buffer_size > 0) {
- int bytes_read = read(dev_urandom, buffer, buffer_size);
- int read_error = errno;
- success = (bytes_read > 0);
- if (success) {
- buffer += bytes_read;
- buffer_size -= bytes_read;
- } else if (bytes_read == -1 && read_error == EINTR) {
- success = true; // Need to try again.
- }
- }
- close(dev_urandom);
- return success;
-}
-
+ const char kEntropyFile[] = "/dev/urandom";
+
+ auto buffer = reinterpret_cast<uint8_t*>(values.data());
+ size_t buffer_size = sizeof(uint32_t) * values.size();
+
+ int dev_urandom = open(kEntropyFile, O_RDONLY);
+ bool success = (-1 != dev_urandom);
+ if (!success) {
+ return false;
+ }
+
+ while (success && buffer_size > 0) {
+ int bytes_read = read(dev_urandom, buffer, buffer_size);
+ int read_error = errno;
+ success = (bytes_read > 0);
+ if (success) {
+ buffer += bytes_read;
+ buffer_size -= bytes_read;
+ } else if (bytes_read == -1 && read_error == EINTR) {
+ success = true; // Need to try again.
+ }
+ }
+ close(dev_urandom);
+ return success;
+}
+
bool ReadSeedMaterialFromOSEntropyImpl(absl::Span<uint32_t> values) {
#if defined(ABSL_RANDOM_USE_GET_ENTROPY)
if (ReadSeedMaterialFromGetEntropy(values)) {
return true;
}
-#endif
+#endif
// Libc may support getentropy, but the kernel may not, so we still have
// to fallback to ReadSeedMaterialFromDevURandom().
return ReadSeedMaterialFromDevURandom(values);
}
-
+
#endif
-} // namespace
-
-bool ReadSeedMaterialFromOSEntropy(absl::Span<uint32_t> values) {
- assert(values.data() != nullptr);
- if (values.data() == nullptr) {
- return false;
- }
- if (values.empty()) {
- return true;
- }
- return ReadSeedMaterialFromOSEntropyImpl(values);
-}
-
-void MixIntoSeedMaterial(absl::Span<const uint32_t> sequence,
- absl::Span<uint32_t> seed_material) {
- // Algorithm is based on code available at
- // https://gist.github.com/imneme/540829265469e673d045
- constexpr uint32_t kInitVal = 0x43b0d7e5;
- constexpr uint32_t kHashMul = 0x931e8875;
- constexpr uint32_t kMixMulL = 0xca01f9dd;
- constexpr uint32_t kMixMulR = 0x4973f715;
- constexpr uint32_t kShiftSize = sizeof(uint32_t) * 8 / 2;
-
- uint32_t hash_const = kInitVal;
- auto hash = [&](uint32_t value) {
- value ^= hash_const;
- hash_const *= kHashMul;
- value *= hash_const;
- value ^= value >> kShiftSize;
- return value;
- };
-
- auto mix = [&](uint32_t x, uint32_t y) {
- uint32_t result = kMixMulL * x - kMixMulR * y;
- result ^= result >> kShiftSize;
- return result;
- };
-
- for (const auto& seq_val : sequence) {
- for (auto& elem : seed_material) {
- elem = mix(elem, hash(seq_val));
- }
- }
-}
-
-absl::optional<uint32_t> GetSaltMaterial() {
- // Salt must be common for all generators within the same process so read it
- // only once and store in static variable.
- static const auto salt_material = []() -> absl::optional<uint32_t> {
- uint32_t salt_value = 0;
-
- if (random_internal::ReadSeedMaterialFromOSEntropy(
- MakeSpan(&salt_value, 1))) {
- return salt_value;
- }
-
- return absl::nullopt;
- }();
-
- return salt_material;
-}
-
-} // namespace random_internal
+} // namespace
+
+bool ReadSeedMaterialFromOSEntropy(absl::Span<uint32_t> values) {
+ assert(values.data() != nullptr);
+ if (values.data() == nullptr) {
+ return false;
+ }
+ if (values.empty()) {
+ return true;
+ }
+ return ReadSeedMaterialFromOSEntropyImpl(values);
+}
+
+void MixIntoSeedMaterial(absl::Span<const uint32_t> sequence,
+ absl::Span<uint32_t> seed_material) {
+ // Algorithm is based on code available at
+ // https://gist.github.com/imneme/540829265469e673d045
+ constexpr uint32_t kInitVal = 0x43b0d7e5;
+ constexpr uint32_t kHashMul = 0x931e8875;
+ constexpr uint32_t kMixMulL = 0xca01f9dd;
+ constexpr uint32_t kMixMulR = 0x4973f715;
+ constexpr uint32_t kShiftSize = sizeof(uint32_t) * 8 / 2;
+
+ uint32_t hash_const = kInitVal;
+ auto hash = [&](uint32_t value) {
+ value ^= hash_const;
+ hash_const *= kHashMul;
+ value *= hash_const;
+ value ^= value >> kShiftSize;
+ return value;
+ };
+
+ auto mix = [&](uint32_t x, uint32_t y) {
+ uint32_t result = kMixMulL * x - kMixMulR * y;
+ result ^= result >> kShiftSize;
+ return result;
+ };
+
+ for (const auto& seq_val : sequence) {
+ for (auto& elem : seed_material) {
+ elem = mix(elem, hash(seq_val));
+ }
+ }
+}
+
+absl::optional<uint32_t> GetSaltMaterial() {
+ // Salt must be common for all generators within the same process so read it
+ // only once and store in static variable.
+ static const auto salt_material = []() -> absl::optional<uint32_t> {
+ uint32_t salt_value = 0;
+
+ if (random_internal::ReadSeedMaterialFromOSEntropy(
+ MakeSpan(&salt_value, 1))) {
+ return salt_value;
+ }
+
+ return absl::nullopt;
+ }();
+
+ return salt_material;
+}
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
+} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.h b/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.h
index bddbb3cda1..4be10e9256 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/seed_material.h
@@ -1,104 +1,104 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_SEED_MATERIAL_H_
-#define ABSL_RANDOM_INTERNAL_SEED_MATERIAL_H_
-
-#include <cassert>
-#include <cstdint>
-#include <cstdlib>
-#include <string>
-#include <vector>
-
-#include "absl/base/attributes.h"
-#include "absl/random/internal/fast_uniform_bits.h"
-#include "absl/types/optional.h"
-#include "absl/types/span.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_SEED_MATERIAL_H_
+#define ABSL_RANDOM_INTERNAL_SEED_MATERIAL_H_
+
+#include <cassert>
+#include <cstdint>
+#include <cstdlib>
+#include <string>
+#include <vector>
+
+#include "absl/base/attributes.h"
+#include "absl/random/internal/fast_uniform_bits.h"
+#include "absl/types/optional.h"
+#include "absl/types/span.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// Returns the number of 32-bit blocks needed to contain the given number of
-// bits.
-constexpr size_t SeedBitsToBlocks(size_t seed_size) {
- return (seed_size + 31) / 32;
-}
-
-// Amount of entropy (measured in bits) used to instantiate a Seed Sequence,
-// with which to create a URBG.
-constexpr size_t kEntropyBitsNeeded = 256;
-
-// Amount of entropy (measured in 32-bit blocks) used to instantiate a Seed
-// Sequence, with which to create a URBG.
-constexpr size_t kEntropyBlocksNeeded =
- random_internal::SeedBitsToBlocks(kEntropyBitsNeeded);
-
-static_assert(kEntropyBlocksNeeded > 0,
- "Entropy used to seed URBGs must be nonzero.");
-
-// Attempts to fill a span of uint32_t-values using an OS-provided source of
-// true entropy (eg. /dev/urandom) into an array of uint32_t blocks of data. The
-// resulting array may be used to initialize an instance of a class conforming
-// to the C++ Standard "Seed Sequence" concept [rand.req.seedseq].
-//
-// If values.data() == nullptr, the behavior is undefined.
-ABSL_MUST_USE_RESULT
-bool ReadSeedMaterialFromOSEntropy(absl::Span<uint32_t> values);
-
-// Attempts to fill a span of uint32_t-values using variates generated by an
-// existing instance of a class conforming to the C++ Standard "Uniform Random
-// Bit Generator" concept [rand.req.urng]. The resulting data may be used to
-// initialize an instance of a class conforming to the C++ Standard
-// "Seed Sequence" concept [rand.req.seedseq].
-//
-// If urbg == nullptr or values.data() == nullptr, the behavior is undefined.
-template <typename URBG>
-ABSL_MUST_USE_RESULT bool ReadSeedMaterialFromURBG(
- URBG* urbg, absl::Span<uint32_t> values) {
- random_internal::FastUniformBits<uint32_t> distr;
-
- assert(urbg != nullptr && values.data() != nullptr);
- if (urbg == nullptr || values.data() == nullptr) {
- return false;
- }
-
- for (uint32_t& seed_value : values) {
- seed_value = distr(*urbg);
- }
- return true;
-}
-
-// Mixes given sequence of values with into given sequence of seed material.
-// Time complexity of this function is O(sequence.size() *
-// seed_material.size()).
-//
-// Algorithm is based on code available at
-// https://gist.github.com/imneme/540829265469e673d045
-// by Melissa O'Neill.
-void MixIntoSeedMaterial(absl::Span<const uint32_t> sequence,
- absl::Span<uint32_t> seed_material);
-
-// Returns salt value.
-//
-// Salt is obtained only once and stored in static variable.
-//
-// May return empty value if optaining the salt was not possible.
-absl::optional<uint32_t> GetSaltMaterial();
-
-} // namespace random_internal
+namespace random_internal {
+
+// Returns the number of 32-bit blocks needed to contain the given number of
+// bits.
+constexpr size_t SeedBitsToBlocks(size_t seed_size) {
+ return (seed_size + 31) / 32;
+}
+
+// Amount of entropy (measured in bits) used to instantiate a Seed Sequence,
+// with which to create a URBG.
+constexpr size_t kEntropyBitsNeeded = 256;
+
+// Amount of entropy (measured in 32-bit blocks) used to instantiate a Seed
+// Sequence, with which to create a URBG.
+constexpr size_t kEntropyBlocksNeeded =
+ random_internal::SeedBitsToBlocks(kEntropyBitsNeeded);
+
+static_assert(kEntropyBlocksNeeded > 0,
+ "Entropy used to seed URBGs must be nonzero.");
+
+// Attempts to fill a span of uint32_t-values using an OS-provided source of
+// true entropy (eg. /dev/urandom) into an array of uint32_t blocks of data. The
+// resulting array may be used to initialize an instance of a class conforming
+// to the C++ Standard "Seed Sequence" concept [rand.req.seedseq].
+//
+// If values.data() == nullptr, the behavior is undefined.
+ABSL_MUST_USE_RESULT
+bool ReadSeedMaterialFromOSEntropy(absl::Span<uint32_t> values);
+
+// Attempts to fill a span of uint32_t-values using variates generated by an
+// existing instance of a class conforming to the C++ Standard "Uniform Random
+// Bit Generator" concept [rand.req.urng]. The resulting data may be used to
+// initialize an instance of a class conforming to the C++ Standard
+// "Seed Sequence" concept [rand.req.seedseq].
+//
+// If urbg == nullptr or values.data() == nullptr, the behavior is undefined.
+template <typename URBG>
+ABSL_MUST_USE_RESULT bool ReadSeedMaterialFromURBG(
+ URBG* urbg, absl::Span<uint32_t> values) {
+ random_internal::FastUniformBits<uint32_t> distr;
+
+ assert(urbg != nullptr && values.data() != nullptr);
+ if (urbg == nullptr || values.data() == nullptr) {
+ return false;
+ }
+
+ for (uint32_t& seed_value : values) {
+ seed_value = distr(*urbg);
+ }
+ return true;
+}
+
+// Mixes given sequence of values with into given sequence of seed material.
+// Time complexity of this function is O(sequence.size() *
+// seed_material.size()).
+//
+// Algorithm is based on code available at
+// https://gist.github.com/imneme/540829265469e673d045
+// by Melissa O'Neill.
+void MixIntoSeedMaterial(absl::Span<const uint32_t> sequence,
+ absl::Span<uint32_t> seed_material);
+
+// Returns salt value.
+//
+// Salt is obtained only once and stored in static variable.
+//
+// May return empty value if optaining the salt was not possible.
+absl::optional<uint32_t> GetSaltMaterial();
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_SEED_MATERIAL_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_SEED_MATERIAL_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/seed_material/ya.make b/contrib/restricted/abseil-cpp/absl/random/internal/seed_material/ya.make
index d4a024053f..65618b087d 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/seed_material/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/seed_material/ya.make
@@ -1,41 +1,41 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
WITHOUT_LICENSE_TEXTS()
-OWNER(g:cpp-contrib)
-
-LICENSE(Apache-2.0)
-
-PEERDIR(
- contrib/restricted/abseil-cpp/absl/base
- contrib/restricted/abseil-cpp/absl/base/internal/raw_logging
- contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait
- contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate
- contrib/restricted/abseil-cpp/absl/base/log_severity
- contrib/restricted/abseil-cpp/absl/numeric
+OWNER(g:cpp-contrib)
+
+LICENSE(Apache-2.0)
+
+PEERDIR(
+ contrib/restricted/abseil-cpp/absl/base
+ contrib/restricted/abseil-cpp/absl/base/internal/raw_logging
+ contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait
+ contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate
+ contrib/restricted/abseil-cpp/absl/base/log_severity
+ contrib/restricted/abseil-cpp/absl/numeric
contrib/restricted/abseil-cpp/absl/strings
contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal
contrib/restricted/abseil-cpp/absl/types/bad_optional_access
-)
-
-ADDINCL(
- GLOBAL contrib/restricted/abseil-cpp
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
+)
+
+ADDINCL(
+ GLOBAL contrib/restricted/abseil-cpp
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
CFLAGS(
-DNOMINMAX
)
SRCDIR(contrib/restricted/abseil-cpp/absl/random/internal)
-SRCS(
+SRCS(
seed_material.cc
-)
-
-END()
+)
+
+END()
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/sequence_urbg.h b/contrib/restricted/abseil-cpp/absl/random/internal/sequence_urbg.h
index 3ed7dfd6e0..bc96a12cd2 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/sequence_urbg.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/sequence_urbg.h
@@ -1,60 +1,60 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_SEQUENCE_URBG_H_
-#define ABSL_RANDOM_INTERNAL_SEQUENCE_URBG_H_
-
-#include <cstdint>
-#include <cstring>
-#include <limits>
-#include <type_traits>
-#include <vector>
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_SEQUENCE_URBG_H_
+#define ABSL_RANDOM_INTERNAL_SEQUENCE_URBG_H_
+
+#include <cstdint>
+#include <cstring>
+#include <limits>
+#include <type_traits>
+#include <vector>
+
#include "absl/base/config.h"
-namespace absl {
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// `sequence_urbg` is a simple random number generator which meets the
-// requirements of [rand.req.urbg], and is solely for testing absl
-// distributions.
-class sequence_urbg {
- public:
- using result_type = uint64_t;
-
- static constexpr result_type(min)() {
- return (std::numeric_limits<result_type>::min)();
- }
- static constexpr result_type(max)() {
- return (std::numeric_limits<result_type>::max)();
- }
-
- sequence_urbg(std::initializer_list<result_type> data) : i_(0), data_(data) {}
- void reset() { i_ = 0; }
-
- result_type operator()() { return data_[i_++ % data_.size()]; }
-
- size_t invocations() const { return i_; }
-
- private:
- size_t i_;
- std::vector<result_type> data_;
-};
-
-} // namespace random_internal
+namespace random_internal {
+
+// `sequence_urbg` is a simple random number generator which meets the
+// requirements of [rand.req.urbg], and is solely for testing absl
+// distributions.
+class sequence_urbg {
+ public:
+ using result_type = uint64_t;
+
+ static constexpr result_type(min)() {
+ return (std::numeric_limits<result_type>::min)();
+ }
+ static constexpr result_type(max)() {
+ return (std::numeric_limits<result_type>::max)();
+ }
+
+ sequence_urbg(std::initializer_list<result_type> data) : i_(0), data_(data) {}
+ void reset() { i_ = 0; }
+
+ result_type operator()() { return data_[i_++ % data_.size()]; }
+
+ size_t invocations() const { return i_; }
+
+ private:
+ size_t i_;
+ std::vector<result_type> data_;
+};
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_SEQUENCE_URBG_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_SEQUENCE_URBG_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/traits.h b/contrib/restricted/abseil-cpp/absl/random/internal/traits.h
index aa39823632..75772bd9ab 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/traits.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/traits.h
@@ -1,101 +1,101 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_TRAITS_H_
-#define ABSL_RANDOM_INTERNAL_TRAITS_H_
-
-#include <cstdint>
-#include <limits>
-#include <type_traits>
-
-#include "absl/base/config.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_TRAITS_H_
+#define ABSL_RANDOM_INTERNAL_TRAITS_H_
+
+#include <cstdint>
+#include <limits>
+#include <type_traits>
+
+#include "absl/base/config.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// random_internal::is_widening_convertible<A, B>
-//
-// Returns whether a type A is widening-convertible to a type B.
-//
-// A is widening-convertible to B means:
-// A a = <any number>;
-// B b = a;
-// A c = b;
-// EXPECT_EQ(a, c);
-template <typename A, typename B>
-class is_widening_convertible {
- // As long as there are enough bits in the exact part of a number:
- // - unsigned can fit in float, signed, unsigned
- // - signed can fit in float, signed
- // - float can fit in float
- // So we define rank to be:
- // - rank(float) -> 2
- // - rank(signed) -> 1
- // - rank(unsigned) -> 0
- template <class T>
- static constexpr int rank() {
- return !std::numeric_limits<T>::is_integer +
- std::numeric_limits<T>::is_signed;
- }
-
- public:
- // If an arithmetic-type B can represent at least as many digits as a type A,
- // and B belongs to a rank no lower than A, then A can be safely represented
- // by B through a widening-conversion.
- static constexpr bool value =
- std::numeric_limits<A>::digits <= std::numeric_limits<B>::digits &&
- rank<A>() <= rank<B>();
-};
-
-// unsigned_bits<N>::type returns the unsigned int type with the indicated
-// number of bits.
-template <size_t N>
-struct unsigned_bits;
-
-template <>
-struct unsigned_bits<8> {
- using type = uint8_t;
-};
-template <>
-struct unsigned_bits<16> {
- using type = uint16_t;
-};
-template <>
-struct unsigned_bits<32> {
- using type = uint32_t;
-};
-template <>
-struct unsigned_bits<64> {
- using type = uint64_t;
-};
-
-#ifdef ABSL_HAVE_INTRINSIC_INT128
-template <>
-struct unsigned_bits<128> {
- using type = __uint128_t;
-};
-#endif
-
-template <typename IntType>
-struct make_unsigned_bits {
- using type = typename unsigned_bits<std::numeric_limits<
- typename std::make_unsigned<IntType>::type>::digits>::type;
-};
-
-} // namespace random_internal
+namespace random_internal {
+
+// random_internal::is_widening_convertible<A, B>
+//
+// Returns whether a type A is widening-convertible to a type B.
+//
+// A is widening-convertible to B means:
+// A a = <any number>;
+// B b = a;
+// A c = b;
+// EXPECT_EQ(a, c);
+template <typename A, typename B>
+class is_widening_convertible {
+ // As long as there are enough bits in the exact part of a number:
+ // - unsigned can fit in float, signed, unsigned
+ // - signed can fit in float, signed
+ // - float can fit in float
+ // So we define rank to be:
+ // - rank(float) -> 2
+ // - rank(signed) -> 1
+ // - rank(unsigned) -> 0
+ template <class T>
+ static constexpr int rank() {
+ return !std::numeric_limits<T>::is_integer +
+ std::numeric_limits<T>::is_signed;
+ }
+
+ public:
+ // If an arithmetic-type B can represent at least as many digits as a type A,
+ // and B belongs to a rank no lower than A, then A can be safely represented
+ // by B through a widening-conversion.
+ static constexpr bool value =
+ std::numeric_limits<A>::digits <= std::numeric_limits<B>::digits &&
+ rank<A>() <= rank<B>();
+};
+
+// unsigned_bits<N>::type returns the unsigned int type with the indicated
+// number of bits.
+template <size_t N>
+struct unsigned_bits;
+
+template <>
+struct unsigned_bits<8> {
+ using type = uint8_t;
+};
+template <>
+struct unsigned_bits<16> {
+ using type = uint16_t;
+};
+template <>
+struct unsigned_bits<32> {
+ using type = uint32_t;
+};
+template <>
+struct unsigned_bits<64> {
+ using type = uint64_t;
+};
+
+#ifdef ABSL_HAVE_INTRINSIC_INT128
+template <>
+struct unsigned_bits<128> {
+ using type = __uint128_t;
+};
+#endif
+
+template <typename IntType>
+struct make_unsigned_bits {
+ using type = typename unsigned_bits<std::numeric_limits<
+ typename std::make_unsigned<IntType>::type>::digits>::type;
+};
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_TRAITS_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_TRAITS_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/uniform_helper.h b/contrib/restricted/abseil-cpp/absl/random/internal/uniform_helper.h
index 30ae9d10f3..1243bc1c62 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/uniform_helper.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/uniform_helper.h
@@ -1,66 +1,66 @@
-// Copyright 2019 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-#ifndef ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_
-#define ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_
-
-#include <cmath>
-#include <limits>
-#include <type_traits>
-
+// Copyright 2019 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#ifndef ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_
+#define ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_
+
+#include <cmath>
+#include <limits>
+#include <type_traits>
+
#include "absl/base/config.h"
-#include "absl/meta/type_traits.h"
+#include "absl/meta/type_traits.h"
#include "absl/random/internal/traits.h"
-
-namespace absl {
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-template <typename IntType>
-class uniform_int_distribution;
-
-template <typename RealType>
-class uniform_real_distribution;
-
-// Interval tag types which specify whether the interval is open or closed
-// on either boundary.
-
-namespace random_internal {
-template <typename T>
-struct TagTypeCompare {};
-
-template <typename T>
-constexpr bool operator==(TagTypeCompare<T>, TagTypeCompare<T>) {
- // Tags are mono-states. They always compare equal.
- return true;
-}
-template <typename T>
-constexpr bool operator!=(TagTypeCompare<T>, TagTypeCompare<T>) {
- return false;
-}
-
-} // namespace random_internal
-
-struct IntervalClosedClosedTag
- : public random_internal::TagTypeCompare<IntervalClosedClosedTag> {};
-struct IntervalClosedOpenTag
- : public random_internal::TagTypeCompare<IntervalClosedOpenTag> {};
-struct IntervalOpenClosedTag
- : public random_internal::TagTypeCompare<IntervalOpenClosedTag> {};
-struct IntervalOpenOpenTag
- : public random_internal::TagTypeCompare<IntervalOpenOpenTag> {};
-
-namespace random_internal {
+template <typename IntType>
+class uniform_int_distribution;
+
+template <typename RealType>
+class uniform_real_distribution;
+
+// Interval tag types which specify whether the interval is open or closed
+// on either boundary.
+
+namespace random_internal {
+template <typename T>
+struct TagTypeCompare {};
+
+template <typename T>
+constexpr bool operator==(TagTypeCompare<T>, TagTypeCompare<T>) {
+ // Tags are mono-states. They always compare equal.
+ return true;
+}
+template <typename T>
+constexpr bool operator!=(TagTypeCompare<T>, TagTypeCompare<T>) {
+ return false;
+}
+
+} // namespace random_internal
+
+struct IntervalClosedClosedTag
+ : public random_internal::TagTypeCompare<IntervalClosedClosedTag> {};
+struct IntervalClosedOpenTag
+ : public random_internal::TagTypeCompare<IntervalClosedOpenTag> {};
+struct IntervalOpenClosedTag
+ : public random_internal::TagTypeCompare<IntervalOpenClosedTag> {};
+struct IntervalOpenOpenTag
+ : public random_internal::TagTypeCompare<IntervalOpenOpenTag> {};
+
+namespace random_internal {
// In the absence of an explicitly provided return-type, the template
// "uniform_inferred_return_t<A, B>" is used to derive a suitable type, based on
@@ -81,97 +81,97 @@ using uniform_inferred_return_t =
typename std::conditional<
is_widening_convertible<A, B>::value, B, A>::type>;
-// The functions
-// uniform_lower_bound(tag, a, b)
-// and
-// uniform_upper_bound(tag, a, b)
-// are used as implementation-details for absl::Uniform().
-//
-// Conceptually,
-// [a, b] == [uniform_lower_bound(IntervalClosedClosed, a, b),
-// uniform_upper_bound(IntervalClosedClosed, a, b)]
-// (a, b) == [uniform_lower_bound(IntervalOpenOpen, a, b),
-// uniform_upper_bound(IntervalOpenOpen, a, b)]
-// [a, b) == [uniform_lower_bound(IntervalClosedOpen, a, b),
-// uniform_upper_bound(IntervalClosedOpen, a, b)]
-// (a, b] == [uniform_lower_bound(IntervalOpenClosed, a, b),
-// uniform_upper_bound(IntervalOpenClosed, a, b)]
-//
-template <typename IntType, typename Tag>
-typename absl::enable_if_t<
- absl::conjunction<
- std::is_integral<IntType>,
- absl::disjunction<std::is_same<Tag, IntervalOpenClosedTag>,
- std::is_same<Tag, IntervalOpenOpenTag>>>::value,
- IntType>
-uniform_lower_bound(Tag, IntType a, IntType) {
+// The functions
+// uniform_lower_bound(tag, a, b)
+// and
+// uniform_upper_bound(tag, a, b)
+// are used as implementation-details for absl::Uniform().
+//
+// Conceptually,
+// [a, b] == [uniform_lower_bound(IntervalClosedClosed, a, b),
+// uniform_upper_bound(IntervalClosedClosed, a, b)]
+// (a, b) == [uniform_lower_bound(IntervalOpenOpen, a, b),
+// uniform_upper_bound(IntervalOpenOpen, a, b)]
+// [a, b) == [uniform_lower_bound(IntervalClosedOpen, a, b),
+// uniform_upper_bound(IntervalClosedOpen, a, b)]
+// (a, b] == [uniform_lower_bound(IntervalOpenClosed, a, b),
+// uniform_upper_bound(IntervalOpenClosed, a, b)]
+//
+template <typename IntType, typename Tag>
+typename absl::enable_if_t<
+ absl::conjunction<
+ std::is_integral<IntType>,
+ absl::disjunction<std::is_same<Tag, IntervalOpenClosedTag>,
+ std::is_same<Tag, IntervalOpenOpenTag>>>::value,
+ IntType>
+uniform_lower_bound(Tag, IntType a, IntType) {
return a < (std::numeric_limits<IntType>::max)() ? (a + 1) : a;
-}
-
-template <typename FloatType, typename Tag>
-typename absl::enable_if_t<
- absl::conjunction<
- std::is_floating_point<FloatType>,
- absl::disjunction<std::is_same<Tag, IntervalOpenClosedTag>,
- std::is_same<Tag, IntervalOpenOpenTag>>>::value,
- FloatType>
-uniform_lower_bound(Tag, FloatType a, FloatType b) {
- return std::nextafter(a, b);
-}
-
-template <typename NumType, typename Tag>
-typename absl::enable_if_t<
- absl::disjunction<std::is_same<Tag, IntervalClosedClosedTag>,
- std::is_same<Tag, IntervalClosedOpenTag>>::value,
- NumType>
-uniform_lower_bound(Tag, NumType a, NumType) {
- return a;
-}
-
-template <typename IntType, typename Tag>
-typename absl::enable_if_t<
- absl::conjunction<
- std::is_integral<IntType>,
- absl::disjunction<std::is_same<Tag, IntervalClosedOpenTag>,
- std::is_same<Tag, IntervalOpenOpenTag>>>::value,
- IntType>
-uniform_upper_bound(Tag, IntType, IntType b) {
+}
+
+template <typename FloatType, typename Tag>
+typename absl::enable_if_t<
+ absl::conjunction<
+ std::is_floating_point<FloatType>,
+ absl::disjunction<std::is_same<Tag, IntervalOpenClosedTag>,
+ std::is_same<Tag, IntervalOpenOpenTag>>>::value,
+ FloatType>
+uniform_lower_bound(Tag, FloatType a, FloatType b) {
+ return std::nextafter(a, b);
+}
+
+template <typename NumType, typename Tag>
+typename absl::enable_if_t<
+ absl::disjunction<std::is_same<Tag, IntervalClosedClosedTag>,
+ std::is_same<Tag, IntervalClosedOpenTag>>::value,
+ NumType>
+uniform_lower_bound(Tag, NumType a, NumType) {
+ return a;
+}
+
+template <typename IntType, typename Tag>
+typename absl::enable_if_t<
+ absl::conjunction<
+ std::is_integral<IntType>,
+ absl::disjunction<std::is_same<Tag, IntervalClosedOpenTag>,
+ std::is_same<Tag, IntervalOpenOpenTag>>>::value,
+ IntType>
+uniform_upper_bound(Tag, IntType, IntType b) {
return b > (std::numeric_limits<IntType>::min)() ? (b - 1) : b;
-}
-
-template <typename FloatType, typename Tag>
-typename absl::enable_if_t<
- absl::conjunction<
- std::is_floating_point<FloatType>,
- absl::disjunction<std::is_same<Tag, IntervalClosedOpenTag>,
- std::is_same<Tag, IntervalOpenOpenTag>>>::value,
- FloatType>
-uniform_upper_bound(Tag, FloatType, FloatType b) {
- return b;
-}
-
-template <typename IntType, typename Tag>
-typename absl::enable_if_t<
- absl::conjunction<
- std::is_integral<IntType>,
- absl::disjunction<std::is_same<Tag, IntervalClosedClosedTag>,
- std::is_same<Tag, IntervalOpenClosedTag>>>::value,
- IntType>
-uniform_upper_bound(Tag, IntType, IntType b) {
- return b;
-}
-
-template <typename FloatType, typename Tag>
-typename absl::enable_if_t<
- absl::conjunction<
- std::is_floating_point<FloatType>,
- absl::disjunction<std::is_same<Tag, IntervalClosedClosedTag>,
- std::is_same<Tag, IntervalOpenClosedTag>>>::value,
- FloatType>
-uniform_upper_bound(Tag, FloatType, FloatType b) {
- return std::nextafter(b, (std::numeric_limits<FloatType>::max)());
-}
-
+}
+
+template <typename FloatType, typename Tag>
+typename absl::enable_if_t<
+ absl::conjunction<
+ std::is_floating_point<FloatType>,
+ absl::disjunction<std::is_same<Tag, IntervalClosedOpenTag>,
+ std::is_same<Tag, IntervalOpenOpenTag>>>::value,
+ FloatType>
+uniform_upper_bound(Tag, FloatType, FloatType b) {
+ return b;
+}
+
+template <typename IntType, typename Tag>
+typename absl::enable_if_t<
+ absl::conjunction<
+ std::is_integral<IntType>,
+ absl::disjunction<std::is_same<Tag, IntervalClosedClosedTag>,
+ std::is_same<Tag, IntervalOpenClosedTag>>>::value,
+ IntType>
+uniform_upper_bound(Tag, IntType, IntType b) {
+ return b;
+}
+
+template <typename FloatType, typename Tag>
+typename absl::enable_if_t<
+ absl::conjunction<
+ std::is_floating_point<FloatType>,
+ absl::disjunction<std::is_same<Tag, IntervalClosedClosedTag>,
+ std::is_same<Tag, IntervalOpenClosedTag>>>::value,
+ FloatType>
+uniform_upper_bound(Tag, FloatType, FloatType b) {
+ return std::nextafter(b, (std::numeric_limits<FloatType>::max)());
+}
+
// Returns whether the bounds are valid for the underlying distribution.
// Inputs must have already been resolved via uniform_*_bound calls.
//
@@ -208,37 +208,37 @@ is_uniform_range_valid(IntType a, IntType b) {
// UniformDistribution selects either absl::uniform_int_distribution
// or absl::uniform_real_distribution depending on the NumType parameter.
-template <typename NumType>
-using UniformDistribution =
- typename std::conditional<std::is_integral<NumType>::value,
- absl::uniform_int_distribution<NumType>,
- absl::uniform_real_distribution<NumType>>::type;
-
+template <typename NumType>
+using UniformDistribution =
+ typename std::conditional<std::is_integral<NumType>::value,
+ absl::uniform_int_distribution<NumType>,
+ absl::uniform_real_distribution<NumType>>::type;
+
// UniformDistributionWrapper is used as the underlying distribution type
// by the absl::Uniform template function. It selects the proper Abseil
// uniform distribution and provides constructor overloads that match the
// expected parameter order as well as adjusting distribtuion bounds based
// on the tag.
-template <typename NumType>
-struct UniformDistributionWrapper : public UniformDistribution<NumType> {
- template <typename TagType>
- explicit UniformDistributionWrapper(TagType, NumType lo, NumType hi)
- : UniformDistribution<NumType>(
- uniform_lower_bound<NumType>(TagType{}, lo, hi),
- uniform_upper_bound<NumType>(TagType{}, lo, hi)) {}
-
- explicit UniformDistributionWrapper(NumType lo, NumType hi)
- : UniformDistribution<NumType>(
- uniform_lower_bound<NumType>(IntervalClosedOpenTag(), lo, hi),
- uniform_upper_bound<NumType>(IntervalClosedOpenTag(), lo, hi)) {}
-
- explicit UniformDistributionWrapper()
- : UniformDistribution<NumType>(std::numeric_limits<NumType>::lowest(),
- (std::numeric_limits<NumType>::max)()) {}
-};
-
-} // namespace random_internal
+template <typename NumType>
+struct UniformDistributionWrapper : public UniformDistribution<NumType> {
+ template <typename TagType>
+ explicit UniformDistributionWrapper(TagType, NumType lo, NumType hi)
+ : UniformDistribution<NumType>(
+ uniform_lower_bound<NumType>(TagType{}, lo, hi),
+ uniform_upper_bound<NumType>(TagType{}, lo, hi)) {}
+
+ explicit UniformDistributionWrapper(NumType lo, NumType hi)
+ : UniformDistribution<NumType>(
+ uniform_lower_bound<NumType>(IntervalClosedOpenTag(), lo, hi),
+ uniform_upper_bound<NumType>(IntervalClosedOpenTag(), lo, hi)) {}
+
+ explicit UniformDistributionWrapper()
+ : UniformDistribution<NumType>(std::numeric_limits<NumType>::lowest(),
+ (std::numeric_limits<NumType>::max)()) {}
+};
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/internal/wide_multiply.h b/contrib/restricted/abseil-cpp/absl/random/internal/wide_multiply.h
index 04085c8411..b6e6c4b6aa 100644
--- a/contrib/restricted/abseil-cpp/absl/random/internal/wide_multiply.h
+++ b/contrib/restricted/abseil-cpp/absl/random/internal/wide_multiply.h
@@ -1,111 +1,111 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_
-#define ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_
-
-#include <cstdint>
-#include <limits>
-#include <type_traits>
-
-#if (defined(_WIN32) || defined(_WIN64)) && defined(_M_IA64)
-#include <intrin.h> // NOLINT(build/include_order)
-#pragma intrinsic(_umul128)
-#define ABSL_INTERNAL_USE_UMUL128 1
-#endif
-
-#include "absl/base/config.h"
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_
+#define ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_
+
+#include <cstdint>
+#include <limits>
+#include <type_traits>
+
+#if (defined(_WIN32) || defined(_WIN64)) && defined(_M_IA64)
+#include <intrin.h> // NOLINT(build/include_order)
+#pragma intrinsic(_umul128)
+#define ABSL_INTERNAL_USE_UMUL128 1
+#endif
+
+#include "absl/base/config.h"
#include "absl/numeric/bits.h"
-#include "absl/numeric/int128.h"
-#include "absl/random/internal/traits.h"
-
-namespace absl {
+#include "absl/numeric/int128.h"
+#include "absl/random/internal/traits.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-namespace random_internal {
-
-// Helper object to multiply two 64-bit values to a 128-bit value.
-// MultiplyU64ToU128 multiplies two 64-bit values to a 128-bit value.
-// If an intrinsic is available, it is used, otherwise use native 32-bit
-// multiplies to construct the result.
+namespace random_internal {
+
+// Helper object to multiply two 64-bit values to a 128-bit value.
+// MultiplyU64ToU128 multiplies two 64-bit values to a 128-bit value.
+// If an intrinsic is available, it is used, otherwise use native 32-bit
+// multiplies to construct the result.
inline absl::uint128 MultiplyU64ToU128(uint64_t a, uint64_t b) {
-#if defined(ABSL_HAVE_INTRINSIC_INT128)
+#if defined(ABSL_HAVE_INTRINSIC_INT128)
return absl::uint128(static_cast<__uint128_t>(a) * b);
-#elif defined(ABSL_INTERNAL_USE_UMUL128)
- // uint64_t * uint64_t => uint128 multiply using imul intrinsic on MSVC.
- uint64_t high = 0;
- const uint64_t low = _umul128(a, b, &high);
- return absl::MakeUint128(high, low);
-#else
- // uint128(a) * uint128(b) in emulated mode computes a full 128-bit x 128-bit
- // multiply. However there are many cases where that is not necessary, and it
- // is only necessary to support a 64-bit x 64-bit = 128-bit multiply. This is
- // for those cases.
- const uint64_t a00 = static_cast<uint32_t>(a);
- const uint64_t a32 = a >> 32;
- const uint64_t b00 = static_cast<uint32_t>(b);
- const uint64_t b32 = b >> 32;
-
- const uint64_t c00 = a00 * b00;
- const uint64_t c32a = a00 * b32;
- const uint64_t c32b = a32 * b00;
- const uint64_t c64 = a32 * b32;
-
- const uint32_t carry =
- static_cast<uint32_t>(((c00 >> 32) + static_cast<uint32_t>(c32a) +
- static_cast<uint32_t>(c32b)) >>
- 32);
-
- return absl::MakeUint128(c64 + (c32a >> 32) + (c32b >> 32) + carry,
- c00 + (c32a << 32) + (c32b << 32));
-#endif
-}
-
-// wide_multiply<T> multiplies two N-bit values to a 2N-bit result.
-template <typename UIntType>
-struct wide_multiply {
- static constexpr size_t kN = std::numeric_limits<UIntType>::digits;
- using input_type = UIntType;
- using result_type = typename random_internal::unsigned_bits<kN * 2>::type;
-
- static result_type multiply(input_type a, input_type b) {
- return static_cast<result_type>(a) * b;
- }
-
- static input_type hi(result_type r) { return r >> kN; }
- static input_type lo(result_type r) { return r; }
-
- static_assert(std::is_unsigned<UIntType>::value,
- "Class-template wide_multiply<> argument must be unsigned.");
-};
-
-#ifndef ABSL_HAVE_INTRINSIC_INT128
-template <>
-struct wide_multiply<uint64_t> {
- using input_type = uint64_t;
+#elif defined(ABSL_INTERNAL_USE_UMUL128)
+ // uint64_t * uint64_t => uint128 multiply using imul intrinsic on MSVC.
+ uint64_t high = 0;
+ const uint64_t low = _umul128(a, b, &high);
+ return absl::MakeUint128(high, low);
+#else
+ // uint128(a) * uint128(b) in emulated mode computes a full 128-bit x 128-bit
+ // multiply. However there are many cases where that is not necessary, and it
+ // is only necessary to support a 64-bit x 64-bit = 128-bit multiply. This is
+ // for those cases.
+ const uint64_t a00 = static_cast<uint32_t>(a);
+ const uint64_t a32 = a >> 32;
+ const uint64_t b00 = static_cast<uint32_t>(b);
+ const uint64_t b32 = b >> 32;
+
+ const uint64_t c00 = a00 * b00;
+ const uint64_t c32a = a00 * b32;
+ const uint64_t c32b = a32 * b00;
+ const uint64_t c64 = a32 * b32;
+
+ const uint32_t carry =
+ static_cast<uint32_t>(((c00 >> 32) + static_cast<uint32_t>(c32a) +
+ static_cast<uint32_t>(c32b)) >>
+ 32);
+
+ return absl::MakeUint128(c64 + (c32a >> 32) + (c32b >> 32) + carry,
+ c00 + (c32a << 32) + (c32b << 32));
+#endif
+}
+
+// wide_multiply<T> multiplies two N-bit values to a 2N-bit result.
+template <typename UIntType>
+struct wide_multiply {
+ static constexpr size_t kN = std::numeric_limits<UIntType>::digits;
+ using input_type = UIntType;
+ using result_type = typename random_internal::unsigned_bits<kN * 2>::type;
+
+ static result_type multiply(input_type a, input_type b) {
+ return static_cast<result_type>(a) * b;
+ }
+
+ static input_type hi(result_type r) { return r >> kN; }
+ static input_type lo(result_type r) { return r; }
+
+ static_assert(std::is_unsigned<UIntType>::value,
+ "Class-template wide_multiply<> argument must be unsigned.");
+};
+
+#ifndef ABSL_HAVE_INTRINSIC_INT128
+template <>
+struct wide_multiply<uint64_t> {
+ using input_type = uint64_t;
using result_type = absl::uint128;
-
- static result_type multiply(uint64_t a, uint64_t b) {
- return MultiplyU64ToU128(a, b);
- }
-
+
+ static result_type multiply(uint64_t a, uint64_t b) {
+ return MultiplyU64ToU128(a, b);
+ }
+
static uint64_t hi(result_type r) { return absl::Uint128High64(r); }
static uint64_t lo(result_type r) { return absl::Uint128Low64(r); }
-};
-#endif
-
-} // namespace random_internal
+};
+#endif
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/log_uniform_int_distribution.h b/contrib/restricted/abseil-cpp/absl/random/log_uniform_int_distribution.h
index e8b7b0cc3e..43e101169c 100644
--- a/contrib/restricted/abseil-cpp/absl/random/log_uniform_int_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/log_uniform_int_distribution.h
@@ -1,257 +1,257 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_LOG_UNIFORM_INT_DISTRIBUTION_H_
-#define ABSL_RANDOM_LOG_UNIFORM_INT_DISTRIBUTION_H_
-
-#include <algorithm>
-#include <cassert>
-#include <cmath>
-#include <istream>
-#include <limits>
-#include <ostream>
-#include <type_traits>
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_LOG_UNIFORM_INT_DISTRIBUTION_H_
+#define ABSL_RANDOM_LOG_UNIFORM_INT_DISTRIBUTION_H_
+
+#include <algorithm>
+#include <cassert>
+#include <cmath>
+#include <istream>
+#include <limits>
+#include <ostream>
+#include <type_traits>
+
#include "absl/numeric/bits.h"
-#include "absl/random/internal/fastmath.h"
-#include "absl/random/internal/generate_real.h"
-#include "absl/random/internal/iostream_state_saver.h"
-#include "absl/random/internal/traits.h"
-#include "absl/random/uniform_int_distribution.h"
-
-namespace absl {
+#include "absl/random/internal/fastmath.h"
+#include "absl/random/internal/generate_real.h"
+#include "absl/random/internal/iostream_state_saver.h"
+#include "absl/random/internal/traits.h"
+#include "absl/random/uniform_int_distribution.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-
-// log_uniform_int_distribution:
-//
-// Returns a random variate R in range [min, max] such that
-// floor(log(R-min, base)) is uniformly distributed.
-// We ensure uniformity by discretization using the
-// boundary sets [0, 1, base, base * base, ... min(base*n, max)]
-//
-template <typename IntType = int>
-class log_uniform_int_distribution {
- private:
- using unsigned_type =
- typename random_internal::make_unsigned_bits<IntType>::type;
-
- public:
- using result_type = IntType;
-
- class param_type {
- public:
- using distribution_type = log_uniform_int_distribution;
-
- explicit param_type(
- result_type min = 0,
- result_type max = (std::numeric_limits<result_type>::max)(),
- result_type base = 2)
- : min_(min),
- max_(max),
- base_(base),
- range_(static_cast<unsigned_type>(max_) -
- static_cast<unsigned_type>(min_)),
- log_range_(0) {
- assert(max_ >= min_);
- assert(base_ > 1);
-
- if (base_ == 2) {
- // Determine where the first set bit is on range(), giving a log2(range)
- // value which can be used to construct bounds.
+
+// log_uniform_int_distribution:
+//
+// Returns a random variate R in range [min, max] such that
+// floor(log(R-min, base)) is uniformly distributed.
+// We ensure uniformity by discretization using the
+// boundary sets [0, 1, base, base * base, ... min(base*n, max)]
+//
+template <typename IntType = int>
+class log_uniform_int_distribution {
+ private:
+ using unsigned_type =
+ typename random_internal::make_unsigned_bits<IntType>::type;
+
+ public:
+ using result_type = IntType;
+
+ class param_type {
+ public:
+ using distribution_type = log_uniform_int_distribution;
+
+ explicit param_type(
+ result_type min = 0,
+ result_type max = (std::numeric_limits<result_type>::max)(),
+ result_type base = 2)
+ : min_(min),
+ max_(max),
+ base_(base),
+ range_(static_cast<unsigned_type>(max_) -
+ static_cast<unsigned_type>(min_)),
+ log_range_(0) {
+ assert(max_ >= min_);
+ assert(base_ > 1);
+
+ if (base_ == 2) {
+ // Determine where the first set bit is on range(), giving a log2(range)
+ // value which can be used to construct bounds.
log_range_ =
(std::min)(bit_width(range()),
static_cast<unsigned_type>(
std::numeric_limits<unsigned_type>::digits));
- } else {
- // NOTE: Computing the logN(x) introduces error from 2 sources:
- // 1. Conversion of int to double loses precision for values >=
- // 2^53, which may cause some log() computations to operate on
- // different values.
- // 2. The error introduced by the division will cause the result
- // to differ from the expected value.
- //
- // Thus a result which should equal K may equal K +/- epsilon,
- // which can eliminate some values depending on where the bounds fall.
- const double inv_log_base = 1.0 / std::log(base_);
- const double log_range = std::log(static_cast<double>(range()) + 0.5);
- log_range_ = static_cast<int>(std::ceil(inv_log_base * log_range));
- }
- }
-
- result_type(min)() const { return min_; }
- result_type(max)() const { return max_; }
- result_type base() const { return base_; }
-
- friend bool operator==(const param_type& a, const param_type& b) {
- return a.min_ == b.min_ && a.max_ == b.max_ && a.base_ == b.base_;
- }
-
- friend bool operator!=(const param_type& a, const param_type& b) {
- return !(a == b);
- }
-
- private:
- friend class log_uniform_int_distribution;
-
- int log_range() const { return log_range_; }
- unsigned_type range() const { return range_; }
-
- result_type min_;
- result_type max_;
- result_type base_;
- unsigned_type range_; // max - min
- int log_range_; // ceil(logN(range_))
-
- static_assert(std::is_integral<IntType>::value,
- "Class-template absl::log_uniform_int_distribution<> must be "
- "parameterized using an integral type.");
- };
-
- log_uniform_int_distribution() : log_uniform_int_distribution(0) {}
-
- explicit log_uniform_int_distribution(
- result_type min,
- result_type max = (std::numeric_limits<result_type>::max)(),
- result_type base = 2)
- : param_(min, max, base) {}
-
- explicit log_uniform_int_distribution(const param_type& p) : param_(p) {}
-
- void reset() {}
-
- // generating functions
- template <typename URBG>
- result_type operator()(URBG& g) { // NOLINT(runtime/references)
- return (*this)(g, param_);
- }
-
- template <typename URBG>
- result_type operator()(URBG& g, // NOLINT(runtime/references)
- const param_type& p) {
- return (p.min)() + Generate(g, p);
- }
-
- result_type(min)() const { return (param_.min)(); }
- result_type(max)() const { return (param_.max)(); }
- result_type base() const { return param_.base(); }
-
- param_type param() const { return param_; }
- void param(const param_type& p) { param_ = p; }
-
- friend bool operator==(const log_uniform_int_distribution& a,
- const log_uniform_int_distribution& b) {
- return a.param_ == b.param_;
- }
- friend bool operator!=(const log_uniform_int_distribution& a,
- const log_uniform_int_distribution& b) {
- return a.param_ != b.param_;
- }
-
- private:
- // Returns a log-uniform variate in the range [0, p.range()]. The caller
- // should add min() to shift the result to the correct range.
- template <typename URNG>
- unsigned_type Generate(URNG& g, // NOLINT(runtime/references)
- const param_type& p);
-
- param_type param_;
-};
-
-template <typename IntType>
-template <typename URBG>
-typename log_uniform_int_distribution<IntType>::unsigned_type
-log_uniform_int_distribution<IntType>::Generate(
- URBG& g, // NOLINT(runtime/references)
- const param_type& p) {
- // sample e over [0, log_range]. Map the results of e to this:
- // 0 => 0
- // 1 => [1, b-1]
- // 2 => [b, (b^2)-1]
- // n => [b^(n-1)..(b^n)-1]
- const int e = absl::uniform_int_distribution<int>(0, p.log_range())(g);
- if (e == 0) {
- return 0;
- }
- const int d = e - 1;
-
- unsigned_type base_e, top_e;
- if (p.base() == 2) {
- base_e = static_cast<unsigned_type>(1) << d;
-
- top_e = (e >= std::numeric_limits<unsigned_type>::digits)
- ? (std::numeric_limits<unsigned_type>::max)()
- : (static_cast<unsigned_type>(1) << e) - 1;
- } else {
- const double r = std::pow(p.base(), d);
- const double s = (r * p.base()) - 1.0;
-
- base_e =
- (r > static_cast<double>((std::numeric_limits<unsigned_type>::max)()))
- ? (std::numeric_limits<unsigned_type>::max)()
- : static_cast<unsigned_type>(r);
-
- top_e =
- (s > static_cast<double>((std::numeric_limits<unsigned_type>::max)()))
- ? (std::numeric_limits<unsigned_type>::max)()
- : static_cast<unsigned_type>(s);
- }
-
- const unsigned_type lo = (base_e >= p.range()) ? p.range() : base_e;
- const unsigned_type hi = (top_e >= p.range()) ? p.range() : top_e;
-
- // choose uniformly over [lo, hi]
- return absl::uniform_int_distribution<result_type>(lo, hi)(g);
-}
-
-template <typename CharT, typename Traits, typename IntType>
-std::basic_ostream<CharT, Traits>& operator<<(
- std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
- const log_uniform_int_distribution<IntType>& x) {
- using stream_type =
- typename random_internal::stream_format_type<IntType>::type;
- auto saver = random_internal::make_ostream_state_saver(os);
- os << static_cast<stream_type>((x.min)()) << os.fill()
- << static_cast<stream_type>((x.max)()) << os.fill()
- << static_cast<stream_type>(x.base());
- return os;
-}
-
-template <typename CharT, typename Traits, typename IntType>
-std::basic_istream<CharT, Traits>& operator>>(
- std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
- log_uniform_int_distribution<IntType>& x) { // NOLINT(runtime/references)
- using param_type = typename log_uniform_int_distribution<IntType>::param_type;
- using result_type =
- typename log_uniform_int_distribution<IntType>::result_type;
- using stream_type =
- typename random_internal::stream_format_type<IntType>::type;
-
- stream_type min;
- stream_type max;
- stream_type base;
-
- auto saver = random_internal::make_istream_state_saver(is);
- is >> min >> max >> base;
- if (!is.fail()) {
- x.param(param_type(static_cast<result_type>(min),
- static_cast<result_type>(max),
- static_cast<result_type>(base)));
- }
- return is;
-}
-
+ } else {
+ // NOTE: Computing the logN(x) introduces error from 2 sources:
+ // 1. Conversion of int to double loses precision for values >=
+ // 2^53, which may cause some log() computations to operate on
+ // different values.
+ // 2. The error introduced by the division will cause the result
+ // to differ from the expected value.
+ //
+ // Thus a result which should equal K may equal K +/- epsilon,
+ // which can eliminate some values depending on where the bounds fall.
+ const double inv_log_base = 1.0 / std::log(base_);
+ const double log_range = std::log(static_cast<double>(range()) + 0.5);
+ log_range_ = static_cast<int>(std::ceil(inv_log_base * log_range));
+ }
+ }
+
+ result_type(min)() const { return min_; }
+ result_type(max)() const { return max_; }
+ result_type base() const { return base_; }
+
+ friend bool operator==(const param_type& a, const param_type& b) {
+ return a.min_ == b.min_ && a.max_ == b.max_ && a.base_ == b.base_;
+ }
+
+ friend bool operator!=(const param_type& a, const param_type& b) {
+ return !(a == b);
+ }
+
+ private:
+ friend class log_uniform_int_distribution;
+
+ int log_range() const { return log_range_; }
+ unsigned_type range() const { return range_; }
+
+ result_type min_;
+ result_type max_;
+ result_type base_;
+ unsigned_type range_; // max - min
+ int log_range_; // ceil(logN(range_))
+
+ static_assert(std::is_integral<IntType>::value,
+ "Class-template absl::log_uniform_int_distribution<> must be "
+ "parameterized using an integral type.");
+ };
+
+ log_uniform_int_distribution() : log_uniform_int_distribution(0) {}
+
+ explicit log_uniform_int_distribution(
+ result_type min,
+ result_type max = (std::numeric_limits<result_type>::max)(),
+ result_type base = 2)
+ : param_(min, max, base) {}
+
+ explicit log_uniform_int_distribution(const param_type& p) : param_(p) {}
+
+ void reset() {}
+
+ // generating functions
+ template <typename URBG>
+ result_type operator()(URBG& g) { // NOLINT(runtime/references)
+ return (*this)(g, param_);
+ }
+
+ template <typename URBG>
+ result_type operator()(URBG& g, // NOLINT(runtime/references)
+ const param_type& p) {
+ return (p.min)() + Generate(g, p);
+ }
+
+ result_type(min)() const { return (param_.min)(); }
+ result_type(max)() const { return (param_.max)(); }
+ result_type base() const { return param_.base(); }
+
+ param_type param() const { return param_; }
+ void param(const param_type& p) { param_ = p; }
+
+ friend bool operator==(const log_uniform_int_distribution& a,
+ const log_uniform_int_distribution& b) {
+ return a.param_ == b.param_;
+ }
+ friend bool operator!=(const log_uniform_int_distribution& a,
+ const log_uniform_int_distribution& b) {
+ return a.param_ != b.param_;
+ }
+
+ private:
+ // Returns a log-uniform variate in the range [0, p.range()]. The caller
+ // should add min() to shift the result to the correct range.
+ template <typename URNG>
+ unsigned_type Generate(URNG& g, // NOLINT(runtime/references)
+ const param_type& p);
+
+ param_type param_;
+};
+
+template <typename IntType>
+template <typename URBG>
+typename log_uniform_int_distribution<IntType>::unsigned_type
+log_uniform_int_distribution<IntType>::Generate(
+ URBG& g, // NOLINT(runtime/references)
+ const param_type& p) {
+ // sample e over [0, log_range]. Map the results of e to this:
+ // 0 => 0
+ // 1 => [1, b-1]
+ // 2 => [b, (b^2)-1]
+ // n => [b^(n-1)..(b^n)-1]
+ const int e = absl::uniform_int_distribution<int>(0, p.log_range())(g);
+ if (e == 0) {
+ return 0;
+ }
+ const int d = e - 1;
+
+ unsigned_type base_e, top_e;
+ if (p.base() == 2) {
+ base_e = static_cast<unsigned_type>(1) << d;
+
+ top_e = (e >= std::numeric_limits<unsigned_type>::digits)
+ ? (std::numeric_limits<unsigned_type>::max)()
+ : (static_cast<unsigned_type>(1) << e) - 1;
+ } else {
+ const double r = std::pow(p.base(), d);
+ const double s = (r * p.base()) - 1.0;
+
+ base_e =
+ (r > static_cast<double>((std::numeric_limits<unsigned_type>::max)()))
+ ? (std::numeric_limits<unsigned_type>::max)()
+ : static_cast<unsigned_type>(r);
+
+ top_e =
+ (s > static_cast<double>((std::numeric_limits<unsigned_type>::max)()))
+ ? (std::numeric_limits<unsigned_type>::max)()
+ : static_cast<unsigned_type>(s);
+ }
+
+ const unsigned_type lo = (base_e >= p.range()) ? p.range() : base_e;
+ const unsigned_type hi = (top_e >= p.range()) ? p.range() : top_e;
+
+ // choose uniformly over [lo, hi]
+ return absl::uniform_int_distribution<result_type>(lo, hi)(g);
+}
+
+template <typename CharT, typename Traits, typename IntType>
+std::basic_ostream<CharT, Traits>& operator<<(
+ std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
+ const log_uniform_int_distribution<IntType>& x) {
+ using stream_type =
+ typename random_internal::stream_format_type<IntType>::type;
+ auto saver = random_internal::make_ostream_state_saver(os);
+ os << static_cast<stream_type>((x.min)()) << os.fill()
+ << static_cast<stream_type>((x.max)()) << os.fill()
+ << static_cast<stream_type>(x.base());
+ return os;
+}
+
+template <typename CharT, typename Traits, typename IntType>
+std::basic_istream<CharT, Traits>& operator>>(
+ std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
+ log_uniform_int_distribution<IntType>& x) { // NOLINT(runtime/references)
+ using param_type = typename log_uniform_int_distribution<IntType>::param_type;
+ using result_type =
+ typename log_uniform_int_distribution<IntType>::result_type;
+ using stream_type =
+ typename random_internal::stream_format_type<IntType>::type;
+
+ stream_type min;
+ stream_type max;
+ stream_type base;
+
+ auto saver = random_internal::make_istream_state_saver(is);
+ is >> min >> max >> base;
+ if (!is.fail()) {
+ x.param(param_type(static_cast<result_type>(min),
+ static_cast<result_type>(max),
+ static_cast<result_type>(base)));
+ }
+ return is;
+}
+
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_LOG_UNIFORM_INT_DISTRIBUTION_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_LOG_UNIFORM_INT_DISTRIBUTION_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/poisson_distribution.h b/contrib/restricted/abseil-cpp/absl/random/poisson_distribution.h
index 37389ead21..cb5f5d5d0f 100644
--- a/contrib/restricted/abseil-cpp/absl/random/poisson_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/poisson_distribution.h
@@ -1,258 +1,258 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_POISSON_DISTRIBUTION_H_
-#define ABSL_RANDOM_POISSON_DISTRIBUTION_H_
-
-#include <cassert>
-#include <cmath>
-#include <istream>
-#include <limits>
-#include <ostream>
-#include <type_traits>
-
-#include "absl/random/internal/fast_uniform_bits.h"
-#include "absl/random/internal/fastmath.h"
-#include "absl/random/internal/generate_real.h"
-#include "absl/random/internal/iostream_state_saver.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_POISSON_DISTRIBUTION_H_
+#define ABSL_RANDOM_POISSON_DISTRIBUTION_H_
+
+#include <cassert>
+#include <cmath>
+#include <istream>
+#include <limits>
+#include <ostream>
+#include <type_traits>
+
+#include "absl/random/internal/fast_uniform_bits.h"
+#include "absl/random/internal/fastmath.h"
+#include "absl/random/internal/generate_real.h"
+#include "absl/random/internal/iostream_state_saver.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-
-// absl::poisson_distribution:
-// Generates discrete variates conforming to a Poisson distribution.
-// p(n) = (mean^n / n!) exp(-mean)
-//
-// Depending on the parameter, the distribution selects one of the following
-// algorithms:
-// * The standard algorithm, attributed to Knuth, extended using a split method
-// for larger values
-// * The "Ratio of Uniforms as a convenient method for sampling from classical
-// discrete distributions", Stadlober, 1989.
-// http://www.sciencedirect.com/science/article/pii/0377042790903495
-//
-// NOTE: param_type.mean() is a double, which permits values larger than
-// poisson_distribution<IntType>::max(), however this should be avoided and
-// the distribution results are limited to the max() value.
-//
-// The goals of this implementation are to provide good performance while still
-// beig thread-safe: This limits the implementation to not using lgamma provided
-// by <math.h>.
-//
-template <typename IntType = int>
-class poisson_distribution {
- public:
- using result_type = IntType;
-
- class param_type {
- public:
- using distribution_type = poisson_distribution;
- explicit param_type(double mean = 1.0);
-
- double mean() const { return mean_; }
-
- friend bool operator==(const param_type& a, const param_type& b) {
- return a.mean_ == b.mean_;
- }
-
- friend bool operator!=(const param_type& a, const param_type& b) {
- return !(a == b);
- }
-
- private:
- friend class poisson_distribution;
-
- double mean_;
- double emu_; // e ^ -mean_
- double lmu_; // ln(mean_)
- double s_;
- double log_k_;
- int split_;
-
- static_assert(std::is_integral<IntType>::value,
- "Class-template absl::poisson_distribution<> must be "
- "parameterized using an integral type.");
- };
-
- poisson_distribution() : poisson_distribution(1.0) {}
-
- explicit poisson_distribution(double mean) : param_(mean) {}
-
- explicit poisson_distribution(const param_type& p) : param_(p) {}
-
- void reset() {}
-
- // generating functions
- template <typename URBG>
- result_type operator()(URBG& g) { // NOLINT(runtime/references)
- return (*this)(g, param_);
- }
-
- template <typename URBG>
- result_type operator()(URBG& g, // NOLINT(runtime/references)
- const param_type& p);
-
- param_type param() const { return param_; }
- void param(const param_type& p) { param_ = p; }
-
- result_type(min)() const { return 0; }
- result_type(max)() const { return (std::numeric_limits<result_type>::max)(); }
-
- double mean() const { return param_.mean(); }
-
- friend bool operator==(const poisson_distribution& a,
- const poisson_distribution& b) {
- return a.param_ == b.param_;
- }
- friend bool operator!=(const poisson_distribution& a,
- const poisson_distribution& b) {
- return a.param_ != b.param_;
- }
-
- private:
- param_type param_;
- random_internal::FastUniformBits<uint64_t> fast_u64_;
-};
-
-// -----------------------------------------------------------------------------
-// Implementation details follow
-// -----------------------------------------------------------------------------
-
-template <typename IntType>
-poisson_distribution<IntType>::param_type::param_type(double mean)
- : mean_(mean), split_(0) {
- assert(mean >= 0);
- assert(mean <= (std::numeric_limits<result_type>::max)());
- // As a defensive measure, avoid large values of the mean. The rejection
- // algorithm used does not support very large values well. It my be worth
- // changing algorithms to better deal with these cases.
- assert(mean <= 1e10);
- if (mean_ < 10) {
- // For small lambda, use the knuth method.
- split_ = 1;
- emu_ = std::exp(-mean_);
- } else if (mean_ <= 50) {
- // Use split-knuth method.
- split_ = 1 + static_cast<int>(mean_ / 10.0);
- emu_ = std::exp(-mean_ / static_cast<double>(split_));
- } else {
- // Use ratio of uniforms method.
- constexpr double k2E = 0.7357588823428846;
- constexpr double kSA = 0.4494580810294493;
-
- lmu_ = std::log(mean_);
- double a = mean_ + 0.5;
- s_ = kSA + std::sqrt(k2E * a);
- const double mode = std::ceil(mean_) - 1;
- log_k_ = lmu_ * mode - absl::random_internal::StirlingLogFactorial(mode);
- }
-}
-
-template <typename IntType>
-template <typename URBG>
-typename poisson_distribution<IntType>::result_type
-poisson_distribution<IntType>::operator()(
- URBG& g, // NOLINT(runtime/references)
- const param_type& p) {
- using random_internal::GeneratePositiveTag;
- using random_internal::GenerateRealFromBits;
- using random_internal::GenerateSignedTag;
-
- if (p.split_ != 0) {
- // Use Knuth's algorithm with range splitting to avoid floating-point
- // errors. Knuth's algorithm is: Ui is a sequence of uniform variates on
- // (0,1); return the number of variates required for product(Ui) <
- // exp(-lambda).
- //
- // The expected number of variates required for Knuth's method can be
- // computed as follows:
- // The expected value of U is 0.5, so solving for 0.5^n < exp(-lambda) gives
- // the expected number of uniform variates
- // required for a given lambda, which is:
- // lambda = [2, 5, 9, 10, 11, 12, 13, 14, 15, 16, 17]
- // n = [3, 8, 13, 15, 16, 18, 19, 21, 22, 24, 25]
- //
- result_type n = 0;
- for (int split = p.split_; split > 0; --split) {
- double r = 1.0;
- do {
- r *= GenerateRealFromBits<double, GeneratePositiveTag, true>(
- fast_u64_(g)); // U(-1, 0)
- ++n;
- } while (r > p.emu_);
- --n;
- }
- return n;
- }
-
- // Use ratio of uniforms method.
- //
- // Let u ~ Uniform(0, 1), v ~ Uniform(-1, 1),
- // a = lambda + 1/2,
- // s = 1.5 - sqrt(3/e) + sqrt(2(lambda + 1/2)/e),
- // x = s * v/u + a.
- // P(floor(x) = k | u^2 < f(floor(x))/k), where
- // f(m) = lambda^m exp(-lambda)/ m!, for 0 <= m, and f(m) = 0 otherwise,
- // and k = max(f).
- const double a = p.mean_ + 0.5;
- for (;;) {
- const double u = GenerateRealFromBits<double, GeneratePositiveTag, false>(
- fast_u64_(g)); // U(0, 1)
- const double v = GenerateRealFromBits<double, GenerateSignedTag, false>(
- fast_u64_(g)); // U(-1, 1)
-
- const double x = std::floor(p.s_ * v / u + a);
- if (x < 0) continue; // f(negative) = 0
- const double rhs = x * p.lmu_;
- // clang-format off
- double s = (x <= 1.0) ? 0.0
- : (x == 2.0) ? 0.693147180559945
- : absl::random_internal::StirlingLogFactorial(x);
- // clang-format on
- const double lhs = 2.0 * std::log(u) + p.log_k_ + s;
- if (lhs < rhs) {
- return x > (max)() ? (max)()
- : static_cast<result_type>(x); // f(x)/k >= u^2
- }
- }
-}
-
-template <typename CharT, typename Traits, typename IntType>
-std::basic_ostream<CharT, Traits>& operator<<(
- std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
- const poisson_distribution<IntType>& x) {
- auto saver = random_internal::make_ostream_state_saver(os);
- os.precision(random_internal::stream_precision_helper<double>::kPrecision);
- os << x.mean();
- return os;
-}
-
-template <typename CharT, typename Traits, typename IntType>
-std::basic_istream<CharT, Traits>& operator>>(
- std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
- poisson_distribution<IntType>& x) { // NOLINT(runtime/references)
- using param_type = typename poisson_distribution<IntType>::param_type;
-
- auto saver = random_internal::make_istream_state_saver(is);
- double mean = random_internal::read_floating_point<double>(is);
- if (!is.fail()) {
- x.param(param_type(mean));
- }
- return is;
-}
-
+
+// absl::poisson_distribution:
+// Generates discrete variates conforming to a Poisson distribution.
+// p(n) = (mean^n / n!) exp(-mean)
+//
+// Depending on the parameter, the distribution selects one of the following
+// algorithms:
+// * The standard algorithm, attributed to Knuth, extended using a split method
+// for larger values
+// * The "Ratio of Uniforms as a convenient method for sampling from classical
+// discrete distributions", Stadlober, 1989.
+// http://www.sciencedirect.com/science/article/pii/0377042790903495
+//
+// NOTE: param_type.mean() is a double, which permits values larger than
+// poisson_distribution<IntType>::max(), however this should be avoided and
+// the distribution results are limited to the max() value.
+//
+// The goals of this implementation are to provide good performance while still
+// beig thread-safe: This limits the implementation to not using lgamma provided
+// by <math.h>.
+//
+template <typename IntType = int>
+class poisson_distribution {
+ public:
+ using result_type = IntType;
+
+ class param_type {
+ public:
+ using distribution_type = poisson_distribution;
+ explicit param_type(double mean = 1.0);
+
+ double mean() const { return mean_; }
+
+ friend bool operator==(const param_type& a, const param_type& b) {
+ return a.mean_ == b.mean_;
+ }
+
+ friend bool operator!=(const param_type& a, const param_type& b) {
+ return !(a == b);
+ }
+
+ private:
+ friend class poisson_distribution;
+
+ double mean_;
+ double emu_; // e ^ -mean_
+ double lmu_; // ln(mean_)
+ double s_;
+ double log_k_;
+ int split_;
+
+ static_assert(std::is_integral<IntType>::value,
+ "Class-template absl::poisson_distribution<> must be "
+ "parameterized using an integral type.");
+ };
+
+ poisson_distribution() : poisson_distribution(1.0) {}
+
+ explicit poisson_distribution(double mean) : param_(mean) {}
+
+ explicit poisson_distribution(const param_type& p) : param_(p) {}
+
+ void reset() {}
+
+ // generating functions
+ template <typename URBG>
+ result_type operator()(URBG& g) { // NOLINT(runtime/references)
+ return (*this)(g, param_);
+ }
+
+ template <typename URBG>
+ result_type operator()(URBG& g, // NOLINT(runtime/references)
+ const param_type& p);
+
+ param_type param() const { return param_; }
+ void param(const param_type& p) { param_ = p; }
+
+ result_type(min)() const { return 0; }
+ result_type(max)() const { return (std::numeric_limits<result_type>::max)(); }
+
+ double mean() const { return param_.mean(); }
+
+ friend bool operator==(const poisson_distribution& a,
+ const poisson_distribution& b) {
+ return a.param_ == b.param_;
+ }
+ friend bool operator!=(const poisson_distribution& a,
+ const poisson_distribution& b) {
+ return a.param_ != b.param_;
+ }
+
+ private:
+ param_type param_;
+ random_internal::FastUniformBits<uint64_t> fast_u64_;
+};
+
+// -----------------------------------------------------------------------------
+// Implementation details follow
+// -----------------------------------------------------------------------------
+
+template <typename IntType>
+poisson_distribution<IntType>::param_type::param_type(double mean)
+ : mean_(mean), split_(0) {
+ assert(mean >= 0);
+ assert(mean <= (std::numeric_limits<result_type>::max)());
+ // As a defensive measure, avoid large values of the mean. The rejection
+ // algorithm used does not support very large values well. It my be worth
+ // changing algorithms to better deal with these cases.
+ assert(mean <= 1e10);
+ if (mean_ < 10) {
+ // For small lambda, use the knuth method.
+ split_ = 1;
+ emu_ = std::exp(-mean_);
+ } else if (mean_ <= 50) {
+ // Use split-knuth method.
+ split_ = 1 + static_cast<int>(mean_ / 10.0);
+ emu_ = std::exp(-mean_ / static_cast<double>(split_));
+ } else {
+ // Use ratio of uniforms method.
+ constexpr double k2E = 0.7357588823428846;
+ constexpr double kSA = 0.4494580810294493;
+
+ lmu_ = std::log(mean_);
+ double a = mean_ + 0.5;
+ s_ = kSA + std::sqrt(k2E * a);
+ const double mode = std::ceil(mean_) - 1;
+ log_k_ = lmu_ * mode - absl::random_internal::StirlingLogFactorial(mode);
+ }
+}
+
+template <typename IntType>
+template <typename URBG>
+typename poisson_distribution<IntType>::result_type
+poisson_distribution<IntType>::operator()(
+ URBG& g, // NOLINT(runtime/references)
+ const param_type& p) {
+ using random_internal::GeneratePositiveTag;
+ using random_internal::GenerateRealFromBits;
+ using random_internal::GenerateSignedTag;
+
+ if (p.split_ != 0) {
+ // Use Knuth's algorithm with range splitting to avoid floating-point
+ // errors. Knuth's algorithm is: Ui is a sequence of uniform variates on
+ // (0,1); return the number of variates required for product(Ui) <
+ // exp(-lambda).
+ //
+ // The expected number of variates required for Knuth's method can be
+ // computed as follows:
+ // The expected value of U is 0.5, so solving for 0.5^n < exp(-lambda) gives
+ // the expected number of uniform variates
+ // required for a given lambda, which is:
+ // lambda = [2, 5, 9, 10, 11, 12, 13, 14, 15, 16, 17]
+ // n = [3, 8, 13, 15, 16, 18, 19, 21, 22, 24, 25]
+ //
+ result_type n = 0;
+ for (int split = p.split_; split > 0; --split) {
+ double r = 1.0;
+ do {
+ r *= GenerateRealFromBits<double, GeneratePositiveTag, true>(
+ fast_u64_(g)); // U(-1, 0)
+ ++n;
+ } while (r > p.emu_);
+ --n;
+ }
+ return n;
+ }
+
+ // Use ratio of uniforms method.
+ //
+ // Let u ~ Uniform(0, 1), v ~ Uniform(-1, 1),
+ // a = lambda + 1/2,
+ // s = 1.5 - sqrt(3/e) + sqrt(2(lambda + 1/2)/e),
+ // x = s * v/u + a.
+ // P(floor(x) = k | u^2 < f(floor(x))/k), where
+ // f(m) = lambda^m exp(-lambda)/ m!, for 0 <= m, and f(m) = 0 otherwise,
+ // and k = max(f).
+ const double a = p.mean_ + 0.5;
+ for (;;) {
+ const double u = GenerateRealFromBits<double, GeneratePositiveTag, false>(
+ fast_u64_(g)); // U(0, 1)
+ const double v = GenerateRealFromBits<double, GenerateSignedTag, false>(
+ fast_u64_(g)); // U(-1, 1)
+
+ const double x = std::floor(p.s_ * v / u + a);
+ if (x < 0) continue; // f(negative) = 0
+ const double rhs = x * p.lmu_;
+ // clang-format off
+ double s = (x <= 1.0) ? 0.0
+ : (x == 2.0) ? 0.693147180559945
+ : absl::random_internal::StirlingLogFactorial(x);
+ // clang-format on
+ const double lhs = 2.0 * std::log(u) + p.log_k_ + s;
+ if (lhs < rhs) {
+ return x > (max)() ? (max)()
+ : static_cast<result_type>(x); // f(x)/k >= u^2
+ }
+ }
+}
+
+template <typename CharT, typename Traits, typename IntType>
+std::basic_ostream<CharT, Traits>& operator<<(
+ std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
+ const poisson_distribution<IntType>& x) {
+ auto saver = random_internal::make_ostream_state_saver(os);
+ os.precision(random_internal::stream_precision_helper<double>::kPrecision);
+ os << x.mean();
+ return os;
+}
+
+template <typename CharT, typename Traits, typename IntType>
+std::basic_istream<CharT, Traits>& operator>>(
+ std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
+ poisson_distribution<IntType>& x) { // NOLINT(runtime/references)
+ using param_type = typename poisson_distribution<IntType>::param_type;
+
+ auto saver = random_internal::make_istream_state_saver(is);
+ double mean = random_internal::read_floating_point<double>(is);
+ if (!is.fail()) {
+ x.param(param_type(mean));
+ }
+ return is;
+}
+
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_POISSON_DISTRIBUTION_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_POISSON_DISTRIBUTION_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/random.h b/contrib/restricted/abseil-cpp/absl/random/random.h
index fc2da78cd5..71b6309288 100644
--- a/contrib/restricted/abseil-cpp/absl/random/random.h
+++ b/contrib/restricted/abseil-cpp/absl/random/random.h
@@ -1,189 +1,189 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// -----------------------------------------------------------------------------
-// File: random.h
-// -----------------------------------------------------------------------------
-//
-// This header defines the recommended Uniform Random Bit Generator (URBG)
-// types for use within the Abseil Random library. These types are not
-// suitable for security-related use-cases, but should suffice for most other
-// uses of generating random values.
-//
-// The Abseil random library provides the following URBG types:
-//
-// * BitGen, a good general-purpose bit generator, optimized for generating
-// random (but not cryptographically secure) values
-// * InsecureBitGen, a slightly faster, though less random, bit generator, for
-// cases where the existing BitGen is a drag on performance.
-
-#ifndef ABSL_RANDOM_RANDOM_H_
-#define ABSL_RANDOM_RANDOM_H_
-
-#include <random>
-
-#include "absl/random/distributions.h" // IWYU pragma: export
-#include "absl/random/internal/nonsecure_base.h" // IWYU pragma: export
-#include "absl/random/internal/pcg_engine.h" // IWYU pragma: export
-#include "absl/random/internal/pool_urbg.h"
-#include "absl/random/internal/randen_engine.h"
-#include "absl/random/seed_sequences.h" // IWYU pragma: export
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// -----------------------------------------------------------------------------
+// File: random.h
+// -----------------------------------------------------------------------------
+//
+// This header defines the recommended Uniform Random Bit Generator (URBG)
+// types for use within the Abseil Random library. These types are not
+// suitable for security-related use-cases, but should suffice for most other
+// uses of generating random values.
+//
+// The Abseil random library provides the following URBG types:
+//
+// * BitGen, a good general-purpose bit generator, optimized for generating
+// random (but not cryptographically secure) values
+// * InsecureBitGen, a slightly faster, though less random, bit generator, for
+// cases where the existing BitGen is a drag on performance.
+
+#ifndef ABSL_RANDOM_RANDOM_H_
+#define ABSL_RANDOM_RANDOM_H_
+
+#include <random>
+
+#include "absl/random/distributions.h" // IWYU pragma: export
+#include "absl/random/internal/nonsecure_base.h" // IWYU pragma: export
+#include "absl/random/internal/pcg_engine.h" // IWYU pragma: export
+#include "absl/random/internal/pool_urbg.h"
+#include "absl/random/internal/randen_engine.h"
+#include "absl/random/seed_sequences.h" // IWYU pragma: export
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-
-// -----------------------------------------------------------------------------
-// absl::BitGen
-// -----------------------------------------------------------------------------
-//
-// `absl::BitGen` is a general-purpose random bit generator for generating
-// random values for use within the Abseil random library. Typically, you use a
-// bit generator in combination with a distribution to provide random values.
-//
-// Example:
-//
-// // Create an absl::BitGen. There is no need to seed this bit generator.
-// absl::BitGen gen;
-//
-// // Generate an integer value in the closed interval [1,6]
-// int die_roll = absl::uniform_int_distribution<int>(1, 6)(gen);
-//
-// `absl::BitGen` is seeded by default with non-deterministic data to produce
-// different sequences of random values across different instances, including
-// different binary invocations. This behavior is different than the standard
-// library bit generators, which use golden values as their seeds. Default
-// construction intentionally provides no stability guarantees, to avoid
-// accidental dependence on such a property.
-//
-// `absl::BitGen` may be constructed with an optional seed sequence type,
-// conforming to [rand.req.seed_seq], which will be mixed with additional
-// non-deterministic data.
-//
-// Example:
-//
-// // Create an absl::BitGen using an std::seed_seq seed sequence
-// std::seed_seq seq{1,2,3};
-// absl::BitGen gen_with_seed(seq);
-//
-// // Generate an integer value in the closed interval [1,6]
-// int die_roll2 = absl::uniform_int_distribution<int>(1, 6)(gen_with_seed);
-//
-// `absl::BitGen` meets the requirements of the Uniform Random Bit Generator
-// (URBG) concept as per the C++17 standard [rand.req.urng] though differs
-// slightly with [rand.req.eng]. Like its standard library equivalents (e.g.
-// `std::mersenne_twister_engine`) `absl::BitGen` is not cryptographically
-// secure.
-//
-// Constructing two `absl::BitGen`s with the same seed sequence in the same
-// binary will produce the same sequence of variates within the same binary, but
-// need not do so across multiple binary invocations.
-//
-// This type has been optimized to perform better than Mersenne Twister
-// (https://en.wikipedia.org/wiki/Mersenne_Twister) and many other complex URBG
-// types on modern x86, ARM, and PPC architectures.
-//
-// This type is thread-compatible, but not thread-safe.
-
-// ---------------------------------------------------------------------------
-// absl::BitGen member functions
-// ---------------------------------------------------------------------------
-
-// absl::BitGen::operator()()
-//
-// Calls the BitGen, returning a generated value.
-
-// absl::BitGen::min()
-//
-// Returns the smallest possible value from this bit generator.
-
-// absl::BitGen::max()
-//
+
+// -----------------------------------------------------------------------------
+// absl::BitGen
+// -----------------------------------------------------------------------------
+//
+// `absl::BitGen` is a general-purpose random bit generator for generating
+// random values for use within the Abseil random library. Typically, you use a
+// bit generator in combination with a distribution to provide random values.
+//
+// Example:
+//
+// // Create an absl::BitGen. There is no need to seed this bit generator.
+// absl::BitGen gen;
+//
+// // Generate an integer value in the closed interval [1,6]
+// int die_roll = absl::uniform_int_distribution<int>(1, 6)(gen);
+//
+// `absl::BitGen` is seeded by default with non-deterministic data to produce
+// different sequences of random values across different instances, including
+// different binary invocations. This behavior is different than the standard
+// library bit generators, which use golden values as their seeds. Default
+// construction intentionally provides no stability guarantees, to avoid
+// accidental dependence on such a property.
+//
+// `absl::BitGen` may be constructed with an optional seed sequence type,
+// conforming to [rand.req.seed_seq], which will be mixed with additional
+// non-deterministic data.
+//
+// Example:
+//
+// // Create an absl::BitGen using an std::seed_seq seed sequence
+// std::seed_seq seq{1,2,3};
+// absl::BitGen gen_with_seed(seq);
+//
+// // Generate an integer value in the closed interval [1,6]
+// int die_roll2 = absl::uniform_int_distribution<int>(1, 6)(gen_with_seed);
+//
+// `absl::BitGen` meets the requirements of the Uniform Random Bit Generator
+// (URBG) concept as per the C++17 standard [rand.req.urng] though differs
+// slightly with [rand.req.eng]. Like its standard library equivalents (e.g.
+// `std::mersenne_twister_engine`) `absl::BitGen` is not cryptographically
+// secure.
+//
+// Constructing two `absl::BitGen`s with the same seed sequence in the same
+// binary will produce the same sequence of variates within the same binary, but
+// need not do so across multiple binary invocations.
+//
+// This type has been optimized to perform better than Mersenne Twister
+// (https://en.wikipedia.org/wiki/Mersenne_Twister) and many other complex URBG
+// types on modern x86, ARM, and PPC architectures.
+//
+// This type is thread-compatible, but not thread-safe.
+
+// ---------------------------------------------------------------------------
+// absl::BitGen member functions
+// ---------------------------------------------------------------------------
+
+// absl::BitGen::operator()()
+//
+// Calls the BitGen, returning a generated value.
+
+// absl::BitGen::min()
+//
+// Returns the smallest possible value from this bit generator.
+
+// absl::BitGen::max()
+//
// Returns the largest possible value from this bit generator.
-
-// absl::BitGen::discard(num)
-//
-// Advances the internal state of this bit generator by `num` times, and
-// discards the intermediate results.
-// ---------------------------------------------------------------------------
-
-using BitGen = random_internal::NonsecureURBGBase<
- random_internal::randen_engine<uint64_t>>;
-
-// -----------------------------------------------------------------------------
-// absl::InsecureBitGen
-// -----------------------------------------------------------------------------
-//
-// `absl::InsecureBitGen` is an efficient random bit generator for generating
-// random values, recommended only for performance-sensitive use cases where
-// `absl::BitGen` is not satisfactory when compute-bounded by bit generation
-// costs.
-//
-// Example:
-//
-// // Create an absl::InsecureBitGen
-// absl::InsecureBitGen gen;
-// for (size_t i = 0; i < 1000000; i++) {
-//
-// // Generate a bunch of random values from some complex distribution
-// auto my_rnd = some_distribution(gen, 1, 1000);
-// }
-//
-// Like `absl::BitGen`, `absl::InsecureBitGen` is seeded by default with
-// non-deterministic data to produce different sequences of random values across
-// different instances, including different binary invocations. (This behavior
-// is different than the standard library bit generators, which use golden
-// values as their seeds.)
-//
-// `absl::InsecureBitGen` may be constructed with an optional seed sequence
-// type, conforming to [rand.req.seed_seq], which will be mixed with additional
-// non-deterministic data. (See std_seed_seq.h for more information.)
-//
-// `absl::InsecureBitGen` meets the requirements of the Uniform Random Bit
-// Generator (URBG) concept as per the C++17 standard [rand.req.urng] though
-// its implementation differs slightly with [rand.req.eng]. Like its standard
-// library equivalents (e.g. `std::mersenne_twister_engine`)
-// `absl::InsecureBitGen` is not cryptographically secure.
-//
-// Prefer `absl::BitGen` over `absl::InsecureBitGen` as the general type is
-// often fast enough for the vast majority of applications.
-
-using InsecureBitGen =
- random_internal::NonsecureURBGBase<random_internal::pcg64_2018_engine>;
-
-// ---------------------------------------------------------------------------
-// absl::InsecureBitGen member functions
-// ---------------------------------------------------------------------------
-
-// absl::InsecureBitGen::operator()()
-//
-// Calls the InsecureBitGen, returning a generated value.
-
-// absl::InsecureBitGen::min()
-//
-// Returns the smallest possible value from this bit generator.
-
-// absl::InsecureBitGen::max()
-//
-// Returns the largest possible value from this bit generator.
-
-// absl::InsecureBitGen::discard(num)
-//
-// Advances the internal state of this bit generator by `num` times, and
-// discards the intermediate results.
-// ---------------------------------------------------------------------------
-
+
+// absl::BitGen::discard(num)
+//
+// Advances the internal state of this bit generator by `num` times, and
+// discards the intermediate results.
+// ---------------------------------------------------------------------------
+
+using BitGen = random_internal::NonsecureURBGBase<
+ random_internal::randen_engine<uint64_t>>;
+
+// -----------------------------------------------------------------------------
+// absl::InsecureBitGen
+// -----------------------------------------------------------------------------
+//
+// `absl::InsecureBitGen` is an efficient random bit generator for generating
+// random values, recommended only for performance-sensitive use cases where
+// `absl::BitGen` is not satisfactory when compute-bounded by bit generation
+// costs.
+//
+// Example:
+//
+// // Create an absl::InsecureBitGen
+// absl::InsecureBitGen gen;
+// for (size_t i = 0; i < 1000000; i++) {
+//
+// // Generate a bunch of random values from some complex distribution
+// auto my_rnd = some_distribution(gen, 1, 1000);
+// }
+//
+// Like `absl::BitGen`, `absl::InsecureBitGen` is seeded by default with
+// non-deterministic data to produce different sequences of random values across
+// different instances, including different binary invocations. (This behavior
+// is different than the standard library bit generators, which use golden
+// values as their seeds.)
+//
+// `absl::InsecureBitGen` may be constructed with an optional seed sequence
+// type, conforming to [rand.req.seed_seq], which will be mixed with additional
+// non-deterministic data. (See std_seed_seq.h for more information.)
+//
+// `absl::InsecureBitGen` meets the requirements of the Uniform Random Bit
+// Generator (URBG) concept as per the C++17 standard [rand.req.urng] though
+// its implementation differs slightly with [rand.req.eng]. Like its standard
+// library equivalents (e.g. `std::mersenne_twister_engine`)
+// `absl::InsecureBitGen` is not cryptographically secure.
+//
+// Prefer `absl::BitGen` over `absl::InsecureBitGen` as the general type is
+// often fast enough for the vast majority of applications.
+
+using InsecureBitGen =
+ random_internal::NonsecureURBGBase<random_internal::pcg64_2018_engine>;
+
+// ---------------------------------------------------------------------------
+// absl::InsecureBitGen member functions
+// ---------------------------------------------------------------------------
+
+// absl::InsecureBitGen::operator()()
+//
+// Calls the InsecureBitGen, returning a generated value.
+
+// absl::InsecureBitGen::min()
+//
+// Returns the smallest possible value from this bit generator.
+
+// absl::InsecureBitGen::max()
+//
+// Returns the largest possible value from this bit generator.
+
+// absl::InsecureBitGen::discard(num)
+//
+// Advances the internal state of this bit generator by `num` times, and
+// discards the intermediate results.
+// ---------------------------------------------------------------------------
+
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_RANDOM_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_RANDOM_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.cc b/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.cc
index 31c2d992f1..fdcb54a86c 100644
--- a/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.cc
+++ b/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.cc
@@ -1,46 +1,46 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/random/seed_gen_exception.h"
-
-#include <iostream>
-
-#include "absl/base/config.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/random/seed_gen_exception.h"
+
+#include <iostream>
+
+#include "absl/base/config.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-
-static constexpr const char kExceptionMessage[] =
- "Failed generating seed-material for URBG.";
-
-SeedGenException::~SeedGenException() = default;
-
-const char* SeedGenException::what() const noexcept {
- return kExceptionMessage;
-}
-
-namespace random_internal {
-
-void ThrowSeedGenException() {
-#ifdef ABSL_HAVE_EXCEPTIONS
- throw absl::SeedGenException();
-#else
- std::cerr << kExceptionMessage << std::endl;
- std::terminate();
-#endif
-}
-
-} // namespace random_internal
+
+static constexpr const char kExceptionMessage[] =
+ "Failed generating seed-material for URBG.";
+
+SeedGenException::~SeedGenException() = default;
+
+const char* SeedGenException::what() const noexcept {
+ return kExceptionMessage;
+}
+
+namespace random_internal {
+
+void ThrowSeedGenException() {
+#ifdef ABSL_HAVE_EXCEPTIONS
+ throw absl::SeedGenException();
+#else
+ std::cerr << kExceptionMessage << std::endl;
+ std::terminate();
+#endif
+}
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
+} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.h b/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.h
index 9b1e783de5..5353900564 100644
--- a/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.h
+++ b/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception.h
@@ -1,55 +1,55 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// -----------------------------------------------------------------------------
-// File: seed_gen_exception.h
-// -----------------------------------------------------------------------------
-//
-// This header defines an exception class which may be thrown if unpredictable
-// events prevent the derivation of suitable seed-material for constructing a
-// bit generator conforming to [rand.req.urng] (eg. entropy cannot be read from
-// /dev/urandom on a Unix-based system).
-//
-// Note: if exceptions are disabled, `std::terminate()` is called instead.
-
-#ifndef ABSL_RANDOM_SEED_GEN_EXCEPTION_H_
-#define ABSL_RANDOM_SEED_GEN_EXCEPTION_H_
-
-#include <exception>
-
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// -----------------------------------------------------------------------------
+// File: seed_gen_exception.h
+// -----------------------------------------------------------------------------
+//
+// This header defines an exception class which may be thrown if unpredictable
+// events prevent the derivation of suitable seed-material for constructing a
+// bit generator conforming to [rand.req.urng] (eg. entropy cannot be read from
+// /dev/urandom on a Unix-based system).
+//
+// Note: if exceptions are disabled, `std::terminate()` is called instead.
+
+#ifndef ABSL_RANDOM_SEED_GEN_EXCEPTION_H_
+#define ABSL_RANDOM_SEED_GEN_EXCEPTION_H_
+
+#include <exception>
+
#include "absl/base/config.h"
-namespace absl {
+namespace absl {
ABSL_NAMESPACE_BEGIN
-
-//------------------------------------------------------------------------------
-// SeedGenException
-//------------------------------------------------------------------------------
-class SeedGenException : public std::exception {
- public:
- SeedGenException() = default;
- ~SeedGenException() override;
- const char* what() const noexcept override;
-};
-
-namespace random_internal {
-
-// throw delegator
-[[noreturn]] void ThrowSeedGenException();
-
-} // namespace random_internal
+
+//------------------------------------------------------------------------------
+// SeedGenException
+//------------------------------------------------------------------------------
+class SeedGenException : public std::exception {
+ public:
+ SeedGenException() = default;
+ ~SeedGenException() override;
+ const char* what() const noexcept override;
+};
+
+namespace random_internal {
+
+// throw delegator
+[[noreturn]] void ThrowSeedGenException();
+
+} // namespace random_internal
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_SEED_GEN_EXCEPTION_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_SEED_GEN_EXCEPTION_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception/ya.make b/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception/ya.make
index 988901e40b..6d9b4a7b19 100644
--- a/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/random/seed_gen_exception/ya.make
@@ -1,29 +1,29 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
WITHOUT_LICENSE_TEXTS()
-OWNER(g:cpp-contrib)
-
-LICENSE(Apache-2.0)
-
-ADDINCL(
- GLOBAL contrib/restricted/abseil-cpp
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
+OWNER(g:cpp-contrib)
+
+LICENSE(Apache-2.0)
+
+ADDINCL(
+ GLOBAL contrib/restricted/abseil-cpp
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
CFLAGS(
-DNOMINMAX
)
-SRCDIR(contrib/restricted/abseil-cpp/absl/random)
-
-SRCS(
- seed_gen_exception.cc
-)
-
-END()
+SRCDIR(contrib/restricted/abseil-cpp/absl/random)
+
+SRCS(
+ seed_gen_exception.cc
+)
+
+END()
diff --git a/contrib/restricted/abseil-cpp/absl/random/seed_sequences.cc b/contrib/restricted/abseil-cpp/absl/random/seed_sequences.cc
index b811932796..426eafd3c8 100644
--- a/contrib/restricted/abseil-cpp/absl/random/seed_sequences.cc
+++ b/contrib/restricted/abseil-cpp/absl/random/seed_sequences.cc
@@ -1,29 +1,29 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/random/seed_sequences.h"
-
-#include "absl/random/internal/pool_urbg.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/random/seed_sequences.h"
+
+#include "absl/random/internal/pool_urbg.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-
-SeedSeq MakeSeedSeq() {
- SeedSeq::result_type seed_material[8];
- random_internal::RandenPool<uint32_t>::Fill(absl::MakeSpan(seed_material));
- return SeedSeq(std::begin(seed_material), std::end(seed_material));
-}
-
+
+SeedSeq MakeSeedSeq() {
+ SeedSeq::result_type seed_material[8];
+ random_internal::RandenPool<uint32_t>::Fill(absl::MakeSpan(seed_material));
+ return SeedSeq(std::begin(seed_material), std::end(seed_material));
+}
+
ABSL_NAMESPACE_END
-} // namespace absl
+} // namespace absl
diff --git a/contrib/restricted/abseil-cpp/absl/random/seed_sequences.h b/contrib/restricted/abseil-cpp/absl/random/seed_sequences.h
index 48e98829e2..ff1340cc8e 100644
--- a/contrib/restricted/abseil-cpp/absl/random/seed_sequences.h
+++ b/contrib/restricted/abseil-cpp/absl/random/seed_sequences.h
@@ -1,110 +1,110 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// -----------------------------------------------------------------------------
-// File: seed_sequences.h
-// -----------------------------------------------------------------------------
-//
-// This header contains utilities for creating and working with seed sequences
-// conforming to [rand.req.seedseq]. In general, direct construction of seed
-// sequences is discouraged, but use-cases for construction of identical bit
-// generators (using the same seed sequence) may be helpful (e.g. replaying a
-// simulation whose state is derived from variates of a bit generator).
-
-#ifndef ABSL_RANDOM_SEED_SEQUENCES_H_
-#define ABSL_RANDOM_SEED_SEQUENCES_H_
-
-#include <iterator>
-#include <random>
-
-#include "absl/random/internal/salted_seed_seq.h"
-#include "absl/random/internal/seed_material.h"
-#include "absl/random/seed_gen_exception.h"
-#include "absl/types/span.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// -----------------------------------------------------------------------------
+// File: seed_sequences.h
+// -----------------------------------------------------------------------------
+//
+// This header contains utilities for creating and working with seed sequences
+// conforming to [rand.req.seedseq]. In general, direct construction of seed
+// sequences is discouraged, but use-cases for construction of identical bit
+// generators (using the same seed sequence) may be helpful (e.g. replaying a
+// simulation whose state is derived from variates of a bit generator).
+
+#ifndef ABSL_RANDOM_SEED_SEQUENCES_H_
+#define ABSL_RANDOM_SEED_SEQUENCES_H_
+
+#include <iterator>
+#include <random>
+
+#include "absl/random/internal/salted_seed_seq.h"
+#include "absl/random/internal/seed_material.h"
+#include "absl/random/seed_gen_exception.h"
+#include "absl/types/span.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-
-// -----------------------------------------------------------------------------
-// absl::SeedSeq
-// -----------------------------------------------------------------------------
-//
-// `absl::SeedSeq` constructs a seed sequence according to [rand.req.seedseq]
-// for use within bit generators. `absl::SeedSeq`, unlike `std::seed_seq`
-// additionally salts the generated seeds with extra implementation-defined
-// entropy. For that reason, you can use `absl::SeedSeq` in combination with
-// standard library bit generators (e.g. `std::mt19937`) to introduce
-// non-determinism in your seeds.
-//
-// Example:
-//
-// absl::SeedSeq my_seed_seq({a, b, c});
-// std::mt19937 my_bitgen(my_seed_seq);
-//
-using SeedSeq = random_internal::SaltedSeedSeq<std::seed_seq>;
-
-// -----------------------------------------------------------------------------
-// absl::CreateSeedSeqFrom(bitgen*)
-// -----------------------------------------------------------------------------
-//
-// Constructs a seed sequence conforming to [rand.req.seedseq] using variates
-// produced by a provided bit generator.
-//
-// You should generally avoid direct construction of seed sequences, but
-// use-cases for reuse of a seed sequence to construct identical bit generators
-// may be helpful (eg. replaying a simulation whose state is derived from bit
-// generator values).
-//
-// If bitgen == nullptr, then behavior is undefined.
-//
-// Example:
-//
-// absl::BitGen my_bitgen;
-// auto seed_seq = absl::CreateSeedSeqFrom(&my_bitgen);
-// absl::BitGen new_engine(seed_seq); // derived from my_bitgen, but not
-// // correlated.
-//
-template <typename URBG>
-SeedSeq CreateSeedSeqFrom(URBG* urbg) {
- SeedSeq::result_type
- seed_material[random_internal::kEntropyBlocksNeeded];
-
- if (!random_internal::ReadSeedMaterialFromURBG(
- urbg, absl::MakeSpan(seed_material))) {
- random_internal::ThrowSeedGenException();
- }
- return SeedSeq(std::begin(seed_material), std::end(seed_material));
-}
-
-// -----------------------------------------------------------------------------
-// absl::MakeSeedSeq()
-// -----------------------------------------------------------------------------
-//
-// Constructs an `absl::SeedSeq` salting the generated values using
-// implementation-defined entropy. The returned sequence can be used to create
-// equivalent bit generators correlated using this sequence.
-//
-// Example:
-//
-// auto my_seed_seq = absl::MakeSeedSeq();
-// std::mt19937 rng1(my_seed_seq);
-// std::mt19937 rng2(my_seed_seq);
-// EXPECT_EQ(rng1(), rng2());
-//
-SeedSeq MakeSeedSeq();
-
+
+// -----------------------------------------------------------------------------
+// absl::SeedSeq
+// -----------------------------------------------------------------------------
+//
+// `absl::SeedSeq` constructs a seed sequence according to [rand.req.seedseq]
+// for use within bit generators. `absl::SeedSeq`, unlike `std::seed_seq`
+// additionally salts the generated seeds with extra implementation-defined
+// entropy. For that reason, you can use `absl::SeedSeq` in combination with
+// standard library bit generators (e.g. `std::mt19937`) to introduce
+// non-determinism in your seeds.
+//
+// Example:
+//
+// absl::SeedSeq my_seed_seq({a, b, c});
+// std::mt19937 my_bitgen(my_seed_seq);
+//
+using SeedSeq = random_internal::SaltedSeedSeq<std::seed_seq>;
+
+// -----------------------------------------------------------------------------
+// absl::CreateSeedSeqFrom(bitgen*)
+// -----------------------------------------------------------------------------
+//
+// Constructs a seed sequence conforming to [rand.req.seedseq] using variates
+// produced by a provided bit generator.
+//
+// You should generally avoid direct construction of seed sequences, but
+// use-cases for reuse of a seed sequence to construct identical bit generators
+// may be helpful (eg. replaying a simulation whose state is derived from bit
+// generator values).
+//
+// If bitgen == nullptr, then behavior is undefined.
+//
+// Example:
+//
+// absl::BitGen my_bitgen;
+// auto seed_seq = absl::CreateSeedSeqFrom(&my_bitgen);
+// absl::BitGen new_engine(seed_seq); // derived from my_bitgen, but not
+// // correlated.
+//
+template <typename URBG>
+SeedSeq CreateSeedSeqFrom(URBG* urbg) {
+ SeedSeq::result_type
+ seed_material[random_internal::kEntropyBlocksNeeded];
+
+ if (!random_internal::ReadSeedMaterialFromURBG(
+ urbg, absl::MakeSpan(seed_material))) {
+ random_internal::ThrowSeedGenException();
+ }
+ return SeedSeq(std::begin(seed_material), std::end(seed_material));
+}
+
+// -----------------------------------------------------------------------------
+// absl::MakeSeedSeq()
+// -----------------------------------------------------------------------------
+//
+// Constructs an `absl::SeedSeq` salting the generated values using
+// implementation-defined entropy. The returned sequence can be used to create
+// equivalent bit generators correlated using this sequence.
+//
+// Example:
+//
+// auto my_seed_seq = absl::MakeSeedSeq();
+// std::mt19937 rng1(my_seed_seq);
+// std::mt19937 rng2(my_seed_seq);
+// EXPECT_EQ(rng1(), rng2());
+//
+SeedSeq MakeSeedSeq();
+
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_SEED_SEQUENCES_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_SEED_SEQUENCES_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/seed_sequences/ya.make b/contrib/restricted/abseil-cpp/absl/random/seed_sequences/ya.make
index c97e6d16e8..49cb3ff19c 100644
--- a/contrib/restricted/abseil-cpp/absl/random/seed_sequences/ya.make
+++ b/contrib/restricted/abseil-cpp/absl/random/seed_sequences/ya.make
@@ -1,49 +1,49 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
WITHOUT_LICENSE_TEXTS()
-OWNER(g:cpp-contrib)
-
-LICENSE(Apache-2.0)
-
-PEERDIR(
- contrib/restricted/abseil-cpp/absl/base
- contrib/restricted/abseil-cpp/absl/base/internal/raw_logging
- contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait
- contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate
- contrib/restricted/abseil-cpp/absl/base/log_severity
- contrib/restricted/abseil-cpp/absl/numeric
- contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg
- contrib/restricted/abseil-cpp/absl/random/internal/randen
- contrib/restricted/abseil-cpp/absl/random/internal/randen_detect
- contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes
+OWNER(g:cpp-contrib)
+
+LICENSE(Apache-2.0)
+
+PEERDIR(
+ contrib/restricted/abseil-cpp/absl/base
+ contrib/restricted/abseil-cpp/absl/base/internal/raw_logging
+ contrib/restricted/abseil-cpp/absl/base/internal/spinlock_wait
+ contrib/restricted/abseil-cpp/absl/base/internal/throw_delegate
+ contrib/restricted/abseil-cpp/absl/base/log_severity
+ contrib/restricted/abseil-cpp/absl/numeric
+ contrib/restricted/abseil-cpp/absl/random/internal/pool_urbg
+ contrib/restricted/abseil-cpp/absl/random/internal/randen
+ contrib/restricted/abseil-cpp/absl/random/internal/randen_detect
+ contrib/restricted/abseil-cpp/absl/random/internal/randen_hwaes
contrib/restricted/abseil-cpp/absl/random/internal/randen_round_keys
- contrib/restricted/abseil-cpp/absl/random/internal/randen_slow
- contrib/restricted/abseil-cpp/absl/random/internal/seed_material
- contrib/restricted/abseil-cpp/absl/random/seed_gen_exception
- contrib/restricted/abseil-cpp/absl/strings
+ contrib/restricted/abseil-cpp/absl/random/internal/randen_slow
+ contrib/restricted/abseil-cpp/absl/random/internal/seed_material
+ contrib/restricted/abseil-cpp/absl/random/seed_gen_exception
+ contrib/restricted/abseil-cpp/absl/strings
contrib/restricted/abseil-cpp/absl/strings/internal/absl_strings_internal
- contrib/restricted/abseil-cpp/absl/types/bad_optional_access
-)
-
-ADDINCL(
- GLOBAL contrib/restricted/abseil-cpp
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
+ contrib/restricted/abseil-cpp/absl/types/bad_optional_access
+)
+
+ADDINCL(
+ GLOBAL contrib/restricted/abseil-cpp
+)
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
CFLAGS(
-DNOMINMAX
)
-SRCDIR(contrib/restricted/abseil-cpp/absl/random)
-
-SRCS(
- seed_sequences.cc
-)
-
-END()
+SRCDIR(contrib/restricted/abseil-cpp/absl/random)
+
+SRCS(
+ seed_sequences.cc
+)
+
+END()
diff --git a/contrib/restricted/abseil-cpp/absl/random/uniform_int_distribution.h b/contrib/restricted/abseil-cpp/absl/random/uniform_int_distribution.h
index df417a1ecf..c1f54ccebc 100644
--- a/contrib/restricted/abseil-cpp/absl/random/uniform_int_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/uniform_int_distribution.h
@@ -1,275 +1,275 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// -----------------------------------------------------------------------------
-// File: uniform_int_distribution.h
-// -----------------------------------------------------------------------------
-//
-// This header defines a class for representing a uniform integer distribution
-// over the closed (inclusive) interval [a,b]. You use this distribution in
-// combination with an Abseil random bit generator to produce random values
-// according to the rules of the distribution.
-//
-// `absl::uniform_int_distribution` is a drop-in replacement for the C++11
-// `std::uniform_int_distribution` [rand.dist.uni.int] but is considerably
-// faster than the libstdc++ implementation.
-
-#ifndef ABSL_RANDOM_UNIFORM_INT_DISTRIBUTION_H_
-#define ABSL_RANDOM_UNIFORM_INT_DISTRIBUTION_H_
-
-#include <cassert>
-#include <istream>
-#include <limits>
-#include <type_traits>
-
-#include "absl/base/optimization.h"
-#include "absl/random/internal/fast_uniform_bits.h"
-#include "absl/random/internal/iostream_state_saver.h"
-#include "absl/random/internal/traits.h"
-#include "absl/random/internal/wide_multiply.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// -----------------------------------------------------------------------------
+// File: uniform_int_distribution.h
+// -----------------------------------------------------------------------------
+//
+// This header defines a class for representing a uniform integer distribution
+// over the closed (inclusive) interval [a,b]. You use this distribution in
+// combination with an Abseil random bit generator to produce random values
+// according to the rules of the distribution.
+//
+// `absl::uniform_int_distribution` is a drop-in replacement for the C++11
+// `std::uniform_int_distribution` [rand.dist.uni.int] but is considerably
+// faster than the libstdc++ implementation.
+
+#ifndef ABSL_RANDOM_UNIFORM_INT_DISTRIBUTION_H_
+#define ABSL_RANDOM_UNIFORM_INT_DISTRIBUTION_H_
+
+#include <cassert>
+#include <istream>
+#include <limits>
+#include <type_traits>
+
+#include "absl/base/optimization.h"
+#include "absl/random/internal/fast_uniform_bits.h"
+#include "absl/random/internal/iostream_state_saver.h"
+#include "absl/random/internal/traits.h"
+#include "absl/random/internal/wide_multiply.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-
-// absl::uniform_int_distribution<T>
-//
-// This distribution produces random integer values uniformly distributed in the
-// closed (inclusive) interval [a, b].
-//
-// Example:
-//
-// absl::BitGen gen;
-//
-// // Use the distribution to produce a value between 1 and 6, inclusive.
-// int die_roll = absl::uniform_int_distribution<int>(1, 6)(gen);
-//
-template <typename IntType = int>
-class uniform_int_distribution {
- private:
- using unsigned_type =
- typename random_internal::make_unsigned_bits<IntType>::type;
-
- public:
- using result_type = IntType;
-
- class param_type {
- public:
- using distribution_type = uniform_int_distribution;
-
- explicit param_type(
- result_type lo = 0,
- result_type hi = (std::numeric_limits<result_type>::max)())
- : lo_(lo),
- range_(static_cast<unsigned_type>(hi) -
- static_cast<unsigned_type>(lo)) {
- // [rand.dist.uni.int] precondition 2
- assert(lo <= hi);
- }
-
- result_type a() const { return lo_; }
- result_type b() const {
- return static_cast<result_type>(static_cast<unsigned_type>(lo_) + range_);
- }
-
- friend bool operator==(const param_type& a, const param_type& b) {
- return a.lo_ == b.lo_ && a.range_ == b.range_;
- }
-
- friend bool operator!=(const param_type& a, const param_type& b) {
- return !(a == b);
- }
-
- private:
- friend class uniform_int_distribution;
- unsigned_type range() const { return range_; }
-
- result_type lo_;
- unsigned_type range_;
-
- static_assert(std::is_integral<result_type>::value,
- "Class-template absl::uniform_int_distribution<> must be "
- "parameterized using an integral type.");
- }; // param_type
-
- uniform_int_distribution() : uniform_int_distribution(0) {}
-
- explicit uniform_int_distribution(
- result_type lo,
- result_type hi = (std::numeric_limits<result_type>::max)())
- : param_(lo, hi) {}
-
- explicit uniform_int_distribution(const param_type& param) : param_(param) {}
-
- // uniform_int_distribution<T>::reset()
- //
- // Resets the uniform int distribution. Note that this function has no effect
- // because the distribution already produces independent values.
- void reset() {}
-
- template <typename URBG>
- result_type operator()(URBG& gen) { // NOLINT(runtime/references)
- return (*this)(gen, param());
- }
-
- template <typename URBG>
- result_type operator()(
- URBG& gen, const param_type& param) { // NOLINT(runtime/references)
- return param.a() + Generate(gen, param.range());
- }
-
- result_type a() const { return param_.a(); }
- result_type b() const { return param_.b(); }
-
- param_type param() const { return param_; }
- void param(const param_type& params) { param_ = params; }
-
- result_type(min)() const { return a(); }
- result_type(max)() const { return b(); }
-
- friend bool operator==(const uniform_int_distribution& a,
- const uniform_int_distribution& b) {
- return a.param_ == b.param_;
- }
- friend bool operator!=(const uniform_int_distribution& a,
- const uniform_int_distribution& b) {
- return !(a == b);
- }
-
- private:
- // Generates a value in the *closed* interval [0, R]
- template <typename URBG>
- unsigned_type Generate(URBG& g, // NOLINT(runtime/references)
- unsigned_type R);
- param_type param_;
-};
-
-// -----------------------------------------------------------------------------
-// Implementation details follow
-// -----------------------------------------------------------------------------
-template <typename CharT, typename Traits, typename IntType>
-std::basic_ostream<CharT, Traits>& operator<<(
- std::basic_ostream<CharT, Traits>& os,
- const uniform_int_distribution<IntType>& x) {
- using stream_type =
- typename random_internal::stream_format_type<IntType>::type;
- auto saver = random_internal::make_ostream_state_saver(os);
- os << static_cast<stream_type>(x.a()) << os.fill()
- << static_cast<stream_type>(x.b());
- return os;
-}
-
-template <typename CharT, typename Traits, typename IntType>
-std::basic_istream<CharT, Traits>& operator>>(
- std::basic_istream<CharT, Traits>& is,
- uniform_int_distribution<IntType>& x) {
- using param_type = typename uniform_int_distribution<IntType>::param_type;
- using result_type = typename uniform_int_distribution<IntType>::result_type;
- using stream_type =
- typename random_internal::stream_format_type<IntType>::type;
-
- stream_type a;
- stream_type b;
-
- auto saver = random_internal::make_istream_state_saver(is);
- is >> a >> b;
- if (!is.fail()) {
- x.param(
- param_type(static_cast<result_type>(a), static_cast<result_type>(b)));
- }
- return is;
-}
-
-template <typename IntType>
-template <typename URBG>
-typename random_internal::make_unsigned_bits<IntType>::type
-uniform_int_distribution<IntType>::Generate(
- URBG& g, // NOLINT(runtime/references)
- typename random_internal::make_unsigned_bits<IntType>::type R) {
+
+// absl::uniform_int_distribution<T>
+//
+// This distribution produces random integer values uniformly distributed in the
+// closed (inclusive) interval [a, b].
+//
+// Example:
+//
+// absl::BitGen gen;
+//
+// // Use the distribution to produce a value between 1 and 6, inclusive.
+// int die_roll = absl::uniform_int_distribution<int>(1, 6)(gen);
+//
+template <typename IntType = int>
+class uniform_int_distribution {
+ private:
+ using unsigned_type =
+ typename random_internal::make_unsigned_bits<IntType>::type;
+
+ public:
+ using result_type = IntType;
+
+ class param_type {
+ public:
+ using distribution_type = uniform_int_distribution;
+
+ explicit param_type(
+ result_type lo = 0,
+ result_type hi = (std::numeric_limits<result_type>::max)())
+ : lo_(lo),
+ range_(static_cast<unsigned_type>(hi) -
+ static_cast<unsigned_type>(lo)) {
+ // [rand.dist.uni.int] precondition 2
+ assert(lo <= hi);
+ }
+
+ result_type a() const { return lo_; }
+ result_type b() const {
+ return static_cast<result_type>(static_cast<unsigned_type>(lo_) + range_);
+ }
+
+ friend bool operator==(const param_type& a, const param_type& b) {
+ return a.lo_ == b.lo_ && a.range_ == b.range_;
+ }
+
+ friend bool operator!=(const param_type& a, const param_type& b) {
+ return !(a == b);
+ }
+
+ private:
+ friend class uniform_int_distribution;
+ unsigned_type range() const { return range_; }
+
+ result_type lo_;
+ unsigned_type range_;
+
+ static_assert(std::is_integral<result_type>::value,
+ "Class-template absl::uniform_int_distribution<> must be "
+ "parameterized using an integral type.");
+ }; // param_type
+
+ uniform_int_distribution() : uniform_int_distribution(0) {}
+
+ explicit uniform_int_distribution(
+ result_type lo,
+ result_type hi = (std::numeric_limits<result_type>::max)())
+ : param_(lo, hi) {}
+
+ explicit uniform_int_distribution(const param_type& param) : param_(param) {}
+
+ // uniform_int_distribution<T>::reset()
+ //
+ // Resets the uniform int distribution. Note that this function has no effect
+ // because the distribution already produces independent values.
+ void reset() {}
+
+ template <typename URBG>
+ result_type operator()(URBG& gen) { // NOLINT(runtime/references)
+ return (*this)(gen, param());
+ }
+
+ template <typename URBG>
+ result_type operator()(
+ URBG& gen, const param_type& param) { // NOLINT(runtime/references)
+ return param.a() + Generate(gen, param.range());
+ }
+
+ result_type a() const { return param_.a(); }
+ result_type b() const { return param_.b(); }
+
+ param_type param() const { return param_; }
+ void param(const param_type& params) { param_ = params; }
+
+ result_type(min)() const { return a(); }
+ result_type(max)() const { return b(); }
+
+ friend bool operator==(const uniform_int_distribution& a,
+ const uniform_int_distribution& b) {
+ return a.param_ == b.param_;
+ }
+ friend bool operator!=(const uniform_int_distribution& a,
+ const uniform_int_distribution& b) {
+ return !(a == b);
+ }
+
+ private:
+ // Generates a value in the *closed* interval [0, R]
+ template <typename URBG>
+ unsigned_type Generate(URBG& g, // NOLINT(runtime/references)
+ unsigned_type R);
+ param_type param_;
+};
+
+// -----------------------------------------------------------------------------
+// Implementation details follow
+// -----------------------------------------------------------------------------
+template <typename CharT, typename Traits, typename IntType>
+std::basic_ostream<CharT, Traits>& operator<<(
+ std::basic_ostream<CharT, Traits>& os,
+ const uniform_int_distribution<IntType>& x) {
+ using stream_type =
+ typename random_internal::stream_format_type<IntType>::type;
+ auto saver = random_internal::make_ostream_state_saver(os);
+ os << static_cast<stream_type>(x.a()) << os.fill()
+ << static_cast<stream_type>(x.b());
+ return os;
+}
+
+template <typename CharT, typename Traits, typename IntType>
+std::basic_istream<CharT, Traits>& operator>>(
+ std::basic_istream<CharT, Traits>& is,
+ uniform_int_distribution<IntType>& x) {
+ using param_type = typename uniform_int_distribution<IntType>::param_type;
+ using result_type = typename uniform_int_distribution<IntType>::result_type;
+ using stream_type =
+ typename random_internal::stream_format_type<IntType>::type;
+
+ stream_type a;
+ stream_type b;
+
+ auto saver = random_internal::make_istream_state_saver(is);
+ is >> a >> b;
+ if (!is.fail()) {
+ x.param(
+ param_type(static_cast<result_type>(a), static_cast<result_type>(b)));
+ }
+ return is;
+}
+
+template <typename IntType>
+template <typename URBG>
+typename random_internal::make_unsigned_bits<IntType>::type
+uniform_int_distribution<IntType>::Generate(
+ URBG& g, // NOLINT(runtime/references)
+ typename random_internal::make_unsigned_bits<IntType>::type R) {
random_internal::FastUniformBits<unsigned_type> fast_bits;
- unsigned_type bits = fast_bits(g);
- const unsigned_type Lim = R + 1;
- if ((R & Lim) == 0) {
- // If the interval's length is a power of two range, just take the low bits.
- return bits & R;
- }
-
- // Generates a uniform variate on [0, Lim) using fixed-point multiplication.
- // The above fast-path guarantees that Lim is representable in unsigned_type.
- //
- // Algorithm adapted from
- // http://lemire.me/blog/2016/06/30/fast-random-shuffling/, with added
- // explanation.
- //
- // The algorithm creates a uniform variate `bits` in the interval [0, 2^N),
- // and treats it as the fractional part of a fixed-point real value in [0, 1),
- // multiplied by 2^N. For example, 0.25 would be represented as 2^(N - 2),
- // because 2^N * 0.25 == 2^(N - 2).
- //
- // Next, `bits` and `Lim` are multiplied with a wide-multiply to bring the
- // value into the range [0, Lim). The integral part (the high word of the
- // multiplication result) is then very nearly the desired result. However,
- // this is not quite accurate; viewing the multiplication result as one
- // double-width integer, the resulting values for the sample are mapped as
- // follows:
- //
- // If the result lies in this interval: Return this value:
- // [0, 2^N) 0
- // [2^N, 2 * 2^N) 1
- // ... ...
- // [K * 2^N, (K + 1) * 2^N) K
- // ... ...
- // [(Lim - 1) * 2^N, Lim * 2^N) Lim - 1
- //
- // While all of these intervals have the same size, the result of `bits * Lim`
- // must be a multiple of `Lim`, and not all of these intervals contain the
- // same number of multiples of `Lim`. In particular, some contain
- // `F = floor(2^N / Lim)` and some contain `F + 1 = ceil(2^N / Lim)`. This
- // difference produces a small nonuniformity, which is corrected by applying
- // rejection sampling to one of the values in the "larger intervals" (i.e.,
- // the intervals containing `F + 1` multiples of `Lim`.
- //
- // An interval contains `F + 1` multiples of `Lim` if and only if its smallest
- // value modulo 2^N is less than `2^N % Lim`. The unique value satisfying
- // this property is used as the one for rejection. That is, a value of
- // `bits * Lim` is rejected if `(bit * Lim) % 2^N < (2^N % Lim)`.
-
- using helper = random_internal::wide_multiply<unsigned_type>;
- auto product = helper::multiply(bits, Lim);
-
- // Two optimizations here:
- // * Rejection occurs with some probability less than 1/2, and for reasonable
- // ranges considerably less (in particular, less than 1/(F+1)), so
- // ABSL_PREDICT_FALSE is apt.
- // * `Lim` is an overestimate of `threshold`, and doesn't require a divide.
- if (ABSL_PREDICT_FALSE(helper::lo(product) < Lim)) {
- // This quantity is exactly equal to `2^N % Lim`, but does not require high
- // precision calculations: `2^N % Lim` is congruent to `(2^N - Lim) % Lim`.
- // Ideally this could be expressed simply as `-X` rather than `2^N - X`, but
- // for types smaller than int, this calculation is incorrect due to integer
- // promotion rules.
- const unsigned_type threshold =
- ((std::numeric_limits<unsigned_type>::max)() - Lim + 1) % Lim;
- while (helper::lo(product) < threshold) {
- bits = fast_bits(g);
- product = helper::multiply(bits, Lim);
- }
- }
-
- return helper::hi(product);
-}
-
+ unsigned_type bits = fast_bits(g);
+ const unsigned_type Lim = R + 1;
+ if ((R & Lim) == 0) {
+ // If the interval's length is a power of two range, just take the low bits.
+ return bits & R;
+ }
+
+ // Generates a uniform variate on [0, Lim) using fixed-point multiplication.
+ // The above fast-path guarantees that Lim is representable in unsigned_type.
+ //
+ // Algorithm adapted from
+ // http://lemire.me/blog/2016/06/30/fast-random-shuffling/, with added
+ // explanation.
+ //
+ // The algorithm creates a uniform variate `bits` in the interval [0, 2^N),
+ // and treats it as the fractional part of a fixed-point real value in [0, 1),
+ // multiplied by 2^N. For example, 0.25 would be represented as 2^(N - 2),
+ // because 2^N * 0.25 == 2^(N - 2).
+ //
+ // Next, `bits` and `Lim` are multiplied with a wide-multiply to bring the
+ // value into the range [0, Lim). The integral part (the high word of the
+ // multiplication result) is then very nearly the desired result. However,
+ // this is not quite accurate; viewing the multiplication result as one
+ // double-width integer, the resulting values for the sample are mapped as
+ // follows:
+ //
+ // If the result lies in this interval: Return this value:
+ // [0, 2^N) 0
+ // [2^N, 2 * 2^N) 1
+ // ... ...
+ // [K * 2^N, (K + 1) * 2^N) K
+ // ... ...
+ // [(Lim - 1) * 2^N, Lim * 2^N) Lim - 1
+ //
+ // While all of these intervals have the same size, the result of `bits * Lim`
+ // must be a multiple of `Lim`, and not all of these intervals contain the
+ // same number of multiples of `Lim`. In particular, some contain
+ // `F = floor(2^N / Lim)` and some contain `F + 1 = ceil(2^N / Lim)`. This
+ // difference produces a small nonuniformity, which is corrected by applying
+ // rejection sampling to one of the values in the "larger intervals" (i.e.,
+ // the intervals containing `F + 1` multiples of `Lim`.
+ //
+ // An interval contains `F + 1` multiples of `Lim` if and only if its smallest
+ // value modulo 2^N is less than `2^N % Lim`. The unique value satisfying
+ // this property is used as the one for rejection. That is, a value of
+ // `bits * Lim` is rejected if `(bit * Lim) % 2^N < (2^N % Lim)`.
+
+ using helper = random_internal::wide_multiply<unsigned_type>;
+ auto product = helper::multiply(bits, Lim);
+
+ // Two optimizations here:
+ // * Rejection occurs with some probability less than 1/2, and for reasonable
+ // ranges considerably less (in particular, less than 1/(F+1)), so
+ // ABSL_PREDICT_FALSE is apt.
+ // * `Lim` is an overestimate of `threshold`, and doesn't require a divide.
+ if (ABSL_PREDICT_FALSE(helper::lo(product) < Lim)) {
+ // This quantity is exactly equal to `2^N % Lim`, but does not require high
+ // precision calculations: `2^N % Lim` is congruent to `(2^N - Lim) % Lim`.
+ // Ideally this could be expressed simply as `-X` rather than `2^N - X`, but
+ // for types smaller than int, this calculation is incorrect due to integer
+ // promotion rules.
+ const unsigned_type threshold =
+ ((std::numeric_limits<unsigned_type>::max)() - Lim + 1) % Lim;
+ while (helper::lo(product) < threshold) {
+ bits = fast_bits(g);
+ product = helper::multiply(bits, Lim);
+ }
+ }
+
+ return helper::hi(product);
+}
+
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_UNIFORM_INT_DISTRIBUTION_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_UNIFORM_INT_DISTRIBUTION_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/uniform_real_distribution.h b/contrib/restricted/abseil-cpp/absl/random/uniform_real_distribution.h
index 4ebe0747c9..5ba17b2341 100644
--- a/contrib/restricted/abseil-cpp/absl/random/uniform_real_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/uniform_real_distribution.h
@@ -1,202 +1,202 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// -----------------------------------------------------------------------------
-// File: uniform_real_distribution.h
-// -----------------------------------------------------------------------------
-//
-// This header defines a class for representing a uniform floating-point
-// distribution over a half-open interval [a,b). You use this distribution in
-// combination with an Abseil random bit generator to produce random values
-// according to the rules of the distribution.
-//
-// `absl::uniform_real_distribution` is a drop-in replacement for the C++11
-// `std::uniform_real_distribution` [rand.dist.uni.real] but is considerably
-// faster than the libstdc++ implementation.
-//
-// Note: the standard-library version may occasionally return `1.0` when
-// default-initialized. See https://bugs.llvm.org//show_bug.cgi?id=18767
-// `absl::uniform_real_distribution` does not exhibit this behavior.
-
-#ifndef ABSL_RANDOM_UNIFORM_REAL_DISTRIBUTION_H_
-#define ABSL_RANDOM_UNIFORM_REAL_DISTRIBUTION_H_
-
-#include <cassert>
-#include <cmath>
-#include <cstdint>
-#include <istream>
-#include <limits>
-#include <type_traits>
-
-#include "absl/meta/type_traits.h"
-#include "absl/random/internal/fast_uniform_bits.h"
-#include "absl/random/internal/generate_real.h"
-#include "absl/random/internal/iostream_state_saver.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// -----------------------------------------------------------------------------
+// File: uniform_real_distribution.h
+// -----------------------------------------------------------------------------
+//
+// This header defines a class for representing a uniform floating-point
+// distribution over a half-open interval [a,b). You use this distribution in
+// combination with an Abseil random bit generator to produce random values
+// according to the rules of the distribution.
+//
+// `absl::uniform_real_distribution` is a drop-in replacement for the C++11
+// `std::uniform_real_distribution` [rand.dist.uni.real] but is considerably
+// faster than the libstdc++ implementation.
+//
+// Note: the standard-library version may occasionally return `1.0` when
+// default-initialized. See https://bugs.llvm.org//show_bug.cgi?id=18767
+// `absl::uniform_real_distribution` does not exhibit this behavior.
+
+#ifndef ABSL_RANDOM_UNIFORM_REAL_DISTRIBUTION_H_
+#define ABSL_RANDOM_UNIFORM_REAL_DISTRIBUTION_H_
+
+#include <cassert>
+#include <cmath>
+#include <cstdint>
+#include <istream>
+#include <limits>
+#include <type_traits>
+
+#include "absl/meta/type_traits.h"
+#include "absl/random/internal/fast_uniform_bits.h"
+#include "absl/random/internal/generate_real.h"
+#include "absl/random/internal/iostream_state_saver.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-
-// absl::uniform_real_distribution<T>
-//
-// This distribution produces random floating-point values uniformly distributed
-// over the half-open interval [a, b).
-//
-// Example:
-//
-// absl::BitGen gen;
-//
-// // Use the distribution to produce a value between 0.0 (inclusive)
-// // and 1.0 (exclusive).
-// double value = absl::uniform_real_distribution<double>(0, 1)(gen);
-//
-template <typename RealType = double>
-class uniform_real_distribution {
- public:
- using result_type = RealType;
-
- class param_type {
- public:
- using distribution_type = uniform_real_distribution;
-
- explicit param_type(result_type lo = 0, result_type hi = 1)
- : lo_(lo), hi_(hi), range_(hi - lo) {
- // [rand.dist.uni.real] preconditions 2 & 3
- assert(lo <= hi);
- // NOTE: For integral types, we can promote the range to an unsigned type,
- // which gives full width of the range. However for real (fp) types, this
- // is not possible, so value generation cannot use the full range of the
- // real type.
- assert(range_ <= (std::numeric_limits<result_type>::max)());
- assert(std::isfinite(range_));
- }
-
- result_type a() const { return lo_; }
- result_type b() const { return hi_; }
-
- friend bool operator==(const param_type& a, const param_type& b) {
- return a.lo_ == b.lo_ && a.hi_ == b.hi_;
- }
-
- friend bool operator!=(const param_type& a, const param_type& b) {
- return !(a == b);
- }
-
- private:
- friend class uniform_real_distribution;
- result_type lo_, hi_, range_;
-
- static_assert(std::is_floating_point<RealType>::value,
- "Class-template absl::uniform_real_distribution<> must be "
- "parameterized using a floating-point type.");
- };
-
- uniform_real_distribution() : uniform_real_distribution(0) {}
-
- explicit uniform_real_distribution(result_type lo, result_type hi = 1)
- : param_(lo, hi) {}
-
- explicit uniform_real_distribution(const param_type& param) : param_(param) {}
-
- // uniform_real_distribution<T>::reset()
- //
- // Resets the uniform real distribution. Note that this function has no effect
- // because the distribution already produces independent values.
- void reset() {}
-
- template <typename URBG>
- result_type operator()(URBG& gen) { // NOLINT(runtime/references)
- return operator()(gen, param_);
- }
-
- template <typename URBG>
- result_type operator()(URBG& gen, // NOLINT(runtime/references)
- const param_type& p);
-
- result_type a() const { return param_.a(); }
- result_type b() const { return param_.b(); }
-
- param_type param() const { return param_; }
- void param(const param_type& params) { param_ = params; }
-
- result_type(min)() const { return a(); }
- result_type(max)() const { return b(); }
-
- friend bool operator==(const uniform_real_distribution& a,
- const uniform_real_distribution& b) {
- return a.param_ == b.param_;
- }
- friend bool operator!=(const uniform_real_distribution& a,
- const uniform_real_distribution& b) {
- return a.param_ != b.param_;
- }
-
- private:
- param_type param_;
- random_internal::FastUniformBits<uint64_t> fast_u64_;
-};
-
-// -----------------------------------------------------------------------------
-// Implementation details follow
-// -----------------------------------------------------------------------------
-template <typename RealType>
-template <typename URBG>
-typename uniform_real_distribution<RealType>::result_type
-uniform_real_distribution<RealType>::operator()(
- URBG& gen, const param_type& p) { // NOLINT(runtime/references)
- using random_internal::GeneratePositiveTag;
- using random_internal::GenerateRealFromBits;
- using real_type =
- absl::conditional_t<std::is_same<RealType, float>::value, float, double>;
-
- while (true) {
- const result_type sample =
- GenerateRealFromBits<real_type, GeneratePositiveTag, true>(
- fast_u64_(gen));
- const result_type res = p.a() + (sample * p.range_);
- if (res < p.b() || p.range_ <= 0 || !std::isfinite(p.range_)) {
- return res;
- }
- // else sample rejected, try again.
- }
-}
-
-template <typename CharT, typename Traits, typename RealType>
-std::basic_ostream<CharT, Traits>& operator<<(
- std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
- const uniform_real_distribution<RealType>& x) {
- auto saver = random_internal::make_ostream_state_saver(os);
- os.precision(random_internal::stream_precision_helper<RealType>::kPrecision);
- os << x.a() << os.fill() << x.b();
- return os;
-}
-
-template <typename CharT, typename Traits, typename RealType>
-std::basic_istream<CharT, Traits>& operator>>(
- std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
- uniform_real_distribution<RealType>& x) { // NOLINT(runtime/references)
- using param_type = typename uniform_real_distribution<RealType>::param_type;
- using result_type = typename uniform_real_distribution<RealType>::result_type;
- auto saver = random_internal::make_istream_state_saver(is);
- auto a = random_internal::read_floating_point<result_type>(is);
- if (is.fail()) return is;
- auto b = random_internal::read_floating_point<result_type>(is);
- if (!is.fail()) {
- x.param(param_type(a, b));
- }
- return is;
-}
+
+// absl::uniform_real_distribution<T>
+//
+// This distribution produces random floating-point values uniformly distributed
+// over the half-open interval [a, b).
+//
+// Example:
+//
+// absl::BitGen gen;
+//
+// // Use the distribution to produce a value between 0.0 (inclusive)
+// // and 1.0 (exclusive).
+// double value = absl::uniform_real_distribution<double>(0, 1)(gen);
+//
+template <typename RealType = double>
+class uniform_real_distribution {
+ public:
+ using result_type = RealType;
+
+ class param_type {
+ public:
+ using distribution_type = uniform_real_distribution;
+
+ explicit param_type(result_type lo = 0, result_type hi = 1)
+ : lo_(lo), hi_(hi), range_(hi - lo) {
+ // [rand.dist.uni.real] preconditions 2 & 3
+ assert(lo <= hi);
+ // NOTE: For integral types, we can promote the range to an unsigned type,
+ // which gives full width of the range. However for real (fp) types, this
+ // is not possible, so value generation cannot use the full range of the
+ // real type.
+ assert(range_ <= (std::numeric_limits<result_type>::max)());
+ assert(std::isfinite(range_));
+ }
+
+ result_type a() const { return lo_; }
+ result_type b() const { return hi_; }
+
+ friend bool operator==(const param_type& a, const param_type& b) {
+ return a.lo_ == b.lo_ && a.hi_ == b.hi_;
+ }
+
+ friend bool operator!=(const param_type& a, const param_type& b) {
+ return !(a == b);
+ }
+
+ private:
+ friend class uniform_real_distribution;
+ result_type lo_, hi_, range_;
+
+ static_assert(std::is_floating_point<RealType>::value,
+ "Class-template absl::uniform_real_distribution<> must be "
+ "parameterized using a floating-point type.");
+ };
+
+ uniform_real_distribution() : uniform_real_distribution(0) {}
+
+ explicit uniform_real_distribution(result_type lo, result_type hi = 1)
+ : param_(lo, hi) {}
+
+ explicit uniform_real_distribution(const param_type& param) : param_(param) {}
+
+ // uniform_real_distribution<T>::reset()
+ //
+ // Resets the uniform real distribution. Note that this function has no effect
+ // because the distribution already produces independent values.
+ void reset() {}
+
+ template <typename URBG>
+ result_type operator()(URBG& gen) { // NOLINT(runtime/references)
+ return operator()(gen, param_);
+ }
+
+ template <typename URBG>
+ result_type operator()(URBG& gen, // NOLINT(runtime/references)
+ const param_type& p);
+
+ result_type a() const { return param_.a(); }
+ result_type b() const { return param_.b(); }
+
+ param_type param() const { return param_; }
+ void param(const param_type& params) { param_ = params; }
+
+ result_type(min)() const { return a(); }
+ result_type(max)() const { return b(); }
+
+ friend bool operator==(const uniform_real_distribution& a,
+ const uniform_real_distribution& b) {
+ return a.param_ == b.param_;
+ }
+ friend bool operator!=(const uniform_real_distribution& a,
+ const uniform_real_distribution& b) {
+ return a.param_ != b.param_;
+ }
+
+ private:
+ param_type param_;
+ random_internal::FastUniformBits<uint64_t> fast_u64_;
+};
+
+// -----------------------------------------------------------------------------
+// Implementation details follow
+// -----------------------------------------------------------------------------
+template <typename RealType>
+template <typename URBG>
+typename uniform_real_distribution<RealType>::result_type
+uniform_real_distribution<RealType>::operator()(
+ URBG& gen, const param_type& p) { // NOLINT(runtime/references)
+ using random_internal::GeneratePositiveTag;
+ using random_internal::GenerateRealFromBits;
+ using real_type =
+ absl::conditional_t<std::is_same<RealType, float>::value, float, double>;
+
+ while (true) {
+ const result_type sample =
+ GenerateRealFromBits<real_type, GeneratePositiveTag, true>(
+ fast_u64_(gen));
+ const result_type res = p.a() + (sample * p.range_);
+ if (res < p.b() || p.range_ <= 0 || !std::isfinite(p.range_)) {
+ return res;
+ }
+ // else sample rejected, try again.
+ }
+}
+
+template <typename CharT, typename Traits, typename RealType>
+std::basic_ostream<CharT, Traits>& operator<<(
+ std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
+ const uniform_real_distribution<RealType>& x) {
+ auto saver = random_internal::make_ostream_state_saver(os);
+ os.precision(random_internal::stream_precision_helper<RealType>::kPrecision);
+ os << x.a() << os.fill() << x.b();
+ return os;
+}
+
+template <typename CharT, typename Traits, typename RealType>
+std::basic_istream<CharT, Traits>& operator>>(
+ std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
+ uniform_real_distribution<RealType>& x) { // NOLINT(runtime/references)
+ using param_type = typename uniform_real_distribution<RealType>::param_type;
+ using result_type = typename uniform_real_distribution<RealType>::result_type;
+ auto saver = random_internal::make_istream_state_saver(is);
+ auto a = random_internal::read_floating_point<result_type>(is);
+ if (is.fail()) return is;
+ auto b = random_internal::read_floating_point<result_type>(is);
+ if (!is.fail()) {
+ x.param(param_type(a, b));
+ }
+ return is;
+}
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_UNIFORM_REAL_DISTRIBUTION_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_UNIFORM_REAL_DISTRIBUTION_H_
diff --git a/contrib/restricted/abseil-cpp/absl/random/zipf_distribution.h b/contrib/restricted/abseil-cpp/absl/random/zipf_distribution.h
index 31212412df..22ebc756cf 100644
--- a/contrib/restricted/abseil-cpp/absl/random/zipf_distribution.h
+++ b/contrib/restricted/abseil-cpp/absl/random/zipf_distribution.h
@@ -1,271 +1,271 @@
-// Copyright 2017 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef ABSL_RANDOM_ZIPF_DISTRIBUTION_H_
-#define ABSL_RANDOM_ZIPF_DISTRIBUTION_H_
-
-#include <cassert>
-#include <cmath>
-#include <istream>
-#include <limits>
-#include <ostream>
-#include <type_traits>
-
-#include "absl/random/internal/iostream_state_saver.h"
-#include "absl/random/uniform_real_distribution.h"
-
-namespace absl {
+// Copyright 2017 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_RANDOM_ZIPF_DISTRIBUTION_H_
+#define ABSL_RANDOM_ZIPF_DISTRIBUTION_H_
+
+#include <cassert>
+#include <cmath>
+#include <istream>
+#include <limits>
+#include <ostream>
+#include <type_traits>
+
+#include "absl/random/internal/iostream_state_saver.h"
+#include "absl/random/uniform_real_distribution.h"
+
+namespace absl {
ABSL_NAMESPACE_BEGIN
-
-// absl::zipf_distribution produces random integer-values in the range [0, k],
-// distributed according to the discrete probability function:
-//
-// P(x) = (v + x) ^ -q
-//
-// The parameter `v` must be greater than 0 and the parameter `q` must be
-// greater than 1. If either of these parameters take invalid values then the
-// behavior is undefined.
-//
-// IntType is the result_type generated by the generator. It must be of integral
-// type; a static_assert ensures this is the case.
-//
-// The implementation is based on W.Hormann, G.Derflinger:
-//
-// "Rejection-Inversion to Generate Variates from Monotone Discrete
-// Distributions"
-//
-// http://eeyore.wu-wien.ac.at/papers/96-04-04.wh-der.ps.gz
-//
-template <typename IntType = int>
-class zipf_distribution {
- public:
- using result_type = IntType;
-
- class param_type {
- public:
- using distribution_type = zipf_distribution;
-
- // Preconditions: k > 0, v > 0, q > 1
- // The precondidtions are validated when NDEBUG is not defined via
- // a pair of assert() directives.
- // If NDEBUG is defined and either or both of these parameters take invalid
- // values, the behavior of the class is undefined.
- explicit param_type(result_type k = (std::numeric_limits<IntType>::max)(),
- double q = 2.0, double v = 1.0);
-
- result_type k() const { return k_; }
- double q() const { return q_; }
- double v() const { return v_; }
-
- friend bool operator==(const param_type& a, const param_type& b) {
- return a.k_ == b.k_ && a.q_ == b.q_ && a.v_ == b.v_;
- }
- friend bool operator!=(const param_type& a, const param_type& b) {
- return !(a == b);
- }
-
- private:
- friend class zipf_distribution;
- inline double h(double x) const;
- inline double hinv(double x) const;
- inline double compute_s() const;
- inline double pow_negative_q(double x) const;
-
- // Parameters here are exactly the same as the parameters of Algorithm ZRI
- // in the paper.
- IntType k_;
- double q_;
- double v_;
-
- double one_minus_q_; // 1-q
- double s_;
- double one_minus_q_inv_; // 1 / 1-q
- double hxm_; // h(k + 0.5)
- double hx0_minus_hxm_; // h(x0) - h(k + 0.5)
-
- static_assert(std::is_integral<IntType>::value,
- "Class-template absl::zipf_distribution<> must be "
- "parameterized using an integral type.");
- };
-
- zipf_distribution()
- : zipf_distribution((std::numeric_limits<IntType>::max)()) {}
-
- explicit zipf_distribution(result_type k, double q = 2.0, double v = 1.0)
- : param_(k, q, v) {}
-
- explicit zipf_distribution(const param_type& p) : param_(p) {}
-
- void reset() {}
-
- template <typename URBG>
- result_type operator()(URBG& g) { // NOLINT(runtime/references)
- return (*this)(g, param_);
- }
-
- template <typename URBG>
- result_type operator()(URBG& g, // NOLINT(runtime/references)
- const param_type& p);
-
- result_type k() const { return param_.k(); }
- double q() const { return param_.q(); }
- double v() const { return param_.v(); }
-
- param_type param() const { return param_; }
- void param(const param_type& p) { param_ = p; }
-
- result_type(min)() const { return 0; }
- result_type(max)() const { return k(); }
-
- friend bool operator==(const zipf_distribution& a,
- const zipf_distribution& b) {
- return a.param_ == b.param_;
- }
- friend bool operator!=(const zipf_distribution& a,
- const zipf_distribution& b) {
- return a.param_ != b.param_;
- }
-
- private:
- param_type param_;
-};
-
-// --------------------------------------------------------------------------
-// Implementation details follow
-// --------------------------------------------------------------------------
-
-template <typename IntType>
-zipf_distribution<IntType>::param_type::param_type(
- typename zipf_distribution<IntType>::result_type k, double q, double v)
- : k_(k), q_(q), v_(v), one_minus_q_(1 - q) {
- assert(q > 1);
- assert(v > 0);
- assert(k > 0);
- one_minus_q_inv_ = 1 / one_minus_q_;
-
- // Setup for the ZRI algorithm (pg 17 of the paper).
- // Compute: h(i max) => h(k + 0.5)
- constexpr double kMax = 18446744073709549568.0;
- double kd = static_cast<double>(k);
- // TODO(absl-team): Determine if this check is needed, and if so, add a test
- // that fails for k > kMax
- if (kd > kMax) {
- // Ensure that our maximum value is capped to a value which will
- // round-trip back through double.
- kd = kMax;
- }
- hxm_ = h(kd + 0.5);
-
- // Compute: h(0)
- const bool use_precomputed = (v == 1.0 && q == 2.0);
- const double h0x5 = use_precomputed ? (-1.0 / 1.5) // exp(-log(1.5))
- : h(0.5);
- const double elogv_q = (v_ == 1.0) ? 1 : pow_negative_q(v_);
-
- // h(0) = h(0.5) - exp(log(v) * -q)
- hx0_minus_hxm_ = (h0x5 - elogv_q) - hxm_;
-
- // And s
- s_ = use_precomputed ? 0.46153846153846123 : compute_s();
-}
-
-template <typename IntType>
-double zipf_distribution<IntType>::param_type::h(double x) const {
- // std::exp(one_minus_q_ * std::log(v_ + x)) * one_minus_q_inv_;
- x += v_;
- return (one_minus_q_ == -1.0)
- ? (-1.0 / x) // -exp(-log(x))
- : (std::exp(std::log(x) * one_minus_q_) * one_minus_q_inv_);
-}
-
-template <typename IntType>
-double zipf_distribution<IntType>::param_type::hinv(double x) const {
- // std::exp(one_minus_q_inv_ * std::log(one_minus_q_ * x)) - v_;
- return -v_ + ((one_minus_q_ == -1.0)
- ? (-1.0 / x) // exp(-log(-x))
- : std::exp(one_minus_q_inv_ * std::log(one_minus_q_ * x)));
-}
-
-template <typename IntType>
-double zipf_distribution<IntType>::param_type::compute_s() const {
- // 1 - hinv(h(1.5) - std::exp(std::log(v_ + 1) * -q_));
- return 1.0 - hinv(h(1.5) - pow_negative_q(v_ + 1.0));
-}
-
-template <typename IntType>
-double zipf_distribution<IntType>::param_type::pow_negative_q(double x) const {
- // std::exp(std::log(x) * -q_);
- return q_ == 2.0 ? (1.0 / (x * x)) : std::exp(std::log(x) * -q_);
-}
-
-template <typename IntType>
-template <typename URBG>
-typename zipf_distribution<IntType>::result_type
-zipf_distribution<IntType>::operator()(
- URBG& g, const param_type& p) { // NOLINT(runtime/references)
- absl::uniform_real_distribution<double> uniform_double;
- double k;
- for (;;) {
- const double v = uniform_double(g);
- const double u = p.hxm_ + v * p.hx0_minus_hxm_;
- const double x = p.hinv(u);
- k = rint(x); // std::floor(x + 0.5);
- if (k > p.k()) continue; // reject k > max_k
- if (k - x <= p.s_) break;
- const double h = p.h(k + 0.5);
- const double r = p.pow_negative_q(p.v_ + k);
- if (u >= h - r) break;
- }
- IntType ki = static_cast<IntType>(k);
- assert(ki <= p.k_);
- return ki;
-}
-
-template <typename CharT, typename Traits, typename IntType>
-std::basic_ostream<CharT, Traits>& operator<<(
- std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
- const zipf_distribution<IntType>& x) {
- using stream_type =
- typename random_internal::stream_format_type<IntType>::type;
- auto saver = random_internal::make_ostream_state_saver(os);
- os.precision(random_internal::stream_precision_helper<double>::kPrecision);
- os << static_cast<stream_type>(x.k()) << os.fill() << x.q() << os.fill()
- << x.v();
- return os;
-}
-
-template <typename CharT, typename Traits, typename IntType>
-std::basic_istream<CharT, Traits>& operator>>(
- std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
- zipf_distribution<IntType>& x) { // NOLINT(runtime/references)
- using result_type = typename zipf_distribution<IntType>::result_type;
- using param_type = typename zipf_distribution<IntType>::param_type;
- using stream_type =
- typename random_internal::stream_format_type<IntType>::type;
- stream_type k;
- double q;
- double v;
-
- auto saver = random_internal::make_istream_state_saver(is);
- is >> k >> q >> v;
- if (!is.fail()) {
- x.param(param_type(static_cast<result_type>(k), q, v));
- }
- return is;
-}
-
+
+// absl::zipf_distribution produces random integer-values in the range [0, k],
+// distributed according to the discrete probability function:
+//
+// P(x) = (v + x) ^ -q
+//
+// The parameter `v` must be greater than 0 and the parameter `q` must be
+// greater than 1. If either of these parameters take invalid values then the
+// behavior is undefined.
+//
+// IntType is the result_type generated by the generator. It must be of integral
+// type; a static_assert ensures this is the case.
+//
+// The implementation is based on W.Hormann, G.Derflinger:
+//
+// "Rejection-Inversion to Generate Variates from Monotone Discrete
+// Distributions"
+//
+// http://eeyore.wu-wien.ac.at/papers/96-04-04.wh-der.ps.gz
+//
+template <typename IntType = int>
+class zipf_distribution {
+ public:
+ using result_type = IntType;
+
+ class param_type {
+ public:
+ using distribution_type = zipf_distribution;
+
+ // Preconditions: k > 0, v > 0, q > 1
+ // The precondidtions are validated when NDEBUG is not defined via
+ // a pair of assert() directives.
+ // If NDEBUG is defined and either or both of these parameters take invalid
+ // values, the behavior of the class is undefined.
+ explicit param_type(result_type k = (std::numeric_limits<IntType>::max)(),
+ double q = 2.0, double v = 1.0);
+
+ result_type k() const { return k_; }
+ double q() const { return q_; }
+ double v() const { return v_; }
+
+ friend bool operator==(const param_type& a, const param_type& b) {
+ return a.k_ == b.k_ && a.q_ == b.q_ && a.v_ == b.v_;
+ }
+ friend bool operator!=(const param_type& a, const param_type& b) {
+ return !(a == b);
+ }
+
+ private:
+ friend class zipf_distribution;
+ inline double h(double x) const;
+ inline double hinv(double x) const;
+ inline double compute_s() const;
+ inline double pow_negative_q(double x) const;
+
+ // Parameters here are exactly the same as the parameters of Algorithm ZRI
+ // in the paper.
+ IntType k_;
+ double q_;
+ double v_;
+
+ double one_minus_q_; // 1-q
+ double s_;
+ double one_minus_q_inv_; // 1 / 1-q
+ double hxm_; // h(k + 0.5)
+ double hx0_minus_hxm_; // h(x0) - h(k + 0.5)
+
+ static_assert(std::is_integral<IntType>::value,
+ "Class-template absl::zipf_distribution<> must be "
+ "parameterized using an integral type.");
+ };
+
+ zipf_distribution()
+ : zipf_distribution((std::numeric_limits<IntType>::max)()) {}
+
+ explicit zipf_distribution(result_type k, double q = 2.0, double v = 1.0)
+ : param_(k, q, v) {}
+
+ explicit zipf_distribution(const param_type& p) : param_(p) {}
+
+ void reset() {}
+
+ template <typename URBG>
+ result_type operator()(URBG& g) { // NOLINT(runtime/references)
+ return (*this)(g, param_);
+ }
+
+ template <typename URBG>
+ result_type operator()(URBG& g, // NOLINT(runtime/references)
+ const param_type& p);
+
+ result_type k() const { return param_.k(); }
+ double q() const { return param_.q(); }
+ double v() const { return param_.v(); }
+
+ param_type param() const { return param_; }
+ void param(const param_type& p) { param_ = p; }
+
+ result_type(min)() const { return 0; }
+ result_type(max)() const { return k(); }
+
+ friend bool operator==(const zipf_distribution& a,
+ const zipf_distribution& b) {
+ return a.param_ == b.param_;
+ }
+ friend bool operator!=(const zipf_distribution& a,
+ const zipf_distribution& b) {
+ return a.param_ != b.param_;
+ }
+
+ private:
+ param_type param_;
+};
+
+// --------------------------------------------------------------------------
+// Implementation details follow
+// --------------------------------------------------------------------------
+
+template <typename IntType>
+zipf_distribution<IntType>::param_type::param_type(
+ typename zipf_distribution<IntType>::result_type k, double q, double v)
+ : k_(k), q_(q), v_(v), one_minus_q_(1 - q) {
+ assert(q > 1);
+ assert(v > 0);
+ assert(k > 0);
+ one_minus_q_inv_ = 1 / one_minus_q_;
+
+ // Setup for the ZRI algorithm (pg 17 of the paper).
+ // Compute: h(i max) => h(k + 0.5)
+ constexpr double kMax = 18446744073709549568.0;
+ double kd = static_cast<double>(k);
+ // TODO(absl-team): Determine if this check is needed, and if so, add a test
+ // that fails for k > kMax
+ if (kd > kMax) {
+ // Ensure that our maximum value is capped to a value which will
+ // round-trip back through double.
+ kd = kMax;
+ }
+ hxm_ = h(kd + 0.5);
+
+ // Compute: h(0)
+ const bool use_precomputed = (v == 1.0 && q == 2.0);
+ const double h0x5 = use_precomputed ? (-1.0 / 1.5) // exp(-log(1.5))
+ : h(0.5);
+ const double elogv_q = (v_ == 1.0) ? 1 : pow_negative_q(v_);
+
+ // h(0) = h(0.5) - exp(log(v) * -q)
+ hx0_minus_hxm_ = (h0x5 - elogv_q) - hxm_;
+
+ // And s
+ s_ = use_precomputed ? 0.46153846153846123 : compute_s();
+}
+
+template <typename IntType>
+double zipf_distribution<IntType>::param_type::h(double x) const {
+ // std::exp(one_minus_q_ * std::log(v_ + x)) * one_minus_q_inv_;
+ x += v_;
+ return (one_minus_q_ == -1.0)
+ ? (-1.0 / x) // -exp(-log(x))
+ : (std::exp(std::log(x) * one_minus_q_) * one_minus_q_inv_);
+}
+
+template <typename IntType>
+double zipf_distribution<IntType>::param_type::hinv(double x) const {
+ // std::exp(one_minus_q_inv_ * std::log(one_minus_q_ * x)) - v_;
+ return -v_ + ((one_minus_q_ == -1.0)
+ ? (-1.0 / x) // exp(-log(-x))
+ : std::exp(one_minus_q_inv_ * std::log(one_minus_q_ * x)));
+}
+
+template <typename IntType>
+double zipf_distribution<IntType>::param_type::compute_s() const {
+ // 1 - hinv(h(1.5) - std::exp(std::log(v_ + 1) * -q_));
+ return 1.0 - hinv(h(1.5) - pow_negative_q(v_ + 1.0));
+}
+
+template <typename IntType>
+double zipf_distribution<IntType>::param_type::pow_negative_q(double x) const {
+ // std::exp(std::log(x) * -q_);
+ return q_ == 2.0 ? (1.0 / (x * x)) : std::exp(std::log(x) * -q_);
+}
+
+template <typename IntType>
+template <typename URBG>
+typename zipf_distribution<IntType>::result_type
+zipf_distribution<IntType>::operator()(
+ URBG& g, const param_type& p) { // NOLINT(runtime/references)
+ absl::uniform_real_distribution<double> uniform_double;
+ double k;
+ for (;;) {
+ const double v = uniform_double(g);
+ const double u = p.hxm_ + v * p.hx0_minus_hxm_;
+ const double x = p.hinv(u);
+ k = rint(x); // std::floor(x + 0.5);
+ if (k > p.k()) continue; // reject k > max_k
+ if (k - x <= p.s_) break;
+ const double h = p.h(k + 0.5);
+ const double r = p.pow_negative_q(p.v_ + k);
+ if (u >= h - r) break;
+ }
+ IntType ki = static_cast<IntType>(k);
+ assert(ki <= p.k_);
+ return ki;
+}
+
+template <typename CharT, typename Traits, typename IntType>
+std::basic_ostream<CharT, Traits>& operator<<(
+ std::basic_ostream<CharT, Traits>& os, // NOLINT(runtime/references)
+ const zipf_distribution<IntType>& x) {
+ using stream_type =
+ typename random_internal::stream_format_type<IntType>::type;
+ auto saver = random_internal::make_ostream_state_saver(os);
+ os.precision(random_internal::stream_precision_helper<double>::kPrecision);
+ os << static_cast<stream_type>(x.k()) << os.fill() << x.q() << os.fill()
+ << x.v();
+ return os;
+}
+
+template <typename CharT, typename Traits, typename IntType>
+std::basic_istream<CharT, Traits>& operator>>(
+ std::basic_istream<CharT, Traits>& is, // NOLINT(runtime/references)
+ zipf_distribution<IntType>& x) { // NOLINT(runtime/references)
+ using result_type = typename zipf_distribution<IntType>::result_type;
+ using param_type = typename zipf_distribution<IntType>::param_type;
+ using stream_type =
+ typename random_internal::stream_format_type<IntType>::type;
+ stream_type k;
+ double q;
+ double v;
+
+ auto saver = random_internal::make_istream_state_saver(is);
+ is >> k >> q >> v;
+ if (!is.fail()) {
+ x.param(param_type(static_cast<result_type>(k), q, v));
+ }
+ return is;
+}
+
ABSL_NAMESPACE_END
-} // namespace absl
-
-#endif // ABSL_RANDOM_ZIPF_DISTRIBUTION_H_
+} // namespace absl
+
+#endif // ABSL_RANDOM_ZIPF_DISTRIBUTION_H_