Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/core/quic_time.h b/quic/core/quic_time.h
new file mode 100644
index 0000000..6bd3f68
--- /dev/null
+++ b/quic/core/quic_time.h
@@ -0,0 +1,277 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// QuicTime represents one point in time, stored in microsecond resolution.
+// QuicTime is monotonically increasing, even across system clock adjustments.
+// The epoch (time 0) of QuicTime is unspecified.
+//
+// This implementation wraps a int64_t of usec since the epoch.  While
+// the epoch is the Unix epoch, do not depend on this fact because other
+// implementations, like Chrome's, do NOT have the same epoch.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_TIME_H_
+#define QUICHE_QUIC_CORE_QUIC_TIME_H_
+
+#include <cmath>
+#include <cstdint>
+#include <limits>
+#include <ostream>
+
+#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+
+// TODO(vasilvv): replace with ABSL_MUST_USE_RESULT once we're using absl.
+#if defined(__clang__)
+#define QUIC_TIME_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#define QUIC_TIME_WARN_UNUSED_RESULT
+#endif /* defined(__clang__) */
+
+namespace quic {
+
+class QuicClock;
+
+// A QuicTime is a purely relative time. QuicTime values from different clocks
+// cannot be compared to each other. If you need an absolute time, see
+// QuicWallTime, below.
+class QUIC_EXPORT_PRIVATE QuicTime {
+ public:
+  // A QuicTime::Delta represents the signed difference between two points in
+  // time, stored in microsecond resolution.
+  class QUIC_EXPORT_PRIVATE Delta {
+   public:
+    // Create a object with an offset of 0.
+    static constexpr Delta Zero() { return Delta(0); }
+
+    // Create a object with infinite offset time.
+    static constexpr Delta Infinite() { return Delta(kQuicInfiniteTimeUs); }
+
+    // Converts a number of seconds to a time offset.
+    static constexpr Delta FromSeconds(int64_t secs) {
+      return Delta(secs * 1000 * 1000);
+    }
+
+    // Converts a number of milliseconds to a time offset.
+    static constexpr Delta FromMilliseconds(int64_t ms) {
+      return Delta(ms * 1000);
+    }
+
+    // Converts a number of microseconds to a time offset.
+    static constexpr Delta FromMicroseconds(int64_t us) { return Delta(us); }
+
+    // Converts the time offset to a rounded number of seconds.
+    inline int64_t ToSeconds() const { return time_offset_ / 1000 / 1000; }
+
+    // Converts the time offset to a rounded number of milliseconds.
+    inline int64_t ToMilliseconds() const { return time_offset_ / 1000; }
+
+    // Converts the time offset to a rounded number of microseconds.
+    inline int64_t ToMicroseconds() const { return time_offset_; }
+
+    inline bool IsZero() const { return time_offset_ == 0; }
+
+    inline bool IsInfinite() const {
+      return time_offset_ == kQuicInfiniteTimeUs;
+    }
+
+    QuicString ToDebugValue() const;
+
+   private:
+    friend inline bool operator==(QuicTime::Delta lhs, QuicTime::Delta rhs);
+    friend inline bool operator<(QuicTime::Delta lhs, QuicTime::Delta rhs);
+    friend inline QuicTime::Delta operator<<(QuicTime::Delta lhs, size_t rhs);
+    friend inline QuicTime::Delta operator>>(QuicTime::Delta lhs, size_t rhs);
+
+    friend inline QuicTime::Delta operator+(QuicTime::Delta lhs,
+                                            QuicTime::Delta rhs);
+    friend inline QuicTime::Delta operator-(QuicTime::Delta lhs,
+                                            QuicTime::Delta rhs);
+    friend inline QuicTime::Delta operator*(QuicTime::Delta lhs, int rhs);
+    friend inline QuicTime::Delta operator*(QuicTime::Delta lhs, double rhs);
+
+    friend inline QuicTime operator+(QuicTime lhs, QuicTime::Delta rhs);
+    friend inline QuicTime operator-(QuicTime lhs, QuicTime::Delta rhs);
+    friend inline QuicTime::Delta operator-(QuicTime lhs, QuicTime rhs);
+
+    static const int64_t kQuicInfiniteTimeUs =
+        std::numeric_limits<int64_t>::max();
+
+    explicit constexpr Delta(int64_t time_offset) : time_offset_(time_offset) {}
+
+    int64_t time_offset_;
+    friend class QuicTime;
+  };
+
+  // Creates a new QuicTime with an internal value of 0.  IsInitialized()
+  // will return false for these times.
+  static constexpr QuicTime Zero() { return QuicTime(0); }
+
+  // Creates a new QuicTime with an infinite time.
+  static constexpr QuicTime Infinite() {
+    return QuicTime(Delta::kQuicInfiniteTimeUs);
+  }
+
+  QuicTime(const QuicTime& other) = default;
+
+  QuicTime& operator=(const QuicTime& other) {
+    time_ = other.time_;
+    return *this;
+  }
+
+  // Produce the internal value to be used when logging.  This value
+  // represents the number of microseconds since some epoch.  It may
+  // be the UNIX epoch on some platforms.  On others, it may
+  // be a CPU ticks based value.
+  inline int64_t ToDebuggingValue() const { return time_; }
+
+  inline bool IsInitialized() const { return 0 != time_; }
+
+ private:
+  friend class QuicClock;
+
+  friend inline bool operator==(QuicTime lhs, QuicTime rhs);
+  friend inline bool operator<(QuicTime lhs, QuicTime rhs);
+  friend inline QuicTime operator+(QuicTime lhs, QuicTime::Delta rhs);
+  friend inline QuicTime operator-(QuicTime lhs, QuicTime::Delta rhs);
+  friend inline QuicTime::Delta operator-(QuicTime lhs, QuicTime rhs);
+
+  explicit constexpr QuicTime(int64_t time) : time_(time) {}
+
+  int64_t time_;
+};
+
+// A QuicWallTime represents an absolute time that is globally consistent. In
+// practice, clock-skew means that comparing values from different machines
+// requires some flexibility.
+class QUIC_EXPORT_PRIVATE QuicWallTime {
+ public:
+  // FromUNIXSeconds constructs a QuicWallTime from a count of the seconds
+  // since the UNIX epoch.
+  static constexpr QuicWallTime FromUNIXSeconds(uint64_t seconds) {
+    return QuicWallTime(seconds * 1000000);
+  }
+
+  static constexpr QuicWallTime FromUNIXMicroseconds(uint64_t microseconds) {
+    return QuicWallTime(microseconds);
+  }
+
+  // Zero returns a QuicWallTime set to zero. IsZero will return true for this
+  // value.
+  static constexpr QuicWallTime Zero() { return QuicWallTime(0); }
+
+  // Returns the number of seconds since the UNIX epoch.
+  uint64_t ToUNIXSeconds() const;
+  // Returns the number of microseconds since the UNIX epoch.
+  uint64_t ToUNIXMicroseconds() const;
+
+  bool IsAfter(QuicWallTime other) const;
+  bool IsBefore(QuicWallTime other) const;
+
+  // IsZero returns true if this object is the result of calling |Zero|.
+  bool IsZero() const;
+
+  // AbsoluteDifference returns the absolute value of the time difference
+  // between |this| and |other|.
+  QuicTime::Delta AbsoluteDifference(QuicWallTime other) const;
+
+  // Add returns a new QuicWallTime that represents the time of |this| plus
+  // |delta|.
+  QUIC_TIME_WARN_UNUSED_RESULT QuicWallTime Add(QuicTime::Delta delta) const;
+
+  // Subtract returns a new QuicWallTime that represents the time of |this|
+  // minus |delta|.
+  QUIC_TIME_WARN_UNUSED_RESULT QuicWallTime
+  Subtract(QuicTime::Delta delta) const;
+
+ private:
+  explicit constexpr QuicWallTime(uint64_t microseconds)
+      : microseconds_(microseconds) {}
+
+  uint64_t microseconds_;
+};
+
+// Non-member relational operators for QuicTime::Delta.
+inline bool operator==(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return lhs.time_offset_ == rhs.time_offset_;
+}
+inline bool operator!=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return !(lhs == rhs);
+}
+inline bool operator<(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return lhs.time_offset_ < rhs.time_offset_;
+}
+inline bool operator>(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return rhs < lhs;
+}
+inline bool operator<=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return !(rhs < lhs);
+}
+inline bool operator>=(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return !(lhs < rhs);
+}
+inline QuicTime::Delta operator>>(QuicTime::Delta lhs, size_t rhs) {
+  return QuicTime::Delta(lhs.time_offset_ >> rhs);
+}
+
+// Non-member relational operators for QuicTime.
+inline bool operator==(QuicTime lhs, QuicTime rhs) {
+  return lhs.time_ == rhs.time_;
+}
+inline bool operator!=(QuicTime lhs, QuicTime rhs) {
+  return !(lhs == rhs);
+}
+inline bool operator<(QuicTime lhs, QuicTime rhs) {
+  return lhs.time_ < rhs.time_;
+}
+inline bool operator>(QuicTime lhs, QuicTime rhs) {
+  return rhs < lhs;
+}
+inline bool operator<=(QuicTime lhs, QuicTime rhs) {
+  return !(rhs < lhs);
+}
+inline bool operator>=(QuicTime lhs, QuicTime rhs) {
+  return !(lhs < rhs);
+}
+
+// Non-member arithmetic operators for QuicTime::Delta.
+inline QuicTime::Delta operator+(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return QuicTime::Delta(lhs.time_offset_ + rhs.time_offset_);
+}
+inline QuicTime::Delta operator-(QuicTime::Delta lhs, QuicTime::Delta rhs) {
+  return QuicTime::Delta(lhs.time_offset_ - rhs.time_offset_);
+}
+inline QuicTime::Delta operator*(QuicTime::Delta lhs, int rhs) {
+  return QuicTime::Delta(lhs.time_offset_ * rhs);
+}
+inline QuicTime::Delta operator*(QuicTime::Delta lhs, double rhs) {
+  return QuicTime::Delta(
+      static_cast<int64_t>(std::llround(lhs.time_offset_ * rhs)));
+}
+inline QuicTime::Delta operator*(int lhs, QuicTime::Delta rhs) {
+  return rhs * lhs;
+}
+inline QuicTime::Delta operator*(double lhs, QuicTime::Delta rhs) {
+  return rhs * lhs;
+}
+
+// Non-member arithmetic operators for QuicTime and QuicTime::Delta.
+inline QuicTime operator+(QuicTime lhs, QuicTime::Delta rhs) {
+  return QuicTime(lhs.time_ + rhs.time_offset_);
+}
+inline QuicTime operator-(QuicTime lhs, QuicTime::Delta rhs) {
+  return QuicTime(lhs.time_ - rhs.time_offset_);
+}
+inline QuicTime::Delta operator-(QuicTime lhs, QuicTime rhs) {
+  return QuicTime::Delta(lhs.time_ - rhs.time_);
+}
+
+// Override stream output operator for gtest.
+inline std::ostream& operator<<(std::ostream& output,
+                                const QuicTime::Delta delta) {
+  output << delta.ToDebugValue();
+  return output;
+}
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_TIME_H_