Line data Source code
1 : #pragma once
2 :
3 : #include <jage/engine/time/durations.hpp>
4 :
5 : #include <jage/engine/time/internal/concepts/real_number_duration.hpp>
6 :
7 : #include <concepts>
8 : #include <cstdint>
9 : #include <limits>
10 : #include <stdexcept>
11 :
12 : namespace jage::engine::time {
13 : class hertz {
14 : using value_type_ = std::uint16_t;
15 : value_type_ cycles_;
16 : template <internal::concepts::real_number_duration TTimeDuration>
17 15 : constexpr auto to_duration() const -> TTimeDuration {
18 15 : constexpr auto period_duration =
19 : static_cast<double>(TTimeDuration::period::den);
20 15 : return TTimeDuration{period_duration / cycles_};
21 : }
22 :
23 : public:
24 : using value_type = value_type_;
25 :
26 : template <std::integral T>
27 17 : explicit constexpr hertz(const T cycles)
28 17 : : cycles_{static_cast<value_type>(cycles)} {
29 17 : if (0 >= cycles) {
30 1 : throw std::invalid_argument("Refusing to construct hertz with cycles "
31 : "less than or equal to zero.");
32 : }
33 16 : if (std::numeric_limits<hertz::value_type>::max() < cycles) [[unlikely]] {
34 1 : throw std::invalid_argument("Refusing to construct hertz with cycles "
35 : "that would overflow value type");
36 : }
37 15 : }
38 :
39 : template <internal::concepts::real_number_duration TTimeDuration>
40 15 : constexpr explicit operator TTimeDuration() const {
41 15 : return to_duration<TTimeDuration>();
42 : }
43 : };
44 :
45 17 : constexpr auto operator""_Hz(unsigned long long value) -> hertz {
46 17 : if (std::numeric_limits<hertz::value_type>::max() < value) [[unlikely]] {
47 : throw std::invalid_argument("Refusing to construct hertz with cycles "
48 1 : "that would overflow value type");
49 : }
50 16 : return hertz(static_cast<hertz::value_type>(value));
51 : }
52 : } // namespace jage::engine::time
|