blob: 75a6ff88efac0f6de981296d022ecc61215fff85 [file] [log] [blame]
Sebastian Jansson30bd4032018-04-13 13:56:17 +02001/*
2 * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Sebastian Jansson6fae6ec2018-05-08 10:43:18 +020011#ifndef API_UNITS_TIMESTAMP_H_
12#define API_UNITS_TIMESTAMP_H_
Sebastian Jansson30bd4032018-04-13 13:56:17 +020013
Sebastian Jansson2afd2812018-08-23 14:44:05 +020014#ifdef UNIT_TEST
15#include <ostream> // no-presubmit-check TODO(webrtc:8982)
16#endif // UNIT_TEST
17
Sebastian Jansson30bd4032018-04-13 13:56:17 +020018#include <string>
Yves Gerey988cc082018-10-23 12:03:01 +020019#include <type_traits>
Sebastian Jansson30bd4032018-04-13 13:56:17 +020020
Sebastian Jansson6fae6ec2018-05-08 10:43:18 +020021#include "api/units/time_delta.h"
Sebastian Jansson30bd4032018-04-13 13:56:17 +020022#include "rtc_base/checks.h"
23
24namespace webrtc {
Sebastian Jansson30bd4032018-04-13 13:56:17 +020025// Timestamp represents the time that has passed since some unspecified epoch.
26// The epoch is assumed to be before any represented timestamps, this means that
27// negative values are not valid. The most notable feature is that the
28// difference of two Timestamps results in a TimeDelta.
Sebastian Jansson72bba622018-11-19 11:17:12 +010029class Timestamp final : public rtc_units_impl::UnitBase<Timestamp> {
Sebastian Jansson30bd4032018-04-13 13:56:17 +020030 public:
Danil Chapovalov8d94dc22020-01-28 17:54:47 +010031 template <typename T>
32 static constexpr Timestamp Seconds(T value) {
33 static_assert(std::is_arithmetic<T>::value, "");
34 return FromFraction(1'000'000, value);
35 }
36 template <typename T>
37 static constexpr Timestamp Millis(T value) {
38 static_assert(std::is_arithmetic<T>::value, "");
39 return FromFraction(1'000, value);
40 }
41 template <typename T>
42 static constexpr Timestamp Micros(T value) {
43 static_assert(std::is_arithmetic<T>::value, "");
44 return FromValue(value);
45 }
46
Sebastian Jansson3b69b192018-05-07 13:51:51 +020047 Timestamp() = delete;
Sebastian Jansson72bba622018-11-19 11:17:12 +010048
Danil Chapovalov8d94dc22020-01-28 17:54:47 +010049 // TODO(danilchap): Migrate all code to the 3 factories above and delete the
50 // 6 factories below.
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020051 template <int64_t seconds>
52 static constexpr Timestamp Seconds() {
Danil Chapovalov7356a562020-01-20 13:02:44 +010053 return FromFraction(1'000'000, seconds);
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020054 }
55 template <int64_t ms>
56 static constexpr Timestamp Millis() {
Danil Chapovalov7356a562020-01-20 13:02:44 +010057 return FromFraction(1000, ms);
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020058 }
59 template <int64_t us>
60 static constexpr Timestamp Micros() {
Danil Chapovalov7356a562020-01-20 13:02:44 +010061 return FromValue(us);
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020062 }
Sebastian Jansson942b3602018-05-30 15:47:44 +020063
Sebastian Jansson72bba622018-11-19 11:17:12 +010064 template <typename T>
Sebastian Janssond7fade52020-01-29 10:44:51 +010065 static constexpr Timestamp seconds(T seconds) {
Sebastian Jansson0c3f4d32018-11-30 10:02:44 +010066 static_assert(std::is_arithmetic<T>::value, "");
Danil Chapovalov7356a562020-01-20 13:02:44 +010067 return FromFraction(1'000'000, seconds);
Sebastian Jansson30bd4032018-04-13 13:56:17 +020068 }
Sebastian Jansson72bba622018-11-19 11:17:12 +010069 template <typename T>
Sebastian Janssond7fade52020-01-29 10:44:51 +010070 static constexpr Timestamp ms(T milliseconds) {
Sebastian Jansson0c3f4d32018-11-30 10:02:44 +010071 static_assert(std::is_arithmetic<T>::value, "");
Danil Chapovalov7356a562020-01-20 13:02:44 +010072 return FromFraction(1000, milliseconds);
Sebastian Jansson942b3602018-05-30 15:47:44 +020073 }
Sebastian Jansson72bba622018-11-19 11:17:12 +010074 template <typename T>
Sebastian Janssond7fade52020-01-29 10:44:51 +010075 static constexpr Timestamp us(T microseconds) {
Sebastian Jansson0c3f4d32018-11-30 10:02:44 +010076 static_assert(std::is_arithmetic<T>::value, "");
Sebastian Jansson72bba622018-11-19 11:17:12 +010077 return FromValue(microseconds);
Sebastian Jansson942b3602018-05-30 15:47:44 +020078 }
79 template <typename T = int64_t>
Sebastian Janssond7fade52020-01-29 10:44:51 +010080 constexpr T seconds() const {
Sebastian Jansson72bba622018-11-19 11:17:12 +010081 return ToFraction<1000000, T>();
Sebastian Jansson942b3602018-05-30 15:47:44 +020082 }
83 template <typename T = int64_t>
Sebastian Janssond7fade52020-01-29 10:44:51 +010084 constexpr T ms() const {
Sebastian Jansson72bba622018-11-19 11:17:12 +010085 return ToFraction<1000, T>();
Sebastian Jansson942b3602018-05-30 15:47:44 +020086 }
Sebastian Jansson72bba622018-11-19 11:17:12 +010087 template <typename T = int64_t>
Sebastian Janssond7fade52020-01-29 10:44:51 +010088 constexpr T us() const {
Sebastian Jansson72bba622018-11-19 11:17:12 +010089 return ToValue<T>();
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020090 }
91
92 constexpr int64_t seconds_or(int64_t fallback_value) const {
Sebastian Jansson72bba622018-11-19 11:17:12 +010093 return ToFractionOr<1000000>(fallback_value);
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020094 }
95 constexpr int64_t ms_or(int64_t fallback_value) const {
Sebastian Jansson72bba622018-11-19 11:17:12 +010096 return ToFractionOr<1000>(fallback_value);
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020097 }
98 constexpr int64_t us_or(int64_t fallback_value) const {
Sebastian Jansson72bba622018-11-19 11:17:12 +010099 return ToValueOr(fallback_value);
Sebastian Jansson942b3602018-05-30 15:47:44 +0200100 }
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200101
Sebastian Janssond7fade52020-01-29 10:44:51 +0100102 constexpr Timestamp operator+(const TimeDelta delta) const {
Sebastian Jansson72bba622018-11-19 11:17:12 +0100103 if (IsPlusInfinity() || delta.IsPlusInfinity()) {
Sebastian Jansson9de4ef42018-09-04 17:32:36 +0200104 RTC_DCHECK(!IsMinusInfinity());
Sebastian Jansson72bba622018-11-19 11:17:12 +0100105 RTC_DCHECK(!delta.IsMinusInfinity());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +0200106 return PlusInfinity();
Sebastian Jansson72bba622018-11-19 11:17:12 +0100107 } else if (IsMinusInfinity() || delta.IsMinusInfinity()) {
Sebastian Jansson9de4ef42018-09-04 17:32:36 +0200108 RTC_DCHECK(!IsPlusInfinity());
Sebastian Jansson72bba622018-11-19 11:17:12 +0100109 RTC_DCHECK(!delta.IsPlusInfinity());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +0200110 return MinusInfinity();
111 }
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100112 return Timestamp::Micros(us() + delta.us());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +0200113 }
Sebastian Janssond7fade52020-01-29 10:44:51 +0100114 constexpr Timestamp operator-(const TimeDelta delta) const {
Sebastian Jansson72bba622018-11-19 11:17:12 +0100115 if (IsPlusInfinity() || delta.IsMinusInfinity()) {
Sebastian Jansson9de4ef42018-09-04 17:32:36 +0200116 RTC_DCHECK(!IsMinusInfinity());
Sebastian Jansson72bba622018-11-19 11:17:12 +0100117 RTC_DCHECK(!delta.IsPlusInfinity());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +0200118 return PlusInfinity();
Sebastian Jansson72bba622018-11-19 11:17:12 +0100119 } else if (IsMinusInfinity() || delta.IsPlusInfinity()) {
Sebastian Jansson9de4ef42018-09-04 17:32:36 +0200120 RTC_DCHECK(!IsPlusInfinity());
Sebastian Jansson72bba622018-11-19 11:17:12 +0100121 RTC_DCHECK(!delta.IsMinusInfinity());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +0200122 return MinusInfinity();
123 }
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100124 return Timestamp::Micros(us() - delta.us());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +0200125 }
Sebastian Janssond7fade52020-01-29 10:44:51 +0100126 constexpr TimeDelta operator-(const Timestamp other) const {
Sebastian Jansson9de4ef42018-09-04 17:32:36 +0200127 if (IsPlusInfinity() || other.IsMinusInfinity()) {
128 RTC_DCHECK(!IsMinusInfinity());
129 RTC_DCHECK(!other.IsPlusInfinity());
130 return TimeDelta::PlusInfinity();
131 } else if (IsMinusInfinity() || other.IsPlusInfinity()) {
132 RTC_DCHECK(!IsPlusInfinity());
133 RTC_DCHECK(!other.IsMinusInfinity());
134 return TimeDelta::MinusInfinity();
135 }
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100136 return TimeDelta::Micros(us() - other.us());
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200137 }
Sebastian Janssond7fade52020-01-29 10:44:51 +0100138 constexpr Timestamp& operator-=(const TimeDelta delta) {
Sebastian Jansson72bba622018-11-19 11:17:12 +0100139 *this = *this - delta;
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200140 return *this;
141 }
Sebastian Janssond7fade52020-01-29 10:44:51 +0100142 constexpr Timestamp& operator+=(const TimeDelta delta) {
Sebastian Jansson72bba622018-11-19 11:17:12 +0100143 *this = *this + delta;
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200144 return *this;
145 }
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200146
147 private:
Sebastian Jansson72bba622018-11-19 11:17:12 +0100148 friend class rtc_units_impl::UnitBase<Timestamp>;
149 using UnitBase::UnitBase;
150 static constexpr bool one_sided = true;
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200151};
152
Sebastian Jansson72bba622018-11-19 11:17:12 +0100153std::string ToString(Timestamp value);
Sebastian Janssonb1138622019-04-11 16:48:15 +0200154inline std::string ToLogString(Timestamp value) {
155 return ToString(value);
156}
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200157
Sebastian Jansson2afd2812018-08-23 14:44:05 +0200158#ifdef UNIT_TEST
159inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982)
160 std::ostream& stream, // no-presubmit-check TODO(webrtc:8982)
161 Timestamp value) {
162 return stream << ToString(value);
163}
164#endif // UNIT_TEST
165
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200166} // namespace webrtc
167
Sebastian Jansson6fae6ec2018-05-08 10:43:18 +0200168#endif // API_UNITS_TIMESTAMP_H_