1 //===------ MappedIteratorTest.cpp - Unit tests for mapped_iterator -------===// 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 "gtest/gtest.h" 11 12 using namespace llvm; 13 14 namespace { 15 16 TEST(MappedIteratorTest, ApplyFunctionOnDereference) { 17 std::vector<int> V({0}); 18 19 auto I = map_iterator(V.begin(), [](int X) { return X + 1; }); 20 21 EXPECT_EQ(*I, 1) << "should have applied function in dereference"; 22 } 23 24 TEST(MappedIteratorTest, ApplyFunctionOnArrow) { 25 struct S { 26 int Z = 0; 27 }; 28 29 std::vector<int> V({0}); 30 S Y; 31 S* P = &Y; 32 33 auto I = map_iterator(V.begin(), [&](int X) -> S& { return *(P + X); }); 34 35 I->Z = 42; 36 37 EXPECT_EQ(Y.Z, 42) << "should have applied function during arrow"; 38 } 39 40 TEST(MappedIteratorTest, FunctionPreservesReferences) { 41 std::vector<int> V({1}); 42 std::map<int, int> M({ {1, 1} }); 43 44 auto I = map_iterator(V.begin(), [&](int X) -> int& { return M[X]; }); 45 *I = 42; 46 47 EXPECT_EQ(M[1], 42) << "assignment should have modified M"; 48 } 49 50 TEST(MappedIteratorTest, CustomIteratorApplyFunctionOnDereference) { 51 struct CustomMapIterator 52 : public llvm::mapped_iterator_base<CustomMapIterator, 53 std::vector<int>::iterator, int> { 54 using BaseT::BaseT; 55 56 /// Map the element to the iterator result type. 57 int mapElement(int X) const { return X + 1; } 58 }; 59 60 std::vector<int> V({0}); 61 62 CustomMapIterator I(V.begin()); 63 64 EXPECT_EQ(*I, 1) << "should have applied function in dereference"; 65 } 66 67 TEST(MappedIteratorTest, CustomIteratorApplyFunctionOnArrow) { 68 struct S { 69 int Z = 0; 70 }; 71 struct CustomMapIterator 72 : public llvm::mapped_iterator_base<CustomMapIterator, 73 std::vector<int>::iterator, S &> { 74 CustomMapIterator(std::vector<int>::iterator it, S *P) : BaseT(it), P(P) {} 75 76 /// Map the element to the iterator result type. 77 S &mapElement(int X) const { return *(P + X); } 78 79 S *P; 80 }; 81 82 std::vector<int> V({0}); 83 S Y; 84 85 CustomMapIterator I(V.begin(), &Y); 86 87 I->Z = 42; 88 89 EXPECT_EQ(Y.Z, 42) << "should have applied function during arrow"; 90 } 91 92 TEST(MappedIteratorTest, CustomIteratorFunctionPreservesReferences) { 93 struct CustomMapIterator 94 : public llvm::mapped_iterator_base<CustomMapIterator, 95 std::vector<int>::iterator, int &> { 96 CustomMapIterator(std::vector<int>::iterator it, std::map<int, int> &M) 97 : BaseT(it), M(M) {} 98 99 /// Map the element to the iterator result type. 100 int &mapElement(int X) const { return M[X]; } 101 102 std::map<int, int> &M; 103 }; 104 std::vector<int> V({1}); 105 std::map<int, int> M({{1, 1}}); 106 107 auto I = CustomMapIterator(V.begin(), M); 108 *I = 42; 109 110 EXPECT_EQ(M[1], 42) << "assignment should have modified M"; 111 } 112 113 } // anonymous namespace 114