1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef API_UNITS_TIMESTAMP_H_ 12*d9f75844SAndroid Build Coastguard Worker #define API_UNITS_TIMESTAMP_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #ifdef WEBRTC_UNIT_TEST 15*d9f75844SAndroid Build Coastguard Worker #include <ostream> // no-presubmit-check TODO(webrtc:8982) 16*d9f75844SAndroid Build Coastguard Worker #endif // WEBRTC_UNIT_TEST 17*d9f75844SAndroid Build Coastguard Worker 18*d9f75844SAndroid Build Coastguard Worker #include <string> 19*d9f75844SAndroid Build Coastguard Worker #include <type_traits> 20*d9f75844SAndroid Build Coastguard Worker 21*d9f75844SAndroid Build Coastguard Worker #include "api/units/time_delta.h" 22*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h" 23*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/units/unit_base.h" // IWYU pragma: export 24*d9f75844SAndroid Build Coastguard Worker 25*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 26*d9f75844SAndroid Build Coastguard Worker // Timestamp represents the time that has passed since some unspecified epoch. 27*d9f75844SAndroid Build Coastguard Worker // The epoch is assumed to be before any represented timestamps, this means that 28*d9f75844SAndroid Build Coastguard Worker // negative values are not valid. The most notable feature is that the 29*d9f75844SAndroid Build Coastguard Worker // difference of two Timestamps results in a TimeDelta. 30*d9f75844SAndroid Build Coastguard Worker class Timestamp final : public rtc_units_impl::UnitBase<Timestamp> { 31*d9f75844SAndroid Build Coastguard Worker public: 32*d9f75844SAndroid Build Coastguard Worker template <typename T> Seconds(T value)33*d9f75844SAndroid Build Coastguard Worker static constexpr Timestamp Seconds(T value) { 34*d9f75844SAndroid Build Coastguard Worker static_assert(std::is_arithmetic<T>::value, ""); 35*d9f75844SAndroid Build Coastguard Worker return FromFraction(1'000'000, value); 36*d9f75844SAndroid Build Coastguard Worker } 37*d9f75844SAndroid Build Coastguard Worker template <typename T> Millis(T value)38*d9f75844SAndroid Build Coastguard Worker static constexpr Timestamp Millis(T value) { 39*d9f75844SAndroid Build Coastguard Worker static_assert(std::is_arithmetic<T>::value, ""); 40*d9f75844SAndroid Build Coastguard Worker return FromFraction(1'000, value); 41*d9f75844SAndroid Build Coastguard Worker } 42*d9f75844SAndroid Build Coastguard Worker template <typename T> 43*d9f75844SAndroid Build Coastguard Worker static constexpr Timestamp Micros(T value) { 44*d9f75844SAndroid Build Coastguard Worker static_assert(std::is_arithmetic<T>::value, ""); 45*d9f75844SAndroid Build Coastguard Worker return FromValue(value); 46*d9f75844SAndroid Build Coastguard Worker } 47*d9f75844SAndroid Build Coastguard Worker 48*d9f75844SAndroid Build Coastguard Worker Timestamp() = delete; 49*d9f75844SAndroid Build Coastguard Worker 50*d9f75844SAndroid Build Coastguard Worker template <typename T = int64_t> 51*d9f75844SAndroid Build Coastguard Worker constexpr T seconds() const { 52*d9f75844SAndroid Build Coastguard Worker return ToFraction<1000000, T>(); 53*d9f75844SAndroid Build Coastguard Worker } 54*d9f75844SAndroid Build Coastguard Worker template <typename T = int64_t> 55*d9f75844SAndroid Build Coastguard Worker constexpr T ms() const { 56*d9f75844SAndroid Build Coastguard Worker return ToFraction<1000, T>(); 57*d9f75844SAndroid Build Coastguard Worker } 58*d9f75844SAndroid Build Coastguard Worker template <typename T = int64_t> 59*d9f75844SAndroid Build Coastguard Worker constexpr T us() const { 60*d9f75844SAndroid Build Coastguard Worker return ToValue<T>(); 61*d9f75844SAndroid Build Coastguard Worker } 62*d9f75844SAndroid Build Coastguard Worker 63*d9f75844SAndroid Build Coastguard Worker constexpr int64_t seconds_or(int64_t fallback_value) const { 64*d9f75844SAndroid Build Coastguard Worker return ToFractionOr<1000000>(fallback_value); 65*d9f75844SAndroid Build Coastguard Worker } 66*d9f75844SAndroid Build Coastguard Worker constexpr int64_t ms_or(int64_t fallback_value) const { 67*d9f75844SAndroid Build Coastguard Worker return ToFractionOr<1000>(fallback_value); 68*d9f75844SAndroid Build Coastguard Worker } 69*d9f75844SAndroid Build Coastguard Worker constexpr int64_t us_or(int64_t fallback_value) const { 70*d9f75844SAndroid Build Coastguard Worker return ToValueOr(fallback_value); 71*d9f75844SAndroid Build Coastguard Worker } 72*d9f75844SAndroid Build Coastguard Worker 73*d9f75844SAndroid Build Coastguard Worker constexpr Timestamp operator+(const TimeDelta delta) const { 74*d9f75844SAndroid Build Coastguard Worker if (IsPlusInfinity() || delta.IsPlusInfinity()) { 75*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(!IsMinusInfinity()); 76*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(!delta.IsMinusInfinity()); 77*d9f75844SAndroid Build Coastguard Worker return PlusInfinity(); 78*d9f75844SAndroid Build Coastguard Worker } else if (IsMinusInfinity() || delta.IsMinusInfinity()) { 79*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(!IsPlusInfinity()); 80*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(!delta.IsPlusInfinity()); 81*d9f75844SAndroid Build Coastguard Worker return MinusInfinity(); 82*d9f75844SAndroid Build Coastguard Worker } 83*d9f75844SAndroid Build Coastguard Worker return Timestamp::Micros(us() + delta.us()); 84*d9f75844SAndroid Build Coastguard Worker } 85*d9f75844SAndroid Build Coastguard Worker constexpr Timestamp operator-(const TimeDelta delta) const { 86*d9f75844SAndroid Build Coastguard Worker if (IsPlusInfinity() || delta.IsMinusInfinity()) { 87*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(!IsMinusInfinity()); 88*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(!delta.IsPlusInfinity()); 89*d9f75844SAndroid Build Coastguard Worker return PlusInfinity(); 90*d9f75844SAndroid Build Coastguard Worker } else if (IsMinusInfinity() || delta.IsPlusInfinity()) { 91*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(!IsPlusInfinity()); 92*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(!delta.IsMinusInfinity()); 93*d9f75844SAndroid Build Coastguard Worker return MinusInfinity(); 94*d9f75844SAndroid Build Coastguard Worker } 95*d9f75844SAndroid Build Coastguard Worker return Timestamp::Micros(us() - delta.us()); 96*d9f75844SAndroid Build Coastguard Worker } 97*d9f75844SAndroid Build Coastguard Worker constexpr TimeDelta operator-(const Timestamp other) const { 98*d9f75844SAndroid Build Coastguard Worker if (IsPlusInfinity() || other.IsMinusInfinity()) { 99*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(!IsMinusInfinity()); 100*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(!other.IsPlusInfinity()); 101*d9f75844SAndroid Build Coastguard Worker return TimeDelta::PlusInfinity(); 102*d9f75844SAndroid Build Coastguard Worker } else if (IsMinusInfinity() || other.IsPlusInfinity()) { 103*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(!IsPlusInfinity()); 104*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(!other.IsMinusInfinity()); 105*d9f75844SAndroid Build Coastguard Worker return TimeDelta::MinusInfinity(); 106*d9f75844SAndroid Build Coastguard Worker } 107*d9f75844SAndroid Build Coastguard Worker return TimeDelta::Micros(us() - other.us()); 108*d9f75844SAndroid Build Coastguard Worker } 109*d9f75844SAndroid Build Coastguard Worker constexpr Timestamp& operator-=(const TimeDelta delta) { 110*d9f75844SAndroid Build Coastguard Worker *this = *this - delta; 111*d9f75844SAndroid Build Coastguard Worker return *this; 112*d9f75844SAndroid Build Coastguard Worker } 113*d9f75844SAndroid Build Coastguard Worker constexpr Timestamp& operator+=(const TimeDelta delta) { 114*d9f75844SAndroid Build Coastguard Worker *this = *this + delta; 115*d9f75844SAndroid Build Coastguard Worker return *this; 116*d9f75844SAndroid Build Coastguard Worker } 117*d9f75844SAndroid Build Coastguard Worker 118*d9f75844SAndroid Build Coastguard Worker private: 119*d9f75844SAndroid Build Coastguard Worker friend class rtc_units_impl::UnitBase<Timestamp>; 120*d9f75844SAndroid Build Coastguard Worker using UnitBase::UnitBase; 121*d9f75844SAndroid Build Coastguard Worker static constexpr bool one_sided = true; 122*d9f75844SAndroid Build Coastguard Worker }; 123*d9f75844SAndroid Build Coastguard Worker 124*d9f75844SAndroid Build Coastguard Worker std::string ToString(Timestamp value); 125*d9f75844SAndroid Build Coastguard Worker inline std::string ToLogString(Timestamp value) { 126*d9f75844SAndroid Build Coastguard Worker return ToString(value); 127*d9f75844SAndroid Build Coastguard Worker } 128*d9f75844SAndroid Build Coastguard Worker 129*d9f75844SAndroid Build Coastguard Worker #ifdef WEBRTC_UNIT_TEST 130*d9f75844SAndroid Build Coastguard Worker inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982) 131*d9f75844SAndroid Build Coastguard Worker std::ostream& stream, // no-presubmit-check TODO(webrtc:8982) 132*d9f75844SAndroid Build Coastguard Worker Timestamp value) { 133*d9f75844SAndroid Build Coastguard Worker return stream << ToString(value); 134*d9f75844SAndroid Build Coastguard Worker } 135*d9f75844SAndroid Build Coastguard Worker #endif // WEBRTC_UNIT_TEST 136*d9f75844SAndroid Build Coastguard Worker 137*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 138*d9f75844SAndroid Build Coastguard Worker 139*d9f75844SAndroid Build Coastguard Worker #endif // API_UNITS_TIMESTAMP_H_ 140