[ADT] Add filter_iterator for filtering elements
Differential Revision: https://reviews.llvm.org/D22951
llvm-svn: 278569
diff --git a/llvm/unittests/Support/IteratorTest.cpp b/llvm/unittests/Support/IteratorTest.cpp
index 853d16c..63dfa2a 100644
--- a/llvm/unittests/Support/IteratorTest.cpp
+++ b/llvm/unittests/Support/IteratorTest.cpp
@@ -116,4 +116,73 @@
EXPECT_EQ(End, I);
}
+TEST(FilterIteratorTest, Lambda) {
+ auto IsOdd = [](int N) { return N % 2 == 1; };
+ int A[] = {0, 1, 2, 3, 4, 5, 6};
+ auto Range = make_filter_range(A, IsOdd);
+ SmallVector<int, 3> Actual(Range.begin(), Range.end());
+ EXPECT_EQ((SmallVector<int, 3>{1, 3, 5}), Actual);
+}
+
+TEST(FilterIteratorTest, CallableObject) {
+ int Counter = 0;
+ struct Callable {
+ int &Counter;
+
+ Callable(int &Counter) : Counter(Counter) {}
+
+ bool operator()(int N) {
+ Counter++;
+ return N % 2 == 1;
+ }
+ };
+ Callable IsOdd(Counter);
+ int A[] = {0, 1, 2, 3, 4, 5, 6};
+ auto Range = make_filter_range(A, IsOdd);
+ EXPECT_EQ(2, Counter);
+ SmallVector<int, 3> Actual(Range.begin(), Range.end());
+ EXPECT_GE(Counter, 7);
+ EXPECT_EQ((SmallVector<int, 3>{1, 3, 5}), Actual);
+}
+
+TEST(FilterIteratorTest, FunctionPointer) {
+ bool (*IsOdd)(int) = [](int N) { return N % 2 == 1; };
+ int A[] = {0, 1, 2, 3, 4, 5, 6};
+ auto Range = make_filter_range(A, IsOdd);
+ SmallVector<int, 3> Actual(Range.begin(), Range.end());
+ EXPECT_EQ((SmallVector<int, 3>{1, 3, 5}), Actual);
+}
+
+TEST(FilterIteratorTest, Composition) {
+ auto IsOdd = [](int N) { return N % 2 == 1; };
+ std::unique_ptr<int> A[] = {make_unique<int>(0), make_unique<int>(1),
+ make_unique<int>(2), make_unique<int>(3),
+ make_unique<int>(4), make_unique<int>(5),
+ make_unique<int>(6)};
+ using PointeeIterator = pointee_iterator<std::unique_ptr<int> *>;
+ auto Range = make_filter_range(
+ make_range(PointeeIterator(std::begin(A)), PointeeIterator(std::end(A))),
+ IsOdd);
+ SmallVector<int, 3> Actual(Range.begin(), Range.end());
+ EXPECT_EQ((SmallVector<int, 3>{1, 3, 5}), Actual);
+}
+
+TEST(FilterIteratorTest, InputIterator) {
+ struct InputIterator
+ : iterator_adaptor_base<InputIterator, int *, std::input_iterator_tag> {
+ using BaseT =
+ iterator_adaptor_base<InputIterator, int *, std::input_iterator_tag>;
+
+ InputIterator(int *It) : BaseT(It) {}
+ };
+
+ auto IsOdd = [](int N) { return N % 2 == 1; };
+ int A[] = {0, 1, 2, 3, 4, 5, 6};
+ auto Range = make_filter_range(
+ make_range(InputIterator(std::begin(A)), InputIterator(std::end(A))),
+ IsOdd);
+ SmallVector<int, 3> Actual(Range.begin(), Range.end());
+ EXPECT_EQ((SmallVector<int, 3>{1, 3, 5}), Actual);
+}
+
} // anonymous namespace