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 UNIT_TEST 15 #include <ostream> // no-presubmit-check TODO(webrtc:8982) 16 #endif // 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 24 namespace webrtc { 25 // 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. 29 class Timestamp final : public rtc_units_impl::UnitBase<Timestamp> { 30 public: 31 template <typename T> Seconds(T value)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> Millis(T value)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 47 Timestamp() = delete; 48 49 template <typename T = int64_t> 50 constexpr T seconds() const { 51 return ToFraction<1000000, T>(); 52 } 53 template <typename T = int64_t> 54 constexpr T ms() const { 55 return ToFraction<1000, T>(); 56 } 57 template <typename T = int64_t> 58 constexpr T us() const { 59 return ToValue<T>(); 60 } 61 62 constexpr int64_t seconds_or(int64_t fallback_value) const { 63 return ToFractionOr<1000000>(fallback_value); 64 } 65 constexpr int64_t ms_or(int64_t fallback_value) const { 66 return ToFractionOr<1000>(fallback_value); 67 } 68 constexpr int64_t us_or(int64_t fallback_value) const { 69 return ToValueOr(fallback_value); 70 } 71 72 constexpr Timestamp operator+(const TimeDelta delta) const { 73 if (IsPlusInfinity() || delta.IsPlusInfinity()) { 74 RTC_DCHECK(!IsMinusInfinity()); 75 RTC_DCHECK(!delta.IsMinusInfinity()); 76 return PlusInfinity(); 77 } else if (IsMinusInfinity() || delta.IsMinusInfinity()) { 78 RTC_DCHECK(!IsPlusInfinity()); 79 RTC_DCHECK(!delta.IsPlusInfinity()); 80 return MinusInfinity(); 81 } 82 return Timestamp::Micros(us() + delta.us()); 83 } 84 constexpr Timestamp operator-(const TimeDelta delta) const { 85 if (IsPlusInfinity() || delta.IsMinusInfinity()) { 86 RTC_DCHECK(!IsMinusInfinity()); 87 RTC_DCHECK(!delta.IsPlusInfinity()); 88 return PlusInfinity(); 89 } else if (IsMinusInfinity() || delta.IsPlusInfinity()) { 90 RTC_DCHECK(!IsPlusInfinity()); 91 RTC_DCHECK(!delta.IsMinusInfinity()); 92 return MinusInfinity(); 93 } 94 return Timestamp::Micros(us() - delta.us()); 95 } 96 constexpr TimeDelta operator-(const Timestamp other) const { 97 if (IsPlusInfinity() || other.IsMinusInfinity()) { 98 RTC_DCHECK(!IsMinusInfinity()); 99 RTC_DCHECK(!other.IsPlusInfinity()); 100 return TimeDelta::PlusInfinity(); 101 } else if (IsMinusInfinity() || other.IsPlusInfinity()) { 102 RTC_DCHECK(!IsPlusInfinity()); 103 RTC_DCHECK(!other.IsMinusInfinity()); 104 return TimeDelta::MinusInfinity(); 105 } 106 return TimeDelta::Micros(us() - other.us()); 107 } 108 constexpr Timestamp& operator-=(const TimeDelta delta) { 109 *this = *this - delta; 110 return *this; 111 } 112 constexpr Timestamp& operator+=(const TimeDelta delta) { 113 *this = *this + delta; 114 return *this; 115 } 116 117 private: 118 friend class rtc_units_impl::UnitBase<Timestamp>; 119 using UnitBase::UnitBase; 120 static constexpr bool one_sided = true; 121 }; 122 123 std::string ToString(Timestamp value); 124 inline std::string ToLogString(Timestamp value) { 125 return ToString(value); 126 } 127 128 #ifdef UNIT_TEST 129 inline std::ostream& operator<<( // no-presubmit-check TODO(webrtc:8982) 130 std::ostream& stream, // no-presubmit-check TODO(webrtc:8982) 131 Timestamp value) { 132 return stream << ToString(value); 133 } 134 #endif // UNIT_TEST 135 136 } // namespace webrtc 137 138 #endif // API_UNITS_TIMESTAMP_H_ 139