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 | |
parent | 92040fb3ad117c48c87d591bf9fe916ffda61233 (diff) | |
download | ydb-8e9b2f8bbf4a2320f539eef5b85555f42c065425.tar.gz |
Restoring authorship annotation for <pechatnov@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'util')
-rw-r--r-- | util/datetime/base.h | 308 | ||||
-rw-r--r-- | util/datetime/base_ut.cpp | 240 | ||||
-rw-r--r-- | util/generic/adaptor.h | 70 | ||||
-rw-r--r-- | util/generic/adaptor_ut.cpp | 100 | ||||
-rw-r--r-- | util/generic/algorithm.h | 30 | ||||
-rw-r--r-- | util/generic/algorithm_ut.cpp | 10 | ||||
-rw-r--r-- | util/generic/iterator_range.h | 106 | ||||
-rw-r--r-- | util/generic/iterator_range_ut.cpp | 86 | ||||
-rw-r--r-- | util/generic/store_policy.h | 68 | ||||
-rw-r--r-- | util/generic/store_policy_ut.cpp | 162 | ||||
-rw-r--r-- | util/generic/ut/ya.make | 2 | ||||
-rw-r--r-- | util/generic/xrange.h | 6 | ||||
-rw-r--r-- | util/str_stl.h | 6 |
13 files changed, 597 insertions, 597 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)); + } } diff --git a/util/generic/adaptor.h b/util/generic/adaptor.h index b88a65fc81..b89c1f81e5 100644 --- a/util/generic/adaptor.h +++ b/util/generic/adaptor.h @@ -1,6 +1,6 @@ #pragma once -#include "store_policy.h" +#include "store_policy.h" #include "typetraits.h" namespace NPrivate { @@ -42,23 +42,23 @@ namespace NPrivate { using TBase::Base; using TBase::TBase; - auto begin() const { + auto begin() const { return Base().rbegin(); } - auto end() const { + auto end() const { return Base().rend(); - } - - auto begin() { + } + + auto begin() { return Base().rbegin(); - } - - auto end() { + } + + auto end() { return Base().rend(); - } - }; - + } + }; + template <class Range> class TReverseRangeBase<Range, false>: public TReverseRangeStorage<Range> { using TBase = TReverseRangeStorage<Range>; @@ -68,26 +68,26 @@ namespace NPrivate { using TBase::TBase; auto begin() const { - using std::end; + using std::end; return std::make_reverse_iterator(end(Base())); } auto end() const { - using std::begin; + using std::begin; return std::make_reverse_iterator(begin(Base())); } auto begin() { - using std::end; + using std::end; return std::make_reverse_iterator(end(Base())); } auto end() { - using std::begin; + using std::begin; return std::make_reverse_iterator(begin(Base())); } }; - + template <class Range> class TReverseRange: public TReverseRangeBase<Range> { using TBase = TReverseRangeBase<Range>; @@ -95,30 +95,30 @@ namespace NPrivate { public: using TBase::Base; using TBase::TBase; - + TReverseRange(TReverseRange&&) = default; TReverseRange(const TReverseRange&) = default; - - auto rbegin() const { - using std::begin; + + auto rbegin() const { + using std::begin; return begin(Base()); - } - - auto rend() const { - using std::end; + } + + auto rend() const { + using std::end; return end(Base()); - } - - auto rbegin() { - using std::begin; + } + + auto rbegin() { + using std::begin; return begin(Base()); - } - - auto rend() { - using std::end; + } + + auto rend() { + using std::end; return end(Base()); - } - }; + } + }; } /** diff --git a/util/generic/adaptor_ut.cpp b/util/generic/adaptor_ut.cpp index 721f849f93..ff980632b4 100644 --- a/util/generic/adaptor_ut.cpp +++ b/util/generic/adaptor_ut.cpp @@ -40,10 +40,10 @@ Y_UNIT_TEST_SUITE(TReverseAdaptor) { for (const auto& x : Reversed(cont)) { UNIT_ASSERT_VALUES_EQUAL(etalon[idx++], x); } - idx = 0; - for (const auto& x : Reversed(std::move(cont))) { - UNIT_ASSERT_VALUES_EQUAL(etalon[idx++], x); - } + idx = 0; + for (const auto& x : Reversed(std::move(cont))) { + UNIT_ASSERT_VALUES_EQUAL(etalon[idx++], x); + } } Y_UNIT_TEST(WriteTest) { @@ -75,50 +75,50 @@ Y_UNIT_TEST_SUITE(TReverseAdaptor) { UNIT_ASSERT_NO_EXCEPTION(Reversed(lvalue)); UNIT_ASSERT_NO_EXCEPTION(Reversed(clvalue)); } - - Y_UNIT_TEST(ReverseX2Test) { - TVector<int> cont = {1, 2, 3}; - size_t idx = 0; - for (const auto& x : Reversed(Reversed(cont))) { - UNIT_ASSERT_VALUES_EQUAL(cont[idx++], x); - } - } - - Y_UNIT_TEST(ReverseX3Test) { - TVector<int> cont = {1, 2, 3}; - TVector<int> etalon = {3, 2, 1}; - size_t idx = 0; - for (const auto& x : Reversed(Reversed(Reversed(cont)))) { - UNIT_ASSERT_VALUES_EQUAL(etalon[idx++], x); - } - } - - Y_UNIT_TEST(ReverseTemporaryTest) { - TVector<int> etalon = {3, 2, 1}; - TVector<int> etalon2 = {1, 2, 3}; - size_t idx = 0; - for (const auto& x : Reversed(TVector<int>{1, 2, 3})) { - UNIT_ASSERT_VALUES_EQUAL(etalon[idx++], x); - } - idx = 0; - for (const auto& x : Reversed(Reversed(TVector<int>{1, 2, 3}))) { - UNIT_ASSERT_VALUES_EQUAL(etalon2[idx++], x); - } - } - - Y_UNIT_TEST(ReverseInitializerListTest) { - // initializer_list has no rbegin and rend - auto cont = {1, 2, 3}; - TVector<int> etalon = {3, 2, 1}; - TVector<int> etalon2 = {1, 2, 3}; - - size_t idx = 0; - for (const auto& x : Reversed(cont)) { - UNIT_ASSERT_VALUES_EQUAL(etalon[idx++], x); - } - idx = 0; - for (const auto& x : Reversed(Reversed(cont))) { - UNIT_ASSERT_VALUES_EQUAL(etalon2[idx++], x); - } - } + + Y_UNIT_TEST(ReverseX2Test) { + TVector<int> cont = {1, 2, 3}; + size_t idx = 0; + for (const auto& x : Reversed(Reversed(cont))) { + UNIT_ASSERT_VALUES_EQUAL(cont[idx++], x); + } + } + + Y_UNIT_TEST(ReverseX3Test) { + TVector<int> cont = {1, 2, 3}; + TVector<int> etalon = {3, 2, 1}; + size_t idx = 0; + for (const auto& x : Reversed(Reversed(Reversed(cont)))) { + UNIT_ASSERT_VALUES_EQUAL(etalon[idx++], x); + } + } + + Y_UNIT_TEST(ReverseTemporaryTest) { + TVector<int> etalon = {3, 2, 1}; + TVector<int> etalon2 = {1, 2, 3}; + size_t idx = 0; + for (const auto& x : Reversed(TVector<int>{1, 2, 3})) { + UNIT_ASSERT_VALUES_EQUAL(etalon[idx++], x); + } + idx = 0; + for (const auto& x : Reversed(Reversed(TVector<int>{1, 2, 3}))) { + UNIT_ASSERT_VALUES_EQUAL(etalon2[idx++], x); + } + } + + Y_UNIT_TEST(ReverseInitializerListTest) { + // initializer_list has no rbegin and rend + auto cont = {1, 2, 3}; + TVector<int> etalon = {3, 2, 1}; + TVector<int> etalon2 = {1, 2, 3}; + + size_t idx = 0; + for (const auto& x : Reversed(cont)) { + UNIT_ASSERT_VALUES_EQUAL(etalon[idx++], x); + } + idx = 0; + for (const auto& x : Reversed(Reversed(cont))) { + UNIT_ASSERT_VALUES_EQUAL(etalon2[idx++], x); + } + } } diff --git a/util/generic/algorithm.h b/util/generic/algorithm.h index badfb88993..d183d4ab00 100644 --- a/util/generic/algorithm.h +++ b/util/generic/algorithm.h @@ -638,11 +638,11 @@ inline typename std::iterator_traits<T>::difference_type Count(T first, T last, return std::count(first, last, value); } -template <class TContainer, class TValue> -static inline auto Count(const TContainer& container, const TValue& value) { - return Count(std::cbegin(container), std::cend(container), value); -} - +template <class TContainer, class TValue> +static inline auto Count(const TContainer& container, const TValue& value) { + return Count(std::cbegin(container), std::cend(container), value); +} + template <class It, class P> static inline auto CountIf(It first, It last, P p) { return std::count_if(first, last, p); @@ -753,13 +753,13 @@ template <class It> std::pair<It, It> MinMaxElement(It first, It last) { return std::minmax_element(first, last); } - -template <class TIterator, class TGenerator> -void Generate(TIterator first, TIterator last, TGenerator generator) { - std::generate(first, last, generator); -} - -template <class TIterator, class TSize, class TGenerator> -void GenerateN(TIterator first, TSize count, TGenerator generator) { - std::generate_n(first, count, generator); -} + +template <class TIterator, class TGenerator> +void Generate(TIterator first, TIterator last, TGenerator generator) { + std::generate(first, last, generator); +} + +template <class TIterator, class TSize, class TGenerator> +void GenerateN(TIterator first, TSize count, TGenerator generator) { + std::generate_n(first, count, generator); +} diff --git a/util/generic/algorithm_ut.cpp b/util/generic/algorithm_ut.cpp index 8d732fcc0c..2473adb021 100644 --- a/util/generic/algorithm_ut.cpp +++ b/util/generic/algorithm_ut.cpp @@ -44,18 +44,18 @@ Y_UNIT_TEST_SUITE(TAlgorithm) { UNIT_ASSERT(3 == CountIf(array, isOne)); } - Y_UNIT_TEST(CountTest) { - UNIT_ASSERT(3 == Count("____1________1____1_______", '1')); + Y_UNIT_TEST(CountTest) { + UNIT_ASSERT(3 == Count("____1________1____1_______", '1')); UNIT_ASSERT(3 == Count(TStringBuf("____1________1____1_______"), '1')); UNIT_ASSERT(5 == Count(TStringBuf("1____1________1____1_______1"), '1')); UNIT_ASSERT(0 == Count(TStringBuf("___________"), '1')); - UNIT_ASSERT(0 == Count(TStringBuf(), '1')); + UNIT_ASSERT(0 == Count(TStringBuf(), '1')); UNIT_ASSERT(1 == Count(TStringBuf("1"), '1')); const char array[] = "____1________1____1_______"; UNIT_ASSERT(3 == Count(array, '1')); - } - + } + struct TStrokaNoCopy: TString { public: TStrokaNoCopy(const char* p) diff --git a/util/generic/iterator_range.h b/util/generic/iterator_range.h index 9f4d02da29..c03ec723a2 100644 --- a/util/generic/iterator_range.h +++ b/util/generic/iterator_range.h @@ -5,44 +5,44 @@ #include <iterator> #include <utility> -template <typename TBegin, typename TEnd = TBegin> -struct TIteratorRange { - using TElement = std::remove_reference_t<decltype(*std::declval<TBegin>())>; - - TIteratorRange(TBegin begin, TEnd end) - : Begin_(begin) - , End_(end) - { - } - - TIteratorRange() - : TIteratorRange(TBegin{}, TEnd{}) - { - } - - TBegin begin() const { - return Begin_; - } - - TEnd end() const { - return End_; - } - - bool empty() const { - // because range based for requires exactly '!=' - return !(Begin_ != End_); - } - -private: - TBegin Begin_; - TEnd End_; -}; - -template <class TIterator> -class TIteratorRange<TIterator, TIterator> { +template <typename TBegin, typename TEnd = TBegin> +struct TIteratorRange { + using TElement = std::remove_reference_t<decltype(*std::declval<TBegin>())>; + + TIteratorRange(TBegin begin, TEnd end) + : Begin_(begin) + , End_(end) + { + } + + TIteratorRange() + : TIteratorRange(TBegin{}, TEnd{}) + { + } + + TBegin begin() const { + return Begin_; + } + + TEnd end() const { + return End_; + } + + bool empty() const { + // because range based for requires exactly '!=' + return !(Begin_ != End_); + } + +private: + TBegin Begin_; + TEnd End_; +}; + +template <class TIterator> +class TIteratorRange<TIterator, TIterator> { public: - using iterator = TIterator; - using const_iterator = TIterator; + using iterator = TIterator; + using const_iterator = TIterator; using value_type = typename std::iterator_traits<iterator>::value_type; using reference = typename std::iterator_traits<iterator>::reference; using const_reference = typename std::iterator_traits<const_iterator>::reference; @@ -55,17 +55,17 @@ public: { } - TIteratorRange(TIterator begin, TIterator end) + TIteratorRange(TIterator begin, TIterator end) : Begin_(begin) , End_(end) { } - TIterator begin() const { + TIterator begin() const { return Begin_; } - TIterator end() const { + TIterator end() const { return End_; } @@ -84,21 +84,21 @@ public: } private: - TIterator Begin_; - TIterator End_; + TIterator Begin_; + TIterator End_; }; -template <class TIterator> -TIteratorRange<TIterator> MakeIteratorRange(TIterator begin, TIterator end) { - return TIteratorRange<TIterator>(begin, end); -} - -template <class TIterator> -TIteratorRange<TIterator> MakeIteratorRange(const std::pair<TIterator, TIterator>& range) { - return TIteratorRange<TIterator>(range.first, range.second); +template <class TIterator> +TIteratorRange<TIterator> MakeIteratorRange(TIterator begin, TIterator end) { + return TIteratorRange<TIterator>(begin, end); } -template <class TBegin, class TEnd> -TIteratorRange<TBegin, TEnd> MakeIteratorRange(TBegin begin, TEnd end) { - return {begin, end}; +template <class TIterator> +TIteratorRange<TIterator> MakeIteratorRange(const std::pair<TIterator, TIterator>& range) { + return TIteratorRange<TIterator>(range.first, range.second); } + +template <class TBegin, class TEnd> +TIteratorRange<TBegin, TEnd> MakeIteratorRange(TBegin begin, TEnd end) { + return {begin, end}; +} diff --git a/util/generic/iterator_range_ut.cpp b/util/generic/iterator_range_ut.cpp index a7e3670ae1..60032745f5 100644 --- a/util/generic/iterator_range_ut.cpp +++ b/util/generic/iterator_range_ut.cpp @@ -10,11 +10,11 @@ Y_UNIT_TEST_SUITE(IteratorRange) { UNIT_ASSERT(range.empty()); } - Y_UNIT_TEST(DefaultConstructorSentinel) { - TIteratorRange<int*, void*> range; - UNIT_ASSERT(range.empty()); - } - + Y_UNIT_TEST(DefaultConstructorSentinel) { + TIteratorRange<int*, void*> range; + UNIT_ASSERT(range.empty()); + } + Y_UNIT_TEST(RangeBasedForLoop) { // compileability test for (int i : TIteratorRange<int*>()) { @@ -22,13 +22,13 @@ Y_UNIT_TEST_SUITE(IteratorRange) { } } - Y_UNIT_TEST(RangeBasedForLoopSentinel) { - // compileability test - for (int i : TIteratorRange<int*, void*>()) { - Y_UNUSED(i); - } - } - + Y_UNIT_TEST(RangeBasedForLoopSentinel) { + // compileability test + for (int i : TIteratorRange<int*, void*>()) { + Y_UNUSED(i); + } + } + Y_UNIT_TEST(Works) { const int values[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; auto range = MakeIteratorRange(values, values + Y_ARRAY_SIZE(values)); @@ -37,37 +37,37 @@ Y_UNIT_TEST_SUITE(IteratorRange) { UNIT_ASSERT(!range.empty()); } - Y_UNIT_TEST(WorksSentinel) { - struct TRangeSentinel { - }; - - struct TEnumerator { - ui32 operator*() const { - return Cur; - } - - void operator++() { - ++Cur; - } - - bool operator!=(const TRangeSentinel&) const { - return Cur < End; - } - - ui32 Cur; - ui32 End; - }; - - auto range = MakeIteratorRange(TEnumerator{0, 10}, TRangeSentinel{}); - UNIT_ASSERT(!range.empty()); - - ui32 i = 0; - for (auto j : range) { - UNIT_ASSERT_VALUES_EQUAL(j, i++); - } - UNIT_ASSERT_VALUES_EQUAL(i, 10); - } - + Y_UNIT_TEST(WorksSentinel) { + struct TRangeSentinel { + }; + + struct TEnumerator { + ui32 operator*() const { + return Cur; + } + + void operator++() { + ++Cur; + } + + bool operator!=(const TRangeSentinel&) const { + return Cur < End; + } + + ui32 Cur; + ui32 End; + }; + + auto range = MakeIteratorRange(TEnumerator{0, 10}, TRangeSentinel{}); + UNIT_ASSERT(!range.empty()); + + ui32 i = 0; + for (auto j : range) { + UNIT_ASSERT_VALUES_EQUAL(j, i++); + } + UNIT_ASSERT_VALUES_EQUAL(i, 10); + } + Y_UNIT_TEST(OperatorsAndReferences) { TVector<size_t> values{1, 2, 3, 4, 5}; auto range = MakeIteratorRange(values.begin(), values.end()); diff --git a/util/generic/store_policy.h b/util/generic/store_policy.h index 148821c70c..c3c88c1e14 100644 --- a/util/generic/store_policy.h +++ b/util/generic/store_policy.h @@ -14,20 +14,20 @@ struct TWithRefCount: public TBase, public TRefCounted<TWithRefCount<TBase, TCou template <class T> struct TPtrPolicy { - inline TPtrPolicy(T* t) + inline TPtrPolicy(T* t) : T_(t) { } - inline T* Ptr() noexcept { - return T_; - } - + inline T* Ptr() noexcept { + return T_; + } + inline const T* Ptr() const noexcept { return T_; } - T* T_; + T* T_; }; template <class T> @@ -70,49 +70,49 @@ struct TRefPolicy { TIntrusivePtr<THelper> T_; }; -/** +/** * Storage class that can be handy for implementing proxies / adaptors that can * accept both lvalues and rvalues. In the latter case it's often required to * extend the lifetime of the passed rvalue, and the only option is to store it * in your proxy / adaptor. - * - * Example usage: - * \code - * template<class T> - * struct TProxy { - * TAutoEmbedOrPtrPolicy<T> Value_; - * // Your proxy code... - * }; - * - * template<class T> - * TProxy<T> MakeProxy(T&& value) { - * // Rvalues are automagically moved-from, and stored inside the proxy. + * + * Example usage: + * \code + * template<class T> + * struct TProxy { + * TAutoEmbedOrPtrPolicy<T> Value_; + * // Your proxy code... + * }; + * + * template<class T> + * TProxy<T> MakeProxy(T&& value) { + * // Rvalues are automagically moved-from, and stored inside the proxy. * return {std::forward<T>(value)}; - * } - * \endcode - * - * Look at `Reversed` in `adaptor.h` for real example. - */ + * } + * \endcode + * + * Look at `Reversed` in `adaptor.h` for real example. + */ template <class T, bool IsReference = std::is_reference<T>::value> struct TAutoEmbedOrPtrPolicy: TPtrPolicy<std::remove_reference_t<T>> { using TBase = TPtrPolicy<std::remove_reference_t<T>>; - + TAutoEmbedOrPtrPolicy(T& reference) : TBase(&reference) - { - } -}; - + { + } +}; + template <class T> struct TAutoEmbedOrPtrPolicy<T, false>: TEmbedPolicy<T> { using TBase = TEmbedPolicy<T>; - + TAutoEmbedOrPtrPolicy(T&& object) : TBase(std::move(object)) - { - } -}; - + { + } +}; + template <class T> using TAtomicRefPolicy = TRefPolicy<T, TAtomicCounter>; diff --git a/util/generic/store_policy_ut.cpp b/util/generic/store_policy_ut.cpp index c9722203aa..30710dc913 100644 --- a/util/generic/store_policy_ut.cpp +++ b/util/generic/store_policy_ut.cpp @@ -1,87 +1,87 @@ -#include "store_policy.h" - +#include "store_policy.h" + #include <library/cpp/testing/unittest/registar.h> -#include <util/generic/algorithm.h> -#include <util/generic/vector.h> - -Y_UNIT_TEST_SUITE(StorePolicy) { - Y_UNIT_TEST(Compileability) { - // construction - TAutoEmbedOrPtrPolicy<THolder<int>>(MakeHolder<int>(1)); - TAutoEmbedOrPtrPolicy<TVector<int>>(TVector<int>{1, 2, 3}); - auto a = MakeHolder<int>(42); - TAutoEmbedOrPtrPolicy<THolder<int>&>{a}; - - // const - (**TAutoEmbedOrPtrPolicy<THolder<int>>(MakeHolder<int>(1)).Ptr())++; // ok +#include <util/generic/algorithm.h> +#include <util/generic/vector.h> + +Y_UNIT_TEST_SUITE(StorePolicy) { + Y_UNIT_TEST(Compileability) { + // construction + TAutoEmbedOrPtrPolicy<THolder<int>>(MakeHolder<int>(1)); + TAutoEmbedOrPtrPolicy<TVector<int>>(TVector<int>{1, 2, 3}); + auto a = MakeHolder<int>(42); + TAutoEmbedOrPtrPolicy<THolder<int>&>{a}; + + // const + (**TAutoEmbedOrPtrPolicy<THolder<int>>(MakeHolder<int>(1)).Ptr())++; // ok (**TAutoEmbedOrPtrPolicy<THolder<int>&>(a).Ptr())++; // ok - - const TVector<int> b = {0}; - auto bValue = (*TAutoEmbedOrPtrPolicy<const TVector<int>&>(b).Ptr())[0]; // ok - // (*TAutoEmbedOrPtrPolicy<const TVector<int>&>(b).Ptr())[0]++; // not ok - Y_UNUSED(bValue); - } - - template <typename T, typename TFunc> + + const TVector<int> b = {0}; + auto bValue = (*TAutoEmbedOrPtrPolicy<const TVector<int>&>(b).Ptr())[0]; // ok + // (*TAutoEmbedOrPtrPolicy<const TVector<int>&>(b).Ptr())[0]++; // not ok + Y_UNUSED(bValue); + } + + template <typename T, typename TFunc> void FunctionTakingRefDefaultIsObject(T&& a, TFunc func) { - TAutoEmbedOrPtrPolicy<T> refHolder(a); - func(refHolder); - } - - Y_UNIT_TEST(Reference) { - { - TVector<ui32> a = {1, 2, 3}; - - FunctionTakingRefDefaultIsObject(a, [](auto& holder) { - holder.Ptr()->push_back(4); - auto secondHolder = holder; - secondHolder.Ptr()->push_back(5); - }); - - UNIT_ASSERT_VALUES_EQUAL(a.size(), 5); - } - { - const TVector<ui32> a = {1, 2, 3}; - - static_assert(std::is_const<decltype(a)>::value); - - FunctionTakingRefDefaultIsObject(a, [](auto& holder) { + TAutoEmbedOrPtrPolicy<T> refHolder(a); + func(refHolder); + } + + Y_UNIT_TEST(Reference) { + { + TVector<ui32> a = {1, 2, 3}; + + FunctionTakingRefDefaultIsObject(a, [](auto& holder) { + holder.Ptr()->push_back(4); + auto secondHolder = holder; + secondHolder.Ptr()->push_back(5); + }); + + UNIT_ASSERT_VALUES_EQUAL(a.size(), 5); + } + { + const TVector<ui32> a = {1, 2, 3}; + + static_assert(std::is_const<decltype(a)>::value); + + FunctionTakingRefDefaultIsObject(a, [](auto& holder) { static_assert(std::is_const<std::remove_reference_t<decltype(*holder.Ptr())>>::value); - UNIT_ASSERT_VALUES_EQUAL(holder.Ptr()->size(), 3); - }); - } - } - - template <typename T, typename TFunc> + UNIT_ASSERT_VALUES_EQUAL(holder.Ptr()->size(), 3); + }); + } + } + + template <typename T, typename TFunc> void FunctionTakingObjectDefaultObject(T&& a, TFunc func) { TAutoEmbedOrPtrPolicy<T> objectHolder(std::forward<T>(a)); - func(objectHolder); - } - - Y_UNIT_TEST(Object) { - TVector<ui32> a = {1, 2, 3}; - - FunctionTakingObjectDefaultObject(std::move(a), [&a](auto& holder) { - static_assert(std::is_copy_assignable<decltype(holder)>::value); - UNIT_ASSERT_VALUES_EQUAL(a.size(), 0); - UNIT_ASSERT_VALUES_EQUAL(holder.Ptr()->size(), 3); - holder.Ptr()->push_back(4); - auto secondHolder = holder; - secondHolder.Ptr()->push_back(5); - - UNIT_ASSERT_VALUES_EQUAL(holder.Ptr()->size(), 4); - UNIT_ASSERT_VALUES_EQUAL(secondHolder.Ptr()->size(), 5); - }); - - UNIT_ASSERT_VALUES_EQUAL(a.size(), 0); - - THolder<int> b = MakeHolder<int>(42); - FunctionTakingObjectDefaultObject(std::move(b), [](auto& holder) { - static_assert(!std::is_copy_assignable<decltype(holder)>::value); - UNIT_ASSERT_VALUES_EQUAL(**holder.Ptr(), 42); - auto secondHolder = std::move(holder); - UNIT_ASSERT(!*holder.Ptr()); - UNIT_ASSERT_VALUES_EQUAL(**secondHolder.Ptr(), 42); - }); - } -} + func(objectHolder); + } + + Y_UNIT_TEST(Object) { + TVector<ui32> a = {1, 2, 3}; + + FunctionTakingObjectDefaultObject(std::move(a), [&a](auto& holder) { + static_assert(std::is_copy_assignable<decltype(holder)>::value); + UNIT_ASSERT_VALUES_EQUAL(a.size(), 0); + UNIT_ASSERT_VALUES_EQUAL(holder.Ptr()->size(), 3); + holder.Ptr()->push_back(4); + auto secondHolder = holder; + secondHolder.Ptr()->push_back(5); + + UNIT_ASSERT_VALUES_EQUAL(holder.Ptr()->size(), 4); + UNIT_ASSERT_VALUES_EQUAL(secondHolder.Ptr()->size(), 5); + }); + + UNIT_ASSERT_VALUES_EQUAL(a.size(), 0); + + THolder<int> b = MakeHolder<int>(42); + FunctionTakingObjectDefaultObject(std::move(b), [](auto& holder) { + static_assert(!std::is_copy_assignable<decltype(holder)>::value); + UNIT_ASSERT_VALUES_EQUAL(**holder.Ptr(), 42); + auto secondHolder = std::move(holder); + UNIT_ASSERT(!*holder.Ptr()); + UNIT_ASSERT_VALUES_EQUAL(**secondHolder.Ptr(), 42); + }); + } +} diff --git a/util/generic/ut/ya.make b/util/generic/ut/ya.make index 6eaf24cc5f..a9626dc057 100644 --- a/util/generic/ut/ya.make +++ b/util/generic/ut/ya.make @@ -40,7 +40,7 @@ SRCS( generic/singleton_ut.cpp generic/size_literals_ut.cpp generic/stack_ut.cpp - generic/store_policy_ut.cpp + generic/store_policy_ut.cpp generic/strbuf_ut.cpp generic/string_ut.cpp generic/typelist_ut.cpp diff --git a/util/generic/xrange.h b/util/generic/xrange.h index 5fc8c82912..48db812b2e 100644 --- a/util/generic/xrange.h +++ b/util/generic/xrange.h @@ -148,7 +148,7 @@ namespace NPrivate { constexpr TIterator(T value, const TSteppedXRange& parent) noexcept : Value_(value) - , Parent_(&parent) + , Parent_(&parent) { } @@ -165,7 +165,7 @@ namespace NPrivate { } TIterator& operator++() noexcept { - Value_ += Parent_->Step_; + Value_ += Parent_->Step_; return *this; } @@ -202,7 +202,7 @@ namespace NPrivate { private: T Value_; - const TSteppedXRange* Parent_; + const TSteppedXRange* Parent_; }; using value_type = T; diff --git a/util/str_stl.h b/util/str_stl.h index f1e137181d..2113e2bed2 100644 --- a/util/str_stl.h +++ b/util/str_stl.h @@ -34,9 +34,9 @@ namespace NHashPrivate { template <class T, bool needNumericHashing> struct THashHelper { inline size_t operator()(const T& t) const noexcept { - return (size_t)t; // If you have a compilation error here, look at explanation below: - // Probably error is caused by undefined template specialization of THash<T> - // You can find examples of specialization in this file + return (size_t)t; // If you have a compilation error here, look at explanation below: + // Probably error is caused by undefined template specialization of THash<T> + // You can find examples of specialization in this file } }; |