libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
framenumber.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
13#include <cmath>
14#include <cstdint>
15#include <limits>
16#include <promeki/namespace.h>
17#include <promeki/string.h>
18#include <promeki/error.h>
19#include <promeki/result.h>
20#include <promeki/datatype.h>
21
22PROMEKI_NAMESPACE_BEGIN
23
24class DataStream;
25
26class FrameCount;
27
68class FrameNumber {
69 public:
70 PROMEKI_DATATYPE(FrameNumber, DataTypeFrameNumber, 1)
71
72
73 Error writeToStream(DataStream &s) const;
75 template <uint32_t V> static Result<FrameNumber> readFromStream(DataStream &s);
76
78 static constexpr int64_t UnknownValue = -1;
79
84 static constexpr FrameNumber unknown() { return FrameNumber(); }
85
101 static Result<FrameNumber> fromString(const String &str);
102
104 constexpr FrameNumber() = default;
105
116 constexpr FrameNumber(int64_t v) : _value(v < 0 ? UnknownValue : v) {}
117
119 constexpr bool isValid() const { return _value >= 0; }
120
122 constexpr bool isUnknown() const { return _value < 0; }
123
125 constexpr int64_t value() const { return _value; }
126
133 double toDouble() const {
134 return isValid() ? static_cast<double>(_value)
135 : std::numeric_limits<double>::quiet_NaN();
136 }
137
146 static Result<FrameNumber> fromDouble(double v) {
147 if (std::isnan(v)) return makeResult(FrameNumber());
148 if (!std::isfinite(v) || v < 0.0) return makeResult(FrameNumber());
149 return makeResult(FrameNumber(static_cast<int64_t>(v)));
150 }
151
153 FrameNumber &operator++() {
154 if (isValid()) ++_value;
155 return *this;
156 }
157
159 FrameNumber operator++(int) {
160 FrameNumber old = *this;
161 ++(*this);
162 return old;
163 }
164
166 FrameNumber &operator--() {
167 if (isValid()) {
168 if (_value == 0)
169 _value = UnknownValue;
170 else
171 --_value;
172 }
173 return *this;
174 }
175
177 FrameNumber operator--(int) {
178 FrameNumber old = *this;
179 --(*this);
180 return old;
181 }
182
184 FrameNumber &operator+=(int64_t n) {
185 if (isValid()) {
186 int64_t nv = _value + n;
187 _value = nv < 0 ? UnknownValue : nv;
188 }
189 return *this;
190 }
191
193 FrameNumber &operator-=(int64_t n) {
194 if (isValid()) {
195 int64_t nv = _value - n;
196 _value = nv < 0 ? UnknownValue : nv;
197 }
198 return *this;
199 }
200
202 FrameNumber &operator+=(const FrameCount &c);
203
205 FrameNumber &operator-=(const FrameCount &c);
206
208 constexpr bool operator==(const FrameNumber &other) const { return _value == other._value; }
209
211 constexpr bool operator!=(const FrameNumber &other) const { return _value != other._value; }
212
214 constexpr bool operator<(const FrameNumber &other) const { return _value < other._value; }
215 constexpr bool operator<=(const FrameNumber &other) const { return _value <= other._value; }
216 constexpr bool operator>(const FrameNumber &other) const { return _value > other._value; }
217 constexpr bool operator>=(const FrameNumber &other) const { return _value >= other._value; }
218
224 String toString() const;
225
227 operator String() const { return toString(); }
228
229 private:
230 int64_t _value = UnknownValue;
231};
232
234inline FrameNumber operator+(FrameNumber a, int64_t n) {
235 a += n;
236 return a;
237}
239inline FrameNumber operator-(FrameNumber a, int64_t n) {
240 a -= n;
241 return a;
242}
244inline FrameNumber operator+(int64_t n, FrameNumber a) {
245 a += n;
246 return a;
247}
248
249PROMEKI_NAMESPACE_END
250
251PROMEKI_FORMAT_VIA_TOSTRING(promeki::FrameNumber);
252
261template <> struct std::hash<promeki::FrameNumber> {
262 size_t operator()(const promeki::FrameNumber &v) const noexcept {
263 return std::hash<int64_t>()(v.value());
264 }
265};
266
267#endif // PROMEKI_ENABLE_CORE