Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 56 return SrcLimits::max(); | 56 return SrcLimits::max(); |
| 57 Src max = SrcLimits::max() / 2 + (SrcLimits::is_integer ? 1 : 0); | 57 Src max = SrcLimits::max() / 2 + (SrcLimits::is_integer ? 1 : 0); |
| 58 while (max != static_cast<Src>(static_cast<Dst>(max))) { | 58 while (max != static_cast<Src>(static_cast<Dst>(max))) { |
| 59 max /= 2; | 59 max /= 2; |
| 60 } | 60 } |
| 61 return static_cast<Dst>(max); | 61 return static_cast<Dst>(max); |
| 62 } | 62 } |
| 63 | 63 |
| 64 // Helper macros to wrap displaying the conversion types and line numbers. | 64 // Helper macros to wrap displaying the conversion types and line numbers. |
| 65 #define TEST_EXPECTED_VALIDITY(expected, actual) \ | 65 #define TEST_EXPECTED_VALIDITY(expected, actual) \ |
| 66 EXPECT_EQ(expected, CheckedNumeric<Dst>(actual).validity()) \ | 66 EXPECT_EQ(expected, CheckedNumeric<Dst>(actual).IsValid()) \ |
|
brucedawson
2016/05/20 21:00:57
Now that expected has only two values it might mak
jschuh
2016/05/20 21:19:05
Done.
| |
| 67 << "Result test: Value " << +(actual).ValueUnsafe() << " as " << dst \ | 67 << "Result test: Value " << +(actual).ValueUnsafe() << " as " << dst \ |
| 68 << " on line " << line; | 68 << " on line " << line; |
| 69 | 69 |
| 70 #define TEST_EXPECTED_VALUE(expected, actual) \ | 70 #define TEST_EXPECTED_VALUE(expected, actual) \ |
| 71 EXPECT_EQ(static_cast<Dst>(expected), \ | 71 EXPECT_EQ(static_cast<Dst>(expected), \ |
| 72 CheckedNumeric<Dst>(actual).ValueUnsafe()) \ | 72 CheckedNumeric<Dst>(actual).ValueUnsafe()) \ |
| 73 << "Result test: Value " << +((actual).ValueUnsafe()) << " as " << dst \ | 73 << "Result test: Value " << +((actual).ValueUnsafe()) << " as " << dst \ |
| 74 << " on line " << line; | 74 << " on line " << line; |
| 75 | 75 |
| 76 // Signed integer arithmetic. | 76 // Signed integer arithmetic. |
| 77 template <typename Dst> | 77 template <typename Dst> |
| 78 static void TestSpecializedArithmetic( | 78 static void TestSpecializedArithmetic( |
| 79 const char* dst, | 79 const char* dst, |
| 80 int line, | 80 int line, |
| 81 typename std::enable_if<numeric_limits<Dst>::is_integer && | 81 typename std::enable_if<numeric_limits<Dst>::is_integer && |
| 82 numeric_limits<Dst>::is_signed, | 82 numeric_limits<Dst>::is_signed, |
| 83 int>::type = 0) { | 83 int>::type = 0) { |
| 84 typedef numeric_limits<Dst> DstLimits; | 84 typedef numeric_limits<Dst> DstLimits; |
| 85 TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, | 85 TEST_EXPECTED_VALIDITY(false, -CheckedNumeric<Dst>(DstLimits::min())); |
| 86 -CheckedNumeric<Dst>(DstLimits::min())); | 86 TEST_EXPECTED_VALIDITY(false, CheckedNumeric<Dst>(DstLimits::min()).Abs()); |
| 87 TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, | |
| 88 CheckedNumeric<Dst>(DstLimits::min()).Abs()); | |
| 89 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs()); | 87 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs()); |
| 90 | 88 |
| 91 TEST_EXPECTED_VALIDITY(RANGE_VALID, | 89 TEST_EXPECTED_VALIDITY(true, CheckedNumeric<Dst>(DstLimits::max()) + -1); |
| 92 CheckedNumeric<Dst>(DstLimits::max()) + -1); | 90 TEST_EXPECTED_VALIDITY(false, CheckedNumeric<Dst>(DstLimits::min()) + -1); |
| 93 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, | |
| 94 CheckedNumeric<Dst>(DstLimits::min()) + -1); | |
| 95 TEST_EXPECTED_VALIDITY( | 91 TEST_EXPECTED_VALIDITY( |
| 96 RANGE_UNDERFLOW, | 92 false, CheckedNumeric<Dst>(-DstLimits::max()) + -DstLimits::max()); |
| 97 CheckedNumeric<Dst>(-DstLimits::max()) + -DstLimits::max()); | |
| 98 | 93 |
| 99 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, | 94 TEST_EXPECTED_VALIDITY(false, CheckedNumeric<Dst>(DstLimits::min()) - 1); |
| 100 CheckedNumeric<Dst>(DstLimits::min()) - 1); | 95 TEST_EXPECTED_VALIDITY(true, CheckedNumeric<Dst>(DstLimits::min()) - -1); |
| 101 TEST_EXPECTED_VALIDITY(RANGE_VALID, | |
| 102 CheckedNumeric<Dst>(DstLimits::min()) - -1); | |
| 103 TEST_EXPECTED_VALIDITY( | 96 TEST_EXPECTED_VALIDITY( |
| 104 RANGE_OVERFLOW, | 97 false, CheckedNumeric<Dst>(DstLimits::max()) - -DstLimits::max()); |
| 105 CheckedNumeric<Dst>(DstLimits::max()) - -DstLimits::max()); | |
| 106 TEST_EXPECTED_VALIDITY( | 98 TEST_EXPECTED_VALIDITY( |
| 107 RANGE_UNDERFLOW, | 99 false, CheckedNumeric<Dst>(-DstLimits::max()) - DstLimits::max()); |
| 108 CheckedNumeric<Dst>(-DstLimits::max()) - DstLimits::max()); | |
| 109 | 100 |
| 110 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, | 101 TEST_EXPECTED_VALIDITY(false, CheckedNumeric<Dst>(DstLimits::min()) * 2); |
| 111 CheckedNumeric<Dst>(DstLimits::min()) * 2); | |
| 112 | 102 |
| 113 TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, | 103 TEST_EXPECTED_VALIDITY(false, CheckedNumeric<Dst>(DstLimits::min()) / -1); |
| 114 CheckedNumeric<Dst>(DstLimits::min()) / -1); | |
| 115 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) / 2); | 104 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(-1) / 2); |
| 116 | 105 |
| 117 // Modulus is legal only for integers. | 106 // Modulus is legal only for integers. |
| 118 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1); | 107 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1); |
| 119 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); | 108 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); |
| 120 TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % 2); | 109 TEST_EXPECTED_VALUE(-1, CheckedNumeric<Dst>(-1) % 2); |
| 121 TEST_EXPECTED_VALIDITY(RANGE_INVALID, CheckedNumeric<Dst>(-1) % -2); | 110 TEST_EXPECTED_VALIDITY(false, CheckedNumeric<Dst>(-1) % -2); |
| 122 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2); | 111 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2); |
| 123 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2); | 112 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2); |
| 124 // Test all the different modulus combinations. | 113 // Test all the different modulus combinations. |
| 125 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1)); | 114 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1)); |
| 126 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1)); | 115 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1)); |
| 127 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); | 116 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); |
| 128 CheckedNumeric<Dst> checked_dst = 1; | 117 CheckedNumeric<Dst> checked_dst = 1; |
| 129 TEST_EXPECTED_VALUE(0, checked_dst %= 1); | 118 TEST_EXPECTED_VALUE(0, checked_dst %= 1); |
| 130 } | 119 } |
| 131 | 120 |
| 132 // Unsigned integer arithmetic. | 121 // Unsigned integer arithmetic. |
| 133 template <typename Dst> | 122 template <typename Dst> |
| 134 static void TestSpecializedArithmetic( | 123 static void TestSpecializedArithmetic( |
| 135 const char* dst, | 124 const char* dst, |
| 136 int line, | 125 int line, |
| 137 typename std::enable_if<numeric_limits<Dst>::is_integer && | 126 typename std::enable_if<numeric_limits<Dst>::is_integer && |
| 138 !numeric_limits<Dst>::is_signed, | 127 !numeric_limits<Dst>::is_signed, |
| 139 int>::type = 0) { | 128 int>::type = 0) { |
| 140 typedef numeric_limits<Dst> DstLimits; | 129 typedef numeric_limits<Dst> DstLimits; |
| 141 TEST_EXPECTED_VALIDITY(RANGE_VALID, -CheckedNumeric<Dst>(DstLimits::min())); | 130 TEST_EXPECTED_VALIDITY(true, -CheckedNumeric<Dst>(DstLimits::min())); |
| 142 TEST_EXPECTED_VALIDITY(RANGE_VALID, | 131 TEST_EXPECTED_VALIDITY(true, CheckedNumeric<Dst>(DstLimits::min()).Abs()); |
| 143 CheckedNumeric<Dst>(DstLimits::min()).Abs()); | 132 TEST_EXPECTED_VALIDITY(false, CheckedNumeric<Dst>(DstLimits::min()) + -1); |
| 144 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, | 133 TEST_EXPECTED_VALIDITY(false, CheckedNumeric<Dst>(DstLimits::min()) - 1); |
| 145 CheckedNumeric<Dst>(DstLimits::min()) + -1); | |
| 146 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, | |
| 147 CheckedNumeric<Dst>(DstLimits::min()) - 1); | |
| 148 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) * 2); | 134 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) * 2); |
| 149 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) / 2); | 135 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) / 2); |
| 150 TEST_EXPECTED_VALIDITY(RANGE_VALID, | 136 TEST_EXPECTED_VALIDITY(true, |
| 151 CheckedNumeric<Dst>(DstLimits::min()).UnsignedAbs()); | 137 CheckedNumeric<Dst>(DstLimits::min()).UnsignedAbs()); |
| 152 TEST_EXPECTED_VALIDITY( | 138 TEST_EXPECTED_VALIDITY( |
| 153 RANGE_VALID, | 139 true, |
| 154 CheckedNumeric<typename SignedIntegerForSize<Dst>::type>( | 140 CheckedNumeric<typename SignedIntegerForSize<Dst>::type>( |
| 155 std::numeric_limits<typename SignedIntegerForSize<Dst>::type>::min()) | 141 std::numeric_limits<typename SignedIntegerForSize<Dst>::type>::min()) |
| 156 .UnsignedAbs()); | 142 .UnsignedAbs()); |
| 157 | 143 |
| 158 // Modulus is legal only for integers. | 144 // Modulus is legal only for integers. |
| 159 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1); | 145 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() % 1); |
| 160 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); | 146 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); |
| 161 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2); | 147 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) % 2); |
| 162 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2); | 148 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(DstLimits::min()) % 2); |
| 163 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2); | 149 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(DstLimits::max()) % 2); |
| 164 // Test all the different modulus combinations. | 150 // Test all the different modulus combinations. |
| 165 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1)); | 151 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % CheckedNumeric<Dst>(1)); |
| 166 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1)); | 152 TEST_EXPECTED_VALUE(0, 1 % CheckedNumeric<Dst>(1)); |
| 167 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); | 153 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>(1) % 1); |
| 168 CheckedNumeric<Dst> checked_dst = 1; | 154 CheckedNumeric<Dst> checked_dst = 1; |
| 169 TEST_EXPECTED_VALUE(0, checked_dst %= 1); | 155 TEST_EXPECTED_VALUE(0, checked_dst %= 1); |
| 170 } | 156 } |
| 171 | 157 |
| 172 // Floating point arithmetic. | 158 // Floating point arithmetic. |
| 173 template <typename Dst> | 159 template <typename Dst> |
| 174 void TestSpecializedArithmetic( | 160 void TestSpecializedArithmetic( |
| 175 const char* dst, | 161 const char* dst, |
| 176 int line, | 162 int line, |
| 177 typename std::enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) { | 163 typename std::enable_if<numeric_limits<Dst>::is_iec559, int>::type = 0) { |
| 178 typedef numeric_limits<Dst> DstLimits; | 164 typedef numeric_limits<Dst> DstLimits; |
| 179 TEST_EXPECTED_VALIDITY(RANGE_VALID, -CheckedNumeric<Dst>(DstLimits::min())); | 165 TEST_EXPECTED_VALIDITY(true, -CheckedNumeric<Dst>(DstLimits::min())); |
| 180 | 166 |
| 181 TEST_EXPECTED_VALIDITY(RANGE_VALID, | 167 TEST_EXPECTED_VALIDITY(true, CheckedNumeric<Dst>(DstLimits::min()).Abs()); |
| 182 CheckedNumeric<Dst>(DstLimits::min()).Abs()); | |
| 183 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs()); | 168 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(-1).Abs()); |
| 184 | 169 |
| 185 TEST_EXPECTED_VALIDITY(RANGE_VALID, | 170 TEST_EXPECTED_VALIDITY(true, CheckedNumeric<Dst>(DstLimits::min()) + -1); |
| 186 CheckedNumeric<Dst>(DstLimits::min()) + -1); | 171 TEST_EXPECTED_VALIDITY(true, CheckedNumeric<Dst>(DstLimits::max()) + 1); |
| 187 TEST_EXPECTED_VALIDITY(RANGE_VALID, | |
| 188 CheckedNumeric<Dst>(DstLimits::max()) + 1); | |
| 189 TEST_EXPECTED_VALIDITY( | 172 TEST_EXPECTED_VALIDITY( |
| 190 RANGE_UNDERFLOW, | 173 false, CheckedNumeric<Dst>(-DstLimits::max()) + -DstLimits::max()); |
| 191 CheckedNumeric<Dst>(-DstLimits::max()) + -DstLimits::max()); | |
| 192 | 174 |
| 193 TEST_EXPECTED_VALIDITY( | 175 TEST_EXPECTED_VALIDITY( |
| 194 RANGE_OVERFLOW, | 176 false, CheckedNumeric<Dst>(DstLimits::max()) - -DstLimits::max()); |
| 195 CheckedNumeric<Dst>(DstLimits::max()) - -DstLimits::max()); | |
| 196 TEST_EXPECTED_VALIDITY( | 177 TEST_EXPECTED_VALIDITY( |
| 197 RANGE_UNDERFLOW, | 178 false, CheckedNumeric<Dst>(-DstLimits::max()) - DstLimits::max()); |
| 198 CheckedNumeric<Dst>(-DstLimits::max()) - DstLimits::max()); | |
| 199 | 179 |
| 200 TEST_EXPECTED_VALIDITY(RANGE_VALID, | 180 TEST_EXPECTED_VALIDITY(true, CheckedNumeric<Dst>(DstLimits::min()) * 2); |
| 201 CheckedNumeric<Dst>(DstLimits::min()) * 2); | |
| 202 | 181 |
| 203 TEST_EXPECTED_VALUE(-0.5, CheckedNumeric<Dst>(-1.0) / 2); | 182 TEST_EXPECTED_VALUE(-0.5, CheckedNumeric<Dst>(-1.0) / 2); |
| 204 EXPECT_EQ(static_cast<Dst>(1.0), CheckedNumeric<Dst>(1.0).ValueFloating()); | 183 EXPECT_EQ(static_cast<Dst>(1.0), CheckedNumeric<Dst>(1.0).ValueFloating()); |
| 205 } | 184 } |
| 206 | 185 |
| 207 // Generic arithmetic tests. | 186 // Generic arithmetic tests. |
| 208 template <typename Dst> | 187 template <typename Dst> |
| 209 static void TestArithmetic(const char* dst, int line) { | 188 static void TestArithmetic(const char* dst, int line) { |
| 210 typedef numeric_limits<Dst> DstLimits; | 189 typedef numeric_limits<Dst> DstLimits; |
| 211 | 190 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 // Generic absolute value. | 230 // Generic absolute value. |
| 252 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>().Abs()); | 231 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>().Abs()); |
| 253 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).Abs()); | 232 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1).Abs()); |
| 254 TEST_EXPECTED_VALUE(DstLimits::max(), | 233 TEST_EXPECTED_VALUE(DstLimits::max(), |
| 255 CheckedNumeric<Dst>(DstLimits::max()).Abs()); | 234 CheckedNumeric<Dst>(DstLimits::max()).Abs()); |
| 256 | 235 |
| 257 // Generic addition. | 236 // Generic addition. |
| 258 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>() + 1)); | 237 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>() + 1)); |
| 259 TEST_EXPECTED_VALUE(2, (CheckedNumeric<Dst>(1) + 1)); | 238 TEST_EXPECTED_VALUE(2, (CheckedNumeric<Dst>(1) + 1)); |
| 260 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) + 1)); | 239 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) + 1)); |
| 261 TEST_EXPECTED_VALIDITY(RANGE_VALID, | 240 TEST_EXPECTED_VALIDITY(true, CheckedNumeric<Dst>(DstLimits::min()) + 1); |
| 262 CheckedNumeric<Dst>(DstLimits::min()) + 1); | |
| 263 TEST_EXPECTED_VALIDITY( | 241 TEST_EXPECTED_VALIDITY( |
| 264 RANGE_OVERFLOW, CheckedNumeric<Dst>(DstLimits::max()) + DstLimits::max()); | 242 false, CheckedNumeric<Dst>(DstLimits::max()) + DstLimits::max()); |
| 265 | 243 |
| 266 // Generic subtraction. | 244 // Generic subtraction. |
| 267 TEST_EXPECTED_VALUE(-1, (CheckedNumeric<Dst>() - 1)); | 245 TEST_EXPECTED_VALUE(-1, (CheckedNumeric<Dst>() - 1)); |
| 268 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(1) - 1)); | 246 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(1) - 1)); |
| 269 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) - 1)); | 247 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) - 1)); |
| 270 TEST_EXPECTED_VALIDITY(RANGE_VALID, | 248 TEST_EXPECTED_VALIDITY(true, CheckedNumeric<Dst>(DstLimits::max()) - 1); |
| 271 CheckedNumeric<Dst>(DstLimits::max()) - 1); | |
| 272 | 249 |
| 273 // Generic multiplication. | 250 // Generic multiplication. |
| 274 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>() * 1)); | 251 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>() * 1)); |
| 275 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>(1) * 1)); | 252 TEST_EXPECTED_VALUE(1, (CheckedNumeric<Dst>(1) * 1)); |
| 276 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) * 2)); | 253 TEST_EXPECTED_VALUE(-2, (CheckedNumeric<Dst>(-1) * 2)); |
| 277 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * 0)); | 254 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * 0)); |
| 278 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) * 0)); | 255 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(-1) * 0)); |
| 279 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * -1)); | 256 TEST_EXPECTED_VALUE(0, (CheckedNumeric<Dst>(0) * -1)); |
| 280 TEST_EXPECTED_VALIDITY( | 257 TEST_EXPECTED_VALIDITY( |
| 281 RANGE_OVERFLOW, CheckedNumeric<Dst>(DstLimits::max()) * DstLimits::max()); | 258 false, CheckedNumeric<Dst>(DstLimits::max()) * DstLimits::max()); |
| 282 | 259 |
| 283 // Generic division. | 260 // Generic division. |
| 284 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() / 1); | 261 TEST_EXPECTED_VALUE(0, CheckedNumeric<Dst>() / 1); |
| 285 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1); | 262 TEST_EXPECTED_VALUE(1, CheckedNumeric<Dst>(1) / 1); |
| 286 TEST_EXPECTED_VALUE(DstLimits::min() / 2, | 263 TEST_EXPECTED_VALUE(DstLimits::min() / 2, |
| 287 CheckedNumeric<Dst>(DstLimits::min()) / 2); | 264 CheckedNumeric<Dst>(DstLimits::min()) / 2); |
| 288 TEST_EXPECTED_VALUE(DstLimits::max() / 2, | 265 TEST_EXPECTED_VALUE(DstLimits::max() / 2, |
| 289 CheckedNumeric<Dst>(DstLimits::max()) / 2); | 266 CheckedNumeric<Dst>(DstLimits::max()) / 2); |
| 290 | 267 |
| 291 TestSpecializedArithmetic<Dst>(dst, line); | 268 TestSpecializedArithmetic<Dst>(dst, line); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 342 // Not floating to integral and... | 319 // Not floating to integral and... |
| 343 (!(DstLimits::is_integer && SrcLimits::is_iec559) && | 320 (!(DstLimits::is_integer && SrcLimits::is_iec559) && |
| 344 // Same sign, same numeric, source is narrower or same. | 321 // Same sign, same numeric, source is narrower or same. |
| 345 ((SrcLimits::is_signed == DstLimits::is_signed && | 322 ((SrcLimits::is_signed == DstLimits::is_signed && |
| 346 sizeof(Dst) >= sizeof(Src)) || | 323 sizeof(Dst) >= sizeof(Src)) || |
| 347 // Or signed destination and source is smaller | 324 // Or signed destination and source is smaller |
| 348 (DstLimits::is_signed && sizeof(Dst) > sizeof(Src)))), | 325 (DstLimits::is_signed && sizeof(Dst) > sizeof(Src)))), |
| 349 "Comparison must be sign preserving and value preserving"); | 326 "Comparison must be sign preserving and value preserving"); |
| 350 | 327 |
| 351 const CheckedNumeric<Dst> checked_dst = SrcLimits::max(); | 328 const CheckedNumeric<Dst> checked_dst = SrcLimits::max(); |
| 352 TEST_EXPECTED_VALIDITY(RANGE_VALID, checked_dst); | 329 TEST_EXPECTED_VALIDITY(true, checked_dst); |
| 353 if (MaxExponent<Dst>::value > MaxExponent<Src>::value) { | 330 if (MaxExponent<Dst>::value > MaxExponent<Src>::value) { |
| 354 if (MaxExponent<Dst>::value >= MaxExponent<Src>::value * 2 - 1) { | 331 if (MaxExponent<Dst>::value >= MaxExponent<Src>::value * 2 - 1) { |
| 355 // At least twice larger type. | 332 // At least twice larger type. |
| 356 TEST_EXPECTED_VALIDITY(RANGE_VALID, SrcLimits::max() * checked_dst); | 333 TEST_EXPECTED_VALIDITY(true, SrcLimits::max() * checked_dst); |
| 357 | 334 |
| 358 } else { // Larger, but not at least twice as large. | 335 } else { // Larger, but not at least twice as large. |
| 359 TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, SrcLimits::max() * checked_dst); | 336 TEST_EXPECTED_VALIDITY(false, SrcLimits::max() * checked_dst); |
| 360 TEST_EXPECTED_VALIDITY(RANGE_VALID, checked_dst + 1); | 337 TEST_EXPECTED_VALIDITY(true, checked_dst + 1); |
| 361 } | 338 } |
| 362 } else { // Same width type. | 339 } else { // Same width type. |
| 363 TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, checked_dst + 1); | 340 TEST_EXPECTED_VALIDITY(false, checked_dst + 1); |
| 364 } | 341 } |
| 365 | 342 |
| 366 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max()); | 343 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max()); |
| 367 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); | 344 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); |
| 368 if (SrcLimits::is_iec559) { | 345 if (SrcLimits::is_iec559) { |
| 369 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast<Src>(-1)); | 346 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max() * static_cast<Src>(-1)); |
| 370 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); | 347 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); |
| 371 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); | 348 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); |
| 372 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); | 349 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); |
| 373 } else if (numeric_limits<Src>::is_signed) { | 350 } else if (numeric_limits<Src>::is_signed) { |
| 374 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); | 351 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); |
| 375 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); | 352 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); |
| 376 } | 353 } |
| 377 } | 354 } |
| 378 }; | 355 }; |
| 379 | 356 |
| 380 template <typename Dst, typename Src> | 357 template <typename Dst, typename Src> |
| 381 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW> { | 358 struct TestNumericConversion<Dst, Src, SIGN_PRESERVING_NARROW> { |
| 382 static void Test(const char *dst, const char *src, int line) { | 359 static void Test(const char *dst, const char *src, int line) { |
| 383 typedef numeric_limits<Src> SrcLimits; | 360 typedef numeric_limits<Src> SrcLimits; |
| 384 typedef numeric_limits<Dst> DstLimits; | 361 typedef numeric_limits<Dst> DstLimits; |
| 385 static_assert(SrcLimits::is_signed == DstLimits::is_signed, | 362 static_assert(SrcLimits::is_signed == DstLimits::is_signed, |
| 386 "Destination and source sign must be the same"); | 363 "Destination and source sign must be the same"); |
| 387 static_assert(sizeof(Dst) < sizeof(Src) || | 364 static_assert(sizeof(Dst) < sizeof(Src) || |
| 388 (DstLimits::is_integer && SrcLimits::is_iec559), | 365 (DstLimits::is_integer && SrcLimits::is_iec559), |
| 389 "Destination must be narrower than source"); | 366 "Destination must be narrower than source"); |
| 390 | 367 |
| 391 const CheckedNumeric<Dst> checked_dst; | 368 const CheckedNumeric<Dst> checked_dst; |
| 392 TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, checked_dst + SrcLimits::max()); | 369 TEST_EXPECTED_VALIDITY(false, checked_dst + SrcLimits::max()); |
| 393 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); | 370 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); |
| 394 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst - SrcLimits::max()); | 371 TEST_EXPECTED_VALIDITY(false, checked_dst - SrcLimits::max()); |
| 395 | 372 |
| 396 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); | 373 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); |
| 397 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); | 374 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); |
| 398 if (SrcLimits::is_iec559) { | 375 if (SrcLimits::is_iec559) { |
| 399 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); | 376 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); |
| 400 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); | 377 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); |
| 401 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); | 378 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); |
| 402 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); | 379 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); |
| 403 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); | 380 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); |
| 404 if (DstLimits::is_integer) { | 381 if (DstLimits::is_integer) { |
| 405 if (SrcLimits::digits < DstLimits::digits) { | 382 if (SrcLimits::digits < DstLimits::digits) { |
| 406 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, | 383 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, |
| 407 static_cast<Src>(DstLimits::max())); | 384 static_cast<Src>(DstLimits::max())); |
| 408 } else { | 385 } else { |
| 409 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max())); | 386 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::max())); |
| 410 } | 387 } |
| 411 TEST_EXPECTED_RANGE( | 388 TEST_EXPECTED_RANGE( |
| 412 RANGE_VALID, | 389 RANGE_VALID, |
| 413 static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>())); | 390 static_cast<Src>(GetMaxConvertibleToFloat<Src, Dst>())); |
| 414 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min())); | 391 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(DstLimits::min())); |
| 415 } | 392 } |
| 416 } else if (SrcLimits::is_signed) { | 393 } else if (SrcLimits::is_signed) { |
| 417 TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1)); | 394 TEST_EXPECTED_VALUE(-1, checked_dst - static_cast<Src>(1)); |
| 418 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); | 395 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); |
| 419 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); | 396 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(-1)); |
| 420 } else { | 397 } else { |
| 421 TEST_EXPECTED_VALIDITY(RANGE_INVALID, checked_dst - static_cast<Src>(1)); | 398 TEST_EXPECTED_VALIDITY(false, checked_dst - static_cast<Src>(1)); |
| 422 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); | 399 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); |
| 423 } | 400 } |
| 424 } | 401 } |
| 425 }; | 402 }; |
| 426 | 403 |
| 427 template <typename Dst, typename Src> | 404 template <typename Dst, typename Src> |
| 428 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL> { | 405 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_WIDEN_OR_EQUAL> { |
| 429 static void Test(const char *dst, const char *src, int line) { | 406 static void Test(const char *dst, const char *src, int line) { |
| 430 typedef numeric_limits<Src> SrcLimits; | 407 typedef numeric_limits<Src> SrcLimits; |
| 431 typedef numeric_limits<Dst> DstLimits; | 408 typedef numeric_limits<Dst> DstLimits; |
| 432 static_assert(sizeof(Dst) >= sizeof(Src), | 409 static_assert(sizeof(Dst) >= sizeof(Src), |
| 433 "Destination must be equal or wider than source."); | 410 "Destination must be equal or wider than source."); |
| 434 static_assert(SrcLimits::is_signed, "Source must be signed"); | 411 static_assert(SrcLimits::is_signed, "Source must be signed"); |
| 435 static_assert(!DstLimits::is_signed, "Destination must be unsigned"); | 412 static_assert(!DstLimits::is_signed, "Destination must be unsigned"); |
| 436 | 413 |
| 437 const CheckedNumeric<Dst> checked_dst; | 414 const CheckedNumeric<Dst> checked_dst; |
| 438 TEST_EXPECTED_VALUE(SrcLimits::max(), checked_dst + SrcLimits::max()); | 415 TEST_EXPECTED_VALUE(SrcLimits::max(), checked_dst + SrcLimits::max()); |
| 439 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + static_cast<Src>(-1)); | 416 TEST_EXPECTED_VALIDITY(false, checked_dst + static_cast<Src>(-1)); |
| 440 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + -SrcLimits::max()); | 417 TEST_EXPECTED_VALIDITY(false, checked_dst + -SrcLimits::max()); |
| 441 | 418 |
| 442 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); | 419 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::min()); |
| 443 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max()); | 420 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::max()); |
| 444 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); | 421 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); |
| 445 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); | 422 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); |
| 446 } | 423 } |
| 447 }; | 424 }; |
| 448 | 425 |
| 449 template <typename Dst, typename Src> | 426 template <typename Dst, typename Src> |
| 450 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_NARROW> { | 427 struct TestNumericConversion<Dst, Src, SIGN_TO_UNSIGN_NARROW> { |
| 451 static void Test(const char *dst, const char *src, int line) { | 428 static void Test(const char *dst, const char *src, int line) { |
| 452 typedef numeric_limits<Src> SrcLimits; | 429 typedef numeric_limits<Src> SrcLimits; |
| 453 typedef numeric_limits<Dst> DstLimits; | 430 typedef numeric_limits<Dst> DstLimits; |
| 454 static_assert((DstLimits::is_integer && SrcLimits::is_iec559) || | 431 static_assert((DstLimits::is_integer && SrcLimits::is_iec559) || |
| 455 (sizeof(Dst) < sizeof(Src)), | 432 (sizeof(Dst) < sizeof(Src)), |
| 456 "Destination must be narrower than source."); | 433 "Destination must be narrower than source."); |
| 457 static_assert(SrcLimits::is_signed, "Source must be signed."); | 434 static_assert(SrcLimits::is_signed, "Source must be signed."); |
| 458 static_assert(!DstLimits::is_signed, "Destination must be unsigned."); | 435 static_assert(!DstLimits::is_signed, "Destination must be unsigned."); |
| 459 | 436 |
| 460 const CheckedNumeric<Dst> checked_dst; | 437 const CheckedNumeric<Dst> checked_dst; |
| 461 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); | 438 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); |
| 462 TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, checked_dst + SrcLimits::max()); | 439 TEST_EXPECTED_VALIDITY(false, checked_dst + SrcLimits::max()); |
| 463 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + static_cast<Src>(-1)); | 440 TEST_EXPECTED_VALIDITY(false, checked_dst + static_cast<Src>(-1)); |
| 464 TEST_EXPECTED_VALIDITY(RANGE_UNDERFLOW, checked_dst + -SrcLimits::max()); | 441 TEST_EXPECTED_VALIDITY(false, checked_dst + -SrcLimits::max()); |
| 465 | 442 |
| 466 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); | 443 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); |
| 467 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); | 444 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); |
| 468 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); | 445 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, static_cast<Src>(-1)); |
| 469 if (SrcLimits::is_iec559) { | 446 if (SrcLimits::is_iec559) { |
| 470 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); | 447 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::max() * -1); |
| 471 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); | 448 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::infinity()); |
| 472 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); | 449 TEST_EXPECTED_RANGE(RANGE_UNDERFLOW, SrcLimits::infinity() * -1); |
| 473 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); | 450 TEST_EXPECTED_RANGE(RANGE_INVALID, SrcLimits::quiet_NaN()); |
| 474 if (DstLimits::is_integer) { | 451 if (DstLimits::is_integer) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 494 static void Test(const char *dst, const char *src, int line) { | 471 static void Test(const char *dst, const char *src, int line) { |
| 495 typedef numeric_limits<Src> SrcLimits; | 472 typedef numeric_limits<Src> SrcLimits; |
| 496 typedef numeric_limits<Dst> DstLimits; | 473 typedef numeric_limits<Dst> DstLimits; |
| 497 static_assert(sizeof(Dst) <= sizeof(Src), | 474 static_assert(sizeof(Dst) <= sizeof(Src), |
| 498 "Destination must be narrower or equal to source."); | 475 "Destination must be narrower or equal to source."); |
| 499 static_assert(!SrcLimits::is_signed, "Source must be unsigned."); | 476 static_assert(!SrcLimits::is_signed, "Source must be unsigned."); |
| 500 static_assert(DstLimits::is_signed, "Destination must be signed."); | 477 static_assert(DstLimits::is_signed, "Destination must be signed."); |
| 501 | 478 |
| 502 const CheckedNumeric<Dst> checked_dst; | 479 const CheckedNumeric<Dst> checked_dst; |
| 503 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); | 480 TEST_EXPECTED_VALUE(1, checked_dst + static_cast<Src>(1)); |
| 504 TEST_EXPECTED_VALIDITY(RANGE_OVERFLOW, checked_dst + SrcLimits::max()); | 481 TEST_EXPECTED_VALIDITY(false, checked_dst + SrcLimits::max()); |
| 505 TEST_EXPECTED_VALUE(SrcLimits::min(), checked_dst + SrcLimits::min()); | 482 TEST_EXPECTED_VALUE(SrcLimits::min(), checked_dst + SrcLimits::min()); |
| 506 | 483 |
| 507 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); | 484 TEST_EXPECTED_RANGE(RANGE_VALID, SrcLimits::min()); |
| 508 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); | 485 TEST_EXPECTED_RANGE(RANGE_OVERFLOW, SrcLimits::max()); |
| 509 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); | 486 TEST_EXPECTED_RANGE(RANGE_VALID, static_cast<Src>(1)); |
| 510 } | 487 } |
| 511 }; | 488 }; |
| 512 | 489 |
| 513 // Helper macro to wrap displaying the conversion types and line numbers | 490 // Helper macro to wrap displaying the conversion types and line numbers |
| 514 #define TEST_NUMERIC_CONVERSION(d, s, t) \ | 491 #define TEST_NUMERIC_CONVERSION(d, s, t) \ |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 775 | 752 |
| 776 CheckedNumeric<int> too_large = std::numeric_limits<int>::max(); | 753 CheckedNumeric<int> too_large = std::numeric_limits<int>::max(); |
| 777 EXPECT_TRUE(too_large.IsValid()); | 754 EXPECT_TRUE(too_large.IsValid()); |
| 778 too_large += d; | 755 too_large += d; |
| 779 EXPECT_FALSE(too_large.IsValid()); | 756 EXPECT_FALSE(too_large.IsValid()); |
| 780 too_large -= d; | 757 too_large -= d; |
| 781 EXPECT_FALSE(too_large.IsValid()); | 758 EXPECT_FALSE(too_large.IsValid()); |
| 782 too_large /= d; | 759 too_large /= d; |
| 783 EXPECT_FALSE(too_large.IsValid()); | 760 EXPECT_FALSE(too_large.IsValid()); |
| 784 } | 761 } |
| OLD | NEW |