123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217 |
- #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);
- }
- }
- } // Y_UNIT_TEST_SUITE(XRange)
|