diff options
Diffstat (limited to 'absl/random/distributions.h')
-rw-r--r-- | absl/random/distributions.h | 91 |
1 files changed, 56 insertions, 35 deletions
diff --git a/absl/random/distributions.h b/absl/random/distributions.h index f2ebfc2d..d026d92b 100644 --- a/absl/random/distributions.h +++ b/absl/random/distributions.h @@ -67,20 +67,15 @@ #include "absl/random/zipf_distribution.h" namespace absl { -inline namespace lts_2019_08_08 { - -ABSL_INTERNAL_INLINE_CONSTEXPR(random_internal::IntervalClosedClosedT, - IntervalClosedClosed, {}); -ABSL_INTERNAL_INLINE_CONSTEXPR(random_internal::IntervalClosedClosedT, - IntervalClosed, {}); -ABSL_INTERNAL_INLINE_CONSTEXPR(random_internal::IntervalClosedOpenT, - IntervalClosedOpen, {}); -ABSL_INTERNAL_INLINE_CONSTEXPR(random_internal::IntervalOpenOpenT, - IntervalOpenOpen, {}); -ABSL_INTERNAL_INLINE_CONSTEXPR(random_internal::IntervalOpenOpenT, - IntervalOpen, {}); -ABSL_INTERNAL_INLINE_CONSTEXPR(random_internal::IntervalOpenClosedT, - IntervalOpenClosed, {}); +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) @@ -102,7 +97,7 @@ ABSL_INTERNAL_INLINE_CONSTEXPR(random_internal::IntervalOpenClosedT, // 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 implcit conversion between {A, B} will produce a +// lack of any such implicit conversion between {A, B} will produce a // compile-time error // // See https://en.wikipedia.org/wiki/Uniform_distribution_(continuous) @@ -130,7 +125,15 @@ Uniform(TagType tag, URBG&& urbg, // NOLINT(runtime/references) R lo, R hi) { using gen_t = absl::decay_t<URBG>; - return random_internal::UniformImpl<R, TagType, gen_t>(tag, urbg, lo, hi); + using distribution_t = random_internal::UniformDistributionWrapper<R>; + using format_t = random_internal::DistributionFormatTraits<distribution_t>; + + auto a = random_internal::uniform_lower_bound(tag, lo, hi); + auto b = random_internal::uniform_upper_bound(tag, lo, hi); + if (a > b) return a; + + return random_internal::DistributionCaller<gen_t>::template Call< + distribution_t, format_t>(&urbg, tag, lo, hi); } // absl::Uniform<T>(bitgen, lo, hi) @@ -141,11 +144,17 @@ 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) { - constexpr auto tag = absl::IntervalClosedOpen; - using tag_t = decltype(tag); using gen_t = absl::decay_t<URBG>; + using distribution_t = random_internal::UniformDistributionWrapper<R>; + using format_t = random_internal::DistributionFormatTraits<distribution_t>; - return random_internal::UniformImpl<R, tag_t, gen_t>(tag, urbg, lo, hi); + 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); + if (a > b) return a; + + return random_internal::DistributionCaller<gen_t>::template Call< + distribution_t, format_t>(&urbg, lo, hi); } // absl::Uniform(tag, bitgen, lo, hi) @@ -162,9 +171,16 @@ Uniform(TagType tag, 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>; + using format_t = random_internal::DistributionFormatTraits<distribution_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 (a > b) return a; - return random_internal::UniformImpl<return_t, TagType, gen_t>(tag, urbg, lo, - hi); + return random_internal::DistributionCaller<gen_t>::template Call< + distribution_t, format_t>(&urbg, tag, static_cast<return_t>(lo), + static_cast<return_t>(hi)); } // absl::Uniform(bitgen, lo, hi) @@ -177,13 +193,19 @@ 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) { - constexpr auto tag = absl::IntervalClosedOpen; - using tag_t = decltype(tag); 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>; + using format_t = random_internal::DistributionFormatTraits<distribution_t>; - return random_internal::UniformImpl<return_t, tag_t, gen_t>(tag, urbg, lo, - hi); + 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 (a > b) return a; + + return random_internal::DistributionCaller<gen_t>::template Call< + distribution_t, format_t>(&urbg, static_cast<return_t>(lo), + static_cast<return_t>(hi)); } // absl::Uniform<unsigned T>(bitgen) @@ -193,13 +215,12 @@ Uniform(URBG&& urbg, // NOLINT(runtime/references) template <typename R, typename URBG> typename absl::enable_if_t<!std::is_signed<R>::value, R> // Uniform(URBG&& urbg) { // NOLINT(runtime/references) - constexpr auto tag = absl::IntervalClosedClosed; - constexpr auto lo = std::numeric_limits<R>::lowest(); - constexpr auto hi = (std::numeric_limits<R>::max)(); - using tag_t = decltype(tag); using gen_t = absl::decay_t<URBG>; + using distribution_t = random_internal::UniformDistributionWrapper<R>; + using format_t = random_internal::DistributionFormatTraits<distribution_t>; - return random_internal::UniformImpl<R, tag_t, gen_t>(tag, urbg, lo, hi); + return random_internal::DistributionCaller<gen_t>::template Call< + distribution_t, format_t>(&urbg); } // ----------------------------------------------------------------------------- @@ -270,10 +291,10 @@ RealType Beta(URBG&& urbg, // NOLINT(runtime/references) // absl::Exponential<T>(bitgen, lambda = 1) // ----------------------------------------------------------------------------- // -// `absl::Exponential` produces a floating point number for discrete -// distributions 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`. +// `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. // @@ -438,7 +459,7 @@ IntType Zipf(URBG&& urbg, // NOLINT(runtime/references) distribution_t, format_t>(&urbg, hi, q, v); } -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_DISTRIBUTIONS_H_ |