Chromium Code Reviews| Index: webrtc/base/mod_ops.h | 
| diff --git a/webrtc/base/mod_ops.h b/webrtc/base/mod_ops.h | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..b105a49db4225b22d926c59730950665928f1296 | 
| --- /dev/null | 
| +++ b/webrtc/base/mod_ops.h | 
| @@ -0,0 +1,115 @@ | 
| +/* | 
| + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 
| + * | 
| + * Use of this source code is governed by a BSD-style license | 
| + * that can be found in the LICENSE file in the root of the source | 
| + * tree. An additional intellectual property rights grant can be found | 
| + * in the file PATENTS. All contributing project authors may | 
| + * be found in the AUTHORS file in the root of the source tree. | 
| + */ | 
| + | 
| +#ifndef WEBRTC_BASE_MOD_OPS_H_ | 
| +#define WEBRTC_BASE_MOD_OPS_H_ | 
| + | 
| +#include <limits> | 
| +#include <type_traits> | 
| + | 
| +#include "webrtc/base/checks.h" | 
| + | 
| +#define MOD_OPS_ASSERT_TYPE_IS_UNSIGNED(T) \ | 
| + static_assert(std::numeric_limits<T>::is_integer && \ | 
| + !std::numeric_limits<T>::is_signed, \ | 
| + "ModNum type must be of unsigned integer.") | 
| + | 
| +namespace webrtc { | 
| + | 
| +template <unsigned long M> // NOLINT | 
| +inline unsigned long Add(unsigned long a, unsigned long b) { // NOLINT | 
| + RTC_DCHECK_LT(a, M); | 
| + unsigned long t = M - b % M; // NOLINT | 
| + unsigned long res = a - t; // NOLINT | 
| + if (t > a) | 
| + return res + M; | 
| + return res; | 
| +} | 
| + | 
| +template <unsigned long M> // NOLINT | 
| +inline unsigned long Subtract(unsigned long a, unsigned long b) { // NOLINT | 
| + RTC_DCHECK_LT(a, M); // NOLINT | 
| 
 
torbjorng (webrtc)
2016/03/02 16:20:50
Nit: this NOLINT seems unneeded.
 
philipel
2016/03/03 12:21:36
Done.
 
 | 
| + unsigned long sub = b % M; // NOLINT | 
| + if (a < sub) | 
| + return M - (sub - a); | 
| + return a - sub; | 
| +} | 
| + | 
| +// Calculates the forward difference between two numbers. | 
| +// | 
| +// Example: | 
| +// uint8_t a = 253; | 
| +// uint8_t b = 2; | 
| +// | 
| +// ForwardDiff(a, b) == 4 | 
| +// | 
| +// 252 253 254 255 0 1 2 3 | 
| +// ################################################# | 
| +// | | a | | | | | b | | | 
| +// ################################################# | 
| +// |----->----->----->----->-----> | 
| +// | 
| +// ForwardDiff(b, a) == 251 | 
| +// | 
| +// 252 253 254 255 0 1 2 3 | 
| +// ################################################# | 
| +// | | a | | | | | b | | | 
| +// ################################################# | 
| +// -->-----> |----->--- | 
| +// | 
| +template <typename T> | 
| +inline T ForwardDiff(T a, T b) { | 
| 
 
torbjorng (webrtc)
2016/03/02 16:20:50
See comment about ReverseDiff.
 
philipel
2016/03/03 12:21:36
Done.
 
 | 
| + MOD_OPS_ASSERT_TYPE_IS_UNSIGNED(T); | 
| + return a <= b ? b - a : std::numeric_limits<T>::max() - (a - b); | 
| +} | 
| + | 
| +// Calculates the reverse difference between two numbers. | 
| +// | 
| +// Example: | 
| +// uint8_t a = 253; | 
| +// uint8_t b = 2; | 
| +// | 
| +// ReverseDiff(a, b) == 251 | 
| +// | 
| +// 252 253 254 255 0 1 2 3 | 
| +// ################################################# | 
| +// | | a | | | | | b | | | 
| +// ################################################# | 
| +// <-----<-----<-----<-----<-----| | 
| +// | 
| +// ReverseDiff(b, a) == 5 | 
| +// | 
| +// 252 253 254 255 0 1 2 3 | 
| +// ################################################# | 
| +// | | a | | | | | b | | | 
| +// ################################################# | 
| +// ---<-----| |<-----<-- | 
| +// | 
| +template <typename T> | 
| 
 
torbjorng (webrtc)
2016/03/02 16:20:50
What's the intended range here?  Presumably 0..255
 
philipel
2016/03/03 12:21:36
I have now unstupidified the code and implemented
 
 | 
| +inline T ReverseDiff(T a, T b) { | 
| + MOD_OPS_ASSERT_TYPE_IS_UNSIGNED(T); | 
| + return a < b ? std::numeric_limits<T>::max() - (b - a) : a - b; | 
| +} | 
| + | 
| +template <typename T> | 
| 
 
torbjorng (webrtc)
2016/03/02 16:20:50
The criteria for "ahead of" is a bit arbitrary. Pl
 
philipel
2016/03/03 12:21:36
Done.
 
 | 
| +inline bool AheadOrAt(T a, T b) { | 
| + MOD_OPS_ASSERT_TYPE_IS_UNSIGNED(T); | 
| + return ForwardDiff(b, a) < std::numeric_limits<T>::max() / 2; | 
| +} | 
| + | 
| +template <typename T> | 
| +inline bool AheadOf(T a, T b) { | 
| + MOD_OPS_ASSERT_TYPE_IS_UNSIGNED(T); | 
| + return a != b && AheadOrAt(a, b); | 
| +} | 
| + | 
| +} // namespace webrtc | 
| + | 
| +#endif // WEBRTC_BASE_MOD_OPS_H_ |