• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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