diff --git a/xpcom/ds/TimeStamp.h b/xpcom/ds/TimeStamp.h index 8e6430b0f8c0b..6218c5f391841 100644 --- a/xpcom/ds/TimeStamp.h +++ b/xpcom/ds/TimeStamp.h @@ -11,6 +11,7 @@ #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/FloatingPoint.h" +#include "mozilla/TypeTraits.h" #include "nscore.h" #include "nsDebug.h" @@ -143,20 +144,20 @@ class BaseTimeDuration BaseTimeDuration operator+(const BaseTimeDuration& aOther) const { - return FromTicks(mValue + aOther.mValue); + return FromTicks(ValueCalculator::Add(mValue, aOther.mValue)); } BaseTimeDuration operator-(const BaseTimeDuration& aOther) const { - return FromTicks(mValue - aOther.mValue); + return FromTicks(ValueCalculator::Subtract(mValue, aOther.mValue)); } BaseTimeDuration& operator+=(const BaseTimeDuration& aOther) { - mValue += aOther.mValue; + mValue = ValueCalculator::Add(mValue, aOther.mValue); return *this; } BaseTimeDuration& operator-=(const BaseTimeDuration& aOther) { - mValue -= aOther.mValue; + mValue = ValueCalculator::Subtract(mValue, aOther.mValue); return *this; } @@ -168,19 +169,19 @@ class BaseTimeDuration public: BaseTimeDuration MultDouble(double aMultiplier) const { - return FromTicks(static_cast(mValue * aMultiplier)); + return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); } BaseTimeDuration operator*(const int32_t aMultiplier) const { - return FromTicks(mValue * int64_t(aMultiplier)); + return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); } BaseTimeDuration operator*(const uint32_t aMultiplier) const { - return FromTicks(mValue * int64_t(aMultiplier)); + return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); } BaseTimeDuration operator*(const int64_t aMultiplier) const { - return FromTicks(mValue * aMultiplier); + return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); } BaseTimeDuration operator*(const uint64_t aMultiplier) const { @@ -188,20 +189,25 @@ class BaseTimeDuration NS_WARNING("Out-of-range multiplier when multiplying BaseTimeDuration"); return Forever(); } - return FromTicks(mValue * int64_t(aMultiplier)); + return FromTicks(ValueCalculator::Multiply(mValue, aMultiplier)); } BaseTimeDuration operator/(const int64_t aDivisor) const { - return FromTicks(mValue / aDivisor); + MOZ_ASSERT(aDivisor != 0, "Division by zero"); + return FromTicks(ValueCalculator::Divide(mValue, aDivisor)); } double operator/(const BaseTimeDuration& aOther) const { - return static_cast(mValue) / aOther.mValue; +#ifndef MOZ_B2G + // Bug 1066388 - This fails on B2G ICS Emulator + MOZ_ASSERT(aOther.mValue != 0, "Division by zero"); +#endif + return ValueCalculator::DivideDouble(mValue, aOther.mValue); } BaseTimeDuration operator%(const BaseTimeDuration& aOther) const { MOZ_ASSERT(aOther.mValue != 0, "Division by zero"); - return FromTicks(mValue % aOther.mValue); + return FromTicks(ValueCalculator::Modulo(mValue, aOther.mValue)); } template @@ -283,10 +289,48 @@ class BaseTimeDuration int64_t mValue; }; -// FIXME: To be filled-in a subsequent patch in this series. +/** + * Perform arithmetic operations on the value of a BaseTimeDuration without + * doing strict checks on the range of values. + */ class TimeDurationValueCalculator -{ }; +{ +public: + static int64_t Add(int64_t aA, int64_t aB) { return aA + aB; } + static int64_t Subtract(int64_t aA, int64_t aB) { return aA - aB; } + + template + static int64_t Multiply(int64_t aA, T aB) + { + static_assert(IsIntegral::value, + "Using integer multiplication routine with non-integer type." + " Further specialization required"); + return aA * static_cast(aB); + } + static int64_t Divide(int64_t aA, int64_t aB) { return aA / aB; } + static double DivideDouble(int64_t aA, int64_t aB) + { + return static_cast(aA) / aB; + } + static int64_t Modulo(int64_t aA, int64_t aB) { return aA % aB; } +}; + +template <> +inline int64_t +TimeDurationValueCalculator::Multiply(int64_t aA, double aB) +{ + return static_cast(aA * aB); +} + +/** + * Specialization of BaseTimeDuration that uses TimeDurationValueCalculator for + * arithmetic on the mValue member. + * + * Use this class for time durations that are *not* expected to hold values of + * Forever (or the negative equivalent) or when such time duration are *not* + * expected to be used in arithmetic operations. + */ typedef BaseTimeDuration TimeDuration; /**