// // SeqNum.h // libraries/networking/src/udt // // Created by Clement on 7/23/15. // Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #ifndef hifi_SeqNum_h #define hifi_SeqNum_h #include #include namespace udt { class SeqNum { public: // Base type of sequence numbers using Type = uint32_t; // Values are for 29 bit SeqNum static const Type THRESHOLD = 0x0FFFFFFF; // threshold for comparing sequence numbers static const Type MAX = 0x1FFFFFFF; // maximum sequence number used in UDT SeqNum() = default; SeqNum(const SeqNum& other) : _value(other._value) {} // Only explicit conversions explicit SeqNum(char* value) { _value = (*reinterpret_cast(value)) & MAX; } explicit SeqNum(Type value) { _value = (value <= MAX) ? value : MAX; } explicit operator Type() { return _value; } inline SeqNum& operator++() { _value = (_value == MAX) ? 0 : ++_value; return *this; } inline SeqNum& operator--() { _value = (_value == 0) ? MAX : --_value; return *this; } inline SeqNum operator++(int) { SeqNum before = *this; (*this)++; return before; } inline SeqNum operator--(int) { SeqNum before = *this; (*this)--; return before; } inline SeqNum& operator=(const SeqNum& other) { _value = other._value; return *this; } inline SeqNum& operator+=(Type inc) { _value = (_value + inc > MAX) ? _value + inc - (MAX + 1) : _value + inc; return *this; } inline SeqNum& operator-=(Type dec) { _value = (_value < dec) ? MAX - (dec - _value + 1) : _value - dec; return *this; } inline bool operator==(const SeqNum& other) const { return _value == other._value; } inline bool operator!=(const SeqNum& other) const { return _value != other._value; } friend bool operator<(const SeqNum& a, const SeqNum& b); friend bool operator>(const SeqNum& a, const SeqNum& b); friend bool operator<=(const SeqNum& a, const SeqNum& b); friend bool operator>=(const SeqNum& a, const SeqNum& b); friend SeqNum operator+(const SeqNum a, const Type& b); friend SeqNum operator+(const Type& a, const SeqNum b); friend SeqNum operator-(const SeqNum a, const Type& b); friend SeqNum operator-(const Type& a, const SeqNum b); friend int seqlen(const SeqNum& seq1, const SeqNum& seq2); friend int seqoff(const SeqNum& seq1, const SeqNum& seq2); private: Type _value { 0 }; friend struct std::hash; }; inline bool operator<(const SeqNum& a, const SeqNum& b) { return (glm::abs(a._value - b._value) < SeqNum::THRESHOLD) ? a._value < b._value : b._value < a._value; } inline bool operator>(const SeqNum& a, const SeqNum& b) { return (glm::abs(a._value - b._value) < SeqNum::THRESHOLD) ? a._value > b._value : b._value > a._value; } inline bool operator<=(const SeqNum& a, const SeqNum& b) { return (glm::abs(a._value - b._value) < SeqNum::THRESHOLD) ? a._value <= b._value : b._value <= a._value; } inline bool operator>=(const SeqNum& a, const SeqNum& b) { return (glm::abs(a._value - b._value) < SeqNum::THRESHOLD) ? a._value >= b._value : b._value >= a._value; } inline SeqNum operator+(SeqNum a, const SeqNum::Type& b) { a += b; return a; } inline SeqNum operator+(const SeqNum::Type& a, SeqNum b) { b += a; return b; } inline SeqNum operator-(SeqNum a, const SeqNum::Type& b) { a -= b; return a; } inline SeqNum operator-(const SeqNum::Type& a, SeqNum b) { b -= a; return b; } int seqlen(const SeqNum& seq1, const SeqNum& seq2); int seqoff(const SeqNum& seq1, const SeqNum& seq2); } template<> struct std::hash { size_t operator()(const udt::SeqNum& seqNum) const { return std::hash()(seqNum._value); } }; #endif // hifi_SeqNum_h