math_utils.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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 API_NUMERICS_MATH_UTILS_H_
  11. #define API_NUMERICS_MATH_UTILS_H_
  12. #include <limits>
  13. #include <type_traits>
  14. #include "rtc_base/checks.h"
  15. namespace webrtc {
  16. namespace webrtc_impl {
  17. // Given two numbers |x| and |y| such that x >= y, computes the difference
  18. // x - y without causing undefined behavior due to signed overflow.
  19. template <typename T>
  20. typename std::make_unsigned<T>::type unsigned_difference(T x, T y) {
  21. static_assert(
  22. std::is_signed<T>::value,
  23. "Function unsigned_difference is only meaningful for signed types.");
  24. RTC_DCHECK_GE(x, y);
  25. typedef typename std::make_unsigned<T>::type unsigned_type;
  26. // int -> unsigned conversion repeatedly adds UINT_MAX + 1 until the number
  27. // can be represented as an unsigned. Since we know that the actual
  28. // difference x - y can be represented as an unsigned, it is sufficient to
  29. // compute the difference modulo UINT_MAX + 1, i.e using unsigned arithmetic.
  30. return static_cast<unsigned_type>(x) - static_cast<unsigned_type>(y);
  31. }
  32. // Provide neutral element with respect to min().
  33. // Typically used as an initial value for running minimum.
  34. template <typename T,
  35. typename std::enable_if<std::numeric_limits<T>::has_infinity>::type* =
  36. nullptr>
  37. constexpr T infinity_or_max() {
  38. return std::numeric_limits<T>::infinity();
  39. }
  40. template <typename T,
  41. typename std::enable_if<
  42. !std::numeric_limits<T>::has_infinity>::type* = nullptr>
  43. constexpr T infinity_or_max() {
  44. // Fallback to max().
  45. return std::numeric_limits<T>::max();
  46. }
  47. // Provide neutral element with respect to max().
  48. // Typically used as an initial value for running maximum.
  49. template <typename T,
  50. typename std::enable_if<std::numeric_limits<T>::has_infinity>::type* =
  51. nullptr>
  52. constexpr T minus_infinity_or_min() {
  53. static_assert(std::is_signed<T>::value, "Unsupported. Please open a bug.");
  54. return -std::numeric_limits<T>::infinity();
  55. }
  56. template <typename T,
  57. typename std::enable_if<
  58. !std::numeric_limits<T>::has_infinity>::type* = nullptr>
  59. constexpr T minus_infinity_or_min() {
  60. // Fallback to min().
  61. return std::numeric_limits<T>::min();
  62. }
  63. } // namespace webrtc_impl
  64. } // namespace webrtc
  65. #endif // API_NUMERICS_MATH_UTILS_H_