1fd4e5da5Sopenharmony_ci// Copyright (c) 2016 Google Inc. 2fd4e5da5Sopenharmony_ci// 3fd4e5da5Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License"); 4fd4e5da5Sopenharmony_ci// you may not use this file except in compliance with the License. 5fd4e5da5Sopenharmony_ci// You may obtain a copy of the License at 6fd4e5da5Sopenharmony_ci// 7fd4e5da5Sopenharmony_ci// http://www.apache.org/licenses/LICENSE-2.0 8fd4e5da5Sopenharmony_ci// 9fd4e5da5Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software 10fd4e5da5Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS, 11fd4e5da5Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fd4e5da5Sopenharmony_ci// See the License for the specific language governing permissions and 13fd4e5da5Sopenharmony_ci// limitations under the License. 14fd4e5da5Sopenharmony_ci 15fd4e5da5Sopenharmony_ci#include <memory> 16fd4e5da5Sopenharmony_ci#include <vector> 17fd4e5da5Sopenharmony_ci 18fd4e5da5Sopenharmony_ci#include "gmock/gmock.h" 19fd4e5da5Sopenharmony_ci 20fd4e5da5Sopenharmony_ci#include "source/opt/iterator.h" 21fd4e5da5Sopenharmony_ci#include "source/util/make_unique.h" 22fd4e5da5Sopenharmony_ci 23fd4e5da5Sopenharmony_cinamespace spvtools { 24fd4e5da5Sopenharmony_cinamespace opt { 25fd4e5da5Sopenharmony_cinamespace { 26fd4e5da5Sopenharmony_ci 27fd4e5da5Sopenharmony_ciusing ::testing::ContainerEq; 28fd4e5da5Sopenharmony_ci 29fd4e5da5Sopenharmony_ciTEST(Iterator, IncrementDeref) { 30fd4e5da5Sopenharmony_ci const int count = 100; 31fd4e5da5Sopenharmony_ci std::vector<std::unique_ptr<int>> data; 32fd4e5da5Sopenharmony_ci for (int i = 0; i < count; ++i) { 33fd4e5da5Sopenharmony_ci data.emplace_back(new int(i)); 34fd4e5da5Sopenharmony_ci } 35fd4e5da5Sopenharmony_ci 36fd4e5da5Sopenharmony_ci UptrVectorIterator<int> it(&data, data.begin()); 37fd4e5da5Sopenharmony_ci UptrVectorIterator<int> end(&data, data.end()); 38fd4e5da5Sopenharmony_ci 39fd4e5da5Sopenharmony_ci EXPECT_EQ(*data[0], *it); 40fd4e5da5Sopenharmony_ci for (int i = 1; i < count; ++i) { 41fd4e5da5Sopenharmony_ci EXPECT_NE(end, it); 42fd4e5da5Sopenharmony_ci EXPECT_EQ(*data[i], *(++it)); 43fd4e5da5Sopenharmony_ci } 44fd4e5da5Sopenharmony_ci EXPECT_EQ(end, ++it); 45fd4e5da5Sopenharmony_ci} 46fd4e5da5Sopenharmony_ci 47fd4e5da5Sopenharmony_ciTEST(Iterator, DecrementDeref) { 48fd4e5da5Sopenharmony_ci const int count = 100; 49fd4e5da5Sopenharmony_ci std::vector<std::unique_ptr<int>> data; 50fd4e5da5Sopenharmony_ci for (int i = 0; i < count; ++i) { 51fd4e5da5Sopenharmony_ci data.emplace_back(new int(i)); 52fd4e5da5Sopenharmony_ci } 53fd4e5da5Sopenharmony_ci 54fd4e5da5Sopenharmony_ci UptrVectorIterator<int> begin(&data, data.begin()); 55fd4e5da5Sopenharmony_ci UptrVectorIterator<int> it(&data, data.end()); 56fd4e5da5Sopenharmony_ci 57fd4e5da5Sopenharmony_ci for (int i = count - 1; i >= 0; --i) { 58fd4e5da5Sopenharmony_ci EXPECT_NE(begin, it); 59fd4e5da5Sopenharmony_ci EXPECT_EQ(*data[i], *(--it)); 60fd4e5da5Sopenharmony_ci } 61fd4e5da5Sopenharmony_ci EXPECT_EQ(begin, it); 62fd4e5da5Sopenharmony_ci} 63fd4e5da5Sopenharmony_ci 64fd4e5da5Sopenharmony_ciTEST(Iterator, PostIncrementDeref) { 65fd4e5da5Sopenharmony_ci const int count = 100; 66fd4e5da5Sopenharmony_ci std::vector<std::unique_ptr<int>> data; 67fd4e5da5Sopenharmony_ci for (int i = 0; i < count; ++i) { 68fd4e5da5Sopenharmony_ci data.emplace_back(new int(i)); 69fd4e5da5Sopenharmony_ci } 70fd4e5da5Sopenharmony_ci 71fd4e5da5Sopenharmony_ci UptrVectorIterator<int> it(&data, data.begin()); 72fd4e5da5Sopenharmony_ci UptrVectorIterator<int> end(&data, data.end()); 73fd4e5da5Sopenharmony_ci 74fd4e5da5Sopenharmony_ci for (int i = 0; i < count; ++i) { 75fd4e5da5Sopenharmony_ci EXPECT_NE(end, it); 76fd4e5da5Sopenharmony_ci EXPECT_EQ(*data[i], *(it++)); 77fd4e5da5Sopenharmony_ci } 78fd4e5da5Sopenharmony_ci EXPECT_EQ(end, it); 79fd4e5da5Sopenharmony_ci} 80fd4e5da5Sopenharmony_ci 81fd4e5da5Sopenharmony_ciTEST(Iterator, PostDecrementDeref) { 82fd4e5da5Sopenharmony_ci const int count = 100; 83fd4e5da5Sopenharmony_ci std::vector<std::unique_ptr<int>> data; 84fd4e5da5Sopenharmony_ci for (int i = 0; i < count; ++i) { 85fd4e5da5Sopenharmony_ci data.emplace_back(new int(i)); 86fd4e5da5Sopenharmony_ci } 87fd4e5da5Sopenharmony_ci 88fd4e5da5Sopenharmony_ci UptrVectorIterator<int> begin(&data, data.begin()); 89fd4e5da5Sopenharmony_ci UptrVectorIterator<int> end(&data, data.end()); 90fd4e5da5Sopenharmony_ci UptrVectorIterator<int> it(&data, data.end()); 91fd4e5da5Sopenharmony_ci 92fd4e5da5Sopenharmony_ci EXPECT_EQ(end, it--); 93fd4e5da5Sopenharmony_ci for (int i = count - 1; i >= 1; --i) { 94fd4e5da5Sopenharmony_ci EXPECT_EQ(*data[i], *(it--)); 95fd4e5da5Sopenharmony_ci } 96fd4e5da5Sopenharmony_ci // Decrementing .begin() is undefined behavior. 97fd4e5da5Sopenharmony_ci EXPECT_EQ(*data[0], *it); 98fd4e5da5Sopenharmony_ci} 99fd4e5da5Sopenharmony_ci 100fd4e5da5Sopenharmony_ciTEST(Iterator, Access) { 101fd4e5da5Sopenharmony_ci const int count = 100; 102fd4e5da5Sopenharmony_ci std::vector<std::unique_ptr<int>> data; 103fd4e5da5Sopenharmony_ci for (int i = 0; i < count; ++i) { 104fd4e5da5Sopenharmony_ci data.emplace_back(new int(i)); 105fd4e5da5Sopenharmony_ci } 106fd4e5da5Sopenharmony_ci 107fd4e5da5Sopenharmony_ci UptrVectorIterator<int> it(&data, data.begin()); 108fd4e5da5Sopenharmony_ci 109fd4e5da5Sopenharmony_ci for (int i = 0; i < count; ++i) EXPECT_EQ(*data[i], it[i]); 110fd4e5da5Sopenharmony_ci} 111fd4e5da5Sopenharmony_ci 112fd4e5da5Sopenharmony_ciTEST(Iterator, Comparison) { 113fd4e5da5Sopenharmony_ci const int count = 100; 114fd4e5da5Sopenharmony_ci std::vector<std::unique_ptr<int>> data; 115fd4e5da5Sopenharmony_ci for (int i = 0; i < count; ++i) { 116fd4e5da5Sopenharmony_ci data.emplace_back(new int(i)); 117fd4e5da5Sopenharmony_ci } 118fd4e5da5Sopenharmony_ci 119fd4e5da5Sopenharmony_ci UptrVectorIterator<int> it(&data, data.begin()); 120fd4e5da5Sopenharmony_ci UptrVectorIterator<int> end(&data, data.end()); 121fd4e5da5Sopenharmony_ci 122fd4e5da5Sopenharmony_ci for (int i = 0; i < count; ++i, ++it) EXPECT_TRUE(it < end); 123fd4e5da5Sopenharmony_ci EXPECT_EQ(end, it); 124fd4e5da5Sopenharmony_ci} 125fd4e5da5Sopenharmony_ci 126fd4e5da5Sopenharmony_ciTEST(Iterator, InsertBeginEnd) { 127fd4e5da5Sopenharmony_ci const int count = 100; 128fd4e5da5Sopenharmony_ci 129fd4e5da5Sopenharmony_ci std::vector<std::unique_ptr<int>> data; 130fd4e5da5Sopenharmony_ci std::vector<int> expected; 131fd4e5da5Sopenharmony_ci std::vector<int> actual; 132fd4e5da5Sopenharmony_ci 133fd4e5da5Sopenharmony_ci for (int i = 0; i < count; ++i) { 134fd4e5da5Sopenharmony_ci data.emplace_back(new int(i)); 135fd4e5da5Sopenharmony_ci expected.push_back(i); 136fd4e5da5Sopenharmony_ci } 137fd4e5da5Sopenharmony_ci 138fd4e5da5Sopenharmony_ci // Insert at the beginning 139fd4e5da5Sopenharmony_ci expected.insert(expected.begin(), -100); 140fd4e5da5Sopenharmony_ci UptrVectorIterator<int> begin(&data, data.begin()); 141fd4e5da5Sopenharmony_ci auto insert_point = begin.InsertBefore(MakeUnique<int>(-100)); 142fd4e5da5Sopenharmony_ci for (int i = 0; i < count + 1; ++i) { 143fd4e5da5Sopenharmony_ci actual.push_back(*(insert_point++)); 144fd4e5da5Sopenharmony_ci } 145fd4e5da5Sopenharmony_ci EXPECT_THAT(actual, ContainerEq(expected)); 146fd4e5da5Sopenharmony_ci 147fd4e5da5Sopenharmony_ci // Insert at the end 148fd4e5da5Sopenharmony_ci expected.push_back(-42); 149fd4e5da5Sopenharmony_ci expected.push_back(-36); 150fd4e5da5Sopenharmony_ci expected.push_back(-77); 151fd4e5da5Sopenharmony_ci UptrVectorIterator<int> end(&data, data.end()); 152fd4e5da5Sopenharmony_ci end = end.InsertBefore(MakeUnique<int>(-77)); 153fd4e5da5Sopenharmony_ci end = end.InsertBefore(MakeUnique<int>(-36)); 154fd4e5da5Sopenharmony_ci end = end.InsertBefore(MakeUnique<int>(-42)); 155fd4e5da5Sopenharmony_ci 156fd4e5da5Sopenharmony_ci actual.clear(); 157fd4e5da5Sopenharmony_ci begin = UptrVectorIterator<int>(&data, data.begin()); 158fd4e5da5Sopenharmony_ci for (int i = 0; i < count + 4; ++i) { 159fd4e5da5Sopenharmony_ci actual.push_back(*(begin++)); 160fd4e5da5Sopenharmony_ci } 161fd4e5da5Sopenharmony_ci EXPECT_THAT(actual, ContainerEq(expected)); 162fd4e5da5Sopenharmony_ci} 163fd4e5da5Sopenharmony_ci 164fd4e5da5Sopenharmony_ciTEST(Iterator, InsertMiddle) { 165fd4e5da5Sopenharmony_ci const int count = 100; 166fd4e5da5Sopenharmony_ci 167fd4e5da5Sopenharmony_ci std::vector<std::unique_ptr<int>> data; 168fd4e5da5Sopenharmony_ci std::vector<int> expected; 169fd4e5da5Sopenharmony_ci std::vector<int> actual; 170fd4e5da5Sopenharmony_ci 171fd4e5da5Sopenharmony_ci for (int i = 0; i < count; ++i) { 172fd4e5da5Sopenharmony_ci data.emplace_back(new int(i)); 173fd4e5da5Sopenharmony_ci expected.push_back(i); 174fd4e5da5Sopenharmony_ci } 175fd4e5da5Sopenharmony_ci 176fd4e5da5Sopenharmony_ci const int insert_pos = 42; 177fd4e5da5Sopenharmony_ci expected.insert(expected.begin() + insert_pos, -100); 178fd4e5da5Sopenharmony_ci expected.insert(expected.begin() + insert_pos, -42); 179fd4e5da5Sopenharmony_ci 180fd4e5da5Sopenharmony_ci UptrVectorIterator<int> it(&data, data.begin()); 181fd4e5da5Sopenharmony_ci for (int i = 0; i < insert_pos; ++i) ++it; 182fd4e5da5Sopenharmony_ci it = it.InsertBefore(MakeUnique<int>(-100)); 183fd4e5da5Sopenharmony_ci it = it.InsertBefore(MakeUnique<int>(-42)); 184fd4e5da5Sopenharmony_ci auto begin = UptrVectorIterator<int>(&data, data.begin()); 185fd4e5da5Sopenharmony_ci for (int i = 0; i < count + 2; ++i) { 186fd4e5da5Sopenharmony_ci actual.push_back(*(begin++)); 187fd4e5da5Sopenharmony_ci } 188fd4e5da5Sopenharmony_ci EXPECT_THAT(actual, ContainerEq(expected)); 189fd4e5da5Sopenharmony_ci} 190fd4e5da5Sopenharmony_ci 191fd4e5da5Sopenharmony_ciTEST(IteratorRange, Interface) { 192fd4e5da5Sopenharmony_ci const uint32_t count = 100; 193fd4e5da5Sopenharmony_ci 194fd4e5da5Sopenharmony_ci std::vector<std::unique_ptr<uint32_t>> data; 195fd4e5da5Sopenharmony_ci 196fd4e5da5Sopenharmony_ci for (uint32_t i = 0; i < count; ++i) { 197fd4e5da5Sopenharmony_ci data.emplace_back(new uint32_t(i)); 198fd4e5da5Sopenharmony_ci } 199fd4e5da5Sopenharmony_ci 200fd4e5da5Sopenharmony_ci auto b = UptrVectorIterator<uint32_t>(&data, data.begin()); 201fd4e5da5Sopenharmony_ci auto e = UptrVectorIterator<uint32_t>(&data, data.end()); 202fd4e5da5Sopenharmony_ci auto range = IteratorRange<decltype(b)>(b, e); 203fd4e5da5Sopenharmony_ci 204fd4e5da5Sopenharmony_ci EXPECT_EQ(b, range.begin()); 205fd4e5da5Sopenharmony_ci EXPECT_EQ(e, range.end()); 206fd4e5da5Sopenharmony_ci EXPECT_FALSE(range.empty()); 207fd4e5da5Sopenharmony_ci EXPECT_EQ(count, range.size()); 208fd4e5da5Sopenharmony_ci EXPECT_EQ(0u, *range.begin()); 209fd4e5da5Sopenharmony_ci EXPECT_EQ(99u, *(--range.end())); 210fd4e5da5Sopenharmony_ci 211fd4e5da5Sopenharmony_ci // IteratorRange itself is immutable. 212fd4e5da5Sopenharmony_ci ++b, --e; 213fd4e5da5Sopenharmony_ci EXPECT_EQ(count, range.size()); 214fd4e5da5Sopenharmony_ci ++range.begin(), --range.end(); 215fd4e5da5Sopenharmony_ci EXPECT_EQ(count, range.size()); 216fd4e5da5Sopenharmony_ci} 217fd4e5da5Sopenharmony_ci 218fd4e5da5Sopenharmony_ciTEST(Iterator, FilterIterator) { 219fd4e5da5Sopenharmony_ci struct Placeholder { 220fd4e5da5Sopenharmony_ci int val; 221fd4e5da5Sopenharmony_ci }; 222fd4e5da5Sopenharmony_ci std::vector<Placeholder> data = {{1}, {2}, {3}, {4}, {5}, 223fd4e5da5Sopenharmony_ci {6}, {7}, {8}, {9}, {10}}; 224fd4e5da5Sopenharmony_ci 225fd4e5da5Sopenharmony_ci // Predicate to only consider odd values. 226fd4e5da5Sopenharmony_ci struct Predicate { 227fd4e5da5Sopenharmony_ci bool operator()(const Placeholder& data) { return data.val % 2; } 228fd4e5da5Sopenharmony_ci }; 229fd4e5da5Sopenharmony_ci Predicate pred; 230fd4e5da5Sopenharmony_ci 231fd4e5da5Sopenharmony_ci auto filter_range = MakeFilterIteratorRange(data.begin(), data.end(), pred); 232fd4e5da5Sopenharmony_ci 233fd4e5da5Sopenharmony_ci EXPECT_EQ(filter_range.begin().Get(), data.begin()); 234fd4e5da5Sopenharmony_ci EXPECT_EQ(filter_range.end(), filter_range.begin().GetEnd()); 235fd4e5da5Sopenharmony_ci 236fd4e5da5Sopenharmony_ci for (Placeholder& data : filter_range) { 237fd4e5da5Sopenharmony_ci EXPECT_EQ(data.val % 2, 1); 238fd4e5da5Sopenharmony_ci } 239fd4e5da5Sopenharmony_ci 240fd4e5da5Sopenharmony_ci for (auto it = filter_range.begin(); it != filter_range.end(); it++) { 241fd4e5da5Sopenharmony_ci EXPECT_EQ(it->val % 2, 1); 242fd4e5da5Sopenharmony_ci EXPECT_EQ((*it).val % 2, 1); 243fd4e5da5Sopenharmony_ci } 244fd4e5da5Sopenharmony_ci 245fd4e5da5Sopenharmony_ci for (auto it = filter_range.begin(); it != filter_range.end(); ++it) { 246fd4e5da5Sopenharmony_ci EXPECT_EQ(it->val % 2, 1); 247fd4e5da5Sopenharmony_ci EXPECT_EQ((*it).val % 2, 1); 248fd4e5da5Sopenharmony_ci } 249fd4e5da5Sopenharmony_ci 250fd4e5da5Sopenharmony_ci EXPECT_EQ(MakeFilterIterator(data.begin(), data.end(), pred).Get(), 251fd4e5da5Sopenharmony_ci data.begin()); 252fd4e5da5Sopenharmony_ci EXPECT_EQ(MakeFilterIterator(data.end(), data.end(), pred).Get(), data.end()); 253fd4e5da5Sopenharmony_ci EXPECT_EQ(MakeFilterIterator(data.begin(), data.end(), pred).GetEnd(), 254fd4e5da5Sopenharmony_ci MakeFilterIterator(data.end(), data.end(), pred)); 255fd4e5da5Sopenharmony_ci EXPECT_NE(MakeFilterIterator(data.begin(), data.end(), pred), 256fd4e5da5Sopenharmony_ci MakeFilterIterator(data.end(), data.end(), pred)); 257fd4e5da5Sopenharmony_ci 258fd4e5da5Sopenharmony_ci // Empty range: no values satisfies the predicate. 259fd4e5da5Sopenharmony_ci auto empty_range = MakeFilterIteratorRange( 260fd4e5da5Sopenharmony_ci data.begin(), data.end(), 261fd4e5da5Sopenharmony_ci [](const Placeholder& data) { return data.val > 10; }); 262fd4e5da5Sopenharmony_ci EXPECT_EQ(empty_range.begin(), empty_range.end()); 263fd4e5da5Sopenharmony_ci} 264fd4e5da5Sopenharmony_ci 265fd4e5da5Sopenharmony_ci} // namespace 266fd4e5da5Sopenharmony_ci} // namespace opt 267fd4e5da5Sopenharmony_ci} // namespace spvtools 268