Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Realtime.h
Go to the documentation of this file.
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Time_Realtime_h_
5#define _Stroika_Foundation_Time_Realtime_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
9#include <chrono>
10
14
15/**
16 * \file
17 *
18 * \note Code-Status: <a href="Code-Status.md#Beta">Beta</a>
19 */
20namespace Stroika::Foundation {
21 using namespace std;
22};
23
24namespace Stroika::Foundation::Time {
25
26 using chrono::time_point;
27
28 /**
29 * \brief chrono::duration<double> - a time span (length of time) measured in seconds, but high precision.
30 *
31 * DurationSeconds is just a choice of what chrono::duration template parameters to use to make use much simpler.
32 * Converting to a common sensible base format greatly simplifies a number of Stroika APIs, so rather than having to
33 * template all your 'duration' arguments, just use this DurationSeconds for simplicity, clarity, and at only
34 * a small cost.
35 *
36 * \note this is one of two types which replaces the Stroika v2.1 DurationSecondsType (DurationSeconds and TimePointSeconds)
37 *
38 * \note Because chrono::duration supports automatic conversion from other 'base units' etc, you can maintain your code/data
39 * structures with any chrono::duration<> and seamlessly use Stroika APIs which expect DurationSeconds.
40 *
41 * \note Use double instead of long double (as the rep) because we don't have time to test performance impact, and only some (gcc/unix)
42 * systems make a difference anyhow (not on ppc). Everything else in Stroika should key off this choice, so this is the place to change
43 * the basic rep used throughout Stroika if I need to experiment (float/long double).
44 *
45 * \note DurationSeconds is a 'floating point version of chrono::seconds'
46 *
47 * \note - WHY is it so important Stroika uses a 'floating point' version of duration.
48 * Consider this code:
49 * TimeOutAt t = now + REALLY_BIG_TIMOUT;
50 * say we define REALLY_BIG_TIMEOUT = DURUATION::max();
51 * if we used fixed point numbers, REALLY_BIG_TIMOUT + tiny number wraps - basically back to zero.
52 * with floating point numbers, max + small number remains max.
53 * That's a HUGE, and USEFUL simplification of wildly common code.
54 *
55 * \see See Also Duration - which can be easily interoperate with DurationSeconds - which provides additional functionality.
56 */
57 using DurationSeconds = chrono::duration<double>;
58 static_assert (sizeof (DurationSeconds::rep) == sizeof (DurationSeconds));
59 static_assert (floating_point<DurationSeconds::rep>); // perhaps allow #define control over DurationSeconds, but always promise its a floating point type
60
61 /**
62 * \brief this is an alias for steady_clock; this is the clock used for GetTickCount () results.
63 *
64 * The clock it uses IS guaranteed to be a 'steady' clock, though not necessarily THE 'steady_clock' class.
65 *
66 * \note - could use AppStartZeroedClock to get zero-based results, or clock_cast to map from regular tick-counts to zero based.
67 *
68 * \todo consider a configuration define that could be used to switch RealtimeClock to chrono::high_resolution_clock
69 */
70 using RealtimeClock = chrono::steady_clock;
71 static_assert (RealtimeClock::is_steady);
72
73 /**
74 * \brief TimePointSeconds is a simpler approach to chrono::time_point, which doesn't require using templates everywhere.
75 *
76 * But - TimePointSeconds - since it uses chrono::time_point - is mostly (see Pin2SafeSeconds()) interoperable with the other time_point etc objects.
77 *
78 * \note - CARE is required passing this value to STD C++ APIs!; see and consider using Pin2SafeSeconds() in calling those APIs.
79 *
80 * \see RealtimeClock for details of how time is measured.
81 */
82 using TimePointSeconds = time_point<RealtimeClock, DurationSeconds>;
83 static_assert (sizeof (DurationSeconds::rep) == sizeof (TimePointSeconds));
84
85 /**
86 * \brief get the current (monotonically increasing) time - from RealtimeClock
87 *
88 * \note no longer true, but in Stroika v2.1:
89 * this always started at offset zero for start of app.
90 * this always used steady_clock (now see TimePointSeconds).
91 * it used to return a 'float' type and now returns a chrono::time_point<> type (for better type safety).
92 *
93 * Since Stroika v3.0d5 - defined to be based on RealtimeClock (which is same - steady_clock), and uses double
94 * internally (using DurationSeconds = chrono::duration<double>). And to get it to be zero based,
95 * \code
96 * Time::clock_cast<Time::AppStartZeroedClock<Time::RealtimeClock>> (Time::GetTickCount ());
97 * \endcode
98 */
100
101 /**
102 * @See http://stroika-bugs.sophists.com/browse/STK-619 CONSIDER LOSING THIS - AND USE special TYPE and overloading, and handle kInfinity differently - no arithmatic, just no timeout
103 */
104 constexpr DurationSeconds kInfinity = DurationSeconds{numeric_limits<DurationSeconds::rep>::infinity ()};
105
106 /**
107 * If you want to convert tick-count times to be zero based (often helpful for display purposes), you can use:
108 * \code
109 * clock_cast<DisplayedRealtimeClock> (GetTickCount ())
110 * \endcode
111 */
113
114}
115
117
118 /*
119 * Cannot #include Traversal/Range (easily) due to mutual include nightmare. So just forward declare template, and still
120 * define it anyhow (only need to #include enuf for Openness enum).
121 *
122 * Then we can easily construct Ranges of DurationSeconds, and TimePointSeconds (time ranges).
123 */
124 template <typename T>
125 struct Default;
126
127 template <>
128 struct Default<Time::DurationSeconds> {
129 using value_type = Time::DurationSeconds;
130 using SignedDifferenceType = Time::DurationSeconds;
131 using UnsignedDifferenceType = Time::DurationSeconds;
132
133 static constexpr inline Openness kLowerBoundOpenness{Openness::eClosed};
134 static constexpr inline Openness kUpperBoundOpenness{Openness::eClosed};
135
136 static constexpr inline value_type kLowerBound{Time::DurationSeconds::min ()};
137 static constexpr inline value_type kUpperBound{Time::DurationSeconds::max ()};
138
139 static value_type GetNext (value_type i);
140 static value_type GetPrevious (value_type i);
141
142 static constexpr SignedDifferenceType Difference (Common::ArgByValueType<value_type> lhs, Common::ArgByValueType<value_type> rhs);
143 };
144
145 template <>
146 struct Default<Time::TimePointSeconds> {
147 using value_type = Time::TimePointSeconds;
148 using SignedDifferenceType = Time::DurationSeconds;
149 using UnsignedDifferenceType = Time::DurationSeconds;
150
151 static constexpr inline Openness kLowerBoundOpenness{Openness::eClosed};
152 static constexpr inline Openness kUpperBoundOpenness{Openness::eClosed};
153
154 static constexpr inline value_type kLowerBound{value_type{Time::DurationSeconds::min ()}};
155 static constexpr inline value_type kUpperBound{value_type{Time::DurationSeconds::max ()}};
156
157 static value_type GetNext (value_type i);
158 static value_type GetPrevious (value_type i);
159
160 static constexpr SignedDifferenceType Difference (Common::ArgByValueType<value_type> lhs, Common::ArgByValueType<value_type> rhs);
161 };
162
163 template <>
164 struct Default<chrono::time_point<Time::DisplayedRealtimeClock, Time::DurationSeconds>> {
165 using value_type = chrono::time_point<Time::DisplayedRealtimeClock, Time::DurationSeconds>;
166 using SignedDifferenceType = Time::DurationSeconds;
167 using UnsignedDifferenceType = Time::DurationSeconds;
168
169 static constexpr inline Openness kLowerBoundOpenness{Openness::eClosed};
170 static constexpr inline Openness kUpperBoundOpenness{Openness::eClosed};
171
172 static constexpr inline value_type kLowerBound{value_type{Time::DurationSeconds::min ()}};
173 static constexpr inline value_type kUpperBound{value_type{Time::DurationSeconds::max ()}};
174
175 static value_type GetNext (value_type i);
176 static value_type GetPrevious (value_type i);
177
178 static constexpr SignedDifferenceType Difference (Common::ArgByValueType<value_type> lhs, Common::ArgByValueType<value_type> rhs);
179 };
180
181}
182
183/*
184 ********************************************************************************
185 ***************************** Implementation Details ***************************
186 ********************************************************************************
187 */
188#include "Realtime.inl"
189
190#endif /*_Stroika_Foundation_Time_Realtime_h_*/
time_point< RealtimeClock, DurationSeconds > TimePointSeconds
TimePointSeconds is a simpler approach to chrono::time_point, which doesn't require using templates e...
Definition Realtime.h:82
chrono::steady_clock RealtimeClock
this is an alias for steady_clock; this is the clock used for GetTickCount () results.
Definition Realtime.h:70
chrono::duration< double > DurationSeconds
chrono::duration<double> - a time span (length of time) measured in seconds, but high precision.
Definition Realtime.h:57
TimePointSeconds GetTickCount() noexcept
get the current (monotonically increasing) time - from RealtimeClock
Definition Realtime.inl:16
conditional_t<(sizeof(CHECK_T)<=2 *sizeof(void *)) and is_trivially_copyable_v< CHECK_T >, CHECK_T, const CHECK_T & > ArgByValueType
This is an alias for 'T' - but how we want to pass it on stack as formal parameter.
Definition TypeHints.h:32
STL namespace.