1 /* 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 11 #ifndef API_UNITS_TIMESTAMP_H_ 12 #define API_UNITS_TIMESTAMP_H_ 13 14 #ifdef WEBRTC_UNIT_TEST 15 #include <ostream> // no-presubmit-check TODO(webrtc:8982) 16 #endif // WEBRTC_UNIT_TEST 17 18 #include <string> 19 #include <type_traits> 20 21 #include "api/units/time_delta.h" 22 #include "rtc_base/checks.h" 23 #include "rtc_base/units/unit_base.h" // IWYU pragma: export 24 25 namespace webrtc { 26 // 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. 30 class Timestamp final : public rtc_units_impl::UnitBase<Timestamp> { 31 public: 32 template <typename T> Seconds(T value)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> Millis(T value)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 48 Timestamp() = delete; 49 50 template <typename T = int64_t> 51 constexpr T seconds() const { 52 return ToFraction<1000000, T>(); 53 } 54 template <typename T = int64_t> 55 constexpr T ms() const { 56 return ToFraction<1000, T>(); 57 } 58 template <typename T = int64_t> 59 constexpr T us() const { 60 return ToValue<T>(); 61 } 62 63 constexpr int64_t seconds_or(int64_t fallback_value) const { 64 return ToFractionOr<1000000>(fallback_value); 65 } 66 constexpr int64_t ms_or(int64_t fallback_value) const { 67 return ToFractionOr<1000>(fallback_value); 68 } 69 constexpr int64_t us_or(int64_t fallback_value) const { 70 return ToValueOr(fallback_value); 71 } 72 73 constexpr Timestamp operator+(const TimeDelta delta) const { 74 if (IsPlusInfinity() || delta.IsPlusInfinity()) { 75 RTC_DCHECK(!IsMinusInfinity()); 76 RTC_DCHECK(!delta.IsMinusInfinity()); 77 return PlusInfinity(); 78 } else if (IsMinusInfinity() || delta.IsMinusInfinity()) { 79 RTC_DCHECK(!IsPlusInfinity()); 80 RTC_DCHECK(!delta.IsPlusInfinity()); 81 return MinusInfinity(); 82 } 83 return Timestamp::Micros(us() + delta.us()); 84 } 85 constexpr Timestamp operator-(const TimeDelta delta) const { 86 if (IsPlusInfinity() || delta.IsMinusInfinity()) { 87 RTC_DCHECK(!IsMinusInfinity()); 88 RTC_DCHECK(!delta.IsPlusInfinity()); 89 return PlusInfinity(); 90 } else if (IsMinusInfinity() || delta.IsPlusInfinity()) { 91 RTC_DCHECK(!IsPlusInfinity()); 92 RTC_DCHECK(!delta.IsMinusInfinity()); 93 return MinusInfinity(); 94 } 95 return Timestamp::Micros(us() - delta.us()); 96 } 97 constexpr TimeDelta operator-(const Timestamp other) const { 98 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 } 107 return TimeDelta::Micros(us() - other.us()); 108 } 109 constexpr Timestamp& operator-=(const TimeDelta delta) { 110 *this = *this - delta; 111 return *this; 112 } 113 constexpr Timestamp& operator+=(const TimeDelta delta) { 114 *this = *this + delta; 115 return *this; 116 } 117 118 private: 119 friend class rtc_units_impl::UnitBase<Timestamp>; 120 using UnitBase::UnitBase; 121 static constexpr bool one_sided = true; 122 }; 123 124 std::string ToString(Timestamp value); 125 inline std::string ToLogString(Timestamp value) { 126 return ToString(value); 127 } 128 129 #ifdef WEBRTC_UNIT_TEST 130 inline 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 } 135 #endif // WEBRTC_UNIT_TEST 136 137 } // namespace webrtc 138 139 #endif // API_UNITS_TIMESTAMP_H_ 140