Bring Time(Delta)::Min/Max() and related helpers to V8.
Copied as-is modulo compile tweaks from Chromium's base. Copied tests highlighting existing overflow issues with V8's impl... TimeDelta::Max() will initially be used in V8 to flag events that never triggered in a TimedHistogram. Also constexpr'ed a few things while I was in there, it's harmless at worst and helps a little at best. Ideally would constexpr all the Time*::From*() methods like in Chromium but that has inlining implications and I don't know the impact that could have on V8. Bug: chromium:807606 Change-Id: If5aa92759d985be070e12af4dd20f0159169048b Reviewed-on: https://chromium-review.googlesource.com/899342 Reviewed-by: Hannes Payer <hpayer@chromium.org> Commit-Queue: Gabriel Charette <gab@chromium.org> Cr-Commit-Position: refs/heads/master@{#51073}
This commit is contained in:
parent
7a0f8052d0
commit
db73d446b9
@ -143,41 +143,83 @@ TimeDelta TimeDelta::FromNanoseconds(int64_t nanoseconds) {
|
||||
|
||||
|
||||
int TimeDelta::InDays() const {
|
||||
if (IsMax()) {
|
||||
// Preserve max to prevent overflow.
|
||||
return std::numeric_limits<int>::max();
|
||||
}
|
||||
return static_cast<int>(delta_ / Time::kMicrosecondsPerDay);
|
||||
}
|
||||
|
||||
|
||||
int TimeDelta::InHours() const {
|
||||
if (IsMax()) {
|
||||
// Preserve max to prevent overflow.
|
||||
return std::numeric_limits<int>::max();
|
||||
}
|
||||
return static_cast<int>(delta_ / Time::kMicrosecondsPerHour);
|
||||
}
|
||||
|
||||
|
||||
int TimeDelta::InMinutes() const {
|
||||
if (IsMax()) {
|
||||
// Preserve max to prevent overflow.
|
||||
return std::numeric_limits<int>::max();
|
||||
}
|
||||
return static_cast<int>(delta_ / Time::kMicrosecondsPerMinute);
|
||||
}
|
||||
|
||||
|
||||
double TimeDelta::InSecondsF() const {
|
||||
if (IsMax()) {
|
||||
// Preserve max to prevent overflow.
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
return static_cast<double>(delta_) / Time::kMicrosecondsPerSecond;
|
||||
}
|
||||
|
||||
|
||||
int64_t TimeDelta::InSeconds() const {
|
||||
if (IsMax()) {
|
||||
// Preserve max to prevent overflow.
|
||||
return std::numeric_limits<int64_t>::max();
|
||||
}
|
||||
return delta_ / Time::kMicrosecondsPerSecond;
|
||||
}
|
||||
|
||||
|
||||
double TimeDelta::InMillisecondsF() const {
|
||||
if (IsMax()) {
|
||||
// Preserve max to prevent overflow.
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
return static_cast<double>(delta_) / Time::kMicrosecondsPerMillisecond;
|
||||
}
|
||||
|
||||
|
||||
int64_t TimeDelta::InMilliseconds() const {
|
||||
if (IsMax()) {
|
||||
// Preserve max to prevent overflow.
|
||||
return std::numeric_limits<int64_t>::max();
|
||||
}
|
||||
return delta_ / Time::kMicrosecondsPerMillisecond;
|
||||
}
|
||||
|
||||
int64_t TimeDelta::InMillisecondsRoundedUp() const {
|
||||
if (IsMax()) {
|
||||
// Preserve max to prevent overflow.
|
||||
return std::numeric_limits<int64_t>::max();
|
||||
}
|
||||
return (delta_ + Time::kMicrosecondsPerMillisecond - 1) /
|
||||
Time::kMicrosecondsPerMillisecond;
|
||||
}
|
||||
|
||||
int64_t TimeDelta::InMicroseconds() const {
|
||||
if (IsMax()) {
|
||||
// Preserve max to prevent overflow.
|
||||
return std::numeric_limits<int64_t>::max();
|
||||
}
|
||||
return delta_;
|
||||
}
|
||||
|
||||
int64_t TimeDelta::InNanoseconds() const {
|
||||
if (IsMax()) {
|
||||
// Preserve max to prevent overflow.
|
||||
return std::numeric_limits<int64_t>::max();
|
||||
}
|
||||
return delta_ * Time::kNanosecondsPerMicrosecond;
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ class TimeBase;
|
||||
|
||||
class V8_BASE_EXPORT TimeDelta final {
|
||||
public:
|
||||
TimeDelta() : delta_(0) {}
|
||||
constexpr TimeDelta() : delta_(0) {}
|
||||
|
||||
// Converts units of time to TimeDeltas.
|
||||
static TimeDelta FromDays(int days);
|
||||
@ -60,6 +60,27 @@ class V8_BASE_EXPORT TimeDelta final {
|
||||
}
|
||||
static TimeDelta FromNanoseconds(int64_t nanoseconds);
|
||||
|
||||
// Returns the maximum time delta, which should be greater than any reasonable
|
||||
// time delta we might compare it to. Adding or subtracting the maximum time
|
||||
// delta to a time or another time delta has an undefined result.
|
||||
static constexpr TimeDelta Max();
|
||||
|
||||
// Returns the minimum time delta, which should be less than than any
|
||||
// reasonable time delta we might compare it to. Adding or subtracting the
|
||||
// minimum time delta to a time or another time delta has an undefined result.
|
||||
static constexpr TimeDelta Min();
|
||||
|
||||
// Returns true if the time delta is zero.
|
||||
constexpr bool IsZero() const { return delta_ == 0; }
|
||||
|
||||
// Returns true if the time delta is the maximum/minimum time delta.
|
||||
constexpr bool IsMax() const {
|
||||
return delta_ == std::numeric_limits<int64_t>::max();
|
||||
}
|
||||
constexpr bool IsMin() const {
|
||||
return delta_ == std::numeric_limits<int64_t>::min();
|
||||
}
|
||||
|
||||
// Returns the time delta in some unit. The F versions return a floating
|
||||
// point value, the "regular" versions return a rounded-down value.
|
||||
//
|
||||
@ -73,7 +94,7 @@ class V8_BASE_EXPORT TimeDelta final {
|
||||
double InMillisecondsF() const;
|
||||
int64_t InMilliseconds() const;
|
||||
int64_t InMillisecondsRoundedUp() const;
|
||||
int64_t InMicroseconds() const { return delta_; }
|
||||
int64_t InMicroseconds() const;
|
||||
int64_t InNanoseconds() const;
|
||||
|
||||
// Converts to/from Mach time specs.
|
||||
@ -105,9 +126,7 @@ class V8_BASE_EXPORT TimeDelta final {
|
||||
delta_ -= other.delta_;
|
||||
return *this;
|
||||
}
|
||||
TimeDelta operator-() const {
|
||||
return TimeDelta(-delta_);
|
||||
}
|
||||
constexpr TimeDelta operator-() const { return TimeDelta(-delta_); }
|
||||
|
||||
double TimesOf(const TimeDelta& other) const {
|
||||
return static_cast<double>(delta_) / static_cast<double>(other.delta_);
|
||||
@ -137,22 +156,22 @@ class V8_BASE_EXPORT TimeDelta final {
|
||||
}
|
||||
|
||||
// Comparison operators.
|
||||
bool operator==(const TimeDelta& other) const {
|
||||
constexpr bool operator==(const TimeDelta& other) const {
|
||||
return delta_ == other.delta_;
|
||||
}
|
||||
bool operator!=(const TimeDelta& other) const {
|
||||
constexpr bool operator!=(const TimeDelta& other) const {
|
||||
return delta_ != other.delta_;
|
||||
}
|
||||
bool operator<(const TimeDelta& other) const {
|
||||
constexpr bool operator<(const TimeDelta& other) const {
|
||||
return delta_ < other.delta_;
|
||||
}
|
||||
bool operator<=(const TimeDelta& other) const {
|
||||
constexpr bool operator<=(const TimeDelta& other) const {
|
||||
return delta_ <= other.delta_;
|
||||
}
|
||||
bool operator>(const TimeDelta& other) const {
|
||||
constexpr bool operator>(const TimeDelta& other) const {
|
||||
return delta_ > other.delta_;
|
||||
}
|
||||
bool operator>=(const TimeDelta& other) const {
|
||||
constexpr bool operator>=(const TimeDelta& other) const {
|
||||
return delta_ >= other.delta_;
|
||||
}
|
||||
|
||||
@ -161,12 +180,21 @@ class V8_BASE_EXPORT TimeDelta final {
|
||||
// Constructs a delta given the duration in microseconds. This is private
|
||||
// to avoid confusion by callers with an integer constructor. Use
|
||||
// FromSeconds, FromMilliseconds, etc. instead.
|
||||
explicit TimeDelta(int64_t delta) : delta_(delta) {}
|
||||
explicit constexpr TimeDelta(int64_t delta) : delta_(delta) {}
|
||||
|
||||
// Delta in microseconds.
|
||||
int64_t delta_;
|
||||
};
|
||||
|
||||
// static
|
||||
constexpr TimeDelta TimeDelta::Max() {
|
||||
return TimeDelta(std::numeric_limits<int64_t>::max());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr TimeDelta TimeDelta::Min() {
|
||||
return TimeDelta(std::numeric_limits<int64_t>::min());
|
||||
}
|
||||
|
||||
namespace time_internal {
|
||||
|
||||
@ -207,12 +235,24 @@ class TimeBase {
|
||||
// Warning: Be careful when writing code that performs math on time values,
|
||||
// since it's possible to produce a valid "zero" result that should not be
|
||||
// interpreted as a "null" value.
|
||||
bool IsNull() const {
|
||||
return us_ == 0;
|
||||
constexpr bool IsNull() const { return us_ == 0; }
|
||||
|
||||
// Returns the maximum/minimum times, which should be greater/less than any
|
||||
// reasonable time with which we might compare it.
|
||||
static TimeClass Max() {
|
||||
return TimeClass(std::numeric_limits<int64_t>::max());
|
||||
}
|
||||
static TimeClass Min() {
|
||||
return TimeClass(std::numeric_limits<int64_t>::min());
|
||||
}
|
||||
|
||||
// Returns true if this object represents the maximum time.
|
||||
bool IsMax() const { return us_ == std::numeric_limits<int64_t>::max(); }
|
||||
// Returns true if this object represents the maximum/minimum time.
|
||||
constexpr bool IsMax() const {
|
||||
return us_ == std::numeric_limits<int64_t>::max();
|
||||
}
|
||||
constexpr bool IsMin() const {
|
||||
return us_ == std::numeric_limits<int64_t>::min();
|
||||
}
|
||||
|
||||
// For serializing only. Use FromInternalValue() to reconstitute. Please don't
|
||||
// use this and do arithmetic on it, as it is more error prone than using the
|
||||
@ -272,7 +312,7 @@ class TimeBase {
|
||||
static TimeClass FromInternalValue(int64_t us) { return TimeClass(us); }
|
||||
|
||||
protected:
|
||||
explicit TimeBase(int64_t us) : us_(us) {}
|
||||
explicit constexpr TimeBase(int64_t us) : us_(us) {}
|
||||
|
||||
// Time value in a microsecond timebase.
|
||||
int64_t us_;
|
||||
@ -290,7 +330,7 @@ class TimeBase {
|
||||
class V8_BASE_EXPORT Time final : public time_internal::TimeBase<Time> {
|
||||
public:
|
||||
// Contains the nullptr time. Use Time::Now() to get the current time.
|
||||
Time() : TimeBase(0) {}
|
||||
constexpr Time() : TimeBase(0) {}
|
||||
|
||||
// Returns the current time. Watch out, the system might adjust its clock
|
||||
// in which case time will actually go backwards. We don't guarantee that
|
||||
@ -306,10 +346,6 @@ class V8_BASE_EXPORT Time final : public time_internal::TimeBase<Time> {
|
||||
// Returns the time for epoch in Unix-like system (Jan 1, 1970).
|
||||
static Time UnixEpoch() { return Time(0); }
|
||||
|
||||
// Returns the maximum time, which should be greater than any reasonable time
|
||||
// with which we might compare it.
|
||||
static Time Max() { return Time(std::numeric_limits<int64_t>::max()); }
|
||||
|
||||
// Converts to/from POSIX time specs.
|
||||
static Time FromTimespec(struct timespec ts);
|
||||
struct timespec ToTimespec() const;
|
||||
@ -329,7 +365,7 @@ class V8_BASE_EXPORT Time final : public time_internal::TimeBase<Time> {
|
||||
|
||||
private:
|
||||
friend class time_internal::TimeBase<Time>;
|
||||
explicit Time(int64_t us) : TimeBase(us) {}
|
||||
explicit constexpr Time(int64_t us) : TimeBase(us) {}
|
||||
};
|
||||
|
||||
V8_BASE_EXPORT std::ostream& operator<<(std::ostream&, const Time&);
|
||||
@ -352,7 +388,7 @@ inline Time operator+(const TimeDelta& delta, const Time& time) {
|
||||
class V8_BASE_EXPORT TimeTicks final
|
||||
: public time_internal::TimeBase<TimeTicks> {
|
||||
public:
|
||||
TimeTicks() : TimeBase(0) {}
|
||||
constexpr TimeTicks() : TimeBase(0) {}
|
||||
|
||||
// Platform-dependent tick count representing "right now." When
|
||||
// IsHighResolution() returns false, the resolution of the clock could be as
|
||||
@ -374,7 +410,7 @@ class V8_BASE_EXPORT TimeTicks final
|
||||
|
||||
// Please use Now() to create a new object. This is for internal use
|
||||
// and testing. Ticks are in microseconds.
|
||||
explicit TimeTicks(int64_t ticks) : TimeBase(ticks) {}
|
||||
explicit constexpr TimeTicks(int64_t ticks) : TimeBase(ticks) {}
|
||||
};
|
||||
|
||||
inline TimeTicks operator+(const TimeDelta& delta, const TimeTicks& ticks) {
|
||||
@ -389,7 +425,7 @@ inline TimeTicks operator+(const TimeDelta& delta, const TimeTicks& ticks) {
|
||||
class V8_BASE_EXPORT ThreadTicks final
|
||||
: public time_internal::TimeBase<ThreadTicks> {
|
||||
public:
|
||||
ThreadTicks() : TimeBase(0) {}
|
||||
constexpr ThreadTicks() : TimeBase(0) {}
|
||||
|
||||
// Returns true if ThreadTicks::Now() is supported on this system.
|
||||
static bool IsSupported();
|
||||
@ -424,7 +460,7 @@ class V8_BASE_EXPORT ThreadTicks final
|
||||
|
||||
// Please use Now() or GetForThread() to create a new object. This is for
|
||||
// internal use and testing. Ticks are in microseconds.
|
||||
explicit ThreadTicks(int64_t ticks) : TimeBase(ticks) {}
|
||||
explicit constexpr ThreadTicks(int64_t ticks) : TimeBase(ticks) {}
|
||||
|
||||
#if V8_OS_WIN
|
||||
// Returns the frequency of the TSC in ticks per second, or 0 if it hasn't
|
||||
|
@ -24,6 +24,163 @@
|
||||
namespace v8 {
|
||||
namespace base {
|
||||
|
||||
TEST(TimeDelta, ZeroMinMax) {
|
||||
constexpr TimeDelta kZero;
|
||||
static_assert(kZero.IsZero(), "");
|
||||
|
||||
constexpr TimeDelta kMax = TimeDelta::Max();
|
||||
static_assert(kMax.IsMax(), "");
|
||||
static_assert(kMax == TimeDelta::Max(), "");
|
||||
EXPECT_GT(kMax, TimeDelta::FromDays(100 * 365));
|
||||
static_assert(kMax > kZero, "");
|
||||
|
||||
constexpr TimeDelta kMin = TimeDelta::Min();
|
||||
static_assert(kMin.IsMin(), "");
|
||||
static_assert(kMin == TimeDelta::Min(), "");
|
||||
EXPECT_LT(kMin, TimeDelta::FromDays(-100 * 365));
|
||||
static_assert(kMin < kZero, "");
|
||||
}
|
||||
|
||||
TEST(TimeDelta, MaxConversions) {
|
||||
// static_assert also confirms constexpr works as intended.
|
||||
constexpr TimeDelta kMax = TimeDelta::Max();
|
||||
EXPECT_EQ(kMax.InDays(), std::numeric_limits<int>::max());
|
||||
EXPECT_EQ(kMax.InHours(), std::numeric_limits<int>::max());
|
||||
EXPECT_EQ(kMax.InMinutes(), std::numeric_limits<int>::max());
|
||||
EXPECT_EQ(kMax.InSecondsF(), std::numeric_limits<double>::infinity());
|
||||
EXPECT_EQ(kMax.InSeconds(), std::numeric_limits<int64_t>::max());
|
||||
EXPECT_EQ(kMax.InMillisecondsF(), std::numeric_limits<double>::infinity());
|
||||
EXPECT_EQ(kMax.InMilliseconds(), std::numeric_limits<int64_t>::max());
|
||||
EXPECT_EQ(kMax.InMillisecondsRoundedUp(),
|
||||
std::numeric_limits<int64_t>::max());
|
||||
|
||||
// TODO(v8-team): Import overflow support from Chromium's base.
|
||||
|
||||
// EXPECT_TRUE(TimeDelta::FromDays(std::numeric_limits<int>::max()).IsMax());
|
||||
|
||||
// EXPECT_TRUE(
|
||||
// TimeDelta::FromHours(std::numeric_limits<int>::max()).IsMax());
|
||||
|
||||
// EXPECT_TRUE(
|
||||
// TimeDelta::FromMinutes(std::numeric_limits<int>::max()).IsMax());
|
||||
|
||||
// constexpr int64_t max_int = std::numeric_limits<int64_t>::max();
|
||||
// constexpr int64_t min_int = std::numeric_limits<int64_t>::min();
|
||||
|
||||
// EXPECT_TRUE(
|
||||
// TimeDelta::FromSeconds(max_int / Time::kMicrosecondsPerSecond + 1)
|
||||
// .IsMax());
|
||||
|
||||
// EXPECT_TRUE(TimeDelta::FromMilliseconds(
|
||||
// max_int / Time::kMillisecondsPerSecond + 1)
|
||||
// .IsMax());
|
||||
|
||||
// EXPECT_TRUE(TimeDelta::FromMicroseconds(max_int).IsMax());
|
||||
|
||||
// EXPECT_TRUE(
|
||||
// TimeDelta::FromSeconds(min_int / Time::kMicrosecondsPerSecond - 1)
|
||||
// .IsMin());
|
||||
|
||||
// EXPECT_TRUE(TimeDelta::FromMilliseconds(
|
||||
// min_int / Time::kMillisecondsPerSecond - 1)
|
||||
// .IsMin());
|
||||
|
||||
// EXPECT_TRUE(TimeDelta::FromMicroseconds(min_int).IsMin());
|
||||
|
||||
// EXPECT_TRUE(
|
||||
// TimeDelta::FromMicroseconds(std::numeric_limits<int64_t>::min())
|
||||
// .IsMin());
|
||||
}
|
||||
|
||||
TEST(TimeDelta, NumericOperators) {
|
||||
constexpr int i = 2;
|
||||
EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
|
||||
(TimeDelta::FromMilliseconds(1000) * i));
|
||||
EXPECT_EQ(TimeDelta::FromMilliseconds(500),
|
||||
(TimeDelta::FromMilliseconds(1000) / i));
|
||||
EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
|
||||
(TimeDelta::FromMilliseconds(1000) *= i));
|
||||
EXPECT_EQ(TimeDelta::FromMilliseconds(500),
|
||||
(TimeDelta::FromMilliseconds(1000) /= i));
|
||||
|
||||
constexpr int64_t i64 = 2;
|
||||
EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
|
||||
(TimeDelta::FromMilliseconds(1000) * i64));
|
||||
EXPECT_EQ(TimeDelta::FromMilliseconds(500),
|
||||
(TimeDelta::FromMilliseconds(1000) / i64));
|
||||
EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
|
||||
(TimeDelta::FromMilliseconds(1000) *= i64));
|
||||
EXPECT_EQ(TimeDelta::FromMilliseconds(500),
|
||||
(TimeDelta::FromMilliseconds(1000) /= i64));
|
||||
|
||||
EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
|
||||
(TimeDelta::FromMilliseconds(1000) * 2));
|
||||
EXPECT_EQ(TimeDelta::FromMilliseconds(500),
|
||||
(TimeDelta::FromMilliseconds(1000) / 2));
|
||||
EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
|
||||
(TimeDelta::FromMilliseconds(1000) *= 2));
|
||||
EXPECT_EQ(TimeDelta::FromMilliseconds(500),
|
||||
(TimeDelta::FromMilliseconds(1000) /= 2));
|
||||
}
|
||||
|
||||
// TODO(v8-team): Import support for overflow from Chromium's base.
|
||||
TEST(TimeDelta, DISABLED_Overflows) {
|
||||
// Some sanity checks. static_assert's used were possible to verify constexpr
|
||||
// evaluation at the same time.
|
||||
static_assert(TimeDelta::Max().IsMax(), "");
|
||||
static_assert(-TimeDelta::Max() < TimeDelta(), "");
|
||||
static_assert(-TimeDelta::Max() > TimeDelta::Min(), "");
|
||||
static_assert(TimeDelta() > -TimeDelta::Max(), "");
|
||||
|
||||
TimeDelta large_delta = TimeDelta::Max() - TimeDelta::FromMilliseconds(1);
|
||||
TimeDelta large_negative = -large_delta;
|
||||
EXPECT_GT(TimeDelta(), large_negative);
|
||||
EXPECT_FALSE(large_delta.IsMax());
|
||||
EXPECT_FALSE((-large_negative).IsMin());
|
||||
const TimeDelta kOneSecond = TimeDelta::FromSeconds(1);
|
||||
|
||||
// Test +, -, * and / operators.
|
||||
EXPECT_TRUE((large_delta + kOneSecond).IsMax());
|
||||
EXPECT_TRUE((large_negative + (-kOneSecond)).IsMin());
|
||||
EXPECT_TRUE((large_negative - kOneSecond).IsMin());
|
||||
EXPECT_TRUE((large_delta - (-kOneSecond)).IsMax());
|
||||
EXPECT_TRUE((large_delta * 2).IsMax());
|
||||
EXPECT_TRUE((large_delta * -2).IsMin());
|
||||
|
||||
// Test +=, -=, *= and /= operators.
|
||||
TimeDelta delta = large_delta;
|
||||
delta += kOneSecond;
|
||||
EXPECT_TRUE(delta.IsMax());
|
||||
delta = large_negative;
|
||||
delta += -kOneSecond;
|
||||
EXPECT_TRUE((delta).IsMin());
|
||||
|
||||
delta = large_negative;
|
||||
delta -= kOneSecond;
|
||||
EXPECT_TRUE((delta).IsMin());
|
||||
delta = large_delta;
|
||||
delta -= -kOneSecond;
|
||||
EXPECT_TRUE(delta.IsMax());
|
||||
|
||||
delta = large_delta;
|
||||
delta *= 2;
|
||||
EXPECT_TRUE(delta.IsMax());
|
||||
|
||||
// Test operations with Time and TimeTicks.
|
||||
EXPECT_TRUE((large_delta + Time::Now()).IsMax());
|
||||
EXPECT_TRUE((large_delta + TimeTicks::Now()).IsMax());
|
||||
EXPECT_TRUE((Time::Now() + large_delta).IsMax());
|
||||
EXPECT_TRUE((TimeTicks::Now() + large_delta).IsMax());
|
||||
|
||||
Time time_now = Time::Now();
|
||||
EXPECT_EQ(kOneSecond, (time_now + kOneSecond) - time_now);
|
||||
EXPECT_EQ(-kOneSecond, (time_now - kOneSecond) - time_now);
|
||||
|
||||
TimeTicks ticks_now = TimeTicks::Now();
|
||||
EXPECT_EQ(-kOneSecond, (ticks_now - kOneSecond) - ticks_now);
|
||||
EXPECT_EQ(kOneSecond, (ticks_now + kOneSecond) - ticks_now);
|
||||
}
|
||||
|
||||
TEST(TimeDelta, FromAndIn) {
|
||||
EXPECT_EQ(TimeDelta::FromDays(2), TimeDelta::FromHours(48));
|
||||
EXPECT_EQ(TimeDelta::FromHours(3), TimeDelta::FromMinutes(180));
|
||||
@ -54,6 +211,47 @@ TEST(TimeDelta, MachTimespec) {
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(Time, Max) {
|
||||
Time max = Time::Max();
|
||||
EXPECT_TRUE(max.IsMax());
|
||||
EXPECT_EQ(max, Time::Max());
|
||||
EXPECT_GT(max, Time::Now());
|
||||
EXPECT_GT(max, Time());
|
||||
}
|
||||
|
||||
TEST(Time, MaxConversions) {
|
||||
Time t = Time::Max();
|
||||
EXPECT_EQ(std::numeric_limits<int64_t>::max(), t.ToInternalValue());
|
||||
|
||||
// TODO(v8-team): Time::FromJsTime() overflows with infinity. Import support
|
||||
// from Chromium's base.
|
||||
// t = Time::FromJsTime(std::numeric_limits<double>::infinity());
|
||||
// EXPECT_TRUE(t.IsMax());
|
||||
// EXPECT_EQ(std::numeric_limits<double>::infinity(), t.ToJsTime());
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
struct timeval tval;
|
||||
tval.tv_sec = std::numeric_limits<time_t>::max();
|
||||
tval.tv_usec = static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1;
|
||||
t = Time::FromTimeVal(tval);
|
||||
EXPECT_TRUE(t.IsMax());
|
||||
tval = t.ToTimeVal();
|
||||
EXPECT_EQ(std::numeric_limits<time_t>::max(), tval.tv_sec);
|
||||
EXPECT_EQ(static_cast<suseconds_t>(Time::kMicrosecondsPerSecond) - 1,
|
||||
tval.tv_usec);
|
||||
#endif
|
||||
|
||||
#if defined(OS_WIN)
|
||||
FILETIME ftime;
|
||||
ftime.dwHighDateTime = std::numeric_limits<DWORD>::max();
|
||||
ftime.dwLowDateTime = std::numeric_limits<DWORD>::max();
|
||||
t = Time::FromFileTime(ftime);
|
||||
EXPECT_TRUE(t.IsMax());
|
||||
ftime = t.ToFileTime();
|
||||
EXPECT_EQ(std::numeric_limits<DWORD>::max(), ftime.dwHighDateTime);
|
||||
EXPECT_EQ(std::numeric_limits<DWORD>::max(), ftime.dwLowDateTime);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Time, JsTime) {
|
||||
Time t = Time::FromJsTime(700000.3);
|
||||
|
Loading…
Reference in New Issue
Block a user