OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 // |----->----->----->----->-----> | 52 // |----->----->----->----->-----> |
53 // | 53 // |
54 // ForwardDiff(y, x) == 251 | 54 // ForwardDiff(y, x) == 251 |
55 // | 55 // |
56 // 252 253 254 255 0 1 2 3 | 56 // 252 253 254 255 0 1 2 3 |
57 // ################################################# | 57 // ################################################# |
58 // | | x | | | | | y | | | 58 // | | x | | | | | y | | |
59 // ################################################# | 59 // ################################################# |
60 // -->-----> |----->--- | 60 // -->-----> |----->--- |
61 // | 61 // |
| 62 // If M > 0 then wrapping occurs at M, if M == 0 then wrapping occurs at the |
| 63 // largest value representable by T. |
62 template <typename T, T M> | 64 template <typename T, T M> |
63 inline T ForwardDiff(T a, T b) { | 65 inline typename std::enable_if<(M > 0), T>::type ForwardDiff(T a, T b) { |
64 static_assert(std::is_unsigned<T>::value, | 66 static_assert(std::is_unsigned<T>::value, |
65 "Type must be an unsigned integer."); | 67 "Type must be an unsigned integer."); |
66 RTC_DCHECK_LT(a, M); | 68 RTC_DCHECK_LT(a, M); |
67 RTC_DCHECK_LT(b, M); | 69 RTC_DCHECK_LT(b, M); |
68 return a <= b ? b - a : M - (a - b); | 70 return a <= b ? b - a : M - (a - b); |
69 } | 71 } |
70 | 72 |
71 template <typename T> | 73 template <typename T, T M> |
72 inline T ForwardDiff(T a, T b) { | 74 inline typename std::enable_if<(M == 0), T>::type ForwardDiff(T a, T b) { |
73 static_assert(std::is_unsigned<T>::value, | 75 static_assert(std::is_unsigned<T>::value, |
74 "Type must be an unsigned integer."); | 76 "Type must be an unsigned integer."); |
75 return b - a; | 77 return b - a; |
76 } | 78 } |
77 | 79 |
| 80 template <typename T> |
| 81 inline T ForwardDiff(T a, T b) { |
| 82 return ForwardDiff<T, 0>(a, b); |
| 83 } |
| 84 |
78 // Calculates the reverse difference between two wrapping numbers. | 85 // Calculates the reverse difference between two wrapping numbers. |
79 // | 86 // |
80 // Example: | 87 // Example: |
81 // uint8_t x = 253; | 88 // uint8_t x = 253; |
82 // uint8_t y = 2; | 89 // uint8_t y = 2; |
83 // | 90 // |
84 // ReverseDiff(y, x) == 5 | 91 // ReverseDiff(y, x) == 5 |
85 // | 92 // |
86 // 252 253 254 255 0 1 2 3 | 93 // 252 253 254 255 0 1 2 3 |
87 // ################################################# | 94 // ################################################# |
88 // | | x | | | | | y | | | 95 // | | x | | | | | y | | |
89 // ################################################# | 96 // ################################################# |
90 // <-----<-----<-----<-----<-----| | 97 // <-----<-----<-----<-----<-----| |
91 // | 98 // |
92 // ReverseDiff(x, y) == 251 | 99 // ReverseDiff(x, y) == 251 |
93 // | 100 // |
94 // 252 253 254 255 0 1 2 3 | 101 // 252 253 254 255 0 1 2 3 |
95 // ################################################# | 102 // ################################################# |
96 // | | x | | | | | y | | | 103 // | | x | | | | | y | | |
97 // ################################################# | 104 // ################################################# |
98 // ---<-----| |<-----<-- | 105 // ---<-----| |<-----<-- |
99 // | 106 // |
| 107 // If M > 0 then wrapping occurs at M, if M == 0 then wrapping occurs at the |
| 108 // largest value representable by T. |
100 template <typename T, T M> | 109 template <typename T, T M> |
101 inline T ReverseDiff(T a, T b) { | 110 inline typename std::enable_if<(M > 0), T>::type ReverseDiff(T a, T b) { |
102 static_assert(std::is_unsigned<T>::value, | 111 static_assert(std::is_unsigned<T>::value, |
103 "Type must be an unsigned integer."); | 112 "Type must be an unsigned integer."); |
104 RTC_DCHECK_LT(a, M); | 113 RTC_DCHECK_LT(a, M); |
105 RTC_DCHECK_LT(b, M); | 114 RTC_DCHECK_LT(b, M); |
106 return b <= a ? a - b : M - (b - a); | 115 return b <= a ? a - b : M - (b - a); |
107 } | 116 } |
108 | 117 |
109 template <typename T> | 118 template <typename T, T M> |
110 inline T ReverseDiff(T a, T b) { | 119 inline typename std::enable_if<(M == 0), T>::type ReverseDiff(T a, T b) { |
111 static_assert(std::is_unsigned<T>::value, | 120 static_assert(std::is_unsigned<T>::value, |
112 "Type must be an unsigned integer."); | 121 "Type must be an unsigned integer."); |
113 return a - b; | 122 return a - b; |
114 } | 123 } |
115 | 124 |
| 125 template <typename T> |
| 126 inline T ReverseDiff(T a, T b) { |
| 127 return ReverseDiff<T, 0>(a, b); |
| 128 } |
| 129 |
116 // Calculates the minimum distance between to wrapping numbers. | 130 // Calculates the minimum distance between to wrapping numbers. |
117 // | 131 // |
118 // The minimum distance is defined as min(ForwardDiff(a, b), ReverseDiff(a, b)) | 132 // The minimum distance is defined as min(ForwardDiff(a, b), ReverseDiff(a, b)) |
119 template <typename T, T M> | 133 template <typename T, T M = 0> |
120 inline T MinDiff(T a, T b) { | 134 inline T MinDiff(T a, T b) { |
121 static_assert(std::is_unsigned<T>::value, | 135 static_assert(std::is_unsigned<T>::value, |
122 "Type must be an unsigned integer."); | 136 "Type must be an unsigned integer."); |
123 return std::min(ForwardDiff<T, M>(a, b), ReverseDiff<T, M>(a, b)); | 137 return std::min(ForwardDiff<T, M>(a, b), ReverseDiff<T, M>(a, b)); |
124 } | 138 } |
125 | 139 |
126 template <typename T> | |
127 inline T MinDiff(T a, T b) { | |
128 static_assert(std::is_unsigned<T>::value, | |
129 "Type must be an unsigned integer."); | |
130 return std::min(ForwardDiff(a, b), ReverseDiff(a, b)); | |
131 } | |
132 | |
133 } // namespace webrtc | 140 } // namespace webrtc |
134 | 141 |
135 #endif // WEBRTC_RTC_BASE_MOD_OPS_H_ | 142 #endif // WEBRTC_RTC_BASE_MOD_OPS_H_ |
OLD | NEW |