summaryrefslogtreecommitdiffstats
path: root/llvm/unittests
diff options
context:
space:
mode:
authorMichael Kruse <llvm@meinersbur.de>2018-12-04 21:06:16 +0000
committerMichael Kruse <llvm@meinersbur.de>2018-12-04 21:06:16 +0000
commite6899bf0027d85b44cab48de1c07b434952a4444 (patch)
tree99115409e6ad542b49bb88bfa4ecba262500e221 /llvm/unittests
parent24fb29658962d16552a917e9eb74bdca2884d259 (diff)
downloadbcm5719-llvm-e6899bf0027d85b44cab48de1c07b434952a4444.tar.gz
bcm5719-llvm-e6899bf0027d85b44cab48de1c07b434952a4444.zip
[ADT] Add zip_longest iterators
Like the already existing zip_shortest/zip_first iterators, zip_longest iterates over multiple iterators at once, but has as many iterations as the longest sequence. This means some iterators may reach the end before others do. zip_longest uses llvm::Optional's None value to mark a past-the-end value. zip_longest is not reverse-iteratable because the tuples iterated over would be different for different length sequences (IMHO for the same reason neither zip_shortest nor zip_first should be reverse-iteratable; one can still reverse the ranges individually if that's the expected behavior). In contrast to zip_shortest/zip_first, zip_longest tuples contain rvalues instead of references. This is because llvm::Optional cannot contain reference types and the value-initialized default does not have a memory location a reference could point to. The motivation for these iterators is to use C++ foreach to compare two lists of ordered attributes in D48100 (SemaOverload.cpp and ASTReaderDecl.cpp). Idea by @hfinkel. Differential Revision: https://reviews.llvm.org/D48348 llvm-svn: 348301
Diffstat (limited to 'llvm/unittests')
-rw-r--r--llvm/unittests/ADT/IteratorTest.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/llvm/unittests/ADT/IteratorTest.cpp b/llvm/unittests/ADT/IteratorTest.cpp
index de0a6710789..f15ba8eac83 100644
--- a/llvm/unittests/ADT/IteratorTest.cpp
+++ b/llvm/unittests/ADT/IteratorTest.cpp
@@ -328,6 +328,36 @@ TEST(ZipIteratorTest, ZipFirstBasic) {
EXPECT_EQ(iters, 4u);
}
+TEST(ZipIteratorTest, ZipLongestBasic) {
+ using namespace std;
+ const vector<unsigned> pi{3, 1, 4, 1, 5, 9};
+ const vector<StringRef> e{"2", "7", "1", "8"};
+
+ {
+ // Check left range longer than right.
+ const vector<tuple<Optional<unsigned>, Optional<StringRef>>> expected{
+ {3, {"2"}}, {1, {"7"}}, {4, {"1"}}, {1, {"8"}}, {5, None}, {9, None}};
+ size_t iters = 0;
+ for (auto tup : zip_longest(pi, e)) {
+ EXPECT_EQ(tup, expected[iters]);
+ iters += 1;
+ }
+ EXPECT_EQ(iters, expected.size());
+ }
+
+ {
+ // Check right range longer than left.
+ const vector<tuple<Optional<StringRef>, Optional<unsigned>>> expected{
+ {{"2"}, 3}, {{"7"}, 1}, {{"1"}, 4}, {{"8"}, 1}, {None, 5}, {None, 9}};
+ size_t iters = 0;
+ for (auto tup : zip_longest(e, pi)) {
+ EXPECT_EQ(tup, expected[iters]);
+ iters += 1;
+ }
+ EXPECT_EQ(iters, expected.size());
+ }
+}
+
TEST(ZipIteratorTest, Mutability) {
using namespace std;
const SmallVector<unsigned, 4> pi{3, 1, 4, 1, 5, 9};
OpenPOWER on IntegriCloud