blob: 8aabe05cad50a3e2b5a7be5df1589b644154e9ac [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
Andrey Logvinb95d90b2020-12-09 12:49:39 +000014#ifdef WEBRTC_UNIT_TEST
Sebastian Jansson2afd2812018-08-23 14:44:05 +020015#include <ostream> // no-presubmit-check TODO(webrtc:8982)
Andrey Logvinb95d90b2020-12-09 12:49:39 +000016#endif // WEBRTC_UNIT_TEST
Sebastian Jansson2afd2812018-08-23 14:44:05 +020017
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"
Danil Chapovalovf6e48bf2022-10-31 15:16:50 +010023#include "rtc_base/units/unit_base.h" // IWYU pragma: export
Sebastian Jansson30bd4032018-04-13 13:56:17 +020024
25namespace webrtc {
Sebastian Jansson30bd4032018-04-13 13:56:17 +020026// Timestamp represents the time that has passed since some unspecified epoch.
27// The epoch is assumed to be before any represented timestamps, this means that
28// negative values are not valid. The most notable feature is that the
29// difference of two Timestamps results in a TimeDelta.
Sebastian Jansson72bba622018-11-19 11:17:12 +010030class Timestamp final : public rtc_units_impl::UnitBase<Timestamp> {
Sebastian Jansson30bd4032018-04-13 13:56:17 +020031 public:
Danil Chapovalov8d94dc22020-01-28 17:54:47 +010032 template <typename T>
33 static constexpr Timestamp Seconds(T value) {
34 static_assert(std::is_arithmetic<T>::value, "");
35 return FromFraction(1'000'000, value);
36 }
37 template <typename T>
38 static constexpr Timestamp Millis(T value) {
39 static_assert(std::is_arithmetic<T>::value, "");
40 return FromFraction(1'000, value);
41 }
42 template <typename T>
43 static constexpr Timestamp Micros(T value) {
44 static_assert(std::is_arithmetic<T>::value, "");
45 return FromValue(value);
46 }
47
Sebastian Jansson3b69b192018-05-07 13:51:51 +020048 Timestamp() = delete;
Sebastian Jansson72bba622018-11-19 11:17:12 +010049
Sebastian Jansson942b3602018-05-30 15:47:44 +020050 template <typename T = int64_t>
Sebastian Janssond7fade52020-01-29 10:44:51 +010051 constexpr T seconds() const {
Sebastian Jansson72bba622018-11-19 11:17:12 +010052 return ToFraction<1000000, T>();
Sebastian Jansson942b3602018-05-30 15:47:44 +020053 }
54 template <typename T = int64_t>
Sebastian Janssond7fade52020-01-29 10:44:51 +010055 constexpr T ms() const {
Sebastian Jansson72bba622018-11-19 11:17:12 +010056 return ToFraction<1000, T>();
Sebastian Jansson942b3602018-05-30 15:47:44 +020057 }
Sebastian Jansson72bba622018-11-19 11:17:12 +010058 template <typename T = int64_t>
Sebastian Janssond7fade52020-01-29 10:44:51 +010059 constexpr T us() const {
Sebastian Jansson72bba622018-11-19 11:17:12 +010060 return ToValue<T>();
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020061 }
62
63 constexpr int64_t seconds_or(int64_t fallback_value) const {
Sebastian Jansson72bba622018-11-19 11:17:12 +010064 return ToFractionOr<1000000>(fallback_value);
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020065 }
66 constexpr int64_t ms_or(int64_t fallback_value) const {
Sebastian Jansson72bba622018-11-19 11:17:12 +010067 return ToFractionOr<1000>(fallback_value);
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020068 }
69 constexpr int64_t us_or(int64_t fallback_value) const {
Sebastian Jansson72bba622018-11-19 11:17:12 +010070 return ToValueOr(fallback_value);
Sebastian Jansson942b3602018-05-30 15:47:44 +020071 }
Sebastian Jansson30bd4032018-04-13 13:56:17 +020072
Sebastian Janssond7fade52020-01-29 10:44:51 +010073 constexpr Timestamp operator+(const TimeDelta delta) const {
Sebastian Jansson72bba622018-11-19 11:17:12 +010074 if (IsPlusInfinity() || delta.IsPlusInfinity()) {
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020075 RTC_DCHECK(!IsMinusInfinity());
Sebastian Jansson72bba622018-11-19 11:17:12 +010076 RTC_DCHECK(!delta.IsMinusInfinity());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020077 return PlusInfinity();
Sebastian Jansson72bba622018-11-19 11:17:12 +010078 } else if (IsMinusInfinity() || delta.IsMinusInfinity()) {
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020079 RTC_DCHECK(!IsPlusInfinity());
Sebastian Jansson72bba622018-11-19 11:17:12 +010080 RTC_DCHECK(!delta.IsPlusInfinity());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020081 return MinusInfinity();
82 }
Danil Chapovalov0c626af2020-02-10 11:16:00 +010083 return Timestamp::Micros(us() + delta.us());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020084 }
Sebastian Janssond7fade52020-01-29 10:44:51 +010085 constexpr Timestamp operator-(const TimeDelta delta) const {
Sebastian Jansson72bba622018-11-19 11:17:12 +010086 if (IsPlusInfinity() || delta.IsMinusInfinity()) {
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020087 RTC_DCHECK(!IsMinusInfinity());
Sebastian Jansson72bba622018-11-19 11:17:12 +010088 RTC_DCHECK(!delta.IsPlusInfinity());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020089 return PlusInfinity();
Sebastian Jansson72bba622018-11-19 11:17:12 +010090 } else if (IsMinusInfinity() || delta.IsPlusInfinity()) {
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020091 RTC_DCHECK(!IsPlusInfinity());
Sebastian Jansson72bba622018-11-19 11:17:12 +010092 RTC_DCHECK(!delta.IsMinusInfinity());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020093 return MinusInfinity();
94 }
Danil Chapovalov0c626af2020-02-10 11:16:00 +010095 return Timestamp::Micros(us() - delta.us());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020096 }
Sebastian Janssond7fade52020-01-29 10:44:51 +010097 constexpr TimeDelta operator-(const Timestamp other) const {
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020098 if (IsPlusInfinity() || other.IsMinusInfinity()) {
99 RTC_DCHECK(!IsMinusInfinity());
100 RTC_DCHECK(!other.IsPlusInfinity());
101 return TimeDelta::PlusInfinity();
102 } else if (IsMinusInfinity() || other.IsPlusInfinity()) {
103 RTC_DCHECK(!IsPlusInfinity());
104 RTC_DCHECK(!other.IsMinusInfinity());
105 return TimeDelta::MinusInfinity();
106 }
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100107 return TimeDelta::Micros(us() - other.us());
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200108 }
Sebastian Janssond7fade52020-01-29 10:44:51 +0100109 constexpr Timestamp& operator-=(const TimeDelta delta) {
Sebastian Jansson72bba622018-11-19 11:17:12 +0100110 *this = *this - delta;
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200111 return *this;
112 }
Sebastian Janssond7fade52020-01-29 10:44:51 +0100113 constexpr Timestamp& operator+=(const TimeDelta delta) {
Sebastian Jansson72bba622018-11-19 11:17:12 +0100114 *this = *this + delta;
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200115 return *this;
116 }
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200117
118 private:
Sebastian Jansson72bba622018-11-19 11:17:12 +0100119 friend class rtc_units_impl::UnitBase<Timestamp>;
120 using UnitBase::UnitBase;
121 static constexpr bool one_sided = true;
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200122};
123
Sebastian Jansson72bba622018-11-19 11:17:12 +0100124std::string ToString(Timestamp value);
Sebastian Janssonb1138622019-04-11 16:48:15 +0200125inline std::string ToLogString(Timestamp value) {
126 return ToString(value);
127}
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200128
Andrey Logvinb95d90b2020-12-09 12:49:39 +0000129#ifdef WEBRTC_UNIT_TEST
Sebastian Jansson2afd2812018-08-23 14:44:05 +0200130inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982)
131 std::ostream& stream, // no-presubmit-check TODO(webrtc:8982)
132 Timestamp value) {
133 return stream << ToString(value);
134}
Andrey Logvinb95d90b2020-12-09 12:49:39 +0000135#endif // WEBRTC_UNIT_TEST
Sebastian Jansson2afd2812018-08-23 14:44:05 +0200136
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200137} // namespace webrtc
138
Sebastian Jansson6fae6ec2018-05-08 10:43:18 +0200139#endif // API_UNITS_TIMESTAMP_H_