abseil-cpp/absl/random/internal/uniform_helper.h
Go to the documentation of this file.
1 // Copyright 2019 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 #ifndef ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_
16 #define ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_
17 
18 #include <cmath>
19 #include <limits>
20 #include <type_traits>
21 
22 #include "absl/base/config.h"
23 #include "absl/meta/type_traits.h"
24 #include "absl/random/internal/traits.h"
25 
26 namespace absl {
28 
29 template <typename IntType>
31 
32 template <typename RealType>
34 
35 // Interval tag types which specify whether the interval is open or closed
36 // on either boundary.
37 
38 namespace random_internal {
39 template <typename T>
40 struct TagTypeCompare {};
41 
42 template <typename T>
44  // Tags are mono-states. They always compare equal.
45  return true;
46 }
47 template <typename T>
49  return false;
50 }
51 
52 } // namespace random_internal
53 
55  : public random_internal::TagTypeCompare<IntervalClosedClosedTag> {};
57  : public random_internal::TagTypeCompare<IntervalClosedOpenTag> {};
59  : public random_internal::TagTypeCompare<IntervalOpenClosedTag> {};
61  : public random_internal::TagTypeCompare<IntervalOpenOpenTag> {};
62 
63 namespace random_internal {
64 
65 // In the absence of an explicitly provided return-type, the template
66 // "uniform_inferred_return_t<A, B>" is used to derive a suitable type, based on
67 // the data-types of the endpoint-arguments {A lo, B hi}.
68 //
69 // Given endpoints {A lo, B hi}, one of {A, B} will be chosen as the
70 // return-type, if one type can be implicitly converted into the other, in a
71 // lossless way. The template "is_widening_convertible" implements the
72 // compile-time logic for deciding if such a conversion is possible.
73 //
74 // If no such conversion between {A, B} exists, then the overload for
75 // absl::Uniform() will be discarded, and the call will be ill-formed.
76 // Return-type for absl::Uniform() when the return-type is inferred.
77 template <typename A, typename B>
80  is_widening_convertible<B, A>>::value,
81  typename std::conditional<
83 
84 // The functions
85 // uniform_lower_bound(tag, a, b)
86 // and
87 // uniform_upper_bound(tag, a, b)
88 // are used as implementation-details for absl::Uniform().
89 //
90 // Conceptually,
91 // [a, b] == [uniform_lower_bound(IntervalClosedClosed, a, b),
92 // uniform_upper_bound(IntervalClosedClosed, a, b)]
93 // (a, b) == [uniform_lower_bound(IntervalOpenOpen, a, b),
94 // uniform_upper_bound(IntervalOpenOpen, a, b)]
95 // [a, b) == [uniform_lower_bound(IntervalClosedOpen, a, b),
96 // uniform_upper_bound(IntervalClosedOpen, a, b)]
97 // (a, b] == [uniform_lower_bound(IntervalOpenClosed, a, b),
98 // uniform_upper_bound(IntervalOpenClosed, a, b)]
99 //
100 template <typename IntType, typename Tag>
101 typename absl::enable_if_t<
105  std::is_same<Tag, IntervalOpenOpenTag>>>::value,
106  IntType>
107 uniform_lower_bound(Tag, IntType a, IntType) {
108  return a < (std::numeric_limits<IntType>::max)() ? (a + 1) : a;
109 }
110 
111 template <typename FloatType, typename Tag>
112 typename absl::enable_if_t<
114  std::is_floating_point<FloatType>,
116  std::is_same<Tag, IntervalOpenOpenTag>>>::value,
117  FloatType>
119  return std::nextafter(a, b);
120 }
121 
122 template <typename NumType, typename Tag>
123 typename absl::enable_if_t<
125  std::is_same<Tag, IntervalClosedOpenTag>>::value,
126  NumType>
127 uniform_lower_bound(Tag, NumType a, NumType) {
128  return a;
129 }
130 
131 template <typename IntType, typename Tag>
132 typename absl::enable_if_t<
134  IsIntegral<IntType>,
136  std::is_same<Tag, IntervalOpenOpenTag>>>::value,
137  IntType>
138 uniform_upper_bound(Tag, IntType, IntType b) {
139  return b > (std::numeric_limits<IntType>::min)() ? (b - 1) : b;
140 }
141 
142 template <typename FloatType, typename Tag>
143 typename absl::enable_if_t<
145  std::is_floating_point<FloatType>,
147  std::is_same<Tag, IntervalOpenOpenTag>>>::value,
148  FloatType>
150  return b;
151 }
152 
153 template <typename IntType, typename Tag>
154 typename absl::enable_if_t<
156  IsIntegral<IntType>,
158  std::is_same<Tag, IntervalOpenClosedTag>>>::value,
159  IntType>
160 uniform_upper_bound(Tag, IntType, IntType b) {
161  return b;
162 }
163 
164 template <typename FloatType, typename Tag>
165 typename absl::enable_if_t<
167  std::is_floating_point<FloatType>,
169  std::is_same<Tag, IntervalOpenClosedTag>>>::value,
170  FloatType>
172  return std::nextafter(b, (std::numeric_limits<FloatType>::max)());
173 }
174 
175 // Returns whether the bounds are valid for the underlying distribution.
176 // Inputs must have already been resolved via uniform_*_bound calls.
177 //
178 // The c++ standard constraints in [rand.dist.uni.int] are listed as:
179 // requires: lo <= hi.
180 //
181 // In the uniform_int_distrubtion, {lo, hi} are closed, closed. Thus:
182 // [0, 0] is legal.
183 // [0, 0) is not legal, but [0, 1) is, which translates to [0, 0].
184 // (0, 1) is not legal, but (0, 2) is, which translates to [1, 1].
185 // (0, 0] is not legal, but (0, 1] is, which translates to [1, 1].
186 //
187 // The c++ standard constraints in [rand.dist.uni.real] are listed as:
188 // requires: lo <= hi.
189 // requires: (hi - lo) <= numeric_limits<T>::max()
190 //
191 // In the uniform_real_distribution, {lo, hi} are closed, open, Thus:
192 // [0, 0] is legal, which is [0, 0+epsilon).
193 // [0, 0) is legal.
194 // (0, 0) is not legal, but (0-epsilon, 0+epsilon) is.
195 // (0, 0] is not legal, but (0, 0+epsilon] is.
196 //
197 template <typename FloatType>
200  return a <= b && std::isfinite(b - a);
201 }
202 
203 template <typename IntType>
205 is_uniform_range_valid(IntType a, IntType b) {
206  return a <= b;
207 }
208 
209 // UniformDistribution selects either absl::uniform_int_distribution
210 // or absl::uniform_real_distribution depending on the NumType parameter.
211 template <typename NumType>
212 using UniformDistribution =
216 
217 // UniformDistributionWrapper is used as the underlying distribution type
218 // by the absl::Uniform template function. It selects the proper Abseil
219 // uniform distribution and provides constructor overloads that match the
220 // expected parameter order as well as adjusting distribtuion bounds based
221 // on the tag.
222 template <typename NumType>
224  template <typename TagType>
225  explicit UniformDistributionWrapper(TagType, NumType lo, NumType hi)
226  : UniformDistribution<NumType>(
227  uniform_lower_bound<NumType>(TagType{}, lo, hi),
228  uniform_upper_bound<NumType>(TagType{}, lo, hi)) {}
229 
230  explicit UniformDistributionWrapper(NumType lo, NumType hi)
231  : UniformDistribution<NumType>(
232  uniform_lower_bound<NumType>(IntervalClosedOpenTag(), lo, hi),
233  uniform_upper_bound<NumType>(IntervalClosedOpenTag(), lo, hi)) {}
234 
236  : UniformDistribution<NumType>(std::numeric_limits<NumType>::lowest(),
237  (std::numeric_limits<NumType>::max)()) {}
238 };
239 
240 } // namespace random_internal
242 } // namespace absl
243 
244 #endif // ABSL_RANDOM_INTERNAL_UNIFORM_HELPER_H_
absl::IntervalOpenClosedTag
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:58
absl::IntervalOpenOpenTag
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:60
absl::random_internal::uniform_inferred_return_t
absl::enable_if_t< absl::disjunction< is_widening_convertible< A, B >, is_widening_convertible< B, A > >::value, typename std::conditional< is_widening_convertible< A, B >::value, B, A >::type > uniform_inferred_return_t
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:82
absl::conjunction
Definition: abseil-cpp/absl/meta/type_traits.h:230
absl::uniform_int_distribution
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:30
absl::enable_if_t
typename std::enable_if< B, T >::type enable_if_t
Definition: abseil-cpp/absl/meta/type_traits.h:631
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
absl::random_internal::IsIntegral
Definition: abseil-cpp/absl/random/internal/traits.h:65
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
absl::IntervalClosedClosedTag
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:54
absl::random_internal::operator!=
constexpr bool operator!=(TagTypeCompare< T >, TagTypeCompare< T >)
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:48
absl::random_internal::TagTypeCompare
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:40
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
absl::random_internal::operator==
constexpr bool operator==(TagTypeCompare< T >, TagTypeCompare< T >)
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:43
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
opencensus.proto.stats.v1.stats_pb2.Tag
Tag
Definition: stats_pb2.py:431
absl::random_internal::is_widening_convertible
Definition: abseil-cpp/absl/random/internal/traits.h:40
absl::random_internal::is_uniform_range_valid
absl::enable_if_t< std::is_floating_point< FloatType >::value, bool > is_uniform_range_valid(FloatType a, FloatType b)
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:199
absl::uniform_real_distribution
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:33
min
#define min(a, b)
Definition: qsort.h:83
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
absl::random_internal::uniform_lower_bound
absl::enable_if_t< absl::conjunction< IsIntegral< IntType >, absl::disjunction< std::is_same< Tag, IntervalOpenClosedTag >, std::is_same< Tag, IntervalOpenOpenTag > > >::value, IntType > uniform_lower_bound(Tag, IntType a, IntType)
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:107
absl::strings_internal::FloatType
FloatType
Definition: abseil-cpp/absl/strings/internal/charconv_parse.h:28
absl::random_internal::UniformDistributionWrapper
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:223
value
const char * value
Definition: hpack_parser_table.cc:165
absl::IntervalClosedOpenTag
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:56
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
A
Definition: miscompile_with_no_unique_address_test.cc:23
absl::random_internal::UniformDistribution
typename std::conditional< IsIntegral< NumType >::value, absl::uniform_int_distribution< NumType >, absl::uniform_real_distribution< NumType > >::type UniformDistribution
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:215
absl::disjunction
Definition: abseil-cpp/absl/meta/type_traits.h:249
absl::random_internal::UniformDistributionWrapper::UniformDistributionWrapper
UniformDistributionWrapper(NumType lo, NumType hi)
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:230
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
isfinite
#define isfinite
Definition: bloaty/third_party/protobuf/conformance/third_party/jsoncpp/jsoncpp.cpp:4014
absl::random_internal::UniformDistributionWrapper::UniformDistributionWrapper
UniformDistributionWrapper(TagType, NumType lo, NumType hi)
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:225
absl::random_internal::uniform_upper_bound
absl::enable_if_t< absl::conjunction< IsIntegral< IntType >, absl::disjunction< std::is_same< Tag, IntervalClosedOpenTag >, std::is_same< Tag, IntervalOpenOpenTag > > >::value, IntType > uniform_upper_bound(Tag, IntType, IntType b)
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:138
absl::random_internal::UniformDistributionWrapper::UniformDistributionWrapper
UniformDistributionWrapper()
Definition: abseil-cpp/absl/random/internal/uniform_helper.h:235


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:44