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

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

Issue 2945433003: Add ClampedNumeric templates (Closed)
Patch Set: feedback round 2 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
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));
dcheng 2017/07/03 10:01:44 Nit: add a test case that lowest() saturates to -1
jschuh 2017/07/03 13:03:46 Done.
405
269 TestStrictPointerMath<Dst>(); 406 TestStrictPointerMath<Dst>();
270 } 407 }
271 408
272 // Unsigned integer arithmetic. 409 // Unsigned integer arithmetic.
273 template <typename Dst> 410 template <typename Dst>
274 static void TestSpecializedArithmetic( 411 static void TestSpecializedArithmetic(
275 const char* dst, 412 const char* dst,
276 int line, 413 int line,
277 typename std::enable_if<numeric_limits<Dst>::is_integer && 414 typename std::enable_if<numeric_limits<Dst>::is_integer &&
278 !numeric_limits<Dst>::is_signed, 415 !numeric_limits<Dst>::is_signed,
279 int>::type = 0) { 416 int>::type = 0) {
280 using DstLimits = numeric_limits<Dst>; 417 using DstLimits = SaturationDefaultLimits<Dst>;
281 TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::lowest())); 418 TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::lowest()));
282 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).Abs()); 419 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).Abs());
283 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) + -1); 420 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) + -1);
284 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) - 1); 421 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) - 1);
285 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) * 2); 422 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) * 2);
286 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) / 2); 423 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) / 2);
287 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).UnsignedAbs()); 424 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).UnsignedAbs());
288 TEST_EXPECTED_SUCCESS( 425 TEST_EXPECTED_SUCCESS(
289 CheckedNumeric<typename std::make_signed<Dst>::type>( 426 CheckedNumeric<typename std::make_signed<Dst>::type>(
290 std::numeric_limits<typename std::make_signed<Dst>::type>::lowest()) 427 std::numeric_limits<typename std::make_signed<Dst>::type>::lowest())
291 .UnsignedAbs()); 428 .UnsignedAbs());
292 TEST_EXPECTED_VALUE(DstLimits::lowest(), 429 TEST_EXPECTED_VALUE(DstLimits::lowest(),
293 MakeCheckedNum(DstLimits::lowest()).UnsignedAbs()); 430 MakeCheckedNum(DstLimits::lowest()).UnsignedAbs());
294 TEST_EXPECTED_VALUE(DstLimits::max(), 431 TEST_EXPECTED_VALUE(DstLimits::max(),
295 MakeCheckedNum(DstLimits::max()).UnsignedAbs()); 432 MakeCheckedNum(DstLimits::max()).UnsignedAbs());
296 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0).UnsignedAbs()); 433 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0).UnsignedAbs());
297 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).UnsignedAbs()); 434 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).UnsignedAbs());
298 435
436 TEST_EXPECTED_VALUE(0, -ClampedNumeric<Dst>(DstLimits::lowest()));
437 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()).Abs());
438 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
439 ClampedNumeric<Dst>(DstLimits::lowest()) + -1);
440 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
441 ClampedNumeric<Dst>(DstLimits::lowest()) - 1);
442 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) * 2);
443 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) / 2);
444 TEST_EXPECTED_VALUE(0,
445 ClampedNumeric<Dst>(DstLimits::lowest()).UnsignedAbs());
446 TEST_EXPECTED_VALUE(
447 as_unsigned(
448 std::numeric_limits<typename std::make_signed<Dst>::type>::lowest()),
449 ClampedNumeric<typename std::make_signed<Dst>::type>(
450 std::numeric_limits<typename std::make_signed<Dst>::type>::lowest())
451 .UnsignedAbs());
452 TEST_EXPECTED_VALUE(DstLimits::lowest(),
453 MakeClampedNum(DstLimits::lowest()).UnsignedAbs());
454 TEST_EXPECTED_VALUE(DstLimits::max(),
455 MakeClampedNum(DstLimits::max()).UnsignedAbs());
456 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0).UnsignedAbs());
457 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1).UnsignedAbs());
458
299 // Modulus is legal only for integers. 459 // Modulus is legal only for integers.
300 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1); 460 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1);
301 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); 461 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1);
302 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2); 462 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2);
303 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % 2); 463 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::lowest()) % 2);
304 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2); 464 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2);
305 // Test all the different modulus combinations. 465 // Test all the different modulus combinations.
306 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1)); 466 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1));
307 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1)); 467 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1));
308 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); 468 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(), 503 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
344 CheckedNumeric<Dst>(0) | static_cast<Dst>(-1)); 504 CheckedNumeric<Dst>(0) | static_cast<Dst>(-1));
345 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) ^ 1); 505 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) ^ 1);
346 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) ^ 0); 506 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) ^ 0);
347 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(0) ^ 1); 507 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(0) ^ 1);
348 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) ^ 0); 508 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(0) ^ 0);
349 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(), 509 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
350 CheckedNumeric<Dst>(0) ^ static_cast<Dst>(-1)); 510 CheckedNumeric<Dst>(0) ^ static_cast<Dst>(-1));
351 TEST_EXPECTED_VALUE(DstLimits::max(), ~CheckedNumeric<Dst>(0)); 511 TEST_EXPECTED_VALUE(DstLimits::max(), ~CheckedNumeric<Dst>(0));
352 512
513 // Modulus is legal only for integers.
514 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>() % 1);
515 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
516 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) % 2);
517 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::lowest()) % 2);
518 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(DstLimits::max()) % 2);
519 // Test all the different modulus combinations.
520 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % ClampedNumeric<Dst>(1));
521 TEST_EXPECTED_VALUE(0, 1 % ClampedNumeric<Dst>(1));
522 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) % 1);
523 ClampedNumeric<Dst> clamped_dst = 1;
524 TEST_EXPECTED_VALUE(0, clamped_dst %= 1);
525 // Test that div by 0 is avoided but returns invalid result.
526 TEST_EXPECTED_VALUE(Dst(1), ClampedNumeric<Dst>(1) % 0);
527 // Test bit shifts.
528 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
529 ClampedNumeric<Dst>(1)
530 << as_unsigned(IntegerBitsPlusSign<Dst>::value));
531 TEST_EXPECTED_VALUE(Dst(0), ClampedNumeric<Dst>(0) << as_unsigned(
532 IntegerBitsPlusSign<Dst>::value));
533 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
534 ClampedNumeric<Dst>(DstLimits::max()) << 1U);
535 TEST_EXPECTED_VALUE(
536 static_cast<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 1U),
537 ClampedNumeric<Dst>(1) << (IntegerBitsPlusSign<Dst>::value - 1U));
538 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) << 0U);
539 TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) << 1U);
540 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) >>
541 as_unsigned(IntegerBitsPlusSign<Dst>::value));
542 TEST_EXPECTED_VALUE(
543 0, ClampedNumeric<Dst>(1) >> (IntegerBitsPlusSign<Dst>::value - 1U));
544 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) & 1);
545 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) & 0);
546 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) & 1);
547 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) & 0);
548 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
549 MakeClampedNum(DstLimits::max()) & -1);
550 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) | 1);
551 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) | 0);
552 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(0) | 1);
553 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) | 0);
554 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
555 ClampedNumeric<Dst>(0) | static_cast<Dst>(-1));
556 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) ^ 1);
557 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) ^ 0);
558 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(0) ^ 1);
559 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) ^ 0);
560 TEST_EXPECTED_VALUE(std::numeric_limits<Dst>::max(),
561 ClampedNumeric<Dst>(0) ^ static_cast<Dst>(-1));
562 TEST_EXPECTED_VALUE(DstLimits::max(), ~ClampedNumeric<Dst>(0));
563
353 TestStrictPointerMath<Dst>(); 564 TestStrictPointerMath<Dst>();
354 } 565 }
355 566
356 // Floating point arithmetic. 567 // Floating point arithmetic.
357 template <typename Dst> 568 template <typename Dst>
358 void TestSpecializedArithmetic( 569 void TestSpecializedArithmetic(
359 const char* dst, 570 const char* dst,
360 int line, 571 int line,
361 typename std::enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) { 572 typename std::enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) {
362 using DstLimits = numeric_limits<Dst>; 573 using DstLimits = SaturationDefaultLimits<Dst>;
363 TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::lowest())); 574 TEST_EXPECTED_SUCCESS(-CheckedNumeric<Dst>(DstLimits::lowest()));
364 575
365 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).Abs()); 576 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()).Abs());
366 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs()); 577 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs());
367 578
368 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) + -1); 579 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) + -1);
369 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + 1); 580 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) + 1);
370 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) + 581 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) +
371 DstLimits::lowest()); 582 DstLimits::lowest());
372 583
373 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - 584 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) -
374 DstLimits::lowest()); 585 DstLimits::lowest());
375 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) - 586 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) -
376 DstLimits::max()); 587 DstLimits::max());
377 588
378 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * 2); 589 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::lowest()) * 2);
379 590
380 TEST_EXPECTED_VALUE(-0.5, CheckedNumeric<Dst>(-1.0) / 2); 591 TEST_EXPECTED_VALUE(-0.5, CheckedNumeric<Dst>(-1.0) / 2);
592
593 TEST_EXPECTED_VALUE(DstLimits::max(),
594 -ClampedNumeric<Dst>(DstLimits::lowest()));
595
596 TEST_EXPECTED_VALUE(DstLimits::max(),
597 ClampedNumeric<Dst>(DstLimits::lowest()).Abs());
598 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(-1).Abs());
599
600 TEST_EXPECTED_VALUE(DstLimits::lowest() - 1,
601 ClampedNumeric<Dst>(DstLimits::lowest()) + -1);
602 TEST_EXPECTED_VALUE(DstLimits::max() + 1,
603 ClampedNumeric<Dst>(DstLimits::max()) + 1);
604 TEST_EXPECTED_VALUE(
605 DstLimits::Underflow(),
606 ClampedNumeric<Dst>(DstLimits::lowest()) + DstLimits::lowest());
607
608 TEST_EXPECTED_VALUE(
609 DstLimits::Overflow(),
610 ClampedNumeric<Dst>(DstLimits::max()) - DstLimits::lowest());
611 TEST_EXPECTED_VALUE(
612 DstLimits::Underflow(),
613 ClampedNumeric<Dst>(DstLimits::lowest()) - DstLimits::max());
614
615 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
616 ClampedNumeric<Dst>(DstLimits::lowest()) * 2);
617
618 TEST_EXPECTED_VALUE(-0.5, ClampedNumeric<Dst>(-1.0) / 2);
381 } 619 }
382 620
383 // Generic arithmetic tests. 621 // Generic arithmetic tests.
384 template <typename Dst> 622 template <typename Dst>
385 static void TestArithmetic(const char* dst, int line) { 623 static void TestArithmetic(const char* dst, int line) {
386 using DstLimits = numeric_limits<Dst>; 624 using DstLimits = SaturationDefaultLimits<Dst>;
387 625
388 EXPECT_EQ(true, CheckedNumeric<Dst>().IsValid()); 626 EXPECT_EQ(true, CheckedNumeric<Dst>().IsValid());
389 EXPECT_EQ(false, 627 EXPECT_EQ(false,
390 CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) * 628 CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) *
391 DstLimits::max()).IsValid()); 629 DstLimits::max()).IsValid());
392 EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDie()); 630 EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDie());
393 EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDefault(1)); 631 EXPECT_EQ(static_cast<Dst>(0), CheckedNumeric<Dst>().ValueOrDefault(1));
394 EXPECT_EQ(static_cast<Dst>(1), 632 EXPECT_EQ(static_cast<Dst>(1),
395 CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) * 633 CheckedNumeric<Dst>(CheckedNumeric<Dst>(DstLimits::max()) *
396 DstLimits::max()).ValueOrDefault(1)); 634 DstLimits::max()).ValueOrDefault(1));
(...skipping 13 matching lines...) Expand all
410 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1); 648 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
411 CheckedNumeric<Dst> checked_dst = 1; 649 CheckedNumeric<Dst> checked_dst = 1;
412 TEST_EXPECTED_VALUE(2, checked_dst += 1); 650 TEST_EXPECTED_VALUE(2, checked_dst += 1);
413 checked_dst = 1; 651 checked_dst = 1;
414 TEST_EXPECTED_VALUE(0, checked_dst -= 1); 652 TEST_EXPECTED_VALUE(0, checked_dst -= 1);
415 checked_dst = 1; 653 checked_dst = 1;
416 TEST_EXPECTED_VALUE(1, checked_dst *= 1); 654 TEST_EXPECTED_VALUE(1, checked_dst *= 1);
417 checked_dst = 1; 655 checked_dst = 1;
418 TEST_EXPECTED_VALUE(1, checked_dst /= 1); 656 TEST_EXPECTED_VALUE(1, checked_dst /= 1);
419 657
658 TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) + ClampedNumeric<Dst>(1));
659 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) - ClampedNumeric<Dst>(1));
660 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) * ClampedNumeric<Dst>(1));
661 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) / ClampedNumeric<Dst>(1));
662 TEST_EXPECTED_VALUE(2, 1 + ClampedNumeric<Dst>(1));
663 TEST_EXPECTED_VALUE(0, 1 - ClampedNumeric<Dst>(1));
664 TEST_EXPECTED_VALUE(1, 1 * ClampedNumeric<Dst>(1));
665 TEST_EXPECTED_VALUE(1, 1 / ClampedNumeric<Dst>(1));
666 TEST_EXPECTED_VALUE(2, ClampedNumeric<Dst>(1) + 1);
667 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(1) - 1);
668 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) * 1);
669 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) / 1);
670 ClampedNumeric<Dst> clamped_dst = 1;
671 TEST_EXPECTED_VALUE(2, clamped_dst += 1);
672 clamped_dst = 1;
673 TEST_EXPECTED_VALUE(0, clamped_dst -= 1);
674 clamped_dst = 1;
675 TEST_EXPECTED_VALUE(1, clamped_dst *= 1);
676 clamped_dst = 1;
677 TEST_EXPECTED_VALUE(1, clamped_dst /= 1);
678
420 // Generic negation. 679 // Generic negation.
421 if (DstLimits::is_signed) { 680 if (DstLimits::is_signed) {
422 TEST_EXPECTED_VALUE(0, -CheckedNumeric<Dst>()); 681 TEST_EXPECTED_VALUE(0, -CheckedNumeric<Dst>());
423 TEST_EXPECTED_VALUE(-1, -CheckedNumeric<Dst>(1)); 682 TEST_EXPECTED_VALUE(-1, -CheckedNumeric<Dst>(1));
424 TEST_EXPECTED_VALUE(1, -CheckedNumeric<Dst>(-1)); 683 TEST_EXPECTED_VALUE(1, -CheckedNumeric<Dst>(-1));
425 TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1), 684 TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1),
426 -CheckedNumeric<Dst>(DstLimits::max())); 685 -CheckedNumeric<Dst>(DstLimits::max()));
686
687 TEST_EXPECTED_VALUE(0, -ClampedNumeric<Dst>());
688 TEST_EXPECTED_VALUE(-1, -ClampedNumeric<Dst>(1));
689 TEST_EXPECTED_VALUE(1, -ClampedNumeric<Dst>(-1));
690 TEST_EXPECTED_VALUE(static_cast<Dst>(DstLimits::max() * -1),
691 -ClampedNumeric<Dst>(DstLimits::max()));
427 } 692 }
428 693
429 // Generic absolute value. 694 // Generic absolute value.
430 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>().Abs()); 695 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>().Abs());
431 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).Abs()); 696 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).Abs());
432 TEST_EXPECTED_VALUE(DstLimits::max(), 697 TEST_EXPECTED_VALUE(DstLimits::max(),
433 CheckedNumeric<Dst>(DstLimits::max()).Abs()); 698 CheckedNumeric<Dst>(DstLimits::max()).Abs());
434 699
700 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>().Abs());
701 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1).Abs());
702 TEST_EXPECTED_VALUE(DstLimits::max(),
703 ClampedNumeric<Dst>(DstLimits::max()).Abs());
704
435 // Generic addition. 705 // Generic addition.
436 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>() + 1)); 706 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>() + 1));
437 TEST_EXPECTED_VALUE(2, (CheckedNumeric<Dst>(1) + 1)); 707 TEST_EXPECTED_VALUE(2, (CheckedNumeric<Dst>(1) + 1));
438 if (numeric_limits<Dst>::is_signed) 708 if (numeric_limits<Dst>::is_signed)
439 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) + 1)); 709 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) + 1));
440 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) + 1); 710 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::lowest()) + 1);
441 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) + 711 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) +
442 DstLimits::max()); 712 DstLimits::max());
443 713
714 TEST_EXPECTED_VALUE(1, (ClampedNumeric<Dst>() + 1));
715 TEST_EXPECTED_VALUE(2, (ClampedNumeric<Dst>(1) + 1));
716 if (numeric_limits<Dst>::is_signed)
717 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(-1) + 1));
718 TEST_EXPECTED_VALUE(DstLimits::lowest() + 1,
719 ClampedNumeric<Dst>(DstLimits::lowest()) + 1);
720 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
721 ClampedNumeric<Dst>(DstLimits::max()) + DstLimits::max());
722
444 // Generic subtraction. 723 // Generic subtraction.
445 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(1) - 1)); 724 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(1) - 1));
446 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) - 1); 725 TEST_EXPECTED_SUCCESS(CheckedNumeric<Dst>(DstLimits::max()) - 1);
447 if (numeric_limits<Dst>::is_signed) { 726 if (numeric_limits<Dst>::is_signed) {
448 TEST_EXPECTED_VALUE(-1, (CheckedNumeric<Dst>() - 1)); 727 TEST_EXPECTED_VALUE(-1, (CheckedNumeric<Dst>() - 1));
449 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) - 1)); 728 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) - 1));
450 } else { 729 } else {
451 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - -1); 730 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) - -1);
452 } 731 }
453 732
733 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(1) - 1));
734 TEST_EXPECTED_VALUE(DstLimits::max() - 1,
735 ClampedNumeric<Dst>(DstLimits::max()) - 1);
736 if (numeric_limits<Dst>::is_signed) {
737 TEST_EXPECTED_VALUE(-1, (ClampedNumeric<Dst>() - 1));
738 TEST_EXPECTED_VALUE(-2, (ClampedNumeric<Dst>(-1) - 1));
739 } else {
740 TEST_EXPECTED_VALUE(DstLimits::max(),
741 ClampedNumeric<Dst>(DstLimits::max()) - -1);
742 }
743
454 // Generic multiplication. 744 // Generic multiplication.
455 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>() * 1)); 745 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>() * 1));
456 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>(1) * 1)); 746 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>(1) * 1));
457 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * 0)); 747 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * 0));
458 if (numeric_limits<Dst>::is_signed) { 748 if (numeric_limits<Dst>::is_signed) {
459 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) * 0)); 749 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) * 0));
460 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * -1)); 750 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * -1));
461 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) * 2)); 751 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) * 2));
462 } else { 752 } else {
463 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * -2); 753 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * -2);
464 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * 754 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) *
465 CheckedNumeric<uintmax_t>(-2)); 755 CheckedNumeric<uintmax_t>(-2));
466 } 756 }
467 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) * 757 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(DstLimits::max()) *
468 DstLimits::max()); 758 DstLimits::max());
469 759
760 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>() * 1));
761 TEST_EXPECTED_VALUE(1, (ClampedNumeric<Dst>(1) * 1));
762 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(0) * 0));
763 if (numeric_limits<Dst>::is_signed) {
764 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(-1) * 0));
765 TEST_EXPECTED_VALUE(0, (ClampedNumeric<Dst>(0) * -1));
766 TEST_EXPECTED_VALUE(-2, (ClampedNumeric<Dst>(-1) * 2));
767 } else {
768 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
769 ClampedNumeric<Dst>(DstLimits::max()) * -2);
770 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(DstLimits::max()) *
771 ClampedNumeric<uintmax_t>(-2));
772 }
773 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
774 ClampedNumeric<Dst>(DstLimits::max()) * DstLimits::max());
775
470 // Generic division. 776 // Generic division.
471 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() / 1); 777 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() / 1);
472 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1); 778 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1);
473 TEST_EXPECTED_VALUE(DstLimits::lowest() / 2, 779 TEST_EXPECTED_VALUE(DstLimits::lowest() / 2,
474 CheckedNumeric<Dst>(DstLimits::lowest()) / 2); 780 CheckedNumeric<Dst>(DstLimits::lowest()) / 2);
475 TEST_EXPECTED_VALUE(DstLimits::max() / 2, 781 TEST_EXPECTED_VALUE(DstLimits::max() / 2,
476 CheckedNumeric<Dst>(DstLimits::max()) / 2); 782 CheckedNumeric<Dst>(DstLimits::max()) / 2);
783 TEST_EXPECTED_FAILURE(CheckedNumeric<Dst>(1) / 0);
784
785 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>() / 1);
786 TEST_EXPECTED_VALUE(1, ClampedNumeric<Dst>(1) / 1);
787 TEST_EXPECTED_VALUE(DstLimits::lowest() / 2,
788 ClampedNumeric<Dst>(DstLimits::lowest()) / 2);
789 TEST_EXPECTED_VALUE(DstLimits::max() / 2,
790 ClampedNumeric<Dst>(DstLimits::max()) / 2);
791 TEST_EXPECTED_VALUE(DstLimits::Overflow(), ClampedNumeric<Dst>(1) / 0);
792 TEST_EXPECTED_VALUE(DstLimits::Underflow(), ClampedNumeric<Dst>(-1) / 0);
793 TEST_EXPECTED_VALUE(0, ClampedNumeric<Dst>(0) / 0);
dcheng 2017/07/03 10:01:44 Please update the documentation for clamped divisi
jschuh 2017/07/03 13:03:46 Done.
477 794
478 TestSpecializedArithmetic<Dst>(dst, line); 795 TestSpecializedArithmetic<Dst>(dst, line);
479 } 796 }
480 797
481 // Helper macro to wrap displaying the conversion types and line numbers. 798 // Helper macro to wrap displaying the conversion types and line numbers.
482 #define TEST_ARITHMETIC(Dst) TestArithmetic<Dst>(#Dst, __LINE__) 799 #define TEST_ARITHMETIC(Dst) TestArithmetic<Dst>(#Dst, __LINE__)
483 800
484 TEST(SafeNumerics, SignedIntegerMath) { 801 TEST(SafeNumerics, SignedIntegerMath) {
485 TEST_ARITHMETIC(int8_t); 802 TEST_ARITHMETIC(int8_t);
486 TEST_ARITHMETIC(int); 803 TEST_ARITHMETIC(int);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 DstLimits::max(), SrcLimits::lowest()) 915 DstLimits::max(), SrcLimits::lowest())
599 .ValueOrDie()); 916 .ValueOrDie());
600 EXPECT_EQ(DstLimits::max(), CheckMax(MakeStrictNum(1), MakeCheckedNum(0), 917 EXPECT_EQ(DstLimits::max(), CheckMax(MakeStrictNum(1), MakeCheckedNum(0),
601 DstLimits::max(), SrcLimits::lowest()) 918 DstLimits::max(), SrcLimits::lowest())
602 .ValueOrDie()); 919 .ValueOrDie());
603 } 920 }
604 921
605 template <typename Dst, typename Src> 922 template <typename Dst, typename Src>
606 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> { 923 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_VALUE_PRESERVING> {
607 static void Test(const char *dst, const char *src, int line) { 924 static void Test(const char *dst, const char *src, int line) {
608 using SrcLimits = numeric_limits<Src>; 925 using SrcLimits = SaturationDefaultLimits<Src>;
609 using DstLimits = numeric_limits<Dst>; 926 using DstLimits = SaturationDefaultLimits<Dst>;
610 // Integral to floating. 927 // Integral to floating.
611 static_assert((DstLimits::is_iec559 && SrcLimits::is_integer) || 928 static_assert((DstLimits::is_iec559 && SrcLimits::is_integer) ||
612 // Not floating to integral and... 929 // Not floating to integral and...
613 (!(DstLimits::is_integer && SrcLimits::is_iec559) && 930 (!(DstLimits::is_integer && SrcLimits::is_iec559) &&
614 // Same sign, same numeric, source is narrower or same. 931 // Same sign, same numeric, source is narrower or same.
615 ((SrcLimits::is_signed == DstLimits::is_signed && 932 ((SrcLimits::is_signed == DstLimits::is_signed &&
616 MaxExponent<Dst>::value >= MaxExponent<Src>::value) || 933 MaxExponent<Dst>::value >= MaxExponent<Src>::value) ||
617 // Or signed destination and source is smaller 934 // Or signed destination and source is smaller
618 (DstLimits::is_signed && 935 (DstLimits::is_signed &&
619 MaxExponent<Dst>::value >= MaxExponent<Src>::value))), 936 MaxExponent<Dst>::value >= MaxExponent<Src>::value))),
620 "Comparison must be sign preserving and value preserving"); 937 "Comparison must be sign preserving and value preserving");
621 938
622 TestStrictComparison<Dst, Src>(); 939 TestStrictComparison<Dst, Src>();
623 940
624 const CheckedNumeric<Dst> checked_dst = SrcLimits::max(); 941 const CheckedNumeric<Dst> checked_dst = SrcLimits::max();
942 const ClampedNumeric<Dst> clamped_dst = SrcLimits::max();
625 TEST_EXPECTED_SUCCESS(checked_dst); 943 TEST_EXPECTED_SUCCESS(checked_dst);
944 TEST_EXPECTED_VALUE(Dst(SrcLimits::max()), clamped_dst);
626 if (MaxExponent<Dst>::value > MaxExponent<Src>::value) { 945 if (MaxExponent<Dst>::value > MaxExponent<Src>::value) {
627 if (MaxExponent<Dst>::value >= MaxExponent<Src>::value * 2 - 1) { 946 if (MaxExponent<Dst>::value >= MaxExponent<Src>::value * 2 - 1) {
628 // At least twice larger type. 947 // At least twice larger type.
629 TEST_EXPECTED_SUCCESS(SrcLimits::max() * checked_dst); 948 TEST_EXPECTED_SUCCESS(SrcLimits::max() * checked_dst);
630 949 TEST_EXPECTED_VALUE(SrcLimits::max() * clamped_dst,
950 Dst(SrcLimits::max()) * SrcLimits::max());
631 } else { // Larger, but not at least twice as large. 951 } else { // Larger, but not at least twice as large.
632 TEST_EXPECTED_FAILURE(SrcLimits::max() * checked_dst); 952 TEST_EXPECTED_FAILURE(SrcLimits::max() * checked_dst);
633 TEST_EXPECTED_SUCCESS(checked_dst + 1); 953 TEST_EXPECTED_SUCCESS(checked_dst + 1);
954 TEST_EXPECTED_VALUE(DstLimits::Overflow(),
955 SrcLimits::max() * clamped_dst);
956 TEST_EXPECTED_VALUE(Dst(SrcLimits::max()) + Dst(1),
957 clamped_dst + Dst(1));
634 } 958 }
635 } else { // Same width type. 959 } else { // Same width type.
636 TEST_EXPECTED_FAILURE(checked_dst + 1); 960 TEST_EXPECTED_FAILURE(checked_dst + 1);
961 TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + Dst(1));
637 } 962 }
638 963
639 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max()); 964 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
640 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 965 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
641 if (SrcLimits::is_iec559) { 966 if (SrcLimits::is_iec559) {
642 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast<Src>(-1)); 967 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast<Src>(-1));
643 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); 968 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
644 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); 969 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
645 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); 970 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
646 } else if (numeric_limits<Src>::is_signed) { 971 } else if (numeric_limits<Src>::is_signed) {
647 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); 972 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
648 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest()); 973 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest());
649 } 974 }
650 } 975 }
651 }; 976 };
652 977
653 template <typename Dst, typename Src> 978 template <typename Dst, typename Src>
654 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW> { 979 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW> {
655 static void Test(const char *dst, const char *src, int line) { 980 static void Test(const char *dst, const char *src, int line) {
656 using SrcLimits = numeric_limits<Src>; 981 using SrcLimits = SaturationDefaultLimits<Src>;
657 using DstLimits = numeric_limits<Dst>; 982 using DstLimits = SaturationDefaultLimits<Dst>;
658 static_assert(SrcLimits::is_signed == DstLimits::is_signed, 983 static_assert(SrcLimits::is_signed == DstLimits::is_signed,
659 "Destination and source sign must be the same"); 984 "Destination and source sign must be the same");
660 static_assert(MaxExponent<Dst>::value <= MaxExponent<Src>::value, 985 static_assert(MaxExponent<Dst>::value <= MaxExponent<Src>::value,
661 "Destination must be narrower than source"); 986 "Destination must be narrower than source");
662 987
663 TestStrictComparison<Dst, Src>(); 988 TestStrictComparison<Dst, Src>();
664 989
665 const CheckedNumeric<Dst> checked_dst; 990 const CheckedNumeric<Dst> checked_dst;
666 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max()); 991 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
667 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); 992 TEST_EXPECTED_VALUE(1, checked_dst + Src(1));
668 TEST_EXPECTED_FAILURE(checked_dst - SrcLimits::max()); 993 TEST_EXPECTED_FAILURE(checked_dst - SrcLimits::max());
669 994
995 const ClampedNumeric<Dst> clamped_dst;
996 TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + SrcLimits::max());
997 TEST_EXPECTED_VALUE(1, clamped_dst + Src(1));
998 TEST_EXPECTED_VALUE(DstLimits::Underflow(), clamped_dst - SrcLimits::max());
999
670 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); 1000 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
671 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 1001 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
672 if (SrcLimits::is_iec559) { 1002 if (SrcLimits::is_iec559) {
673 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); 1003 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
674 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); 1004 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
675 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); 1005 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
676 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); 1006 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
677 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); 1007 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
678 if (DstLimits::is_integer) { 1008 if (DstLimits::is_integer) {
679 if (SrcLimits::digits < DstLimits::digits) { 1009 if (SrcLimits::digits < DstLimits::digits) {
680 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, 1010 TEST_EXPECTED_RANGE(RANGE_OVERFLOW,
681 static_cast<Src>(DstLimits::max())); 1011 static_cast<Src>(DstLimits::max()));
682 } else { 1012 } else {
683 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max())); 1013 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max()));
684 } 1014 }
685 TEST_EXPECTED_RANGE( 1015 TEST_EXPECTED_RANGE(
686 RANGE_VALID, 1016 RANGE_VALID,
687 static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>())); 1017 static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>()));
688 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::lowest())); 1018 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::lowest()));
689 } 1019 }
690 } else if (SrcLimits::is_signed) { 1020 } else if (SrcLimits::is_signed) {
691 TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1)); 1021 TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1));
1022 TEST_EXPECTED_VALUE(-1, clamped_dst - static_cast<Src>(1));
692 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest()); 1023 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest());
693 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); 1024 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1));
694 } else { 1025 } else {
695 TEST_EXPECTED_FAILURE(checked_dst - static_cast<Src>(1)); 1026 TEST_EXPECTED_FAILURE(checked_dst - static_cast<Src>(1));
1027 TEST_EXPECTED_VALUE(Dst(0), clamped_dst - static_cast<Src>(1));
696 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest()); 1028 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest());
697 } 1029 }
698 } 1030 }
699 }; 1031 };
700 1032
701 template <typename Dst, typename Src> 1033 template <typename Dst, typename Src>
702 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL> { 1034 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL> {
703 static void Test(const char *dst, const char *src, int line) { 1035 static void Test(const char *dst, const char *src, int line) {
704 using SrcLimits = numeric_limits<Src>; 1036 using SrcLimits = SaturationDefaultLimits<Src>;
705 using DstLimits = numeric_limits<Dst>; 1037 using DstLimits = SaturationDefaultLimits<Dst>;
706 static_assert(MaxExponent<Dst>::value >= MaxExponent<Src>::value, 1038 static_assert(MaxExponent<Dst>::value >= MaxExponent<Src>::value,
707 "Destination must be equal or wider than source."); 1039 "Destination must be equal or wider than source.");
708 static_assert(SrcLimits::is_signed, "Source must be signed"); 1040 static_assert(SrcLimits::is_signed, "Source must be signed");
709 static_assert(!DstLimits::is_signed, "Destination must be unsigned"); 1041 static_assert(!DstLimits::is_signed, "Destination must be unsigned");
710 1042
711 TestStrictComparison<Dst, Src>(); 1043 TestStrictComparison<Dst, Src>();
712 1044
713 const CheckedNumeric<Dst> checked_dst; 1045 const CheckedNumeric<Dst> checked_dst;
714 TEST_EXPECTED_VALUE(SrcLimits::max(), checked_dst + SrcLimits::max()); 1046 TEST_EXPECTED_VALUE(SrcLimits::max(), checked_dst + SrcLimits::max());
715 TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1)); 1047 TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1));
1048 TEST_EXPECTED_SUCCESS(checked_dst * static_cast<Src>(-1));
716 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::lowest()); 1049 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::lowest());
717 1050
1051 const ClampedNumeric<Dst> clamped_dst;
1052 TEST_EXPECTED_VALUE(SrcLimits::max(), clamped_dst + SrcLimits::max());
1053 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
1054 clamped_dst + static_cast<Src>(-1));
1055 TEST_EXPECTED_VALUE(0, clamped_dst * static_cast<Src>(-1));
1056 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
1057 clamped_dst + SrcLimits::lowest());
1058
718 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest()); 1059 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest());
719 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max()); 1060 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max());
720 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 1061 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
721 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); 1062 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
722 } 1063 }
723 }; 1064 };
724 1065
725 template <typename Dst, typename Src> 1066 template <typename Dst, typename Src>
726 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_NARROW> { 1067 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_NARROW> {
727 static void Test(const char *dst, const char *src, int line) { 1068 static void Test(const char *dst, const char *src, int line) {
728 using SrcLimits = numeric_limits<Src>; 1069 using SrcLimits = SaturationDefaultLimits<Src>;
729 using DstLimits = numeric_limits<Dst>; 1070 using DstLimits = SaturationDefaultLimits<Dst>;
730 static_assert(MaxExponent<Dst>::value < MaxExponent<Src>::value, 1071 static_assert(MaxExponent<Dst>::value < MaxExponent<Src>::value,
731 "Destination must be narrower than source."); 1072 "Destination must be narrower than source.");
732 static_assert(SrcLimits::is_signed, "Source must be signed."); 1073 static_assert(SrcLimits::is_signed, "Source must be signed.");
733 static_assert(!DstLimits::is_signed, "Destination must be unsigned."); 1074 static_assert(!DstLimits::is_signed, "Destination must be unsigned.");
734 1075
735 TestStrictComparison<Dst, Src>(); 1076 TestStrictComparison<Dst, Src>();
736 1077
737 const CheckedNumeric<Dst> checked_dst; 1078 const CheckedNumeric<Dst> checked_dst;
738 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); 1079 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
739 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max()); 1080 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
740 TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1)); 1081 TEST_EXPECTED_FAILURE(checked_dst + static_cast<Src>(-1));
741 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::lowest()); 1082 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::lowest());
742 1083
1084 const ClampedNumeric<Dst> clamped_dst;
1085 TEST_EXPECTED_VALUE(1, clamped_dst + static_cast<Src>(1));
1086 TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + SrcLimits::max());
1087 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
1088 clamped_dst + static_cast<Src>(-1));
1089 TEST_EXPECTED_VALUE(DstLimits::Underflow(),
1090 clamped_dst + SrcLimits::lowest());
1091
743 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); 1092 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
744 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 1093 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
745 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); 1094 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1));
746 1095
747 // Additional saturation tests. 1096 // Additional saturation tests.
748 EXPECT_EQ(DstLimits::max(), saturated_cast<Dst>(SrcLimits::max())) << src; 1097 EXPECT_EQ(DstLimits::max(), saturated_cast<Dst>(SrcLimits::max()));
749 EXPECT_EQ(DstLimits::lowest(), saturated_cast<Dst>(SrcLimits::lowest())); 1098 EXPECT_EQ(DstLimits::lowest(), saturated_cast<Dst>(SrcLimits::lowest()));
750 1099
751 if (SrcLimits::is_iec559) { 1100 if (SrcLimits::is_iec559) {
752 EXPECT_EQ(Dst(0), saturated_cast<Dst>(SrcLimits::quiet_NaN())); 1101 EXPECT_EQ(Dst(0), saturated_cast<Dst>(SrcLimits::quiet_NaN()));
753 1102
754 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); 1103 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1);
755 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); 1104 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity());
756 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); 1105 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1);
757 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); 1106 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN());
758 if (DstLimits::is_integer) { 1107 if (DstLimits::is_integer) {
(...skipping 10 matching lines...) Expand all
769 } 1118 }
770 } else { 1119 } else {
771 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest()); 1120 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::lowest());
772 } 1121 }
773 } 1122 }
774 }; 1123 };
775 1124
776 template <typename Dst, typename Src> 1125 template <typename Dst, typename Src>
777 struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL> { 1126 struct TestNumericConversion<Dst, Src, UNSIGN_TO_SIGN_NARROW_OR_EQUAL> {
778 static void Test(const char *dst, const char *src, int line) { 1127 static void Test(const char *dst, const char *src, int line) {
779 using SrcLimits = numeric_limits<Src>; 1128 using SrcLimits = SaturationDefaultLimits<Src>;
780 using DstLimits = numeric_limits<Dst>; 1129 using DstLimits = SaturationDefaultLimits<Dst>;
781 static_assert(MaxExponent<Dst>::value <= MaxExponent<Src>::value, 1130 static_assert(MaxExponent<Dst>::value <= MaxExponent<Src>::value,
782 "Destination must be narrower or equal to source."); 1131 "Destination must be narrower or equal to source.");
783 static_assert(!SrcLimits::is_signed, "Source must be unsigned."); 1132 static_assert(!SrcLimits::is_signed, "Source must be unsigned.");
784 static_assert(DstLimits::is_signed, "Destination must be signed."); 1133 static_assert(DstLimits::is_signed, "Destination must be signed.");
785 1134
786 TestStrictComparison<Dst, Src>(); 1135 TestStrictComparison<Dst, Src>();
787 1136
788 const CheckedNumeric<Dst> checked_dst; 1137 const CheckedNumeric<Dst> checked_dst;
789 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); 1138 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1));
790 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max()); 1139 TEST_EXPECTED_FAILURE(checked_dst + SrcLimits::max());
791 TEST_EXPECTED_VALUE(SrcLimits::lowest(), checked_dst + SrcLimits::lowest()); 1140 TEST_EXPECTED_VALUE(SrcLimits::lowest(), checked_dst + SrcLimits::lowest());
792 1141
1142 const ClampedNumeric<Dst> clamped_dst;
1143 TEST_EXPECTED_VALUE(1, clamped_dst + static_cast<Src>(1));
1144 TEST_EXPECTED_VALUE(DstLimits::Overflow(), clamped_dst + SrcLimits::max());
1145 TEST_EXPECTED_VALUE(SrcLimits::lowest(), clamped_dst + SrcLimits::lowest());
1146
793 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest()); 1147 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::lowest());
794 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); 1148 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max());
795 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); 1149 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1));
796 1150
797 // Additional saturation tests. 1151 // Additional saturation tests.
798 EXPECT_EQ(DstLimits::max(), saturated_cast<Dst>(SrcLimits::max())); 1152 EXPECT_EQ(DstLimits::max(), saturated_cast<Dst>(SrcLimits::max()));
799 EXPECT_EQ(Dst(0), saturated_cast<Dst>(SrcLimits::lowest())); 1153 EXPECT_EQ(Dst(0), saturated_cast<Dst>(SrcLimits::lowest()));
800 } 1154 }
801 }; 1155 };
802 1156
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 EXPECT_TRUE(too_large.IsValid()); 1514 EXPECT_TRUE(too_large.IsValid());
1161 too_large += d; 1515 too_large += d;
1162 EXPECT_FALSE(too_large.IsValid()); 1516 EXPECT_FALSE(too_large.IsValid());
1163 too_large -= d; 1517 too_large -= d;
1164 EXPECT_FALSE(too_large.IsValid()); 1518 EXPECT_FALSE(too_large.IsValid());
1165 too_large /= d; 1519 too_large /= d;
1166 EXPECT_FALSE(too_large.IsValid()); 1520 EXPECT_FALSE(too_large.IsValid());
1167 } 1521 }
1168 1522
1169 TEST(SafeNumerics, VariadicNumericOperations) { 1523 TEST(SafeNumerics, VariadicNumericOperations) {
1170 auto a = CheckAdd(1, 2UL, MakeCheckedNum(3LL), 4).ValueOrDie(); 1524 { // Synthetic scope to avoid variable naming collisions.
1171 EXPECT_EQ(static_cast<decltype(a)::type>(10), a); 1525 auto a = CheckAdd(1, 2UL, MakeCheckedNum(3LL), 4).ValueOrDie();
1172 auto b = CheckSub(MakeCheckedNum(20.0), 2UL, 4).ValueOrDie(); 1526 EXPECT_EQ(static_cast<decltype(a)::type>(10), a);
1173 EXPECT_EQ(static_cast<decltype(b)::type>(14.0), b); 1527 auto b = CheckSub(MakeCheckedNum(20.0), 2UL, 4).ValueOrDie();
1174 auto c = CheckMul(20.0, MakeCheckedNum(1), 5, 3UL).ValueOrDie(); 1528 EXPECT_EQ(static_cast<decltype(b)::type>(14.0), b);
1175 EXPECT_EQ(static_cast<decltype(c)::type>(300.0), c); 1529 auto c = CheckMul(20.0, MakeCheckedNum(1), 5, 3UL).ValueOrDie();
1176 auto d = CheckDiv(20.0, 2.0, MakeCheckedNum(5LL), -4).ValueOrDie(); 1530 EXPECT_EQ(static_cast<decltype(c)::type>(300.0), c);
1177 EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d); 1531 auto d = CheckDiv(20.0, 2.0, MakeCheckedNum(5LL), -4).ValueOrDie();
1178 auto e = CheckMod(MakeCheckedNum(20), 3).ValueOrDie(); 1532 EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d);
1179 EXPECT_EQ(static_cast<decltype(e)::type>(2), e); 1533 auto e = CheckMod(MakeCheckedNum(20), 3).ValueOrDie();
1180 auto f = CheckLsh(1, MakeCheckedNum(2)).ValueOrDie(); 1534 EXPECT_EQ(static_cast<decltype(e)::type>(2), e);
1181 EXPECT_EQ(static_cast<decltype(f)::type>(4), f); 1535 auto f = CheckLsh(1, MakeCheckedNum(2)).ValueOrDie();
1182 auto g = CheckRsh(4, MakeCheckedNum(2)).ValueOrDie(); 1536 EXPECT_EQ(static_cast<decltype(f)::type>(4), f);
1183 EXPECT_EQ(static_cast<decltype(g)::type>(1), g); 1537 auto g = CheckRsh(4, MakeCheckedNum(2)).ValueOrDie();
1184 auto h = CheckRsh(CheckAdd(1, 1, 1, 1), CheckSub(4, 2)).ValueOrDie(); 1538 EXPECT_EQ(static_cast<decltype(g)::type>(1), g);
1185 EXPECT_EQ(static_cast<decltype(h)::type>(1), h); 1539 auto h = CheckRsh(CheckAdd(1, 1, 1, 1), CheckSub(4, 2)).ValueOrDie();
1540 EXPECT_EQ(static_cast<decltype(h)::type>(1), h);
1541 }
1542
1543 {
1544 auto a = ClampAdd(1, 2UL, MakeClampedNum(3LL), 4);
1545 EXPECT_EQ(static_cast<decltype(a)::type>(10), a);
1546 auto b = ClampSub(MakeClampedNum(20.0), 2UL, 4);
1547 EXPECT_EQ(static_cast<decltype(b)::type>(14.0), b);
1548 auto c = ClampMul(20.0, MakeClampedNum(1), 5, 3UL);
1549 EXPECT_EQ(static_cast<decltype(c)::type>(300.0), c);
1550 auto d = ClampDiv(20.0, 2.0, MakeClampedNum(5LL), -4);
1551 EXPECT_EQ(static_cast<decltype(d)::type>(-.5), d);
1552 auto e = ClampMod(MakeClampedNum(20), 3);
1553 EXPECT_EQ(static_cast<decltype(e)::type>(2), e);
1554 auto f = ClampLsh(1, MakeClampedNum(2U));
1555 EXPECT_EQ(static_cast<decltype(f)::type>(4), f);
1556 auto g = ClampRsh(4, MakeClampedNum(2U));
1557 EXPECT_EQ(static_cast<decltype(g)::type>(1), g);
1558 auto h = ClampRsh(ClampAdd(1, 1, 1, 1), ClampSub(4U, 2));
1559 EXPECT_EQ(static_cast<decltype(h)::type>(1), h);
1560 }
1186 } 1561 }
OLDNEW
« base/numerics/README.md ('K') | « 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