Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: base/numerics/safe_numerics_unittest.cc

Issue 2945433003: Add ClampedNumeric templates (Closed)
Patch Set: final Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/numerics/safe_math_shared_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stddef.h> 5 #include <stddef.h>
6 #include <stdint.h> 6 #include <stdint.h>
7 7
8 #include <limits> 8 #include <limits>
9 #include <type_traits> 9 #include <type_traits>
10 10
11 #include "base/compiler_specific.h" 11 #include "base/compiler_specific.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/numerics/safe_conversions.h" 13 #include "base/numerics/safe_conversions.h"
14 #include "base/numerics/safe_math.h" 14 #include "base/numerics/safe_math.h"
15 #include "base/test/gtest_util.h" 15 #include "base/test/gtest_util.h"
16 #include "build/build_config.h" 16 #include "build/build_config.h"
17 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/gtest/include/gtest/gtest.h"
18 18
19 #if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS) 19 #if defined(COMPILER_MSVC) && defined(ARCH_CPU_32_BITS)
20 #include <mmintrin.h> 20 #include <mmintrin.h>
21 #endif 21 #endif
22 22
23 using std::numeric_limits; 23 using std::numeric_limits;
24 using base::CheckedNumeric; 24 using base::CheckedNumeric;
25 using base::ClampedNumeric;
25 using base::IsValidForType; 26 using base::IsValidForType;
26 using base::ValueOrDieForType; 27 using base::ValueOrDieForType;
27 using base::ValueOrDefaultForType; 28 using base::ValueOrDefaultForType;
28 using base::MakeCheckedNum; 29 using base::MakeCheckedNum;
30 using base::MakeClampedNum;
29 using base::CheckMax; 31 using base::CheckMax;
30 using base::CheckMin; 32 using base::CheckMin;
31 using base::CheckAdd; 33 using base::CheckAdd;
32 using base::CheckSub; 34 using base::CheckSub;
33 using base::CheckMul; 35 using base::CheckMul;
34 using base::CheckDiv; 36 using base::CheckDiv;
35 using base::CheckMod; 37 using base::CheckMod;
36 using base::CheckLsh; 38 using base::CheckLsh;
37 using base::CheckRsh; 39 using base::CheckRsh;
40 using base::ClampMax;
41 using base::ClampMin;
42 using base::ClampAdd;
43 using base::ClampSub;
44 using base::ClampMul;
45 using base::ClampDiv;
46 using base::ClampMod;
47 using base::ClampLsh;
48 using base::ClampRsh;
49 using base::as_unsigned;
38 using base::checked_cast; 50 using base::checked_cast;
39 using base::IsValueInRangeForNumericType; 51 using base::IsValueInRangeForNumericType;
40 using base::IsValueNegative; 52 using base::IsValueNegative;
53 using base::SaturationDefaultLimits;
41 using base::SizeT; 54 using base::SizeT;
42 using base::StrictNumeric; 55 using base::StrictNumeric;
43 using base::MakeStrictNum; 56 using base::MakeStrictNum;
44 using base::saturated_cast; 57 using base::saturated_cast;
45 using base::strict_cast; 58 using base::strict_cast;
46 using base::internal::MaxExponent; 59 using base::internal::MaxExponent;
47 using base::internal::IntegerBitsPlusSign; 60 using base::internal::IntegerBitsPlusSign;
48 using base::internal::RangeCheck; 61 using base::internal::RangeCheck;
49 62
50 // These tests deliberately cause arithmetic boundary errors. If the compiler is 63 // These tests deliberately cause arithmetic boundary errors. If the compiler is
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 ""); 137 "");
125 static_assert(!FastIntegerArithmeticPromotion<intmax_t, int8_t>::is_contained, 138 static_assert(!FastIntegerArithmeticPromotion<intmax_t, int8_t>::is_contained,
126 ""); 139 "");
127 static_assert(!FastIntegerArithmeticPromotion<uintmax_t, int8_t>::is_contained, 140 static_assert(!FastIntegerArithmeticPromotion<uintmax_t, int8_t>::is_contained,
128 ""); 141 "");
129 142
130 template <typename U> 143 template <typename U>
131 U GetNumericValueForTest(const CheckedNumeric<U>& src) { 144 U GetNumericValueForTest(const CheckedNumeric<U>& src) {
132 return src.state_.value(); 145 return src.state_.value();
133 } 146 }
147
148 template <typename U>
149 U GetNumericValueForTest(const ClampedNumeric<U>& src) {
150 return static_cast<U>(src);
151 }
152
153 template <typename U>
154 U GetNumericValueForTest(const U& src) {
155 return src;
156 }
157
134 } // namespace internal. 158 } // namespace internal.
135 } // namespace base. 159 } // namespace base.
136 160
137 using base::internal::GetNumericValueForTest; 161 using base::internal::GetNumericValueForTest;
138 162
139 // Logs the ValueOrDie() failure instead of crashing. 163 // Logs the ValueOrDie() failure instead of crashing.
140 struct LogOnFailure { 164 struct LogOnFailure {
141 template <typename T> 165 template <typename T>
142 static T HandleFailure() { 166 static T HandleFailure() {
143 LOG(WARNING) << "ValueOrDie() failed unexpectedly."; 167 LOG(WARNING) << "ValueOrDie() failed unexpectedly.";
144 return T(); 168 return T();
145 } 169 }
146 }; 170 };
147 171
172 template <typename T>
173 constexpr T GetValue(const T& src) {
174 return src;
175 }
176
177 template <typename T, typename U>
178 constexpr T GetValueAsDest(const U& src) {
179 return static_cast<T>(src);
180 }
181
182 template <typename T>
183 constexpr T GetValue(const CheckedNumeric<T>& src) {
184 return src.template ValueOrDie<T, LogOnFailure>();
185 }
186
187 template <typename T, typename U>
188 constexpr T GetValueAsDest(const CheckedNumeric<U>& src) {
189 return src.template ValueOrDie<T, LogOnFailure>();
190 }
191
192 template <typename T>
193 constexpr T GetValue(const ClampedNumeric<T>& src) {
194 return static_cast<T>(src);
195 }
196
197 template <typename T, typename U>
198 constexpr T GetValueAsDest(const ClampedNumeric<U>& src) {
199 return static_cast<T>(src);
200 }
201
148 // Helper macros to wrap displaying the conversion types and line numbers. 202 // Helper macros to wrap displaying the conversion types and line numbers.
149 #define TEST_EXPECTED_VALIDITY(expected, actual) \ 203 #define TEST_EXPECTED_VALIDITY(expected, actual) \
150 EXPECT_EQ(expected, (actual).template Cast<Dst>().IsValid()) \ 204 EXPECT_EQ(expected, (actual).template Cast<Dst>().IsValid()) \
151 << "Result test: Value " << GetNumericValueForTest(actual) << " as " \ 205 << "Result test: Value " << GetNumericValueForTest(actual) << " as " \
152 << dst << " on line " << line 206 << dst << " on line " << line
153 207
154 #define TEST_EXPECTED_SUCCESS(actual) TEST_EXPECTED_VALIDITY(true, actual) 208 #define TEST_EXPECTED_SUCCESS(actual) TEST_EXPECTED_VALIDITY(true, actual)
155 #define TEST_EXPECTED_FAILURE(actual) TEST_EXPECTED_VALIDITY(false, actual) 209 #define TEST_EXPECTED_FAILURE(actual) TEST_EXPECTED_VALIDITY(false, actual)
156 210
157 // We have to handle promotions, so infer the underlying type below from actual. 211 // We have to handle promotions, so infer the underlying type below from actual.
158 #define TEST_EXPECTED_VALUE(expected, actual) \ 212 #define TEST_EXPECTED_VALUE(expected, actual) \
159 EXPECT_EQ(static_cast<typename std::decay<decltype(actual)>::type::type>( \ 213 EXPECT_EQ(GetValue(expected), GetValueAsDest<decltype(expected)>(actual)) \
160 expected), \
161 ((actual) \
162 .template ValueOrDie< \
163 typename std::decay<decltype(actual)>::type::type, \
164 LogOnFailure>())) \
165 << "Result test: Value " << GetNumericValueForTest(actual) << " as " \ 214 << "Result test: Value " << GetNumericValueForTest(actual) << " as " \
166 << dst << " on line " << line 215 << dst << " on line " << line
167 216
168 // Test the simple pointer arithmetic overrides. 217 // Test the simple pointer arithmetic overrides.
169 template <typename Dst> 218 template <typename Dst>
170 void TestStrictPointerMath() { 219 void TestStrictPointerMath() {
171 Dst dummy_value = 0; 220 Dst dummy_value = 0;
172 Dst* dummy_ptr = &dummy_value; 221 Dst* dummy_ptr = &dummy_value;
173 static const Dst kDummyOffset = 2; // Don't want to go too far. 222 static const Dst kDummyOffset = 2; // Don't want to go too far.
174 EXPECT_EQ(dummy_ptr + kDummyOffset, 223 EXPECT_EQ(dummy_ptr + kDummyOffset,
175 dummy_ptr + StrictNumeric<Dst>(kDummyOffset)); 224 dummy_ptr + StrictNumeric<Dst>(kDummyOffset));
176 EXPECT_EQ(dummy_ptr - kDummyOffset, 225 EXPECT_EQ(dummy_ptr - kDummyOffset,
177 dummy_ptr - StrictNumeric<Dst>(kDummyOffset)); 226 dummy_ptr - StrictNumeric<Dst>(kDummyOffset));
178 EXPECT_NE(dummy_ptr, dummy_ptr + StrictNumeric<Dst>(kDummyOffset)); 227 EXPECT_NE(dummy_ptr, dummy_ptr + StrictNumeric<Dst>(kDummyOffset));
179 EXPECT_NE(dummy_ptr, dummy_ptr - StrictNumeric<Dst>(kDummyOffset)); 228 EXPECT_NE(dummy_ptr, dummy_ptr - StrictNumeric<Dst>(kDummyOffset));
180 EXPECT_DEATH_IF_SUPPORTED( 229 EXPECT_DEATH_IF_SUPPORTED(
181 dummy_ptr + StrictNumeric<size_t>(std::numeric_limits<size_t>::max()), 230 dummy_ptr + StrictNumeric<size_t>(std::numeric_limits<size_t>::max()),
182 ""); 231 "");
183 } 232 }
184 233
185 // Signed integer arithmetic. 234 // Signed integer arithmetic.
186 template <typename Dst> 235 template <typename Dst>
187 static void TestSpecializedArithmetic( 236 static void TestSpecializedArithmetic(
188 const char* dst, 237 const char* dst,
189 int line, 238 int line,
190 typename std::enable_if<numeric_limits<Dst>::is_integer && 239 typename std::enable_if<numeric_limits<Dst>::is_integer &&
191 numeric_limits<Dst>::is_signed, 240 numeric_limits<Dst>::is_signed,
192 int>::type = 0) { 241 int>::type = 0) {
193 using DstLimits = numeric_limits<Dst>; 242 using DstLimits = SaturationDefaultLimits<Dst>;
194 TEST_EXPECTED_FAILURE(-CheckedNumeric<Dst>(DstLimits::lowest())); 243 TEST_EXPECTED_FAILURE(-CheckedNumeric<Dst>(DstLimits::lowest()));
195 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()).Abs()); 244 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()).Abs());
196 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs()); 245 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
197 TEST_EXPECTED_VALUE(DstLimits::max(), 246 TEST_EXPECTED_VALUE(DstLimits::max(),
198 MakeCheckedNum(-DstLimits::max()).Abs()); 247 MakeCheckedNum(-DstLimits::max()).Abs());
199 248
249 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
250 -ClampedNumeric<Dst>(DstLimits::lowest()));
251 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
252 ClampedNumeric<Dst>(DstLimits::lowest()).Abs());
253 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(-1).Abs());
254 TEST_EXPECTED_VALUE(DstLimits::max(),
255 MakeClampedNum(-DstLimits::max()).Abs());
256
200 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + -1); 257 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + -1);
201 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) + -1); 258 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) + -1);
202 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) + 259 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) +
203 DstLimits::lowest()); 260 DstLimits::lowest());
204 261
262 TEST_EXPECTED_VALUE(DstLimits::max() - 1,
263 ClampedNumeric<Dst>(DstLimits::max()) + -1);
264 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
265 ClampedNumeric<Dst>(DstLimits::lowest()) + -1);
266 TEST_EXPECTED_VALUE(
267 DstLimits::Underflow(),
268 ClampedNumeric<Dst>(DstLimits::lowest()) + DstLimits::lowest());
269
205 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) - 1); 270 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) - 1);
206 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) - -1); 271 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) - -1);
207 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - 272 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) -
208 DstLimits::lowest()); 273 DstLimits::lowest());
209 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) - 274 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) -
210 DstLimits::max()); 275 DstLimits::max());
211 276
277 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
278 ClampedNumeric<Dst>(DstLimits::lowest()) - 1);
279 TEST_EXPECTED_VALUE(DstLimits::lowest() + 1,
280 ClampedNumeric<Dst>(DstLimits::lowest()) - -1);
281 TEST_EXPECTED_VALUE(
282 DstLimits::Overflow(),
283 ClampedNumeric<Dst>(DstLimits::max()) - DstLimits::lowest());
284 TEST_EXPECTED_VALUE(
285 DstLimits::Underflow(),
286 ClampedNumeric<Dst>(DstLimits::lowest()) - DstLimits::max());
287
212 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * 2); 288 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * 2);
289 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
290 ClampedNumeric<Dst>(DstLimits::lowest()) * 2);
213 291
214 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) / -1); 292 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) / -1);
215 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) / 2); 293 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) / 2);
216 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * -1); 294 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * -1);
217 TEST_EXPECTED_VALUE(DstLimits::max(), 295 TEST_EXPECTED_VALUE(DstLimits::max(),
218 CheckedNumeric<Dst>(DstLimits::lowest() + 1) * Dst(-1)); 296 CheckedNumeric<Dst>(DstLimits::lowest() + 1) * Dst(-1));
219 TEST_EXPECTED_VALUE(DstLimits::max(), 297 TEST_EXPECTED_VALUE(DstLimits::max(),
220 CheckedNumeric<Dst>(-1) * Dst(DstLimits::lowest() + 1)); 298 CheckedNumeric<Dst>(-1) * Dst(DstLimits::lowest() + 1));
221 TEST_EXPECTED_VALUE(DstLimits::lowest(), 299 TEST_EXPECTED_VALUE(DstLimits::lowest(),
222 CheckedNumeric<Dst>(DstLimits::lowest()) * Dst(1)); 300 CheckedNumeric<Dst>(DstLimits::lowest()) * Dst(1));
223 TEST_EXPECTED_VALUE(DstLimits::lowest(), 301 TEST_EXPECTED_VALUE(DstLimits::lowest(),
224 CheckedNumeric<Dst>(1) * Dst(DstLimits::lowest())); 302 CheckedNumeric<Dst>(1) * Dst(DstLimits::lowest()));
225 TEST_EXPECTED_VALUE(DstLimits::lowest(), 303 TEST_EXPECTED_VALUE(
226 MakeCheckedNum(DstLimits::lowest()).UnsignedAbs()); 304 typename std::make_unsigned<Dst>::type(0) - DstLimits::lowest(),
305 MakeCheckedNum(DstLimits::lowest()).UnsignedAbs());
227 TEST_EXPECTED_VALUE(DstLimits::max(), 306 TEST_EXPECTED_VALUE(DstLimits::max(),
228 MakeCheckedNum(DstLimits::max()).UnsignedAbs()); 307 MakeCheckedNum(DstLimits::max()).UnsignedAbs());
229 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0).UnsignedAbs()); 308 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0).UnsignedAbs());
230 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).UnsignedAbs()); 309 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).UnsignedAbs());
231 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).UnsignedAbs()); 310 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).UnsignedAbs());
232 311
312 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
313 ClampedNumeric<Dst>(DstLimits::lowest()) / -1);
314 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(-1) / 2);
315 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
316 ClampedNumeric<Dst>(DstLimits::lowest()) * -1);
317 TEST_EXPECTED_VALUE(DstLimits::max(),
318 ClampedNumeric<Dst>(DstLimits::lowest() + 1) * Dst(-1));
319 TEST_EXPECTED_VALUE(DstLimits::max(),
320 ClampedNumeric<Dst>(-1) * Dst(DstLimits::lowest() + 1));
321 TEST_EXPECTED_VALUE(DstLimits::lowest(),
322 ClampedNumeric<Dst>(DstLimits::lowest()) * Dst(1));
323 TEST_EXPECTED_VALUE(DstLimits::lowest(),
324 ClampedNumeric<Dst>(1) * Dst(DstLimits::lowest()));
325 TEST_EXPECTED_VALUE(
326 typename std::make_unsigned<Dst>::type(0) - DstLimits::lowest(),
327 MakeClampedNum(DstLimits::lowest()).UnsignedAbs());
328 TEST_EXPECTED_VALUE(DstLimits::max(),
329 MakeClampedNum(DstLimits::max()).UnsignedAbs());
330 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0).UnsignedAbs());
331 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1).UnsignedAbs());
332 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(-1).UnsignedAbs());
333
233 // Modulus is legal only for integers. 334 // Modulus is legal only for integers.
234 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1); 335 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);
235 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); 336 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
236 TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % 2); 337 TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % 2);
237 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(-1) % -2); 338 TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % -2);
238 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % 2); 339 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % 2);
239 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2); 340 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2);
240 // Test all the different modulus combinations. 341 // Test all the different modulus combinations.
241 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1)); 342 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1));
242 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1)); 343 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1));
243 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); 344 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
244 CheckedNumeric<Dst> checked_dst = 1; 345 CheckedNumeric<Dst> checked_dst = 1;
245 TEST_EXPECTED_VALUE(0, checked_dst %= 1); 346 TEST_EXPECTED_VALUE(0, checked_dst %= 1);
246 // Test that div by 0 is avoided but returns invalid result. 347 // Test that div by 0 is avoided but returns invalid result.
247 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) % 0); 348 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) % 0);
(...skipping 11 matching lines...) Expand all
259 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) 360 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0)
260 << (IntegerBitsPlusSign<Dst>::value - 1)); 361 << (IntegerBitsPlusSign<Dst>::value - 1));
261 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) << 0); 362 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) << 0);
262 TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) << 1); 363 TEST_EXPECTED_VALUE(2, CheckedNumeric<Dst>(1) << 1);
263 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >> 364 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >>
264 IntegerBitsPlusSign<Dst>::value); 365 IntegerBitsPlusSign<Dst>::value);
265 TEST_EXPECTED_VALUE( 366 TEST_EXPECTED_VALUE(
266 0, CheckedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value - 1)); 367 0, CheckedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value - 1));
267 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >> negative_one); 368 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) >> negative_one);
268 369
370 // Modulus is legal only for integers.
371 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>() % 1);
372 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
373 TEST_EXPECTED_VALUE(-1, ClampedNumeric<Dst>(-1) % 2);
374 TEST_EXPECTED_VALUE(-1, ClampedNumeric<Dst>(-1) % -2);
375 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % 2);
376 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(DstLimits::max()) % 2);
377 // Test all the different modulus combinations.
378 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % ClampedNumeric<Dst>(1));
379 TEST_EXPECTED_VALUE(0, 1 % ClampedNumeric<Dst>(1));
380 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
381 ClampedNumeric<Dst> clamped_dst = 1;
382 TEST_EXPECTED_VALUE(0, clamped_dst %= 1);
383 TEST_EXPECTED_VALUE(Dst(1), ClampedNumeric<Dst>(1) % 0);
384 // Test bit shifts.
385 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
386 ClampedNumeric<Dst>(1)
387 << (IntegerBitsPlusSign<Dst>::value - 1U));
388 TEST_EXPECTED_VALUE(Dst(0), ClampedNumeric<Dst>(0)
389 << (IntegerBitsPlusSign<Dst>::value + 0U));
390 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
391 ClampedNumeric<Dst>(DstLimits::max()) << 1U);
392 TEST_EXPECTED_VALUE(
393 static_cast<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 2U),
394 ClampedNumeric<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 2U));
395 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0)
396 << (IntegerBitsPlusSign<Dst>::value - 1U));
397 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) << 0U);
398 TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) << 1U);
399 TEST_EXPECTED_VALUE(
400 0, ClampedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value + 0U));
401 TEST_EXPECTED_VALUE(
402 0, ClampedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value - 1U));
403 TEST_EXPECTED_VALUE(
404 -1, ClampedNumeric<Dst>(-1) >> (IntegerBitsPlusSign<Dst>::value - 1U));
405 TEST_EXPECTED_VALUE(-1, ClampedNumeric<Dst>(DstLimits::lowest()) >>
406 (IntegerBitsPlusSign<Dst>::value - 0U));
407
269 TestStrictPointerMath<Dst>(); 408 TestStrictPointerMath<Dst>();
270 } 409 }
271 410
272 // Unsigned integer arithmetic. 411 // Unsigned integer arithmetic.
273 template <typename Dst> 412 template <typename Dst>
274 static void TestSpecializedArithmetic( 413 static void TestSpecializedArithmetic(
275 const char* dst, 414 const char* dst,
276 int line, 415 int line,
277 typename std::enable_if<numeric_limits<Dst>::is_integer && 416 typename std::enable_if<numeric_limits<Dst>::is_integer &&
278 !numeric_limits<Dst>::is_signed, 417 !numeric_limits<Dst>::is_signed,
279 int>::type = 0) { 418 int>::type = 0) {
280 using DstLimits = numeric_limits<Dst>; 419 using DstLimits = SaturationDefaultLimits<Dst>;
281 TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::lowest())); 420 TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::lowest()));
282 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).Abs()); 421 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).Abs());
283 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) + -1); 422 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) + -1);
284 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) - 1); 423 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) - 1);
285 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) * 2); 424 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) * 2);
286 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) / 2); 425 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) / 2);
287 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).UnsignedAbs()); 426 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).UnsignedAbs());
288 TEST_EXPECTED_SUCCESS( 427 TEST_EXPECTED_SUCCESS(
289 CheckedNumeric<typename std::make_signed<Dst>::type>( 428 CheckedNumeric<typename std::make_signed<Dst>::type>(
290 std::numeric_limits<typename std::make_signed<Dst>::type>::lowest()) 429 std::numeric_limits<typename std::make_signed<Dst>::type>::lowest())
291 .UnsignedAbs()); 430 .UnsignedAbs());
292 TEST_EXPECTED_VALUE(DstLimits::lowest(), 431 TEST_EXPECTED_VALUE(DstLimits::lowest(),
293 MakeCheckedNum(DstLimits::lowest()).UnsignedAbs()); 432 MakeCheckedNum(DstLimits::lowest()).UnsignedAbs());
294 TEST_EXPECTED_VALUE(DstLimits::max(), 433 TEST_EXPECTED_VALUE(DstLimits::max(),
295 MakeCheckedNum(DstLimits::max()).UnsignedAbs()); 434 MakeCheckedNum(DstLimits::max()).UnsignedAbs());
296 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0).UnsignedAbs()); 435 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0).UnsignedAbs());
297 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).UnsignedAbs()); 436 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).UnsignedAbs());
298 437
438 TEST_EXPECTED_VALUE(0, -ClampedNumeric<Dst>(DstLimits::lowest()));
439 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()).Abs());
440 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
441 ClampedNumeric<Dst>(DstLimits::lowest()) + -1);
442 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
443 ClampedNumeric<Dst>(DstLimits::lowest()) - 1);
444 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) * 2);
445 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) / 2);
446 TEST_EXPECTED_VALUE(0,
447 ClampedNumeric<Dst>(DstLimits::lowest()).UnsignedAbs());
448 TEST_EXPECTED_VALUE(
449 as_unsigned(
450 std::numeric_limits<typename std::make_signed<Dst>::type>::lowest()),
451 ClampedNumeric<typename std::make_signed<Dst>::type>(
452 std::numeric_limits<typename std::make_signed<Dst>::type>::lowest())
453 .UnsignedAbs());
454 TEST_EXPECTED_VALUE(DstLimits::lowest(),
455 MakeClampedNum(DstLimits::lowest()).UnsignedAbs());
456 TEST_EXPECTED_VALUE(DstLimits::max(),
457 MakeClampedNum(DstLimits::max()).UnsignedAbs());
458 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0).UnsignedAbs());
459 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1).UnsignedAbs());
460
299 // Modulus is legal only for integers. 461 // Modulus is legal only for integers.
300 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1); 462 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);
301 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); 463 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
302 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2); 464 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2);
303 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % 2); 465 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % 2);
304 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2); 466 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2);
305 // Test all the different modulus combinations. 467 // Test all the different modulus combinations.
306 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1)); 468 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1));
307 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1)); 469 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1));
308 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); 470 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(), 505 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
344 CheckedNumeric<Dst>(0) | static_cast<Dst>(-1)); 506 CheckedNumeric<Dst>(0) | static_cast<Dst>(-1));
345 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) ^ 1); 507 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) ^ 1);
346 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) ^ 0); 508 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) ^ 0);
347 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(0) ^ 1); 509 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(0) ^ 1);
348 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) ^ 0); 510 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) ^ 0);
349 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(), 511 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
350 CheckedNumeric<Dst>(0) ^ static_cast<Dst>(-1)); 512 CheckedNumeric<Dst>(0) ^ static_cast<Dst>(-1));
351 TEST_EXPECTED_VALUE(DstLimits::max(), ~CheckedNumeric<Dst>(0)); 513 TEST_EXPECTED_VALUE(DstLimits::max(), ~CheckedNumeric<Dst>(0));
352 514
515 // Modulus is legal only for integers.
516 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>() % 1);
517 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
518 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) % 2);
519 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % 2);
520 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(DstLimits::max()) % 2);
521 // Test all the different modulus combinations.
522 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % ClampedNumeric<Dst>(1));
523 TEST_EXPECTED_VALUE(0, 1 % ClampedNumeric<Dst>(1));
524 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
525 ClampedNumeric<Dst> clamped_dst = 1;
526 TEST_EXPECTED_VALUE(0, clamped_dst %= 1);
527 // Test that div by 0 is avoided but returns invalid result.
528 TEST_EXPECTED_VALUE(Dst(1), ClampedNumeric<Dst>(1) % 0);
529 // Test bit shifts.
530 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
531 ClampedNumeric<Dst>(1)
532 << as_unsigned(IntegerBitsPlusSign<Dst>::value));
533 TEST_EXPECTED_VALUE(Dst(0), ClampedNumeric<Dst>(0) << as_unsigned(
534 IntegerBitsPlusSign<Dst>::value));
535 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
536 ClampedNumeric<Dst>(DstLimits::max()) << 1U);
537 TEST_EXPECTED_VALUE(
538 static_cast<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 1U),
539 ClampedNumeric<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 1U));
540 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) << 0U);
541 TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) << 1U);
542 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) >>
543 as_unsigned(IntegerBitsPlusSign<Dst>::value));
544 TEST_EXPECTED_VALUE(
545 0, ClampedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value - 1U));
546 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) & 1);
547 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) & 0);
548 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) & 1);
549 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) & 0);
550 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
551 MakeClampedNum(DstLimits::max()) & -1);
552 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) | 1);
553 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) | 0);
554 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(0) | 1);
555 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) | 0);
556 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
557 ClampedNumeric<Dst>(0) | static_cast<Dst>(-1));
558 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) ^ 1);
559 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) ^ 0);
560 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(0) ^ 1);
561 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) ^ 0);
562 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
563 ClampedNumeric<Dst>(0) ^ static_cast<Dst>(-1));
564 TEST_EXPECTED_VALUE(DstLimits::max(), ~ClampedNumeric<Dst>(0));
565
353 TestStrictPointerMath<Dst>(); 566 TestStrictPointerMath<Dst>();
354 } 567 }
355 568
356 // Floating point arithmetic. 569 // Floating point arithmetic.
357 template <typename Dst> 570 template <typename Dst>
358 void TestSpecializedArithmetic( 571 void TestSpecializedArithmetic(
359 const char* dst, 572 const char* dst,
360 int line, 573 int line,
361 typename std::enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) { 574 typename std::enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) {
362 using DstLimits = numeric_limits<Dst>; 575 using DstLimits = SaturationDefaultLimits<Dst>;
363 TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::lowest())); 576 TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::lowest()));
364 577
365 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).Abs()); 578 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).Abs());
366 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs()); 579 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
367 580
368 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) + -1); 581 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) + -1);
369 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + 1); 582 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + 1);
370 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) + 583 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) +
371 DstLimits::lowest()); 584 DstLimits::lowest());
372 585
373 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - 586 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) -
374 DstLimits::lowest()); 587 DstLimits::lowest());
375 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) - 588 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) -
376 DstLimits::max()); 589 DstLimits::max());
377 590
378 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * 2); 591 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * 2);
379 592
380 TEST_EXPECTED_VALUE(-0.5, CheckedNumeric<Dst>(-1.0) / 2); 593 TEST_EXPECTED_VALUE(-0.5, CheckedNumeric<Dst>(-1.0) / 2);
594
595 TEST_EXPECTED_VALUE(DstLimits::max(),
596 -ClampedNumeric<Dst>(DstLimits::lowest()));
597
598 TEST_EXPECTED_VALUE(DstLimits::max(),
599 ClampedNumeric<Dst>(DstLimits::lowest()).Abs());
600 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(-1).Abs());
601
602 TEST_EXPECTED_VALUE(DstLimits::lowest() - 1,
603 ClampedNumeric<Dst>(DstLimits::lowest()) + -1);
604 TEST_EXPECTED_VALUE(DstLimits::max() + 1,
605 ClampedNumeric<Dst>(DstLimits::max()) + 1);
606 TEST_EXPECTED_VALUE(
607 DstLimits::Underflow(),
608 ClampedNumeric<Dst>(DstLimits::lowest()) + DstLimits::lowest());
609
610 TEST_EXPECTED_VALUE(
611 DstLimits::Overflow(),
612 ClampedNumeric<Dst>(DstLimits::max()) - DstLimits::lowest());
613 TEST_EXPECTED_VALUE(
614 DstLimits::Underflow(),
615 ClampedNumeric<Dst>(DstLimits::lowest()) - DstLimits::max());
616
617 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
618 ClampedNumeric<Dst>(DstLimits::lowest()) * 2);
619
620 TEST_EXPECTED_VALUE(-0.5, ClampedNumeric<Dst>(-1.0) / 2);
381 } 621 }
382 622
383 // Generic arithmetic tests. 623 // Generic arithmetic tests.
384 template <typename Dst> 624 template <typename Dst>
385 static void TestArithmetic(const char* dst, int line) { 625 static void TestArithmetic(const char* dst, int line) {
386 using DstLimits = numeric_limits<Dst>; 626 using DstLimits = SaturationDefaultLimits<Dst>;
387 627
388 EXPECT_EQ(true, CheckedNumeric<Dst>().IsValid()); 628 EXPECT_EQ(true, CheckedNumeric<Dst>().IsValid());
389 EXPECT_EQ(false, 629 EXPECT_EQ(false,
390 CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) * 630 CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) *
391 DstLimits::max()).IsValid()); 631 DstLimits::max()).IsValid());
392 EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDie()); 632 EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDie());
393 EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDefault(1)); 633 EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDefault(1));
394 EXPECT_EQ(static_cast<Dst>(1), 634 EXPECT_EQ(static_cast<Dst>(1),
395 CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) * 635 CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) *
396 DstLimits::max()).ValueOrDefault(1)); 636 DstLimits::max()).ValueOrDefault(1));
(...skipping 13 matching lines...) Expand all
410 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1); 650 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
411 CheckedNumeric<Dst> checked_dst = 1; 651 CheckedNumeric<Dst> checked_dst = 1;
412 TEST_EXPECTED_VALUE(2, checked_dst += 1); 652 TEST_EXPECTED_VALUE(2, checked_dst += 1);
413 checked_dst = 1; 653 checked_dst = 1;
414 TEST_EXPECTED_VALUE(0, checked_dst -= 1); 654 TEST_EXPECTED_VALUE(0, checked_dst -= 1);
415 checked_dst = 1; 655 checked_dst = 1;
416 TEST_EXPECTED_VALUE(1, checked_dst *= 1); 656 TEST_EXPECTED_VALUE(1, checked_dst *= 1);
417 checked_dst = 1; 657 checked_dst = 1;
418 TEST_EXPECTED_VALUE(1, checked_dst /= 1); 658 TEST_EXPECTED_VALUE(1, checked_dst /= 1);
419 659
660 TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) + ClampedNumeric<Dst>(1));
661 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) - ClampedNumeric<Dst>(1));
662 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) * ClampedNumeric<Dst>(1));
663 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) / ClampedNumeric<Dst>(1));
664 TEST_EXPECTED_VALUE(2, 1 + ClampedNumeric<Dst>(1));
665 TEST_EXPECTED_VALUE(0, 1 - ClampedNumeric<Dst>(1));
666 TEST_EXPECTED_VALUE(1, 1 * ClampedNumeric<Dst>(1));
667 TEST_EXPECTED_VALUE(1, 1 / ClampedNumeric<Dst>(1));
668 TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) + 1);
669 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) - 1);
670 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) * 1);
671 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) / 1);
672 ClampedNumeric<Dst> clamped_dst = 1;
673 TEST_EXPECTED_VALUE(2, clamped_dst += 1);
674 clamped_dst = 1;
675 TEST_EXPECTED_VALUE(0, clamped_dst -= 1);
676 clamped_dst = 1;
677 TEST_EXPECTED_VALUE(1, clamped_dst *= 1);
678 clamped_dst = 1;
679 TEST_EXPECTED_VALUE(1, clamped_dst /= 1);
680
420 // Generic negation. 681 // Generic negation.
421 if (DstLimits::is_signed) { 682 if (DstLimits::is_signed) {
422 TEST_EXPECTED_VALUE(0, -CheckedNumeric<Dst>()); 683 TEST_EXPECTED_VALUE(0, -CheckedNumeric<Dst>());
423 TEST_EXPECTED_VALUE(-1, -CheckedNumeric<Dst>(1)); 684 TEST_EXPECTED_VALUE(-1, -CheckedNumeric<Dst>(1));
424 TEST_EXPECTED_VALUE(1, -CheckedNumeric<Dst>(-1)); 685 TEST_EXPECTED_VALUE(1, -CheckedNumeric<Dst>(-1));
425 TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1), 686 TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1),
426 -CheckedNumeric<Dst>(DstLimits::max())); 687 -CheckedNumeric<Dst>(DstLimits::max()));
688
689 TEST_EXPECTED_VALUE(0, -ClampedNumeric<Dst>());
690 TEST_EXPECTED_VALUE(-1, -ClampedNumeric<Dst>(1));
691 TEST_EXPECTED_VALUE(1, -ClampedNumeric<Dst>(-1));
692 TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1),
693 -ClampedNumeric<Dst>(DstLimits::max()));
427 } 694 }
428 695
429 // Generic absolute value. 696 // Generic absolute value.
430 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>().Abs()); 697 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>().Abs());
431 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).Abs()); 698 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).Abs());
432 TEST_EXPECTED_VALUE(DstLimits::max(), 699 TEST_EXPECTED_VALUE(DstLimits::max(),
433 CheckedNumeric<Dst>(DstLimits::max()).Abs()); 700 CheckedNumeric<Dst>(DstLimits::max()).Abs());
434 701
702 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>().Abs());
703 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1).Abs());
704 TEST_EXPECTED_VALUE(DstLimits::max(),
705 ClampedNumeric<Dst>(DstLimits::max()).Abs());
706
435 // Generic addition. 707 // Generic addition.
436 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>() + 1)); 708 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>() + 1));
437 TEST_EXPECTED_VALUE(2, (CheckedNumeric<Dst>(1) + 1)); 709 TEST_EXPECTED_VALUE(2, (CheckedNumeric<Dst>(1) + 1));
438 if (numeric_limits<Dst>::is_signed) 710 if (numeric_limits<Dst>::is_signed)
439 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) + 1)); 711 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) + 1));
440 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) + 1); 712 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) + 1);
441 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) + 713 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) +
442 DstLimits::max()); 714 DstLimits::max());
443 715
716 TEST_EXPECTED_VALUE(1, (ClampedNumeric<Dst>() + 1));
717 TEST_EXPECTED_VALUE(2, (ClampedNumeric<Dst>(1) + 1));
718 if (numeric_limits<Dst>::is_signed)
719 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(-1) + 1));
720 TEST_EXPECTED_VALUE(DstLimits::lowest() + 1,
721 ClampedNumeric<Dst>(DstLimits::lowest()) + 1);
722 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
723 ClampedNumeric<Dst>(DstLimits::max()) + DstLimits::max());
724
444 // Generic subtraction. 725 // Generic subtraction.
445 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(1) - 1)); 726 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(1) - 1));
446 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) - 1); 727 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) - 1);
447 if (numeric_limits<Dst>::is_signed) { 728 if (numeric_limits<Dst>::is_signed) {
448 TEST_EXPECTED_VALUE(-1, (CheckedNumeric<Dst>() - 1)); 729 TEST_EXPECTED_VALUE(-1, (CheckedNumeric<Dst>() - 1));
449 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) - 1)); 730 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) - 1));
450 } else { 731 } else {
451 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - -1); 732 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - -1);
452 } 733 }
453 734
735 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(1) - 1));
736 TEST_EXPECTED_VALUE(DstLimits::max() - 1,
737 ClampedNumeric<Dst>(DstLimits::max()) - 1);
738 if (numeric_limits<Dst>::is_signed) {
739 TEST_EXPECTED_VALUE(-1, (ClampedNumeric<Dst>() - 1));
740 TEST_EXPECTED_VALUE(-2, (ClampedNumeric<Dst>(-1) - 1));
741 } else {
742 TEST_EXPECTED_VALUE(DstLimits::max(),
743 ClampedNumeric<Dst>(DstLimits::max()) - -1);
744 }
745
454 // Generic multiplication. 746 // Generic multiplication.
455 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>() * 1)); 747 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>() * 1));
456 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>(1) * 1)); 748 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>(1) * 1));
457 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * 0)); 749 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * 0));
458 if (numeric_limits<Dst>::is_signed) { 750 if (numeric_limits<Dst>::is_signed) {
459 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) * 0)); 751 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) * 0));
460 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * -1)); 752 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * -1));
461 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) * 2)); 753 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) * 2));
462 } else { 754 } else {
463 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * -2); 755 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * -2);
464 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * 756 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) *
465 CheckedNumeric<uintmax_t>(-2)); 757 CheckedNumeric<uintmax_t>(-2));
466 } 758 }
467 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * 759 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) *
468 DstLimits::max()); 760 DstLimits::max());
469 761
762 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>() * 1));
763 TEST_EXPECTED_VALUE(1, (ClampedNumeric<Dst>(1) * 1));
764 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(0) * 0));
765 if (numeric_limits<Dst>::is_signed) {
766 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(-1) * 0));
767 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(0) * -1));
768 TEST_EXPECTED_VALUE(-2, (ClampedNumeric<Dst>(-1) * 2));
769 } else {
770 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
771 ClampedNumeric<Dst>(DstLimits::max()) * -2);
772 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::max()) *
773 ClampedNumeric<uintmax_t>(-2));
774 }
775 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
776 ClampedNumeric<Dst>(DstLimits::max()) * DstLimits::max());
777
470 // Generic division. 778 // Generic division.
471 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() / 1); 779 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() / 1);
472 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1); 780 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
473 TEST_EXPECTED_VALUE(DstLimits::lowest() / 2, 781 TEST_EXPECTED_VALUE(DstLimits::lowest() / 2,
474 CheckedNumeric<Dst>(DstLimits::lowest()) / 2); 782 CheckedNumeric<Dst>(DstLimits::lowest()) / 2);
475 TEST_EXPECTED_VALUE(DstLimits::max() / 2, 783 TEST_EXPECTED_VALUE(DstLimits::max() / 2,
476 CheckedNumeric<Dst>(DstLimits::max()) / 2); 784 CheckedNumeric<Dst>(DstLimits::max()) / 2);
785 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) / 0);
786
787 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>() / 1);
788 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) / 1);
789 TEST_EXPECTED_VALUE(DstLimits::lowest() / 2,
790 ClampedNumeric<Dst>(DstLimits::lowest()) / 2);
791 TEST_EXPECTED_VALUE(DstLimits::max() / 2,
792 ClampedNumeric<Dst>(DstLimits::max()) / 2);
793 TEST_EXPECTED_VALUE(DstLimits::Overflow(), ClampedNumeric<Dst>(1) / 0);
794 TEST_EXPECTED_VALUE(DstLimits::Underflow(), ClampedNumeric<Dst>(-1) / 0);
795 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) / 0);
477 796
478 TestSpecializedArithmetic<Dst>(dst, line); 797 TestSpecializedArithmetic<Dst>(dst, line);
479 } 798 }
480 799
481 // Helper macro to wrap displaying the conversion types and line numbers. 800 // Helper macro to wrap displaying the conversion types and line numbers.
482 #define TEST_ARITHMETIC(Dst) TestArithmetic<Dst>(#Dst, __LINE__) 801 #define TEST_ARITHMETIC(Dst) TestArithmetic<Dst>(#Dst, __LINE__)
483 802
484 TEST(SafeNumerics, SignedIntegerMath) { 803 TEST(SafeNumerics, SignedIntegerMath) {
485 TEST_ARITHMETIC(int8_t); 804 TEST_ARITHMETIC(int8_t);
486 TEST_ARITHMETIC(int); 805 TEST_ARITHMETIC(int);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 DstLimits::max(), SrcLimits::lowest()) 917 DstLimits::max(), SrcLimits::lowest())
599 .ValueOrDie()); 918 .ValueOrDie());
600 EXPECT_EQ(DstLimits::max(), CheckMax(MakeStrictNum(1), MakeCheckedNum(0), 919 EXPECT_EQ(DstLimits::max(), CheckMax(MakeStrictNum(1), MakeCheckedNum(0),
601 DstLimits::max(), SrcLimits::lowest()) 920 DstLimits::max(), SrcLimits::lowest())
602 .ValueOrDie()); 921 .ValueOrDie());
603 } 922 }
604 923
605 template <typename Dst, typename Src> 924 template <typename Dst, typename Src>
606 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> { 925 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> {
607 static void Test(const char *dst, const char *src, int line) { 926 static void Test(const char *dst, const char *src, int line) {
608 using SrcLimits = numeric_limits<Src>; 927 using SrcLimits = SaturationDefaultLimits<Src>;
609 using DstLimits = numeric_limits<Dst>; 928 using DstLimits = SaturationDefaultLimits<Dst>;
610 // Integral to floating. 929 // Integral to floating.
611 static_assert((DstLimits::is_iec559 && SrcLimits::is_integer) || 930 static_assert((DstLimits::is_iec559 && SrcLimits::is_integer) ||
612 // Not floating to integral and... 931 // Not floating to integral and...
613 (!(DstLimits::is_integer && SrcLimits::is_iec559) && 932 (!(DstLimits::is_integer && SrcLimits::is_iec559) &&
614 // Same sign, same numeric, source is narrower or same. 933 // Same sign, same numeric, source is narrower or same.
615 ((SrcLimits::is_signed == DstLimits::is_signed && 934 ((SrcLimits::is_signed == DstLimits::is_signed &&
616 MaxExponent<Dst>::value >= MaxExponent<Src>::value) || 935 MaxExponent<Dst>::value >= MaxExponent<Src>::value) ||
617 // Or signed destination and source is smaller 936 // Or signed destination and source is smaller
618 (DstLimits::is_signed && 937 (DstLimits::is_signed &&
619 MaxExponent<Dst>::value >= MaxExponent<Src>::value))), 938 MaxExponent<Dst>::value >= MaxExponent<Src>::value))),
620 "Comparison must be sign preserving and value preserving"); 939 "Comparison must be sign preserving and value preserving");
621 940
622 TestStrictComparison<Dst, Src>(); 941 TestStrictComparison<Dst, Src>();
623 942
624 const CheckedNumeric<Dst> checked_dst = SrcLimits::max(); 943 const CheckedNumeric<Dst> checked_dst = SrcLimits::max();
944 const ClampedNumeric<Dst> clamped_dst = SrcLimits::max();
625 TEST_EXPECTED_SUCCESS(checked_dst); 945 TEST_EXPECTED_SUCCESS(checked_dst);
946 TEST_EXPECTED_VALUE(Dst(SrcLimits::max()), clamped_dst);
626 if (MaxExponent<Dst>::value > MaxExponent<Src>::value) { 947 if (MaxExponent<Dst>::value > MaxExponent<Src>::value) {
627 if (MaxExponent<Dst>::value >= MaxExponent<Src>::value * 2 - 1) { 948 if (MaxExponent<Dst>::value >= MaxExponent<Src>::value * 2 - 1) {
628 // At least twice larger type. 949 // At least twice larger type.
629 TEST_EXPECTED_SUCCESS(SrcLimits::max() * checked_dst); 950 TEST_EXPECTED_SUCCESS(SrcLimits::max() * checked_dst);
630 951 TEST_EXPECTED_VALUE(SrcLimits::max() * clamped_dst,
952 Dst(SrcLimits::max()) * SrcLimits::max());
631 } else { // Larger, but not at least twice as large. 953 } else { // Larger, but not at least twice as large.
632 TEST_EXPECTED_FAILURE(SrcLimits::max() * checked_dst); 954 TEST_EXPECTED_FAILURE(SrcLimits::max() * checked_dst);
633 TEST_EXPECTED_SUCCESS(checked_dst + 1); 955 TEST_EXPECTED_SUCCESS(checked_dst + 1);
956 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
957 SrcLimits::max() * clamped_dst);
958 TEST_EXPECTED_VALUE(Dst(SrcLimits::max()) + Dst(1),
959 clamped_dst + Dst(1));
634 } 960 }
635 } else { // Same width type. 961 } else { // Same width type.
636 TEST_EXPECTED_FAILURE(checked_dst + 1); 962 TEST_EXPECTED_FAILURE(checked_dst + 1);
963 TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + Dst(1));
637 } 964 }
638 965
639 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max()); 966 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
640 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 967 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
641 if (SrcLimits::is_iec559) { 968 if (SrcLimits::is_iec559) {
642 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast<Src>(-1)); 969 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast<Src>(-1));
643 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); 970 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
644 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); 971 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
645 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); 972 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
646 } else if (numeric_limits<Src>::is_signed) { 973 } else if (numeric_limits<Src>::is_signed) {
647 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); 974 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
648 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest()); 975 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest());
649 } 976 }
650 } 977 }
651 }; 978 };
652 979
653 template <typename Dst, typename Src> 980 template <typename Dst, typename Src>
654 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW> { 981 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW> {
655 static void Test(const char *dst, const char *src, int line) { 982 static void Test(const char *dst, const char *src, int line) {
656 using SrcLimits = numeric_limits<Src>; 983 using SrcLimits = SaturationDefaultLimits<Src>;
657 using DstLimits = numeric_limits<Dst>; 984 using DstLimits = SaturationDefaultLimits<Dst>;
658 static_assert(SrcLimits::is_signed == DstLimits::is_signed, 985 static_assert(SrcLimits::is_signed == DstLimits::is_signed,
659 "Destination and source sign must be the same"); 986 "Destination and source sign must be the same");
660 static_assert(MaxExponent<Dst>::value <= MaxExponent<Src>::value, 987 static_assert(MaxExponent<Dst>::value <= MaxExponent<Src>::value,
661 "Destination must be narrower than source"); 988 "Destination must be narrower than source");
662 989
663 TestStrictComparison<Dst, Src>(); 990 TestStrictComparison<Dst, Src>();
664 991
665 const CheckedNumeric<Dst> checked_dst; 992 const CheckedNumeric<Dst> checked_dst;
666 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max()); 993 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
667 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); 994 TEST_EXPECTED_VALUE(1, checked_dst + Src(1));
668 TEST_EXPECTED_FAILURE(checked_dst - SrcLimits::max()); 995 TEST_EXPECTED_FAILURE(checked_dst - SrcLimits::max());
669 996
997 const ClampedNumeric<Dst> clamped_dst;
998 TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + SrcLimits::max());
999 TEST_EXPECTED_VALUE(1, clamped_dst + Src(1));
1000 TEST_EXPECTED_VALUE(DstLimits::Underflow(), clamped_dst - SrcLimits::max());
1001
670 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); 1002 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
671 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 1003 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
672 if (SrcLimits::is_iec559) { 1004 if (SrcLimits::is_iec559) {
673 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); 1005 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
674 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); 1006 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
675 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); 1007 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
676 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); 1008 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
677 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); 1009 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
678 if (DstLimits::is_integer) { 1010 if (DstLimits::is_integer) {
679 if (SrcLimits::digits < DstLimits::digits) { 1011 if (SrcLimits::digits < DstLimits::digits) {
680 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, 1012 TEST_EXPECTED_RANGE(RANGE_OVERFLOW,
681 static_cast<Src>(DstLimits::max())); 1013 static_cast<Src>(DstLimits::max()));
682 } else { 1014 } else {
683 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max())); 1015 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
684 } 1016 }
685 TEST_EXPECTED_RANGE( 1017 TEST_EXPECTED_RANGE(
686 RANGE_VALID, 1018 RANGE_VALID,
687 static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>())); 1019 static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
688 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::lowest())); 1020 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::lowest()));
689 } 1021 }
690 } else if (SrcLimits::is_signed) { 1022 } else if (SrcLimits::is_signed) {
691 TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1)); 1023 TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1));
1024 TEST_EXPECTED_VALUE(-1, clamped_dst - static_cast<Src>(1));
692 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest()); 1025 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest());
693 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); 1026 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
694 } else { 1027 } else {
695 TEST_EXPECTED_FAILURE(checked_dst - static_cast<Src>(1)); 1028 TEST_EXPECTED_FAILURE(checked_dst - static_cast<Src>(1));
1029 TEST_EXPECTED_VALUE(Dst(0), clamped_dst - static_cast<Src>(1));
696 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest()); 1030 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest());
697 } 1031 }
698 } 1032 }
699 }; 1033 };
700 1034
701 template <typename Dst, typename Src> 1035 template <typename Dst, typename Src>
702 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL> { 1036 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL> {
703 static void Test(const char *dst, const char *src, int line) { 1037 static void Test(const char *dst, const char *src, int line) {
704 using SrcLimits = numeric_limits<Src>; 1038 using SrcLimits = SaturationDefaultLimits<Src>;
705 using DstLimits = numeric_limits<Dst>; 1039 using DstLimits = SaturationDefaultLimits<Dst>;
706 static_assert(MaxExponent<Dst>::value >= MaxExponent<Src>::value, 1040 static_assert(MaxExponent<Dst>::value >= MaxExponent<Src>::value,
707 "Destination must be equal or wider than source."); 1041 "Destination must be equal or wider than source.");
708 static_assert(SrcLimits::is_signed, "Source must be signed"); 1042 static_assert(SrcLimits::is_signed, "Source must be signed");
709 static_assert(!DstLimits::is_signed, "Destination must be unsigned"); 1043 static_assert(!DstLimits::is_signed, "Destination must be unsigned");
710 1044
711 TestStrictComparison<Dst, Src>(); 1045 TestStrictComparison<Dst, Src>();
712 1046
713 const CheckedNumeric<Dst> checked_dst; 1047 const CheckedNumeric<Dst> checked_dst;
714 TEST_EXPECTED_VALUE(SrcLimits::max(), checked_dst + SrcLimits::max()); 1048 TEST_EXPECTED_VALUE(SrcLimits::max(), checked_dst + SrcLimits::max());
715 TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1)); 1049 TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1));
1050 TEST_EXPECTED_SUCCESS(checked_dst * static_cast<Src>(-1));
716 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::lowest()); 1051 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::lowest());
717 1052
1053 const ClampedNumeric<Dst> clamped_dst;
1054 TEST_EXPECTED_VALUE(SrcLimits::max(), clamped_dst + SrcLimits::max());
1055 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
1056 clamped_dst + static_cast<Src>(-1));
1057 TEST_EXPECTED_VALUE(0, clamped_dst * static_cast<Src>(-1));
1058 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
1059 clamped_dst + SrcLimits::lowest());
1060
718 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest()); 1061 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest());
719 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max()); 1062 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
720 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 1063 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
721 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); 1064 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
722 } 1065 }
723 }; 1066 };
724 1067
725 template <typename Dst, typename Src> 1068 template <typename Dst, typename Src>
726 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_NARROW> { 1069 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_NARROW> {
727 static void Test(const char *dst, const char *src, int line) { 1070 static void Test(const char *dst, const char *src, int line) {
728 using SrcLimits = numeric_limits<Src>; 1071 using SrcLimits = SaturationDefaultLimits<Src>;
729 using DstLimits = numeric_limits<Dst>; 1072 using DstLimits = SaturationDefaultLimits<Dst>;
730 static_assert(MaxExponent<Dst>::value < MaxExponent<Src>::value, 1073 static_assert(MaxExponent<Dst>::value < MaxExponent<Src>::value,
731 "Destination must be narrower than source."); 1074 "Destination must be narrower than source.");
732 static_assert(SrcLimits::is_signed, "Source must be signed."); 1075 static_assert(SrcLimits::is_signed, "Source must be signed.");
733 static_assert(!DstLimits::is_signed, "Destination must be unsigned."); 1076 static_assert(!DstLimits::is_signed, "Destination must be unsigned.");
734 1077
735 TestStrictComparison<Dst, Src>(); 1078 TestStrictComparison<Dst, Src>();
736 1079
737 const CheckedNumeric<Dst> checked_dst; 1080 const CheckedNumeric<Dst> checked_dst;
738 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); 1081 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
739 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max()); 1082 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
740 TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1)); 1083 TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1));
741 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::lowest()); 1084 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::lowest());
742 1085
1086 const ClampedNumeric<Dst> clamped_dst;
1087 TEST_EXPECTED_VALUE(1, clamped_dst + static_cast<Src>(1));
1088 TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + SrcLimits::max());
1089 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
1090 clamped_dst + static_cast<Src>(-1));
1091 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
1092 clamped_dst + SrcLimits::lowest());
1093
743 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); 1094 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
744 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 1095 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
745 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); 1096 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
746 1097
747 // Additional saturation tests. 1098 // Additional saturation tests.
748 EXPECT_EQ(DstLimits::max(), saturated_cast<Dst>(SrcLimits::max())) << src; 1099 EXPECT_EQ(DstLimits::max(), saturated_cast<Dst>(SrcLimits::max()));
749 EXPECT_EQ(DstLimits::lowest(), saturated_cast<Dst>(SrcLimits::lowest())); 1100 EXPECT_EQ(DstLimits::lowest(), saturated_cast<Dst>(SrcLimits::lowest()));
750 1101
751 if (SrcLimits::is_iec559) { 1102 if (SrcLimits::is_iec559) {
752 EXPECT_EQ(Dst(0), saturated_cast<Dst>(SrcLimits::quiet_NaN())); 1103 EXPECT_EQ(Dst(0), saturated_cast<Dst>(SrcLimits::quiet_NaN()));
753 1104
754 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); 1105 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
755 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); 1106 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
756 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); 1107 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
757 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); 1108 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
758 if (DstLimits::is_integer) { 1109 if (DstLimits::is_integer) {
(...skipping 10 matching lines...) Expand all
769 } 1120 }
770 } else { 1121 } else {
771 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest()); 1122 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest());
772 } 1123 }
773 } 1124 }
774 }; 1125 };
775 1126
776 template <typename Dst, typename Src> 1127 template <typename Dst, typename Src>
777 struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL> { 1128 struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL> {
778 static void Test(const char *dst, const char *src, int line) { 1129 static void Test(const char *dst, const char *src, int line) {
779 using SrcLimits = numeric_limits<Src>; 1130 using SrcLimits = SaturationDefaultLimits<Src>;
780 using DstLimits = numeric_limits<Dst>; 1131 using DstLimits = SaturationDefaultLimits<Dst>;
781 static_assert(MaxExponent<Dst>::value <= MaxExponent<Src>::value, 1132 static_assert(MaxExponent<Dst>::value <= MaxExponent<Src>::value,
782 "Destination must be narrower or equal to source."); 1133 "Destination must be narrower or equal to source.");
783 static_assert(!SrcLimits::is_signed, "Source must be unsigned."); 1134 static_assert(!SrcLimits::is_signed, "Source must be unsigned.");
784 static_assert(DstLimits::is_signed, "Destination must be signed."); 1135 static_assert(DstLimits::is_signed, "Destination must be signed.");
785 1136
786 TestStrictComparison<Dst, Src>(); 1137 TestStrictComparison<Dst, Src>();
787 1138
788 const CheckedNumeric<Dst> checked_dst; 1139 const CheckedNumeric<Dst> checked_dst;
789 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); 1140 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
790 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max()); 1141 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
791 TEST_EXPECTED_VALUE(SrcLimits::lowest(), checked_dst + SrcLimits::lowest()); 1142 TEST_EXPECTED_VALUE(SrcLimits::lowest(), checked_dst + SrcLimits::lowest());
792 1143
1144 const ClampedNumeric<Dst> clamped_dst;
1145 TEST_EXPECTED_VALUE(1, clamped_dst + static_cast<Src>(1));
1146 TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + SrcLimits::max());
1147 TEST_EXPECTED_VALUE(SrcLimits::lowest(), clamped_dst + SrcLimits::lowest());
1148
793 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest()); 1149 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest());
794 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); 1150 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
795 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 1151 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
796 1152
797 // Additional saturation tests. 1153 // Additional saturation tests.
798 EXPECT_EQ(DstLimits::max(), saturated_cast<Dst>(SrcLimits::max())); 1154 EXPECT_EQ(DstLimits::max(), saturated_cast<Dst>(SrcLimits::max()));
799 EXPECT_EQ(Dst(0), saturated_cast<Dst>(SrcLimits::lowest())); 1155 EXPECT_EQ(Dst(0), saturated_cast<Dst>(SrcLimits::lowest()));
800 } 1156 }
801 }; 1157 };
802 1158
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 EXPECT_TRUE(too_large.IsValid()); 1516 EXPECT_TRUE(too_large.IsValid());
1161 too_large += d; 1517 too_large += d;
1162 EXPECT_FALSE(too_large.IsValid()); 1518 EXPECT_FALSE(too_large.IsValid());
1163 too_large -= d; 1519 too_large -= d;
1164 EXPECT_FALSE(too_large.IsValid()); 1520 EXPECT_FALSE(too_large.IsValid());
1165 too_large /= d; 1521 too_large /= d;
1166 EXPECT_FALSE(too_large.IsValid()); 1522 EXPECT_FALSE(too_large.IsValid());
1167 } 1523 }
1168 1524
1169 TEST(SafeNumerics, VariadicNumericOperations) { 1525 TEST(SafeNumerics, VariadicNumericOperations) {
1170 auto a = CheckAdd(1, 2UL, MakeCheckedNum(3LL), 4).ValueOrDie(); 1526 { // Synthetic scope to avoid variable naming collisions.
1171 EXPECT_EQ(static_cast<decltype(a)::type>(10), a); 1527 auto a = CheckAdd(1, 2UL, MakeCheckedNum(3LL), 4).ValueOrDie();
1172 auto b = CheckSub(MakeCheckedNum(20.0), 2UL, 4).ValueOrDie(); 1528 EXPECT_EQ(static_cast<decltype(a)::type>(10), a);
1173 EXPECT_EQ(static_cast<decltype(b)::type>(14.0), b); 1529 auto b = CheckSub(MakeCheckedNum(20.0), 2UL, 4).ValueOrDie();
1174 auto c = CheckMul(20.0, MakeCheckedNum(1), 5, 3UL).ValueOrDie(); 1530 EXPECT_EQ(static_cast<decltype(b)::type>(14.0), b);
1175 EXPECT_EQ(static_cast<decltype(c)::type>(300.0), c); 1531 auto c = CheckMul(20.0, MakeCheckedNum(1), 5, 3UL).ValueOrDie();
1176 auto d = CheckDiv(20.0, 2.0, MakeCheckedNum(5LL), -4).ValueOrDie(); 1532 EXPECT_EQ(static_cast<decltype(c)::type>(300.0), c);
1177 EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d); 1533 auto d = CheckDiv(20.0, 2.0, MakeCheckedNum(5LL), -4).ValueOrDie();
1178 auto e = CheckMod(MakeCheckedNum(20), 3).ValueOrDie(); 1534 EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d);
1179 EXPECT_EQ(static_cast<decltype(e)::type>(2), e); 1535 auto e = CheckMod(MakeCheckedNum(20), 3).ValueOrDie();
1180 auto f = CheckLsh(1, MakeCheckedNum(2)).ValueOrDie(); 1536 EXPECT_EQ(static_cast<decltype(e)::type>(2), e);
1181 EXPECT_EQ(static_cast<decltype(f)::type>(4), f); 1537 auto f = CheckLsh(1, MakeCheckedNum(2)).ValueOrDie();
1182 auto g = CheckRsh(4, MakeCheckedNum(2)).ValueOrDie(); 1538 EXPECT_EQ(static_cast<decltype(f)::type>(4), f);
1183 EXPECT_EQ(static_cast<decltype(g)::type>(1), g); 1539 auto g = CheckRsh(4, MakeCheckedNum(2)).ValueOrDie();
1184 auto h = CheckRsh(CheckAdd(1, 1, 1, 1), CheckSub(4, 2)).ValueOrDie(); 1540 EXPECT_EQ(static_cast<decltype(g)::type>(1), g);
1185 EXPECT_EQ(static_cast<decltype(h)::type>(1), h); 1541 auto h = CheckRsh(CheckAdd(1, 1, 1, 1), CheckSub(4, 2)).ValueOrDie();
1542 EXPECT_EQ(static_cast<decltype(h)::type>(1), h);
1543 }
1544
1545 {
1546 auto a = ClampAdd(1, 2UL, MakeClampedNum(3LL), 4);
1547 EXPECT_EQ(static_cast<decltype(a)::type>(10), a);
1548 auto b = ClampSub(MakeClampedNum(20.0), 2UL, 4);
1549 EXPECT_EQ(static_cast<decltype(b)::type>(14.0), b);
1550 auto c = ClampMul(20.0, MakeClampedNum(1), 5, 3UL);
1551 EXPECT_EQ(static_cast<decltype(c)::type>(300.0), c);
1552 auto d = ClampDiv(20.0, 2.0, MakeClampedNum(5LL), -4);
1553 EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d);
1554 auto e = ClampMod(MakeClampedNum(20), 3);
1555 EXPECT_EQ(static_cast<decltype(e)::type>(2), e);
1556 auto f = ClampLsh(1, MakeClampedNum(2U));
1557 EXPECT_EQ(static_cast<decltype(f)::type>(4), f);
1558 auto g = ClampRsh(4, MakeClampedNum(2U));
1559 EXPECT_EQ(static_cast<decltype(g)::type>(1), g);
1560 auto h = ClampRsh(ClampAdd(1, 1, 1, 1), ClampSub(4U, 2));
1561 EXPECT_EQ(static_cast<decltype(h)::type>(1), h);
1562 }
1186 } 1563 }
OLDNEW
« no previous file with comments | « base/numerics/safe_math_shared_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698