1
+ #ifndef ZEPHYR_STRONG_TYPES_HPP_
2
+ #define ZEPHYR_STRONG_TYPES_HPP_
3
+
4
+ #include < chrono>
5
+ #include < concepts>
6
+ #include < cstdint>
7
+ #include < limits>
8
+ #include < ostream>
9
+
10
+ namespace ze {
11
+
12
+ /* *
13
+ * A struct for providing strict typing of thread ids'.
14
+ */
15
+ struct thread_t {
16
+
17
+ /* *
18
+ * @brief This value signifies either no thread or any thread is allowed.
19
+ */
20
+ static constexpr auto ANY_THREAD = std::numeric_limits<std::uint16_t >::max() - 1 ;
21
+
22
+ /* *
23
+ * @brief The logical thread ID
24
+ */
25
+ std::uint16_t m_thread = ANY_THREAD;
26
+
27
+ /* *
28
+ * @brief Gets a thread_t object with its value initialised to ANY_THREAD
29
+ *
30
+ * @return constexpr thread_t
31
+ */
32
+ static constexpr thread_t any_thread () {
33
+ return thread_t {ANY_THREAD};
34
+ }
35
+
36
+ /* *
37
+ * @brief Equality operator is default.
38
+ *
39
+ * @param _first The lhs
40
+ * @param _second The rhs
41
+ * @return true If equal
42
+ * @return false If not equal
43
+ */
44
+ friend constexpr bool operator ==(const thread_t _first, const thread_t _second) = default ;
45
+
46
+ /* *
47
+ * @brief Inequality operator is default.
48
+ *
49
+ * @param _first The lhs.
50
+ * @param _second The rhs.
51
+ * @return true If not equal
52
+ * @return false If equal
53
+ */
54
+ friend constexpr bool operator !=(const thread_t _first, const thread_t _second) = default ;
55
+
56
+ /* *
57
+ * @brief 3-way operator is default for a std::strong_ordering.
58
+ *
59
+ * @param _first The lhs.
60
+ * @param _second The rhs.
61
+ */
62
+ friend constexpr auto operator <=>(const thread_t _first, const thread_t _second) {
63
+ return _first.m_thread <=> _second.m_thread ;
64
+ }
65
+
66
+ /* *
67
+ * @brief 3-way operator with a std::integral for a std::strong_ordering.
68
+ *
69
+ * @param _first The lhs.
70
+ * @param _second The rhs.
71
+ */
72
+ template <std::integral T>
73
+ friend constexpr auto operator <=>(const thread_t _first, const T _number) {
74
+ return _first.m_thread <=> _number;
75
+ }
76
+
77
+ /* *
78
+ * @brief Equality operator with a std::integral.
79
+ *
80
+ * @param _first The lhs
81
+ * @param _second The rhs
82
+ * @return true If equal
83
+ * @return false If not equal
84
+ */
85
+ template <std::integral T>
86
+ friend constexpr bool operator ==(const thread_t _first, const T _second) {
87
+ return _first.m_thread == _second;
88
+ }
89
+
90
+ /* *
91
+ * @brief Inequality operator with a std::integral.
92
+ *
93
+ * @param _first The lhs
94
+ * @param _second The rhs
95
+ * @return true If equal
96
+ * @return false If not equal
97
+ */
98
+ template <std::integral T>
99
+ friend constexpr bool operator !=(const thread_t & _first, const T _second) {
100
+ return _first.m_thread != _second;
101
+ }
102
+ };
103
+
104
+ /* *
105
+ * @brief Namespace for thread_t based operations
106
+ */
107
+ namespace thread {
108
+
109
+ /* *
110
+ * @brief Construct a thread_t based of an id.
111
+ *
112
+ * @param _thread The thread id.
113
+ * @return constexpr auto thread_t{_thread}
114
+ */
115
+ constexpr auto in (std::uint16_t _thread) noexcept {
116
+ return thread_t {_thread};
117
+ }
118
+
119
+ /* *
120
+ * @brief Get a thread_t for any thread.
121
+ *
122
+ * @return constexpr auto thread_t{}
123
+ */
124
+ constexpr auto any () noexcept {
125
+ return thread_t {};
126
+ }
127
+ } // namespace thread
128
+
129
+ /* *
130
+ * @brief Print the value of a thread to a stream.
131
+ *
132
+ * @param _os The out stream.
133
+ * @param _thread The thread to print.
134
+ * @return std::ostream& _os
135
+ */
136
+ inline std::ostream& operator <<(std::ostream& _os, const thread_t _thread) {
137
+ _os << " thread[" << _thread.m_thread << " ]" ;
138
+ return _os;
139
+ }
140
+
141
+ /* *
142
+ * @brief A struct for providing strict typing for timing.
143
+ */
144
+ struct order_t {
145
+
146
+ /* *
147
+ * @brief The amount of time in nanoseconds.
148
+ */
149
+ std::uint64_t m_order = 0 ;
150
+
151
+ /* *
152
+ * @brief 3-way operator for a std::strong_ordering
153
+ */
154
+ constexpr auto operator <=>(const order_t & _other) const {
155
+ return m_order <=> _other.m_order ;
156
+ }
157
+
158
+ /* *
159
+ * @brief 3-way operator with a std::integral for a std::strong_ordering
160
+ */
161
+ template <std::integral Integral>
162
+ constexpr auto operator <=>(const Integral _number) const {
163
+ return m_order <=> _number;
164
+ }
165
+
166
+ /* *
167
+ * @brief Add two order_t's together.
168
+ *
169
+ * @param _lhs The lhs.
170
+ * @param _rhs The rhs.
171
+ * @return constexpr auto order_t{_lhs.order_ + _rhs.order_}
172
+ */
173
+ friend constexpr auto operator +(order_t lhs, order_t rhs) noexcept {
174
+ return order_t {lhs.m_order + rhs.m_order };
175
+ }
176
+
177
+ /* *
178
+ * @brief subtract two order_t's together.
179
+ *
180
+ * @param _lhs The lhs.
181
+ * @param _rhs The rhs.
182
+ * @return constexpr auto order_t{_lhs.order_ - _rhs.order_}
183
+ */
184
+ friend constexpr auto operator -(order_t lhs, order_t rhs) noexcept {
185
+ return order_t {lhs.m_order - rhs.m_order };
186
+ }
187
+ };
188
+
189
+ /* *
190
+ * @brief Namespace for order_t based helper functions.
191
+ */
192
+ namespace order {
193
+
194
+ /* *
195
+ * @brief Get an order_t for _number seconds.
196
+ *
197
+ * @param _number The number of seconds.
198
+ * @return constexpr order_t order_t{_number * 1000000000}
199
+ */
200
+ inline constexpr order_t seconds (std::uint64_t _number) noexcept {
201
+ return order_t {_number * 1000000000 };
202
+ }
203
+
204
+ /* *
205
+ * @brief Get an order_t for _number seconds.
206
+ *
207
+ * @param _number The number of seconds.
208
+ * @return constexpr order_t order_t{_number * 1000000000}
209
+ */
210
+ inline constexpr order_t in_seconds (std::uint64_t _number) noexcept {
211
+ return seconds (_number);
212
+ }
213
+
214
+ /* *
215
+ * @brief Get an order_t for _number milliseconds.
216
+ *
217
+ * @param _number The number of milliseconds.
218
+ * @return constexpr order_t order_t{_number * 1000000}
219
+ */
220
+ inline constexpr order_t milli (std::uint64_t _number) noexcept {
221
+ return order_t {_number * 1000000 };
222
+ }
223
+
224
+ /* *
225
+ * @brief Get an order_t for _number milliseconds.
226
+ *
227
+ * @param _number The number of milliseconds.
228
+ * @return constexpr order_t order_t{_number * 1000000}
229
+ */
230
+ inline constexpr order_t in_milli (std::uint64_t _number) noexcept {
231
+ return milli (_number);
232
+ }
233
+
234
+ /* *
235
+ * @brief Get an order_t that represents now.
236
+ *
237
+ * @return constexpr order_t order_t{};
238
+ */
239
+ inline constexpr order_t now () noexcept {
240
+ return order_t {};
241
+ }
242
+
243
+ } // namespace order
244
+ } // namespace ze
245
+
246
+ #endif // ZEPHYR_STRONG_TYPES_HPP_
0 commit comments