Files
pip/libs/main/core/pisystemtime.h

254 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*! \file pisystemtime.h
* \ingroup Core
* \~\brief
* \~english System time structs and methods
* \~russian Типы и методы системного времени
*/
/*
PIP - Platform Independent Primitives
Time structs
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PISYSTEMTIME_H
#define PISYSTEMTIME_H
#include "pistring.h"
//! \ingroup Core
//! \~\brief
//! \~english System time with nanosecond precision.
//! \~russian Системное время с точностью до наносекунд.
class PIP_EXPORT PISystemTime {
public:
//! \~english Contructs time with seconds and nanoseconds = 0
//! \~russian Создает время с секундами и наносекундами = 0
PISystemTime() {seconds = nanoseconds = 0;}
//! \~english Contructs time with "s" seconds and "ns" nanoseconds
//! \~russian Создает время с секундами "s" и наносекундами "ns"
PISystemTime(int s, int ns) {seconds = s; nanoseconds = ns; checkOverflows();}
//! \~english Returns time value in seconds
//! \~russian Возвращает значение времени в секундах
double toSeconds() const {return double(seconds) + nanoseconds / 1.e+9;}
//! \~english Returns time value in milliseconds
//! \~russian Возвращает значение времени в миллисекундах
double toMilliseconds() const {return seconds * 1.e+3 + nanoseconds / 1.e+6;}
//! \~english Returns time value in microseconds
//! \~russian Возвращает значение времени в микросекундах
double toMicroseconds() const {return seconds * 1.e+6 + nanoseconds / 1.e+3;}
//! \~english Returns time value in nanoseconds
//! \~russian Возвращает значение времени в наносекундах
double toNanoseconds() const {return seconds * 1.e+9 + double(nanoseconds);}
//! \~english Add to time "v" seconds
//! \~russian Добавляет ко времени "v" секунд
PISystemTime & addSeconds(double v) {*this += fromSeconds(v); return *this;}
//! \~english Add to time "v" milliseconds
//! \~russian Добавляет ко времени "v" миллисекунд
PISystemTime & addMilliseconds(double v) {*this += fromMilliseconds(v); return *this;}
//! \~english Add to time "v" microseconds
//! \~russian Добавляет ко времени "v" микросекунд
PISystemTime & addMicroseconds(double v) {*this += fromMicroseconds(v); return *this;}
//! \~english Add to time "v" nanoseconds
//! \~russian Добавляет ко времени "v" наносекунд
PISystemTime & addNanoseconds(double v) {*this += fromNanoseconds(v); return *this;}
//! \~english Sleep for this time
//! \~russian Ожидать это время
void sleep();
//! \~english On *nix system assign current value to timespec struct
//! \~russian На *nix системах присваивает время к timespec структуре
void toTimespec(void * ts);
//! \~english Returns copy of this time with absolutely values of s and ns
//! \~russian Возвращает копию времени с модулем значения
PISystemTime abs() const;
//! \~english Returns sum of this time with "t"
//! \~russian Возвращает сумму этого времени с "t"
PISystemTime operator +(const PISystemTime & t) const {PISystemTime tt(*this); tt.seconds += t.seconds; tt.nanoseconds += t.nanoseconds; tt.checkOverflows(); return tt;}
//! \~english Returns difference between this time and "t"
//! \~russian Возвращает разницу между этим временем и "t"
PISystemTime operator -(const PISystemTime & t) const {PISystemTime tt(*this); tt.seconds -= t.seconds; tt.nanoseconds -= t.nanoseconds; tt.checkOverflows(); return tt;}
//! \~english Returns multiplication between this time and "t"
//! \~russian Возвращает это временя умноженное на "t"
PISystemTime operator *(const double & v) const {return fromMilliseconds(toMilliseconds() * v);}
//! \~english Returns division between this time and "t"
//! \~russian Возвращает это временя поделённое на "t"
PISystemTime operator /(const double & v) const {return fromMilliseconds(toMilliseconds() / v);}
//! \~english Add to time "t"
//! \~russian Добавляет ко времени "t"
PISystemTime & operator +=(const PISystemTime & t) {seconds += t.seconds; nanoseconds += t.nanoseconds; checkOverflows(); return *this;}
//! \~english Subtract from time "t"
//! \~russian Вычитает из времени "t"
PISystemTime & operator -=(const PISystemTime & t) {seconds -= t.seconds; nanoseconds -= t.nanoseconds; checkOverflows(); return *this;}
//! \~english Multiply time by "v"
//! \~russian Умножает время на "v"
PISystemTime & operator *=(const double & v) {*this = fromMilliseconds(toMilliseconds() * v); return *this;}
//! \~english Divide time by "v"
//! \~russian Делит время на "v"
PISystemTime & operator /=(const double & v) {*this = fromMilliseconds(toMilliseconds() / v); return *this;}
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator ==(const PISystemTime & t) const {return ((seconds == t.seconds) && (nanoseconds == t.nanoseconds));}
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator !=(const PISystemTime & t) const {return ((seconds != t.seconds) || (nanoseconds != t.nanoseconds));}
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator >(const PISystemTime & t) const {if (seconds == t.seconds) return nanoseconds > t.nanoseconds; return seconds > t.seconds;}
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator <(const PISystemTime & t) const {if (seconds == t.seconds) return nanoseconds < t.nanoseconds; return seconds < t.seconds;}
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator >=(const PISystemTime & t) const {if (seconds == t.seconds) return nanoseconds >= t.nanoseconds; return seconds >= t.seconds;}
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator <=(const PISystemTime & t) const {if (seconds == t.seconds) return nanoseconds <= t.nanoseconds; return seconds <= t.seconds;}
//! \~english Contructs time from seconds "v"
//! \~russian Создает время из "v" секунд
static PISystemTime fromSeconds(double v) {int s = piFloord(v); return PISystemTime(s, int((v - s) * 1000000000.));}
//! \~english Contructs time from milliseconds "v"
//! \~russian Создает время из "v" миллисекунд
static PISystemTime fromMilliseconds(double v) {int s = piFloord(v / 1000.); return PISystemTime(s, int((v / 1000. - s) * 1000000000.));}
//! \~english Contructs time from microseconds "v"
//! \~russian Создает время из "v" микросекунд
static PISystemTime fromMicroseconds(double v) {int s = piFloord(v / 1000000.); return PISystemTime(s, int((v / 1000000. - s) * 1000000000.));}
//! \~english Contructs time from nanoseconds "v"
//! \~russian Создает время из "v" наносекунд
static PISystemTime fromNanoseconds(double v) {int s = piFloord(v / 1000000000.); return PISystemTime(s, int((v / 1000000000. - s) * 1000000000.));}
//! \~english Returns current system time
//! \~russian Возвращает текущее системное время
static PISystemTime current(bool precise_but_not_system = false);
//! \~english Seconds time part
//! \~russian Секунды времени
int seconds;
//! \~english Nanoseconds time part
//! \~russian Наносекунды времени
int nanoseconds;
private:
void checkOverflows() {while (nanoseconds >= 1000000000) {nanoseconds -= 1000000000; seconds++;} while (nanoseconds < 0) {nanoseconds += 1000000000; seconds--;}}
};
//! \relatesalso PICout
//! \~english \brief Output operator to PICout
//! \~russian \brief Оператор вывода в PICout
inline PICout operator <<(PICout s, const PISystemTime & v) {s.space(); s.saveAndSetControls(0); s << "(" << v.seconds << " s, " << v.nanoseconds << " ns)"; s.restoreControls(); return s;}
//! \ingroup Core
//! \~\brief
//! \~english Time measurements.
//! \~russian Измерение времени.
class PIP_EXPORT PITimeMeasurer {
public:
PITimeMeasurer();
/** \brief Set internal time mark to current system time
* \details This function used for set start time mark. Later
* you can find out elapsed time from this time mark to any
* moment of time with \a elapsed_s(), \a elapsed_m(),
* \a elapsed_u() or \a elapsed_n() functions.
* \sa \a elapsed_s(), \a elapsed_m(), \a elapsed_u(), \a elapsed_n() */
void reset() {t_st = PISystemTime::current(true);}
//! \brief Returns nanoseconds elapsed from last \a reset() execution or from timer measurer creation.
double elapsed_n() const;
//! \brief Returns microseconds elapsed from last \a reset() execution or from timer measurer creation.
double elapsed_u() const;
//! \brief Returns milliseconds elapsed from last \a reset() execution or from timer measurer creation.
double elapsed_m() const;
//! \brief Returns seconds elapsed from last \a reset() execution or from timer measurer creation.
double elapsed_s() const;
//! \brief Returns PISystemTime elapsed from last \a reset() execution or from timer measurer creation.
PISystemTime elapsed() const;
double reset_time_n() const {return t_st.toNanoseconds();}
double reset_time_u() const {return t_st.toMicroseconds();}
double reset_time_m() const {return t_st.toMilliseconds();}
double reset_time_s() const {return t_st.toSeconds();}
//! \brief Returns time mark of last \a reset() execution or timer measurer creation.
PISystemTime reset_time() {return t_st;}
//! \brief Returns nanoseconds representation of current system time.
static double elapsed_system_n() {return PISystemTime::current(true).toNanoseconds();}
//! \brief Returns microseconds representation of current system time.
static double elapsed_system_u() {return PISystemTime::current(true).toMicroseconds();}
//! \brief Returns milliseconds representation of current system time.
static double elapsed_system_m() {return PISystemTime::current(true).toMilliseconds();}
//! \brief Returns seconds representation of current system time.
static double elapsed_system_s() {return PISystemTime::current(true).toSeconds();}
//! \brief Returns time mark of current system time.
static PISystemTime elapsed_system() {return PISystemTime::current(true);}
private:
PISystemTime t_st, t_cur;
};
#endif // PITIME_H