Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc-cloned / deps / grpc / third_party / abseil-cpp / absl / random / internal / uniform_helper.h
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_UNIFORM_HELPER_H_
16 #define ABSL_RANDOM_UNIFORM_HELPER_H_
17
18 #include <cmath>
19 #include <limits>
20 #include <type_traits>
21
22 #include "absl/meta/type_traits.h"
23
24 namespace absl {
25 template <typename IntType>
26 class uniform_int_distribution;
27
28 template <typename RealType>
29 class uniform_real_distribution;
30
31 // Interval tag types which specify whether the interval is open or closed
32 // on either boundary.
33 namespace random_internal {
34 struct IntervalClosedClosedT {};
35 struct IntervalClosedOpenT {};
36 struct IntervalOpenClosedT {};
37 struct IntervalOpenOpenT {};
38 }  // namespace random_internal
39
40 namespace random_internal {
41
42 // The functions
43 //    uniform_lower_bound(tag, a, b)
44 // and
45 //    uniform_upper_bound(tag, a, b)
46 // are used as implementation-details for absl::Uniform().
47 //
48 // Conceptually,
49 //    [a, b] == [uniform_lower_bound(IntervalClosedClosed, a, b),
50 //               uniform_upper_bound(IntervalClosedClosed, a, b)]
51 //    (a, b) == [uniform_lower_bound(IntervalOpenOpen, a, b),
52 //               uniform_upper_bound(IntervalOpenOpen, a, b)]
53 //    [a, b) == [uniform_lower_bound(IntervalClosedOpen, a, b),
54 //               uniform_upper_bound(IntervalClosedOpen, a, b)]
55 //    (a, b] == [uniform_lower_bound(IntervalOpenClosed, a, b),
56 //               uniform_upper_bound(IntervalOpenClosed, a, b)]
57 //
58 template <typename IntType, typename Tag>
59 typename absl::enable_if_t<
60     absl::conjunction<
61         std::is_integral<IntType>,
62         absl::disjunction<std::is_same<Tag, IntervalOpenClosedT>,
63                           std::is_same<Tag, IntervalOpenOpenT>>>::value,
64     IntType>
65 uniform_lower_bound(Tag, IntType a, IntType) {
66   return a + 1;
67 }
68
69 template <typename FloatType, typename Tag>
70 typename absl::enable_if_t<
71     absl::conjunction<
72         std::is_floating_point<FloatType>,
73         absl::disjunction<std::is_same<Tag, IntervalOpenClosedT>,
74                           std::is_same<Tag, IntervalOpenOpenT>>>::value,
75     FloatType>
76 uniform_lower_bound(Tag, FloatType a, FloatType b) {
77   return std::nextafter(a, b);
78 }
79
80 template <typename NumType, typename Tag>
81 typename absl::enable_if_t<
82     absl::disjunction<std::is_same<Tag, IntervalClosedClosedT>,
83                       std::is_same<Tag, IntervalClosedOpenT>>::value,
84     NumType>
85 uniform_lower_bound(Tag, NumType a, NumType) {
86   return a;
87 }
88
89 template <typename IntType, typename Tag>
90 typename absl::enable_if_t<
91     absl::conjunction<
92         std::is_integral<IntType>,
93         absl::disjunction<std::is_same<Tag, IntervalClosedOpenT>,
94                           std::is_same<Tag, IntervalOpenOpenT>>>::value,
95     IntType>
96 uniform_upper_bound(Tag, IntType, IntType b) {
97   return b - 1;
98 }
99
100 template <typename FloatType, typename Tag>
101 typename absl::enable_if_t<
102     absl::conjunction<
103         std::is_floating_point<FloatType>,
104         absl::disjunction<std::is_same<Tag, IntervalClosedOpenT>,
105                           std::is_same<Tag, IntervalOpenOpenT>>>::value,
106     FloatType>
107 uniform_upper_bound(Tag, FloatType, FloatType b) {
108   return b;
109 }
110
111 template <typename IntType, typename Tag>
112 typename absl::enable_if_t<
113     absl::conjunction<
114         std::is_integral<IntType>,
115         absl::disjunction<std::is_same<Tag, IntervalClosedClosedT>,
116                           std::is_same<Tag, IntervalOpenClosedT>>>::value,
117     IntType>
118 uniform_upper_bound(Tag, IntType, IntType b) {
119   return b;
120 }
121
122 template <typename FloatType, typename Tag>
123 typename absl::enable_if_t<
124     absl::conjunction<
125         std::is_floating_point<FloatType>,
126         absl::disjunction<std::is_same<Tag, IntervalClosedClosedT>,
127                           std::is_same<Tag, IntervalOpenClosedT>>>::value,
128     FloatType>
129 uniform_upper_bound(Tag, FloatType, FloatType b) {
130   return std::nextafter(b, (std::numeric_limits<FloatType>::max)());
131 }
132
133 template <typename NumType>
134 using UniformDistribution =
135     typename std::conditional<std::is_integral<NumType>::value,
136                               absl::uniform_int_distribution<NumType>,
137                               absl::uniform_real_distribution<NumType>>::type;
138
139 template <typename TagType, typename NumType>
140 struct UniformDistributionWrapper : public UniformDistribution<NumType> {
141   explicit UniformDistributionWrapper(NumType lo, NumType hi)
142       : UniformDistribution<NumType>(
143             uniform_lower_bound<NumType>(TagType{}, lo, hi),
144             uniform_upper_bound<NumType>(TagType{}, lo, hi)) {}
145 };
146
147 }  // namespace random_internal
148 }  // namespace absl
149
150 #endif  // ABSL_RANDOM_UNIFORM_HELPER_H_