mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-26 20:25:34 +08:00
44 lines
1.7 KiB
C++
44 lines
1.7 KiB
C++
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <limits>
|
|
|
|
template <typename U>
|
|
inline bool IsNewer(U value, U prev_value) {
|
|
static_assert(!std::numeric_limits<U>::is_signed, "U must be unsigned");
|
|
// kBreakpoint is the half-way mark for the type U. For instance, for a
|
|
// uint16_t it will be 0x8000, and for a uint32_t, it will be 0x8000000.
|
|
constexpr U kBreakpoint = (std::numeric_limits<U>::max() >> 1) + 1;
|
|
// Distinguish between elements that are exactly kBreakpoint apart.
|
|
// If t1>t2 and |t1-t2| = kBreakpoint: IsNewer(t1,t2)=true,
|
|
// IsNewer(t2,t1)=false
|
|
// rather than having IsNewer(t1,t2) = IsNewer(t2,t1) = false.
|
|
if (value - prev_value == kBreakpoint) {
|
|
return value > prev_value;
|
|
}
|
|
return value != prev_value &&
|
|
static_cast<U>(value - prev_value) < kBreakpoint;
|
|
}
|
|
|
|
// NB: Doesn't fulfill strict weak ordering requirements.
|
|
// Mustn't be used as std::map Compare function.
|
|
inline bool IsNewerSequenceNumber(uint16_t sequence_number,
|
|
uint16_t prev_sequence_number) {
|
|
return IsNewer(sequence_number, prev_sequence_number);
|
|
}
|
|
|
|
// NB: Doesn't fulfill strict weak ordering requirements.
|
|
// Mustn't be used as std::map Compare function.
|
|
inline bool IsNewerTimestamp(uint32_t timestamp, uint32_t prev_timestamp) {
|
|
return IsNewer(timestamp, prev_timestamp);
|
|
}
|
|
|
|
inline uint16_t LatestSequenceNumber(uint16_t sequence_number1,
|
|
uint16_t sequence_number2) {
|
|
return IsNewerSequenceNumber(sequence_number1, sequence_number2)
|
|
? sequence_number1
|
|
: sequence_number2;
|
|
}
|
|
|
|
inline uint32_t LatestTimestamp(uint32_t timestamp1, uint32_t timestamp2) {
|
|
return IsNewerTimestamp(timestamp1, timestamp2) ? timestamp1 : timestamp2;
|
|
} |