Simo 0.0.1
Loading...
Searching...
No Matches
Time.h
1// Copyright 2026 Matteo Fusi and Contributors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef SIMO_TIME_HH
16#define SIMO_TIME_HH
17
18#include <cmath>
19#include <cstdint>
20#include <functional>
21#include <glaze/core/common.hpp>
22#include <glaze/core/context.hpp>
23#include <glaze/core/custom.hpp>
24#include <glaze/json/generic.hpp>
25#include <limits>
26#include <ostream>
27#include <string>
28#include <string_view>
29#include <type_traits>
30
31#include "../compiler/Compiler.h"
32#include "glaze/api/impl.hpp"
33
34namespace Simo {
40class SIMO_PUBLIC Time final {
41 public:
42 enum struct Unit : std::uint8_t { PS, NS, US, MS, S };
43
44 explicit constexpr Time(const uint64_t time, const Unit unit = Unit::PS) {
45 switch (unit) {
46 case Unit::PS:
47 picoseconds = time;
48 return;
49 case Unit::NS:
50 picoseconds = time * 1'000;
51 return;
52 case Unit::US:
53 picoseconds = time * 1'000'000;
54 return;
55 case Unit::MS:
56 picoseconds = time * 1'000'000'000;
57 return;
58 case Unit::S:
59 picoseconds = time * 1'000'000'000'000;
60 return;
61 }
62 }
63
64 constexpr Time() : Time(0) {}
65
66 constexpr Time operator+(const Time& t) const {
67 return Time(picoseconds + t.picoseconds);
68 }
69
70 constexpr Time operator-(const Time& t) const {
71 return Time(picoseconds - t.picoseconds);
72 }
73
74 constexpr Time operator-(const uint64_t t) const {
75 return Time(picoseconds - t);
76 }
77
78 constexpr Time operator*(const Time& t) const {
79 return Time(picoseconds * t.picoseconds);
80 }
81
82 constexpr Time operator*(const uint64_t t) const {
83 return Time(picoseconds * t);
84 }
85
86 constexpr Time operator/(const Time& t) const {
87 return Time(picoseconds / t.picoseconds);
88 }
89
90 constexpr Time operator/(const uint64_t t) const {
91 return Time(picoseconds / t);
92 }
93
94 [[nodiscard]]
95 constexpr Time operator%(const Time& time) const {
96 return Time(picoseconds % time.picoseconds);
97 }
98
99 [[nodiscard]]
100 constexpr Time operator%(const uint64_t time) const {
101 return Time(picoseconds % time);
102 }
103
104 constexpr bool operator==(const Time& t) const {
105 return picoseconds == t.picoseconds;
106 }
107
108 [[nodiscard]] uint64_t to_picoseconds() const { return picoseconds; }
109
110 auto operator<=>(const Time& time) const {
111 return picoseconds <=> time.picoseconds;
112 }
113
114 friend std::ostream& operator<<(std::ostream& out, const Time& e);
115
116 static Time zero;
117 static Time one;
118
119 private:
120 std::uint64_t picoseconds;
121
122 friend struct glz::meta<Time>;
123};
124} // namespace Simo
125
126template <>
127struct std::hash<Simo::Time> {
128 std::size_t operator()(Simo::Time const& t) const noexcept {
129 return std::hash<uint64_t>{}(t.to_picoseconds());
130 }
131};
132
133template <>
134struct glz::meta<Simo::Time::Unit> {
135 using enum Simo::Time::Unit;
136 static constexpr auto value = enumerate(PS, NS, US, MS, S);
137};
138
139namespace glz {
140using Simo::Time;
141
142struct TimeValue {
143 std::uint64_t time;
144 Time::Unit unit;
145};
146
147template <auto Format>
148struct from<Format, Time> {
149 template <auto Opts>
150 static void op(Time& value, is_context auto&& ctx, auto&& it, auto&& end) {
151 TimeValue tmp{};
152 parse<Format>::template op<Opts>(tmp, ctx, it, end);
153
154 if (ctx.error != error_code::none) {
155 return;
156 }
157
158 value = Time{tmp.time, tmp.unit};
159 }
160};
161
162template <auto Format>
163struct to<Format, Time> {
164 template <auto Opts>
165 static void op(const Time& value, is_context auto&& ctx, auto&& b,
166 auto&& ix) noexcept {
167 TimeValue tmp{.time = value.to_picoseconds(), .unit = Time::Unit::PS};
168 serialize<Format>::template op<Opts>(tmp, ctx, b, ix);
169 }
170};
171
172} // namespace glz
173
174#endif // SIMO_TIME_HH
Definition Time.h:40
Definition Time.h:40
Definition Time.h:142