math_utils.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /*
  2. * Copyright 2005 The WebRTC Project Authors. All rights reserved.
  3. *
  4. * Use of this source code is governed by a BSD-style license
  5. * that can be found in the LICENSE file in the root of the source
  6. * tree. An additional intellectual property rights grant can be found
  7. * in the file PATENTS. All contributing project authors may
  8. * be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef RTC_BASE_NUMERICS_MATH_UTILS_H_
  11. #define RTC_BASE_NUMERICS_MATH_UTILS_H_
  12. #include <limits>
  13. #include <type_traits>
  14. #include "rtc_base/checks.h"
  15. // Given two numbers |x| and |y| such that x >= y, computes the difference
  16. // x - y without causing undefined behavior due to signed overflow.
  17. template <typename T>
  18. typename std::make_unsigned<T>::type unsigned_difference(T x, T y) {
  19. static_assert(
  20. std::is_signed<T>::value,
  21. "Function unsigned_difference is only meaningful for signed types.");
  22. RTC_DCHECK_GE(x, y);
  23. typedef typename std::make_unsigned<T>::type unsigned_type;
  24. // int -> unsigned conversion repeatedly adds UINT_MAX + 1 until the number
  25. // can be represented as an unsigned. Since we know that the actual
  26. // difference x - y can be represented as an unsigned, it is sufficient to
  27. // compute the difference modulo UINT_MAX + 1, i.e using unsigned arithmetic.
  28. return static_cast<unsigned_type>(x) - static_cast<unsigned_type>(y);
  29. }
  30. // Provide neutral element with respect to min().
  31. // Typically used as an initial value for running minimum.
  32. template <typename T,
  33. typename std::enable_if<std::numeric_limits<T>::has_infinity>::type* =
  34. nullptr>
  35. constexpr T infinity_or_max() {
  36. return std::numeric_limits<T>::infinity();
  37. }
  38. template <typename T,
  39. typename std::enable_if<
  40. !std::numeric_limits<T>::has_infinity>::type* = nullptr>
  41. constexpr T infinity_or_max() {
  42. // Fallback to max().
  43. return std::numeric_limits<T>::max();
  44. }
  45. // Provide neutral element with respect to max().
  46. // Typically used as an initial value for running maximum.
  47. template <typename T,
  48. typename std::enable_if<std::numeric_limits<T>::has_infinity>::type* =
  49. nullptr>
  50. constexpr T minus_infinity_or_min() {
  51. static_assert(std::is_signed<T>::value, "Unsupported. Please open a bug.");
  52. return -std::numeric_limits<T>::infinity();
  53. }
  54. template <typename T,
  55. typename std::enable_if<
  56. !std::numeric_limits<T>::has_infinity>::type* = nullptr>
  57. constexpr T minus_infinity_or_min() {
  58. // Fallback to min().
  59. return std::numeric_limits<T>::min();
  60. }
  61. #endif // RTC_BASE_NUMERICS_MATH_UTILS_H_