diff options
Diffstat (limited to 'src/timer.hpp')
-rw-r--r-- | src/timer.hpp | 96 |
1 files changed, 77 insertions, 19 deletions
diff --git a/src/timer.hpp b/src/timer.hpp index 45c41459..1350899b 100644 --- a/src/timer.hpp +++ b/src/timer.hpp @@ -8,20 +8,40 @@ struct Ns { explicit constexpr Ns(): stamp{0} {} explicit constexpr Ns(uint64_t x) : stamp{x} {} - static Ns from_millis(uint64_t x); + explicit constexpr operator uint64_t() const { return stamp; } + explicit constexpr operator double() const { return stamp; } + explicit constexpr operator float() const = delete; - explicit operator uint64_t() const; - explicit operator float() const; - uint64_t operator*() const; + static constexpr Ns from_millis(uint64_t a) + { + constexpr auto b = uint64_t(1e6); + const auto x = a * b; + fm_assert(a == 0 || x / a == b); + return Ns{x}; + } + + // ----- - friend Ns operator+(const Ns& lhs, const Ns& rhs); - friend Ns operator-(const Ns& lhs, const Ns& rhs); + friend constexpr Ns operator+(const Ns& lhs, const Ns& rhs) + { + constexpr auto max = (uint64_t)-1; + auto a = lhs.stamp, b = rhs.stamp; + fm_assert(max - a >= b); + return Ns{a + b}; + } + + friend constexpr Ns operator-(const Ns& lhs, const Ns& rhs) + { + auto a = lhs.stamp, b = rhs.stamp; + fm_assert(a >= b); + return Ns{a - b}; + } friend Ns operator*(const Ns&, const Ns&) = delete; template<typename T> requires (std::is_integral_v<T> && std::is_unsigned_v<T>) - friend Ns operator*(const Ns& lhs, T rhs) + friend constexpr Ns operator*(const Ns& lhs, T rhs) { auto a = lhs.stamp, b = uint64_t{rhs}; auto x = a * b; @@ -31,18 +51,18 @@ struct Ns template<typename T> requires (std::is_integral_v<T> && std::is_signed_v<T> && sizeof(T) < sizeof(uint64_t)) - friend Ns operator*(const Ns& lhs, T rhs) + friend constexpr Ns operator*(const Ns& lhs, T rhs) { fm_assert(rhs >= T{0}); return lhs * uint64_t(rhs); } template<typename T> - friend Ns operator*(T lhs, const Ns& rhs) { return rhs * lhs; } + friend constexpr Ns operator*(T lhs, const Ns& rhs) { return rhs * lhs; } template<typename T> requires std::is_same_v<float, T> - friend Ns operator*(const Ns& lhs, T rhs) + friend constexpr Ns operator*(const Ns& lhs, T rhs) { auto a = lhs.stamp; auto x = float(a) * float{rhs}; @@ -52,15 +72,53 @@ struct Ns template<typename T> requires std::is_same_v<float, T> - friend Ns operator*(T lhs, const Ns& rhs) { return rhs * lhs; } + friend constexpr Ns operator*(T lhs, const Ns& rhs) { return rhs * lhs; } + + friend constexpr uint64_t operator/(const Ns& lhs, const Ns& rhs) + { + auto a = lhs.stamp, b = rhs.stamp; + fm_assert(b != 0); + return a / b; + } - friend uint64_t operator/(const Ns& lhs, const Ns& rhs); - friend Ns operator/(const Ns& lhs, uint64_t rhs); - friend uint64_t operator%(const Ns& lhs, const Ns& rhs); - friend Ns operator%(const Ns& lhs, uint64_t rhs); + friend constexpr Ns operator/(const Ns& lhs, uint64_t b) + { + auto a = lhs.stamp; + fm_assert(b != 0); + return Ns{a / b}; + } + + friend constexpr uint64_t operator%(const Ns& lhs, const Ns& rhs) + { + auto a = lhs.stamp, b = rhs.stamp; + fm_assert(b != 0); + return a % b; + } + + friend constexpr Ns operator%(const Ns& lhs, uint64_t b) + { + auto a = lhs.stamp; + fm_assert(b != 0); + return Ns{a % b}; + } + + friend constexpr Ns& operator+=(Ns& lhs, const Ns& rhs) + { + constexpr auto max = (uint64_t)-1; + auto b = rhs.stamp; + fm_assert(max - lhs.stamp >= b); + lhs.stamp += b; + return lhs; + } + + friend constexpr bool operator==(const Ns& lhs, const Ns& rhs) = default; + + friend constexpr std::strong_ordering operator<=>(const Ns& lhs, const Ns& rhs) + { + auto a = lhs.stamp, b = rhs.stamp; + return a <=> b; + } - friend bool operator==(const Ns& lhs, const Ns& rhs); - friend std::strong_ordering operator<=>(const Ns& lhs, const Ns& rhs); friend Debug& operator<<(Debug& dbg, const Ns& box); uint64_t stamp; @@ -76,8 +134,8 @@ struct Time final friend Ns operator-(const Time& lhs, const Time& rhs) noexcept; [[nodiscard]] Ns update(const Time& ts = now()) & noexcept; - static float to_seconds(const Ns& ts) noexcept; - static float to_milliseconds(const Ns& ts) noexcept; + static double to_seconds(const Ns& ts) noexcept; + static double to_milliseconds(const Ns& ts) noexcept; uint64_t stamp = init(); |