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) {
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 explicit constexpr Time(const uint64_t ps_time) : Time(ps_time, Unit::PS) {}
65
66 constexpr Time() : Time(0) {}
67
68 constexpr Time operator+(const Time& t) const {
69 return Time(picoseconds + t.picoseconds);
70 }
71
72 constexpr Time operator-(const Time& t) const {
73 return Time(picoseconds - t.picoseconds);
74 }
75
76 constexpr Time operator-(const uint64_t t) const {
77 return Time(picoseconds - t);
78 }
79
80 constexpr Time operator*(const Time& t) const {
81 return Time(picoseconds * t.picoseconds);
82 }
83
84 constexpr Time operator*(const uint64_t t) const {
85 return Time(picoseconds * t);
86 }
87
88 constexpr Time operator/(const Time& t) const {
89 return Time(picoseconds / t.picoseconds);
90 }
91
92 constexpr Time operator/(const uint64_t t) const {
93 return Time(picoseconds / t);
94 }
95
96 [[nodiscard]]
97 constexpr Time operator%(const Time& time) const {
98 return Time(picoseconds % time.picoseconds);
99 }
100
101 [[nodiscard]]
102 constexpr Time operator%(const uint64_t time) const {
103 return Time(picoseconds % time);
104 }
105
106 constexpr bool operator==(const Time& t) const {
107 return picoseconds == t.picoseconds;
108 }
109
110 [[nodiscard]] uint64_t to_picoseconds() const { return picoseconds; }
111
112 auto operator<=>(const Time& time) const {
113 return picoseconds <=> time.picoseconds;
114 }
115
116 friend std::ostream& operator<<(std::ostream& out, const Time& e);
117
118 static Time zero;
119 static Time one;
120
121 private:
122 std::uint64_t picoseconds;
123
124 friend struct glz::meta<Time>;
125};
126} // namespace Simo
127
128template <>
129struct std::hash<Simo::Time> {
130 std::size_t operator()(Simo::Time const& t) const noexcept {
131 return std::hash<uint64_t>{}(t.to_picoseconds());
132 }
133};
134
135template <>
136struct glz::meta<Simo::Time::Unit> {
137 using enum Simo::Time::Unit;
138 static constexpr auto value = enumerate(PS, NS, US, MS, S);
139};
140
141namespace glz {
142using Simo::Time;
143
144struct TimeValue {
145 std::uint64_t time;
146 Time::Unit unit;
147};
148
149template <unsigned int Format>
150struct from<Format, Time> {
151 template <auto Opts>
152 static void op(Time& value, is_context auto&& ctx, auto&& it, auto&& end) {
153 TimeValue tmp{};
154 parse<Format>::template op<Opts>(tmp, ctx, it, end);
155
156 if (ctx.error != error_code::none) {
157 return;
158 }
159
160 value = Time{tmp.time, tmp.unit};
161 }
162};
163
164template <unsigned int Format>
165struct to<Format, Time> {
166 template <auto Opts>
167 static void op(const Time& value, is_context auto&& ctx, auto&& b,
168 auto&& ix) noexcept {
169 TimeValue tmp{.time = value.to_picoseconds(), .unit = Time::Unit::PS};
170 serialize<Format>::template op<Opts>(tmp, ctx, b, ix);
171 }
172};
173
174} // namespace glz
175
176template <>
177struct std::formatter<Simo::Time> : std::formatter<std::string> {
178 auto format(Simo::Time t, format_context& ctx) const {
179 return formatter<string>::format(std::format("{} ps", t.to_picoseconds()),
180 ctx);
181 }
182};
183
184#endif // SIMO_TIME_HH
Definition Time.h:40
Definition Time.h:40
General namespace for Simo.
Definition Collection.h:51
Definition Time.h:144