diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /util/generic/xrange_ut.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'util/generic/xrange_ut.cpp')
-rw-r--r-- | util/generic/xrange_ut.cpp | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/util/generic/xrange_ut.cpp b/util/generic/xrange_ut.cpp new file mode 100644 index 0000000000..8106da03e7 --- /dev/null +++ b/util/generic/xrange_ut.cpp @@ -0,0 +1,217 @@ +#include "xrange.h" + +#include "algorithm.h" +#include "maybe.h" +#include "vector.h" +#include <library/cpp/testing/unittest/registar.h> +#include <util/string/builder.h> + +Y_UNIT_TEST_SUITE(XRange) { + void TestXRangeImpl(size_t begin, size_t end) { + size_t count = 0; + size_t sum = 0; + size_t first = 42; + bool firstInited = false; + size_t last = 0; + + for (auto i : xrange(begin, end)) { + ++count; + sum += i; + last = i; + if (!firstInited) { + first = i; + firstInited = true; + } + } + + UNIT_ASSERT_VALUES_EQUAL(count, end - begin); + UNIT_ASSERT_VALUES_EQUAL(first, begin); + UNIT_ASSERT_VALUES_EQUAL(last, end - 1); + UNIT_ASSERT_VALUES_EQUAL(sum, count * (first + last) / 2); + } + + void TestSteppedXRangeImpl(int begin, int end, int step, const TVector<int>& expected) { + size_t expInd = 0; + for (auto i : xrange(begin, end, step)) { + UNIT_ASSERT(expInd < expected.size()); + UNIT_ASSERT_VALUES_EQUAL(i, expected[expInd]); + ++expInd; + } + UNIT_ASSERT_VALUES_EQUAL(expInd, expected.size()); + } + + Y_UNIT_TEST(IncrementWorks) { + TestXRangeImpl(0, 10); + TestXRangeImpl(10, 20); + } + + Y_UNIT_TEST(DecrementWorks) { + TestSteppedXRangeImpl(10, 0, -1, {10, 9, 8, 7, 6, 5, 4, 3, 2, 1}); + TestSteppedXRangeImpl(10, -1, -1, {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}); + TestSteppedXRangeImpl(20, 9, -1, {20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10}); + } + + Y_UNIT_TEST(StepWorks) { + TestSteppedXRangeImpl(0, 0, 1, {}); + TestSteppedXRangeImpl(0, 9, 3, {0, 3, 6}); + TestSteppedXRangeImpl(0, 10, 3, {0, 3, 6, 9}); + TestSteppedXRangeImpl(0, 11, 3, {0, 3, 6, 9}); + TestSteppedXRangeImpl(0, 12, 3, {0, 3, 6, 9}); + TestSteppedXRangeImpl(0, 13, 3, {0, 3, 6, 9, 12}); + TestSteppedXRangeImpl(0, 10, 2, {0, 2, 4, 6, 8}); + TestSteppedXRangeImpl(15, 0, -4, {15, 11, 7, 3}); + TestSteppedXRangeImpl(15, -1, -4, {15, 11, 7, 3}); + TestSteppedXRangeImpl(15, -2, -4, {15, 11, 7, 3, -1}); + } + + Y_UNIT_TEST(PointersWorks) { + TVector<size_t> data = {3, 1, 4, 1, 5, 9, 2, 6}; + const size_t digSumExpected = Accumulate(data.begin(), data.end(), static_cast<size_t>(0)); + size_t digSumByIt = 0; + for (auto ptr : xrange(data.begin(), data.end())) { + digSumByIt += *ptr; + } + UNIT_ASSERT_VALUES_EQUAL(digSumByIt, digSumExpected); + size_t digSumByPtr = 0; + for (auto ptr : xrange(&data[0], &data[0] + data.size())) { + digSumByPtr += *ptr; + } + UNIT_ASSERT_VALUES_EQUAL(digSumByPtr, digSumExpected); + } + + Y_UNIT_TEST(SizeMethodCheck) { + UNIT_ASSERT_VALUES_EQUAL(xrange(5).size(), 5); + UNIT_ASSERT_VALUES_EQUAL(xrange(0, 5, 2).size(), 3); + UNIT_ASSERT_VALUES_EQUAL(xrange(0, 6, 2).size(), 3); + } + + class TVectorChild: public TVector<size_t> { + public: + template <typename TIterator> + TVectorChild(TIterator a, TIterator b) + : TVector<size_t>(a, b) + { + } + }; + + Y_UNIT_TEST(ConvertionWorks) { + TVector<size_t> data = {0, 1, 2, 3, 4, 5, 6, 7, 8}; + + TVector<size_t> convertionResults[] = {xrange<size_t>(9), + xrange<ui32>(0, 9), + xrange(0, 9, 1)}; + + for (const auto& arr : convertionResults) { + UNIT_ASSERT(arr == data); + } + + TVectorChild sons[] = {xrange(0, 9), + xrange(0, 9, 1)}; + + for (const auto& arr : sons) { + UNIT_ASSERT(arr == data); + } + } + + template <class XRangeContainer> + void TestEmptyRanges(const XRangeContainer& c) { + for (const auto& emptyRange : c) { + UNIT_ASSERT_VALUES_EQUAL(emptyRange.size(), 0); + + for (auto i : emptyRange) { + Y_UNUSED(i); + UNIT_ASSERT(false); + } + + using TValueType = decltype(*emptyRange.begin()); + const TVector<TValueType> asVector = emptyRange; + UNIT_ASSERT(asVector.empty()); + } + } + + Y_UNIT_TEST(EmptySimpleRange) { + using TSimpleRange = decltype(xrange(1)); + + const TSimpleRange emptySimpleRanges[] = { + xrange(-1), + xrange(-10), + xrange(0, -5), + xrange(10, 10), + xrange(10, 9), + }; + + TestEmptyRanges(emptySimpleRanges); + } + + Y_UNIT_TEST(EmptySteppedRange) { + using TSteppedRange = decltype(xrange(1, 10, 1)); + + const TSteppedRange emptySteppedRanges[] = { + xrange(5, 5, 1), + xrange(5, 0, 5), + xrange(0, -1, 5), + xrange(0, 1, -1), + xrange(0, -10, 10), + }; + + TestEmptyRanges(emptySteppedRanges); + } + + template <class TRange> + static void TestIteratorDifferenceImpl(TRange range, int a, int b, TMaybe<int> step) { + auto fmtCase = [&]() -> TString { return TStringBuilder() << "xrange(" << a << ", " << b << (step ? ", " + ToString(*step) : TString{}) << ")"; }; + auto begin = std::begin(range); + auto end = std::end(range); + auto distance = end - begin; + UNIT_ASSERT_VALUES_EQUAL_C(range.size(), distance, fmtCase()); + UNIT_ASSERT_EQUAL_C(end, begin + distance, fmtCase()); + } + + Y_UNIT_TEST(IteratorDifference) { + for (int a = -20; a <= 20; ++a) { + for (int b = -20; b <= 20; ++b) { + for (int step = -25; step <= 25; ++step) { + if (step != 0) { + TestIteratorDifferenceImpl(xrange(a, b, step), a, b, step); + } + } + TestIteratorDifferenceImpl(xrange(a, b), a, b, Nothing()); + } + } + } + + Y_UNIT_TEST(Advance) { + { + auto range = xrange(30, 160, 7); + auto it = std::begin(range); + it += 5; + UNIT_ASSERT_VALUES_EQUAL(*(std::begin(range) + 5), *it); + UNIT_ASSERT_VALUES_EQUAL(65, *it); + it -= 2; + UNIT_ASSERT_VALUES_EQUAL(*(std::begin(range) + 3), *it); + UNIT_ASSERT_VALUES_EQUAL(51, *it); + std::advance(it, 10); + UNIT_ASSERT_VALUES_EQUAL(*(std::begin(range) + 13), *it); + UNIT_ASSERT_VALUES_EQUAL(121, *it); + std::advance(it, -5); + UNIT_ASSERT_VALUES_EQUAL(*(std::begin(range) + 8), *it); + UNIT_ASSERT_VALUES_EQUAL(86, *it); + } + { + auto range = xrange(-20, 100); + auto it = std::begin(range); + it += 5; + UNIT_ASSERT_VALUES_EQUAL(*(std::begin(range) + 5), *it); + UNIT_ASSERT_VALUES_EQUAL(-15, *it); + it -= 2; + UNIT_ASSERT_VALUES_EQUAL(*(std::begin(range) + 3), *it); + UNIT_ASSERT_VALUES_EQUAL(-17, *it); + std::advance(it, 30); + UNIT_ASSERT_VALUES_EQUAL(*(std::begin(range) + 33), *it); + UNIT_ASSERT_VALUES_EQUAL(13, *it); + std::advance(it, -8); + UNIT_ASSERT_VALUES_EQUAL(*(std::begin(range) + 25), *it); + UNIT_ASSERT_VALUES_EQUAL(5, *it); + } + } +} |