1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
6*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
7*6777b538SAndroid Build Coastguard Worker
8*6777b538SAndroid Build Coastguard Worker #include <limits>
9*6777b538SAndroid Build Coastguard Worker #include <type_traits>
10*6777b538SAndroid Build Coastguard Worker
11*6777b538SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
12*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
13*6777b538SAndroid Build Coastguard Worker
14*6777b538SAndroid Build Coastguard Worker // WARNING: This block must come before the base/numerics headers are included.
15*6777b538SAndroid Build Coastguard Worker // These tests deliberately cause arithmetic boundary errors. If the compiler is
16*6777b538SAndroid Build Coastguard Worker // aggressive enough, it can const detect these errors, so we disable warnings.
17*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
18*6777b538SAndroid Build Coastguard Worker #pragma warning(disable : 4756) // Arithmetic overflow.
19*6777b538SAndroid Build Coastguard Worker #pragma warning(disable : 4293) // Invalid shift.
20*6777b538SAndroid Build Coastguard Worker #endif
21*6777b538SAndroid Build Coastguard Worker
22*6777b538SAndroid Build Coastguard Worker // This may not need to come before the base/numerics headers, but let's keep
23*6777b538SAndroid Build Coastguard Worker // it close to the MSVC equivalent.
24*6777b538SAndroid Build Coastguard Worker #if defined(__clang__)
25*6777b538SAndroid Build Coastguard Worker #pragma clang diagnostic push
26*6777b538SAndroid Build Coastguard Worker #pragma clang diagnostic ignored "-Winteger-overflow"
27*6777b538SAndroid Build Coastguard Worker #endif
28*6777b538SAndroid Build Coastguard Worker
29*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
30*6777b538SAndroid Build Coastguard Worker #include "base/numerics/safe_conversions.h"
31*6777b538SAndroid Build Coastguard Worker #include "base/numerics/safe_math.h"
32*6777b538SAndroid Build Coastguard Worker #include "base/numerics/wrapping_math.h"
33*6777b538SAndroid Build Coastguard Worker #include "base/test/gtest_util.h"
34*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
35*6777b538SAndroid Build Coastguard Worker
36*6777b538SAndroid Build Coastguard Worker #if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS)
37*6777b538SAndroid Build Coastguard Worker #include <mmintrin.h>
38*6777b538SAndroid Build Coastguard Worker #endif
39*6777b538SAndroid Build Coastguard Worker
40*6777b538SAndroid Build Coastguard Worker namespace base {
41*6777b538SAndroid Build Coastguard Worker namespace internal {
42*6777b538SAndroid Build Coastguard Worker
43*6777b538SAndroid Build Coastguard Worker using std::numeric_limits;
44*6777b538SAndroid Build Coastguard Worker
45*6777b538SAndroid Build Coastguard Worker // This is a helper function for finding the maximum value in Src that can be
46*6777b538SAndroid Build Coastguard Worker // wholy represented as the destination floating-point type.
47*6777b538SAndroid Build Coastguard Worker template <typename Dst, typename Src>
GetMaxConvertibleToFloat()48*6777b538SAndroid Build Coastguard Worker Dst GetMaxConvertibleToFloat() {
49*6777b538SAndroid Build Coastguard Worker using DstLimits = numeric_limits<Dst>;
50*6777b538SAndroid Build Coastguard Worker using SrcLimits = numeric_limits<Src>;
51*6777b538SAndroid Build Coastguard Worker static_assert(SrcLimits::is_specialized, "Source must be numeric.");
52*6777b538SAndroid Build Coastguard Worker static_assert(DstLimits::is_specialized, "Destination must be numeric.");
53*6777b538SAndroid Build Coastguard Worker CHECK(DstLimits::is_iec559);
54*6777b538SAndroid Build Coastguard Worker
55*6777b538SAndroid Build Coastguard Worker if (SrcLimits::digits <= DstLimits::digits &&
56*6777b538SAndroid Build Coastguard Worker MaxExponent<Src>::value <= MaxExponent<Dst>::value)
57*6777b538SAndroid Build Coastguard Worker return SrcLimits::max();
58*6777b538SAndroid Build Coastguard Worker Src max = SrcLimits::max() / 2 + (SrcLimits::is_integer ? 1 : 0);
59*6777b538SAndroid Build Coastguard Worker while (max != static_cast<Src>(static_cast<Dst>(max))) {
60*6777b538SAndroid Build Coastguard Worker max /= 2;
61*6777b538SAndroid Build Coastguard Worker }
62*6777b538SAndroid Build Coastguard Worker return static_cast<Dst>(max);
63*6777b538SAndroid Build Coastguard Worker }
64*6777b538SAndroid Build Coastguard Worker
65*6777b538SAndroid Build Coastguard Worker // Test corner case promotions used
66*6777b538SAndroid Build Coastguard Worker static_assert(IsIntegerArithmeticSafe<int32_t, int8_t, int8_t>::value, "");
67*6777b538SAndroid Build Coastguard Worker static_assert(IsIntegerArithmeticSafe<int32_t, int16_t, int8_t>::value, "");
68*6777b538SAndroid Build Coastguard Worker static_assert(IsIntegerArithmeticSafe<int32_t, int8_t, int16_t>::value, "");
69*6777b538SAndroid Build Coastguard Worker static_assert(!IsIntegerArithmeticSafe<int32_t, int32_t, int8_t>::value, "");
70*6777b538SAndroid Build Coastguard Worker static_assert(BigEnoughPromotion<int16_t, int8_t>::is_contained, "");
71*6777b538SAndroid Build Coastguard Worker static_assert(BigEnoughPromotion<int32_t, uint32_t>::is_contained, "");
72*6777b538SAndroid Build Coastguard Worker static_assert(BigEnoughPromotion<intmax_t, int8_t>::is_contained, "");
73*6777b538SAndroid Build Coastguard Worker static_assert(!BigEnoughPromotion<uintmax_t, int8_t>::is_contained, "");
74*6777b538SAndroid Build Coastguard Worker static_assert(
75*6777b538SAndroid Build Coastguard Worker std::is_same_v<BigEnoughPromotion<int16_t, int8_t>::type, int16_t>,
76*6777b538SAndroid Build Coastguard Worker "");
77*6777b538SAndroid Build Coastguard Worker static_assert(
78*6777b538SAndroid Build Coastguard Worker std::is_same_v<BigEnoughPromotion<int32_t, uint32_t>::type, int64_t>,
79*6777b538SAndroid Build Coastguard Worker "");
80*6777b538SAndroid Build Coastguard Worker static_assert(
81*6777b538SAndroid Build Coastguard Worker std::is_same_v<BigEnoughPromotion<intmax_t, int8_t>::type, intmax_t>,
82*6777b538SAndroid Build Coastguard Worker "");
83*6777b538SAndroid Build Coastguard Worker static_assert(
84*6777b538SAndroid Build Coastguard Worker std::is_same_v<BigEnoughPromotion<uintmax_t, int8_t>::type, uintmax_t>,
85*6777b538SAndroid Build Coastguard Worker "");
86*6777b538SAndroid Build Coastguard Worker static_assert(BigEnoughPromotion<int16_t, int8_t>::is_contained, "");
87*6777b538SAndroid Build Coastguard Worker static_assert(BigEnoughPromotion<int32_t, uint32_t>::is_contained, "");
88*6777b538SAndroid Build Coastguard Worker static_assert(BigEnoughPromotion<intmax_t, int8_t>::is_contained, "");
89*6777b538SAndroid Build Coastguard Worker static_assert(!BigEnoughPromotion<uintmax_t, int8_t>::is_contained, "");
90*6777b538SAndroid Build Coastguard Worker static_assert(
91*6777b538SAndroid Build Coastguard Worker std::is_same_v<FastIntegerArithmeticPromotion<int16_t, int8_t>::type,
92*6777b538SAndroid Build Coastguard Worker int32_t>,
93*6777b538SAndroid Build Coastguard Worker "");
94*6777b538SAndroid Build Coastguard Worker static_assert(
95*6777b538SAndroid Build Coastguard Worker std::is_same_v<FastIntegerArithmeticPromotion<int32_t, uint32_t>::type,
96*6777b538SAndroid Build Coastguard Worker int64_t>,
97*6777b538SAndroid Build Coastguard Worker "");
98*6777b538SAndroid Build Coastguard Worker static_assert(
99*6777b538SAndroid Build Coastguard Worker std::is_same_v<FastIntegerArithmeticPromotion<intmax_t, int8_t>::type,
100*6777b538SAndroid Build Coastguard Worker intmax_t>,
101*6777b538SAndroid Build Coastguard Worker "");
102*6777b538SAndroid Build Coastguard Worker static_assert(
103*6777b538SAndroid Build Coastguard Worker std::is_same_v<FastIntegerArithmeticPromotion<uintmax_t, int8_t>::type,
104*6777b538SAndroid Build Coastguard Worker uintmax_t>,
105*6777b538SAndroid Build Coastguard Worker "");
106*6777b538SAndroid Build Coastguard Worker static_assert(FastIntegerArithmeticPromotion<int16_t, int8_t>::is_contained,
107*6777b538SAndroid Build Coastguard Worker "");
108*6777b538SAndroid Build Coastguard Worker static_assert(FastIntegerArithmeticPromotion<int32_t, uint32_t>::is_contained,
109*6777b538SAndroid Build Coastguard Worker "");
110*6777b538SAndroid Build Coastguard Worker static_assert(!FastIntegerArithmeticPromotion<intmax_t, int8_t>::is_contained,
111*6777b538SAndroid Build Coastguard Worker "");
112*6777b538SAndroid Build Coastguard Worker static_assert(!FastIntegerArithmeticPromotion<uintmax_t, int8_t>::is_contained,
113*6777b538SAndroid Build Coastguard Worker "");
114*6777b538SAndroid Build Coastguard Worker
115*6777b538SAndroid Build Coastguard Worker // Test compile-time (constexpr) evaluation of checking and saturation.
116*6777b538SAndroid Build Coastguard Worker constexpr int32_t kIntOne = 1;
117*6777b538SAndroid Build Coastguard Worker static_assert(1 == checked_cast<uint8_t>(kIntOne), "");
118*6777b538SAndroid Build Coastguard Worker static_assert(1 == saturated_cast<uint8_t>(kIntOne), "");
119*6777b538SAndroid Build Coastguard Worker static_assert(2U == MakeClampedNum(kIntOne) + 1, "");
120*6777b538SAndroid Build Coastguard Worker static_assert(2U == (MakeCheckedNum(kIntOne) + 1).ValueOrDie(), "");
121*6777b538SAndroid Build Coastguard Worker static_assert(0U == MakeClampedNum(kIntOne) - 1, "");
122*6777b538SAndroid Build Coastguard Worker static_assert(0U == (MakeCheckedNum(kIntOne) - 1).ValueOrDie(), "");
123*6777b538SAndroid Build Coastguard Worker static_assert(-1 == -MakeClampedNum(kIntOne), "");
124*6777b538SAndroid Build Coastguard Worker static_assert(-1 == (-MakeCheckedNum(kIntOne)).ValueOrDie(), "");
125*6777b538SAndroid Build Coastguard Worker static_assert(1U == MakeClampedNum(kIntOne) * 1, "");
126*6777b538SAndroid Build Coastguard Worker static_assert(1U == (MakeCheckedNum(kIntOne) * 1).ValueOrDie(), "");
127*6777b538SAndroid Build Coastguard Worker static_assert(1U == MakeClampedNum(kIntOne) / 1, "");
128*6777b538SAndroid Build Coastguard Worker static_assert(1U == (MakeCheckedNum(kIntOne) / 1).ValueOrDie(), "");
129*6777b538SAndroid Build Coastguard Worker static_assert(1 == MakeClampedNum(-kIntOne).Abs(), "");
130*6777b538SAndroid Build Coastguard Worker static_assert(1 == MakeCheckedNum(-kIntOne).Abs().ValueOrDie(), "");
131*6777b538SAndroid Build Coastguard Worker static_assert(1U == MakeClampedNum(kIntOne) % 2, "");
132*6777b538SAndroid Build Coastguard Worker static_assert(1U == (MakeCheckedNum(kIntOne) % 2).ValueOrDie(), "");
133*6777b538SAndroid Build Coastguard Worker static_assert(0U == MakeClampedNum(kIntOne) >> 1U, "");
134*6777b538SAndroid Build Coastguard Worker static_assert(0U == (MakeCheckedNum(kIntOne) >> 1U).ValueOrDie(), "");
135*6777b538SAndroid Build Coastguard Worker static_assert(2U == MakeClampedNum(kIntOne) << 1U, "");
136*6777b538SAndroid Build Coastguard Worker static_assert(2U == (MakeCheckedNum(kIntOne) << 1U).ValueOrDie(), "");
137*6777b538SAndroid Build Coastguard Worker static_assert(1 == MakeClampedNum(kIntOne) & 1U, "");
138*6777b538SAndroid Build Coastguard Worker static_assert(1 == (MakeCheckedNum(kIntOne) & 1U).ValueOrDie(), "");
139*6777b538SAndroid Build Coastguard Worker static_assert(1 == MakeClampedNum(kIntOne) | 1U, "");
140*6777b538SAndroid Build Coastguard Worker static_assert(1 == (MakeCheckedNum(kIntOne) | 1U).ValueOrDie(), "");
141*6777b538SAndroid Build Coastguard Worker static_assert(0 == MakeClampedNum(kIntOne) ^ 1U, "");
142*6777b538SAndroid Build Coastguard Worker static_assert(0 == (MakeCheckedNum(kIntOne) ^ 1U).ValueOrDie(), "");
143*6777b538SAndroid Build Coastguard Worker constexpr float kFloatOne = 1.0;
144*6777b538SAndroid Build Coastguard Worker static_assert(1 == int{checked_cast<int8_t>(kFloatOne)}, "");
145*6777b538SAndroid Build Coastguard Worker static_assert(1 == int{saturated_cast<int8_t>(kFloatOne)}, "");
146*6777b538SAndroid Build Coastguard Worker static_assert(2U == unsigned{MakeClampedNum(kFloatOne) + 1}, "");
147*6777b538SAndroid Build Coastguard Worker static_assert(2U ==
148*6777b538SAndroid Build Coastguard Worker (MakeCheckedNum(kFloatOne) + 1).Cast<unsigned>().ValueOrDie(),
149*6777b538SAndroid Build Coastguard Worker "");
150*6777b538SAndroid Build Coastguard Worker static_assert(0U == unsigned{MakeClampedNum(kFloatOne) - 1}, "");
151*6777b538SAndroid Build Coastguard Worker static_assert(0U ==
152*6777b538SAndroid Build Coastguard Worker (MakeCheckedNum(kFloatOne) - 1).Cast<unsigned>().ValueOrDie(),
153*6777b538SAndroid Build Coastguard Worker "");
154*6777b538SAndroid Build Coastguard Worker static_assert(-1 == int{-MakeClampedNum(kFloatOne)}, "");
155*6777b538SAndroid Build Coastguard Worker static_assert(-1 == (-MakeCheckedNum(kFloatOne)).Cast<int>().ValueOrDie(), "");
156*6777b538SAndroid Build Coastguard Worker static_assert(1U == unsigned{MakeClampedNum(kFloatOne) * 1}, "");
157*6777b538SAndroid Build Coastguard Worker static_assert(1U ==
158*6777b538SAndroid Build Coastguard Worker (MakeCheckedNum(kFloatOne) * 1).Cast<unsigned>().ValueOrDie(),
159*6777b538SAndroid Build Coastguard Worker "");
160*6777b538SAndroid Build Coastguard Worker static_assert(1U == unsigned{MakeClampedNum(kFloatOne) / 1}, "");
161*6777b538SAndroid Build Coastguard Worker static_assert(1U ==
162*6777b538SAndroid Build Coastguard Worker (MakeCheckedNum(kFloatOne) / 1).Cast<unsigned>().ValueOrDie(),
163*6777b538SAndroid Build Coastguard Worker "");
164*6777b538SAndroid Build Coastguard Worker static_assert(1 == int{MakeClampedNum(-kFloatOne).Abs()}, "");
165*6777b538SAndroid Build Coastguard Worker static_assert(1 == MakeCheckedNum(-kFloatOne).Abs().Cast<int>().ValueOrDie(),
166*6777b538SAndroid Build Coastguard Worker "");
167*6777b538SAndroid Build Coastguard Worker
168*6777b538SAndroid Build Coastguard Worker template <typename U>
GetNumericValueForTest(const CheckedNumeric<U> & src)169*6777b538SAndroid Build Coastguard Worker U GetNumericValueForTest(const CheckedNumeric<U>& src) {
170*6777b538SAndroid Build Coastguard Worker return src.state_.value();
171*6777b538SAndroid Build Coastguard Worker }
172*6777b538SAndroid Build Coastguard Worker
173*6777b538SAndroid Build Coastguard Worker template <typename U>
GetNumericValueForTest(const ClampedNumeric<U> & src)174*6777b538SAndroid Build Coastguard Worker U GetNumericValueForTest(const ClampedNumeric<U>& src) {
175*6777b538SAndroid Build Coastguard Worker return static_cast<U>(src);
176*6777b538SAndroid Build Coastguard Worker }
177*6777b538SAndroid Build Coastguard Worker
178*6777b538SAndroid Build Coastguard Worker template <typename U>
GetNumericValueForTest(const U & src)179*6777b538SAndroid Build Coastguard Worker U GetNumericValueForTest(const U& src) {
180*6777b538SAndroid Build Coastguard Worker return src;
181*6777b538SAndroid Build Coastguard Worker }
182*6777b538SAndroid Build Coastguard Worker
183*6777b538SAndroid Build Coastguard Worker // Logs the ValueOrDie() failure instead of crashing.
184*6777b538SAndroid Build Coastguard Worker struct LogOnFailure {
185*6777b538SAndroid Build Coastguard Worker template <typename T>
HandleFailurebase::internal::LogOnFailure186*6777b538SAndroid Build Coastguard Worker static T HandleFailure() {
187*6777b538SAndroid Build Coastguard Worker LOG(WARNING) << "ValueOrDie() failed unexpectedly.";
188*6777b538SAndroid Build Coastguard Worker return T();
189*6777b538SAndroid Build Coastguard Worker }
190*6777b538SAndroid Build Coastguard Worker };
191*6777b538SAndroid Build Coastguard Worker
192*6777b538SAndroid Build Coastguard Worker template <typename T>
GetValue(const T & src)193*6777b538SAndroid Build Coastguard Worker constexpr T GetValue(const T& src) {
194*6777b538SAndroid Build Coastguard Worker return src;
195*6777b538SAndroid Build Coastguard Worker }
196*6777b538SAndroid Build Coastguard Worker
197*6777b538SAndroid Build Coastguard Worker template <typename T, typename U>
GetValueAsDest(const U & src)198*6777b538SAndroid Build Coastguard Worker constexpr T GetValueAsDest(const U& src) {
199*6777b538SAndroid Build Coastguard Worker return static_cast<T>(src);
200*6777b538SAndroid Build Coastguard Worker }
201*6777b538SAndroid Build Coastguard Worker
202*6777b538SAndroid Build Coastguard Worker template <typename T>
GetValue(const CheckedNumeric<T> & src)203*6777b538SAndroid Build Coastguard Worker constexpr T GetValue(const CheckedNumeric<T>& src) {
204*6777b538SAndroid Build Coastguard Worker return src.template ValueOrDie<T, LogOnFailure>();
205*6777b538SAndroid Build Coastguard Worker }
206*6777b538SAndroid Build Coastguard Worker
207*6777b538SAndroid Build Coastguard Worker template <typename T, typename U>
GetValueAsDest(const CheckedNumeric<U> & src)208*6777b538SAndroid Build Coastguard Worker constexpr T GetValueAsDest(const CheckedNumeric<U>& src) {
209*6777b538SAndroid Build Coastguard Worker return src.template ValueOrDie<T, LogOnFailure>();
210*6777b538SAndroid Build Coastguard Worker }
211*6777b538SAndroid Build Coastguard Worker
212*6777b538SAndroid Build Coastguard Worker template <typename T>
GetValue(const ClampedNumeric<T> & src)213*6777b538SAndroid Build Coastguard Worker constexpr T GetValue(const ClampedNumeric<T>& src) {
214*6777b538SAndroid Build Coastguard Worker return static_cast<T>(src);
215*6777b538SAndroid Build Coastguard Worker }
216*6777b538SAndroid Build Coastguard Worker
217*6777b538SAndroid Build Coastguard Worker template <typename T, typename U>
GetValueAsDest(const ClampedNumeric<U> & src)218*6777b538SAndroid Build Coastguard Worker constexpr T GetValueAsDest(const ClampedNumeric<U>& src) {
219*6777b538SAndroid Build Coastguard Worker return static_cast<T>(src);
220*6777b538SAndroid Build Coastguard Worker }
221*6777b538SAndroid Build Coastguard Worker
222*6777b538SAndroid Build Coastguard Worker // Helper macros to wrap displaying the conversion types and line numbers.
223*6777b538SAndroid Build Coastguard Worker #define TEST_EXPECTED_VALIDITY(expected, actual) \
224*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(expected, (actual).template Cast<Dst>().IsValid()) \
225*6777b538SAndroid Build Coastguard Worker << "Result test: Value " << GetNumericValueForTest(actual) << " as " \
226*6777b538SAndroid Build Coastguard Worker << dst << " on line " << line
227*6777b538SAndroid Build Coastguard Worker
228*6777b538SAndroid Build Coastguard Worker #define TEST_EXPECTED_SUCCESS(actual) TEST_EXPECTED_VALIDITY(true, actual)
229*6777b538SAndroid Build Coastguard Worker #define TEST_EXPECTED_FAILURE(actual) TEST_EXPECTED_VALIDITY(false, actual)
230*6777b538SAndroid Build Coastguard Worker
231*6777b538SAndroid Build Coastguard Worker // We have to handle promotions, so infer the underlying type below from actual.
232*6777b538SAndroid Build Coastguard Worker #define TEST_EXPECTED_VALUE(expected, actual) \
233*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(GetValue(expected), GetValueAsDest<decltype(expected)>(actual)) \
234*6777b538SAndroid Build Coastguard Worker << "Result test: Value " << GetNumericValueForTest(actual) << " as " \
235*6777b538SAndroid Build Coastguard Worker << dst << " on line " << line
236*6777b538SAndroid Build Coastguard Worker
237*6777b538SAndroid Build Coastguard Worker // Test the simple pointer arithmetic overrides.
238*6777b538SAndroid Build Coastguard Worker template <typename Dst>
TestStrictPointerMath()239*6777b538SAndroid Build Coastguard Worker void TestStrictPointerMath() {
240*6777b538SAndroid Build Coastguard Worker Dst dummy_value = 0;
241*6777b538SAndroid Build Coastguard Worker Dst* dummy_ptr = &dummy_value;
242*6777b538SAndroid Build Coastguard Worker static const Dst kDummyOffset = 2; // Don't want to go too far.
243*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(dummy_ptr + kDummyOffset,
244*6777b538SAndroid Build Coastguard Worker dummy_ptr + StrictNumeric<Dst>(kDummyOffset));
245*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(dummy_ptr - kDummyOffset,
246*6777b538SAndroid Build Coastguard Worker dummy_ptr - StrictNumeric<Dst>(kDummyOffset));
247*6777b538SAndroid Build Coastguard Worker EXPECT_NE(dummy_ptr, dummy_ptr + StrictNumeric<Dst>(kDummyOffset));
248*6777b538SAndroid Build Coastguard Worker EXPECT_NE(dummy_ptr, dummy_ptr - StrictNumeric<Dst>(kDummyOffset));
249*6777b538SAndroid Build Coastguard Worker EXPECT_DEATH_IF_SUPPORTED(
250*6777b538SAndroid Build Coastguard Worker dummy_ptr + StrictNumeric<size_t>(std::numeric_limits<size_t>::max()),
251*6777b538SAndroid Build Coastguard Worker "");
252*6777b538SAndroid Build Coastguard Worker }
253*6777b538SAndroid Build Coastguard Worker
254*6777b538SAndroid Build Coastguard Worker // Signed integer arithmetic.
255*6777b538SAndroid Build Coastguard Worker template <typename Dst>
TestSpecializedArithmetic(const char * dst,int line,std::enable_if_t<numeric_limits<Dst>::is_integer && numeric_limits<Dst>::is_signed,int>=0)256*6777b538SAndroid Build Coastguard Worker static void TestSpecializedArithmetic(
257*6777b538SAndroid Build Coastguard Worker const char* dst,
258*6777b538SAndroid Build Coastguard Worker int line,
259*6777b538SAndroid Build Coastguard Worker std::enable_if_t<numeric_limits<Dst>::is_integer &&
260*6777b538SAndroid Build Coastguard Worker numeric_limits<Dst>::is_signed,
261*6777b538SAndroid Build Coastguard Worker int> = 0) {
262*6777b538SAndroid Build Coastguard Worker using DstLimits = SaturationDefaultLimits<Dst>;
263*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(-CheckedNumeric<Dst>(DstLimits::lowest()));
264*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()).Abs());
265*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
266*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(),
267*6777b538SAndroid Build Coastguard Worker MakeCheckedNum(-DstLimits::max()).Abs());
268*6777b538SAndroid Build Coastguard Worker
269*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(),
270*6777b538SAndroid Build Coastguard Worker -ClampedNumeric<Dst>(DstLimits::lowest()));
271*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(),
272*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()).Abs());
273*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(-1).Abs());
274*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(),
275*6777b538SAndroid Build Coastguard Worker MakeClampedNum(-DstLimits::max()).Abs());
276*6777b538SAndroid Build Coastguard Worker
277*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + -1);
278*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) + -1);
279*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) +
280*6777b538SAndroid Build Coastguard Worker DstLimits::lowest());
281*6777b538SAndroid Build Coastguard Worker
282*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max() - 1,
283*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::max()) + -1);
284*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Underflow(),
285*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()) + -1);
286*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
287*6777b538SAndroid Build Coastguard Worker DstLimits::Underflow(),
288*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()) + DstLimits::lowest());
289*6777b538SAndroid Build Coastguard Worker
290*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) - 1);
291*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) - -1);
292*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) -
293*6777b538SAndroid Build Coastguard Worker DstLimits::lowest());
294*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) -
295*6777b538SAndroid Build Coastguard Worker DstLimits::max());
296*6777b538SAndroid Build Coastguard Worker
297*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Underflow(),
298*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()) - 1);
299*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::lowest() + 1,
300*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()) - -1);
301*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
302*6777b538SAndroid Build Coastguard Worker DstLimits::Overflow(),
303*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::max()) - DstLimits::lowest());
304*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
305*6777b538SAndroid Build Coastguard Worker DstLimits::Underflow(),
306*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()) - DstLimits::max());
307*6777b538SAndroid Build Coastguard Worker
308*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * 2);
309*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Underflow(),
310*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()) * 2);
311*6777b538SAndroid Build Coastguard Worker
312*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) / -1);
313*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) / 2);
314*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * -1);
315*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(),
316*6777b538SAndroid Build Coastguard Worker CheckedNumeric<Dst>(DstLimits::lowest() + 1) * Dst(-1));
317*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(),
318*6777b538SAndroid Build Coastguard Worker CheckedNumeric<Dst>(-1) * Dst(DstLimits::lowest() + 1));
319*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::lowest(),
320*6777b538SAndroid Build Coastguard Worker CheckedNumeric<Dst>(DstLimits::lowest()) * Dst(1));
321*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::lowest(),
322*6777b538SAndroid Build Coastguard Worker CheckedNumeric<Dst>(1) * Dst(DstLimits::lowest()));
323*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
324*6777b538SAndroid Build Coastguard Worker typename std::make_unsigned<Dst>::type(0) - DstLimits::lowest(),
325*6777b538SAndroid Build Coastguard Worker MakeCheckedNum(DstLimits::lowest()).UnsignedAbs());
326*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(),
327*6777b538SAndroid Build Coastguard Worker MakeCheckedNum(DstLimits::max()).UnsignedAbs());
328*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0).UnsignedAbs());
329*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).UnsignedAbs());
330*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).UnsignedAbs());
331*6777b538SAndroid Build Coastguard Worker
332*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(),
333*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()) / -1);
334*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(-1) / 2);
335*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(),
336*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()) * -1);
337*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(),
338*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest() + 1) * Dst(-1));
339*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(),
340*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(-1) * Dst(DstLimits::lowest() + 1));
341*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::lowest(),
342*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()) * Dst(1));
343*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::lowest(),
344*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(1) * Dst(DstLimits::lowest()));
345*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
346*6777b538SAndroid Build Coastguard Worker typename std::make_unsigned<Dst>::type(0) - DstLimits::lowest(),
347*6777b538SAndroid Build Coastguard Worker MakeClampedNum(DstLimits::lowest()).UnsignedAbs());
348*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(),
349*6777b538SAndroid Build Coastguard Worker MakeClampedNum(DstLimits::max()).UnsignedAbs());
350*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0).UnsignedAbs());
351*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1).UnsignedAbs());
352*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(-1).UnsignedAbs());
353*6777b538SAndroid Build Coastguard Worker
354*6777b538SAndroid Build Coastguard Worker // Modulus is legal only for integers.
355*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) % 2);
356*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) % 1);
357*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) % -1);
358*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) % -2);
359*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2);
360*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
361*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % -1);
362*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % -2);
363*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % 2);
364*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) % 1);
365*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) % -1);
366*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % -2);
367*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % 2);
368*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % 1);
369*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % -1);
370*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % -2);
371*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2);
372*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::max()) % 1);
373*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::max()) % -1);
374*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % -2);
375*6777b538SAndroid Build Coastguard Worker // Test all the different modulus combinations.
376*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1));
377*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1));
378*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
379*6777b538SAndroid Build Coastguard Worker CheckedNumeric<Dst> checked_dst = 1;
380*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, checked_dst %= 1);
381*6777b538SAndroid Build Coastguard Worker // Test that div by 0 is avoided but returns invalid result.
382*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) % 0);
383*6777b538SAndroid Build Coastguard Worker // Test bit shifts.
384*6777b538SAndroid Build Coastguard Worker volatile Dst negative_one = -1;
385*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) << negative_one);
386*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1)
387*6777b538SAndroid Build Coastguard Worker << (IntegerBitsPlusSign<Dst>::value - 1));
388*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(0)
389*6777b538SAndroid Build Coastguard Worker << IntegerBitsPlusSign<Dst>::value);
390*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) << 1);
391*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
392*6777b538SAndroid Build Coastguard Worker static_cast<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 2),
393*6777b538SAndroid Build Coastguard Worker CheckedNumeric<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 2));
394*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0)
395*6777b538SAndroid Build Coastguard Worker << (IntegerBitsPlusSign<Dst>::value - 1));
396*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) << 0);
397*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) << 1);
398*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >>
399*6777b538SAndroid Build Coastguard Worker IntegerBitsPlusSign<Dst>::value);
400*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
401*6777b538SAndroid Build Coastguard Worker 0, CheckedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value - 1));
402*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >> negative_one);
403*6777b538SAndroid Build Coastguard Worker
404*6777b538SAndroid Build Coastguard Worker // Modulus is legal only for integers.
405*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) % 2);
406*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) % 1);
407*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) % -1);
408*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) % -2);
409*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) % 2);
410*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
411*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % -1);
412*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) % -2);
413*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-1, ClampedNumeric<Dst>(-1) % 2);
414*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(-1) % 1);
415*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(-1) % -1);
416*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-1, ClampedNumeric<Dst>(-1) % -2);
417*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % 2);
418*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % 1);
419*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % -1);
420*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % -2);
421*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(DstLimits::max()) % 2);
422*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::max()) % 1);
423*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::max()) % -1);
424*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(DstLimits::max()) % -2);
425*6777b538SAndroid Build Coastguard Worker // Test all the different modulus combinations.
426*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % ClampedNumeric<Dst>(1));
427*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, 1 % ClampedNumeric<Dst>(1));
428*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
429*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst> clamped_dst = 1;
430*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, clamped_dst %= 1);
431*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(Dst(1), ClampedNumeric<Dst>(1) % 0);
432*6777b538SAndroid Build Coastguard Worker // Test bit shifts.
433*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(),
434*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(1)
435*6777b538SAndroid Build Coastguard Worker << (IntegerBitsPlusSign<Dst>::value - 1U));
436*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(Dst(0), ClampedNumeric<Dst>(0)
437*6777b538SAndroid Build Coastguard Worker << (IntegerBitsPlusSign<Dst>::value + 0U));
438*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(),
439*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::max()) << 1U);
440*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
441*6777b538SAndroid Build Coastguard Worker static_cast<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 2U),
442*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 2U));
443*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0)
444*6777b538SAndroid Build Coastguard Worker << (IntegerBitsPlusSign<Dst>::value - 1U));
445*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) << 0U);
446*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) << 1U);
447*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
448*6777b538SAndroid Build Coastguard Worker 0, ClampedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value + 0U));
449*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
450*6777b538SAndroid Build Coastguard Worker 0, ClampedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value - 1U));
451*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
452*6777b538SAndroid Build Coastguard Worker -1, ClampedNumeric<Dst>(-1) >> (IntegerBitsPlusSign<Dst>::value - 1U));
453*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-1, ClampedNumeric<Dst>(DstLimits::lowest()) >>
454*6777b538SAndroid Build Coastguard Worker (IntegerBitsPlusSign<Dst>::value - 0U));
455*6777b538SAndroid Build Coastguard Worker
456*6777b538SAndroid Build Coastguard Worker TestStrictPointerMath<Dst>();
457*6777b538SAndroid Build Coastguard Worker }
458*6777b538SAndroid Build Coastguard Worker
459*6777b538SAndroid Build Coastguard Worker // Unsigned integer arithmetic.
460*6777b538SAndroid Build Coastguard Worker template <typename Dst>
TestSpecializedArithmetic(const char * dst,int line,std::enable_if_t<numeric_limits<Dst>::is_integer &&!numeric_limits<Dst>::is_signed,int>=0)461*6777b538SAndroid Build Coastguard Worker static void TestSpecializedArithmetic(
462*6777b538SAndroid Build Coastguard Worker const char* dst,
463*6777b538SAndroid Build Coastguard Worker int line,
464*6777b538SAndroid Build Coastguard Worker std::enable_if_t<numeric_limits<Dst>::is_integer &&
465*6777b538SAndroid Build Coastguard Worker !numeric_limits<Dst>::is_signed,
466*6777b538SAndroid Build Coastguard Worker int> = 0) {
467*6777b538SAndroid Build Coastguard Worker using DstLimits = SaturationDefaultLimits<Dst>;
468*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::lowest()));
469*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).Abs());
470*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) + -1);
471*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) - 1);
472*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) * 2);
473*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) / 2);
474*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).UnsignedAbs());
475*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_SUCCESS(
476*6777b538SAndroid Build Coastguard Worker CheckedNumeric<typename std::make_signed<Dst>::type>(
477*6777b538SAndroid Build Coastguard Worker std::numeric_limits<typename std::make_signed<Dst>::type>::lowest())
478*6777b538SAndroid Build Coastguard Worker .UnsignedAbs());
479*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::lowest(),
480*6777b538SAndroid Build Coastguard Worker MakeCheckedNum(DstLimits::lowest()).UnsignedAbs());
481*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(),
482*6777b538SAndroid Build Coastguard Worker MakeCheckedNum(DstLimits::max()).UnsignedAbs());
483*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0).UnsignedAbs());
484*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).UnsignedAbs());
485*6777b538SAndroid Build Coastguard Worker
486*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, -ClampedNumeric<Dst>(DstLimits::lowest()));
487*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()).Abs());
488*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Underflow(),
489*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()) + -1);
490*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Underflow(),
491*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()) - 1);
492*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) * 2);
493*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) / 2);
494*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0,
495*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()).UnsignedAbs());
496*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
497*6777b538SAndroid Build Coastguard Worker as_unsigned(
498*6777b538SAndroid Build Coastguard Worker std::numeric_limits<typename std::make_signed<Dst>::type>::lowest()),
499*6777b538SAndroid Build Coastguard Worker ClampedNumeric<typename std::make_signed<Dst>::type>(
500*6777b538SAndroid Build Coastguard Worker std::numeric_limits<typename std::make_signed<Dst>::type>::lowest())
501*6777b538SAndroid Build Coastguard Worker .UnsignedAbs());
502*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::lowest(),
503*6777b538SAndroid Build Coastguard Worker MakeClampedNum(DstLimits::lowest()).UnsignedAbs());
504*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(),
505*6777b538SAndroid Build Coastguard Worker MakeClampedNum(DstLimits::max()).UnsignedAbs());
506*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0).UnsignedAbs());
507*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1).UnsignedAbs());
508*6777b538SAndroid Build Coastguard Worker
509*6777b538SAndroid Build Coastguard Worker // Modulus is legal only for integers.
510*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);
511*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
512*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2);
513*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % 2);
514*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2);
515*6777b538SAndroid Build Coastguard Worker // Test all the different modulus combinations.
516*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1));
517*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1));
518*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
519*6777b538SAndroid Build Coastguard Worker CheckedNumeric<Dst> checked_dst = 1;
520*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, checked_dst %= 1);
521*6777b538SAndroid Build Coastguard Worker // Test that div by 0 is avoided but returns invalid result.
522*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) % 0);
523*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1)
524*6777b538SAndroid Build Coastguard Worker << IntegerBitsPlusSign<Dst>::value);
525*6777b538SAndroid Build Coastguard Worker // Test bit shifts.
526*6777b538SAndroid Build Coastguard Worker volatile int negative_one = -1;
527*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) << negative_one);
528*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1)
529*6777b538SAndroid Build Coastguard Worker << IntegerBitsPlusSign<Dst>::value);
530*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(0)
531*6777b538SAndroid Build Coastguard Worker << IntegerBitsPlusSign<Dst>::value);
532*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) << 1);
533*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
534*6777b538SAndroid Build Coastguard Worker static_cast<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 1),
535*6777b538SAndroid Build Coastguard Worker CheckedNumeric<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 1));
536*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) << 0);
537*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) << 1);
538*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >>
539*6777b538SAndroid Build Coastguard Worker IntegerBitsPlusSign<Dst>::value);
540*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
541*6777b538SAndroid Build Coastguard Worker 0, CheckedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value - 1));
542*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >> negative_one);
543*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) & 1);
544*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) & 0);
545*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) & 1);
546*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) & 0);
547*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
548*6777b538SAndroid Build Coastguard Worker MakeCheckedNum(DstLimits::max()) & -1);
549*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) | 1);
550*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) | 0);
551*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(0) | 1);
552*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) | 0);
553*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
554*6777b538SAndroid Build Coastguard Worker CheckedNumeric<Dst>(0) | static_cast<Dst>(-1));
555*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) ^ 1);
556*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) ^ 0);
557*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(0) ^ 1);
558*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) ^ 0);
559*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
560*6777b538SAndroid Build Coastguard Worker CheckedNumeric<Dst>(0) ^ static_cast<Dst>(-1));
561*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(), ~CheckedNumeric<Dst>(0));
562*6777b538SAndroid Build Coastguard Worker
563*6777b538SAndroid Build Coastguard Worker // Modulus is legal only for integers.
564*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>() % 1);
565*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
566*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) % 2);
567*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % 2);
568*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(DstLimits::max()) % 2);
569*6777b538SAndroid Build Coastguard Worker // Test all the different modulus combinations.
570*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % ClampedNumeric<Dst>(1));
571*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, 1 % ClampedNumeric<Dst>(1));
572*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
573*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst> clamped_dst = 1;
574*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, clamped_dst %= 1);
575*6777b538SAndroid Build Coastguard Worker // Test that div by 0 is avoided but returns invalid result.
576*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(Dst(1), ClampedNumeric<Dst>(1) % 0);
577*6777b538SAndroid Build Coastguard Worker // Test bit shifts.
578*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(),
579*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(1)
580*6777b538SAndroid Build Coastguard Worker << as_unsigned(IntegerBitsPlusSign<Dst>::value));
581*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(Dst(0), ClampedNumeric<Dst>(0) << as_unsigned(
582*6777b538SAndroid Build Coastguard Worker IntegerBitsPlusSign<Dst>::value));
583*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(),
584*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::max()) << 1U);
585*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
586*6777b538SAndroid Build Coastguard Worker static_cast<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 1U),
587*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 1U));
588*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) << 0U);
589*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) << 1U);
590*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) >>
591*6777b538SAndroid Build Coastguard Worker as_unsigned(IntegerBitsPlusSign<Dst>::value));
592*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
593*6777b538SAndroid Build Coastguard Worker 0, ClampedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value - 1U));
594*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) & 1);
595*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) & 0);
596*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) & 1);
597*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) & 0);
598*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
599*6777b538SAndroid Build Coastguard Worker MakeClampedNum(DstLimits::max()) & -1);
600*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) | 1);
601*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) | 0);
602*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(0) | 1);
603*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) | 0);
604*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
605*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(0) | static_cast<Dst>(-1));
606*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) ^ 1);
607*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) ^ 0);
608*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(0) ^ 1);
609*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) ^ 0);
610*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
611*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(0) ^ static_cast<Dst>(-1));
612*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(), ~ClampedNumeric<Dst>(0));
613*6777b538SAndroid Build Coastguard Worker
614*6777b538SAndroid Build Coastguard Worker TestStrictPointerMath<Dst>();
615*6777b538SAndroid Build Coastguard Worker }
616*6777b538SAndroid Build Coastguard Worker
617*6777b538SAndroid Build Coastguard Worker // Floating point arithmetic.
618*6777b538SAndroid Build Coastguard Worker template <typename Dst>
TestSpecializedArithmetic(const char * dst,int line,std::enable_if_t<numeric_limits<Dst>::is_iec559,int>=0)619*6777b538SAndroid Build Coastguard Worker void TestSpecializedArithmetic(
620*6777b538SAndroid Build Coastguard Worker const char* dst,
621*6777b538SAndroid Build Coastguard Worker int line,
622*6777b538SAndroid Build Coastguard Worker std::enable_if_t<numeric_limits<Dst>::is_iec559, int> = 0) {
623*6777b538SAndroid Build Coastguard Worker using DstLimits = SaturationDefaultLimits<Dst>;
624*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::lowest()));
625*6777b538SAndroid Build Coastguard Worker
626*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).Abs());
627*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
628*6777b538SAndroid Build Coastguard Worker
629*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) + -1);
630*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + 1);
631*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) +
632*6777b538SAndroid Build Coastguard Worker DstLimits::lowest());
633*6777b538SAndroid Build Coastguard Worker
634*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) -
635*6777b538SAndroid Build Coastguard Worker DstLimits::lowest());
636*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) -
637*6777b538SAndroid Build Coastguard Worker DstLimits::max());
638*6777b538SAndroid Build Coastguard Worker
639*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * 2);
640*6777b538SAndroid Build Coastguard Worker
641*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-0.5, CheckedNumeric<Dst>(-1.0) / 2);
642*6777b538SAndroid Build Coastguard Worker
643*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(),
644*6777b538SAndroid Build Coastguard Worker -ClampedNumeric<Dst>(DstLimits::lowest()));
645*6777b538SAndroid Build Coastguard Worker
646*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(),
647*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()).Abs());
648*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(-1).Abs());
649*6777b538SAndroid Build Coastguard Worker
650*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::lowest() - 1,
651*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()) + -1);
652*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max() + 1,
653*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::max()) + 1);
654*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
655*6777b538SAndroid Build Coastguard Worker DstLimits::Underflow(),
656*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()) + DstLimits::lowest());
657*6777b538SAndroid Build Coastguard Worker
658*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
659*6777b538SAndroid Build Coastguard Worker DstLimits::Overflow(),
660*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::max()) - DstLimits::lowest());
661*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(
662*6777b538SAndroid Build Coastguard Worker DstLimits::Underflow(),
663*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()) - DstLimits::max());
664*6777b538SAndroid Build Coastguard Worker
665*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Underflow(),
666*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()) * 2);
667*6777b538SAndroid Build Coastguard Worker
668*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-0.5, ClampedNumeric<Dst>(-1.0) / 2);
669*6777b538SAndroid Build Coastguard Worker }
670*6777b538SAndroid Build Coastguard Worker
671*6777b538SAndroid Build Coastguard Worker // Generic arithmetic tests.
672*6777b538SAndroid Build Coastguard Worker template <typename Dst>
TestArithmetic(const char * dst,int line)673*6777b538SAndroid Build Coastguard Worker static void TestArithmetic(const char* dst, int line) {
674*6777b538SAndroid Build Coastguard Worker using DstLimits = SaturationDefaultLimits<Dst>;
675*6777b538SAndroid Build Coastguard Worker
676*6777b538SAndroid Build Coastguard Worker // Test C++17 class template argument deduction
677*6777b538SAndroid Build Coastguard Worker static_assert(
678*6777b538SAndroid Build Coastguard Worker std::is_same_v<Dst, typename decltype(CheckedNumeric(Dst{0}))::type>);
679*6777b538SAndroid Build Coastguard Worker static_assert(
680*6777b538SAndroid Build Coastguard Worker std::is_same_v<Dst, typename decltype(ClampedNumeric(Dst{0}))::type>);
681*6777b538SAndroid Build Coastguard Worker static_assert(
682*6777b538SAndroid Build Coastguard Worker std::is_same_v<Dst, typename decltype(StrictNumeric(Dst{0}))::type>);
683*6777b538SAndroid Build Coastguard Worker
684*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(true, CheckedNumeric<Dst>().IsValid());
685*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(false, CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) *
686*6777b538SAndroid Build Coastguard Worker DstLimits::max())
687*6777b538SAndroid Build Coastguard Worker .IsValid());
688*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDie());
689*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDefault(1));
690*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<Dst>(1),
691*6777b538SAndroid Build Coastguard Worker CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) *
692*6777b538SAndroid Build Coastguard Worker DstLimits::max())
693*6777b538SAndroid Build Coastguard Worker .ValueOrDefault(1));
694*6777b538SAndroid Build Coastguard Worker
695*6777b538SAndroid Build Coastguard Worker // Test the operator combinations.
696*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + CheckedNumeric<Dst>(1));
697*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - CheckedNumeric<Dst>(1));
698*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * CheckedNumeric<Dst>(1));
699*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / CheckedNumeric<Dst>(1));
700*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(2, 1 + CheckedNumeric<Dst>(1));
701*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, 1 - CheckedNumeric<Dst>(1));
702*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, 1 * CheckedNumeric<Dst>(1));
703*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, 1 / CheckedNumeric<Dst>(1));
704*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) + 1);
705*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) - 1);
706*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) * 1);
707*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
708*6777b538SAndroid Build Coastguard Worker CheckedNumeric<Dst> checked_dst = 1;
709*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(2, checked_dst += 1);
710*6777b538SAndroid Build Coastguard Worker checked_dst = 1;
711*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, checked_dst -= 1);
712*6777b538SAndroid Build Coastguard Worker checked_dst = 1;
713*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, checked_dst *= 1);
714*6777b538SAndroid Build Coastguard Worker checked_dst = 1;
715*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, checked_dst /= 1);
716*6777b538SAndroid Build Coastguard Worker
717*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) + ClampedNumeric<Dst>(1));
718*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) - ClampedNumeric<Dst>(1));
719*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) * ClampedNumeric<Dst>(1));
720*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) / ClampedNumeric<Dst>(1));
721*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(2, 1 + ClampedNumeric<Dst>(1));
722*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, 1 - ClampedNumeric<Dst>(1));
723*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, 1 * ClampedNumeric<Dst>(1));
724*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, 1 / ClampedNumeric<Dst>(1));
725*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) + 1);
726*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) - 1);
727*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) * 1);
728*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) / 1);
729*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst> clamped_dst = 1;
730*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(2, clamped_dst += 1);
731*6777b538SAndroid Build Coastguard Worker clamped_dst = 1;
732*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, clamped_dst -= 1);
733*6777b538SAndroid Build Coastguard Worker clamped_dst = 1;
734*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, clamped_dst *= 1);
735*6777b538SAndroid Build Coastguard Worker clamped_dst = 1;
736*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, clamped_dst /= 1);
737*6777b538SAndroid Build Coastguard Worker
738*6777b538SAndroid Build Coastguard Worker // Generic negation.
739*6777b538SAndroid Build Coastguard Worker if (DstLimits::is_signed) {
740*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, -CheckedNumeric<Dst>());
741*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-1, -CheckedNumeric<Dst>(1));
742*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, -CheckedNumeric<Dst>(-1));
743*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1),
744*6777b538SAndroid Build Coastguard Worker -CheckedNumeric<Dst>(DstLimits::max()));
745*6777b538SAndroid Build Coastguard Worker
746*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, -ClampedNumeric<Dst>());
747*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-1, -ClampedNumeric<Dst>(1));
748*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, -ClampedNumeric<Dst>(-1));
749*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1),
750*6777b538SAndroid Build Coastguard Worker -ClampedNumeric<Dst>(DstLimits::max()));
751*6777b538SAndroid Build Coastguard Worker
752*6777b538SAndroid Build Coastguard Worker // The runtime paths for saturated negation differ significantly from what
753*6777b538SAndroid Build Coastguard Worker // gets evaluated at compile-time. Making this test volatile forces the
754*6777b538SAndroid Build Coastguard Worker // compiler to generate code rather than fold constant expressions.
755*6777b538SAndroid Build Coastguard Worker volatile Dst value = Dst(0);
756*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, -MakeClampedNum(value));
757*6777b538SAndroid Build Coastguard Worker value = Dst(1);
758*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-1, -MakeClampedNum(value));
759*6777b538SAndroid Build Coastguard Worker value = Dst(2);
760*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-2, -MakeClampedNum(value));
761*6777b538SAndroid Build Coastguard Worker value = Dst(-1);
762*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, -MakeClampedNum(value));
763*6777b538SAndroid Build Coastguard Worker value = Dst(-2);
764*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(2, -MakeClampedNum(value));
765*6777b538SAndroid Build Coastguard Worker value = DstLimits::max();
766*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(Dst(DstLimits::max() * -1), -MakeClampedNum(value));
767*6777b538SAndroid Build Coastguard Worker value = Dst(-1 * DstLimits::max());
768*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(), -MakeClampedNum(value));
769*6777b538SAndroid Build Coastguard Worker value = DstLimits::lowest();
770*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(), -MakeClampedNum(value));
771*6777b538SAndroid Build Coastguard Worker }
772*6777b538SAndroid Build Coastguard Worker
773*6777b538SAndroid Build Coastguard Worker // Generic absolute value.
774*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>().Abs());
775*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).Abs());
776*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(),
777*6777b538SAndroid Build Coastguard Worker CheckedNumeric<Dst>(DstLimits::max()).Abs());
778*6777b538SAndroid Build Coastguard Worker
779*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>().Abs());
780*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1).Abs());
781*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(),
782*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::max()).Abs());
783*6777b538SAndroid Build Coastguard Worker
784*6777b538SAndroid Build Coastguard Worker // Generic addition.
785*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>() + 1));
786*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(2, (CheckedNumeric<Dst>(1) + 1));
787*6777b538SAndroid Build Coastguard Worker if (numeric_limits<Dst>::is_signed)
788*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) + 1));
789*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) + 1);
790*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) +
791*6777b538SAndroid Build Coastguard Worker DstLimits::max());
792*6777b538SAndroid Build Coastguard Worker
793*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, (ClampedNumeric<Dst>() + 1));
794*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(2, (ClampedNumeric<Dst>(1) + 1));
795*6777b538SAndroid Build Coastguard Worker if (numeric_limits<Dst>::is_signed)
796*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(-1) + 1));
797*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::lowest() + 1,
798*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()) + 1);
799*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(),
800*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::max()) + DstLimits::max());
801*6777b538SAndroid Build Coastguard Worker
802*6777b538SAndroid Build Coastguard Worker // Generic subtraction.
803*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(1) - 1));
804*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) - 1);
805*6777b538SAndroid Build Coastguard Worker if (numeric_limits<Dst>::is_signed) {
806*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-1, (CheckedNumeric<Dst>() - 1));
807*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) - 1));
808*6777b538SAndroid Build Coastguard Worker } else {
809*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - -1);
810*6777b538SAndroid Build Coastguard Worker }
811*6777b538SAndroid Build Coastguard Worker
812*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(1) - 1));
813*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max() - 1,
814*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::max()) - 1);
815*6777b538SAndroid Build Coastguard Worker if (numeric_limits<Dst>::is_signed) {
816*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-1, (ClampedNumeric<Dst>() - 1));
817*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-2, (ClampedNumeric<Dst>(-1) - 1));
818*6777b538SAndroid Build Coastguard Worker } else {
819*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(),
820*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::max()) - -1);
821*6777b538SAndroid Build Coastguard Worker }
822*6777b538SAndroid Build Coastguard Worker
823*6777b538SAndroid Build Coastguard Worker // Generic multiplication.
824*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>() * 1));
825*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>(1) * 1));
826*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * 0));
827*6777b538SAndroid Build Coastguard Worker if (numeric_limits<Dst>::is_signed) {
828*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) * 0));
829*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * -1));
830*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) * 2));
831*6777b538SAndroid Build Coastguard Worker } else {
832*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * -2);
833*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) *
834*6777b538SAndroid Build Coastguard Worker CheckedNumeric<uintmax_t>(-2));
835*6777b538SAndroid Build Coastguard Worker }
836*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) *
837*6777b538SAndroid Build Coastguard Worker DstLimits::max());
838*6777b538SAndroid Build Coastguard Worker
839*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>() * 1));
840*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, (ClampedNumeric<Dst>(1) * 1));
841*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(0) * 0));
842*6777b538SAndroid Build Coastguard Worker if (numeric_limits<Dst>::is_signed) {
843*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(-1) * 0));
844*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(0) * -1));
845*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-2, (ClampedNumeric<Dst>(-1) * 2));
846*6777b538SAndroid Build Coastguard Worker } else {
847*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Underflow(),
848*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::max()) * -2);
849*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::max()) *
850*6777b538SAndroid Build Coastguard Worker ClampedNumeric<uintmax_t>(-2));
851*6777b538SAndroid Build Coastguard Worker }
852*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(),
853*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::max()) * DstLimits::max());
854*6777b538SAndroid Build Coastguard Worker
855*6777b538SAndroid Build Coastguard Worker // Generic division.
856*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() / 1);
857*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
858*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::lowest() / 2,
859*6777b538SAndroid Build Coastguard Worker CheckedNumeric<Dst>(DstLimits::lowest()) / 2);
860*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max() / 2,
861*6777b538SAndroid Build Coastguard Worker CheckedNumeric<Dst>(DstLimits::max()) / 2);
862*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) / 0);
863*6777b538SAndroid Build Coastguard Worker
864*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>() / 1);
865*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) / 1);
866*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::lowest() / 2,
867*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::lowest()) / 2);
868*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max() / 2,
869*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst>(DstLimits::max()) / 2);
870*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(), ClampedNumeric<Dst>(1) / 0);
871*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Underflow(), ClampedNumeric<Dst>(-1) / 0);
872*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) / 0);
873*6777b538SAndroid Build Coastguard Worker
874*6777b538SAndroid Build Coastguard Worker TestSpecializedArithmetic<Dst>(dst, line);
875*6777b538SAndroid Build Coastguard Worker }
876*6777b538SAndroid Build Coastguard Worker
877*6777b538SAndroid Build Coastguard Worker // Helper macro to wrap displaying the conversion types and line numbers.
878*6777b538SAndroid Build Coastguard Worker #define TEST_ARITHMETIC(Dst) TestArithmetic<Dst>(#Dst, __LINE__)
879*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,SignedIntegerMath)880*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, SignedIntegerMath) {
881*6777b538SAndroid Build Coastguard Worker TEST_ARITHMETIC(int8_t);
882*6777b538SAndroid Build Coastguard Worker TEST_ARITHMETIC(int16_t);
883*6777b538SAndroid Build Coastguard Worker TEST_ARITHMETIC(int);
884*6777b538SAndroid Build Coastguard Worker TEST_ARITHMETIC(intptr_t);
885*6777b538SAndroid Build Coastguard Worker TEST_ARITHMETIC(intmax_t);
886*6777b538SAndroid Build Coastguard Worker }
887*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,UnsignedIntegerMath)888*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, UnsignedIntegerMath) {
889*6777b538SAndroid Build Coastguard Worker TEST_ARITHMETIC(uint8_t);
890*6777b538SAndroid Build Coastguard Worker TEST_ARITHMETIC(uint16_t);
891*6777b538SAndroid Build Coastguard Worker TEST_ARITHMETIC(unsigned int);
892*6777b538SAndroid Build Coastguard Worker TEST_ARITHMETIC(uintptr_t);
893*6777b538SAndroid Build Coastguard Worker TEST_ARITHMETIC(uintmax_t);
894*6777b538SAndroid Build Coastguard Worker }
895*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,FloatingPointMath)896*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, FloatingPointMath) {
897*6777b538SAndroid Build Coastguard Worker TEST_ARITHMETIC(float);
898*6777b538SAndroid Build Coastguard Worker TEST_ARITHMETIC(double);
899*6777b538SAndroid Build Coastguard Worker }
900*6777b538SAndroid Build Coastguard Worker
901*6777b538SAndroid Build Coastguard Worker // Enumerates the five different conversions types we need to test.
902*6777b538SAndroid Build Coastguard Worker enum NumericConversionType {
903*6777b538SAndroid Build Coastguard Worker SIGN_PRESERVING_VALUE_PRESERVING,
904*6777b538SAndroid Build Coastguard Worker SIGN_PRESERVING_NARROW,
905*6777b538SAndroid Build Coastguard Worker SIGN_TO_UNSIGN_WIDEN_OR_EQUAL,
906*6777b538SAndroid Build Coastguard Worker SIGN_TO_UNSIGN_NARROW,
907*6777b538SAndroid Build Coastguard Worker UNSIGN_TO_SIGN_NARROW_OR_EQUAL,
908*6777b538SAndroid Build Coastguard Worker };
909*6777b538SAndroid Build Coastguard Worker
910*6777b538SAndroid Build Coastguard Worker // Template covering the different conversion tests.
911*6777b538SAndroid Build Coastguard Worker template <typename Dst, typename Src, NumericConversionType conversion>
912*6777b538SAndroid Build Coastguard Worker struct TestNumericConversion {};
913*6777b538SAndroid Build Coastguard Worker
914*6777b538SAndroid Build Coastguard Worker enum RangeConstraint {
915*6777b538SAndroid Build Coastguard Worker RANGE_VALID = 0x0, // Value can be represented by the destination type.
916*6777b538SAndroid Build Coastguard Worker RANGE_UNDERFLOW = 0x1, // Value would underflow.
917*6777b538SAndroid Build Coastguard Worker RANGE_OVERFLOW = 0x2, // Value would overflow.
918*6777b538SAndroid Build Coastguard Worker RANGE_INVALID = RANGE_UNDERFLOW | RANGE_OVERFLOW // Invalid (i.e. NaN).
919*6777b538SAndroid Build Coastguard Worker };
920*6777b538SAndroid Build Coastguard Worker
921*6777b538SAndroid Build Coastguard Worker // These are some wrappers to make the tests a bit cleaner.
RangeCheckToEnum(const RangeCheck constraint)922*6777b538SAndroid Build Coastguard Worker constexpr RangeConstraint RangeCheckToEnum(const RangeCheck constraint) {
923*6777b538SAndroid Build Coastguard Worker return static_cast<RangeConstraint>(
924*6777b538SAndroid Build Coastguard Worker static_cast<int>(constraint.IsOverflowFlagSet()) << 1 |
925*6777b538SAndroid Build Coastguard Worker static_cast<int>(constraint.IsUnderflowFlagSet()));
926*6777b538SAndroid Build Coastguard Worker }
927*6777b538SAndroid Build Coastguard Worker
928*6777b538SAndroid Build Coastguard Worker // EXPECT_EQ wrappers providing specific detail on test failures.
929*6777b538SAndroid Build Coastguard Worker #define TEST_EXPECTED_RANGE(expected, actual) \
930*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(expected, \
931*6777b538SAndroid Build Coastguard Worker RangeCheckToEnum(DstRangeRelationToSrcRange<Dst>(actual))) \
932*6777b538SAndroid Build Coastguard Worker << "Conversion test: " << src << " value " << actual << " to " << dst \
933*6777b538SAndroid Build Coastguard Worker << " on line " << line
934*6777b538SAndroid Build Coastguard Worker
935*6777b538SAndroid Build Coastguard Worker template <typename Dst, typename Src>
TestStrictComparison(const char * dst,const char * src,int line)936*6777b538SAndroid Build Coastguard Worker void TestStrictComparison(const char* dst, const char* src, int line) {
937*6777b538SAndroid Build Coastguard Worker using DstLimits = numeric_limits<Dst>;
938*6777b538SAndroid Build Coastguard Worker using SrcLimits = numeric_limits<Src>;
939*6777b538SAndroid Build Coastguard Worker static_assert(StrictNumeric<Src>(SrcLimits::lowest()) < DstLimits::max(), "");
940*6777b538SAndroid Build Coastguard Worker static_assert(StrictNumeric<Src>(SrcLimits::lowest()) < SrcLimits::max(), "");
941*6777b538SAndroid Build Coastguard Worker static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) >= DstLimits::max()),
942*6777b538SAndroid Build Coastguard Worker "");
943*6777b538SAndroid Build Coastguard Worker static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) >= SrcLimits::max()),
944*6777b538SAndroid Build Coastguard Worker "");
945*6777b538SAndroid Build Coastguard Worker static_assert(StrictNumeric<Src>(SrcLimits::lowest()) <= DstLimits::max(),
946*6777b538SAndroid Build Coastguard Worker "");
947*6777b538SAndroid Build Coastguard Worker static_assert(StrictNumeric<Src>(SrcLimits::lowest()) <= SrcLimits::max(),
948*6777b538SAndroid Build Coastguard Worker "");
949*6777b538SAndroid Build Coastguard Worker static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) > DstLimits::max()),
950*6777b538SAndroid Build Coastguard Worker "");
951*6777b538SAndroid Build Coastguard Worker static_assert(!(StrictNumeric<Src>(SrcLimits::lowest()) > SrcLimits::max()),
952*6777b538SAndroid Build Coastguard Worker "");
953*6777b538SAndroid Build Coastguard Worker static_assert(StrictNumeric<Src>(SrcLimits::max()) > DstLimits::lowest(), "");
954*6777b538SAndroid Build Coastguard Worker static_assert(StrictNumeric<Src>(SrcLimits::max()) > SrcLimits::lowest(), "");
955*6777b538SAndroid Build Coastguard Worker static_assert(!(StrictNumeric<Src>(SrcLimits::max()) <= DstLimits::lowest()),
956*6777b538SAndroid Build Coastguard Worker "");
957*6777b538SAndroid Build Coastguard Worker static_assert(!(StrictNumeric<Src>(SrcLimits::max()) <= SrcLimits::lowest()),
958*6777b538SAndroid Build Coastguard Worker "");
959*6777b538SAndroid Build Coastguard Worker static_assert(StrictNumeric<Src>(SrcLimits::max()) >= DstLimits::lowest(),
960*6777b538SAndroid Build Coastguard Worker "");
961*6777b538SAndroid Build Coastguard Worker static_assert(StrictNumeric<Src>(SrcLimits::max()) >= SrcLimits::lowest(),
962*6777b538SAndroid Build Coastguard Worker "");
963*6777b538SAndroid Build Coastguard Worker static_assert(!(StrictNumeric<Src>(SrcLimits::max()) < DstLimits::lowest()),
964*6777b538SAndroid Build Coastguard Worker "");
965*6777b538SAndroid Build Coastguard Worker static_assert(!(StrictNumeric<Src>(SrcLimits::max()) < SrcLimits::lowest()),
966*6777b538SAndroid Build Coastguard Worker "");
967*6777b538SAndroid Build Coastguard Worker static_assert(StrictNumeric<Src>(static_cast<Src>(1)) == static_cast<Dst>(1),
968*6777b538SAndroid Build Coastguard Worker "");
969*6777b538SAndroid Build Coastguard Worker static_assert(StrictNumeric<Src>(static_cast<Src>(1)) != static_cast<Dst>(0),
970*6777b538SAndroid Build Coastguard Worker "");
971*6777b538SAndroid Build Coastguard Worker static_assert(StrictNumeric<Src>(SrcLimits::max()) != static_cast<Dst>(0),
972*6777b538SAndroid Build Coastguard Worker "");
973*6777b538SAndroid Build Coastguard Worker static_assert(StrictNumeric<Src>(SrcLimits::max()) != DstLimits::lowest(),
974*6777b538SAndroid Build Coastguard Worker "");
975*6777b538SAndroid Build Coastguard Worker static_assert(
976*6777b538SAndroid Build Coastguard Worker !(StrictNumeric<Src>(static_cast<Src>(1)) != static_cast<Dst>(1)), "");
977*6777b538SAndroid Build Coastguard Worker static_assert(
978*6777b538SAndroid Build Coastguard Worker !(StrictNumeric<Src>(static_cast<Src>(1)) == static_cast<Dst>(0)), "");
979*6777b538SAndroid Build Coastguard Worker
980*6777b538SAndroid Build Coastguard Worker // Due to differences in float handling between compilers, these aren't
981*6777b538SAndroid Build Coastguard Worker // compile-time constants everywhere. So, we use run-time tests.
982*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(
983*6777b538SAndroid Build Coastguard Worker SrcLimits::max(),
984*6777b538SAndroid Build Coastguard Worker MakeCheckedNum(SrcLimits::max()).Max(DstLimits::lowest()).ValueOrDie());
985*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(
986*6777b538SAndroid Build Coastguard Worker DstLimits::max(),
987*6777b538SAndroid Build Coastguard Worker MakeCheckedNum(SrcLimits::lowest()).Max(DstLimits::max()).ValueOrDie());
988*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(
989*6777b538SAndroid Build Coastguard Worker DstLimits::lowest(),
990*6777b538SAndroid Build Coastguard Worker MakeCheckedNum(SrcLimits::max()).Min(DstLimits::lowest()).ValueOrDie());
991*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(
992*6777b538SAndroid Build Coastguard Worker SrcLimits::lowest(),
993*6777b538SAndroid Build Coastguard Worker MakeCheckedNum(SrcLimits::lowest()).Min(DstLimits::max()).ValueOrDie());
994*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(SrcLimits::lowest(), CheckMin(MakeStrictNum(1), MakeCheckedNum(0),
995*6777b538SAndroid Build Coastguard Worker DstLimits::max(), SrcLimits::lowest())
996*6777b538SAndroid Build Coastguard Worker .ValueOrDie());
997*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(DstLimits::max(), CheckMax(MakeStrictNum(1), MakeCheckedNum(0),
998*6777b538SAndroid Build Coastguard Worker DstLimits::max(), SrcLimits::lowest())
999*6777b538SAndroid Build Coastguard Worker .ValueOrDie());
1000*6777b538SAndroid Build Coastguard Worker
1001*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(SrcLimits::max(),
1002*6777b538SAndroid Build Coastguard Worker MakeClampedNum(SrcLimits::max()).Max(DstLimits::lowest()));
1003*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(DstLimits::max(),
1004*6777b538SAndroid Build Coastguard Worker MakeClampedNum(SrcLimits::lowest()).Max(DstLimits::max()));
1005*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(DstLimits::lowest(),
1006*6777b538SAndroid Build Coastguard Worker MakeClampedNum(SrcLimits::max()).Min(DstLimits::lowest()));
1007*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(SrcLimits::lowest(),
1008*6777b538SAndroid Build Coastguard Worker MakeClampedNum(SrcLimits::lowest()).Min(DstLimits::max()));
1009*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(SrcLimits::lowest(),
1010*6777b538SAndroid Build Coastguard Worker ClampMin(MakeStrictNum(1), MakeClampedNum(0), DstLimits::max(),
1011*6777b538SAndroid Build Coastguard Worker SrcLimits::lowest()));
1012*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(DstLimits::max(), ClampMax(MakeStrictNum(1), MakeClampedNum(0),
1013*6777b538SAndroid Build Coastguard Worker DstLimits::max(), SrcLimits::lowest()));
1014*6777b538SAndroid Build Coastguard Worker
1015*6777b538SAndroid Build Coastguard Worker if (IsValueInRangeForNumericType<Dst>(SrcLimits::max())) {
1016*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(Dst(SrcLimits::max()), (CommonMax<Dst, Src>()));
1017*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(Dst(SrcLimits::max()),
1018*6777b538SAndroid Build Coastguard Worker (CommonMaxOrMin<Dst, Src>(false)));
1019*6777b538SAndroid Build Coastguard Worker } else {
1020*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(), (CommonMax<Dst, Src>()));
1021*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::max(), (CommonMaxOrMin<Dst, Src>(false)));
1022*6777b538SAndroid Build Coastguard Worker }
1023*6777b538SAndroid Build Coastguard Worker
1024*6777b538SAndroid Build Coastguard Worker if (IsValueInRangeForNumericType<Dst>(SrcLimits::lowest())) {
1025*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(Dst(SrcLimits::lowest()), (CommonMin<Dst, Src>()));
1026*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(Dst(SrcLimits::lowest()),
1027*6777b538SAndroid Build Coastguard Worker (CommonMaxOrMin<Dst, Src>(true)));
1028*6777b538SAndroid Build Coastguard Worker } else {
1029*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::lowest(), (CommonMin<Dst, Src>()));
1030*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::lowest(), (CommonMaxOrMin<Dst, Src>(true)));
1031*6777b538SAndroid Build Coastguard Worker }
1032*6777b538SAndroid Build Coastguard Worker }
1033*6777b538SAndroid Build Coastguard Worker
1034*6777b538SAndroid Build Coastguard Worker template <typename Dst, typename Src>
1035*6777b538SAndroid Build Coastguard Worker struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> {
Testbase::internal::TestNumericConversion1036*6777b538SAndroid Build Coastguard Worker static void Test(const char* dst, const char* src, int line) {
1037*6777b538SAndroid Build Coastguard Worker using SrcLimits = SaturationDefaultLimits<Src>;
1038*6777b538SAndroid Build Coastguard Worker using DstLimits = SaturationDefaultLimits<Dst>;
1039*6777b538SAndroid Build Coastguard Worker // Integral to floating.
1040*6777b538SAndroid Build Coastguard Worker static_assert((DstLimits::is_iec559 && SrcLimits::is_integer) ||
1041*6777b538SAndroid Build Coastguard Worker // Not floating to integral and...
1042*6777b538SAndroid Build Coastguard Worker (!(DstLimits::is_integer && SrcLimits::is_iec559) &&
1043*6777b538SAndroid Build Coastguard Worker // Same sign, same numeric, source is narrower or same.
1044*6777b538SAndroid Build Coastguard Worker ((SrcLimits::is_signed == DstLimits::is_signed &&
1045*6777b538SAndroid Build Coastguard Worker MaxExponent<Dst>::value >= MaxExponent<Src>::value) ||
1046*6777b538SAndroid Build Coastguard Worker // Or signed destination and source is smaller
1047*6777b538SAndroid Build Coastguard Worker (DstLimits::is_signed &&
1048*6777b538SAndroid Build Coastguard Worker MaxExponent<Dst>::value >= MaxExponent<Src>::value))),
1049*6777b538SAndroid Build Coastguard Worker "Comparison must be sign preserving and value preserving");
1050*6777b538SAndroid Build Coastguard Worker
1051*6777b538SAndroid Build Coastguard Worker TestStrictComparison<Dst, Src>(dst, src, line);
1052*6777b538SAndroid Build Coastguard Worker
1053*6777b538SAndroid Build Coastguard Worker const CheckedNumeric<Dst> checked_dst = SrcLimits::max();
1054*6777b538SAndroid Build Coastguard Worker const ClampedNumeric<Dst> clamped_dst = SrcLimits::max();
1055*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_SUCCESS(checked_dst);
1056*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(Dst(SrcLimits::max()), clamped_dst);
1057*6777b538SAndroid Build Coastguard Worker if (MaxExponent<Dst>::value > MaxExponent<Src>::value) {
1058*6777b538SAndroid Build Coastguard Worker if (MaxExponent<Dst>::value >= MaxExponent<Src>::value * 2 - 1) {
1059*6777b538SAndroid Build Coastguard Worker // At least twice larger type.
1060*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_SUCCESS(SrcLimits::max() * checked_dst);
1061*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(SrcLimits::max() * clamped_dst,
1062*6777b538SAndroid Build Coastguard Worker Dst(SrcLimits::max()) * Dst(SrcLimits::max()));
1063*6777b538SAndroid Build Coastguard Worker } else { // Larger, but not at least twice as large.
1064*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(SrcLimits::max() * checked_dst);
1065*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_SUCCESS(checked_dst + 1);
1066*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(),
1067*6777b538SAndroid Build Coastguard Worker SrcLimits::max() * clamped_dst);
1068*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(Dst(SrcLimits::max()) + Dst(1),
1069*6777b538SAndroid Build Coastguard Worker clamped_dst + Dst(1));
1070*6777b538SAndroid Build Coastguard Worker }
1071*6777b538SAndroid Build Coastguard Worker } else { // Same width type.
1072*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(checked_dst + 1);
1073*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + Dst(1));
1074*6777b538SAndroid Build Coastguard Worker }
1075*6777b538SAndroid Build Coastguard Worker
1076*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
1077*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
1078*6777b538SAndroid Build Coastguard Worker if (SrcLimits::is_iec559) {
1079*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast<Src>(-1));
1080*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
1081*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
1082*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
1083*6777b538SAndroid Build Coastguard Worker } else if (numeric_limits<Src>::is_signed) {
1084*6777b538SAndroid Build Coastguard Worker // This block reverses the Src to Dst relationship so we don't have to
1085*6777b538SAndroid Build Coastguard Worker // complicate the test macros.
1086*6777b538SAndroid Build Coastguard Worker if (!std::is_same_v<Src, Dst>) {
1087*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_SUCCESS(CheckDiv(SrcLimits::lowest(), Dst(-1)));
1088*6777b538SAndroid Build Coastguard Worker }
1089*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
1090*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest());
1091*6777b538SAndroid Build Coastguard Worker }
1092*6777b538SAndroid Build Coastguard Worker }
1093*6777b538SAndroid Build Coastguard Worker };
1094*6777b538SAndroid Build Coastguard Worker
1095*6777b538SAndroid Build Coastguard Worker template <typename Dst, typename Src>
1096*6777b538SAndroid Build Coastguard Worker struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW> {
Testbase::internal::TestNumericConversion1097*6777b538SAndroid Build Coastguard Worker static void Test(const char* dst, const char* src, int line) {
1098*6777b538SAndroid Build Coastguard Worker using SrcLimits = SaturationDefaultLimits<Src>;
1099*6777b538SAndroid Build Coastguard Worker using DstLimits = SaturationDefaultLimits<Dst>;
1100*6777b538SAndroid Build Coastguard Worker static_assert(SrcLimits::is_signed == DstLimits::is_signed,
1101*6777b538SAndroid Build Coastguard Worker "Destination and source sign must be the same");
1102*6777b538SAndroid Build Coastguard Worker static_assert(MaxExponent<Dst>::value <= MaxExponent<Src>::value,
1103*6777b538SAndroid Build Coastguard Worker "Destination must be narrower than source");
1104*6777b538SAndroid Build Coastguard Worker
1105*6777b538SAndroid Build Coastguard Worker TestStrictComparison<Dst, Src>(dst, src, line);
1106*6777b538SAndroid Build Coastguard Worker
1107*6777b538SAndroid Build Coastguard Worker const CheckedNumeric<Dst> checked_dst;
1108*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
1109*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, checked_dst + Src(1));
1110*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(checked_dst - SrcLimits::max());
1111*6777b538SAndroid Build Coastguard Worker
1112*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst> clamped_dst;
1113*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + SrcLimits::max());
1114*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, clamped_dst + Src(1));
1115*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Underflow(), clamped_dst - SrcLimits::max());
1116*6777b538SAndroid Build Coastguard Worker clamped_dst += SrcLimits::max();
1117*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst);
1118*6777b538SAndroid Build Coastguard Worker clamped_dst = DstLimits::max();
1119*6777b538SAndroid Build Coastguard Worker clamped_dst += SrcLimits::max();
1120*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst);
1121*6777b538SAndroid Build Coastguard Worker clamped_dst = DstLimits::max();
1122*6777b538SAndroid Build Coastguard Worker clamped_dst -= SrcLimits::max();
1123*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Underflow(), clamped_dst);
1124*6777b538SAndroid Build Coastguard Worker clamped_dst = 0;
1125*6777b538SAndroid Build Coastguard Worker
1126*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
1127*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
1128*6777b538SAndroid Build Coastguard Worker if (SrcLimits::is_iec559) {
1129*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
1130*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
1131*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
1132*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
1133*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
1134*6777b538SAndroid Build Coastguard Worker if (DstLimits::is_integer) {
1135*6777b538SAndroid Build Coastguard Worker if (SrcLimits::digits < DstLimits::digits) {
1136*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_OVERFLOW,
1137*6777b538SAndroid Build Coastguard Worker static_cast<Src>(DstLimits::max()));
1138*6777b538SAndroid Build Coastguard Worker } else {
1139*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
1140*6777b538SAndroid Build Coastguard Worker }
1141*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(
1142*6777b538SAndroid Build Coastguard Worker RANGE_VALID,
1143*6777b538SAndroid Build Coastguard Worker static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
1144*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::lowest()));
1145*6777b538SAndroid Build Coastguard Worker }
1146*6777b538SAndroid Build Coastguard Worker } else if (SrcLimits::is_signed) {
1147*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1));
1148*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(-1, clamped_dst - static_cast<Src>(1));
1149*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(Src(Src(0) - DstLimits::lowest()),
1150*6777b538SAndroid Build Coastguard Worker ClampDiv(DstLimits::lowest(), Src(-1)));
1151*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest());
1152*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
1153*6777b538SAndroid Build Coastguard Worker } else {
1154*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(checked_dst - static_cast<Src>(1));
1155*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(Dst(0), clamped_dst - static_cast<Src>(1));
1156*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest());
1157*6777b538SAndroid Build Coastguard Worker }
1158*6777b538SAndroid Build Coastguard Worker }
1159*6777b538SAndroid Build Coastguard Worker };
1160*6777b538SAndroid Build Coastguard Worker
1161*6777b538SAndroid Build Coastguard Worker template <typename Dst, typename Src>
1162*6777b538SAndroid Build Coastguard Worker struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL> {
Testbase::internal::TestNumericConversion1163*6777b538SAndroid Build Coastguard Worker static void Test(const char* dst, const char* src, int line) {
1164*6777b538SAndroid Build Coastguard Worker using SrcLimits = SaturationDefaultLimits<Src>;
1165*6777b538SAndroid Build Coastguard Worker using DstLimits = SaturationDefaultLimits<Dst>;
1166*6777b538SAndroid Build Coastguard Worker static_assert(MaxExponent<Dst>::value >= MaxExponent<Src>::value,
1167*6777b538SAndroid Build Coastguard Worker "Destination must be equal or wider than source.");
1168*6777b538SAndroid Build Coastguard Worker static_assert(SrcLimits::is_signed, "Source must be signed");
1169*6777b538SAndroid Build Coastguard Worker static_assert(!DstLimits::is_signed, "Destination must be unsigned");
1170*6777b538SAndroid Build Coastguard Worker
1171*6777b538SAndroid Build Coastguard Worker TestStrictComparison<Dst, Src>(dst, src, line);
1172*6777b538SAndroid Build Coastguard Worker
1173*6777b538SAndroid Build Coastguard Worker const CheckedNumeric<Dst> checked_dst;
1174*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(SrcLimits::max(), checked_dst + SrcLimits::max());
1175*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1));
1176*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_SUCCESS(checked_dst * static_cast<Src>(-1));
1177*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::lowest());
1178*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(Dst(0), CheckDiv(Dst(0), Src(-1)));
1179*6777b538SAndroid Build Coastguard Worker
1180*6777b538SAndroid Build Coastguard Worker const ClampedNumeric<Dst> clamped_dst;
1181*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(SrcLimits::max(), clamped_dst + SrcLimits::max());
1182*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Underflow(),
1183*6777b538SAndroid Build Coastguard Worker clamped_dst + static_cast<Src>(-1));
1184*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(0, clamped_dst * static_cast<Src>(-1));
1185*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Underflow(),
1186*6777b538SAndroid Build Coastguard Worker clamped_dst + SrcLimits::lowest());
1187*6777b538SAndroid Build Coastguard Worker
1188*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest());
1189*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
1190*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
1191*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
1192*6777b538SAndroid Build Coastguard Worker }
1193*6777b538SAndroid Build Coastguard Worker };
1194*6777b538SAndroid Build Coastguard Worker
1195*6777b538SAndroid Build Coastguard Worker template <typename Dst, typename Src>
1196*6777b538SAndroid Build Coastguard Worker struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_NARROW> {
Testbase::internal::TestNumericConversion1197*6777b538SAndroid Build Coastguard Worker static void Test(const char* dst, const char* src, int line) {
1198*6777b538SAndroid Build Coastguard Worker using SrcLimits = SaturationDefaultLimits<Src>;
1199*6777b538SAndroid Build Coastguard Worker using DstLimits = SaturationDefaultLimits<Dst>;
1200*6777b538SAndroid Build Coastguard Worker static_assert(MaxExponent<Dst>::value < MaxExponent<Src>::value,
1201*6777b538SAndroid Build Coastguard Worker "Destination must be narrower than source.");
1202*6777b538SAndroid Build Coastguard Worker static_assert(SrcLimits::is_signed, "Source must be signed.");
1203*6777b538SAndroid Build Coastguard Worker static_assert(!DstLimits::is_signed, "Destination must be unsigned.");
1204*6777b538SAndroid Build Coastguard Worker
1205*6777b538SAndroid Build Coastguard Worker TestStrictComparison<Dst, Src>(dst, src, line);
1206*6777b538SAndroid Build Coastguard Worker
1207*6777b538SAndroid Build Coastguard Worker const CheckedNumeric<Dst> checked_dst;
1208*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
1209*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
1210*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1));
1211*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::lowest());
1212*6777b538SAndroid Build Coastguard Worker
1213*6777b538SAndroid Build Coastguard Worker ClampedNumeric<Dst> clamped_dst;
1214*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, clamped_dst + static_cast<Src>(1));
1215*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + SrcLimits::max());
1216*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Underflow(),
1217*6777b538SAndroid Build Coastguard Worker clamped_dst + static_cast<Src>(-1));
1218*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Underflow(),
1219*6777b538SAndroid Build Coastguard Worker clamped_dst + SrcLimits::lowest());
1220*6777b538SAndroid Build Coastguard Worker clamped_dst += SrcLimits::max();
1221*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst);
1222*6777b538SAndroid Build Coastguard Worker clamped_dst = DstLimits::max();
1223*6777b538SAndroid Build Coastguard Worker clamped_dst += SrcLimits::max();
1224*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst);
1225*6777b538SAndroid Build Coastguard Worker clamped_dst = DstLimits::max();
1226*6777b538SAndroid Build Coastguard Worker clamped_dst -= SrcLimits::max();
1227*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Underflow(), clamped_dst);
1228*6777b538SAndroid Build Coastguard Worker clamped_dst = 0;
1229*6777b538SAndroid Build Coastguard Worker
1230*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
1231*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
1232*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
1233*6777b538SAndroid Build Coastguard Worker
1234*6777b538SAndroid Build Coastguard Worker // Additional saturation tests.
1235*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(DstLimits::max(), saturated_cast<Dst>(SrcLimits::max()));
1236*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(DstLimits::lowest(), saturated_cast<Dst>(SrcLimits::lowest()));
1237*6777b538SAndroid Build Coastguard Worker
1238*6777b538SAndroid Build Coastguard Worker if (SrcLimits::is_iec559) {
1239*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(Dst(0), saturated_cast<Dst>(SrcLimits::quiet_NaN()));
1240*6777b538SAndroid Build Coastguard Worker
1241*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
1242*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
1243*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
1244*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
1245*6777b538SAndroid Build Coastguard Worker if (DstLimits::is_integer) {
1246*6777b538SAndroid Build Coastguard Worker if (SrcLimits::digits < DstLimits::digits) {
1247*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_OVERFLOW,
1248*6777b538SAndroid Build Coastguard Worker static_cast<Src>(DstLimits::max()));
1249*6777b538SAndroid Build Coastguard Worker } else {
1250*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
1251*6777b538SAndroid Build Coastguard Worker }
1252*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(
1253*6777b538SAndroid Build Coastguard Worker RANGE_VALID,
1254*6777b538SAndroid Build Coastguard Worker static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
1255*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::lowest()));
1256*6777b538SAndroid Build Coastguard Worker }
1257*6777b538SAndroid Build Coastguard Worker } else {
1258*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest());
1259*6777b538SAndroid Build Coastguard Worker }
1260*6777b538SAndroid Build Coastguard Worker }
1261*6777b538SAndroid Build Coastguard Worker };
1262*6777b538SAndroid Build Coastguard Worker
1263*6777b538SAndroid Build Coastguard Worker template <typename Dst, typename Src>
1264*6777b538SAndroid Build Coastguard Worker struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL> {
Testbase::internal::TestNumericConversion1265*6777b538SAndroid Build Coastguard Worker static void Test(const char* dst, const char* src, int line) {
1266*6777b538SAndroid Build Coastguard Worker using SrcLimits = SaturationDefaultLimits<Src>;
1267*6777b538SAndroid Build Coastguard Worker using DstLimits = SaturationDefaultLimits<Dst>;
1268*6777b538SAndroid Build Coastguard Worker static_assert(MaxExponent<Dst>::value <= MaxExponent<Src>::value,
1269*6777b538SAndroid Build Coastguard Worker "Destination must be narrower or equal to source.");
1270*6777b538SAndroid Build Coastguard Worker static_assert(!SrcLimits::is_signed, "Source must be unsigned.");
1271*6777b538SAndroid Build Coastguard Worker static_assert(DstLimits::is_signed, "Destination must be signed.");
1272*6777b538SAndroid Build Coastguard Worker
1273*6777b538SAndroid Build Coastguard Worker TestStrictComparison<Dst, Src>(dst, src, line);
1274*6777b538SAndroid Build Coastguard Worker
1275*6777b538SAndroid Build Coastguard Worker const CheckedNumeric<Dst> checked_dst;
1276*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
1277*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
1278*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(SrcLimits::lowest(), checked_dst + SrcLimits::lowest());
1279*6777b538SAndroid Build Coastguard Worker
1280*6777b538SAndroid Build Coastguard Worker const ClampedNumeric<Dst> clamped_dst;
1281*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(1, clamped_dst + static_cast<Src>(1));
1282*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + SrcLimits::max());
1283*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_VALUE(SrcLimits::lowest(), clamped_dst + SrcLimits::lowest());
1284*6777b538SAndroid Build Coastguard Worker
1285*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest());
1286*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
1287*6777b538SAndroid Build Coastguard Worker TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
1288*6777b538SAndroid Build Coastguard Worker
1289*6777b538SAndroid Build Coastguard Worker // Additional saturation tests.
1290*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(DstLimits::max(), saturated_cast<Dst>(SrcLimits::max()));
1291*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(Dst(0), saturated_cast<Dst>(SrcLimits::lowest()));
1292*6777b538SAndroid Build Coastguard Worker }
1293*6777b538SAndroid Build Coastguard Worker };
1294*6777b538SAndroid Build Coastguard Worker
1295*6777b538SAndroid Build Coastguard Worker // Helper macro to wrap displaying the conversion types and line numbers
1296*6777b538SAndroid Build Coastguard Worker #define TEST_NUMERIC_CONVERSION(d, s, t) \
1297*6777b538SAndroid Build Coastguard Worker TestNumericConversion<d, s, t>::Test(#d, #s, __LINE__)
1298*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,IntMinOperations)1299*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, IntMinOperations) {
1300*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int8_t, int8_t, SIGN_PRESERVING_VALUE_PRESERVING);
1301*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uint8_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
1302*6777b538SAndroid Build Coastguard Worker
1303*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int8_t, int16_t, SIGN_PRESERVING_NARROW);
1304*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int8_t, int, SIGN_PRESERVING_NARROW);
1305*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uint8_t, uint16_t, SIGN_PRESERVING_NARROW);
1306*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uint8_t, unsigned int, SIGN_PRESERVING_NARROW);
1307*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int8_t, float, SIGN_PRESERVING_NARROW);
1308*6777b538SAndroid Build Coastguard Worker
1309*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uint8_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
1310*6777b538SAndroid Build Coastguard Worker
1311*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uint8_t, int16_t, SIGN_TO_UNSIGN_NARROW);
1312*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uint8_t, int, SIGN_TO_UNSIGN_NARROW);
1313*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uint8_t, intmax_t, SIGN_TO_UNSIGN_NARROW);
1314*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uint8_t, float, SIGN_TO_UNSIGN_NARROW);
1315*6777b538SAndroid Build Coastguard Worker
1316*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int8_t, uint16_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1317*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int8_t, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1318*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int8_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1319*6777b538SAndroid Build Coastguard Worker }
1320*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,Int16Operations)1321*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, Int16Operations) {
1322*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int16_t, int16_t, SIGN_PRESERVING_VALUE_PRESERVING);
1323*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uint16_t, uint16_t, SIGN_PRESERVING_VALUE_PRESERVING);
1324*6777b538SAndroid Build Coastguard Worker
1325*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int16_t, int, SIGN_PRESERVING_NARROW);
1326*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uint16_t, unsigned int, SIGN_PRESERVING_NARROW);
1327*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int16_t, float, SIGN_PRESERVING_NARROW);
1328*6777b538SAndroid Build Coastguard Worker
1329*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uint16_t, int16_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
1330*6777b538SAndroid Build Coastguard Worker
1331*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uint16_t, int, SIGN_TO_UNSIGN_NARROW);
1332*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uint16_t, intmax_t, SIGN_TO_UNSIGN_NARROW);
1333*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uint16_t, float, SIGN_TO_UNSIGN_NARROW);
1334*6777b538SAndroid Build Coastguard Worker
1335*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int16_t, unsigned int,
1336*6777b538SAndroid Build Coastguard Worker UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1337*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int16_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1338*6777b538SAndroid Build Coastguard Worker }
1339*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,IntOperations)1340*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, IntOperations) {
1341*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int, int, SIGN_PRESERVING_VALUE_PRESERVING);
1342*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(unsigned int, unsigned int,
1343*6777b538SAndroid Build Coastguard Worker SIGN_PRESERVING_VALUE_PRESERVING);
1344*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int, int8_t, SIGN_PRESERVING_VALUE_PRESERVING);
1345*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(unsigned int, uint8_t,
1346*6777b538SAndroid Build Coastguard Worker SIGN_PRESERVING_VALUE_PRESERVING);
1347*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
1348*6777b538SAndroid Build Coastguard Worker
1349*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int, intmax_t, SIGN_PRESERVING_NARROW);
1350*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(unsigned int, uintmax_t, SIGN_PRESERVING_NARROW);
1351*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int, float, SIGN_PRESERVING_NARROW);
1352*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int, double, SIGN_PRESERVING_NARROW);
1353*6777b538SAndroid Build Coastguard Worker
1354*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(unsigned int, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
1355*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(unsigned int, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
1356*6777b538SAndroid Build Coastguard Worker
1357*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(unsigned int, intmax_t, SIGN_TO_UNSIGN_NARROW);
1358*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(unsigned int, float, SIGN_TO_UNSIGN_NARROW);
1359*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(unsigned int, double, SIGN_TO_UNSIGN_NARROW);
1360*6777b538SAndroid Build Coastguard Worker
1361*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int, unsigned int, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1362*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1363*6777b538SAndroid Build Coastguard Worker }
1364*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,IntMaxOperations)1365*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, IntMaxOperations) {
1366*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(intmax_t, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
1367*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uintmax_t, uintmax_t,
1368*6777b538SAndroid Build Coastguard Worker SIGN_PRESERVING_VALUE_PRESERVING);
1369*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(intmax_t, int, SIGN_PRESERVING_VALUE_PRESERVING);
1370*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uintmax_t, unsigned int,
1371*6777b538SAndroid Build Coastguard Worker SIGN_PRESERVING_VALUE_PRESERVING);
1372*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(intmax_t, unsigned int,
1373*6777b538SAndroid Build Coastguard Worker SIGN_PRESERVING_VALUE_PRESERVING);
1374*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(intmax_t, uint8_t, SIGN_PRESERVING_VALUE_PRESERVING);
1375*6777b538SAndroid Build Coastguard Worker
1376*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(intmax_t, float, SIGN_PRESERVING_NARROW);
1377*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(intmax_t, double, SIGN_PRESERVING_NARROW);
1378*6777b538SAndroid Build Coastguard Worker
1379*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uintmax_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
1380*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uintmax_t, int8_t, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
1381*6777b538SAndroid Build Coastguard Worker
1382*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uintmax_t, float, SIGN_TO_UNSIGN_NARROW);
1383*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(uintmax_t, double, SIGN_TO_UNSIGN_NARROW);
1384*6777b538SAndroid Build Coastguard Worker
1385*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(intmax_t, uintmax_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1386*6777b538SAndroid Build Coastguard Worker }
1387*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,FloatOperations)1388*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, FloatOperations) {
1389*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(float, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
1390*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(float, uintmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
1391*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(float, int, SIGN_PRESERVING_VALUE_PRESERVING);
1392*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(float, unsigned int,
1393*6777b538SAndroid Build Coastguard Worker SIGN_PRESERVING_VALUE_PRESERVING);
1394*6777b538SAndroid Build Coastguard Worker
1395*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(float, double, SIGN_PRESERVING_NARROW);
1396*6777b538SAndroid Build Coastguard Worker }
1397*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,DoubleOperations)1398*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, DoubleOperations) {
1399*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(double, intmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
1400*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(double, uintmax_t, SIGN_PRESERVING_VALUE_PRESERVING);
1401*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(double, int, SIGN_PRESERVING_VALUE_PRESERVING);
1402*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(double, unsigned int,
1403*6777b538SAndroid Build Coastguard Worker SIGN_PRESERVING_VALUE_PRESERVING);
1404*6777b538SAndroid Build Coastguard Worker }
1405*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,SizeTOperations)1406*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, SizeTOperations) {
1407*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(size_t, int, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL);
1408*6777b538SAndroid Build Coastguard Worker TEST_NUMERIC_CONVERSION(int, size_t, UNSIGN_TO_SIGN_NARROW_OR_EQUAL);
1409*6777b538SAndroid Build Coastguard Worker }
1410*6777b538SAndroid Build Coastguard Worker
1411*6777b538SAndroid Build Coastguard Worker // A one-off test to ensure StrictNumeric won't resolve to an incorrect type.
1412*6777b538SAndroid Build Coastguard Worker // If this fails we'll just get a compiler error on an ambiguous overload.
TestOverload(int)1413*6777b538SAndroid Build Coastguard Worker int TestOverload(int) { // Overload fails.
1414*6777b538SAndroid Build Coastguard Worker return 0;
1415*6777b538SAndroid Build Coastguard Worker }
TestOverload(uint8_t)1416*6777b538SAndroid Build Coastguard Worker uint8_t TestOverload(uint8_t) { // Overload fails.
1417*6777b538SAndroid Build Coastguard Worker return 0;
1418*6777b538SAndroid Build Coastguard Worker }
TestOverload(size_t)1419*6777b538SAndroid Build Coastguard Worker size_t TestOverload(size_t) { // Overload succeeds.
1420*6777b538SAndroid Build Coastguard Worker return 0;
1421*6777b538SAndroid Build Coastguard Worker }
1422*6777b538SAndroid Build Coastguard Worker
1423*6777b538SAndroid Build Coastguard Worker static_assert(std::is_same_v<decltype(TestOverload(StrictNumeric<int>())), int>,
1424*6777b538SAndroid Build Coastguard Worker "");
1425*6777b538SAndroid Build Coastguard Worker static_assert(
1426*6777b538SAndroid Build Coastguard Worker std::is_same_v<decltype(TestOverload(StrictNumeric<size_t>())), size_t>,
1427*6777b538SAndroid Build Coastguard Worker "");
1428*6777b538SAndroid Build Coastguard Worker
1429*6777b538SAndroid Build Coastguard Worker template <typename T>
1430*6777b538SAndroid Build Coastguard Worker struct CastTest1 {
NaNbase::internal::CastTest11431*6777b538SAndroid Build Coastguard Worker static constexpr T NaN() { return -1; }
maxbase::internal::CastTest11432*6777b538SAndroid Build Coastguard Worker static constexpr T max() { return numeric_limits<T>::max() - 1; }
Overflowbase::internal::CastTest11433*6777b538SAndroid Build Coastguard Worker static constexpr T Overflow() { return max(); }
lowestbase::internal::CastTest11434*6777b538SAndroid Build Coastguard Worker static constexpr T lowest() { return numeric_limits<T>::lowest() + 1; }
Underflowbase::internal::CastTest11435*6777b538SAndroid Build Coastguard Worker static constexpr T Underflow() { return lowest(); }
1436*6777b538SAndroid Build Coastguard Worker };
1437*6777b538SAndroid Build Coastguard Worker
1438*6777b538SAndroid Build Coastguard Worker template <typename T>
1439*6777b538SAndroid Build Coastguard Worker struct CastTest2 {
NaNbase::internal::CastTest21440*6777b538SAndroid Build Coastguard Worker static constexpr T NaN() { return 11; }
maxbase::internal::CastTest21441*6777b538SAndroid Build Coastguard Worker static constexpr T max() { return 10; }
Overflowbase::internal::CastTest21442*6777b538SAndroid Build Coastguard Worker static constexpr T Overflow() { return max(); }
lowestbase::internal::CastTest21443*6777b538SAndroid Build Coastguard Worker static constexpr T lowest() { return 1; }
Underflowbase::internal::CastTest21444*6777b538SAndroid Build Coastguard Worker static constexpr T Underflow() { return lowest(); }
1445*6777b538SAndroid Build Coastguard Worker };
1446*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,CastTests)1447*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, CastTests) {
1448*6777b538SAndroid Build Coastguard Worker // MSVC catches and warns that we're forcing saturation in these tests.
1449*6777b538SAndroid Build Coastguard Worker // Since that's intentional, we need to shut this warning off.
1450*6777b538SAndroid Build Coastguard Worker #if defined(COMPILER_MSVC)
1451*6777b538SAndroid Build Coastguard Worker #pragma warning(disable : 4756)
1452*6777b538SAndroid Build Coastguard Worker #endif
1453*6777b538SAndroid Build Coastguard Worker
1454*6777b538SAndroid Build Coastguard Worker int small_positive = 1;
1455*6777b538SAndroid Build Coastguard Worker int small_negative = -1;
1456*6777b538SAndroid Build Coastguard Worker double double_small = 1.0;
1457*6777b538SAndroid Build Coastguard Worker double double_large = numeric_limits<double>::max();
1458*6777b538SAndroid Build Coastguard Worker double double_infinity = numeric_limits<float>::infinity();
1459*6777b538SAndroid Build Coastguard Worker double double_large_int = numeric_limits<int>::max();
1460*6777b538SAndroid Build Coastguard Worker double double_small_int = numeric_limits<int>::lowest();
1461*6777b538SAndroid Build Coastguard Worker
1462*6777b538SAndroid Build Coastguard Worker // Just test that the casts compile, since the other tests cover logic.
1463*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, checked_cast<int>(static_cast<size_t>(0)));
1464*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, strict_cast<int>(static_cast<char>(0)));
1465*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, strict_cast<int>(static_cast<unsigned char>(0)));
1466*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0U, strict_cast<unsigned>(static_cast<unsigned char>(0)));
1467*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1ULL, static_cast<uint64_t>(StrictNumeric<size_t>(1U)));
1468*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1ULL, static_cast<uint64_t>(SizeT(1U)));
1469*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1U, static_cast<size_t>(StrictNumeric<unsigned>(1U)));
1470*6777b538SAndroid Build Coastguard Worker
1471*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(CheckedNumeric<uint64_t>(StrictNumeric<unsigned>(1U)).IsValid());
1472*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(CheckedNumeric<int>(StrictNumeric<unsigned>(1U)).IsValid());
1473*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(CheckedNumeric<unsigned>(StrictNumeric<int>(-1)).IsValid());
1474*6777b538SAndroid Build Coastguard Worker
1475*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueNegative(-1));
1476*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueNegative(numeric_limits<int>::lowest()));
1477*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::lowest()));
1478*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueNegative(numeric_limits<double>::lowest()));
1479*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueNegative(0));
1480*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueNegative(1));
1481*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueNegative(0u));
1482*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueNegative(1u));
1483*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueNegative(numeric_limits<int>::max()));
1484*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueNegative(numeric_limits<unsigned>::max()));
1485*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueNegative(numeric_limits<double>::max()));
1486*6777b538SAndroid Build Coastguard Worker
1487*6777b538SAndroid Build Coastguard Worker // These casts and coercions will fail to compile:
1488*6777b538SAndroid Build Coastguard Worker // EXPECT_EQ(0, strict_cast<int>(static_cast<size_t>(0)));
1489*6777b538SAndroid Build Coastguard Worker // EXPECT_EQ(0, strict_cast<size_t>(static_cast<int>(0)));
1490*6777b538SAndroid Build Coastguard Worker // EXPECT_EQ(1ULL, StrictNumeric<size_t>(1));
1491*6777b538SAndroid Build Coastguard Worker // EXPECT_EQ(1, StrictNumeric<size_t>(1U));
1492*6777b538SAndroid Build Coastguard Worker
1493*6777b538SAndroid Build Coastguard Worker // Test various saturation corner cases.
1494*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(saturated_cast<int>(small_negative),
1495*6777b538SAndroid Build Coastguard Worker static_cast<int>(small_negative));
1496*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(saturated_cast<int>(small_positive),
1497*6777b538SAndroid Build Coastguard Worker static_cast<int>(small_positive));
1498*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(saturated_cast<unsigned>(small_negative), static_cast<unsigned>(0));
1499*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(saturated_cast<int>(double_small), static_cast<int>(double_small));
1500*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(saturated_cast<int>(double_large), numeric_limits<int>::max());
1501*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(saturated_cast<float>(double_large), double_infinity);
1502*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(saturated_cast<float>(-double_large), -double_infinity);
1503*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(numeric_limits<int>::lowest(),
1504*6777b538SAndroid Build Coastguard Worker saturated_cast<int>(double_small_int));
1505*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(numeric_limits<int>::max(), saturated_cast<int>(double_large_int));
1506*6777b538SAndroid Build Coastguard Worker
1507*6777b538SAndroid Build Coastguard Worker // Test the saturated cast overrides.
1508*6777b538SAndroid Build Coastguard Worker using FloatLimits = numeric_limits<float>;
1509*6777b538SAndroid Build Coastguard Worker using IntLimits = numeric_limits<int>;
1510*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(-1, (saturated_cast<int, CastTest1>(FloatLimits::quiet_NaN())));
1511*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(CastTest1<int>::max(),
1512*6777b538SAndroid Build Coastguard Worker (saturated_cast<int, CastTest1>(FloatLimits::infinity())));
1513*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(CastTest1<int>::max(),
1514*6777b538SAndroid Build Coastguard Worker (saturated_cast<int, CastTest1>(FloatLimits::max())));
1515*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(CastTest1<int>::max(),
1516*6777b538SAndroid Build Coastguard Worker (saturated_cast<int, CastTest1>(float(IntLimits::max()))));
1517*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(CastTest1<int>::lowest(),
1518*6777b538SAndroid Build Coastguard Worker (saturated_cast<int, CastTest1>(-FloatLimits::infinity())));
1519*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(CastTest1<int>::lowest(),
1520*6777b538SAndroid Build Coastguard Worker (saturated_cast<int, CastTest1>(FloatLimits::lowest())));
1521*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, (saturated_cast<int, CastTest1>(0.0)));
1522*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, (saturated_cast<int, CastTest1>(1.0)));
1523*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(-1, (saturated_cast<int, CastTest1>(-1.0)));
1524*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, (saturated_cast<int, CastTest1>(0)));
1525*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, (saturated_cast<int, CastTest1>(1)));
1526*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(-1, (saturated_cast<int, CastTest1>(-1)));
1527*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(CastTest1<int>::lowest(),
1528*6777b538SAndroid Build Coastguard Worker (saturated_cast<int, CastTest1>(float(IntLimits::lowest()))));
1529*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(11, (saturated_cast<int, CastTest2>(FloatLimits::quiet_NaN())));
1530*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(10, (saturated_cast<int, CastTest2>(FloatLimits::infinity())));
1531*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(10, (saturated_cast<int, CastTest2>(FloatLimits::max())));
1532*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, (saturated_cast<int, CastTest2>(-FloatLimits::infinity())));
1533*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, (saturated_cast<int, CastTest2>(FloatLimits::lowest())));
1534*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, (saturated_cast<int, CastTest2>(0U)));
1535*6777b538SAndroid Build Coastguard Worker
1536*6777b538SAndroid Build Coastguard Worker float not_a_number = std::numeric_limits<float>::infinity() -
1537*6777b538SAndroid Build Coastguard Worker std::numeric_limits<float>::infinity();
1538*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(std::isnan(not_a_number));
1539*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, saturated_cast<int>(not_a_number));
1540*6777b538SAndroid Build Coastguard Worker
1541*6777b538SAndroid Build Coastguard Worker // Test the CheckedNumeric value extractions functions.
1542*6777b538SAndroid Build Coastguard Worker auto int8_min = MakeCheckedNum(numeric_limits<int8_t>::lowest());
1543*6777b538SAndroid Build Coastguard Worker auto int8_max = MakeCheckedNum(numeric_limits<int8_t>::max());
1544*6777b538SAndroid Build Coastguard Worker auto double_max = MakeCheckedNum(numeric_limits<double>::max());
1545*6777b538SAndroid Build Coastguard Worker static_assert(
1546*6777b538SAndroid Build Coastguard Worker std::is_same_v<int16_t, decltype(int8_min.ValueOrDie<int16_t>())::type>,
1547*6777b538SAndroid Build Coastguard Worker "ValueOrDie returning incorrect type.");
1548*6777b538SAndroid Build Coastguard Worker static_assert(
1549*6777b538SAndroid Build Coastguard Worker std::is_same_v<int16_t,
1550*6777b538SAndroid Build Coastguard Worker decltype(int8_min.ValueOrDefault<int16_t>(0))::type>,
1551*6777b538SAndroid Build Coastguard Worker "ValueOrDefault returning incorrect type.");
1552*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValidForType<uint8_t>(int8_min));
1553*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValidForType<uint8_t>(int8_max));
1554*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<int>(numeric_limits<int8_t>::lowest()),
1555*6777b538SAndroid Build Coastguard Worker ValueOrDieForType<int>(int8_min));
1556*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValidForType<uint32_t>(int8_max));
1557*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<int>(numeric_limits<int8_t>::max()),
1558*6777b538SAndroid Build Coastguard Worker ValueOrDieForType<int>(int8_max));
1559*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ValueOrDefaultForType<int>(double_max, 0));
1560*6777b538SAndroid Build Coastguard Worker uint8_t uint8_dest = 0;
1561*6777b538SAndroid Build Coastguard Worker int16_t int16_dest = 0;
1562*6777b538SAndroid Build Coastguard Worker double double_dest = 0;
1563*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(int8_max.AssignIfValid(&uint8_dest));
1564*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<uint8_t>(numeric_limits<int8_t>::max()), uint8_dest);
1565*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(int8_min.AssignIfValid(&uint8_dest));
1566*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(int8_max.AssignIfValid(&int16_dest));
1567*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<int16_t>(numeric_limits<int8_t>::max()), int16_dest);
1568*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(int8_min.AssignIfValid(&int16_dest));
1569*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<int16_t>(numeric_limits<int8_t>::lowest()), int16_dest);
1570*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(double_max.AssignIfValid(&uint8_dest));
1571*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(double_max.AssignIfValid(&int16_dest));
1572*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(double_max.AssignIfValid(&double_dest));
1573*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(numeric_limits<double>::max(), double_dest);
1574*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, checked_cast<int>(StrictNumeric<int>(1)));
1575*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, saturated_cast<int>(StrictNumeric<int>(1)));
1576*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, strict_cast<int>(StrictNumeric<int>(1)));
1577*6777b538SAndroid Build Coastguard Worker
1578*6777b538SAndroid Build Coastguard Worker enum class EnumTest { kOne = 1 };
1579*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, checked_cast<int>(EnumTest::kOne));
1580*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, saturated_cast<int>(EnumTest::kOne));
1581*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, strict_cast<int>(EnumTest::kOne));
1582*6777b538SAndroid Build Coastguard Worker }
1583*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,IsValueInRangeForNumericType)1584*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, IsValueInRangeForNumericType) {
1585*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0));
1586*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(1));
1587*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(2));
1588*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(-1));
1589*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(0xffffffffu));
1590*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0xffffffff)));
1591*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000000)));
1592*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(UINT64_C(0x100000001)));
1593*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(
1594*6777b538SAndroid Build Coastguard Worker std::numeric_limits<int32_t>::lowest()));
1595*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(
1596*6777b538SAndroid Build Coastguard Worker std::numeric_limits<int64_t>::lowest()));
1597*6777b538SAndroid Build Coastguard Worker
1598*6777b538SAndroid Build Coastguard Worker // Converting to integer types will discard the fractional part first, so -0.9
1599*6777b538SAndroid Build Coastguard Worker // will be truncated to -0.0.
1600*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<uint32_t>(-0.9));
1601*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<uint32_t>(-1.0));
1602*6777b538SAndroid Build Coastguard Worker
1603*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0));
1604*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(1));
1605*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(2));
1606*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(-1));
1607*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffff));
1608*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(0x7fffffffu));
1609*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0x80000000u));
1610*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(0xffffffffu));
1611*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x80000000)));
1612*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0xffffffff)));
1613*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(INT64_C(0x100000000)));
1614*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(
1615*6777b538SAndroid Build Coastguard Worker std::numeric_limits<int32_t>::lowest()));
1616*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int32_t>(
1617*6777b538SAndroid Build Coastguard Worker static_cast<int64_t>(std::numeric_limits<int32_t>::lowest())));
1618*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(
1619*6777b538SAndroid Build Coastguard Worker static_cast<int64_t>(std::numeric_limits<int32_t>::lowest()) - 1));
1620*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<int32_t>(
1621*6777b538SAndroid Build Coastguard Worker std::numeric_limits<int64_t>::lowest()));
1622*6777b538SAndroid Build Coastguard Worker
1623*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0));
1624*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(1));
1625*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(2));
1626*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(-1));
1627*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(0xffffffffu));
1628*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0xffffffff)));
1629*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000000)));
1630*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(UINT64_C(0x100000001)));
1631*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(
1632*6777b538SAndroid Build Coastguard Worker std::numeric_limits<int32_t>::lowest()));
1633*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(INT64_C(-1)));
1634*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(
1635*6777b538SAndroid Build Coastguard Worker std::numeric_limits<int64_t>::lowest()));
1636*6777b538SAndroid Build Coastguard Worker
1637*6777b538SAndroid Build Coastguard Worker // Converting to integer types will discard the fractional part first, so -0.9
1638*6777b538SAndroid Build Coastguard Worker // will be truncated to -0.0.
1639*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<uint64_t>(-0.9));
1640*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(IsValueInRangeForNumericType<uint64_t>(-1.0));
1641*6777b538SAndroid Build Coastguard Worker
1642*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0));
1643*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(1));
1644*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(2));
1645*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(-1));
1646*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffff));
1647*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x7fffffffu));
1648*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0x80000000u));
1649*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(0xffffffffu));
1650*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x80000000)));
1651*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0xffffffff)));
1652*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(INT64_C(0x100000000)));
1653*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(
1654*6777b538SAndroid Build Coastguard Worker IsValueInRangeForNumericType<int64_t>(INT64_C(0x7fffffffffffffff)));
1655*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(
1656*6777b538SAndroid Build Coastguard Worker IsValueInRangeForNumericType<int64_t>(UINT64_C(0x7fffffffffffffff)));
1657*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(
1658*6777b538SAndroid Build Coastguard Worker IsValueInRangeForNumericType<int64_t>(UINT64_C(0x8000000000000000)));
1659*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(
1660*6777b538SAndroid Build Coastguard Worker IsValueInRangeForNumericType<int64_t>(UINT64_C(0xffffffffffffffff)));
1661*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
1662*6777b538SAndroid Build Coastguard Worker std::numeric_limits<int32_t>::lowest()));
1663*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
1664*6777b538SAndroid Build Coastguard Worker static_cast<int64_t>(std::numeric_limits<int32_t>::lowest())));
1665*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(IsValueInRangeForNumericType<int64_t>(
1666*6777b538SAndroid Build Coastguard Worker std::numeric_limits<int64_t>::lowest()));
1667*6777b538SAndroid Build Coastguard Worker }
1668*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,CompoundNumericOperations)1669*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, CompoundNumericOperations) {
1670*6777b538SAndroid Build Coastguard Worker CheckedNumeric<int> a = 1;
1671*6777b538SAndroid Build Coastguard Worker CheckedNumeric<int> b = 2;
1672*6777b538SAndroid Build Coastguard Worker CheckedNumeric<int> c = 3;
1673*6777b538SAndroid Build Coastguard Worker CheckedNumeric<int> d = 4;
1674*6777b538SAndroid Build Coastguard Worker a += b;
1675*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3, a.ValueOrDie());
1676*6777b538SAndroid Build Coastguard Worker a -= c;
1677*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, a.ValueOrDie());
1678*6777b538SAndroid Build Coastguard Worker d /= b;
1679*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, d.ValueOrDie());
1680*6777b538SAndroid Build Coastguard Worker d *= d;
1681*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(4, d.ValueOrDie());
1682*6777b538SAndroid Build Coastguard Worker d *= 0.5;
1683*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2, d.ValueOrDie());
1684*6777b538SAndroid Build Coastguard Worker
1685*6777b538SAndroid Build Coastguard Worker CheckedNumeric<int> too_large = std::numeric_limits<int>::max();
1686*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(too_large.IsValid());
1687*6777b538SAndroid Build Coastguard Worker too_large += d;
1688*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(too_large.IsValid());
1689*6777b538SAndroid Build Coastguard Worker too_large -= d;
1690*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(too_large.IsValid());
1691*6777b538SAndroid Build Coastguard Worker too_large /= d;
1692*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(too_large.IsValid());
1693*6777b538SAndroid Build Coastguard Worker }
1694*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,TemplatedSafeMath)1695*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, TemplatedSafeMath) {
1696*6777b538SAndroid Build Coastguard Worker // CheckMul and friends can be confusing, as they change behavior depending on
1697*6777b538SAndroid Build Coastguard Worker // where the template is specified.
1698*6777b538SAndroid Build Coastguard Worker uint64_t result;
1699*6777b538SAndroid Build Coastguard Worker short short_one_thousand = 1000;
1700*6777b538SAndroid Build Coastguard Worker // In this case, CheckMul uses template deduction to use the <short> variant,
1701*6777b538SAndroid Build Coastguard Worker // and this will overflow even if assigned to a uint64_t.
1702*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(CheckMul(short_one_thousand, short_one_thousand)
1703*6777b538SAndroid Build Coastguard Worker .AssignIfValid<uint64_t>(&result));
1704*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(CheckMul(short_one_thousand, short_one_thousand).IsValid());
1705*6777b538SAndroid Build Coastguard Worker // In both cases, CheckMul is forced to use the uint64_t template and will not
1706*6777b538SAndroid Build Coastguard Worker // overflow.
1707*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(CheckMul<uint64_t>(short_one_thousand, short_one_thousand)
1708*6777b538SAndroid Build Coastguard Worker .AssignIfValid(&result));
1709*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(CheckMul<uint64_t>(short_one_thousand, short_one_thousand)
1710*6777b538SAndroid Build Coastguard Worker .AssignIfValid<uint64_t>(&result));
1711*6777b538SAndroid Build Coastguard Worker
1712*6777b538SAndroid Build Coastguard Worker uint64_t big_one_thousand = 1000u;
1713*6777b538SAndroid Build Coastguard Worker // Order doesn't matter here: if one of the parameters is uint64_t then the
1714*6777b538SAndroid Build Coastguard Worker // operation is done on a uint64_t.
1715*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(
1716*6777b538SAndroid Build Coastguard Worker CheckMul(big_one_thousand, short_one_thousand).AssignIfValid(&result));
1717*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(
1718*6777b538SAndroid Build Coastguard Worker CheckMul(short_one_thousand, big_one_thousand).AssignIfValid(&result));
1719*6777b538SAndroid Build Coastguard Worker
1720*6777b538SAndroid Build Coastguard Worker // Checked math functions can also take two template type parameters. Here are
1721*6777b538SAndroid Build Coastguard Worker // the results of all four combinations.
1722*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE((CheckMul<short, uint64_t>(1000, 1000).AssignIfValid(&result)));
1723*6777b538SAndroid Build Coastguard Worker
1724*6777b538SAndroid Build Coastguard Worker // Note: Order here does not matter.
1725*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE((CheckMul<uint64_t, short>(1000, 1000).AssignIfValid(&result)));
1726*6777b538SAndroid Build Coastguard Worker
1727*6777b538SAndroid Build Coastguard Worker // Only if both are short will the operation be invalid.
1728*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE((CheckMul<short, short>(1000, 1000).AssignIfValid(&result)));
1729*6777b538SAndroid Build Coastguard Worker
1730*6777b538SAndroid Build Coastguard Worker // Same as above.
1731*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(
1732*6777b538SAndroid Build Coastguard Worker (CheckMul<uint64_t, uint64_t>(1000, 1000).AssignIfValid(&result)));
1733*6777b538SAndroid Build Coastguard Worker }
1734*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,VariadicNumericOperations)1735*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, VariadicNumericOperations) {
1736*6777b538SAndroid Build Coastguard Worker { // Synthetic scope to avoid variable naming collisions.
1737*6777b538SAndroid Build Coastguard Worker auto a = CheckAdd(1, 2UL, MakeCheckedNum(3LL), 4).ValueOrDie();
1738*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<decltype(a)::type>(10), a);
1739*6777b538SAndroid Build Coastguard Worker auto b = CheckSub(MakeCheckedNum(20.0), 2UL, 4).ValueOrDie();
1740*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<decltype(b)::type>(14.0), b);
1741*6777b538SAndroid Build Coastguard Worker auto c = CheckMul(20.0, MakeCheckedNum(1), 5, 3UL).ValueOrDie();
1742*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<decltype(c)::type>(300.0), c);
1743*6777b538SAndroid Build Coastguard Worker auto d = CheckDiv(20.0, 2.0, MakeCheckedNum(5LL), -4).ValueOrDie();
1744*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d);
1745*6777b538SAndroid Build Coastguard Worker auto e = CheckMod(MakeCheckedNum(20), 3).ValueOrDie();
1746*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<decltype(e)::type>(2), e);
1747*6777b538SAndroid Build Coastguard Worker auto f = CheckLsh(1, MakeCheckedNum(2)).ValueOrDie();
1748*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<decltype(f)::type>(4), f);
1749*6777b538SAndroid Build Coastguard Worker auto g = CheckRsh(4, MakeCheckedNum(2)).ValueOrDie();
1750*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<decltype(g)::type>(1), g);
1751*6777b538SAndroid Build Coastguard Worker auto h = CheckRsh(CheckAdd(1, 1, 1, 1), CheckSub(4, 2)).ValueOrDie();
1752*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<decltype(h)::type>(1), h);
1753*6777b538SAndroid Build Coastguard Worker }
1754*6777b538SAndroid Build Coastguard Worker
1755*6777b538SAndroid Build Coastguard Worker {
1756*6777b538SAndroid Build Coastguard Worker auto a = ClampAdd(1, 2UL, MakeClampedNum(3LL), 4);
1757*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<decltype(a)::type>(10), a);
1758*6777b538SAndroid Build Coastguard Worker auto b = ClampSub(MakeClampedNum(20.0), 2UL, 4);
1759*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<decltype(b)::type>(14.0), b);
1760*6777b538SAndroid Build Coastguard Worker auto c = ClampMul(20.0, MakeClampedNum(1), 5, 3UL);
1761*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<decltype(c)::type>(300.0), c);
1762*6777b538SAndroid Build Coastguard Worker auto d = ClampDiv(20.0, 2.0, MakeClampedNum(5LL), -4);
1763*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d);
1764*6777b538SAndroid Build Coastguard Worker auto e = ClampMod(MakeClampedNum(20), 3);
1765*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<decltype(e)::type>(2), e);
1766*6777b538SAndroid Build Coastguard Worker auto f = ClampLsh(1, MakeClampedNum(2U));
1767*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<decltype(f)::type>(4), f);
1768*6777b538SAndroid Build Coastguard Worker auto g = ClampRsh(4, MakeClampedNum(2U));
1769*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<decltype(g)::type>(1), g);
1770*6777b538SAndroid Build Coastguard Worker auto h = ClampRsh(ClampAdd(1, 1, 1, 1), ClampSub(4U, 2));
1771*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<decltype(h)::type>(1), h);
1772*6777b538SAndroid Build Coastguard Worker }
1773*6777b538SAndroid Build Coastguard Worker }
1774*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,CeilInt)1775*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, CeilInt) {
1776*6777b538SAndroid Build Coastguard Worker constexpr float kMax = static_cast<float>(std::numeric_limits<int>::max());
1777*6777b538SAndroid Build Coastguard Worker constexpr float kMin = std::numeric_limits<int>::min();
1778*6777b538SAndroid Build Coastguard Worker constexpr float kInfinity = std::numeric_limits<float>::infinity();
1779*6777b538SAndroid Build Coastguard Worker constexpr float kNaN = std::numeric_limits<float>::quiet_NaN();
1780*6777b538SAndroid Build Coastguard Worker
1781*6777b538SAndroid Build Coastguard Worker constexpr int kIntMax = std::numeric_limits<int>::max();
1782*6777b538SAndroid Build Coastguard Worker constexpr int kIntMin = std::numeric_limits<int>::min();
1783*6777b538SAndroid Build Coastguard Worker
1784*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMax, ClampCeil(kInfinity));
1785*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMax, ClampCeil(kMax));
1786*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMax, ClampCeil(kMax + 100.0f));
1787*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ClampCeil(kNaN));
1788*6777b538SAndroid Build Coastguard Worker
1789*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(-100, ClampCeil(-100.5f));
1790*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ClampCeil(0.0f));
1791*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(101, ClampCeil(100.5f));
1792*6777b538SAndroid Build Coastguard Worker
1793*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMin, ClampCeil(-kInfinity));
1794*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMin, ClampCeil(kMin));
1795*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMin, ClampCeil(kMin - 100.0f));
1796*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ClampCeil(-kNaN));
1797*6777b538SAndroid Build Coastguard Worker }
1798*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,FloorInt)1799*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, FloorInt) {
1800*6777b538SAndroid Build Coastguard Worker constexpr float kMax = static_cast<float>(std::numeric_limits<int>::max());
1801*6777b538SAndroid Build Coastguard Worker constexpr float kMin = std::numeric_limits<int>::min();
1802*6777b538SAndroid Build Coastguard Worker constexpr float kInfinity = std::numeric_limits<float>::infinity();
1803*6777b538SAndroid Build Coastguard Worker constexpr float kNaN = std::numeric_limits<float>::quiet_NaN();
1804*6777b538SAndroid Build Coastguard Worker
1805*6777b538SAndroid Build Coastguard Worker constexpr int kIntMax = std::numeric_limits<int>::max();
1806*6777b538SAndroid Build Coastguard Worker constexpr int kIntMin = std::numeric_limits<int>::min();
1807*6777b538SAndroid Build Coastguard Worker
1808*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMax, ClampFloor(kInfinity));
1809*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMax, ClampFloor(kMax));
1810*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMax, ClampFloor(kMax + 100.0f));
1811*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ClampFloor(kNaN));
1812*6777b538SAndroid Build Coastguard Worker
1813*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(-101, ClampFloor(-100.5f));
1814*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ClampFloor(0.0f));
1815*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(100, ClampFloor(100.5f));
1816*6777b538SAndroid Build Coastguard Worker
1817*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMin, ClampFloor(-kInfinity));
1818*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMin, ClampFloor(kMin));
1819*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMin, ClampFloor(kMin - 100.0f));
1820*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ClampFloor(-kNaN));
1821*6777b538SAndroid Build Coastguard Worker }
1822*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,RoundInt)1823*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, RoundInt) {
1824*6777b538SAndroid Build Coastguard Worker constexpr float kMax = static_cast<float>(std::numeric_limits<int>::max());
1825*6777b538SAndroid Build Coastguard Worker constexpr float kMin = std::numeric_limits<int>::min();
1826*6777b538SAndroid Build Coastguard Worker constexpr float kInfinity = std::numeric_limits<float>::infinity();
1827*6777b538SAndroid Build Coastguard Worker constexpr float kNaN = std::numeric_limits<float>::quiet_NaN();
1828*6777b538SAndroid Build Coastguard Worker
1829*6777b538SAndroid Build Coastguard Worker constexpr int kIntMax = std::numeric_limits<int>::max();
1830*6777b538SAndroid Build Coastguard Worker constexpr int kIntMin = std::numeric_limits<int>::min();
1831*6777b538SAndroid Build Coastguard Worker
1832*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMax, ClampRound(kInfinity));
1833*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMax, ClampRound(kMax));
1834*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMax, ClampRound(kMax + 100.0f));
1835*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ClampRound(kNaN));
1836*6777b538SAndroid Build Coastguard Worker
1837*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(-100, ClampRound(-100.1f));
1838*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(-101, ClampRound(-100.5f));
1839*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(-101, ClampRound(-100.9f));
1840*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ClampRound(std::nextafter(-0.5f, 0.0f)));
1841*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ClampRound(0.0f));
1842*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ClampRound(std::nextafter(0.5f, 0.0f)));
1843*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(100, ClampRound(100.1f));
1844*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(101, ClampRound(100.5f));
1845*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(101, ClampRound(100.9f));
1846*6777b538SAndroid Build Coastguard Worker
1847*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMin, ClampRound(-kInfinity));
1848*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMin, ClampRound(kMin));
1849*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kIntMin, ClampRound(kMin - 100.0f));
1850*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ClampRound(-kNaN));
1851*6777b538SAndroid Build Coastguard Worker }
1852*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,Int64)1853*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, Int64) {
1854*6777b538SAndroid Build Coastguard Worker constexpr double kMax =
1855*6777b538SAndroid Build Coastguard Worker static_cast<double>(std::numeric_limits<int64_t>::max());
1856*6777b538SAndroid Build Coastguard Worker constexpr double kMin = std::numeric_limits<int64_t>::min();
1857*6777b538SAndroid Build Coastguard Worker constexpr double kInfinity = std::numeric_limits<double>::infinity();
1858*6777b538SAndroid Build Coastguard Worker constexpr double kNaN = std::numeric_limits<double>::quiet_NaN();
1859*6777b538SAndroid Build Coastguard Worker
1860*6777b538SAndroid Build Coastguard Worker constexpr int64_t kInt64Max = std::numeric_limits<int64_t>::max();
1861*6777b538SAndroid Build Coastguard Worker constexpr int64_t kInt64Min = std::numeric_limits<int64_t>::min();
1862*6777b538SAndroid Build Coastguard Worker
1863*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Max, ClampFloor<int64_t>(kInfinity));
1864*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Max, ClampCeil<int64_t>(kInfinity));
1865*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Max, ClampRound<int64_t>(kInfinity));
1866*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Max, ClampFloor<int64_t>(kMax));
1867*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Max, ClampCeil<int64_t>(kMax));
1868*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Max, ClampRound<int64_t>(kMax));
1869*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Max, ClampFloor<int64_t>(kMax + 100.0));
1870*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Max, ClampCeil<int64_t>(kMax + 100.0));
1871*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Max, ClampRound<int64_t>(kMax + 100.0));
1872*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ClampFloor<int64_t>(kNaN));
1873*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ClampCeil<int64_t>(kNaN));
1874*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ClampRound<int64_t>(kNaN));
1875*6777b538SAndroid Build Coastguard Worker
1876*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Min, ClampFloor<int64_t>(-kInfinity));
1877*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Min, ClampCeil<int64_t>(-kInfinity));
1878*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Min, ClampRound<int64_t>(-kInfinity));
1879*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Min, ClampFloor<int64_t>(kMin));
1880*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Min, ClampCeil<int64_t>(kMin));
1881*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Min, ClampRound<int64_t>(kMin));
1882*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Min, ClampFloor<int64_t>(kMin - 100.0));
1883*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Min, ClampCeil<int64_t>(kMin - 100.0));
1884*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(kInt64Min, ClampRound<int64_t>(kMin - 100.0));
1885*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ClampFloor<int64_t>(-kNaN));
1886*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ClampCeil<int64_t>(-kNaN));
1887*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, ClampRound<int64_t>(-kNaN));
1888*6777b538SAndroid Build Coastguard Worker }
1889*6777b538SAndroid Build Coastguard Worker
1890*6777b538SAndroid Build Coastguard Worker template <typename T>
TestWrappingMathSigned()1891*6777b538SAndroid Build Coastguard Worker void TestWrappingMathSigned() {
1892*6777b538SAndroid Build Coastguard Worker static_assert(std::is_signed_v<T>);
1893*6777b538SAndroid Build Coastguard Worker constexpr T kMinusTwo = -2;
1894*6777b538SAndroid Build Coastguard Worker constexpr T kMinusOne = -1;
1895*6777b538SAndroid Build Coastguard Worker constexpr T kZero = 0;
1896*6777b538SAndroid Build Coastguard Worker constexpr T kOne = 1;
1897*6777b538SAndroid Build Coastguard Worker constexpr T kTwo = 2;
1898*6777b538SAndroid Build Coastguard Worker constexpr T kThree = 3;
1899*6777b538SAndroid Build Coastguard Worker constexpr T kMax = std::numeric_limits<T>::max();
1900*6777b538SAndroid Build Coastguard Worker constexpr T kMin = std::numeric_limits<T>::min();
1901*6777b538SAndroid Build Coastguard Worker
1902*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingAdd(kOne, kTwo), kThree);
1903*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingAdd(kOne, kTwo) == kThree);
1904*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingAdd(kMax, kOne), kMin);
1905*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingAdd(kMax, kOne) == kMin);
1906*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingAdd(kMax, kTwo), kMin + 1);
1907*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingAdd(kMax, kTwo) == kMin + 1);
1908*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingAdd(kMax, kMax), kMinusTwo);
1909*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingAdd(kMax, kMax) == kMinusTwo);
1910*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingAdd(kMin, kMin), kZero);
1911*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingAdd(kMin, kMin) == kZero);
1912*6777b538SAndroid Build Coastguard Worker
1913*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingSub(kTwo, kOne), kOne);
1914*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingSub(kTwo, kOne) == kOne);
1915*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingSub(kOne, kTwo), kMinusOne);
1916*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingSub(kOne, kTwo) == kMinusOne);
1917*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingSub(kMin, kOne), kMax);
1918*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingSub(kMin, kOne) == kMax);
1919*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingSub(kMin, kTwo), kMax - 1);
1920*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingSub(kMin, kTwo) == kMax - 1);
1921*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingSub(kMax, kMin), kMinusOne);
1922*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingSub(kMax, kMin) == kMinusOne);
1923*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingSub(kMin, kMax), kOne);
1924*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingSub(kMin, kMax) == kOne);
1925*6777b538SAndroid Build Coastguard Worker }
1926*6777b538SAndroid Build Coastguard Worker
1927*6777b538SAndroid Build Coastguard Worker template <typename T>
TestWrappingMathUnsigned()1928*6777b538SAndroid Build Coastguard Worker void TestWrappingMathUnsigned() {
1929*6777b538SAndroid Build Coastguard Worker static_assert(std::is_unsigned_v<T>);
1930*6777b538SAndroid Build Coastguard Worker constexpr T kZero = 0;
1931*6777b538SAndroid Build Coastguard Worker constexpr T kOne = 1;
1932*6777b538SAndroid Build Coastguard Worker constexpr T kTwo = 2;
1933*6777b538SAndroid Build Coastguard Worker constexpr T kThree = 3;
1934*6777b538SAndroid Build Coastguard Worker constexpr T kMax = std::numeric_limits<T>::max();
1935*6777b538SAndroid Build Coastguard Worker
1936*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingAdd(kOne, kTwo), kThree);
1937*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingAdd(kOne, kTwo) == kThree);
1938*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingAdd(kMax, kOne), kZero);
1939*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingAdd(kMax, kOne) == kZero);
1940*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingAdd(kMax, kTwo), kOne);
1941*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingAdd(kMax, kTwo) == kOne);
1942*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingAdd(kMax, kMax), kMax - 1);
1943*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingAdd(kMax, kMax) == kMax - 1);
1944*6777b538SAndroid Build Coastguard Worker
1945*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingSub(kTwo, kOne), kOne);
1946*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingSub(kTwo, kOne) == kOne);
1947*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingSub(kOne, kTwo), kMax);
1948*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingSub(kOne, kTwo) == kMax);
1949*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingSub(kZero, kOne), kMax);
1950*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingSub(kZero, kOne) == kMax);
1951*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(base::WrappingSub(kZero, kTwo), kMax - 1);
1952*6777b538SAndroid Build Coastguard Worker static_assert(base::WrappingSub(kZero, kTwo) == kMax - 1);
1953*6777b538SAndroid Build Coastguard Worker }
1954*6777b538SAndroid Build Coastguard Worker
TEST(SafeNumerics,WrappingMath)1955*6777b538SAndroid Build Coastguard Worker TEST(SafeNumerics, WrappingMath) {
1956*6777b538SAndroid Build Coastguard Worker TestWrappingMathSigned<int8_t>();
1957*6777b538SAndroid Build Coastguard Worker TestWrappingMathUnsigned<uint8_t>();
1958*6777b538SAndroid Build Coastguard Worker TestWrappingMathSigned<int16_t>();
1959*6777b538SAndroid Build Coastguard Worker TestWrappingMathUnsigned<uint16_t>();
1960*6777b538SAndroid Build Coastguard Worker TestWrappingMathSigned<int32_t>();
1961*6777b538SAndroid Build Coastguard Worker TestWrappingMathUnsigned<uint32_t>();
1962*6777b538SAndroid Build Coastguard Worker TestWrappingMathSigned<int64_t>();
1963*6777b538SAndroid Build Coastguard Worker TestWrappingMathUnsigned<uint64_t>();
1964*6777b538SAndroid Build Coastguard Worker }
1965*6777b538SAndroid Build Coastguard Worker
1966*6777b538SAndroid Build Coastguard Worker #if defined(__clang__)
1967*6777b538SAndroid Build Coastguard Worker #pragma clang diagnostic pop // -Winteger-overflow
1968*6777b538SAndroid Build Coastguard Worker #endif
1969*6777b538SAndroid Build Coastguard Worker
1970*6777b538SAndroid Build Coastguard Worker } // namespace internal
1971*6777b538SAndroid Build Coastguard Worker } // namespace base
1972