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

Side by Side Diff: webrtc/base/mod_ops.h

Issue 1786043004: Implemented more general version of ForwardDiff/RevereseDiff. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Feedback fixes Created 4 years, 9 months 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
« no previous file with comments | « no previous file | webrtc/base/mod_ops_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
11 #ifndef WEBRTC_BASE_MOD_OPS_H_ 11 #ifndef WEBRTC_BASE_MOD_OPS_H_
12 #define WEBRTC_BASE_MOD_OPS_H_ 12 #define WEBRTC_BASE_MOD_OPS_H_
13 13
14 #include <limits> 14 #include <limits>
15 #include <type_traits> 15 #include <type_traits>
16 16
17 #include "webrtc/base/checks.h" 17 #include "webrtc/base/checks.h"
18 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 "Type must be of unsigned integer.")
23
24 namespace webrtc { 19 namespace webrtc {
25 20
26 template <unsigned long M> // NOLINT 21 template <unsigned long M> // NOLINT
27 inline unsigned long Add(unsigned long a, unsigned long b) { // NOLINT 22 inline unsigned long Add(unsigned long a, unsigned long b) { // NOLINT
28 RTC_DCHECK_LT(a, M); 23 RTC_DCHECK_LT(a, M);
29 unsigned long t = M - b % M; // NOLINT 24 unsigned long t = M - b % M; // NOLINT
30 unsigned long res = a - t; // NOLINT 25 unsigned long res = a - t; // NOLINT
31 if (t > a) 26 if (t > a)
32 return res + M; 27 return res + M;
33 return res; 28 return res;
34 } 29 }
35 30
36 template <unsigned long M> // NOLINT 31 template <unsigned long M> // NOLINT
37 inline unsigned long Subtract(unsigned long a, unsigned long b) { // NOLINT 32 inline unsigned long Subtract(unsigned long a, unsigned long b) { // NOLINT
38 RTC_DCHECK_LT(a, M); 33 RTC_DCHECK_LT(a, M);
39 unsigned long sub = b % M; // NOLINT 34 unsigned long sub = b % M; // NOLINT
40 if (a < sub) 35 if (a < sub)
41 return M - (sub - a); 36 return M - (sub - a);
42 return a - sub; 37 return a - sub;
43 } 38 }
44 39
45 // Calculates the forward difference between two numbers. 40 // Calculates the forward difference between two wrapping numbers.
46 // 41 //
47 // Example: 42 // Example:
48 // uint8_t x = 253; 43 // uint8_t x = 253;
49 // uint8_t y = 2; 44 // uint8_t y = 2;
50 // 45 //
51 // ForwardDiff(x, y) == 4 46 // ForwardDiff(x, y) == 4
52 // 47 //
53 // 252 253 254 255 0 1 2 3 48 // 252 253 254 255 0 1 2 3
54 // ################################################# 49 // #################################################
55 // | | x | | | | | y | | 50 // | | x | | | | | y | |
56 // ################################################# 51 // #################################################
57 // |----->----->----->----->-----> 52 // |----->----->----->----->----->
58 // 53 //
59 // ForwardDiff(y, x) == 251 54 // ForwardDiff(y, x) == 251
60 // 55 //
61 // 252 253 254 255 0 1 2 3 56 // 252 253 254 255 0 1 2 3
62 // ################################################# 57 // #################################################
63 // | | x | | | | | y | | 58 // | | x | | | | | y | |
64 // ################################################# 59 // #################################################
65 // -->-----> |----->--- 60 // -->-----> |----->---
66 // 61 //
62 template <typename T, T M>
63 inline T ForwardDiff(T a, T b) {
64 static_assert(std::is_unsigned<T>::value,
65 "Type must be an unsigned integer.");
66 RTC_DCHECK_LT(a, M);
67 RTC_DCHECK_LT(b, M);
68 return a <= b ? b - a : M - (a - b);
69 }
70
67 template <typename T> 71 template <typename T>
68 inline T ForwardDiff(T a, T b) { 72 inline T ForwardDiff(T a, T b) {
69 MOD_OPS_ASSERT_TYPE_IS_UNSIGNED(T); 73 static_assert(std::is_unsigned<T>::value,
74 "Type must be an unsigned integer.");
70 return b - a; 75 return b - a;
71 } 76 }
72 77
73 // Calculates the reverse difference between two numbers. 78 // Calculates the reverse difference between two wrapping numbers.
74 // 79 //
75 // Example: 80 // Example:
76 // uint8_t x = 253; 81 // uint8_t x = 253;
77 // uint8_t y = 2; 82 // uint8_t y = 2;
78 // 83 //
79 // ReverseDiff(y, x) == 5 84 // ReverseDiff(y, x) == 5
80 // 85 //
81 // 252 253 254 255 0 1 2 3 86 // 252 253 254 255 0 1 2 3
82 // ################################################# 87 // #################################################
83 // | | x | | | | | y | | 88 // | | x | | | | | y | |
84 // ################################################# 89 // #################################################
85 // <-----<-----<-----<-----<-----| 90 // <-----<-----<-----<-----<-----|
86 // 91 //
87 // ReverseDiff(x, y) == 251 92 // ReverseDiff(x, y) == 251
88 // 93 //
89 // 252 253 254 255 0 1 2 3 94 // 252 253 254 255 0 1 2 3
90 // ################################################# 95 // #################################################
91 // | | x | | | | | y | | 96 // | | x | | | | | y | |
92 // ################################################# 97 // #################################################
93 // ---<-----| |<-----<-- 98 // ---<-----| |<-----<--
94 // 99 //
100 template <typename T, T M>
101 inline T ReverseDiff(T a, T b) {
102 static_assert(std::is_unsigned<T>::value,
103 "Type must be an unsigned integer.");
104 RTC_DCHECK_LT(a, M);
105 RTC_DCHECK_LT(b, M);
106 return b <= a ? a - b : M - (b - a);
107 }
108
95 template <typename T> 109 template <typename T>
96 inline T ReverseDiff(T a, T b) { 110 inline T ReverseDiff(T a, T b) {
97 MOD_OPS_ASSERT_TYPE_IS_UNSIGNED(T); 111 static_assert(std::is_unsigned<T>::value,
112 "Type must be an unsigned integer.");
98 return a - b; 113 return a - b;
99 } 114 }
100 115
101 // Test if the sequence number a is ahead or at sequence number b. 116 // Test if the sequence number a is ahead or at sequence number b.
102 // If the two sequence numbers are at max distance from each other 117 // If the two sequence numbers are at max distance from each other
103 // then the sequence number with highest value is considered to 118 // then the sequence number with highest value is considered to
104 // be ahead. 119 // be ahead.
105 template <typename T> 120 template <typename T>
106 inline bool AheadOrAt(T a, T b) { 121 inline bool AheadOrAt(T a, T b) {
107 MOD_OPS_ASSERT_TYPE_IS_UNSIGNED(T); 122 static_assert(std::is_unsigned<T>::value,
123 "Type must be an unsigned integer.");
108 const T maxDist = std::numeric_limits<T>::max() / 2 + T(1); 124 const T maxDist = std::numeric_limits<T>::max() / 2 + T(1);
109 if (a - b == maxDist) 125 if (a - b == maxDist)
110 return b < a; 126 return b < a;
111 return ForwardDiff(b, a) < maxDist; 127 return ForwardDiff(b, a) < maxDist;
112 } 128 }
113 129
114 // Test if sequence number a is ahead of sequence number b. 130 // Test if sequence number a is ahead of sequence number b.
115 template <typename T> 131 template <typename T>
116 inline bool AheadOf(T a, T b) { 132 inline bool AheadOf(T a, T b) {
117 MOD_OPS_ASSERT_TYPE_IS_UNSIGNED(T); 133 static_assert(std::is_unsigned<T>::value,
134 "Type must be an unsigned integer.");
118 return a != b && AheadOrAt(a, b); 135 return a != b && AheadOrAt(a, b);
119 } 136 }
120 137
121 } // namespace webrtc 138 } // namespace webrtc
122 139
123 #endif // WEBRTC_BASE_MOD_OPS_H_ 140 #endif // WEBRTC_BASE_MOD_OPS_H_
OLDNEW
« no previous file with comments | « no previous file | webrtc/base/mod_ops_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698