123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496 |
- #include "map.h"
- #include <library/cpp/testing/unittest/registar.h>
- #include <util/memory/pool.h>
- #include <algorithm>
- Y_UNIT_TEST_SUITE(TYMapTest) {
- template <typename TAlloc>
- void DoTestMap1(TMap<char, int, TLess<char>, TAlloc>& m);
- template <typename TAlloc>
- void DoTestMMap1(TMultiMap<char, int, TLess<char>, TAlloc>& mm);
- Y_UNIT_TEST(TestMap1) {
- {
- TMap<char, int, TLess<char>> m;
- DoTestMap1(m);
- }
- {
- TMemoryPool p(100);
- TMap<char, int, TLess<char>, TPoolAllocator> m(&p);
- DoTestMap1(m);
- }
- }
- Y_UNIT_TEST(TestMMap1) {
- {
- TMultiMap<char, int, TLess<char>> mm;
- DoTestMMap1(mm);
- }
- {
- TMemoryPool p(100);
- TMultiMap<char, int, TLess<char>, TPoolAllocator> mm(&p);
- DoTestMMap1(mm);
- }
- }
- template <typename TAlloc>
- void DoTestMap1(TMap<char, int, TLess<char>, TAlloc>& m) {
- using maptype = TMap<char, int, TLess<char>, TAlloc>;
- // Store mappings between roman numerals and decimals.
- m['l'] = 50;
- m['x'] = 20; // Deliberate mistake.
- m['v'] = 5;
- m['i'] = 1;
- UNIT_ASSERT(m['x'] == 20);
- m['x'] = 10; // Correct mistake.
- UNIT_ASSERT(m['x'] == 10);
- UNIT_ASSERT(m['z'] == 0);
- UNIT_ASSERT(m.count('z') == 1);
- std::pair<typename maptype::iterator, bool> p = m.insert(std::pair<const char, int>('c', 100));
- UNIT_ASSERT(p.second);
- UNIT_ASSERT(p.first != m.end());
- UNIT_ASSERT((*p.first).first == 'c');
- UNIT_ASSERT((*p.first).second == 100);
- p = m.insert(std::pair<const char, int>('c', 100));
- UNIT_ASSERT(!p.second); // already existing pair
- UNIT_ASSERT(p.first != m.end());
- UNIT_ASSERT((*p.first).first == 'c');
- UNIT_ASSERT((*p.first).second == 100);
- }
- template <typename TAlloc>
- void DoTestMMap1(TMultiMap<char, int, TLess<char>, TAlloc>& m) {
- using mmap = TMultiMap<char, int, TLess<char>, TAlloc>;
- UNIT_ASSERT(m.count('X') == 0);
- m.insert(std::pair<const char, int>('X', 10)); // Standard way.
- UNIT_ASSERT(m.count('X') == 1);
- m.insert(std::pair<const char, int>('X', 20)); // jbuck: standard way
- UNIT_ASSERT(m.count('X') == 2);
- m.insert(std::pair<const char, int>('Y', 32)); // jbuck: standard way
- typename mmap::iterator i = m.find('X'); // Find first match.
- ++i;
- UNIT_ASSERT((*i).first == 'X');
- UNIT_ASSERT((*i).second == 20);
- ++i;
- UNIT_ASSERT((*i).first == 'Y');
- UNIT_ASSERT((*i).second == 32);
- ++i;
- UNIT_ASSERT(i == m.end());
- size_t count = m.erase('X');
- UNIT_ASSERT(count == 2);
- }
- Y_UNIT_TEST(TestMMap2) {
- using pair_type = std::pair<const int, char>;
- pair_type p1(3, 'c');
- pair_type p2(6, 'f');
- pair_type p3(1, 'a');
- pair_type p4(2, 'b');
- pair_type p5(3, 'x');
- pair_type p6(6, 'f');
- using mmap = TMultiMap<int, char, TLess<int>>;
- pair_type array[] = {
- p1,
- p2,
- p3,
- p4,
- p5,
- p6};
- mmap m(array + 0, array + 6);
- mmap::iterator i;
- i = m.lower_bound(3);
- UNIT_ASSERT((*i).first == 3);
- UNIT_ASSERT((*i).second == 'c');
- i = m.upper_bound(3);
- UNIT_ASSERT((*i).first == 6);
- UNIT_ASSERT((*i).second == 'f');
- }
- Y_UNIT_TEST(TestIterators) {
- using int_map = TMap<int, char, TLess<int>>;
- int_map imap;
- {
- int_map::iterator ite(imap.begin());
- int_map::const_iterator cite(imap.begin());
- UNIT_ASSERT(ite == cite);
- UNIT_ASSERT(!(ite != cite));
- UNIT_ASSERT(cite == ite);
- UNIT_ASSERT(!(cite != ite));
- }
- using mmap = TMultiMap<int, char, TLess<int>>;
- using pair_type = mmap::value_type;
- pair_type p1(3, 'c');
- pair_type p2(6, 'f');
- pair_type p3(1, 'a');
- pair_type p4(2, 'b');
- pair_type p5(3, 'x');
- pair_type p6(6, 'f');
- pair_type array[] = {
- p1,
- p2,
- p3,
- p4,
- p5,
- p6};
- mmap m(array + 0, array + 6);
- {
- mmap::iterator ite(m.begin());
- mmap::const_iterator cite(m.begin());
- //test compare between const_iterator and iterator
- UNIT_ASSERT(ite == cite);
- UNIT_ASSERT(!(ite != cite));
- UNIT_ASSERT(cite == ite);
- UNIT_ASSERT(!(cite != ite));
- }
- mmap::reverse_iterator ri = m.rbegin();
- UNIT_ASSERT(ri != m.rend());
- UNIT_ASSERT(ri == m.rbegin());
- UNIT_ASSERT((*ri).first == 6);
- UNIT_ASSERT((*ri++).second == 'f');
- UNIT_ASSERT((*ri).first == 6);
- UNIT_ASSERT((*ri).second == 'f');
- mmap const& cm = m;
- mmap::const_reverse_iterator rci = cm.rbegin();
- UNIT_ASSERT(rci != cm.rend());
- UNIT_ASSERT((*rci).first == 6);
- UNIT_ASSERT((*rci++).second == 'f');
- UNIT_ASSERT((*rci).first == 6);
- UNIT_ASSERT((*rci).second == 'f');
- }
- Y_UNIT_TEST(TestEqualRange) {
- using maptype = TMap<char, int, TLess<char>>;
- {
- maptype m;
- m['x'] = 10;
- std::pair<maptype::iterator, maptype::iterator> ret;
- ret = m.equal_range('x');
- UNIT_ASSERT(ret.first != ret.second);
- UNIT_ASSERT((*(ret.first)).first == 'x');
- UNIT_ASSERT((*(ret.first)).second == 10);
- UNIT_ASSERT(++(ret.first) == ret.second);
- }
- {
- {
- maptype m;
- maptype::iterator i = m.lower_bound('x');
- UNIT_ASSERT(i == m.end());
- i = m.upper_bound('x');
- UNIT_ASSERT(i == m.end());
- std::pair<maptype::iterator, maptype::iterator> ret;
- ret = m.equal_range('x');
- UNIT_ASSERT(ret.first == ret.second);
- UNIT_ASSERT(ret.first == m.end());
- }
- {
- const maptype m;
- std::pair<maptype::const_iterator, maptype::const_iterator> ret;
- ret = m.equal_range('x');
- UNIT_ASSERT(ret.first == ret.second);
- UNIT_ASSERT(ret.first == m.end());
- }
- }
- }
- struct TKey {
- TKey()
- : m_data(0)
- {
- }
- explicit TKey(int data)
- : m_data(data)
- {
- }
- int m_data;
- };
- struct TKeyCmp {
- bool operator()(TKey lhs, TKey rhs) const {
- return lhs.m_data < rhs.m_data;
- }
- bool operator()(TKey lhs, int rhs) const {
- return lhs.m_data < rhs;
- }
- bool operator()(int lhs, TKey rhs) const {
- return lhs < rhs.m_data;
- }
- using is_transparent = void;
- };
- struct TKeyCmpPtr {
- bool operator()(TKey const volatile* lhs, TKey const volatile* rhs) const {
- return (*lhs).m_data < (*rhs).m_data;
- }
- bool operator()(TKey const volatile* lhs, int rhs) const {
- return (*lhs).m_data < rhs;
- }
- bool operator()(int lhs, TKey const volatile* rhs) const {
- return lhs < (*rhs).m_data;
- }
- using is_transparent = void;
- };
- Y_UNIT_TEST(TestTemplateMethods) {
- {
- using Container = TMap<TKey, int, TKeyCmp>;
- using value = Container::value_type;
- Container cont;
- cont.insert(value(TKey(1), 1));
- cont.insert(value(TKey(2), 2));
- cont.insert(value(TKey(3), 3));
- cont.insert(value(TKey(4), 4));
- UNIT_ASSERT(cont.count(TKey(1)) == 1);
- UNIT_ASSERT(cont.count(1) == 1);
- UNIT_ASSERT(cont.count(5) == 0);
- UNIT_ASSERT(cont.find(2) != cont.end());
- UNIT_ASSERT(cont.lower_bound(2) != cont.end());
- UNIT_ASSERT(cont.upper_bound(2) != cont.end());
- UNIT_ASSERT(cont.equal_range(2) != std::make_pair(cont.begin(), cont.end()));
- Container const& ccont = cont;
- UNIT_ASSERT(ccont.find(2) != ccont.end());
- UNIT_ASSERT(ccont.lower_bound(2) != ccont.end());
- UNIT_ASSERT(ccont.upper_bound(2) != ccont.end());
- UNIT_ASSERT(ccont.equal_range(2) != std::make_pair(ccont.end(), ccont.end()));
- }
- {
- using Container = TMap<TKey*, int, TKeyCmpPtr>;
- using value = Container::value_type;
- Container cont;
- TKey key1(1), key2(2), key3(3), key4(4);
- cont.insert(value(&key1, 1));
- cont.insert(value(&key2, 2));
- cont.insert(value(&key3, 3));
- cont.insert(value(&key4, 4));
- UNIT_ASSERT(cont.count(1) == 1);
- UNIT_ASSERT(cont.count(5) == 0);
- UNIT_ASSERT(cont.find(2) != cont.end());
- UNIT_ASSERT(cont.lower_bound(2) != cont.end());
- UNIT_ASSERT(cont.upper_bound(2) != cont.end());
- UNIT_ASSERT(cont.equal_range(2) != std::make_pair(cont.begin(), cont.end()));
- Container const& ccont = cont;
- UNIT_ASSERT(ccont.find(2) != ccont.end());
- UNIT_ASSERT(ccont.lower_bound(2) != ccont.end());
- UNIT_ASSERT(ccont.upper_bound(2) != ccont.end());
- UNIT_ASSERT(ccont.equal_range(2) != std::make_pair(ccont.begin(), ccont.end()));
- }
- {
- using Container = TMultiMap<TKey, int, TKeyCmp>;
- using value = Container::value_type;
- Container cont;
- cont.insert(value(TKey(1), 1));
- cont.insert(value(TKey(2), 2));
- cont.insert(value(TKey(3), 3));
- cont.insert(value(TKey(4), 4));
- UNIT_ASSERT(cont.count(TKey(1)) == 1);
- UNIT_ASSERT(cont.count(1) == 1);
- UNIT_ASSERT(cont.count(5) == 0);
- UNIT_ASSERT(cont.find(2) != cont.end());
- UNIT_ASSERT(cont.lower_bound(2) != cont.end());
- UNIT_ASSERT(cont.upper_bound(2) != cont.end());
- UNIT_ASSERT(cont.equal_range(2) != std::make_pair(cont.begin(), cont.end()));
- Container const& ccont = cont;
- UNIT_ASSERT(ccont.find(2) != ccont.end());
- UNIT_ASSERT(ccont.lower_bound(2) != ccont.end());
- UNIT_ASSERT(ccont.upper_bound(2) != ccont.end());
- UNIT_ASSERT(ccont.equal_range(2) != std::make_pair(ccont.end(), ccont.end()));
- }
- {
- using Container = TMultiMap<TKey const volatile*, int, TKeyCmpPtr>;
- using value = Container::value_type;
- Container cont;
- TKey key1(1), key2(2), key3(3), key4(4);
- cont.insert(value(&key1, 1));
- cont.insert(value(&key2, 2));
- cont.insert(value(&key3, 3));
- cont.insert(value(&key4, 4));
- UNIT_ASSERT(cont.count(1) == 1);
- UNIT_ASSERT(cont.count(5) == 0);
- UNIT_ASSERT(cont.find(2) != cont.end());
- UNIT_ASSERT(cont.lower_bound(2) != cont.end());
- UNIT_ASSERT(cont.upper_bound(2) != cont.end());
- UNIT_ASSERT(cont.equal_range(2) != std::make_pair(cont.begin(), cont.end()));
- Container const& ccont = cont;
- UNIT_ASSERT(ccont.find(2) != ccont.end());
- UNIT_ASSERT(ccont.lower_bound(2) != ccont.end());
- UNIT_ASSERT(ccont.upper_bound(2) != ccont.end());
- UNIT_ASSERT(ccont.equal_range(2) != std::make_pair(ccont.begin(), ccont.end()));
- }
- }
- template <typename T>
- static void EmptyAndInsertTest(typename T::value_type v) {
- T c;
- UNIT_ASSERT(!c);
- c.insert(v);
- UNIT_ASSERT(c);
- }
- Y_UNIT_TEST(TestEmpty) {
- EmptyAndInsertTest<TMap<char, int, TLess<char>>>(std::pair<char, int>('a', 1));
- EmptyAndInsertTest<TMultiMap<char, int, TLess<char>>>(std::pair<char, int>('a', 1));
- }
- struct TParametrizedKeyCmp {
- bool Inverse;
- TParametrizedKeyCmp(bool inverse = false)
- : Inverse(inverse)
- {
- }
- bool operator()(TKey lhs, TKey rhs) const {
- if (Inverse) {
- return lhs.m_data > rhs.m_data;
- } else {
- return lhs.m_data < rhs.m_data;
- }
- }
- };
- Y_UNIT_TEST(TestMoveComparator) {
- using Container = TMultiMap<TKey, int, TParametrizedKeyCmp>;
- TParametrizedKeyCmp direct(false);
- TParametrizedKeyCmp inverse(true);
- {
- Container c(direct);
- c = Container(inverse);
- c.insert(std::make_pair(TKey(1), 101));
- c.insert(std::make_pair(TKey(2), 102));
- c.insert(std::make_pair(TKey(3), 103));
- TVector<int> values;
- for (auto& i : c) {
- values.push_back(i.second);
- }
- UNIT_ASSERT_VALUES_EQUAL(values.size(), 3);
- UNIT_ASSERT_VALUES_EQUAL(values[0], 103);
- UNIT_ASSERT_VALUES_EQUAL(values[1], 102);
- UNIT_ASSERT_VALUES_EQUAL(values[2], 101);
- }
- }
- Y_UNIT_TEST(TestMapInitializerList) {
- TMap<TString, int> m = {
- {"one", 1},
- {"two", 2},
- {"three", 3},
- {"four", 4},
- };
- UNIT_ASSERT_VALUES_EQUAL(m.size(), 4);
- UNIT_ASSERT_VALUES_EQUAL(m["one"], 1);
- UNIT_ASSERT_VALUES_EQUAL(m["two"], 2);
- UNIT_ASSERT_VALUES_EQUAL(m["three"], 3);
- UNIT_ASSERT_VALUES_EQUAL(m["four"], 4);
- }
- Y_UNIT_TEST(TestMMapInitializerList) {
- TMultiMap<TString, int> mm = {
- {"one", 1},
- {"two", 2},
- {"two", -2},
- {"three", 3},
- };
- UNIT_ASSERT(mm.contains("two"));
- TMultiMap<TString, int> expected;
- expected.emplace("one", 1);
- expected.emplace("two", 2);
- expected.emplace("two", -2);
- expected.emplace("three", 3);
- UNIT_ASSERT_VALUES_EQUAL(mm, expected);
- }
- Y_UNIT_TEST(TestMovePoolAlloc) {
- using TMapInPool = TMap<int, int, TLess<int>, TPoolAllocator>;
- TMemoryPool pool(1);
- TMapInPool m(&pool);
- m.emplace(0, 1);
- UNIT_ASSERT(m.contains(0));
- UNIT_ASSERT_VALUES_EQUAL(1, m[0]);
- TMapInPool movedM = std::move(m);
- UNIT_ASSERT(movedM.contains(0));
- UNIT_ASSERT_VALUES_EQUAL(1, movedM[0]);
- }
- }
|