diff options
author | pechatnov <pechatnov@yandex-team.ru> | 2022-02-10 16:48:57 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:48:57 +0300 |
commit | 8e9b2f8bbf4a2320f539eef5b85555f42c065425 (patch) | |
tree | 189a13fe5128c85492e45518171a532ffa90ba03 /util/datetime | |
parent | 92040fb3ad117c48c87d591bf9fe916ffda61233 (diff) | |
download | ydb-8e9b2f8bbf4a2320f539eef5b85555f42c065425.tar.gz |
Restoring authorship annotation for <pechatnov@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'util/datetime')
-rw-r--r-- | util/datetime/base.h | 308 | ||||
-rw-r--r-- | util/datetime/base_ut.cpp | 240 |
2 files changed, 274 insertions, 274 deletions
diff --git a/util/datetime/base.h b/util/datetime/base.h index 5e902b8f63..a9c890ff3f 100644 --- a/util/datetime/base.h +++ b/util/datetime/base.h @@ -12,15 +12,15 @@ #include <util/generic/typetraits.h> #include <util/generic/yexception.h> -#include <chrono> - -#if defined(__cpp_lib_three_way_comparison) - #include <compare> -#endif - +#include <chrono> + +#if defined(__cpp_lib_three_way_comparison) + #include <compare> +#endif + #include <ctime> #include <cstdio> -#include <ratio> +#include <ratio> #include <time.h> @@ -213,49 +213,49 @@ public: { } - /** - * TDuration is compatible with std::chrono::duration: - * it can be constructed and compared with std::chrono::duration. - * But there is two significant and dangerous differencies between them: - * 1) TDuration is never negative and use saturation between 0 and maximum value. - * std::chrono::duration can be negative and can overflow. - * 2) TDuration uses integer number of microseconds. - * std::chrono::duration is flexible, can be integer of floating point, - * can have different precisions. - * So when casted from std::chrono::duration to TDuration value is clamped and rounded. - * In arithmethic operations std::chrono::duration argument is only rounded, - * result is TDuration and it clamped and rounded. - * In comparisons std::chrono::duration argument is rounded. - */ - template <typename T, typename TRatio> - constexpr TDuration(std::chrono::duration<T, TRatio> duration) noexcept { - static_assert( - std::ratio_greater_equal<TRatio, std::micro>::value && - (!std::is_floating_point<T>::value || std::ratio_greater<TRatio, std::micro>::value), - "Extremely likely it is loss of precision, because TDuration stores microseconds. " - "Cast you duration explicitly to microseconds if you really need it."); - - if (duration.count() < 0) { - *this = TDuration::Zero(); // clamp from the bottom - } else { - if -#if !defined(__NVCC__) - constexpr -#endif - /* if [constexpr] */ (std::ratio_greater<TRatio, std::micro>::value || std::is_floating_point<T>::value) { - // clamp from the top - using TCommonDuration = std::chrono::duration<typename std::common_type<T, TValue>::type, TRatio>; - constexpr auto maxDuration = std::chrono::duration<TValue, std::micro>(::Max<TValue>()); - if (std::chrono::duration_cast<TCommonDuration>(duration) >= std::chrono::duration_cast<TCommonDuration>(maxDuration)) { - *this = TDuration::Max(); - return; - } - } - const TValue us = std::chrono::duration_cast<std::chrono::duration<TValue, std::micro>>(duration).count(); - *this = TDuration::MicroSeconds(us); - } - } - + /** + * TDuration is compatible with std::chrono::duration: + * it can be constructed and compared with std::chrono::duration. + * But there is two significant and dangerous differencies between them: + * 1) TDuration is never negative and use saturation between 0 and maximum value. + * std::chrono::duration can be negative and can overflow. + * 2) TDuration uses integer number of microseconds. + * std::chrono::duration is flexible, can be integer of floating point, + * can have different precisions. + * So when casted from std::chrono::duration to TDuration value is clamped and rounded. + * In arithmethic operations std::chrono::duration argument is only rounded, + * result is TDuration and it clamped and rounded. + * In comparisons std::chrono::duration argument is rounded. + */ + template <typename T, typename TRatio> + constexpr TDuration(std::chrono::duration<T, TRatio> duration) noexcept { + static_assert( + std::ratio_greater_equal<TRatio, std::micro>::value && + (!std::is_floating_point<T>::value || std::ratio_greater<TRatio, std::micro>::value), + "Extremely likely it is loss of precision, because TDuration stores microseconds. " + "Cast you duration explicitly to microseconds if you really need it."); + + if (duration.count() < 0) { + *this = TDuration::Zero(); // clamp from the bottom + } else { + if +#if !defined(__NVCC__) + constexpr +#endif + /* if [constexpr] */ (std::ratio_greater<TRatio, std::micro>::value || std::is_floating_point<T>::value) { + // clamp from the top + using TCommonDuration = std::chrono::duration<typename std::common_type<T, TValue>::type, TRatio>; + constexpr auto maxDuration = std::chrono::duration<TValue, std::micro>(::Max<TValue>()); + if (std::chrono::duration_cast<TCommonDuration>(duration) >= std::chrono::duration_cast<TCommonDuration>(maxDuration)) { + *this = TDuration::Max(); + return; + } + } + const TValue us = std::chrono::duration_cast<std::chrono::duration<TValue, std::micro>>(duration).count(); + *this = TDuration::MicroSeconds(us); + } + } + static constexpr TDuration FromValue(TValue value) noexcept { return TDuration(value); } @@ -667,110 +667,110 @@ constexpr TDuration operator+(const TDuration& l, const TDuration& r) noexcept { return TDuration::FromValue(::NDateTimeHelpers::SumWithSaturation(l.GetValue(), r.GetValue())); } -template <typename T, typename TRatio> -constexpr bool operator==(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { - return r.count() >= 0 && l == TDuration(r); -} - -#if defined(__cpp_lib_three_way_comparison) - -template <typename T, typename TRatio> -constexpr std::strong_ordering operator<=>(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { - if (r.count() < 0) { - return std::strong_ordering::greater; - } - return l.GetValue() <=> TDuration(r).GetValue(); -} - -#else - -template <typename T, typename TRatio> -constexpr bool operator<(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { - return r.count() >= 0 && l < TDuration(r); -} - -template <typename T, typename TRatio> -constexpr bool operator<=(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { - return r.count() >= 0 && l <= TDuration(r); -} - -template <typename T, typename TRatio> -constexpr bool operator!=(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { - return !(l == r); -} - -template <typename T, typename TRatio> -constexpr bool operator>(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { - return r.count() < 0 || l > TDuration(r); -} - -template <typename T, typename TRatio> -constexpr bool operator>=(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { - return r.count() < 0 || l >= TDuration(r); -} - -template <typename T, typename TRatio> -constexpr bool operator<(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept { - return r > l; -} - -template <typename T, typename TRatio> -constexpr bool operator<=(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept { - return r >= l; -} - -template <typename T, typename TRatio> -constexpr bool operator==(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept { - return r == l; -} - -template <typename T, typename TRatio> -constexpr bool operator!=(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept { - return r != l; -} - -template <typename T, typename TRatio> -constexpr bool operator>(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept { - return r < l; -} - -template <typename T, typename TRatio> -constexpr bool operator>=(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept { - return r >= l; -} - -#endif - -template <typename T, typename TRatio> -constexpr TDuration operator+(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { - return r < r.zero() ? l - TDuration(-r) : l + TDuration(r); -} - -template <typename T, typename TRatio> -constexpr TDuration operator+(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept { - return r + l; -} - -template <typename T, typename TRatio> -constexpr TDuration operator-(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { - return l + (-r); -} - -template <typename T, typename TRatio> -constexpr TDuration operator-(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept { - return TDuration(l) - r; -} - -template <typename T, typename TRatio> -constexpr TInstant operator+(const TInstant& l, const std::chrono::duration<T, TRatio>& r) noexcept { - return r < r.zero() ? l - TDuration(-r) : l + TDuration(r); -} - -template <typename T, typename TRatio> -constexpr TInstant operator-(const TInstant& l, const std::chrono::duration<T, TRatio>& r) noexcept { - return l + (-r); -} - +template <typename T, typename TRatio> +constexpr bool operator==(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { + return r.count() >= 0 && l == TDuration(r); +} + +#if defined(__cpp_lib_three_way_comparison) + +template <typename T, typename TRatio> +constexpr std::strong_ordering operator<=>(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { + if (r.count() < 0) { + return std::strong_ordering::greater; + } + return l.GetValue() <=> TDuration(r).GetValue(); +} + +#else + +template <typename T, typename TRatio> +constexpr bool operator<(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { + return r.count() >= 0 && l < TDuration(r); +} + +template <typename T, typename TRatio> +constexpr bool operator<=(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { + return r.count() >= 0 && l <= TDuration(r); +} + +template <typename T, typename TRatio> +constexpr bool operator!=(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { + return !(l == r); +} + +template <typename T, typename TRatio> +constexpr bool operator>(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { + return r.count() < 0 || l > TDuration(r); +} + +template <typename T, typename TRatio> +constexpr bool operator>=(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { + return r.count() < 0 || l >= TDuration(r); +} + +template <typename T, typename TRatio> +constexpr bool operator<(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept { + return r > l; +} + +template <typename T, typename TRatio> +constexpr bool operator<=(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept { + return r >= l; +} + +template <typename T, typename TRatio> +constexpr bool operator==(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept { + return r == l; +} + +template <typename T, typename TRatio> +constexpr bool operator!=(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept { + return r != l; +} + +template <typename T, typename TRatio> +constexpr bool operator>(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept { + return r < l; +} + +template <typename T, typename TRatio> +constexpr bool operator>=(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept { + return r >= l; +} + +#endif + +template <typename T, typename TRatio> +constexpr TDuration operator+(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { + return r < r.zero() ? l - TDuration(-r) : l + TDuration(r); +} + +template <typename T, typename TRatio> +constexpr TDuration operator+(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept { + return r + l; +} + +template <typename T, typename TRatio> +constexpr TDuration operator-(const TDuration& l, const std::chrono::duration<T, TRatio>& r) noexcept { + return l + (-r); +} + +template <typename T, typename TRatio> +constexpr TDuration operator-(const std::chrono::duration<T, TRatio>& l, const TDuration& r) noexcept { + return TDuration(l) - r; +} + +template <typename T, typename TRatio> +constexpr TInstant operator+(const TInstant& l, const std::chrono::duration<T, TRatio>& r) noexcept { + return r < r.zero() ? l - TDuration(-r) : l + TDuration(r); +} + +template <typename T, typename TRatio> +constexpr TInstant operator-(const TInstant& l, const std::chrono::duration<T, TRatio>& r) noexcept { + return l + (-r); +} + template <class T> inline TDuration operator*(TDuration d, T t) noexcept { Y_ASSERT(t >= T()); diff --git a/util/datetime/base_ut.cpp b/util/datetime/base_ut.cpp index afc3f802eb..8a7e6976b6 100644 --- a/util/datetime/base_ut.cpp +++ b/util/datetime/base_ut.cpp @@ -12,8 +12,8 @@ #include <limits.h> -using namespace std::chrono_literals; - +using namespace std::chrono_literals; + struct TTestTime { const time_t T_ = 987654321; const char* Date_ = "Thu Apr 19 04:25:21 2001\n"; @@ -530,125 +530,125 @@ Y_UNIT_TEST_SUITE(DateTimeTest) { "incorrect date " << (1900 + time.tm_year) << "-" << (time.tm_mon + 1) << "-" << time.tm_mday); } } - - Y_UNIT_TEST(TestTDurationConstructorFromStdChronoDuration) { - - UNIT_ASSERT_VALUES_EQUAL(TDuration::Zero(), TDuration(0ms)); - UNIT_ASSERT_VALUES_EQUAL(TDuration::MicroSeconds(42), TDuration(42us)); - UNIT_ASSERT_VALUES_EQUAL(TDuration::MicroSeconds(42000000000000L), TDuration(42000000000000us)); - UNIT_ASSERT_VALUES_EQUAL(TDuration::MilliSeconds(42), TDuration(42ms)); - UNIT_ASSERT_VALUES_EQUAL(TDuration::MilliSeconds(42.75), TDuration(42.75ms)); - UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(42), TDuration(42s)); - UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(42.25), TDuration(42.25s)); - UNIT_ASSERT_VALUES_EQUAL(TDuration::Minutes(42), TDuration(42min)); - UNIT_ASSERT_VALUES_EQUAL(TDuration::Hours(42), TDuration(42h)); - - // TDuration doesn't support negative durations - UNIT_ASSERT_VALUES_EQUAL(TDuration::Zero(), TDuration(-5min)); - - UNIT_ASSERT_VALUES_EQUAL(TDuration::MilliSeconds(5), TDuration(std::chrono::duration<i8, std::milli>{5ms})); - + + Y_UNIT_TEST(TestTDurationConstructorFromStdChronoDuration) { + + UNIT_ASSERT_VALUES_EQUAL(TDuration::Zero(), TDuration(0ms)); + UNIT_ASSERT_VALUES_EQUAL(TDuration::MicroSeconds(42), TDuration(42us)); + UNIT_ASSERT_VALUES_EQUAL(TDuration::MicroSeconds(42000000000000L), TDuration(42000000000000us)); + UNIT_ASSERT_VALUES_EQUAL(TDuration::MilliSeconds(42), TDuration(42ms)); + UNIT_ASSERT_VALUES_EQUAL(TDuration::MilliSeconds(42.75), TDuration(42.75ms)); + UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(42), TDuration(42s)); + UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(42.25), TDuration(42.25s)); + UNIT_ASSERT_VALUES_EQUAL(TDuration::Minutes(42), TDuration(42min)); + UNIT_ASSERT_VALUES_EQUAL(TDuration::Hours(42), TDuration(42h)); + + // TDuration doesn't support negative durations + UNIT_ASSERT_VALUES_EQUAL(TDuration::Zero(), TDuration(-5min)); + + UNIT_ASSERT_VALUES_EQUAL(TDuration::MilliSeconds(5), TDuration(std::chrono::duration<i8, std::milli>{5ms})); + #if defined(_LIBCPP_STD_VER) && _LIBCPP_STD_VER > 17 // libstdc++ does not provide std::chrono::days at the time // Consider removing this code upon OS_SDK update - UNIT_ASSERT_VALUES_EQUAL(TDuration::Days(1), TDuration(std::chrono::days{1})); -#endif - - // clump - UNIT_ASSERT_VALUES_EQUAL(TDuration::Zero(), TDuration(std::chrono::duration<i64>{-1})); - UNIT_ASSERT_VALUES_EQUAL(TDuration::Zero(), TDuration(std::chrono::duration<double>{-1})); - UNIT_ASSERT_VALUES_EQUAL(TDuration::Max(), - TDuration(std::chrono::duration<ui64, std::ratio<3600>>{static_cast<ui64>(1e18)})); - UNIT_ASSERT_VALUES_EQUAL(TDuration::Max(), - TDuration(std::chrono::duration<i64, std::milli>{static_cast<i64>(::Max<ui64>() / 1000)})); - UNIT_ASSERT_VALUES_EQUAL(TDuration::Max(), - TDuration(std::chrono::duration<double, std::ratio<3600>>{1e18})); - UNIT_ASSERT_VALUES_EQUAL(TDuration::Max(), - TDuration(std::chrono::duration<double, std::milli>{::Max<ui64>() / 1000})); - UNIT_ASSERT_VALUES_EQUAL(TDuration::Max(), TDuration(std::chrono::duration<double, std::milli>{ - static_cast<double>(::Max<ui64>()) / 1000 + 0.1})); - UNIT_ASSERT_VALUES_EQUAL(TDuration::Max(), TDuration(std::chrono::duration<float, std::milli>{ - static_cast<float>(::Max<ui64>()) / 1000 + 0.1})); - } - - Y_UNIT_TEST(TestTDurationCompareWithStdChronoDuration) { - UNIT_ASSERT(TDuration::Zero() == 0ms); - UNIT_ASSERT(TDuration::Seconds(42) == 42s); - - UNIT_ASSERT(0ms == TDuration::Zero()); - - UNIT_ASSERT(TDuration::Zero() != 1ms); - UNIT_ASSERT(TDuration::Zero() != -1ms); - UNIT_ASSERT(TDuration::MilliSeconds(1) != -1ms); - UNIT_ASSERT(TDuration::MilliSeconds(1) != -1ms); - - UNIT_ASSERT(1ms != TDuration::Zero()); - - UNIT_ASSERT(TDuration::Seconds(2) < 3s); - UNIT_ASSERT(3s > TDuration::Seconds(2)); - UNIT_ASSERT(!(TDuration::Seconds(2) < 1s)); - UNIT_ASSERT(!(TDuration::Seconds(2) < -3s)); - UNIT_ASSERT(!(TDuration::Seconds(2) < 2s)); - - UNIT_ASSERT(2s < TDuration::Seconds(3)); - - UNIT_ASSERT(TDuration::Seconds(2) <= 3s); - UNIT_ASSERT(!(TDuration::Seconds(2) <= 1s)); - UNIT_ASSERT(!(TDuration::Seconds(2) <= -3s)); - UNIT_ASSERT(TDuration::Seconds(2) <= 2s); - - UNIT_ASSERT(2s <= TDuration::Seconds(2)); - - UNIT_ASSERT(TDuration::Seconds(2) > -2s); - UNIT_ASSERT(TDuration::Seconds(2) > 1s); - UNIT_ASSERT(TDuration::Seconds(2) > 0s); - UNIT_ASSERT(!(TDuration::Seconds(2) > 3s)); - UNIT_ASSERT(!(TDuration::Seconds(2) > 2s)); - - UNIT_ASSERT(2s > TDuration::Seconds(1)); - - UNIT_ASSERT(TDuration::Seconds(2) >= -2s); - UNIT_ASSERT(TDuration::Seconds(2) >= 1s); - UNIT_ASSERT(TDuration::Seconds(2) >= 0s); - UNIT_ASSERT(!(TDuration::Seconds(2) >= 3s)); - UNIT_ASSERT(TDuration::Seconds(2) >= 2s); - - UNIT_ASSERT(2s >= TDuration::Seconds(2)); - - static_assert(TDuration::Zero() == 0ms); - static_assert(TDuration::Zero() < 1ms); - } - - Y_UNIT_TEST(TestAdditionOfStdChronoDuration) { - UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(1) + 2s, TDuration::Seconds(3)); - UNIT_ASSERT_VALUES_EQUAL(2s + TDuration::Seconds(1), TDuration::Seconds(3)); - UNIT_ASSERT_VALUES_EQUAL(-2s + TDuration::Seconds(3), TDuration::Seconds(1)); - UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(3) + (-2s), TDuration::Seconds(1)); - UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(3) - 2s, TDuration::Seconds(1)); - UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(1) - (-2s), TDuration::Seconds(3)); - UNIT_ASSERT_VALUES_EQUAL(3s - TDuration::Seconds(2), TDuration::Seconds(1)); - UNIT_ASSERT_VALUES_EQUAL(3s - TDuration::Seconds(4), TDuration::Zero()); - - UNIT_ASSERT_VALUES_EQUAL(TInstant::Seconds(1) + 2s, TInstant::Seconds(3)); - UNIT_ASSERT_VALUES_EQUAL(TInstant::Seconds(3) + (-2s), TInstant::Seconds(1)); - UNIT_ASSERT_VALUES_EQUAL(TInstant::Seconds(3) - 2s, TInstant::Seconds(1)); - UNIT_ASSERT_VALUES_EQUAL(TInstant::Seconds(1) - (-2s), TInstant::Seconds(3)); - - // Operations between TDuration/TInstant and std::chrono::duration are performed - // with saturation according to the rules of TDuration/TInstant - UNIT_ASSERT_VALUES_EQUAL(TDuration::Max() + 1h, TDuration::Max()); - UNIT_ASSERT_VALUES_EQUAL(TInstant::Max() + 1h, TInstant::Max()); - UNIT_ASSERT_VALUES_EQUAL(1h + TDuration::Max(), TDuration::Max()); - UNIT_ASSERT_VALUES_EQUAL(TInstant::Max() + 1h, TInstant::Max()); - - UNIT_ASSERT_VALUES_EQUAL(TDuration::Max() - (-1h), TDuration::Max()); - UNIT_ASSERT_VALUES_EQUAL(TInstant::Max() - (-1h), TInstant::Max()); - UNIT_ASSERT_VALUES_EQUAL(TInstant::Max() - (-1h), TInstant::Max()); - - UNIT_ASSERT_VALUES_EQUAL(-1h - TDuration::Max(), TDuration::Zero()); - UNIT_ASSERT_VALUES_EQUAL(1h - TDuration::Max(), TDuration::Zero()); - - static_assert(TDuration::Zero() + 1s == 1s); - static_assert(TInstant::Seconds(1) + 1s == TInstant::Seconds(2)); - } + UNIT_ASSERT_VALUES_EQUAL(TDuration::Days(1), TDuration(std::chrono::days{1})); +#endif + + // clump + UNIT_ASSERT_VALUES_EQUAL(TDuration::Zero(), TDuration(std::chrono::duration<i64>{-1})); + UNIT_ASSERT_VALUES_EQUAL(TDuration::Zero(), TDuration(std::chrono::duration<double>{-1})); + UNIT_ASSERT_VALUES_EQUAL(TDuration::Max(), + TDuration(std::chrono::duration<ui64, std::ratio<3600>>{static_cast<ui64>(1e18)})); + UNIT_ASSERT_VALUES_EQUAL(TDuration::Max(), + TDuration(std::chrono::duration<i64, std::milli>{static_cast<i64>(::Max<ui64>() / 1000)})); + UNIT_ASSERT_VALUES_EQUAL(TDuration::Max(), + TDuration(std::chrono::duration<double, std::ratio<3600>>{1e18})); + UNIT_ASSERT_VALUES_EQUAL(TDuration::Max(), + TDuration(std::chrono::duration<double, std::milli>{::Max<ui64>() / 1000})); + UNIT_ASSERT_VALUES_EQUAL(TDuration::Max(), TDuration(std::chrono::duration<double, std::milli>{ + static_cast<double>(::Max<ui64>()) / 1000 + 0.1})); + UNIT_ASSERT_VALUES_EQUAL(TDuration::Max(), TDuration(std::chrono::duration<float, std::milli>{ + static_cast<float>(::Max<ui64>()) / 1000 + 0.1})); + } + + Y_UNIT_TEST(TestTDurationCompareWithStdChronoDuration) { + UNIT_ASSERT(TDuration::Zero() == 0ms); + UNIT_ASSERT(TDuration::Seconds(42) == 42s); + + UNIT_ASSERT(0ms == TDuration::Zero()); + + UNIT_ASSERT(TDuration::Zero() != 1ms); + UNIT_ASSERT(TDuration::Zero() != -1ms); + UNIT_ASSERT(TDuration::MilliSeconds(1) != -1ms); + UNIT_ASSERT(TDuration::MilliSeconds(1) != -1ms); + + UNIT_ASSERT(1ms != TDuration::Zero()); + + UNIT_ASSERT(TDuration::Seconds(2) < 3s); + UNIT_ASSERT(3s > TDuration::Seconds(2)); + UNIT_ASSERT(!(TDuration::Seconds(2) < 1s)); + UNIT_ASSERT(!(TDuration::Seconds(2) < -3s)); + UNIT_ASSERT(!(TDuration::Seconds(2) < 2s)); + + UNIT_ASSERT(2s < TDuration::Seconds(3)); + + UNIT_ASSERT(TDuration::Seconds(2) <= 3s); + UNIT_ASSERT(!(TDuration::Seconds(2) <= 1s)); + UNIT_ASSERT(!(TDuration::Seconds(2) <= -3s)); + UNIT_ASSERT(TDuration::Seconds(2) <= 2s); + + UNIT_ASSERT(2s <= TDuration::Seconds(2)); + + UNIT_ASSERT(TDuration::Seconds(2) > -2s); + UNIT_ASSERT(TDuration::Seconds(2) > 1s); + UNIT_ASSERT(TDuration::Seconds(2) > 0s); + UNIT_ASSERT(!(TDuration::Seconds(2) > 3s)); + UNIT_ASSERT(!(TDuration::Seconds(2) > 2s)); + + UNIT_ASSERT(2s > TDuration::Seconds(1)); + + UNIT_ASSERT(TDuration::Seconds(2) >= -2s); + UNIT_ASSERT(TDuration::Seconds(2) >= 1s); + UNIT_ASSERT(TDuration::Seconds(2) >= 0s); + UNIT_ASSERT(!(TDuration::Seconds(2) >= 3s)); + UNIT_ASSERT(TDuration::Seconds(2) >= 2s); + + UNIT_ASSERT(2s >= TDuration::Seconds(2)); + + static_assert(TDuration::Zero() == 0ms); + static_assert(TDuration::Zero() < 1ms); + } + + Y_UNIT_TEST(TestAdditionOfStdChronoDuration) { + UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(1) + 2s, TDuration::Seconds(3)); + UNIT_ASSERT_VALUES_EQUAL(2s + TDuration::Seconds(1), TDuration::Seconds(3)); + UNIT_ASSERT_VALUES_EQUAL(-2s + TDuration::Seconds(3), TDuration::Seconds(1)); + UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(3) + (-2s), TDuration::Seconds(1)); + UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(3) - 2s, TDuration::Seconds(1)); + UNIT_ASSERT_VALUES_EQUAL(TDuration::Seconds(1) - (-2s), TDuration::Seconds(3)); + UNIT_ASSERT_VALUES_EQUAL(3s - TDuration::Seconds(2), TDuration::Seconds(1)); + UNIT_ASSERT_VALUES_EQUAL(3s - TDuration::Seconds(4), TDuration::Zero()); + + UNIT_ASSERT_VALUES_EQUAL(TInstant::Seconds(1) + 2s, TInstant::Seconds(3)); + UNIT_ASSERT_VALUES_EQUAL(TInstant::Seconds(3) + (-2s), TInstant::Seconds(1)); + UNIT_ASSERT_VALUES_EQUAL(TInstant::Seconds(3) - 2s, TInstant::Seconds(1)); + UNIT_ASSERT_VALUES_EQUAL(TInstant::Seconds(1) - (-2s), TInstant::Seconds(3)); + + // Operations between TDuration/TInstant and std::chrono::duration are performed + // with saturation according to the rules of TDuration/TInstant + UNIT_ASSERT_VALUES_EQUAL(TDuration::Max() + 1h, TDuration::Max()); + UNIT_ASSERT_VALUES_EQUAL(TInstant::Max() + 1h, TInstant::Max()); + UNIT_ASSERT_VALUES_EQUAL(1h + TDuration::Max(), TDuration::Max()); + UNIT_ASSERT_VALUES_EQUAL(TInstant::Max() + 1h, TInstant::Max()); + + UNIT_ASSERT_VALUES_EQUAL(TDuration::Max() - (-1h), TDuration::Max()); + UNIT_ASSERT_VALUES_EQUAL(TInstant::Max() - (-1h), TInstant::Max()); + UNIT_ASSERT_VALUES_EQUAL(TInstant::Max() - (-1h), TInstant::Max()); + + UNIT_ASSERT_VALUES_EQUAL(-1h - TDuration::Max(), TDuration::Zero()); + UNIT_ASSERT_VALUES_EQUAL(1h - TDuration::Max(), TDuration::Zero()); + + static_assert(TDuration::Zero() + 1s == 1s); + static_assert(TInstant::Seconds(1) + 1s == TInstant::Seconds(2)); + } } |