Stroika Library 3.0d23
 
Loading...
Searching...
No Matches
Realtime.h
Go to the documentation of this file.
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. 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 ***Not Cancelation Point*** - and uses noexcept
89 *
90 * \note no longer true, but in Stroika v2.1:
91 * this always started at offset zero for start of app.
92 * this always used steady_clock (now see TimePointSeconds).
93 * it used to return a 'float' type and now returns a chrono::time_point<> type (for better type safety).
94 *
95 * Since Stroika v3.0d5 - defined to be based on RealtimeClock (which is same - steady_clock), and uses double
96 * internally (using DurationSeconds = chrono::duration<double>). And to get it to be zero based,
97 * \code
98 * Time::clock_cast<Time::AppStartZeroedClock<Time::RealtimeClock>> (Time::GetTickCount ());
99 * \endcode
100 */
101 TimePointSeconds GetTickCount () noexcept;
102
103 /**
104 * @See http://stroika-bugs.sophists.com/browse/STK-619 CONSIDER LOSING THIS - AND USE special TYPE and overloading, and handle kInfinity differently - no arithmetic, just no timeout
105 */
106 constexpr DurationSeconds kInfinity = DurationSeconds{numeric_limits<DurationSeconds::rep>::infinity ()};
107
108 /**
109 * If you want to convert tick-count times to be zero based (often helpful for display purposes), you can use:
110 * \code
111 * clock_cast<DisplayedRealtimeClock> (GetTickCount ())
112 * \endcode
113 */
115
116}
117
119
120 /*
121 * Cannot #include Traversal/Range (easily) due to mutual include nightmare. So just forward declare template, and still
122 * define it anyhow (only need to #include enuf for Openness enum).
123 *
124 * Then we can easily construct Ranges of DurationSeconds, and TimePointSeconds (time ranges).
125 */
126 template <typename T>
127 struct Default;
128
129 template <>
130 struct Default<Time::DurationSeconds> {
131 using value_type = Time::DurationSeconds;
132 using SignedDifferenceType = Time::DurationSeconds;
133 using UnsignedDifferenceType = Time::DurationSeconds;
134
135 static constexpr inline Openness kLowerBoundOpenness{Openness::eClosed};
136 static constexpr inline Openness kUpperBoundOpenness{Openness::eClosed};
137
138 static constexpr inline value_type kLowerBound{Time::DurationSeconds::min ()};
139 static constexpr inline value_type kUpperBound{Time::DurationSeconds::max ()};
140
141 static value_type GetNext (value_type i);
142 static value_type GetPrevious (value_type i);
143
144 static constexpr SignedDifferenceType Difference (Common::ArgByValueType<value_type> lhs, Common::ArgByValueType<value_type> rhs);
145 };
146
147 template <>
148 struct Default<Time::TimePointSeconds> {
149 using value_type = Time::TimePointSeconds;
150 using SignedDifferenceType = Time::DurationSeconds;
151 using UnsignedDifferenceType = Time::DurationSeconds;
152
153 static constexpr inline Openness kLowerBoundOpenness{Openness::eClosed};
154 static constexpr inline Openness kUpperBoundOpenness{Openness::eClosed};
155
156 static constexpr inline value_type kLowerBound{value_type{Time::DurationSeconds::min ()}};
157 static constexpr inline value_type kUpperBound{value_type{Time::DurationSeconds::max ()}};
158
159 static value_type GetNext (value_type i);
160 static value_type GetPrevious (value_type i);
161
162 static constexpr SignedDifferenceType Difference (Common::ArgByValueType<value_type> lhs, Common::ArgByValueType<value_type> rhs);
163 };
164
165 template <>
166 struct Default<chrono::time_point<Time::DisplayedRealtimeClock, Time::DurationSeconds>> {
167 using value_type = chrono::time_point<Time::DisplayedRealtimeClock, Time::DurationSeconds>;
168 using SignedDifferenceType = Time::DurationSeconds;
169 using UnsignedDifferenceType = Time::DurationSeconds;
170
171 static constexpr inline Openness kLowerBoundOpenness{Openness::eClosed};
172 static constexpr inline Openness kUpperBoundOpenness{Openness::eClosed};
173
174 static constexpr inline value_type kLowerBound{value_type{Time::DurationSeconds::min ()}};
175 static constexpr inline value_type kUpperBound{value_type{Time::DurationSeconds::max ()}};
176
177 static value_type GetNext (value_type i);
178 static value_type GetPrevious (value_type i);
179
180 static constexpr SignedDifferenceType Difference (Common::ArgByValueType<value_type> lhs, Common::ArgByValueType<value_type> rhs);
181 };
182
183}
184
185/*
186 ********************************************************************************
187 ***************************** Implementation Details ***************************
188 ********************************************************************************
189 */
190#include "Realtime.inl"
191
192#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.