about summary refs log tree commit diff
path: root/absl/random/distributions.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/random/distributions.h')
-rw-r--r--absl/random/distributions.h56
1 files changed, 41 insertions, 15 deletions
diff --git a/absl/random/distributions.h b/absl/random/distributions.h
index 3a4e93abfa2f..6ced60616158 100644
--- a/absl/random/distributions.h
+++ b/absl/random/distributions.h
@@ -124,7 +124,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)
@@ -135,11 +143,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>;
+
+  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::UniformImpl<R, tag_t, gen_t>(tag, urbg, lo, hi);
+  return random_internal::DistributionCaller<gen_t>::template Call<
+      distribution_t, format_t>(&urbg, lo, hi);
 }
 
 // absl::Uniform(tag, bitgen, lo, hi)
@@ -156,9 +170,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>;
 
-  return random_internal::UniformImpl<return_t, TagType, gen_t>(tag, urbg, lo,
-                                                                hi);
+  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, tag, static_cast<return_t>(lo),
+                                static_cast<return_t>(hi));
 }
 
 // absl::Uniform(bitgen, lo, hi)
@@ -171,13 +192,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)
@@ -187,13 +214,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);
 }
 
 // -----------------------------------------------------------------------------