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