11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
23PROMEKI_NAMESPACE_BEGIN
82 PROMEKI_DATATYPE(FrameCount, DataTypeFrameCount, 1)
85 Error writeToStream(DataStream &s) const;
87 template <uint32_t V> static Result<FrameCount> readFromStream(DataStream &s);
90 static constexpr int64_t UnknownValue = -1;
92 static constexpr int64_t InfinityValue = -2;
95 static constexpr FrameCount unknown() {
97 c._value = UnknownValue;
101 static constexpr FrameCount infinity() {
103 c._value = InfinityValue;
107 static constexpr FrameCount empty() {
130 static Result<FrameCount> fromString(
const String &str);
133 constexpr FrameCount() =
default;
145 constexpr FrameCount(int64_t v) : _value(v < 0 ? UnknownValue : v) {}
148 constexpr bool isValid()
const {
return _value != UnknownValue; }
151 constexpr bool isUnknown()
const {
return _value == UnknownValue; }
154 constexpr bool isInfinite()
const {
return _value == InfinityValue; }
157 constexpr bool isFinite()
const {
return _value >= 0; }
160 constexpr bool isEmpty()
const {
return _value == 0; }
163 constexpr int64_t value()
const {
return _value; }
172 double toDouble()
const {
173 if (isUnknown())
return std::numeric_limits<double>::quiet_NaN();
174 if (isInfinite())
return std::numeric_limits<double>::infinity();
175 return static_cast<double>(_value);
186 static Result<FrameCount> fromDouble(
double v) {
187 if (std::isnan(v))
return makeResult(FrameCount::unknown());
188 if (std::isinf(v))
return makeResult(FrameCount::infinity());
189 if (v < 0.0)
return makeResult(FrameCount::unknown());
190 return makeResult(FrameCount(
static_cast<int64_t
>(v)));
194 FrameCount &operator+=(int64_t n);
197 FrameCount &operator-=(int64_t n);
200 FrameCount &operator+=(
const FrameCount &other);
203 FrameCount &operator-=(
const FrameCount &other);
206 FrameCount &operator++() {
211 FrameCount operator++(
int) {
212 FrameCount o = *
this;
217 FrameCount &operator--() {
222 FrameCount operator--(
int) {
223 FrameCount o = *
this;
229 constexpr bool operator==(
const FrameCount &other)
const {
return _value == other._value; }
231 constexpr bool operator!=(
const FrameCount &other)
const {
return _value != other._value; }
240 bool operator<(
const FrameCount &other)
const;
242 bool operator>(
const FrameCount &other)
const {
return other < *
this; }
252 bool operator<=(
const FrameCount &other)
const {
253 if (isUnknown() || other.isUnknown())
return false;
254 return !(other < *
this);
257 bool operator>=(
const FrameCount &other)
const {
258 if (isUnknown() || other.isUnknown())
return false;
259 return !(*
this < other);
268 String toString()
const;
271 operator String()
const {
return toString(); }
274 int64_t _value = UnknownValue;
288inline FrameNumber toFrameNumber(
const FrameCount &c) {
289 return c.isFinite() ? FrameNumber(c.value()) : FrameNumber::unknown();
303inline FrameCount toFrameCount(
const FrameNumber &n) {
304 return n.isValid() ? FrameCount(n.value()) : FrameCount::unknown();
308inline FrameCount operator+(FrameCount a,
const FrameCount &b) {
313inline FrameCount operator-(FrameCount a,
const FrameCount &b) {
318inline FrameCount operator+(FrameCount a, int64_t n) {
323inline FrameCount operator-(FrameCount a, int64_t n) {
328inline FrameCount operator+(int64_t n, FrameCount a) {
342inline FrameNumber operator+(FrameNumber a,
const FrameCount &c) {
343 if (a.isUnknown() || c.isUnknown() || c.isInfinite())
return FrameNumber::unknown();
344 return FrameNumber(a.value() + c.value());
348inline FrameNumber operator-(FrameNumber a,
const FrameCount &c) {
349 if (a.isUnknown() || c.isUnknown() || c.isInfinite())
return FrameNumber::unknown();
350 int64_t nv = a.value() - c.value();
351 return nv < 0 ? FrameNumber::unknown() : FrameNumber(nv);
360inline FrameCount operator-(
const FrameNumber &a,
const FrameNumber &b) {
361 if (a.isUnknown() || b.isUnknown())
return FrameCount::unknown();
362 int64_t d = a.value() - b.value();
363 return d < 0 ? FrameCount::unknown() : FrameCount(d);
366inline FrameNumber &FrameNumber::operator+=(
const FrameCount &c) {
370inline FrameNumber &FrameNumber::operator-=(
const FrameCount &c) {
377PROMEKI_FORMAT_VIA_TOSTRING(promeki::FrameCount);
387template <>
struct std::hash<promeki::FrameCount> {
388 size_t operator()(
const promeki::FrameCount &v)
const noexcept {
389 return std::hash<int64_t>()(v.value());