OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #ifndef BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ | 5 #ifndef BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ |
6 #define BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ | 6 #define BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ |
7 | 7 |
8 #include <limits.h> | 8 #include <limits.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 static const typename std::enable_if<std::numeric_limits<Integer>::is_integer, | 328 static const typename std::enable_if<std::numeric_limits<Integer>::is_integer, |
329 size_t>::type value = | 329 size_t>::type value = |
330 CHAR_BIT * sizeof(Integer) - 1; | 330 CHAR_BIT * sizeof(Integer) - 1; |
331 }; | 331 }; |
332 | 332 |
333 enum ArithmeticPromotionCategory { | 333 enum ArithmeticPromotionCategory { |
334 LEFT_PROMOTION, // Use the type of the left-hand argument. | 334 LEFT_PROMOTION, // Use the type of the left-hand argument. |
335 RIGHT_PROMOTION // Use the type of the right-hand argument. | 335 RIGHT_PROMOTION // Use the type of the right-hand argument. |
336 }; | 336 }; |
337 | 337 |
338 template <ArithmeticPromotionCategory Promotion, | 338 // Determines the type that can represent the largest positive value. |
339 typename Lhs, | |
340 typename Rhs = Lhs> | |
341 struct ArithmeticPromotion; | |
342 | |
343 template <typename Lhs, | 339 template <typename Lhs, |
344 typename Rhs, | 340 typename Rhs, |
345 ArithmeticPromotionCategory Promotion = | 341 ArithmeticPromotionCategory Promotion = |
346 (MaxExponent<Lhs>::value > MaxExponent<Rhs>::value) | 342 (MaxExponent<Lhs>::value > MaxExponent<Rhs>::value) |
347 ? LEFT_PROMOTION | 343 ? LEFT_PROMOTION |
348 : RIGHT_PROMOTION> | 344 : RIGHT_PROMOTION> |
349 struct MaxExponentPromotion; | 345 struct MaxExponentPromotion; |
350 | 346 |
351 template <typename Lhs, typename Rhs> | 347 template <typename Lhs, typename Rhs> |
352 struct MaxExponentPromotion<Lhs, Rhs, LEFT_PROMOTION> { | 348 struct MaxExponentPromotion<Lhs, Rhs, LEFT_PROMOTION> { |
353 using type = Lhs; | 349 using type = Lhs; |
354 }; | 350 }; |
355 | 351 |
356 template <typename Lhs, typename Rhs> | 352 template <typename Lhs, typename Rhs> |
357 struct MaxExponentPromotion<Lhs, Rhs, RIGHT_PROMOTION> { | 353 struct MaxExponentPromotion<Lhs, Rhs, RIGHT_PROMOTION> { |
358 using type = Rhs; | 354 using type = Rhs; |
359 }; | 355 }; |
360 | 356 |
| 357 // Determines the type that can represent the lowest arithmetic value. |
| 358 template <typename Lhs, |
| 359 typename Rhs, |
| 360 ArithmeticPromotionCategory Promotion = |
| 361 std::is_signed<Lhs>::value |
| 362 ? (std::is_signed<Rhs>::value |
| 363 ? (MaxExponent<Lhs>::value > MaxExponent<Rhs>::value |
| 364 ? LEFT_PROMOTION |
| 365 : RIGHT_PROMOTION) |
| 366 : LEFT_PROMOTION) |
| 367 : (std::is_signed<Rhs>::value |
| 368 ? RIGHT_PROMOTION |
| 369 : (MaxExponent<Lhs>::value < MaxExponent<Rhs>::value |
| 370 ? LEFT_PROMOTION |
| 371 : RIGHT_PROMOTION))> |
| 372 struct LowestValuePromotion; |
| 373 |
| 374 template <typename Lhs, typename Rhs> |
| 375 struct LowestValuePromotion<Lhs, Rhs, LEFT_PROMOTION> { |
| 376 using type = Lhs; |
| 377 }; |
| 378 |
| 379 template <typename Lhs, typename Rhs> |
| 380 struct LowestValuePromotion<Lhs, Rhs, RIGHT_PROMOTION> { |
| 381 using type = Rhs; |
| 382 }; |
| 383 |
| 384 // Determines the type that is best able to represent an arithmetic result. |
361 template <typename Lhs, | 385 template <typename Lhs, |
362 typename Rhs = Lhs, | 386 typename Rhs = Lhs, |
363 bool is_intmax_type = | 387 bool is_intmax_type = |
364 std::is_integral< | 388 std::is_integral< |
365 typename MaxExponentPromotion<Lhs, Rhs>::type>::value && | 389 typename MaxExponentPromotion<Lhs, Rhs>::type>::value && |
366 sizeof(typename MaxExponentPromotion<Lhs, Rhs>::type) == | 390 sizeof(typename MaxExponentPromotion<Lhs, Rhs>::type) == |
367 sizeof(intmax_t), | 391 sizeof(intmax_t), |
368 bool is_max_exponent = | 392 bool is_max_exponent = |
369 StaticDstRangeRelationToSrcRange< | 393 StaticDstRangeRelationToSrcRange< |
370 typename MaxExponentPromotion<Lhs, Rhs>::type, | 394 typename MaxExponentPromotion<Lhs, Rhs>::type, |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 static_cast<BigType>(static_cast<L>(lhs)), | 642 static_cast<BigType>(static_cast<L>(lhs)), |
619 static_cast<BigType>(static_cast<R>(rhs))) | 643 static_cast<BigType>(static_cast<R>(rhs))) |
620 // Let the template functions figure it out for mixed types. | 644 // Let the template functions figure it out for mixed types. |
621 : C<L, R>::Test(lhs, rhs); | 645 : C<L, R>::Test(lhs, rhs); |
622 }; | 646 }; |
623 | 647 |
624 } // namespace internal | 648 } // namespace internal |
625 } // namespace base | 649 } // namespace base |
626 | 650 |
627 #endif // BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ | 651 #endif // BASE_NUMERICS_SAFE_CONVERSIONS_IMPL_H_ |
OLD | NEW |