mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-12-01 15:30:06 +00:00
1553025f4c
This MakeUnique code is used in places other then source/opt so move it to source/utils.
268 lines
7.3 KiB
C++
268 lines
7.3 KiB
C++
// Copyright (c) 2016 Google Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
#include "gmock/gmock.h"
|
|
|
|
#include "source/opt/iterator.h"
|
|
#include "source/util/make_unique.h"
|
|
|
|
namespace spvtools {
|
|
namespace opt {
|
|
namespace {
|
|
|
|
using ::testing::ContainerEq;
|
|
|
|
TEST(Iterator, IncrementDeref) {
|
|
const int count = 100;
|
|
std::vector<std::unique_ptr<int>> data;
|
|
for (int i = 0; i < count; ++i) {
|
|
data.emplace_back(new int(i));
|
|
}
|
|
|
|
UptrVectorIterator<int> it(&data, data.begin());
|
|
UptrVectorIterator<int> end(&data, data.end());
|
|
|
|
EXPECT_EQ(*data[0], *it);
|
|
for (int i = 1; i < count; ++i) {
|
|
EXPECT_NE(end, it);
|
|
EXPECT_EQ(*data[i], *(++it));
|
|
}
|
|
EXPECT_EQ(end, ++it);
|
|
}
|
|
|
|
TEST(Iterator, DecrementDeref) {
|
|
const int count = 100;
|
|
std::vector<std::unique_ptr<int>> data;
|
|
for (int i = 0; i < count; ++i) {
|
|
data.emplace_back(new int(i));
|
|
}
|
|
|
|
UptrVectorIterator<int> begin(&data, data.begin());
|
|
UptrVectorIterator<int> it(&data, data.end());
|
|
|
|
for (int i = count - 1; i >= 0; --i) {
|
|
EXPECT_NE(begin, it);
|
|
EXPECT_EQ(*data[i], *(--it));
|
|
}
|
|
EXPECT_EQ(begin, it);
|
|
}
|
|
|
|
TEST(Iterator, PostIncrementDeref) {
|
|
const int count = 100;
|
|
std::vector<std::unique_ptr<int>> data;
|
|
for (int i = 0; i < count; ++i) {
|
|
data.emplace_back(new int(i));
|
|
}
|
|
|
|
UptrVectorIterator<int> it(&data, data.begin());
|
|
UptrVectorIterator<int> end(&data, data.end());
|
|
|
|
for (int i = 0; i < count; ++i) {
|
|
EXPECT_NE(end, it);
|
|
EXPECT_EQ(*data[i], *(it++));
|
|
}
|
|
EXPECT_EQ(end, it);
|
|
}
|
|
|
|
TEST(Iterator, PostDecrementDeref) {
|
|
const int count = 100;
|
|
std::vector<std::unique_ptr<int>> data;
|
|
for (int i = 0; i < count; ++i) {
|
|
data.emplace_back(new int(i));
|
|
}
|
|
|
|
UptrVectorIterator<int> begin(&data, data.begin());
|
|
UptrVectorIterator<int> end(&data, data.end());
|
|
UptrVectorIterator<int> it(&data, data.end());
|
|
|
|
EXPECT_EQ(end, it--);
|
|
for (int i = count - 1; i >= 1; --i) {
|
|
EXPECT_EQ(*data[i], *(it--));
|
|
}
|
|
// Decrementing .begin() is undefined behavior.
|
|
EXPECT_EQ(*data[0], *it);
|
|
}
|
|
|
|
TEST(Iterator, Access) {
|
|
const int count = 100;
|
|
std::vector<std::unique_ptr<int>> data;
|
|
for (int i = 0; i < count; ++i) {
|
|
data.emplace_back(new int(i));
|
|
}
|
|
|
|
UptrVectorIterator<int> it(&data, data.begin());
|
|
|
|
for (int i = 0; i < count; ++i) EXPECT_EQ(*data[i], it[i]);
|
|
}
|
|
|
|
TEST(Iterator, Comparison) {
|
|
const int count = 100;
|
|
std::vector<std::unique_ptr<int>> data;
|
|
for (int i = 0; i < count; ++i) {
|
|
data.emplace_back(new int(i));
|
|
}
|
|
|
|
UptrVectorIterator<int> it(&data, data.begin());
|
|
UptrVectorIterator<int> end(&data, data.end());
|
|
|
|
for (int i = 0; i < count; ++i, ++it) EXPECT_TRUE(it < end);
|
|
EXPECT_EQ(end, it);
|
|
}
|
|
|
|
TEST(Iterator, InsertBeginEnd) {
|
|
const int count = 100;
|
|
|
|
std::vector<std::unique_ptr<int>> data;
|
|
std::vector<int> expected;
|
|
std::vector<int> actual;
|
|
|
|
for (int i = 0; i < count; ++i) {
|
|
data.emplace_back(new int(i));
|
|
expected.push_back(i);
|
|
}
|
|
|
|
// Insert at the beginning
|
|
expected.insert(expected.begin(), -100);
|
|
UptrVectorIterator<int> begin(&data, data.begin());
|
|
auto insert_point = begin.InsertBefore(MakeUnique<int>(-100));
|
|
for (int i = 0; i < count + 1; ++i) {
|
|
actual.push_back(*(insert_point++));
|
|
}
|
|
EXPECT_THAT(actual, ContainerEq(expected));
|
|
|
|
// Insert at the end
|
|
expected.push_back(-42);
|
|
expected.push_back(-36);
|
|
expected.push_back(-77);
|
|
UptrVectorIterator<int> end(&data, data.end());
|
|
end = end.InsertBefore(MakeUnique<int>(-77));
|
|
end = end.InsertBefore(MakeUnique<int>(-36));
|
|
end = end.InsertBefore(MakeUnique<int>(-42));
|
|
|
|
actual.clear();
|
|
begin = UptrVectorIterator<int>(&data, data.begin());
|
|
for (int i = 0; i < count + 4; ++i) {
|
|
actual.push_back(*(begin++));
|
|
}
|
|
EXPECT_THAT(actual, ContainerEq(expected));
|
|
}
|
|
|
|
TEST(Iterator, InsertMiddle) {
|
|
const int count = 100;
|
|
|
|
std::vector<std::unique_ptr<int>> data;
|
|
std::vector<int> expected;
|
|
std::vector<int> actual;
|
|
|
|
for (int i = 0; i < count; ++i) {
|
|
data.emplace_back(new int(i));
|
|
expected.push_back(i);
|
|
}
|
|
|
|
const int insert_pos = 42;
|
|
expected.insert(expected.begin() + insert_pos, -100);
|
|
expected.insert(expected.begin() + insert_pos, -42);
|
|
|
|
UptrVectorIterator<int> it(&data, data.begin());
|
|
for (int i = 0; i < insert_pos; ++i) ++it;
|
|
it = it.InsertBefore(MakeUnique<int>(-100));
|
|
it = it.InsertBefore(MakeUnique<int>(-42));
|
|
auto begin = UptrVectorIterator<int>(&data, data.begin());
|
|
for (int i = 0; i < count + 2; ++i) {
|
|
actual.push_back(*(begin++));
|
|
}
|
|
EXPECT_THAT(actual, ContainerEq(expected));
|
|
}
|
|
|
|
TEST(IteratorRange, Interface) {
|
|
const uint32_t count = 100;
|
|
|
|
std::vector<std::unique_ptr<uint32_t>> data;
|
|
|
|
for (uint32_t i = 0; i < count; ++i) {
|
|
data.emplace_back(new uint32_t(i));
|
|
}
|
|
|
|
auto b = UptrVectorIterator<uint32_t>(&data, data.begin());
|
|
auto e = UptrVectorIterator<uint32_t>(&data, data.end());
|
|
auto range = IteratorRange<decltype(b)>(b, e);
|
|
|
|
EXPECT_EQ(b, range.begin());
|
|
EXPECT_EQ(e, range.end());
|
|
EXPECT_FALSE(range.empty());
|
|
EXPECT_EQ(count, range.size());
|
|
EXPECT_EQ(0u, *range.begin());
|
|
EXPECT_EQ(99u, *(--range.end()));
|
|
|
|
// IteratorRange itself is immutable.
|
|
++b, --e;
|
|
EXPECT_EQ(count, range.size());
|
|
++range.begin(), --range.end();
|
|
EXPECT_EQ(count, range.size());
|
|
}
|
|
|
|
TEST(Iterator, FilterIterator) {
|
|
struct Placeholder {
|
|
int val;
|
|
};
|
|
std::vector<Placeholder> data = {{1}, {2}, {3}, {4}, {5},
|
|
{6}, {7}, {8}, {9}, {10}};
|
|
|
|
// Predicate to only consider odd values.
|
|
struct Predicate {
|
|
bool operator()(const Placeholder& data) { return data.val % 2; }
|
|
};
|
|
Predicate pred;
|
|
|
|
auto filter_range = MakeFilterIteratorRange(data.begin(), data.end(), pred);
|
|
|
|
EXPECT_EQ(filter_range.begin().Get(), data.begin());
|
|
EXPECT_EQ(filter_range.end(), filter_range.begin().GetEnd());
|
|
|
|
for (Placeholder& data : filter_range) {
|
|
EXPECT_EQ(data.val % 2, 1);
|
|
}
|
|
|
|
for (auto it = filter_range.begin(); it != filter_range.end(); it++) {
|
|
EXPECT_EQ(it->val % 2, 1);
|
|
EXPECT_EQ((*it).val % 2, 1);
|
|
}
|
|
|
|
for (auto it = filter_range.begin(); it != filter_range.end(); ++it) {
|
|
EXPECT_EQ(it->val % 2, 1);
|
|
EXPECT_EQ((*it).val % 2, 1);
|
|
}
|
|
|
|
EXPECT_EQ(MakeFilterIterator(data.begin(), data.end(), pred).Get(),
|
|
data.begin());
|
|
EXPECT_EQ(MakeFilterIterator(data.end(), data.end(), pred).Get(), data.end());
|
|
EXPECT_EQ(MakeFilterIterator(data.begin(), data.end(), pred).GetEnd(),
|
|
MakeFilterIterator(data.end(), data.end(), pred));
|
|
EXPECT_NE(MakeFilterIterator(data.begin(), data.end(), pred),
|
|
MakeFilterIterator(data.end(), data.end(), pred));
|
|
|
|
// Empty range: no values satisfies the predicate.
|
|
auto empty_range = MakeFilterIteratorRange(
|
|
data.begin(), data.end(),
|
|
[](const Placeholder& data) { return data.val > 10; });
|
|
EXPECT_EQ(empty_range.begin(), empty_range.end());
|
|
}
|
|
|
|
} // namespace
|
|
} // namespace opt
|
|
} // namespace spvtools
|