ThreadSchedule 3.0.0
Modern C++ thread management library
Loading...
Searching...
No Matches
time.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "../expected.hpp"
4
5#include <chrono>
6#include <cmath>
7#include <limits>
8#include <system_error>
9#include <type_traits>
10
12{
13
14template <typename ToDuration, typename Rep, typename Period>
15[[nodiscard]] inline auto
16checked_duration_cast(std::chrono::duration<Rep, Period> value) -> expected<ToDuration, std::error_code>
17{
18 using source_duration = std::chrono::duration<Rep, Period>;
19 using target_rep = typename ToDuration::rep;
20
21 if constexpr (std::is_same_v<source_duration, ToDuration>)
22 return value;
23
24 using floating_duration = std::chrono::duration<long double, typename ToDuration::period>;
25
26 auto const count = floating_duration(value).count();
27 if (!std::isfinite(count))
28 return unexpected(std::make_error_code(std::errc::invalid_argument));
29
30 if constexpr (std::is_integral_v<target_rep>)
31 {
32 auto const minimum = static_cast<long double>((std::numeric_limits<target_rep>::lowest)());
33 auto const upper_bound = static_cast<long double>((std::numeric_limits<target_rep>::max)()) + 1.0L;
34 if (count < minimum || count >= upper_bound)
35 return unexpected(std::make_error_code(std::errc::value_too_large));
36 }
37 else
38 {
39 auto const minimum = static_cast<long double>((std::numeric_limits<target_rep>::lowest)());
40 auto const maximum = static_cast<long double>((std::numeric_limits<target_rep>::max)());
41 if (count < minimum || count > maximum)
42 return unexpected(std::make_error_code(std::errc::value_too_large));
43 }
44
45 return ToDuration(static_cast<target_rep>(count));
46}
47
48template <typename Clock, typename Duration>
49[[nodiscard]] inline auto
50checked_deadline_after(std::chrono::time_point<Clock, Duration> now, Duration delay)
52{
53 if (delay <= Duration::zero())
54 return now;
55
56 auto const current = now.time_since_epoch().count();
57 auto const delta = delay.count();
58 auto const maximum = (std::numeric_limits<typename Duration::rep>::max)();
59 if (current > maximum - delta)
60 return unexpected(std::make_error_code(std::errc::value_too_large));
61 return std::chrono::time_point<Clock, Duration>(Duration(current + delta));
62}
63
64} // namespace threadschedule::detail
Aggregates multiple thread_registry_backend instances into a single queryable view.
auto checked_duration_cast(std::chrono::duration< Rep, Period > value) -> expected< ToDuration, std::error_code >
Definition time.hpp:16
auto checked_deadline_after(std::chrono::time_point< Clock, Duration > now, Duration delay) -> expected< std::chrono::time_point< Clock, Duration >, std::error_code >
Definition time.hpp:50