| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 /* | 
|  | 2  *  Copyright (c) 2016 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 | 
|  | 11 #ifndef WEBRTC_BASE_MOD_OPS_H_ | 
|  | 12 #define WEBRTC_BASE_MOD_OPS_H_ | 
|  | 13 | 
|  | 14 #include <limits> | 
|  | 15 #include <type_traits> | 
|  | 16 | 
|  | 17 #include "webrtc/base/checks.h" | 
|  | 18 | 
|  | 19 #define MOD_OPS_ASSERT_TYPE_IS_UNSIGNED(T)              \ | 
|  | 20   static_assert(std::numeric_limits<T>::is_integer &&   \ | 
|  | 21                     !std::numeric_limits<T>::is_signed, \ | 
|  | 22                 "ModNum type must be of unsigned integer.") | 
|  | 23 | 
|  | 24 namespace webrtc { | 
|  | 25 | 
|  | 26 template <uint64_t M> | 
|  | 27 inline uint64_t Add(uint64_t a, uint64_t b) { | 
|  | 28   RTC_DCHECK_LT(a, M); | 
|  | 29   uint64_t add = b % M; | 
|  | 30   if (a + add < a) | 
|  | 31     return a + add - M; | 
|  | 32   return (a + add) % M; | 
|  | 33 } | 
|  | 34 | 
|  | 35 template <uint64_t M> | 
|  | 36 inline uint64_t Subtract(uint64_t a, uint64_t b) { | 
|  | 37   RTC_DCHECK_LT(a, M); | 
|  | 38   uint64_t sub = b % M; | 
|  | 39   if (a < sub) | 
|  | 40     return M - (sub - a); | 
|  | 41   return a - sub; | 
|  | 42 } | 
|  | 43 | 
|  | 44 // Calculates the forward difference between two numbers. | 
|  | 45 // | 
|  | 46 // Example: | 
|  | 47 // uint8_t a = 253; | 
|  | 48 // uint8_t b = 2; | 
|  | 49 // | 
|  | 50 // ForwardDiff(a, b) == 4 | 
|  | 51 // | 
|  | 52 //   252   253   254   255    0     1     2     3 | 
|  | 53 // ################################################# | 
|  | 54 // |     |  a  |     |     |     |     |  b  |     | | 
|  | 55 // ################################################# | 
|  | 56 //          |----->----->----->----->-----> | 
|  | 57 // | 
|  | 58 // ForwardDiff(b, a) == 251 | 
|  | 59 // | 
|  | 60 //   252   253   254   255    0     1     2     3 | 
|  | 61 // ################################################# | 
|  | 62 // |     |  a  |     |     |     |     |  b  |     | | 
|  | 63 // ################################################# | 
|  | 64 // -->----->                              |----->--- | 
|  | 65 // | 
|  | 66 template <typename T> | 
|  | 67 inline T ForwardDiff(T a, T b) { | 
|  | 68   MOD_OPS_ASSERT_TYPE_IS_UNSIGNED(T); | 
|  | 69   return a <= b ? b - a : std::numeric_limits<T>::max() - (a - b); | 
|  | 70 } | 
|  | 71 | 
|  | 72 // Calculates the reverse difference between two numbers. | 
|  | 73 // | 
|  | 74 // Example: | 
|  | 75 // uint8_t a = 253; | 
|  | 76 // uint8_t b = 2; | 
|  | 77 // | 
|  | 78 // ReverseDiff(a, b) == 251 | 
|  | 79 // | 
|  | 80 //   252   253   254   255    0     1     2     3 | 
|  | 81 // ################################################# | 
|  | 82 // |     |  a  |     |     |     |     |  b  |     | | 
|  | 83 // ################################################# | 
|  | 84 //          <-----<-----<-----<-----<-----| | 
|  | 85 // | 
|  | 86 // ReverseDiff(b, a) == 5 | 
|  | 87 // | 
|  | 88 //   252   253   254   255    0     1     2     3 | 
|  | 89 // ################################################# | 
|  | 90 // |     |  a  |     |     |     |     |  b  |     | | 
|  | 91 // ################################################# | 
|  | 92 // ---<-----|                             |<-----<-- | 
|  | 93 // | 
|  | 94 template <typename T> | 
|  | 95 inline T ReverseDiff(T a, T b) { | 
|  | 96   MOD_OPS_ASSERT_TYPE_IS_UNSIGNED(T); | 
|  | 97   return a < b ? std::numeric_limits<T>::max() - (b - a) : a - b; | 
|  | 98 } | 
|  | 99 | 
|  | 100 template <typename T> | 
|  | 101 inline bool AheadOrAt(T a, T b) { | 
|  | 102   MOD_OPS_ASSERT_TYPE_IS_UNSIGNED(T); | 
|  | 103   return ForwardDiff(b, a) < std::numeric_limits<T>::max() / 2; | 
|  | 104 } | 
|  | 105 | 
|  | 106 template <typename T> | 
|  | 107 inline bool AheadOf(T a, T b) { | 
|  | 108   MOD_OPS_ASSERT_TYPE_IS_UNSIGNED(T); | 
|  | 109   return a != b && AheadOrAt(a, b); | 
|  | 110 } | 
|  | 111 | 
|  | 112 }  // namespace webrtc | 
|  | 113 | 
|  | 114 #endif  // WEBRTC_BASE_MOD_OPS_H_ | 
| OLD | NEW | 
|---|