RAVENNAKIT
Loading...
Searching...
No Matches
wrapping_uint.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-or-later
2/*
3 * Project: RAVENNAKIT (RAVENNA / AES67 / ST2110-30 SDK)
4 * Copyright (c) 2024-2025 Sound on Digital
5 *
6 * This file is part of RAVENNAKIT.
7 *
8 * RAVENNAKIT is dual-licensed:
9 * 1) Under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version (the "AGPL License"); and
12 * 2) Under a commercial license from Sound on Digital, for customers who
13 * cannot (or do not wish to) comply with the AGPL License terms.
14 *
15 * If you obtained this file under the AGPL License, you may redistribute it
16 * and/or modify it under the terms of the AGPL License. See the LICENSE
17 * file in the project root for details.
18 *
19 * For commercial licensing, support, and other inquiries, please visit:
20 *
21 * https://ravennakit.com
22 *
23 */
24
25#pragma once
26
27#include <limits>
28#include <type_traits>
29#include <cstdint>
30#include <optional>
31
32namespace rav {
33
40template<class T>
42 static_assert(std::is_integral_v<T>, "WrappingUint only supports integral types");
43 static_assert(std::is_unsigned_v<T>, "WrappingUint only supports unsigned types");
44
45 public:
49 WrappingUint() = default;
50
55 explicit WrappingUint(const T value) : value_(value) {}
56
67 std::optional<T> update(const T value) {
68 if (is_older_than(value, value_)) {
69 return std::nullopt; // Value too old
70 }
71
72 const auto diff = value - value_;
73 value_ = value;
74 return static_cast<T>(diff);
75 }
76
80 [[nodiscard]] explicit operator T() const {
81 return value_;
82 }
83
87 [[nodiscard]] T value() const {
88 return value_;
89 }
90
97 value_ = value;
98 return *this;
99 }
100
107 value_ += value;
108 return *this;
109 }
110
117 value_ -= value;
118 return *this;
119 }
120
126 [[nodiscard]] WrappingUint operator+(const T value) const {
127 return WrappingUint(value_ + value);
128 }
129
135 [[nodiscard]] WrappingUint operator-(const T value) const {
136 return WrappingUint(value_ - value);
137 }
138
144 [[nodiscard]] bool operator==(T other) {
145 return value_ == other;
146 }
147
153 [[nodiscard]] bool operator!=(T other) {
154 return value_ != other;
155 }
156
163 friend bool operator==(const WrappingUint& lhs, const WrappingUint& rhs) {
164 return lhs.value_ == rhs.value_;
165 }
166
173 friend bool operator!=(const WrappingUint& lhs, const WrappingUint& rhs) {
174 return lhs.value_ != rhs.value_;
175 }
176
183 friend bool operator<(const WrappingUint& lhs, const WrappingUint& rhs) {
184 return is_older_than(lhs.value_, rhs.value_);
185 }
186
193 friend bool operator<=(const WrappingUint& lhs, const WrappingUint& rhs) {
194 return lhs < rhs || lhs == rhs;
195 }
196
203 friend bool operator>(const WrappingUint& lhs, const WrappingUint& rhs) {
204 return !(lhs <= rhs);
205 }
206
213 friend bool operator>=(const WrappingUint& lhs, const WrappingUint& rhs) {
214 return lhs > rhs || lhs == rhs;
215 }
216
224 [[nodiscard]] std::make_signed_t<T> diff(const WrappingUint& other) const {
225 return diff(other.value_);
226 }
227
235 [[nodiscard]] std::make_signed_t<T> diff(T other) const {
236 // 1 -> 0
237 if (is_older_than(other, value_)) {
238 return static_cast<std::make_signed_t<T>>(value_ - other) * -1;
239 }
240 return static_cast<std::make_signed_t<T>>(other - value_);
241 }
242
243 private:
244 T value_ {};
245
252 static bool is_older_than(T a, T b) {
253 return !(a == b) && static_cast<T>(b - a) < std::numeric_limits<T>::max() / 2 + 1;
254 }
255};
256
259
262
265
268
269} // namespace rav
Represents sequence numbers with rollover (wraparound) semantics.
friend bool operator>(const WrappingUint &lhs, const WrappingUint &rhs)
Compares the sequence number with the given value.
friend bool operator>=(const WrappingUint &lhs, const WrappingUint &rhs)
Compares the sequence number with the given value.
WrappingUint()=default
Default construct a sequence number with the value 0.
WrappingUint operator-(const T value) const
Decrements the sequence number by the given value.
std::optional< T > update(const T value)
Updates the value in the sequence.
WrappingUint & operator+=(const T value)
Increments the sequence number by 1 using modulo arithmetic.
std::make_signed_t< uint8_t > diff(const WrappingUint &other) const
std::make_signed_t< T > diff(T other) const
Calculates the difference between two sequence numbers, taking into account wraparound.
bool operator!=(T other)
Compares the sequence number with the given value.
WrappingUint operator+(const T value) const
Increments the sequence number by the given value.
WrappingUint & operator-=(const T value)
Decrements the sequence number by 1 using modulo arithmetic.
friend bool operator<=(const WrappingUint &lhs, const WrappingUint &rhs)
Compares the sequence number with the given value.
WrappingUint(const T value)
Construct a sequence number with the given value.
WrappingUint & operator=(const T value)
Assigns a new value to the sequence number.
bool operator==(T other)
Compares the sequence number with the given value.
friend bool operator==(const WrappingUint &lhs, const WrappingUint &rhs)
Compares the sequence number with the given value.
friend bool operator<(const WrappingUint &lhs, const WrappingUint &rhs)
Compares the sequence number with the given value.
friend bool operator!=(const WrappingUint &lhs, const WrappingUint &rhs)
Compares the sequence number with the given value.
WrappingUint< uint32_t > WrappingUint32
32-bit wrapping unsigned integer.
WrappingUint< uint8_t > WrappingUint8
8-bit wrapping unsigned integer.
WrappingUint< uint16_t > WrappingUint16
16-bit wrapping unsigned integer.
WrappingUint< uint64_t > WrappingUint64
64-bit wrapping unsigned integer.