123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906 |
- #include <library/cpp/testing/unittest/registar.h>
- #include "algorithm.h"
- #include "hash.h"
- #include "hash_multi_map.h"
- #include "strbuf.h"
- #include "string.h"
- static auto isOne = [](char c) { return c == '1'; };
- Y_UNIT_TEST_SUITE(TAlgorithm) {
- Y_UNIT_TEST(AnyTest) {
- UNIT_ASSERT(0 == AnyOf(TStringBuf("00"), isOne));
- UNIT_ASSERT(1 == AnyOf(TStringBuf("01"), isOne));
- UNIT_ASSERT(1 == AnyOf(TStringBuf("10"), isOne));
- UNIT_ASSERT(1 == AnyOf(TStringBuf("11"), isOne));
- UNIT_ASSERT(0 == AnyOf(TStringBuf(), isOne));
- const char array00[]{'0', '0'};
- UNIT_ASSERT(0 == AnyOf(array00, isOne));
- const char array01[]{'0', '1'};
- UNIT_ASSERT(1 == AnyOf(array01, isOne));
- }
- Y_UNIT_TEST(AllOfTest) {
- UNIT_ASSERT(0 == AllOf(TStringBuf("00"), isOne));
- UNIT_ASSERT(0 == AllOf(TStringBuf("01"), isOne));
- UNIT_ASSERT(0 == AllOf(TStringBuf("10"), isOne));
- UNIT_ASSERT(1 == AllOf(TStringBuf("11"), isOne));
- UNIT_ASSERT(1 == AllOf(TStringBuf(), isOne));
- const char array01[]{'0', '1'};
- UNIT_ASSERT(0 == AllOf(array01, isOne));
- const char array11[]{'1', '1'};
- UNIT_ASSERT(1 == AllOf(array11, isOne));
- }
- Y_UNIT_TEST(CountIfTest) {
- UNIT_ASSERT(3 == CountIf(TStringBuf("____1________1____1_______"), isOne));
- UNIT_ASSERT(5 == CountIf(TStringBuf("1____1________1____1_______1"), isOne));
- UNIT_ASSERT(0 == CountIf(TStringBuf("___________"), isOne));
- UNIT_ASSERT(0 == CountIf(TStringBuf(), isOne));
- UNIT_ASSERT(1 == CountIf(TStringBuf("1"), isOne));
- const char array[] = "____1________1____1_______";
- UNIT_ASSERT(3 == CountIf(array, isOne));
- }
- 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(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)
- : TString(p)
- {
- }
- private:
- TStrokaNoCopy(const TStrokaNoCopy&);
- void operator=(const TStrokaNoCopy&);
- };
- Y_UNIT_TEST(CountOfTest) {
- UNIT_ASSERT_VALUES_EQUAL(CountOf(1, 2), 0);
- UNIT_ASSERT_VALUES_EQUAL(CountOf(1, 1), 1);
- UNIT_ASSERT_VALUES_EQUAL(CountOf(2, 4, 5), 0);
- UNIT_ASSERT_VALUES_EQUAL(CountOf(2, 4, 2), 1);
- UNIT_ASSERT_VALUES_EQUAL(CountOf(3, 3, 3), 2);
- // Checking comparison of different types.
- UNIT_ASSERT_VALUES_EQUAL(CountOf(0x61, 'x', 'y', 'z'), 0);
- UNIT_ASSERT_VALUES_EQUAL(CountOf(0x61, 'a', 'b', 'c', 0x61), 2);
- UNIT_ASSERT_VALUES_EQUAL(CountOf(0x61, 'a', 'b', 'c', 0x61ll), 2);
- // TString and const char *
- UNIT_ASSERT_VALUES_EQUAL(CountOf(TString("xyz"), "123", "poi"), 0);
- UNIT_ASSERT_VALUES_EQUAL(CountOf(TString("xyz"), "123", "poi", "xyz"), 1);
- // TString and TStringBuf
- UNIT_ASSERT_VALUES_EQUAL(CountOf(TString("xyz"), TStringBuf("123"), TStringBuf("poi")), 0);
- UNIT_ASSERT_VALUES_EQUAL(CountOf(TString("xyz"), TStringBuf("123"), TStringBuf("poi"),
- TStringBuf("xyz")),
- 1);
- // TStringBuf and const char *
- UNIT_ASSERT_VALUES_EQUAL(CountOf(TStringBuf("xyz"), "123", "poi"), 0);
- UNIT_ASSERT_VALUES_EQUAL(CountOf(TStringBuf("xyz"), "123", "poi", "xyz"), 1);
- // TStringBuf and TString
- UNIT_ASSERT_VALUES_EQUAL(CountOf(TStringBuf("xyz"), TString("123"), TString("poi")), 0);
- UNIT_ASSERT_VALUES_EQUAL(CountOf(TStringBuf("xyz"), TString("123"), TString("poi"),
- TString("xyz")),
- 1);
- }
- Y_UNIT_TEST(EqualToOneOfTest) {
- UNIT_ASSERT(1 == EqualToOneOf(1, 1, 2));
- UNIT_ASSERT(1 == EqualToOneOf(2, 1, 2));
- UNIT_ASSERT(0 == EqualToOneOf(3, 1, 2));
- UNIT_ASSERT(1 == EqualToOneOf(1, 1));
- UNIT_ASSERT(0 == EqualToOneOf(1, 2));
- UNIT_ASSERT(0 == EqualToOneOf(3));
- //test, that EqualToOneOf can compare different types, and don't copy objects:
- TStrokaNoCopy x("x");
- TStrokaNoCopy y("y");
- TStrokaNoCopy z("z");
- const char* px = "x";
- const char* py = "y";
- const char* pz = "z";
- UNIT_ASSERT(1 == EqualToOneOf(x, px, py));
- UNIT_ASSERT(1 == EqualToOneOf(y, px, py));
- UNIT_ASSERT(1 == EqualToOneOf(y, px, y));
- UNIT_ASSERT(1 == EqualToOneOf(y, x, py));
- UNIT_ASSERT(0 == EqualToOneOf(z, px, py));
- UNIT_ASSERT(1 == EqualToOneOf(px, x, y));
- UNIT_ASSERT(1 == EqualToOneOf(py, x, y));
- UNIT_ASSERT(0 == EqualToOneOf(pz, x, y));
- }
- template <class TTestConstPtr>
- void TestFindPtrFoundValue(int j, TTestConstPtr root) {
- if (j == 3) {
- UNIT_ASSERT(root && *root == 3);
- } else if (j == 4) {
- UNIT_ASSERT(root == nullptr);
- } else {
- ythrow yexception() << "invalid param " << j;
- }
- }
- template <class TTestConstPtr>
- void TestFindIfPtrFoundValue(int j, TTestConstPtr root) {
- if (j == 3) {
- UNIT_ASSERT(root == nullptr);
- } else if (j == 4) {
- UNIT_ASSERT(root && *root == 2);
- } else {
- ythrow yexception() << "invalid param " << j;
- }
- }
- struct TVectorNoCopy: std::vector<int> {
- public:
- TVectorNoCopy() = default;
- private:
- TVectorNoCopy(const TVectorNoCopy&);
- void operator=(const TVectorNoCopy&);
- };
- Y_UNIT_TEST(FindPtrTest) {
- TVectorNoCopy v;
- v.push_back(1);
- v.push_back(2);
- v.push_back(3);
- int array[3] = {1, 2, 3};
- const int array_const[3] = {1, 2, 3};
- //test (const, non-const) * (iterator, vector, array) * (found, not found) variants.
- // value '3' is in container, value '4' is not
- for (int j = 3; j <= 4; ++j) {
- TestFindPtrFoundValue<int*>(j, FindPtr(v, j));
- TestFindPtrFoundValue<int*>(j, FindPtr(v.begin(), v.end(), j));
- const TVectorNoCopy& q = v;
- TestFindPtrFoundValue<const int*>(j, FindPtr(q, j));
- TestFindPtrFoundValue<const int*>(j, FindPtr(q.begin(), q.end(), j));
- TestFindPtrFoundValue<int*>(j, FindPtr(array, j));
- TestFindPtrFoundValue<const int*>(j, FindPtr(array_const, j));
- }
- }
- Y_UNIT_TEST(FindIfPtrTest) {
- TVectorNoCopy v;
- v.push_back(1);
- v.push_back(2);
- v.push_back(3);
- int array[3] = {1, 2, 3};
- const int array_const[3] = {1, 2, 3};
- //test (const, non-const) * (iterator, vector, array) * (found, not found) variants.
- // search, that 2*2 == 4, but there is no value 'x' in array that (x*x == 3)
- for (int j = 3; j <= 4; ++j) {
- TestFindIfPtrFoundValue<int*>(j, FindIfPtr(v, [j](int i) { return i * i == j; }));
- TestFindIfPtrFoundValue<int*>(j, FindIfPtr(v.begin(), v.end(), [j](int i) { return i * i == j; }));
- const TVectorNoCopy& q = v;
- TestFindIfPtrFoundValue<const int*>(j, FindIfPtr(q, [j](int i) { return i * i == j; }));
- TestFindIfPtrFoundValue<const int*>(j, FindIfPtr(q.begin(), q.end(), [j](int i) { return i * i == j; }));
- TestFindIfPtrFoundValue<int*>(j, FindIfPtr(array, [j](int i) { return i * i == j; }));
- TestFindIfPtrFoundValue<const int*>(j, FindIfPtr(array_const, [j](int i) { return i * i == j; }));
- }
- }
- Y_UNIT_TEST(FindIndexTest) {
- TVectorNoCopy v;
- v.push_back(1);
- v.push_back(2);
- v.push_back(3);
- UNIT_ASSERT_EQUAL(0, FindIndex(v, 1));
- UNIT_ASSERT_EQUAL(1, FindIndex(v, 2));
- UNIT_ASSERT_EQUAL(2, FindIndex(v, 3));
- UNIT_ASSERT_EQUAL(NPOS, FindIndex(v, 42));
- int array[3] = {1, 2, 3};
- UNIT_ASSERT_EQUAL(0, FindIndex(array, 1));
- UNIT_ASSERT_EQUAL(1, FindIndex(array, 2));
- UNIT_ASSERT_EQUAL(2, FindIndex(array, 3));
- UNIT_ASSERT_EQUAL(NPOS, FindIndex(array, 42));
- TVector<int> empty;
- UNIT_ASSERT_EQUAL(NPOS, FindIndex(empty, 0));
- }
- Y_UNIT_TEST(FindIndexIfTest) {
- TVectorNoCopy v;
- v.push_back(1);
- v.push_back(2);
- v.push_back(3);
- UNIT_ASSERT_EQUAL(0, FindIndexIf(v, [](int x) { return x == 1; }));
- UNIT_ASSERT_EQUAL(1, FindIndexIf(v, [](int x) { return x == 2; }));
- UNIT_ASSERT_EQUAL(2, FindIndexIf(v, [](int x) { return x == 3; }));
- UNIT_ASSERT_EQUAL(NPOS, FindIndexIf(v, [](int x) { return x == 42; }));
- int array[3] = {1, 2, 3};
- UNIT_ASSERT_EQUAL(0, FindIndexIf(array, [](int x) { return x == 1; }));
- UNIT_ASSERT_EQUAL(1, FindIndexIf(array, [](int x) { return x == 2; }));
- UNIT_ASSERT_EQUAL(2, FindIndexIf(array, [](int x) { return x == 3; }));
- UNIT_ASSERT_EQUAL(NPOS, FindIndexIf(array, [](int x) { return x == 42; }));
- TVector<int> empty;
- UNIT_ASSERT_EQUAL(NPOS, FindIndexIf(empty, [](int x) { return x == 3; }));
- }
- Y_UNIT_TEST(SortUniqueTest) {
- {
- TVector<TString> v;
- SortUnique(v);
- UNIT_ASSERT_EQUAL(v, TVector<TString>());
- }
- {
- const char* ar[] = {"345", "3", "123", "2", "23", "3", "2"};
- TVector<TString> v(ar, ar + Y_ARRAY_SIZE(ar));
- SortUnique(v);
- const char* suAr[] = {"123", "2", "23", "3", "345"};
- TVector<TString> suV(suAr, suAr + Y_ARRAY_SIZE(suAr));
- UNIT_ASSERT_EQUAL(v, suV);
- }
- }
- Y_UNIT_TEST(EraseTest) {
- TVector<int> data = {5, 4, 3, 2, 1, 0};
- TVector<int> expected = {5, 4, 2, 1, 0};
- Erase(data, 3);
- UNIT_ASSERT_EQUAL(data, expected);
- }
- Y_UNIT_TEST(EraseIfTest) {
- TVector<int> data = {5, 4, 3, 2, 1, 0};
- TVector<int> expected = {2, 1, 0};
- EraseIf(data, [](int i) { return i >= 3; });
- UNIT_ASSERT_EQUAL(data, expected);
- }
- Y_UNIT_TEST(EraseNodesIfTest) {
- TMap<int, int> map{{1, 1}, {2, 2}, {3, 5}};
- TMap<int, int> expectedMap{{1, 1}};
- EraseNodesIf(map, [](auto p) { return p.first >= 2; });
- UNIT_ASSERT_EQUAL(map, expectedMap);
- TMultiMap<int, int> multiMap{{1, 1}, {1, 3}, {2, 2}, {3, 5}};
- TMultiMap<int, int> expectedMultiMap{{1, 1}, {1, 3}};
- EraseNodesIf(multiMap, [](auto p) { return p.first >= 2; });
- UNIT_ASSERT_EQUAL(multiMap, expectedMultiMap);
- TSet<int> set{1, 2, 3, 4, 5, 6, 7};
- TSet<int> expectedSet{1, 3, 5, 7};
- EraseNodesIf(set, [](int i) { return i % 2 == 0; });
- UNIT_ASSERT_EQUAL(set, expectedSet);
- TMultiSet<int> multiSet{1, 1, 2, 3, 4, 4, 4, 5, 5, 5, 6, 7};
- TMultiSet<int> expectedMultiSet{1, 1, 3, 5, 5, 5, 7};
- EraseNodesIf(multiSet, [](int i) { return i % 2 == 0; });
- UNIT_ASSERT_EQUAL(multiSet, expectedMultiSet);
- THashMap<int, int> hashMap{{1, 0}, {3, 0}, {4, 0}, {10, 0}, {2, 0}, {5, 2}};
- THashMap<int, int> expectedHashMap{{1, 0}, {3, 0}, {5, 2}};
- EraseNodesIf(hashMap, [](auto p) { return p.first % 2 == 0; });
- UNIT_ASSERT_EQUAL(hashMap, expectedHashMap);
- THashMultiMap<int, int> hashMultiMap{{1, 0}, {3, 0}, {4, 0}, {10, 0}, {2, 0}, {5, 0}, {1, 0}, {1, 0}, {2, 0}, {2, 2}};
- THashMultiMap<int, int> expectedHashMultiMap{{1, 0}, {1, 0}, {1, 0}, {3, 0}, {5, 0}};
- EraseNodesIf(hashMultiMap, [](auto p) { return p.first % 2 == 0; });
- UNIT_ASSERT_EQUAL(hashMultiMap, expectedHashMultiMap);
- }
- Y_UNIT_TEST(NthElementTest) {
- {
- TVector<TString> v;
- NthElement(v.begin(), v.begin(), v.end());
- UNIT_ASSERT_EQUAL(v, TVector<TString>());
- }
- {
- int data[] = {3, 2, 1, 4, 6, 5, 7, 9, 8};
- TVector<int> testVector(data, data + Y_ARRAY_SIZE(data));
- size_t medianInd = testVector.size() / 2;
- NthElement(testVector.begin(), testVector.begin() + medianInd, testVector.end());
- UNIT_ASSERT_EQUAL(testVector[medianInd], 5);
- NthElement(testVector.begin(), testVector.begin() + medianInd, testVector.end(), [](int lhs, int rhs) { return lhs > rhs; });
- UNIT_ASSERT_EQUAL(testVector[medianInd], 5);
- }
- {
- const char* data[] = {"3", "234", "1231", "333", "545345", "11", "111", "55", "66"};
- TVector<TString> testVector(data, data + Y_ARRAY_SIZE(data));
- size_t medianInd = testVector.size() / 2;
- NthElement(testVector.begin(), testVector.begin() + medianInd, testVector.end());
- auto median = testVector.begin() + medianInd;
- for (auto it0 = testVector.begin(); it0 != median; ++it0) {
- for (auto it1 = median; it1 != testVector.end(); ++it1) {
- UNIT_ASSERT(*it0 <= *it1);
- }
- }
- }
- }
- Y_UNIT_TEST(BinarySearchTest) {
- {
- TVector<TString> v;
- bool test = BinarySearch(v.begin(), v.end(), "test");
- UNIT_ASSERT_EQUAL(test, false);
- }
- {
- int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
- bool test = BinarySearch(data, data + Y_ARRAY_SIZE(data), 2);
- UNIT_ASSERT_EQUAL(test, true);
- test = BinarySearch(data, data + Y_ARRAY_SIZE(data), 10);
- UNIT_ASSERT_EQUAL(test, false);
- }
- {
- TVector<size_t> data = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
- bool test = BinarySearch(data.begin(), data.end(), (size_t)9, TGreater<size_t>());
- UNIT_ASSERT_EQUAL(test, true);
- test = BinarySearch(data.begin(), data.end(), (size_t)11, TGreater<size_t>());
- UNIT_ASSERT_EQUAL(test, false);
- test = BinarySearch(data.rbegin(), data.rend(), (size_t)1);
- UNIT_ASSERT_EQUAL(test, true);
- }
- }
- Y_UNIT_TEST(EqualRangeTest) {
- {
- TVector<TString> v;
- using PairOfVector = std::pair<TVector<TString>::iterator, TVector<TString>::iterator>;
- PairOfVector tmp = EqualRange(v.begin(), v.end(), "tmp");
- UNIT_ASSERT_EQUAL(tmp.first, tmp.second);
- UNIT_ASSERT_EQUAL(tmp.first, v.end());
- }
- {
- int data[] = {1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 5};
- using PairOfInt = std::pair<int*, int*>;
- PairOfInt tmp = EqualRange(data, data + Y_ARRAY_SIZE(data), 3);
- UNIT_ASSERT_EQUAL(tmp.second - tmp.first, 4);
- UNIT_ASSERT_EQUAL(tmp.first - data, 7);
- UNIT_ASSERT_EQUAL(data + Y_ARRAY_SIZE(data) - tmp.second, 2);
- }
- {
- TVector<size_t> data = {9, 9, 8, 8, 8, 5, 4, 3, 3, 0, 0};
- using PairOfVector = std::pair<TVector<size_t>::iterator, TVector<size_t>::iterator>;
- PairOfVector tmp = EqualRange(data.begin(), data.end(), 8, TGreater<size_t>());
- UNIT_ASSERT_EQUAL(tmp.first - data.begin(), 2);
- UNIT_ASSERT_EQUAL(tmp.second - tmp.first, 3);
- using PairOfVectorReverse = std::pair<TVector<size_t>::reverse_iterator, TVector<size_t>::reverse_iterator>;
- PairOfVectorReverse tmpR = EqualRange(data.rbegin(), data.rend(), (size_t)0);
- UNIT_ASSERT_EQUAL(tmpR.first, data.rbegin());
- UNIT_ASSERT_EQUAL(tmpR.second - tmpR.first, 2);
- }
- }
- Y_UNIT_TEST(AdjacentFindTest) {
- TVector<int> v0;
- UNIT_ASSERT_EQUAL(AdjacentFind(v0), v0.end());
- TVector<int> v1 = {1};
- UNIT_ASSERT_EQUAL(AdjacentFind(v1), v1.end());
- const int v2[] = {8, 7, 6, 6, 5, 5, 5, 4, 3, 2, 1};
- UNIT_ASSERT_EQUAL(AdjacentFind(v2), std::begin(v2) + 2);
- TVector<TStringBuf> v3 = {"six", "five", "four", "three", "two", "one"};
- UNIT_ASSERT_EQUAL(AdjacentFind(v3), v3.end());
- TVector<int> v4 = {1, 1, 1, 1, 1};
- for (;;) {
- if (auto it = AdjacentFind(v4); it == v4.end()) {
- break;
- } else {
- *it += 1;
- }
- }
- UNIT_ASSERT_VALUES_EQUAL(v4, (TVector<int>{5, 4, 3, 2, 1}));
- }
- Y_UNIT_TEST(AdjacentFindByTest) {
- TVector<int> v0;
- UNIT_ASSERT_EQUAL(AdjacentFindBy(v0, std::negate<int>()), v0.end());
- TVector<int> v1 = {1};
- UNIT_ASSERT_EQUAL(AdjacentFindBy(v1, std::negate<int>()), v1.end());
- const int v2[] = {8, 7, 6, 6, 5, 5, 5, 4, 3, 2, 1};
- UNIT_ASSERT_EQUAL(AdjacentFindBy(v2, std::negate<int>()), std::begin(v2) + 2);
- UNIT_ASSERT_EQUAL(AdjacentFindBy(v2, [](const auto& e) { return e / 8; }), std::begin(v2) + 1);
- TVector<TStringBuf> v3 = {"six", "five", "four", "three", "two", "one"};
- UNIT_ASSERT_EQUAL(AdjacentFind(v3), v3.end());
- UNIT_ASSERT_EQUAL(AdjacentFindBy(v3, std::mem_fn(&TStringBuf::size)), v3.begin() + 1);
- TVector<int> v4 = {101, 201, 301, 401, 501};
- for (;;) {
- if (auto it = AdjacentFindBy(v4, [](int a) { return a % 10; }); it == v4.end()) {
- break;
- } else {
- *it += 1;
- }
- }
- UNIT_ASSERT_VALUES_EQUAL(v4, (TVector<int>{105, 204, 303, 402, 501}));
- }
- Y_UNIT_TEST(IsSortedTest) {
- TVector<int> v0;
- UNIT_ASSERT_VALUES_EQUAL(IsSorted(v0.begin(), v0.end()), true);
- TVector<int> v1 = {1, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8};
- UNIT_ASSERT_VALUES_EQUAL(IsSorted(v1.begin(), v1.end()), true);
- UNIT_ASSERT_VALUES_EQUAL(IsSorted(v1.begin(), v1.end(), TLess<int>()), true);
- UNIT_ASSERT_VALUES_EQUAL(IsSorted(v1.begin(), v1.end(), TGreater<int>()), false);
- TVector<int> v2 = {1, 2, 1};
- UNIT_ASSERT_VALUES_EQUAL(IsSorted(v2.begin(), v2.end()), false);
- UNIT_ASSERT_VALUES_EQUAL(IsSorted(v2.begin(), v2.end(), TLess<int>()), false);
- UNIT_ASSERT_VALUES_EQUAL(IsSorted(v2.begin(), v2.end(), TGreater<int>()), false);
- }
- Y_UNIT_TEST(IsSortedByTest) {
- TVector<int> v0;
- UNIT_ASSERT_VALUES_EQUAL(IsSortedBy(v0.begin(), v0.end(), std::negate<int>()), true);
- UNIT_ASSERT_VALUES_EQUAL(IsSortedBy(v0, std::negate<int>()), true);
- TVector<int> v1 = {1};
- UNIT_ASSERT_VALUES_EQUAL(IsSortedBy(v1.begin(), v1.end(), std::negate<int>()), true);
- UNIT_ASSERT_VALUES_EQUAL(IsSortedBy(v1, std::negate<int>()), true);
- TVector<int> v2 = {8, 7, 6, 6, 5, 5, 5, 4, 3, 2, 1};
- UNIT_ASSERT_VALUES_EQUAL(IsSortedBy(v2.begin(), v2.end(), std::negate<int>()), true);
- UNIT_ASSERT_VALUES_EQUAL(IsSortedBy(v2, std::negate<int>()), true);
- TVector<int> v3 = {1, 2, 1};
- UNIT_ASSERT_VALUES_EQUAL(IsSortedBy(v3.begin(), v3.end(), std::negate<int>()), false);
- UNIT_ASSERT_VALUES_EQUAL(IsSortedBy(v3, std::negate<int>()), false);
- }
- Y_UNIT_TEST(SortTestTwoIterators) {
- TVector<int> collection = {10, 2, 7};
- Sort(collection.begin(), collection.end());
- TVector<int> expected = {2, 7, 10};
- UNIT_ASSERT_VALUES_EQUAL(collection, expected);
- }
- Y_UNIT_TEST(SortTestTwoIteratorsAndComparator) {
- TVector<int> collection = {10, 2, 7};
- Sort(collection.begin(), collection.end(), [](int l, int r) { return l > r; });
- TVector<int> expected = {10, 7, 2};
- UNIT_ASSERT_VALUES_EQUAL(collection, expected);
- }
- Y_UNIT_TEST(SortTestContainer) {
- TVector<int> collection = {10, 2, 7};
- Sort(collection);
- TVector<int> expected = {2, 7, 10};
- UNIT_ASSERT_VALUES_EQUAL(collection, expected);
- }
- Y_UNIT_TEST(SortTestContainerAndComparator) {
- TVector<int> collection = {10, 2, 7};
- Sort(collection, [](int l, int r) { return l > r; });
- TVector<int> expected = {10, 7, 2};
- UNIT_ASSERT_VALUES_EQUAL(collection, expected);
- }
- Y_UNIT_TEST(StableSortTestTwoIterators) {
- TVector<int> collection = {10, 2, 7};
- StableSort(collection.begin(), collection.end());
- TVector<int> expected = {2, 7, 10};
- UNIT_ASSERT_VALUES_EQUAL(collection, expected);
- }
- Y_UNIT_TEST(StableSortTestTwoIteratorsAndComparator) {
- TVector<int> collection = {404, 101, 106, 203, 102, 205, 401};
- StableSort(collection.begin(), collection.end(), [](int l, int r) { return (l / 100) < (r / 100); });
- TVector<int> expected = {101, 106, 102, 203, 205, 404, 401};
- UNIT_ASSERT_VALUES_EQUAL(collection, expected);
- }
- Y_UNIT_TEST(StableSortTestContainer) {
- TVector<int> collection = {10, 2, 7};
- StableSort(collection);
- TVector<int> expected = {2, 7, 10};
- UNIT_ASSERT_VALUES_EQUAL(collection, expected);
- }
- Y_UNIT_TEST(StableSortTestContainerAndComparator) {
- TVector<int> collection = {404, 101, 106, 203, 102, 205, 401};
- StableSort(collection, [](int l, int r) { return (l / 100) < (r / 100); });
- TVector<int> expected = {101, 106, 102, 203, 205, 404, 401};
- UNIT_ASSERT_VALUES_EQUAL(collection, expected);
- }
- Y_UNIT_TEST(SortByTest) {
- TVector<int> collection = {10, 2, 7};
- SortBy(collection, [](int x) { return -x; });
- TVector<int> expected = {10, 7, 2};
- UNIT_ASSERT_VALUES_EQUAL(collection, expected);
- }
- Y_UNIT_TEST(StableSortByTest) {
- TVector<int> collection = {404, 101, 106, 203, 102, 205, 401};
- StableSortBy(collection, [](int x) { return x / 100; });
- TVector<int> expected = {101, 106, 102, 203, 205, 404, 401};
- UNIT_ASSERT_VALUES_EQUAL(collection, expected);
- }
- Y_UNIT_TEST(SortUniqueByTest) {
- TVector<int> collection = {404, 101, 101, 203, 101, 203, 404};
- StableSortUniqueBy(collection, [](int x) { return x / 100; });
- TVector<int> expected = {101, 203, 404};
- UNIT_ASSERT_VALUES_EQUAL(collection, expected);
- }
- Y_UNIT_TEST(StableSortUniqueByTest) {
- TVector<int> collection = {404, 101, 106, 203, 102, 205, 401};
- StableSortUniqueBy(collection, [](int x) { return x / 100; });
- TVector<int> expected = {101, 203, 404};
- UNIT_ASSERT_VALUES_EQUAL(collection, expected);
- }
- Y_UNIT_TEST(IotaTest) {
- TVector<int> v(10);
- Iota(v.begin(), v.end(), 0);
- UNIT_ASSERT_VALUES_EQUAL(v[0], 0);
- UNIT_ASSERT_VALUES_EQUAL(v[5], 5);
- UNIT_ASSERT_VALUES_EQUAL(v[9], 9);
- Iota(v.begin() + 2, v.begin() + 5, 162);
- UNIT_ASSERT_VALUES_EQUAL(v[0], 0);
- UNIT_ASSERT_VALUES_EQUAL(v[3], 163);
- UNIT_ASSERT_VALUES_EQUAL(v[9], 9);
- }
- Y_UNIT_TEST(CopyNTest) {
- int data[] = {1, 2, 3, 4, 8, 7, 6, 5};
- const size_t vSize = 10;
- TVector<int> result(10, 0);
- size_t toCopy = 5;
- TVector<int>::iterator iter = CopyN(data, toCopy, result.begin());
- UNIT_ASSERT_VALUES_EQUAL(iter - result.begin(), toCopy);
- UNIT_ASSERT_VALUES_EQUAL(result.size(), 10);
- for (size_t idx = 0; idx < toCopy; ++idx) {
- UNIT_ASSERT_VALUES_EQUAL(data[idx], result[idx]);
- }
- for (size_t idx = toCopy; idx < vSize; ++idx) {
- UNIT_ASSERT_VALUES_EQUAL(result[idx], 0);
- }
- toCopy = 8;
- const size_t start = 1;
- result.assign(vSize, 0);
- iter = CopyN(data, toCopy, result.begin() + start);
- UNIT_ASSERT_VALUES_EQUAL(iter - result.begin(), start + toCopy);
- for (size_t idx = 0; idx < start; ++idx) {
- UNIT_ASSERT_VALUES_EQUAL(result[idx], 0);
- }
- for (size_t idx = 0; idx < toCopy; ++idx) {
- UNIT_ASSERT_VALUES_EQUAL(result[start + idx], data[idx]);
- }
- for (size_t idx = start + toCopy; idx < vSize; ++idx) {
- UNIT_ASSERT_VALUES_EQUAL(result[idx], 0);
- }
- }
- Y_UNIT_TEST(CopyIfTest) {
- const size_t count = 9;
- int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
- const size_t vSize = 10;
- TVector<int> v(vSize, 0);
- TVector<int>::iterator iter = CopyIf(data, data + count, v.begin(), [](int x) { return !(x % 3); });
- UNIT_ASSERT_VALUES_EQUAL(v.size(), vSize);
- UNIT_ASSERT_VALUES_EQUAL(iter - v.begin(), 3);
- v.resize(iter - v.begin());
- for (size_t idx = 0; idx < v.size(); ++idx) {
- UNIT_ASSERT_VALUES_EQUAL(v[idx], 3 * (idx + 1));
- }
- }
- Y_UNIT_TEST(MinMaxElementTest) {
- TVector<int> v(10);
- Iota(v.begin(), v.end(), 0);
- UNIT_ASSERT_EQUAL(*MinMaxElement(v.begin(), v.end()).first, 0);
- UNIT_ASSERT_EQUAL(*MinMaxElement(v.begin(), v.end()).second, 9);
- v[3] = -2;
- v[7] = 11;
- UNIT_ASSERT_EQUAL(*MinMaxElement(v.begin(), v.end()).first, -2);
- UNIT_ASSERT_EQUAL(*MinMaxElement(v.begin(), v.end()).second, 11);
- }
- Y_UNIT_TEST(MinMaxTest) {
- std::pair<int, int> p1 = MinMax(5, 12);
- UNIT_ASSERT_EQUAL(p1.first, 5);
- UNIT_ASSERT_EQUAL(p1.second, 12);
- std::pair<TString, TString> p2 = MinMax(TString("test"), TString("data"));
- UNIT_ASSERT_EQUAL(p2.first, TString("data"));
- UNIT_ASSERT_EQUAL(p2.second, TString("test"));
- }
- Y_UNIT_TEST(TestMaxElementBy) {
- const int array[] = {1, 2, 5, 3, 4, 5};
- UNIT_ASSERT_VALUES_EQUAL(*MaxElementBy(array, [](int x) {
- return x * x;
- }), 5);
- const TVector<int> vec(array, array + Y_ARRAY_SIZE(array));
- UNIT_ASSERT_VALUES_EQUAL(*MaxElementBy(vec, [](int x) {
- return -1.0 * x;
- }), 1);
- int arrayMutable[] = {1, 2, 5, 3, 4, 5};
- auto maxPtr = MaxElementBy(arrayMutable, [](int x) { return x; });
- *maxPtr += 100;
- UNIT_ASSERT_VALUES_EQUAL(*maxPtr, 105);
- auto identity = [](char x) {
- return x;
- };
- auto singleElementSequence = {'z'};
- UNIT_ASSERT_VALUES_EQUAL(*MaxElementBy(singleElementSequence, identity), 'z');
- const TString strings[] = {"one", "two", "three", "four"};
- UNIT_ASSERT_STRINGS_EQUAL(*MaxElementBy(strings, [](TString s) { return s.size(); }), "three");
- }
- Y_UNIT_TEST(TestMinElementBy) {
- const int array[] = {2, 3, 4, 1, 5};
- UNIT_ASSERT_VALUES_EQUAL(*MinElementBy(array, [](int x) -> char {
- return 'a' + x;
- }), 1);
- const TVector<int> vec(std::begin(array), std::end(array));
- UNIT_ASSERT_VALUES_EQUAL(*MinElementBy(vec, [](int x) {
- return -x;
- }), 5);
- int arrayMutable[] = {1, 2, 5, 3, 4, 5};
- auto minPtr = MinElementBy(arrayMutable, [](int x) { return x; });
- *minPtr += 100;
- UNIT_ASSERT_VALUES_EQUAL(*minPtr, 101);
- auto identity = [](char x) {
- return x;
- };
- auto singleElementSequence = {'z'};
- UNIT_ASSERT_VALUES_EQUAL(*MinElementBy(singleElementSequence, identity), 'z');
- const TVector<TStringBuf> strings = {"one", "two", "three", "four"};
- auto stringLength = [](TStringBuf s) {
- return s.size();
- };
- UNIT_ASSERT_STRINGS_EQUAL(*MinElementBy(strings, stringLength), "one");
- UNIT_ASSERT_STRINGS_EQUAL(*MinElementBy(strings.rbegin(), strings.rend(), stringLength), "two");
- }
- Y_UNIT_TEST(MaxElementByReturnsEndForEmptyRange) {
- const TVector<int> empty;
- UNIT_ASSERT_EQUAL(MaxElementBy(empty, [](int) { return 0; }), empty.end());
- }
- Y_UNIT_TEST(MaxElementByDoesntCallFunctorForEmptyRange) {
- const TVector<int> empty;
- auto functor = [](int) {
- UNIT_ASSERT(false);
- return 0;
- };
- MaxElementBy(empty, functor);
- }
- Y_UNIT_TEST(MinElementByReturnsEndForEmptyRange) {
- const TVector<int> empty;
- UNIT_ASSERT_EQUAL(MinElementBy(empty, [](int) { return 0; }), empty.end());
- }
- Y_UNIT_TEST(MinElementByDoesntCallFunctorForEmptyRange) {
- const TVector<int> empty;
- auto functor = [](int) {
- UNIT_ASSERT(false);
- return 0;
- };
- MinElementBy(empty, functor);
- }
- Y_UNIT_TEST(TestApplyToMany) {
- int res = 0;
- ApplyToMany([&res](auto v) { res += v; }, 1, 2, 3, 4, 5);
- UNIT_ASSERT_EQUAL(res, 15);
- struct TVisitor {
- TVisitor(int& acc)
- : Acc(acc)
- {
- }
- void operator()(const TString& s) {
- Acc += s.size();
- }
- void operator()(int v) {
- Acc += v * 2;
- }
- int& Acc;
- };
- TString s{"8-800-555-35-35"};
- ApplyToMany(TVisitor{res = 0}, 1, s, 5, s);
- UNIT_ASSERT_EQUAL(res, 12 + 2 * static_cast<int>(s.size()));
- }
- Y_UNIT_TEST(TestTupleForEach) {
- ForEach(std::tuple<>{}, [&](auto) { UNIT_ASSERT(false); });
- auto t = std::make_tuple(5, 6, 2, 3, 6);
- ForEach(t, [](auto& v) { v *= -1; });
- UNIT_ASSERT_EQUAL(t, std::make_tuple(-5, -6, -2, -3, -6));
- }
- Y_UNIT_TEST(TestTupleAllOf) {
- UNIT_ASSERT(AllOf(std::tuple<>{}, [](auto) { return false; }));
- UNIT_ASSERT(!AllOf(std::make_tuple(1, 2, 0, 4, 5), [&](auto v) { UNIT_ASSERT_LT(v, 3); return 0 != v; }));
- UNIT_ASSERT(AllOf(std::make_tuple(1, 2, 3, 4, 5), [](auto v) { return 0 != v; }));
- {
- auto pred = std::function<bool(int)>([x = TVector<int>(1, 0)](auto v) { return x.front() != v; });
- UNIT_ASSERT(AllOf(std::make_tuple(1, 2), pred));
- UNIT_ASSERT(AllOf(std::make_tuple(1, 2), pred));
- }
- {
- auto ts = std::make_tuple(TString{"foo"}, TString{"bar"});
- auto pred = [](auto s) { return s.size() == 3; };
- UNIT_ASSERT_VALUES_EQUAL(AllOf(ts, pred), AllOf(ts, pred));
- }
- }
- Y_UNIT_TEST(TestTupleAnyOf) {
- UNIT_ASSERT(!AnyOf(std::tuple<>{}, [](auto) { return true; }));
- UNIT_ASSERT(AnyOf(std::make_tuple(0, 1, 2, 3, 4), [&](auto v) { UNIT_ASSERT_LT(v, 2); return 1 == v; }));
- UNIT_ASSERT(AnyOf(std::make_tuple(1, 2, 3, 4, 5), [](auto v) { return 5 == v; }));
- auto pred = std::function<bool(int)>([x = TVector<int>(1, 0)](auto v) { return x.front() == v; });
- UNIT_ASSERT(!AnyOf(std::make_tuple(1, 2), pred));
- UNIT_ASSERT(!AnyOf(std::make_tuple(1, 2), pred));
- {
- auto ts = std::make_tuple(TString{"f"}, TString{"bar"});
- auto pred = [](auto s) { return s.size() == 3; };
- UNIT_ASSERT_VALUES_EQUAL(AnyOf(ts, pred), AnyOf(ts, pred));
- }
- }
- Y_UNIT_TEST(FindIfForContainer) {
- using std::begin;
- using std::end;
- int array[] = {1, 2, 3, 4, 5};
- UNIT_ASSERT_EQUAL(FindIf(array, [](int x) { return x == 1; }), begin(array));
- UNIT_ASSERT_EQUAL(FindIf(array, [](int x) { return x > 5; }), end(array));
- TVector<int> vector = {1, 2, 3, 4, 5};
- UNIT_ASSERT_EQUAL(FindIf(vector, [](int x) { return x == 1; }), begin(vector));
- UNIT_ASSERT_EQUAL(FindIf(vector, [](int x) { return x > 5; }), end(vector));
- // Compilability test. Check if the returned iterator is non const
- auto iter = FindIf(vector, [](int x) { return x == 1; });
- *iter = 5;
- // Compilability test. Check if the returned iterator is const. Should not compile
- const TVector<int> constVector = {1, 2, 3, 4, 5};
- auto constIter = FindIf(constVector, [](int x) { return x == 1; });
- Y_UNUSED(constIter);
- // *constIter = 5;
- }
- struct TRange {
- };
- const TRange* begin(const TRange& r) {
- return &r;
- }
- const TRange* end(const TRange& r) {
- return &r + 1;
- }
- Y_UNIT_TEST(FindIfForUserType) {
- // Compileability test. Should work for user types with begin/end overloads
- TRange range;
- auto i = FindIf(range, [](auto) { return false; });
- Y_UNUSED(i);
- }
- Y_UNIT_TEST(TestLowerBoundBy) {
- using TIntPairs = TVector<std::pair<i32, i32>>;
- auto data = TIntPairs{{1, 5}, {3, 2}, {3, 4}, {8, 0}, {5, 4}};
- auto getKey = [](const auto& x) { return x.second; };
- StableSortBy(data, getKey);
- auto it = LowerBoundBy(data.begin(), data.end(), 4, getKey);
- UNIT_ASSERT(it != data.end());
- UNIT_ASSERT_EQUAL(it->second, 4);
- UNIT_ASSERT_EQUAL(it->first, 3);
- UNIT_ASSERT(it > data.begin());
- UNIT_ASSERT_EQUAL((it - 1)->second, 2);
- UNIT_ASSERT((it + 1) < data.end());
- UNIT_ASSERT_EQUAL((it + 1)->second, 4);
- }
- Y_UNIT_TEST(TestUpperBoundBy) {
- using TIntPairs = TVector<std::pair<i32, i32>>;
- auto data = TIntPairs{{1, 5}, {3, 2}, {3, 4}, {8, 0}, {5, 4}};
- auto getKey = [](const auto& x) { return x.second; };
- StableSortBy(data, getKey);
- auto it = UpperBoundBy(data.begin(), data.end(), 4, getKey);
- UNIT_ASSERT(it != data.end());
- UNIT_ASSERT_EQUAL(it->second, 5);
- UNIT_ASSERT_EQUAL(it->first, 1);
- UNIT_ASSERT(it > data.begin());
- UNIT_ASSERT_EQUAL((it - 1)->second, 4);
- UNIT_ASSERT((it + 1) == data.end());
- }
- Y_UNIT_TEST(TestFindInContainer) {
- std::vector<int> v = {1, 2, 1000, 15, 100};
- UNIT_ASSERT(Find(v, 5) == v.end());
- UNIT_ASSERT(Find(v, 1) == v.begin());
- UNIT_ASSERT(Find(v, 100) == v.end() - 1);
- }
- Y_UNIT_TEST(AccumulateWithBinOp) {
- std::vector<int> v = {1, 2, 777};
- UNIT_ASSERT_VALUES_EQUAL(TString("begin;1;2;777"), Accumulate(v, TString("begin"), [](auto&& a, auto& b) { return a + ";" + ToString(b); }));
- }
- }
|