File indexing completed on 2026-04-09 07:49:52
0001 #pragma once
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #include <cassert>
0036 #include <chrono>
0037 #include <thread>
0038 #include <cstring>
0039 #include <ctime>
0040 #include <iostream>
0041 #include <string>
0042 #include <cstdint>
0043 #include <sstream>
0044
0045 struct stimer
0046 {
0047 typedef std::chrono::time_point<std::chrono::system_clock> TP ;
0048 typedef std::chrono::duration<double> DT ;
0049 enum { UNSET, STARTED, STOPPED } ;
0050
0051 static constexpr const char* UNSET_ = "UNSET " ;
0052 static constexpr const char* STARTED_ = "STARTED" ;
0053 static constexpr const char* STOPPED_ = "STOPPED" ;
0054 static constexpr const char* ERROR_ = "ERROR " ;
0055 static constexpr const char* FORMAT_ZERO_ = "FORMAT_ZERO " ;
0056 static const char* Status(int st) ;
0057 static uint64_t EpochCountAsis(const std::chrono::time_point<std::chrono::system_clock>& t0 );
0058 static uint64_t EpochCount(const std::chrono::time_point<std::chrono::system_clock>& t0 );
0059 static uint64_t EpochCountNow() ;
0060 static std::chrono::time_point<std::chrono::system_clock> TimePoint( uint64_t epoch_count );
0061 static std::time_t ApproxTime(const std::chrono::time_point<std::chrono::system_clock>& t0 );
0062
0063 static const char* Format(uint64_t epoch_count );
0064 static const char* Format(const std::chrono::time_point<std::chrono::system_clock>& t0 );
0065 static const char* Format(std::time_t tt );
0066
0067 std::string desc() const ;
0068
0069 TP _start ;
0070 TP _stop ;
0071 int status = UNSET ;
0072
0073 uint64_t start_count() const ;
0074 uint64_t stop_count() const ;
0075
0076
0077
0078 static stimer* create() ;
0079 double done();
0080 double lap();
0081
0082
0083 bool is_ready() const ;
0084 bool is_started() const ;
0085 bool is_stopped() const ;
0086
0087 void start();
0088 void stop();
0089 double duration() const ;
0090
0091
0092 static void sleep(int seconds) ;
0093 };
0094
0095
0096 inline const char* stimer::Status(int st)
0097 {
0098 const char* str = nullptr ;
0099 switch(st)
0100 {
0101 case UNSET: str = UNSET_ ; break ;
0102 case STARTED: str = STARTED_ ; break ;
0103 case STOPPED: str = STOPPED_ ; break ;
0104 default: str = ERROR_ ; break ;
0105 }
0106 return str ;
0107 }
0108
0109 inline uint64_t stimer::EpochCountAsis(const std::chrono::time_point<std::chrono::system_clock>& t0 )
0110 {
0111 return t0.time_since_epoch().count();
0112 }
0113 inline uint64_t stimer::EpochCount(const std::chrono::time_point<std::chrono::system_clock>& t0 )
0114 {
0115 return std::chrono::duration_cast<std::chrono::microseconds>(t0.time_since_epoch()).count() ;
0116 }
0117 inline uint64_t stimer::EpochCountNow()
0118 {
0119 std::chrono::time_point<std::chrono::system_clock> t0 = std::chrono::system_clock::now();
0120 return EpochCount(t0);
0121 }
0122
0123 inline std::chrono::time_point<std::chrono::system_clock> stimer::TimePoint( uint64_t epoch_count_microseconds )
0124 {
0125
0126
0127
0128
0129
0130 std::chrono::system_clock::time_point tp{std::chrono::microseconds{epoch_count_microseconds}};
0131 return tp ;
0132 }
0133
0134
0135 inline std::time_t stimer::ApproxTime(const std::chrono::time_point<std::chrono::system_clock>& t0 )
0136 {
0137
0138
0139
0140
0141 std::time_t tt = std::chrono::system_clock::to_time_t( t0 );
0142 return tt ;
0143 }
0144 inline const char* stimer::Format(uint64_t epoch_count )
0145 {
0146 std::chrono::time_point<std::chrono::system_clock> tp = TimePoint(epoch_count);
0147 return Format(tp) ;
0148 }
0149 inline const char* stimer::Format(const std::chrono::time_point<std::chrono::system_clock>& t0 )
0150 {
0151 return EpochCount(t0) == 0 ? FORMAT_ZERO_ : Format(ApproxTime(t0)) ;
0152 }
0153
0154 inline const char* stimer::Format( std::time_t tt )
0155 {
0156 std::tm* tm = std::localtime(&tt);
0157 char buffer[32];
0158
0159 std::strftime(buffer, 32, "%a, %d.%m.%Y %H:%M:%S", tm);
0160 return strdup(buffer) ;
0161 }
0162 inline std::string stimer::desc() const
0163 {
0164 std::stringstream ss ;
0165 ss << "stimer::desc"
0166 << " status " << Status(status)
0167 << " _start " << EpochCount(_start)
0168 << " start " << Format(_start)
0169 << " _stop " << EpochCount(_stop)
0170 << " stop " << Format(_stop)
0171 << " duration " << std::scientific << duration()
0172 ;
0173 std::string str = ss.str();
0174 return str ;
0175 }
0176
0177 inline uint64_t stimer::start_count() const { return EpochCount(_start) ; }
0178 inline uint64_t stimer::stop_count() const { return EpochCount(_stop) ; }
0179
0180
0181 inline stimer* stimer::create()
0182 {
0183 stimer* t = new stimer ;
0184 t->start();
0185 return t ;
0186 }
0187 inline double stimer::done()
0188 {
0189 stop();
0190 return duration();
0191 }
0192 inline double stimer::lap()
0193 {
0194 stop();
0195 double dt = duration();
0196 start();
0197 return dt ;
0198 }
0199
0200
0201 inline bool stimer::is_ready() const { return status == UNSET || status == STOPPED ; }
0202 inline bool stimer::is_started() const { return status == STARTED ; }
0203 inline bool stimer::is_stopped() const { return status == STOPPED ; }
0204
0205 inline void stimer::start()
0206 {
0207 if(!is_ready()) std::cerr << "stimer::start called when STARTED already ? " << desc() << std::endl ;
0208 status = STARTED ;
0209 _start = std::chrono::system_clock::now();
0210 }
0211 inline void stimer::stop()
0212 {
0213 if(!is_started()) std::cerr << "stimer::stop called when not STARTED ? " << desc() << std::endl ;
0214 status = STOPPED ;
0215 _stop = std::chrono::system_clock::now();
0216 }
0217 inline double stimer::duration() const
0218 {
0219 if(!is_stopped()) return -1. ;
0220 DT _dt = _stop - _start ;
0221 return _dt.count();
0222 }
0223
0224
0225
0226 inline void stimer::sleep(int seconds)
0227 {
0228 std::chrono::seconds dura(seconds);
0229 std::this_thread::sleep_for( dura );
0230 }
0231
0232
0233
0234
0235
0236
0237
0238