blob: a6e450f6850f559332c3d56a9ea3ee9402c55d4c [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:
Sebastian Jansson3b69b192018-05-07 13:51:51 +020031 Timestamp() = delete;
Sebastian Jansson72bba622018-11-19 11:17:12 +010032
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020033 template <int64_t seconds>
34 static constexpr Timestamp Seconds() {
Sebastian Jansson72bba622018-11-19 11:17:12 +010035 return FromStaticFraction<seconds, 1000000>();
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020036 }
37 template <int64_t ms>
38 static constexpr Timestamp Millis() {
Sebastian Jansson72bba622018-11-19 11:17:12 +010039 return FromStaticFraction<ms, 1000>();
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020040 }
41 template <int64_t us>
42 static constexpr Timestamp Micros() {
Sebastian Jansson72bba622018-11-19 11:17:12 +010043 return FromStaticValue<us>();
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020044 }
Sebastian Jansson942b3602018-05-30 15:47:44 +020045
Sebastian Jansson72bba622018-11-19 11:17:12 +010046 template <typename T>
Sebastian Jansson942b3602018-05-30 15:47:44 +020047 static Timestamp seconds(T seconds) {
Sebastian Jansson72bba622018-11-19 11:17:12 +010048 return FromFraction<1000000>(seconds);
Sebastian Jansson30bd4032018-04-13 13:56:17 +020049 }
Sebastian Jansson72bba622018-11-19 11:17:12 +010050 template <typename T>
Sebastian Jansson942b3602018-05-30 15:47:44 +020051 static Timestamp ms(T milliseconds) {
Sebastian Jansson72bba622018-11-19 11:17:12 +010052 return FromFraction<1000>(milliseconds);
Sebastian Jansson942b3602018-05-30 15:47:44 +020053 }
Sebastian Jansson72bba622018-11-19 11:17:12 +010054 template <typename T>
Sebastian Jansson942b3602018-05-30 15:47:44 +020055 static Timestamp us(T microseconds) {
Sebastian Jansson72bba622018-11-19 11:17:12 +010056 return FromValue(microseconds);
Sebastian Jansson942b3602018-05-30 15:47:44 +020057 }
58 template <typename T = int64_t>
Sebastian Jansson72bba622018-11-19 11:17:12 +010059 T seconds() const {
60 return ToFraction<1000000, T>();
Sebastian Jansson942b3602018-05-30 15:47:44 +020061 }
62 template <typename T = int64_t>
Sebastian Jansson72bba622018-11-19 11:17:12 +010063 T ms() const {
64 return ToFraction<1000, T>();
Sebastian Jansson942b3602018-05-30 15:47:44 +020065 }
Sebastian Jansson72bba622018-11-19 11:17:12 +010066 template <typename T = int64_t>
67 T us() const {
68 return ToValue<T>();
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020069 }
70
71 constexpr int64_t seconds_or(int64_t fallback_value) const {
Sebastian Jansson72bba622018-11-19 11:17:12 +010072 return ToFractionOr<1000000>(fallback_value);
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020073 }
74 constexpr int64_t ms_or(int64_t fallback_value) const {
Sebastian Jansson72bba622018-11-19 11:17:12 +010075 return ToFractionOr<1000>(fallback_value);
Sebastian Janssonc1c8b8e2018-08-07 15:29:04 +020076 }
77 constexpr int64_t us_or(int64_t fallback_value) const {
Sebastian Jansson72bba622018-11-19 11:17:12 +010078 return ToValueOr(fallback_value);
Sebastian Jansson942b3602018-05-30 15:47:44 +020079 }
Sebastian Jansson30bd4032018-04-13 13:56:17 +020080
Sebastian Jansson72bba622018-11-19 11:17:12 +010081 Timestamp operator+(const TimeDelta delta) const {
82 if (IsPlusInfinity() || delta.IsPlusInfinity()) {
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020083 RTC_DCHECK(!IsMinusInfinity());
Sebastian Jansson72bba622018-11-19 11:17:12 +010084 RTC_DCHECK(!delta.IsMinusInfinity());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020085 return PlusInfinity();
Sebastian Jansson72bba622018-11-19 11:17:12 +010086 } else if (IsMinusInfinity() || delta.IsMinusInfinity()) {
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020087 RTC_DCHECK(!IsPlusInfinity());
Sebastian Jansson72bba622018-11-19 11:17:12 +010088 RTC_DCHECK(!delta.IsPlusInfinity());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020089 return MinusInfinity();
90 }
Sebastian Jansson72bba622018-11-19 11:17:12 +010091 return Timestamp::us(us() + delta.us());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020092 }
Sebastian Jansson72bba622018-11-19 11:17:12 +010093 Timestamp operator-(const TimeDelta delta) const {
94 if (IsPlusInfinity() || delta.IsMinusInfinity()) {
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020095 RTC_DCHECK(!IsMinusInfinity());
Sebastian Jansson72bba622018-11-19 11:17:12 +010096 RTC_DCHECK(!delta.IsPlusInfinity());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020097 return PlusInfinity();
Sebastian Jansson72bba622018-11-19 11:17:12 +010098 } else if (IsMinusInfinity() || delta.IsPlusInfinity()) {
Sebastian Jansson9de4ef42018-09-04 17:32:36 +020099 RTC_DCHECK(!IsPlusInfinity());
Sebastian Jansson72bba622018-11-19 11:17:12 +0100100 RTC_DCHECK(!delta.IsMinusInfinity());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +0200101 return MinusInfinity();
102 }
Sebastian Jansson72bba622018-11-19 11:17:12 +0100103 return Timestamp::us(us() - delta.us());
Sebastian Jansson9de4ef42018-09-04 17:32:36 +0200104 }
Sebastian Jansson72bba622018-11-19 11:17:12 +0100105 TimeDelta operator-(const Timestamp other) const {
Sebastian Jansson9de4ef42018-09-04 17:32:36 +0200106 if (IsPlusInfinity() || other.IsMinusInfinity()) {
107 RTC_DCHECK(!IsMinusInfinity());
108 RTC_DCHECK(!other.IsPlusInfinity());
109 return TimeDelta::PlusInfinity();
110 } else if (IsMinusInfinity() || other.IsPlusInfinity()) {
111 RTC_DCHECK(!IsPlusInfinity());
112 RTC_DCHECK(!other.IsMinusInfinity());
113 return TimeDelta::MinusInfinity();
114 }
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200115 return TimeDelta::us(us() - other.us());
116 }
Sebastian Jansson72bba622018-11-19 11:17:12 +0100117 Timestamp& operator-=(const TimeDelta delta) {
118 *this = *this - delta;
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200119 return *this;
120 }
Sebastian Jansson72bba622018-11-19 11:17:12 +0100121 Timestamp& operator+=(const TimeDelta delta) {
122 *this = *this + delta;
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200123 return *this;
124 }
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200125
126 private:
Sebastian Jansson72bba622018-11-19 11:17:12 +0100127 friend class rtc_units_impl::UnitBase<Timestamp>;
128 using UnitBase::UnitBase;
129 static constexpr bool one_sided = true;
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200130};
131
Sebastian Jansson72bba622018-11-19 11:17:12 +0100132std::string ToString(Timestamp value);
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200133
Sebastian Jansson2afd2812018-08-23 14:44:05 +0200134#ifdef UNIT_TEST
135inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982)
136 std::ostream& stream, // no-presubmit-check TODO(webrtc:8982)
137 Timestamp value) {
138 return stream << ToString(value);
139}
140#endif // UNIT_TEST
141
Sebastian Jansson30bd4032018-04-13 13:56:17 +0200142} // namespace webrtc
143
Sebastian Jansson6fae6ec2018-05-08 10:43:18 +0200144#endif // API_UNITS_TIMESTAMP_H_