1 // Copyright 2017 The Dawn Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <gtest/gtest.h>
16
17 #include "common/BitSetIterator.h"
18 #include "common/ityp_bitset.h"
19
20 // This is ANGLE's BitSetIterator_unittests.cpp file.
21
22 class BitSetIteratorTest : public testing::Test {
23 protected:
24 std::bitset<40> mStateBits;
25 };
26
27 // Simple iterator test.
TEST_F(BitSetIteratorTest,Iterator)28 TEST_F(BitSetIteratorTest, Iterator) {
29 std::set<unsigned long> originalValues;
30 originalValues.insert(2);
31 originalValues.insert(6);
32 originalValues.insert(8);
33 originalValues.insert(35);
34
35 for (unsigned long value : originalValues) {
36 mStateBits.set(value);
37 }
38
39 std::set<unsigned long> readValues;
40 for (unsigned long bit : IterateBitSet(mStateBits)) {
41 EXPECT_EQ(1u, originalValues.count(bit));
42 EXPECT_EQ(0u, readValues.count(bit));
43 readValues.insert(bit);
44 }
45
46 EXPECT_EQ(originalValues.size(), readValues.size());
47 }
48
49 // Test an empty iterator.
TEST_F(BitSetIteratorTest,EmptySet)50 TEST_F(BitSetIteratorTest, EmptySet) {
51 // We don't use the FAIL gtest macro here since it returns immediately,
52 // causing an unreachable code warning in MSVC
53 bool sawBit = false;
54 for (unsigned long bit : IterateBitSet(mStateBits)) {
55 DAWN_UNUSED(bit);
56 sawBit = true;
57 }
58 EXPECT_FALSE(sawBit);
59 }
60
61 // Test iterating a result of combining two bitsets.
TEST_F(BitSetIteratorTest,NonLValueBitset)62 TEST_F(BitSetIteratorTest, NonLValueBitset) {
63 std::bitset<40> otherBits;
64
65 mStateBits.set(1);
66 mStateBits.set(2);
67 mStateBits.set(3);
68 mStateBits.set(4);
69
70 otherBits.set(0);
71 otherBits.set(1);
72 otherBits.set(3);
73 otherBits.set(5);
74
75 std::set<unsigned long> seenBits;
76
77 for (unsigned long bit : IterateBitSet(mStateBits & otherBits)) {
78 EXPECT_EQ(0u, seenBits.count(bit));
79 seenBits.insert(bit);
80 EXPECT_TRUE(mStateBits[bit]);
81 EXPECT_TRUE(otherBits[bit]);
82 }
83
84 EXPECT_EQ((mStateBits & otherBits).count(), seenBits.size());
85 }
86
87 class EnumBitSetIteratorTest : public testing::Test {
88 protected:
89 enum class TestEnum { A, B, C, D, E, F, G, H, I, J, EnumCount };
90
91 static constexpr size_t kEnumCount = static_cast<size_t>(TestEnum::EnumCount);
92 ityp::bitset<TestEnum, kEnumCount> mStateBits;
93 };
94
95 // Simple iterator test.
TEST_F(EnumBitSetIteratorTest,Iterator)96 TEST_F(EnumBitSetIteratorTest, Iterator) {
97 std::set<TestEnum> originalValues;
98 originalValues.insert(TestEnum::B);
99 originalValues.insert(TestEnum::F);
100 originalValues.insert(TestEnum::C);
101 originalValues.insert(TestEnum::I);
102
103 for (TestEnum value : originalValues) {
104 mStateBits.set(value);
105 }
106
107 std::set<TestEnum> readValues;
108 for (TestEnum bit : IterateBitSet(mStateBits)) {
109 EXPECT_EQ(1u, originalValues.count(bit));
110 EXPECT_EQ(0u, readValues.count(bit));
111 readValues.insert(bit);
112 }
113
114 EXPECT_EQ(originalValues.size(), readValues.size());
115 }
116
117 // Test an empty iterator.
TEST_F(EnumBitSetIteratorTest,EmptySet)118 TEST_F(EnumBitSetIteratorTest, EmptySet) {
119 // We don't use the FAIL gtest macro here since it returns immediately,
120 // causing an unreachable code warning in MSVC
121 bool sawBit = false;
122 for (TestEnum bit : IterateBitSet(mStateBits)) {
123 DAWN_UNUSED(bit);
124 sawBit = true;
125 }
126 EXPECT_FALSE(sawBit);
127 }
128
129 // Test iterating a result of combining two bitsets.
TEST_F(EnumBitSetIteratorTest,NonLValueBitset)130 TEST_F(EnumBitSetIteratorTest, NonLValueBitset) {
131 ityp::bitset<TestEnum, kEnumCount> otherBits;
132
133 mStateBits.set(TestEnum::B);
134 mStateBits.set(TestEnum::C);
135 mStateBits.set(TestEnum::D);
136 mStateBits.set(TestEnum::E);
137
138 otherBits.set(TestEnum::A);
139 otherBits.set(TestEnum::B);
140 otherBits.set(TestEnum::D);
141 otherBits.set(TestEnum::F);
142
143 std::set<TestEnum> seenBits;
144
145 for (TestEnum bit : IterateBitSet(mStateBits & otherBits)) {
146 EXPECT_EQ(0u, seenBits.count(bit));
147 seenBits.insert(bit);
148 EXPECT_TRUE(mStateBits[bit]);
149 EXPECT_TRUE(otherBits[bit]);
150 }
151
152 EXPECT_EQ((mStateBits & otherBits).count(), seenBits.size());
153 }
154
155 class ITypBitsetIteratorTest : public testing::Test {
156 protected:
157 using IntegerT = TypedInteger<struct Foo, uint32_t>;
158 ityp::bitset<IntegerT, 40> mStateBits;
159 };
160
161 // Simple iterator test.
TEST_F(ITypBitsetIteratorTest,Iterator)162 TEST_F(ITypBitsetIteratorTest, Iterator) {
163 std::set<IntegerT> originalValues;
164 originalValues.insert(IntegerT(2));
165 originalValues.insert(IntegerT(6));
166 originalValues.insert(IntegerT(8));
167 originalValues.insert(IntegerT(35));
168
169 for (IntegerT value : originalValues) {
170 mStateBits.set(value);
171 }
172
173 std::set<IntegerT> readValues;
174 for (IntegerT bit : IterateBitSet(mStateBits)) {
175 EXPECT_EQ(1u, originalValues.count(bit));
176 EXPECT_EQ(0u, readValues.count(bit));
177 readValues.insert(bit);
178 }
179
180 EXPECT_EQ(originalValues.size(), readValues.size());
181 }
182
183 // Test an empty iterator.
TEST_F(ITypBitsetIteratorTest,EmptySet)184 TEST_F(ITypBitsetIteratorTest, EmptySet) {
185 // We don't use the FAIL gtest macro here since it returns immediately,
186 // causing an unreachable code warning in MSVC
187 bool sawBit = false;
188 for (IntegerT bit : IterateBitSet(mStateBits)) {
189 DAWN_UNUSED(bit);
190 sawBit = true;
191 }
192 EXPECT_FALSE(sawBit);
193 }
194
195 // Test iterating a result of combining two bitsets.
TEST_F(ITypBitsetIteratorTest,NonLValueBitset)196 TEST_F(ITypBitsetIteratorTest, NonLValueBitset) {
197 ityp::bitset<IntegerT, 40> otherBits;
198
199 mStateBits.set(IntegerT(1));
200 mStateBits.set(IntegerT(2));
201 mStateBits.set(IntegerT(3));
202 mStateBits.set(IntegerT(4));
203
204 otherBits.set(IntegerT(0));
205 otherBits.set(IntegerT(1));
206 otherBits.set(IntegerT(3));
207 otherBits.set(IntegerT(5));
208
209 std::set<IntegerT> seenBits;
210
211 for (IntegerT bit : IterateBitSet(mStateBits & otherBits)) {
212 EXPECT_EQ(0u, seenBits.count(bit));
213 seenBits.insert(bit);
214 EXPECT_TRUE(mStateBits[bit]);
215 EXPECT_TRUE(otherBits[bit]);
216 }
217
218 EXPECT_EQ((mStateBits & otherBits).count(), seenBits.size());
219 }
220