1//===- STLExtrasTest.cpp - Unit tests for STL extras ----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/ADT/STLExtras.h"
10#include "llvm/ADT/StringRef.h"
11#include "gmock/gmock.h"
12#include "gtest/gtest.h"
13
14#include <array>
15#include <climits>
16#include <cstddef>
17#include <initializer_list>
18#include <list>
19#include <tuple>
20#include <type_traits>
21#include <unordered_set>
22#include <utility>
23#include <vector>
24
25using namespace llvm;
26
27using testing::ElementsAre;
28using testing::UnorderedElementsAre;
29
30namespace {
31
32int f(rank<0>) { return 0; }
33int f(rank<1>) { return 1; }
34int f(rank<2>) { return 2; }
35int f(rank<4>) { return 4; }
36
37TEST(STLExtrasTest, Rank) {
38 // We shouldn't get ambiguities and should select the overload of the same
39 // rank as the argument.
40 EXPECT_EQ(0, f(rank<0>()));
41 EXPECT_EQ(1, f(rank<1>()));
42 EXPECT_EQ(2, f(rank<2>()));
43
44 // This overload is missing so we end up back at 2.
45 EXPECT_EQ(2, f(rank<3>()));
46
47 // But going past 3 should work fine.
48 EXPECT_EQ(4, f(rank<4>()));
49
50 // And we can even go higher and just fall back to the last overload.
51 EXPECT_EQ(4, f(rank<5>()));
52 EXPECT_EQ(4, f(rank<6>()));
53}
54
55TEST(STLExtrasTest, EnumerateLValue) {
56 // Test that a simple LValue can be enumerated and gives correct results with
57 // multiple types, including the empty container.
58 std::vector<char> foo = {'a', 'b', 'c'};
59 typedef std::pair<std::size_t, char> CharPairType;
60 std::vector<CharPairType> CharResults;
61
62 for (auto [index, value] : llvm::enumerate(First&: foo)) {
63 CharResults.emplace_back(args&: index, args&: value);
64 }
65
66 EXPECT_THAT(CharResults,
67 ElementsAre(CharPairType(0u, 'a'), CharPairType(1u, 'b'),
68 CharPairType(2u, 'c')));
69
70 // Test a const range of a different type.
71 typedef std::pair<std::size_t, int> IntPairType;
72 std::vector<IntPairType> IntResults;
73 const std::vector<int> bar = {1, 2, 3};
74 for (auto [index, value] : llvm::enumerate(First: bar)) {
75 IntResults.emplace_back(args&: index, args: value);
76 }
77 EXPECT_THAT(IntResults, ElementsAre(IntPairType(0u, 1), IntPairType(1u, 2),
78 IntPairType(2u, 3)));
79
80 // Test an empty range.
81 IntResults.clear();
82 const std::vector<int> baz{};
83 for (auto [index, value] : llvm::enumerate(First: baz)) {
84 IntResults.emplace_back(args&: index, args: value);
85 }
86 EXPECT_TRUE(IntResults.empty());
87}
88
89TEST(STLExtrasTest, EnumerateModifyLValue) {
90 // Test that you can modify the underlying entries of an lvalue range through
91 // the enumeration iterator.
92 std::vector<char> foo = {'a', 'b', 'c'};
93
94 for (auto X : llvm::enumerate(First&: foo)) {
95 ++X.value();
96 }
97 EXPECT_THAT(foo, ElementsAre('b', 'c', 'd'));
98
99 // Also test if this works with structured bindings.
100 foo = {'a', 'b', 'c'};
101
102 for (auto [index, value] : llvm::enumerate(First&: foo)) {
103 ++value;
104 }
105 EXPECT_THAT(foo, ElementsAre('b', 'c', 'd'));
106}
107
108TEST(STLExtrasTest, EnumerateRValueRef) {
109 // Test that an rvalue can be enumerated.
110 typedef std::pair<std::size_t, int> PairType;
111 std::vector<PairType> Results;
112
113 auto Enumerator = llvm::enumerate(First: std::vector<int>{1, 2, 3});
114
115 for (auto X : llvm::enumerate(First: std::vector<int>{1, 2, 3})) {
116 Results.emplace_back(args: X.index(), args&: X.value());
117 }
118
119 EXPECT_THAT(Results,
120 ElementsAre(PairType(0u, 1), PairType(1u, 2), PairType(2u, 3)));
121
122 // Also test if this works with structured bindings.
123 Results.clear();
124
125 for (auto [index, value] : llvm::enumerate(First: std::vector<int>{1, 2, 3})) {
126 Results.emplace_back(args&: index, args&: value);
127 }
128
129 EXPECT_THAT(Results,
130 ElementsAre(PairType(0u, 1), PairType(1u, 2), PairType(2u, 3)));
131}
132
133TEST(STLExtrasTest, EnumerateModifyRValue) {
134 // Test that when enumerating an rvalue, modification still works (even if
135 // this isn't terribly useful, it at least shows that we haven't snuck an
136 // extra const in there somewhere.
137 typedef std::pair<std::size_t, char> PairType;
138 std::vector<PairType> Results;
139
140 for (auto X : llvm::enumerate(First: std::vector<char>{'1', '2', '3'})) {
141 ++X.value();
142 Results.emplace_back(args: X.index(), args&: X.value());
143 }
144
145 EXPECT_THAT(Results, ElementsAre(PairType(0u, '2'), PairType(1u, '3'),
146 PairType(2u, '4')));
147
148 // Also test if this works with structured bindings.
149 Results.clear();
150
151 for (auto [index, value] :
152 llvm::enumerate(First: std::vector<char>{'1', '2', '3'})) {
153 ++value;
154 Results.emplace_back(args&: index, args&: value);
155 }
156
157 EXPECT_THAT(Results, ElementsAre(PairType(0u, '2'), PairType(1u, '3'),
158 PairType(2u, '4')));
159}
160
161TEST(STLExtrasTest, EnumerateTwoRanges) {
162 using Tuple = std::tuple<size_t, int, bool>;
163
164 std::vector<int> Ints = {1, 2};
165 std::vector<bool> Bools = {true, false};
166 EXPECT_THAT(llvm::enumerate(Ints, Bools),
167 ElementsAre(Tuple(0, 1, true), Tuple(1, 2, false)));
168
169 // Check that we can modify the values when the temporary is a const
170 // reference.
171 for (const auto &[Idx, Int, Bool] : llvm::enumerate(First&: Ints, Rest&: Bools)) {
172 (void)Idx;
173 Bool = false;
174 Int = -1;
175 }
176
177 EXPECT_THAT(Ints, ElementsAre(-1, -1));
178 EXPECT_THAT(Bools, ElementsAre(false, false));
179
180 // Check that we can modify the values when the result gets copied.
181 for (auto [Idx, Bool, Int] : llvm::enumerate(First&: Bools, Rest&: Ints)) {
182 (void)Idx;
183 Int = 3;
184 Bool = true;
185 }
186
187 EXPECT_THAT(Ints, ElementsAre(3, 3));
188 EXPECT_THAT(Bools, ElementsAre(true, true));
189
190 // Check that we can modify the values through `.value()`.
191 size_t Iters = 0;
192 for (auto It : llvm::enumerate(First&: Bools, Rest&: Ints)) {
193 EXPECT_EQ(It.index(), Iters);
194 ++Iters;
195
196 std::get<0>(t: It.value()) = false;
197 std::get<1>(t: It.value()) = 4;
198 }
199
200 EXPECT_THAT(Ints, ElementsAre(4, 4));
201 EXPECT_THAT(Bools, ElementsAre(false, false));
202}
203
204TEST(STLExtrasTest, EnumerateThreeRanges) {
205 using Tuple = std::tuple<size_t, int, bool, char>;
206
207 std::vector<int> Ints = {1, 2};
208 std::vector<bool> Bools = {true, false};
209 char Chars[] = {'X', 'D'};
210 EXPECT_THAT(llvm::enumerate(Ints, Bools, Chars),
211 ElementsAre(Tuple(0, 1, true, 'X'), Tuple(1, 2, false, 'D')));
212
213 for (auto [Idx, Int, Bool, Char] : llvm::enumerate(First&: Ints, Rest&: Bools, Rest&: Chars)) {
214 (void)Idx;
215 Int = 0;
216 Bool = true;
217 Char = '!';
218 }
219
220 EXPECT_THAT(Ints, ElementsAre(0, 0));
221 EXPECT_THAT(Bools, ElementsAre(true, true));
222 EXPECT_THAT(Chars, ElementsAre('!', '!'));
223
224 // Check that we can modify the values through `.values()`.
225 size_t Iters = 0;
226 for (auto It : llvm::enumerate(First&: Ints, Rest&: Bools, Rest&: Chars)) {
227 EXPECT_EQ(It.index(), Iters);
228 ++Iters;
229 auto [Int, Bool, Char] = It.value();
230 Int = 42;
231 Bool = false;
232 Char = '$';
233 }
234
235 EXPECT_THAT(Ints, ElementsAre(42, 42));
236 EXPECT_THAT(Bools, ElementsAre(false, false));
237 EXPECT_THAT(Chars, ElementsAre('$', '$'));
238}
239
240TEST(STLExtrasTest, EnumerateTemporaries) {
241 using Tuple = std::tuple<size_t, int, bool>;
242
243 EXPECT_THAT(
244 llvm::enumerate(llvm::SmallVector<int>({1, 2, 3}),
245 std::vector<bool>({true, false, true})),
246 ElementsAre(Tuple(0, 1, true), Tuple(1, 2, false), Tuple(2, 3, true)));
247
248 size_t Iters = 0;
249 // This is fine from the point of view of range lifetimes because `zippy` will
250 // move all temporaries into its storage. No lifetime extension is necessary.
251 for (auto [Idx, Int, Bool] :
252 llvm::enumerate(First: llvm::SmallVector<int>({1, 2, 3}),
253 Rest: std::vector<bool>({true, false, true}))) {
254 EXPECT_EQ(Idx, Iters);
255 ++Iters;
256 Int = 0;
257 Bool = true;
258 }
259
260 Iters = 0;
261 // The same thing but with the result as a const reference.
262 for (const auto &[Idx, Int, Bool] :
263 llvm::enumerate(First: llvm::SmallVector<int>({1, 2, 3}),
264 Rest: std::vector<bool>({true, false, true}))) {
265 EXPECT_EQ(Idx, Iters);
266 ++Iters;
267 Int = 0;
268 Bool = true;
269 }
270}
271
272#if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG)
273TEST(STLExtrasTest, EnumerateDifferentLengths) {
274 std::vector<int> Ints = {0, 1};
275 bool Bools[] = {true, false, true};
276 std::string Chars = "abc";
277 EXPECT_DEATH(llvm::enumerate(Ints, Bools, Chars),
278 "Ranges have different length");
279 EXPECT_DEATH(llvm::enumerate(Bools, Ints, Chars),
280 "Ranges have different length");
281 EXPECT_DEATH(llvm::enumerate(Bools, Chars, Ints),
282 "Ranges have different length");
283}
284#endif
285
286template <bool B> struct CanMove {};
287template <> struct CanMove<false> {
288 CanMove(CanMove &&) = delete;
289
290 CanMove() = default;
291 CanMove(const CanMove &) = default;
292};
293
294template <bool B> struct CanCopy {};
295template <> struct CanCopy<false> {
296 CanCopy(const CanCopy &) = delete;
297
298 CanCopy() = default;
299 CanCopy(CanCopy &&) = default;
300};
301
302template <bool Moveable, bool Copyable>
303class Counted : CanMove<Moveable>, CanCopy<Copyable> {
304 int &C;
305 int &M;
306 int &D;
307
308public:
309 explicit Counted(int &C, int &M, int &D) : C(C), M(M), D(D) {}
310 Counted(const Counted &O) : CanCopy<Copyable>(O), C(O.C), M(O.M), D(O.D) {
311 ++C;
312 }
313 Counted(Counted &&O)
314 : CanMove<Moveable>(std::move(O)), C(O.C), M(O.M), D(O.D) {
315 ++M;
316 }
317 ~Counted() { ++D; }
318};
319
320template <bool Moveable, bool Copyable>
321struct Range : Counted<Moveable, Copyable> {
322 using Counted<Moveable, Copyable>::Counted;
323 int *begin() const { return nullptr; }
324 int *end() const { return nullptr; }
325};
326
327TEST(STLExtrasTest, EnumerateLifetimeSemanticsPRValue) {
328 int Copies = 0;
329 int Moves = 0;
330 int Destructors = 0;
331 {
332 auto E = enumerate(First: Range<true, false>(Copies, Moves, Destructors));
333 (void)E;
334 // Doesn't compile. rvalue ranges must be moveable.
335 // auto E2 = enumerate(Range<false, true>(Copies, Moves, Destructors));
336 EXPECT_EQ(0, Copies);
337 EXPECT_EQ(1, Moves);
338 EXPECT_EQ(1, Destructors);
339 }
340 EXPECT_EQ(0, Copies);
341 EXPECT_EQ(1, Moves);
342 EXPECT_EQ(2, Destructors);
343}
344
345TEST(STLExtrasTest, EnumerateLifetimeSemanticsRValue) {
346 // With an rvalue, it should not be destroyed until the end of the scope.
347 int Copies = 0;
348 int Moves = 0;
349 int Destructors = 0;
350 {
351 Range<true, false> R(Copies, Moves, Destructors);
352 {
353 auto E = enumerate(First: std::move(R));
354 (void)E;
355 // Doesn't compile. rvalue ranges must be moveable.
356 // auto E2 = enumerate(Range<false, true>(Copies, Moves, Destructors));
357 EXPECT_EQ(0, Copies);
358 EXPECT_EQ(1, Moves);
359 EXPECT_EQ(0, Destructors);
360 }
361 EXPECT_EQ(0, Copies);
362 EXPECT_EQ(1, Moves);
363 EXPECT_EQ(1, Destructors);
364 }
365 EXPECT_EQ(0, Copies);
366 EXPECT_EQ(1, Moves);
367 EXPECT_EQ(2, Destructors);
368}
369
370TEST(STLExtrasTest, EnumerateLifetimeSemanticsLValue) {
371 // With an lvalue, it should not be destroyed even after the end of the scope.
372 // lvalue ranges need be neither copyable nor moveable.
373 int Copies = 0;
374 int Moves = 0;
375 int Destructors = 0;
376 {
377 Range<false, false> R(Copies, Moves, Destructors);
378 {
379 auto E = enumerate(First&: R);
380 (void)E;
381 EXPECT_EQ(0, Copies);
382 EXPECT_EQ(0, Moves);
383 EXPECT_EQ(0, Destructors);
384 }
385 EXPECT_EQ(0, Copies);
386 EXPECT_EQ(0, Moves);
387 EXPECT_EQ(0, Destructors);
388 }
389 EXPECT_EQ(0, Copies);
390 EXPECT_EQ(0, Moves);
391 EXPECT_EQ(1, Destructors);
392}
393
394namespace some_namespace {
395struct some_struct {
396 std::vector<int> data;
397 std::string swap_val;
398};
399
400std::vector<int>::const_iterator begin(const some_struct &s) {
401 return s.data.begin();
402}
403
404std::vector<int>::const_iterator end(const some_struct &s) {
405 return s.data.end();
406}
407
408std::vector<int>::const_reverse_iterator rbegin(const some_struct &s) {
409 return s.data.rbegin();
410}
411
412std::vector<int>::const_reverse_iterator rend(const some_struct &s) {
413 return s.data.rend();
414}
415
416void swap(some_struct &lhs, some_struct &rhs) {
417 // make swap visible as non-adl swap would even seem to
418 // work with std::swap which defaults to moving
419 lhs.swap_val = "lhs";
420 rhs.swap_val = "rhs";
421}
422
423struct requires_move {};
424int *begin(requires_move &&) { return nullptr; }
425int *end(requires_move &&) { return nullptr; }
426} // namespace some_namespace
427
428TEST(STLExtrasTest, EnumerateCustomBeginEnd) {
429 // Check that `enumerate` uses ADL to find `begin`/`end` iterators
430 // of the enumerated type.
431 some_namespace::some_struct X{};
432 X.data = {1, 2, 3};
433
434 unsigned Iters = 0;
435 for (auto [Idx, Val] : enumerate(First&: X)) {
436 EXPECT_EQ(Val, X.data[Idx]);
437 ++Iters;
438 }
439 EXPECT_EQ(Iters, 3u);
440}
441
442TEST(STLExtrasTest, CountAdaptor) {
443 std::vector<int> v;
444
445 v.push_back(x: 1);
446 v.push_back(x: 2);
447 v.push_back(x: 1);
448 v.push_back(x: 4);
449 v.push_back(x: 3);
450 v.push_back(x: 2);
451 v.push_back(x: 1);
452
453 EXPECT_EQ(3, count(v, 1));
454 EXPECT_EQ(2, count(v, 2));
455 EXPECT_EQ(1, count(v, 3));
456 EXPECT_EQ(1, count(v, 4));
457}
458
459TEST(STLExtrasTest, for_each) {
460 std::vector<int> v{0, 1, 2, 3, 4};
461 int count = 0;
462
463 llvm::for_each(Range&: v, F: [&count](int) { ++count; });
464 EXPECT_EQ(5, count);
465}
466
467TEST(STLExtrasTest, ToVector) {
468 std::vector<char> v = {'a', 'b', 'c'};
469 auto Enumerated = to_vector<4>(Range: enumerate(First&: v));
470 ASSERT_EQ(3u, Enumerated.size());
471 for (size_t I = 0; I < v.size(); ++I) {
472 EXPECT_EQ(I, Enumerated[I].index());
473 EXPECT_EQ(v[I], Enumerated[I].value());
474 }
475
476 auto EnumeratedImplicitSize = to_vector(Range: enumerate(First&: v));
477 ASSERT_EQ(3u, EnumeratedImplicitSize.size());
478 for (size_t I = 0; I < v.size(); ++I) {
479 EXPECT_EQ(I, EnumeratedImplicitSize[I].index());
480 EXPECT_EQ(v[I], EnumeratedImplicitSize[I].value());
481 }
482}
483
484TEST(STLExtrasTest, ConcatRange) {
485 std::vector<int> Expected = {1, 2, 3, 4, 5, 6, 7, 8};
486 std::vector<int> Test;
487
488 std::vector<int> V1234 = {1, 2, 3, 4};
489 std::list<int> L56 = {5, 6};
490 SmallVector<int, 2> SV78 = {7, 8};
491
492 // Use concat across different sized ranges of different types with different
493 // iterators.
494 for (int &i : concat<int>(Ranges&: V1234, Ranges&: L56, Ranges&: SV78))
495 Test.push_back(x: i);
496 EXPECT_EQ(Expected, Test);
497
498 // Use concat between a temporary, an L-value, and an R-value to make sure
499 // complex lifetimes work well.
500 Test.clear();
501 for (int &i : concat<int>(Ranges: std::vector<int>(V1234), Ranges&: L56, Ranges: std::move(SV78)))
502 Test.push_back(x: i);
503 EXPECT_EQ(Expected, Test);
504}
505
506TEST(STLExtrasTest, PartitionAdaptor) {
507 std::vector<int> V = {1, 2, 3, 4, 5, 6, 7, 8};
508
509 auto I = partition(Range&: V, P: [](int i) { return i % 2 == 0; });
510 ASSERT_EQ(V.begin() + 4, I);
511
512 // Sort the two halves as partition may have messed with the order.
513 llvm::sort(Start: V.begin(), End: I);
514 llvm::sort(Start: I, End: V.end());
515
516 EXPECT_EQ(2, V[0]);
517 EXPECT_EQ(4, V[1]);
518 EXPECT_EQ(6, V[2]);
519 EXPECT_EQ(8, V[3]);
520 EXPECT_EQ(1, V[4]);
521 EXPECT_EQ(3, V[5]);
522 EXPECT_EQ(5, V[6]);
523 EXPECT_EQ(7, V[7]);
524}
525
526TEST(STLExtrasTest, EraseIf) {
527 std::vector<int> V = {1, 2, 3, 4, 5, 6, 7, 8};
528
529 erase_if(C&: V, P: [](int i) { return i % 2 == 0; });
530 EXPECT_EQ(4u, V.size());
531 EXPECT_EQ(1, V[0]);
532 EXPECT_EQ(3, V[1]);
533 EXPECT_EQ(5, V[2]);
534 EXPECT_EQ(7, V[3]);
535}
536
537TEST(STLExtrasTest, AppendRange) {
538 std::vector<int> V = {1, 2};
539 auto AppendVals1 = {3};
540 append_range(C&: V, R&: AppendVals1);
541 EXPECT_THAT(V, ElementsAre(1, 2, 3));
542
543 int AppendVals2[] = {4, 5};
544 append_range(C&: V, R&: AppendVals2);
545 EXPECT_THAT(V, ElementsAre(1, 2, 3, 4, 5));
546
547 std::string Str;
548 append_range(C&: Str, R: "abc");
549 EXPECT_THAT(Str, ElementsAre('a', 'b', 'c', '\0'));
550 append_range(C&: Str, R: "def");
551 EXPECT_THAT(Str, ElementsAre('a', 'b', 'c', '\0', 'd', 'e', 'f', '\0'));
552}
553
554TEST(STLExtrasTest, AppendValues) {
555 std::vector<int> Vals = {1, 2};
556 append_values(C&: Vals, Values: 3);
557 EXPECT_THAT(Vals, ElementsAre(1, 2, 3));
558
559 append_values(C&: Vals, Values: 4, Values: 5);
560 EXPECT_THAT(Vals, ElementsAre(1, 2, 3, 4, 5));
561
562 std::vector<StringRef> Strs;
563 std::string A = "A";
564 std::string B = "B";
565 std::string C = "C";
566 append_values(C&: Strs, Values&: A, Values&: B);
567 EXPECT_THAT(Strs, ElementsAre(A, B));
568 append_values(C&: Strs, Values&: C);
569 EXPECT_THAT(Strs, ElementsAre(A, B, C));
570
571 std::unordered_set<int> Set;
572 append_values(C&: Set, Values: 1, Values: 2);
573 EXPECT_THAT(Set, UnorderedElementsAre(1, 2));
574 append_values(C&: Set, Values: 3, Values: 1);
575 EXPECT_THAT(Set, UnorderedElementsAre(1, 2, 3));
576}
577
578TEST(STLExtrasTest, ADLTest) {
579 some_namespace::some_struct s{.data: {1, 2, 3, 4, 5}, .swap_val: ""};
580 some_namespace::some_struct s2{.data: {2, 4, 6, 8, 10}, .swap_val: ""};
581
582 EXPECT_EQ(*adl_begin(s), 1);
583 EXPECT_EQ(*(adl_end(s) - 1), 5);
584 EXPECT_EQ(*adl_rbegin(s), 5);
585 EXPECT_EQ(*(adl_rend(s) - 1), 1);
586
587 adl_swap(lhs&: s, rhs&: s2);
588 EXPECT_EQ(s.swap_val, "lhs");
589 EXPECT_EQ(s2.swap_val, "rhs");
590
591 int count = 0;
592 llvm::for_each(Range&: s, F: [&count](int) { ++count; });
593 EXPECT_EQ(count, 5);
594}
595
596TEST(STLExtrasTest, ADLTestTemporaryRange) {
597 EXPECT_EQ(adl_begin(some_namespace::requires_move{}), nullptr);
598 EXPECT_EQ(adl_end(some_namespace::requires_move{}), nullptr);
599}
600
601TEST(STLExtrasTest, ADLTestConstexpr) {
602 // `std::begin`/`std::end` are marked as `constexpr`; check that
603 // `adl_begin`/`adl_end` also work in constant-evaluated contexts.
604 static constexpr int c_arr[] = {7, 8, 9};
605 static_assert(adl_begin(range: c_arr) == c_arr);
606 static_assert(adl_end(range: c_arr) == c_arr + 3);
607
608 static constexpr std::array<int, 2> std_arr = {1, 2};
609 static_assert(adl_begin(range: std_arr) == std_arr.begin());
610 static_assert(adl_end(range: std_arr) == std_arr.end());
611 SUCCEED();
612}
613
614struct FooWithMemberSize {
615 size_t size() const { return 42; }
616 auto begin() { return Data.begin(); }
617 auto end() { return Data.end(); }
618
619 std::set<int> Data;
620};
621
622namespace some_namespace {
623struct FooWithFreeSize {
624 auto begin() { return Data.begin(); }
625 auto end() { return Data.end(); }
626
627 std::set<int> Data;
628};
629
630size_t size(const FooWithFreeSize &) { return 13; }
631} // namespace some_namespace
632
633TEST(STLExtrasTest, ADLSizeTest) {
634 FooWithMemberSize foo1;
635 EXPECT_EQ(adl_size(foo1), 42u);
636
637 some_namespace::FooWithFreeSize foo2;
638 EXPECT_EQ(adl_size(foo2), 13u);
639
640 static constexpr int c_arr[] = {1, 2, 3};
641 static_assert(adl_size(range: c_arr) == 3u);
642
643 static constexpr std::array<int, 4> cpp_arr = {};
644 static_assert(adl_size(range: cpp_arr) == 4u);
645}
646
647TEST(STLExtrasTest, DropBeginTest) {
648 SmallVector<int, 5> vec{0, 1, 2, 3, 4};
649
650 for (int n = 0; n < 5; ++n) {
651 int i = n;
652 for (auto &v : drop_begin(RangeOrContainer&: vec, N: n)) {
653 EXPECT_EQ(v, i);
654 i += 1;
655 }
656 EXPECT_EQ(i, 5);
657 }
658}
659
660TEST(STLExtrasTest, DropBeginDefaultTest) {
661 SmallVector<int, 5> vec{0, 1, 2, 3, 4};
662
663 int i = 1;
664 for (auto &v : drop_begin(RangeOrContainer&: vec)) {
665 EXPECT_EQ(v, i);
666 i += 1;
667 }
668 EXPECT_EQ(i, 5);
669}
670
671TEST(STLExtrasTest, DropEndTest) {
672 SmallVector<int, 5> vec{0, 1, 2, 3, 4};
673
674 for (int n = 0; n < 5; ++n) {
675 int i = 0;
676 for (auto &v : drop_end(RangeOrContainer&: vec, N: n)) {
677 EXPECT_EQ(v, i);
678 i += 1;
679 }
680 EXPECT_EQ(i, 5 - n);
681 }
682}
683
684TEST(STLExtrasTest, DropEndDefaultTest) {
685 SmallVector<int, 5> vec{0, 1, 2, 3, 4};
686
687 int i = 0;
688 for (auto &v : drop_end(RangeOrContainer&: vec)) {
689 EXPECT_EQ(v, i);
690 i += 1;
691 }
692 EXPECT_EQ(i, 4);
693}
694
695TEST(STLExtrasTest, EarlyIncrementTest) {
696 std::list<int> L = {1, 2, 3, 4};
697
698 auto EIR = make_early_inc_range(Range&: L);
699
700 auto I = EIR.begin();
701 auto EI = EIR.end();
702 EXPECT_NE(I, EI);
703
704 EXPECT_EQ(1, *I);
705#if LLVM_ENABLE_ABI_BREAKING_CHECKS
706#ifndef NDEBUG
707 // Repeated dereferences are not allowed.
708 EXPECT_DEATH(*I, "Cannot dereference");
709 // Comparison after dereference is not allowed.
710 EXPECT_DEATH((void)(I == EI), "Cannot compare");
711 EXPECT_DEATH((void)(I != EI), "Cannot compare");
712#endif
713#endif
714
715 ++I;
716 EXPECT_NE(I, EI);
717#if LLVM_ENABLE_ABI_BREAKING_CHECKS
718#ifndef NDEBUG
719 // You cannot increment prior to dereference.
720 EXPECT_DEATH(++I, "Cannot increment");
721#endif
722#endif
723 EXPECT_EQ(2, *I);
724#if LLVM_ENABLE_ABI_BREAKING_CHECKS
725#ifndef NDEBUG
726 // Repeated dereferences are not allowed.
727 EXPECT_DEATH(*I, "Cannot dereference");
728#endif
729#endif
730
731 // Inserting shouldn't break anything. We should be able to keep dereferencing
732 // the currrent iterator and increment. The increment to go to the "next"
733 // iterator from before we inserted.
734 L.insert(position: std::next(x: L.begin(), n: 2), x: -1);
735 ++I;
736 EXPECT_EQ(3, *I);
737
738 // Erasing the front including the current doesn't break incrementing.
739 L.erase(first: L.begin(), last: std::prev(x: L.end()));
740 ++I;
741 EXPECT_EQ(4, *I);
742 ++I;
743 EXPECT_EQ(EIR.end(), I);
744}
745
746// A custom iterator that returns a pointer when dereferenced. This is used to
747// test make_early_inc_range with iterators that do not return a reference on
748// dereferencing.
749struct CustomPointerIterator
750 : public iterator_adaptor_base<CustomPointerIterator,
751 std::list<int>::iterator,
752 std::forward_iterator_tag> {
753 using base_type =
754 iterator_adaptor_base<CustomPointerIterator, std::list<int>::iterator,
755 std::forward_iterator_tag>;
756
757 explicit CustomPointerIterator(std::list<int>::iterator I) : base_type(I) {}
758
759 // Retrieve a pointer to the current int.
760 int *operator*() const { return &*base_type::wrapped(); }
761};
762
763// Make sure make_early_inc_range works with iterators that do not return a
764// reference on dereferencing. The test is similar to EarlyIncrementTest, but
765// uses CustomPointerIterator.
766TEST(STLExtrasTest, EarlyIncrementTestCustomPointerIterator) {
767 std::list<int> L = {1, 2, 3, 4};
768
769 auto CustomRange = make_range(x: CustomPointerIterator(L.begin()),
770 y: CustomPointerIterator(L.end()));
771 auto EIR = make_early_inc_range(Range&: CustomRange);
772
773 auto I = EIR.begin();
774 auto EI = EIR.end();
775 EXPECT_NE(I, EI);
776
777 EXPECT_EQ(&*L.begin(), *I);
778#if LLVM_ENABLE_ABI_BREAKING_CHECKS
779#ifndef NDEBUG
780 // Repeated dereferences are not allowed.
781 EXPECT_DEATH(*I, "Cannot dereference");
782 // Comparison after dereference is not allowed.
783 EXPECT_DEATH((void)(I == EI), "Cannot compare");
784 EXPECT_DEATH((void)(I != EI), "Cannot compare");
785#endif
786#endif
787
788 ++I;
789 EXPECT_NE(I, EI);
790#if LLVM_ENABLE_ABI_BREAKING_CHECKS
791#ifndef NDEBUG
792 // You cannot increment prior to dereference.
793 EXPECT_DEATH(++I, "Cannot increment");
794#endif
795#endif
796 EXPECT_EQ(&*std::next(L.begin()), *I);
797#if LLVM_ENABLE_ABI_BREAKING_CHECKS
798#ifndef NDEBUG
799 // Repeated dereferences are not allowed.
800 EXPECT_DEATH(*I, "Cannot dereference");
801#endif
802#endif
803
804 // Inserting shouldn't break anything. We should be able to keep dereferencing
805 // the currrent iterator and increment. The increment to go to the "next"
806 // iterator from before we inserted.
807 L.insert(position: std::next(x: L.begin(), n: 2), x: -1);
808 ++I;
809 EXPECT_EQ(&*std::next(L.begin(), 3), *I);
810
811 // Erasing the front including the current doesn't break incrementing.
812 L.erase(first: L.begin(), last: std::prev(x: L.end()));
813 ++I;
814 EXPECT_EQ(&*L.begin(), *I);
815 ++I;
816 EXPECT_EQ(EIR.end(), I);
817}
818
819TEST(STLExtrasTest, AllEqual) {
820 std::vector<int> V;
821 EXPECT_TRUE(all_equal(V));
822
823 V.push_back(x: 1);
824 EXPECT_TRUE(all_equal(V));
825
826 V.push_back(x: 1);
827 V.push_back(x: 1);
828 EXPECT_TRUE(all_equal(V));
829
830 V.push_back(x: 2);
831 EXPECT_FALSE(all_equal(V));
832}
833
834TEST(STLExtrasTest, AllEqualInitializerList) {
835 EXPECT_TRUE(all_equal({1}));
836 EXPECT_TRUE(all_equal({1, 1}));
837 EXPECT_FALSE(all_equal({1, 2}));
838 EXPECT_FALSE(all_equal({2, 1}));
839 EXPECT_TRUE(all_equal({1, 1, 1}));
840}
841
842TEST(STLExtrasTest, to_address) {
843 int *V1 = new int;
844 EXPECT_EQ(V1, to_address(V1));
845
846 // Check fancy pointer overload for unique_ptr
847 std::unique_ptr<int> V2 = std::make_unique<int>(args: 0);
848 EXPECT_EQ(V2.get(), llvm::to_address(V2));
849
850 V2.reset(p: V1);
851 EXPECT_EQ(V1, llvm::to_address(V2));
852 V2.release();
853
854 // Check fancy pointer overload for shared_ptr
855 std::shared_ptr<int> V3 = std::make_shared<int>(args: 0);
856 std::shared_ptr<int> V4 = V3;
857 EXPECT_EQ(V3.get(), V4.get());
858 EXPECT_EQ(V3.get(), llvm::to_address(V3));
859 EXPECT_EQ(V4.get(), llvm::to_address(V4));
860
861 V3.reset(p: V1);
862 EXPECT_EQ(V1, llvm::to_address(V3));
863}
864
865TEST(STLExtrasTest, partition_point) {
866 std::vector<int> V = {1, 3, 5, 7, 9};
867
868 // Range version.
869 EXPECT_EQ(V.begin() + 3,
870 partition_point(V, [](unsigned X) { return X < 7; }));
871 EXPECT_EQ(V.begin(), partition_point(V, [](unsigned X) { return X < 1; }));
872 EXPECT_EQ(V.end(), partition_point(V, [](unsigned X) { return X < 50; }));
873}
874
875TEST(STLExtrasTest, hasSingleElement) {
876 const std::vector<int> V0 = {}, V1 = {1}, V2 = {1, 2};
877 const std::vector<int> V10(10);
878
879 EXPECT_EQ(hasSingleElement(V0), false);
880 EXPECT_EQ(hasSingleElement(V1), true);
881 EXPECT_EQ(hasSingleElement(V2), false);
882 EXPECT_EQ(hasSingleElement(V10), false);
883}
884
885TEST(STLExtrasTest, hasNItems) {
886 const std::list<int> V0 = {}, V1 = {1}, V2 = {1, 2};
887 const std::list<int> V3 = {1, 3, 5};
888
889 EXPECT_TRUE(hasNItems(V0, 0));
890 EXPECT_FALSE(hasNItems(V0, 2));
891 EXPECT_TRUE(hasNItems(V1, 1));
892 EXPECT_FALSE(hasNItems(V1, 2));
893
894 EXPECT_TRUE(hasNItems(V3.begin(), V3.end(), 3, [](int x) { return x < 10; }));
895 EXPECT_TRUE(hasNItems(V3.begin(), V3.end(), 0, [](int x) { return x > 10; }));
896 EXPECT_TRUE(hasNItems(V3.begin(), V3.end(), 2, [](int x) { return x < 5; }));
897}
898
899TEST(STLExtras, hasNItemsOrMore) {
900 const std::list<int> V0 = {}, V1 = {1}, V2 = {1, 2};
901 const std::list<int> V3 = {1, 3, 5};
902
903 EXPECT_TRUE(hasNItemsOrMore(V1, 1));
904 EXPECT_FALSE(hasNItemsOrMore(V1, 2));
905
906 EXPECT_TRUE(hasNItemsOrMore(V2, 1));
907 EXPECT_TRUE(hasNItemsOrMore(V2, 2));
908 EXPECT_FALSE(hasNItemsOrMore(V2, 3));
909
910 EXPECT_TRUE(hasNItemsOrMore(V3, 3));
911 EXPECT_FALSE(hasNItemsOrMore(V3, 4));
912
913 EXPECT_TRUE(
914 hasNItemsOrMore(V3.begin(), V3.end(), 3, [](int x) { return x < 10; }));
915 EXPECT_FALSE(
916 hasNItemsOrMore(V3.begin(), V3.end(), 3, [](int x) { return x > 10; }));
917 EXPECT_TRUE(
918 hasNItemsOrMore(V3.begin(), V3.end(), 2, [](int x) { return x < 5; }));
919}
920
921TEST(STLExtras, hasNItemsOrLess) {
922 const std::list<int> V0 = {}, V1 = {1}, V2 = {1, 2};
923 const std::list<int> V3 = {1, 3, 5};
924
925 EXPECT_TRUE(hasNItemsOrLess(V0, 0));
926 EXPECT_TRUE(hasNItemsOrLess(V0, 1));
927 EXPECT_TRUE(hasNItemsOrLess(V0, 2));
928
929 EXPECT_FALSE(hasNItemsOrLess(V1, 0));
930 EXPECT_TRUE(hasNItemsOrLess(V1, 1));
931 EXPECT_TRUE(hasNItemsOrLess(V1, 2));
932
933 EXPECT_FALSE(hasNItemsOrLess(V2, 0));
934 EXPECT_FALSE(hasNItemsOrLess(V2, 1));
935 EXPECT_TRUE(hasNItemsOrLess(V2, 2));
936 EXPECT_TRUE(hasNItemsOrLess(V2, 3));
937
938 EXPECT_FALSE(hasNItemsOrLess(V3, 0));
939 EXPECT_FALSE(hasNItemsOrLess(V3, 1));
940 EXPECT_FALSE(hasNItemsOrLess(V3, 2));
941 EXPECT_TRUE(hasNItemsOrLess(V3, 3));
942 EXPECT_TRUE(hasNItemsOrLess(V3, 4));
943
944 EXPECT_TRUE(
945 hasNItemsOrLess(V3.begin(), V3.end(), 1, [](int x) { return x == 1; }));
946 EXPECT_TRUE(
947 hasNItemsOrLess(V3.begin(), V3.end(), 2, [](int x) { return x < 5; }));
948 EXPECT_TRUE(
949 hasNItemsOrLess(V3.begin(), V3.end(), 5, [](int x) { return x < 5; }));
950 EXPECT_FALSE(
951 hasNItemsOrLess(V3.begin(), V3.end(), 2, [](int x) { return x < 10; }));
952}
953
954TEST(STLExtras, MoveRange) {
955 class Foo {
956 bool A;
957
958 public:
959 Foo() : A(true) {}
960 Foo(const Foo &) = delete;
961 Foo(Foo &&Other) : A(Other.A) { Other.A = false; }
962 Foo &operator=(const Foo &) = delete;
963 Foo &operator=(Foo &&Other) {
964 if (this != &Other) {
965 A = Other.A;
966 Other.A = false;
967 }
968 return *this;
969 }
970 operator bool() const { return A; }
971 };
972 SmallVector<Foo, 4U> V1, V2, V3, V4;
973 auto HasVal = [](const Foo &Item) { return static_cast<bool>(Item); };
974 auto Build = [&] {
975 SmallVector<Foo, 4U> Foos;
976 Foos.resize(N: 4U);
977 return Foos;
978 };
979
980 V1.resize(N: 4U);
981 EXPECT_TRUE(llvm::all_of(V1, HasVal));
982
983 llvm::move(Range&: V1, Out: std::back_inserter(x&: V2));
984
985 // Ensure input container is same size, but its contents were moved out.
986 EXPECT_EQ(V1.size(), 4U);
987 EXPECT_TRUE(llvm::none_of(V1, HasVal));
988
989 // Ensure output container has the contents of the input container.
990 EXPECT_EQ(V2.size(), 4U);
991 EXPECT_TRUE(llvm::all_of(V2, HasVal));
992
993 llvm::move(Range: std::move(V2), Out: std::back_inserter(x&: V3));
994
995 EXPECT_TRUE(llvm::none_of(V2, HasVal));
996 EXPECT_EQ(V3.size(), 4U);
997 EXPECT_TRUE(llvm::all_of(V3, HasVal));
998
999 llvm::move(Range: Build(), Out: std::back_inserter(x&: V4));
1000 EXPECT_EQ(V4.size(), 4U);
1001 EXPECT_TRUE(llvm::all_of(V4, HasVal));
1002}
1003
1004TEST(STLExtras, Unique) {
1005 std::vector<int> V = {1, 5, 5, 4, 3, 3, 3};
1006
1007 auto I = llvm::unique(R&: V, P: [](int a, int b) { return a == b; });
1008
1009 EXPECT_EQ(I, V.begin() + 4);
1010
1011 EXPECT_EQ(1, V[0]);
1012 EXPECT_EQ(5, V[1]);
1013 EXPECT_EQ(4, V[2]);
1014 EXPECT_EQ(3, V[3]);
1015}
1016
1017TEST(STLExtras, UniqueNoPred) {
1018 std::vector<int> V = {1, 5, 5, 4, 3, 3, 3};
1019
1020 auto I = llvm::unique(R&: V);
1021
1022 EXPECT_EQ(I, V.begin() + 4);
1023
1024 EXPECT_EQ(1, V[0]);
1025 EXPECT_EQ(5, V[1]);
1026 EXPECT_EQ(4, V[2]);
1027 EXPECT_EQ(3, V[3]);
1028}
1029
1030TEST(STLExtrasTest, MakeVisitorOneCallable) {
1031 auto IdentityLambda = [](auto X) { return X; };
1032 auto IdentityVisitor = makeVisitor(Callables&: IdentityLambda);
1033 EXPECT_EQ(IdentityLambda(1), IdentityVisitor(1));
1034 EXPECT_EQ(IdentityLambda(2.0f), IdentityVisitor(2.0f));
1035 EXPECT_TRUE((std::is_same<decltype(IdentityLambda(IdentityLambda)),
1036 decltype(IdentityLambda)>::value));
1037 EXPECT_TRUE((std::is_same<decltype(IdentityVisitor(IdentityVisitor)),
1038 decltype(IdentityVisitor)>::value));
1039}
1040
1041TEST(STLExtrasTest, MakeVisitorTwoCallables) {
1042 auto Visitor =
1043 makeVisitor(Callables: [](int) { return 0; }, Callables: [](std::string) { return 1; });
1044 EXPECT_EQ(Visitor(42), 0);
1045 EXPECT_EQ(Visitor("foo"), 1);
1046}
1047
1048TEST(STLExtrasTest, MakeVisitorCallableMultipleOperands) {
1049 auto Second = makeVisitor(Callables: [](int I, float F) { return F; },
1050 Callables: [](float F, int I) { return I; });
1051 EXPECT_EQ(Second(1.f, 1), 1);
1052 EXPECT_EQ(Second(1, 1.f), 1.f);
1053}
1054
1055TEST(STLExtrasTest, MakeVisitorDefaultCase) {
1056 {
1057 auto Visitor = makeVisitor(Callables: [](int I) { return I + 100; },
1058 Callables: [](float F) { return F * 2; },
1059 Callables: [](auto) { return -1; });
1060 EXPECT_EQ(Visitor(24), 124);
1061 EXPECT_EQ(Visitor(2.f), 4.f);
1062 EXPECT_EQ(Visitor(2.), -1);
1063 EXPECT_EQ(Visitor(Visitor), -1);
1064 }
1065 {
1066 auto Visitor = makeVisitor(Callables: [](auto) { return -1; },
1067 Callables: [](int I) { return I + 100; },
1068 Callables: [](float F) { return F * 2; });
1069 EXPECT_EQ(Visitor(24), 124);
1070 EXPECT_EQ(Visitor(2.f), 4.f);
1071 EXPECT_EQ(Visitor(2.), -1);
1072 EXPECT_EQ(Visitor(Visitor), -1);
1073 }
1074}
1075
1076template <bool Moveable, bool Copyable>
1077struct Functor : Counted<Moveable, Copyable> {
1078 using Counted<Moveable, Copyable>::Counted;
1079 void operator()() {}
1080};
1081
1082TEST(STLExtrasTest, MakeVisitorLifetimeSemanticsPRValue) {
1083 int Copies = 0;
1084 int Moves = 0;
1085 int Destructors = 0;
1086 {
1087 auto V = makeVisitor(Callables: Functor<true, false>(Copies, Moves, Destructors));
1088 (void)V;
1089 EXPECT_EQ(0, Copies);
1090 EXPECT_EQ(1, Moves);
1091 EXPECT_EQ(1, Destructors);
1092 }
1093 EXPECT_EQ(0, Copies);
1094 EXPECT_EQ(1, Moves);
1095 EXPECT_EQ(2, Destructors);
1096}
1097
1098TEST(STLExtrasTest, MakeVisitorLifetimeSemanticsRValue) {
1099 int Copies = 0;
1100 int Moves = 0;
1101 int Destructors = 0;
1102 {
1103 Functor<true, false> F(Copies, Moves, Destructors);
1104 {
1105 auto V = makeVisitor(Callables: std::move(F));
1106 (void)V;
1107 EXPECT_EQ(0, Copies);
1108 EXPECT_EQ(1, Moves);
1109 EXPECT_EQ(0, Destructors);
1110 }
1111 EXPECT_EQ(0, Copies);
1112 EXPECT_EQ(1, Moves);
1113 EXPECT_EQ(1, Destructors);
1114 }
1115 EXPECT_EQ(0, Copies);
1116 EXPECT_EQ(1, Moves);
1117 EXPECT_EQ(2, Destructors);
1118}
1119
1120TEST(STLExtrasTest, MakeVisitorLifetimeSemanticsLValue) {
1121 int Copies = 0;
1122 int Moves = 0;
1123 int Destructors = 0;
1124 {
1125 Functor<true, true> F(Copies, Moves, Destructors);
1126 {
1127 auto V = makeVisitor(Callables&: F);
1128 (void)V;
1129 EXPECT_EQ(1, Copies);
1130 EXPECT_EQ(0, Moves);
1131 EXPECT_EQ(0, Destructors);
1132 }
1133 EXPECT_EQ(1, Copies);
1134 EXPECT_EQ(0, Moves);
1135 EXPECT_EQ(1, Destructors);
1136 }
1137 EXPECT_EQ(1, Copies);
1138 EXPECT_EQ(0, Moves);
1139 EXPECT_EQ(2, Destructors);
1140}
1141
1142TEST(STLExtrasTest, AllOfZip) {
1143 std::vector<int> v1 = {0, 4, 2, 1};
1144 std::vector<int> v2 = {1, 4, 3, 6};
1145 EXPECT_TRUE(all_of_zip(v1, v2, [](int v1, int v2) { return v1 <= v2; }));
1146 EXPECT_FALSE(all_of_zip(v1, v2, [](int L, int R) { return L < R; }));
1147
1148 // Triple vectors
1149 std::vector<int> v3 = {1, 6, 5, 7};
1150 EXPECT_EQ(true, all_of_zip(v1, v2, v3, [](int a, int b, int c) {
1151 return a <= b && b <= c;
1152 }));
1153 EXPECT_EQ(false, all_of_zip(v1, v2, v3, [](int a, int b, int c) {
1154 return a < b && b < c;
1155 }));
1156
1157 // Shorter vector should fail even with an always-true predicate.
1158 std::vector<int> v_short = {1, 4};
1159 EXPECT_EQ(false, all_of_zip(v1, v_short, [](int, int) { return true; }));
1160 EXPECT_EQ(false,
1161 all_of_zip(v1, v2, v_short, [](int, int, int) { return true; }));
1162}
1163
1164TEST(STLExtrasTest, TypesAreDistinct) {
1165 EXPECT_TRUE((llvm::TypesAreDistinct<>::value));
1166 EXPECT_TRUE((llvm::TypesAreDistinct<int>::value));
1167 EXPECT_FALSE((llvm::TypesAreDistinct<int, int>::value));
1168 EXPECT_TRUE((llvm::TypesAreDistinct<int, float>::value));
1169 EXPECT_FALSE((llvm::TypesAreDistinct<int, float, int>::value));
1170 EXPECT_TRUE((llvm::TypesAreDistinct<int, float, double>::value));
1171 EXPECT_FALSE((llvm::TypesAreDistinct<int, float, double, float>::value));
1172 EXPECT_TRUE((llvm::TypesAreDistinct<int, int *>::value));
1173 EXPECT_TRUE((llvm::TypesAreDistinct<int, int &>::value));
1174 EXPECT_TRUE((llvm::TypesAreDistinct<int, int &&>::value));
1175 EXPECT_TRUE((llvm::TypesAreDistinct<int, const int>::value));
1176}
1177
1178TEST(STLExtrasTest, FirstIndexOfType) {
1179 EXPECT_EQ((llvm::FirstIndexOfType<int, int>::value), 0u);
1180 EXPECT_EQ((llvm::FirstIndexOfType<int, int, int>::value), 0u);
1181 EXPECT_EQ((llvm::FirstIndexOfType<int, float, int>::value), 1u);
1182 EXPECT_EQ((llvm::FirstIndexOfType<int const *, float, int, int const *,
1183 const int>::value),
1184 2u);
1185}
1186
1187TEST(STLExtrasTest, TypeAtIndex) {
1188 EXPECT_TRUE((std::is_same<int, llvm::TypeAtIndex<0, int>>::value));
1189 EXPECT_TRUE((std::is_same<int, llvm::TypeAtIndex<0, int, float>>::value));
1190 EXPECT_TRUE((std::is_same<float, llvm::TypeAtIndex<1, int, float>>::value));
1191 EXPECT_TRUE(
1192 (std::is_same<float, llvm::TypeAtIndex<1, int, float, double>>::value));
1193 EXPECT_TRUE(
1194 (std::is_same<float, llvm::TypeAtIndex<1, int, float, double>>::value));
1195 EXPECT_TRUE(
1196 (std::is_same<double, llvm::TypeAtIndex<2, int, float, double>>::value));
1197}
1198
1199enum Doggos {
1200 Floofer,
1201 Woofer,
1202 SubWoofer,
1203 Pupper,
1204 Pupperino,
1205 Longboi,
1206};
1207
1208struct WooferCmp {
1209 // Not copyable.
1210 WooferCmp() = default;
1211 WooferCmp(const WooferCmp &) = delete;
1212 WooferCmp &operator=(const WooferCmp &) = delete;
1213
1214 friend bool operator==(const Doggos &Doggo, const WooferCmp &) {
1215 return Doggo == Doggos::Woofer;
1216 }
1217};
1218
1219TEST(STLExtrasTest, IsContainedInitializerList) {
1220 EXPECT_TRUE(is_contained({Woofer, SubWoofer}, Woofer));
1221 EXPECT_TRUE(is_contained({Woofer, SubWoofer}, SubWoofer));
1222 EXPECT_FALSE(is_contained({Woofer, SubWoofer}, Pupper));
1223
1224 // Check that the initializer list type and the element type do not have to
1225 // match exactly.
1226 EXPECT_TRUE(is_contained({Floofer, Woofer, SubWoofer}, WooferCmp{}));
1227 EXPECT_FALSE(is_contained({Floofer, SubWoofer}, WooferCmp{}));
1228
1229 EXPECT_TRUE(is_contained({"a", "bb", "ccc", "dddd"}, llvm::StringRef("ccc")));
1230 EXPECT_FALSE(is_contained({"a", "bb", "ccc", "dddd"}, llvm::StringRef("x")));
1231
1232 static_assert(is_contained(Set: {Woofer, SubWoofer}, Element: SubWoofer), "SubWoofer!");
1233 static_assert(!is_contained(Set: {Woofer, SubWoofer}, Element: Pupper), "Missing Pupper!");
1234
1235 EXPECT_TRUE(is_contained({1, 2, 3, 4}, 3));
1236 EXPECT_FALSE(is_contained({1, 2, 3, 4}, 5));
1237
1238 static_assert(is_contained(Set: {1, 2, 3, 4}, Element: 3), "It's there!");
1239 static_assert(!is_contained(Set: {1, 2, 3, 4}, Element: 5), "It's not there :(");
1240}
1241
1242TEST(STLExtrasTest, IsContainedMemberContains) {
1243 // Check that `llvm::is_contained` uses the member `.contains()` when
1244 // available. Check that `.contains()` is preferred over `.find()`.
1245 struct Foo {
1246 bool contains(int) const {
1247 ++NumContainsCalls;
1248 return ContainsResult;
1249 }
1250 int *begin() { return nullptr; }
1251 int *end() { return nullptr; }
1252 int *find(int) { return nullptr; }
1253
1254 bool ContainsResult = false;
1255 mutable unsigned NumContainsCalls = 0;
1256 } Container;
1257
1258 EXPECT_EQ(Container.NumContainsCalls, 0u);
1259 EXPECT_FALSE(is_contained(Container, 1));
1260 EXPECT_EQ(Container.NumContainsCalls, 1u);
1261
1262 Container.ContainsResult = true;
1263 EXPECT_TRUE(is_contained(Container, 1));
1264 EXPECT_EQ(Container.NumContainsCalls, 2u);
1265}
1266
1267TEST(STLExtrasTest, IsContainedMemberFind) {
1268 // Check that `llvm::is_contained` uses the member `.find(x)` when available.
1269 struct Foo {
1270 auto begin() { return Data.begin(); }
1271 auto end() { return Data.end(); }
1272 auto find(int X) {
1273 ++NumFindCalls;
1274 return std::find(first: begin(), last: end(), val: X);
1275 }
1276
1277 std::vector<int> Data;
1278 mutable unsigned NumFindCalls = 0;
1279 } Container;
1280
1281 Container.Data = {1, 2, 3};
1282
1283 EXPECT_EQ(Container.NumFindCalls, 0u);
1284 EXPECT_TRUE(is_contained(Container, 1));
1285 EXPECT_TRUE(is_contained(Container, 3));
1286 EXPECT_EQ(Container.NumFindCalls, 2u);
1287
1288 EXPECT_FALSE(is_contained(Container, 4));
1289 EXPECT_EQ(Container.NumFindCalls, 3u);
1290}
1291
1292TEST(STLExtrasTest, addEnumValues) {
1293 enum A { Zero = 0, One = 1 };
1294 enum B { IntMax = INT_MAX, ULongLongMax = ULLONG_MAX };
1295 enum class C : unsigned { Two = 2 };
1296
1297 // Non-fixed underlying types, with same underlying types
1298 static_assert(addEnumValues(LHS: Zero, RHS: One) == 1,
1299 "addEnumValues(Zero, One) failed.");
1300 static_assert(addEnumValues(LHS: IntMax, RHS: ULongLongMax) ==
1301 INT_MAX + static_cast<unsigned long long>(ULLONG_MAX),
1302 "addEnumValues(IntMax, ULongLongMax) failed.");
1303 // Non-fixed underlying types, with different underlying types
1304 static_assert(addEnumValues(LHS: Zero, RHS: IntMax) == INT_MAX,
1305 "addEnumValues(Zero, IntMax) failed.");
1306 static_assert(addEnumValues(LHS: One, RHS: ULongLongMax) ==
1307 1 + static_cast<unsigned long long>(ULLONG_MAX),
1308 "addEnumValues(One, ULongLongMax) failed.");
1309 // Non-fixed underlying type enum and fixed underlying type enum, with same
1310 // underlying types
1311 static_assert(addEnumValues(LHS: One, RHS: C::Two) == 3,
1312 "addEnumValues(One, C::Two) failed.");
1313 // Non-fixed underlying type enum and fixed underlying type enum, with
1314 // different underlying types
1315 static_assert(addEnumValues(LHS: ULongLongMax, RHS: C::Two) ==
1316 static_cast<unsigned long long>(ULLONG_MAX) + 2,
1317 "addEnumValues(ULongLongMax, C::Two) failed.");
1318}
1319
1320TEST(STLExtrasTest, LessFirst) {
1321 {
1322 std::pair<int, int> A(0, 1);
1323 std::pair<int, int> B(1, 0);
1324 EXPECT_TRUE(less_first()(A, B));
1325 EXPECT_FALSE(less_first()(B, A));
1326 }
1327
1328 {
1329 std::tuple<int, int> A(0, 1);
1330 std::tuple<int, int> B(1, 0);
1331 EXPECT_TRUE(less_first()(A, B));
1332 EXPECT_FALSE(less_first()(B, A));
1333 }
1334}
1335
1336TEST(STLExtrasTest, LessSecond) {
1337 {
1338 std::pair<int, int> A(0, 1);
1339 std::pair<int, int> B(1, 0);
1340 EXPECT_FALSE(less_second()(A, B));
1341 EXPECT_TRUE(less_second()(B, A));
1342 }
1343
1344 {
1345 std::tuple<int, int> A(0, 1);
1346 std::tuple<int, int> B(1, 0);
1347 EXPECT_FALSE(less_second()(A, B));
1348 EXPECT_TRUE(less_second()(B, A));
1349 }
1350}
1351
1352struct Foo;
1353struct Bar {};
1354
1355static_assert(is_incomplete_v<Foo>, "Foo is incomplete");
1356static_assert(!is_incomplete_v<Bar>, "Bar is defined");
1357
1358} // namespace
1359

source code of llvm/unittests/ADT/STLExtrasTest.cpp