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

Side by Side Diff: base/numerics/safe_conversions_impl.h

Issue 2545253002: Add support for CheckedNumeric Max and Min constexpr functions (Closed)
Patch Set: stupid compilers with weak constexpr float support Created 4 years 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 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
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.
dcheng 2016/12/03 21:34:29 Nit: it kind of feels like we should be more consi
jschuh 2016/12/03 22:29:12 I tried to be consistent with std::numeric_limits<
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698