Jlm
BijectiveMapTests.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2023 HÃ¥vard Krogstie <krogstie.havard@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
6 #include <gtest/gtest.h>
7 
9 
10 #include <string>
11 
12 TEST(BijectiveMapTests, TestBijectiveMapConstructors)
13 {
14  using namespace jlm::util;
15 
16  const BijectiveMap<int, std::string> emptyBiMap;
17  EXPECT_EQ(emptyBiMap.Size(), 0u);
18 
19  // Construct from iterator range
20  std::unordered_map<int, std::string> unordMap = { { 10, "Ten" }, { 20, "Twenty" } };
21  BijectiveMap<int, std::string> rangeBiMap(unordMap.begin(), unordMap.end());
22  EXPECT_EQ(rangeBiMap.Size(), 2u);
23 
24  // Make the unordered map illegal
25  unordMap[30] = "Twenty";
26  EXPECT_THROW(
27  (BijectiveMap<int, std::string>{ unordMap.begin(), unordMap.end() }),
29 
30  // Construct from initializer list
31  BijectiveMap<int, std::string> biMap = { { 10, "Ten" }, { 20, "Twenty" } };
32  assert(biMap.Size() == 2);
33 
34  // Construct from illegal initalizer list
35  EXPECT_THROW(
36  (BijectiveMap<int, std::string>{ { 10, "Ten" }, { 10, "Twenty" } }),
38 
39  // Copy ctor
40  BijectiveMap biMap2(biMap);
41  EXPECT_EQ(biMap2, biMap);
42 
43  biMap2.Insert(30, "Thirty");
44  EXPECT_EQ(biMap2.Size(), 3u);
45  EXPECT_NE(biMap2, biMap);
46 
47  // Move ctor
48  BijectiveMap biMap3(std::move(biMap));
49  EXPECT_EQ(biMap3.Size(), 2u);
50  // All of biMap's content has been stolen
51  EXPECT_EQ(biMap.Size(), 0u);
52 
53  // copy assignment
54  biMap2 = biMap3;
55  EXPECT_EQ(biMap2.Size(), 2u);
56  EXPECT_EQ(biMap2, biMap3);
57 
58  // move assignment
59  biMap = std::move(biMap3);
60  EXPECT_EQ(biMap.Size(), 2u);
61  EXPECT_EQ(biMap, biMap2);
62  EXPECT_EQ(biMap3.Size(), 0u);
63 
64  EXPECT_EQ(biMap.LookupKey(10), "Ten");
65  EXPECT_EQ(biMap.LookupKey(20), "Twenty");
66  EXPECT_EQ(biMap.LookupValue("Ten"), 10);
67  EXPECT_EQ(biMap.LookupValue("Twenty"), 20);
68 }
69 
70 TEST(BijectiveMapTests, TestBijectiveMapClear)
71 {
72  using namespace jlm::util;
73 
74  BijectiveMap<int, int> squares;
75  squares.Insert(5, 25);
76  squares.Insert(6, 36);
77  EXPECT_EQ(squares.Size(), 2u);
78  squares.Clear();
79  EXPECT_EQ(squares.Size(), 0u);
80  squares.Insert(5, 25);
81  EXPECT_EQ(squares.Size(), 1u);
82 }
83 
84 TEST(BijectiveMapTests, TestBijectiveMapInsert)
85 {
86  using namespace jlm::util;
87 
88  BijectiveMap<int, int> squares;
89  bool inserted = squares.Insert(5, 25);
90  EXPECT_EQ(inserted && squares.Size(), 1u);
91  EXPECT_TRUE(squares.HasKey(5));
92  EXPECT_TRUE(squares.HasValue(25));
93  inserted = squares.Insert(5, 45);
94  EXPECT_FALSE(inserted);
95  EXPECT_EQ(squares.Size(), 1u);
96  EXPECT_FALSE(squares.HasValue(45));
97 
98  EXPECT_THROW(squares.InsertOrThrow(6, 25), jlm::util::Error);
99  EXPECT_THROW(squares.InsertOrThrow(5, 36), jlm::util::Error);
100 
101  inserted = squares.Insert(6, 36);
102  EXPECT_TRUE(inserted);
103  EXPECT_EQ(squares.Size(), 2u);
104 }
105 
106 TEST(BijectiveMapTests, TestBijectiveMapInsertPairs)
107 {
108  using namespace jlm::util;
109 
110  BijectiveMap<int, std::string> biMap, biMap2;
111 
112  biMap.Insert(4, "four");
113  biMap.Insert(6, "six");
114  biMap.Insert(8, "eight");
115 
116  biMap2.Insert(4, "fire");
117  biMap2.Insert(100, "six");
118  biMap2.Insert(9, "nine");
119  biMap2.Insert(10, "ten");
120 
121  const auto inserted = biMap.InsertPairs(biMap2.begin(), biMap2.end());
122  EXPECT_EQ(inserted, 2u);
123  EXPECT_EQ(biMap.Size(), 5u);
124  EXPECT_FALSE(biMap.HasKey(100));
125  EXPECT_FALSE(biMap.HasValue("fire"));
126  EXPECT_EQ(biMap.LookupKey(9), "nine");
127  EXPECT_EQ(biMap.LookupValue("ten"), 10);
128 }
129 
130 TEST(BijectiveMapTests, TestBijectiveMapLookup)
131 {
132  using namespace jlm::util;
133  BijectiveMap<int, std::string> biMap({ { 1, "one" } });
134  biMap.Insert(2, "two");
135 
136  EXPECT_EQ(biMap.LookupKey(1), "one");
137  EXPECT_EQ(biMap.LookupKey(2), "two");
138  EXPECT_EQ(biMap.LookupValue("one"), 1);
139  EXPECT_EQ(biMap.LookupValue("two"), 2);
140 
141  EXPECT_THROW((void)biMap.LookupKey(3), jlm::util::Error);
142  EXPECT_THROW((void)biMap.LookupValue("three"), jlm::util::Error);
143 }
144 
145 TEST(BijectiveMapTests, TestBijectiveMapIterators)
146 {
147  using namespace jlm::util;
149  { 1, "one" },
150  { 2, "two" },
151  { 3, "three" },
152  });
153 
154  size_t count = 0, sum = 0;
155  for (const auto & [key, value] : biMap)
156  {
157  count++;
158  sum += key;
159  switch (key)
160  {
161  case 1:
162  EXPECT_EQ(value, "one");
163  break;
164  case 2:
165  EXPECT_EQ(value, "two");
166  break;
167  case 3:
168  EXPECT_EQ(value, "three");
169  break;
170  default:
171  FAIL() << "unreachable";
172  }
173  }
174  EXPECT_EQ(count, 3u);
175  EXPECT_EQ(sum, 6u);
176 }
177 
178 TEST(BijectiveMapTests, TestBijectiveMapErase)
179 {
180  using namespace jlm::util;
182  { 0, "zero" },
183  { 1, "one" },
184  { 2, "two" },
185 
186  });
187 
188  // Erasing leaves all other iterators valid
189  const auto first = biMap.begin();
190  const auto second = std::next(first);
191  const auto third = std::next(second);
192  const auto fourth = std::next(third);
193 
194  assert(fourth == biMap.end());
195 
196  const auto afterErased = biMap.Erase(second);
197  EXPECT_EQ(afterErased, third);
198  EXPECT_EQ(afterErased, std::next(first));
199  EXPECT_EQ(biMap.Size(), 2u);
200 }
201 
202 TEST(BijectiveMapTests, TestBijectiveMapRemoves)
203 {
204  using namespace jlm::util;
205  BijectiveMap<int, std::string> biMap({ { 1, "one" }, { 2, "two" }, { 3, "three" } });
206  bool removed = biMap.RemoveKey(1);
207  EXPECT_TRUE(removed);
208  EXPECT_FALSE(biMap.HasKey(1));
209  EXPECT_FALSE(biMap.HasValue("one"));
210  EXPECT_EQ(biMap.Size(), 2u);
211  removed = biMap.RemoveValue("two");
212  EXPECT_TRUE(removed);
213  EXPECT_FALSE(biMap.HasKey(2));
214  EXPECT_FALSE(biMap.HasValue("two"));
215  EXPECT_EQ(biMap.Size(), 1u);
216 
217  removed = biMap.RemoveKey(6);
218  EXPECT_FALSE(removed);
219  removed = biMap.RemoveValue("five");
220  EXPECT_FALSE(removed);
221 }
222 
223 TEST(BijectiveMapTests, TestBijectiveMapRemoveWhere)
224 {
225  using namespace jlm::util;
226  BijectiveMap<int, std::string> biMap({ { 1, "one" },
227  { 2, "two" },
228  { 3, "three" },
229  { 4, "four" },
230  { 5, "five" },
231  { 6, "six" },
232  { 7, "seven" },
233  { 8, "eight" } });
234 
235  const auto KVPredicate = [](int key, const std::string & value)
236  {
237  return key < 4 || value == "eight";
238  };
239  auto removed = biMap.RemoveWhere(KVPredicate);
240  EXPECT_EQ(removed, 4u);
241  EXPECT_FALSE(biMap.HasKey(8));
242  EXPECT_FALSE(biMap.HasValue("three"));
243 
244  removed = biMap.RemoveWhere(KVPredicate);
245  EXPECT_EQ(removed, 0u);
246 
247  // Removes 5 and 7
248  removed = biMap.RemoveKeysWhere(
249  [&](int key)
250  {
251  return key % 2 == 1;
252  });
253  EXPECT_EQ(removed, 2u);
254  EXPECT_FALSE(biMap.HasKey(5));
255  EXPECT_FALSE(biMap.HasValue("seven"));
256 
257  // Removes 5 and 7
258  removed = biMap.RemoveValuesWhere(
259  [&](const std::string & value)
260  {
261  return value.size() > 3;
262  });
263  EXPECT_EQ(removed, 1u);
264  EXPECT_TRUE(!biMap.HasKey(4));
265  EXPECT_EQ(biMap.Size(), 1u);
266  EXPECT_TRUE(biMap.HasValue("six"));
267 }
TEST(BijectiveMapTests, TestBijectiveMapConstructors)
const V & LookupKey(const K &key) const
const K & LookupValue(const V &value) const
bool RemoveKey(const K &key)
size_t RemoveWhere(const F &match)
size_t InsertPairs(IteratorType begin, IteratorType end)
ConstIterator begin() const noexcept
std::size_t Size() const noexcept
ConstIterator end() const noexcept
bool RemoveValue(const V &value)
void InsertOrThrow(const K &key, const V &value)
bool Insert(const K &key, const V &value)
bool HasKey(const K &key) const noexcept
bool HasValue(const V &value) const noexcept