diff options
Diffstat (limited to 'absl/random/internal/uniform_helper.h')
-rw-r--r-- | absl/random/internal/uniform_helper.h | 74 |
1 files changed, 51 insertions, 23 deletions
diff --git a/absl/random/internal/uniform_helper.h b/absl/random/internal/uniform_helper.h index 6af053ef..663107cb 100644 --- a/absl/random/internal/uniform_helper.h +++ b/absl/random/internal/uniform_helper.h @@ -22,7 +22,7 @@ #include "absl/meta/type_traits.h" namespace absl { -inline namespace lts_2019_08_08 { +ABSL_NAMESPACE_BEGIN template <typename IntType> class uniform_int_distribution; @@ -31,15 +31,33 @@ class uniform_real_distribution; // Interval tag types which specify whether the interval is open or closed // on either boundary. + namespace random_internal { -struct IntervalClosedClosedT {}; -struct IntervalClosedOpenT {}; -struct IntervalOpenClosedT {}; -struct IntervalOpenOpenT {}; +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 -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 { // The functions // uniform_lower_bound(tag, a, b) // and @@ -60,8 +78,8 @@ template <typename IntType, typename Tag> typename absl::enable_if_t< absl::conjunction< std::is_integral<IntType>, - absl::disjunction<std::is_same<Tag, IntervalOpenClosedT>, - std::is_same<Tag, IntervalOpenOpenT>>>::value, + absl::disjunction<std::is_same<Tag, IntervalOpenClosedTag>, + std::is_same<Tag, IntervalOpenOpenTag>>>::value, IntType> uniform_lower_bound(Tag, IntType a, IntType) { return a + 1; @@ -71,8 +89,8 @@ template <typename FloatType, typename Tag> typename absl::enable_if_t< absl::conjunction< std::is_floating_point<FloatType>, - absl::disjunction<std::is_same<Tag, IntervalOpenClosedT>, - std::is_same<Tag, IntervalOpenOpenT>>>::value, + 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); @@ -80,8 +98,8 @@ uniform_lower_bound(Tag, FloatType a, FloatType b) { template <typename NumType, typename Tag> typename absl::enable_if_t< - absl::disjunction<std::is_same<Tag, IntervalClosedClosedT>, - std::is_same<Tag, IntervalClosedOpenT>>::value, + absl::disjunction<std::is_same<Tag, IntervalClosedClosedTag>, + std::is_same<Tag, IntervalClosedOpenTag>>::value, NumType> uniform_lower_bound(Tag, NumType a, NumType) { return a; @@ -91,8 +109,8 @@ template <typename IntType, typename Tag> typename absl::enable_if_t< absl::conjunction< std::is_integral<IntType>, - absl::disjunction<std::is_same<Tag, IntervalClosedOpenT>, - std::is_same<Tag, IntervalOpenOpenT>>>::value, + absl::disjunction<std::is_same<Tag, IntervalClosedOpenTag>, + std::is_same<Tag, IntervalOpenOpenTag>>>::value, IntType> uniform_upper_bound(Tag, IntType, IntType b) { return b - 1; @@ -102,8 +120,8 @@ template <typename FloatType, typename Tag> typename absl::enable_if_t< absl::conjunction< std::is_floating_point<FloatType>, - absl::disjunction<std::is_same<Tag, IntervalClosedOpenT>, - std::is_same<Tag, IntervalOpenOpenT>>>::value, + absl::disjunction<std::is_same<Tag, IntervalClosedOpenTag>, + std::is_same<Tag, IntervalOpenOpenTag>>>::value, FloatType> uniform_upper_bound(Tag, FloatType, FloatType b) { return b; @@ -113,8 +131,8 @@ template <typename IntType, typename Tag> typename absl::enable_if_t< absl::conjunction< std::is_integral<IntType>, - absl::disjunction<std::is_same<Tag, IntervalClosedClosedT>, - std::is_same<Tag, IntervalOpenClosedT>>>::value, + absl::disjunction<std::is_same<Tag, IntervalClosedClosedTag>, + std::is_same<Tag, IntervalOpenClosedTag>>>::value, IntType> uniform_upper_bound(Tag, IntType, IntType b) { return b; @@ -124,8 +142,8 @@ template <typename FloatType, typename Tag> typename absl::enable_if_t< absl::conjunction< std::is_floating_point<FloatType>, - absl::disjunction<std::is_same<Tag, IntervalClosedClosedT>, - std::is_same<Tag, IntervalOpenClosedT>>>::value, + 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)()); @@ -137,16 +155,26 @@ using UniformDistribution = absl::uniform_int_distribution<NumType>, absl::uniform_real_distribution<NumType>>::type; -template <typename TagType, typename NumType> +template <typename NumType> struct UniformDistributionWrapper : public UniformDistribution<NumType> { - explicit UniformDistributionWrapper(NumType lo, NumType hi) + 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 -} // inline namespace lts_2019_08_08 +ABSL_NAMESPACE_END } // namespace absl #endif // ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_ |