1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/containers/enum_set.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker #include "base/containers/to_vector.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/test/gtest_util.h"
11*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
12*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest-death-test.h"
13*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
14*6777b538SAndroid Build Coastguard Worker
15*6777b538SAndroid Build Coastguard Worker namespace base {
16*6777b538SAndroid Build Coastguard Worker namespace {
17*6777b538SAndroid Build Coastguard Worker
18*6777b538SAndroid Build Coastguard Worker enum class TestEnum {
19*6777b538SAndroid Build Coastguard Worker TEST_BELOW_MIN_NEGATIVE = -1,
20*6777b538SAndroid Build Coastguard Worker TEST_BELOW_MIN = 0,
21*6777b538SAndroid Build Coastguard Worker TEST_1 = 1,
22*6777b538SAndroid Build Coastguard Worker TEST_MIN = TEST_1,
23*6777b538SAndroid Build Coastguard Worker TEST_2,
24*6777b538SAndroid Build Coastguard Worker TEST_3,
25*6777b538SAndroid Build Coastguard Worker TEST_4,
26*6777b538SAndroid Build Coastguard Worker TEST_5,
27*6777b538SAndroid Build Coastguard Worker TEST_MAX = TEST_5,
28*6777b538SAndroid Build Coastguard Worker TEST_6_OUT_OF_BOUNDS,
29*6777b538SAndroid Build Coastguard Worker TEST_7_OUT_OF_BOUNDS
30*6777b538SAndroid Build Coastguard Worker };
31*6777b538SAndroid Build Coastguard Worker using TestEnumSet = EnumSet<TestEnum, TestEnum::TEST_MIN, TestEnum::TEST_MAX>;
32*6777b538SAndroid Build Coastguard Worker
33*6777b538SAndroid Build Coastguard Worker enum class TestEnumExtreme {
34*6777b538SAndroid Build Coastguard Worker TEST_0 = 0,
35*6777b538SAndroid Build Coastguard Worker TEST_MIN = TEST_0,
36*6777b538SAndroid Build Coastguard Worker TEST_63 = 63,
37*6777b538SAndroid Build Coastguard Worker TEST_MAX = TEST_63,
38*6777b538SAndroid Build Coastguard Worker TEST_64_OUT_OF_BOUNDS,
39*6777b538SAndroid Build Coastguard Worker };
40*6777b538SAndroid Build Coastguard Worker using TestEnumExtremeSet = EnumSet<TestEnumExtreme,
41*6777b538SAndroid Build Coastguard Worker TestEnumExtreme::TEST_MIN,
42*6777b538SAndroid Build Coastguard Worker TestEnumExtreme::TEST_MAX>;
43*6777b538SAndroid Build Coastguard Worker
44*6777b538SAndroid Build Coastguard Worker class EnumSetTest : public ::testing::Test {};
45*6777b538SAndroid Build Coastguard Worker class EnumSetDeathTest : public ::testing::Test {};
46*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,ClassConstants)47*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, ClassConstants) {
48*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnum::TEST_MIN, TestEnumSet::kMinValue);
49*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnum::TEST_MAX, TestEnumSet::kMaxValue);
50*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(5u, TestEnumSet::kValueCount);
51*6777b538SAndroid Build Coastguard Worker }
52*6777b538SAndroid Build Coastguard Worker
53*6777b538SAndroid Build Coastguard Worker // Use static_assert to check that functions we expect to be compile time
54*6777b538SAndroid Build Coastguard Worker // evaluatable are really that way.
TEST_F(EnumSetTest,ConstexprsAreValid)55*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, ConstexprsAreValid) {
56*6777b538SAndroid Build Coastguard Worker static_assert(TestEnumSet::All().Has(TestEnum::TEST_2),
57*6777b538SAndroid Build Coastguard Worker "Expected All() to be integral constant expression");
58*6777b538SAndroid Build Coastguard Worker static_assert(TestEnumSet::FromRange(TestEnum::TEST_2, TestEnum::TEST_4)
59*6777b538SAndroid Build Coastguard Worker .Has(TestEnum::TEST_2),
60*6777b538SAndroid Build Coastguard Worker "Expected FromRange() to be integral constant expression");
61*6777b538SAndroid Build Coastguard Worker static_assert(TestEnumSet{TestEnum::TEST_2}.Has(TestEnum::TEST_2),
62*6777b538SAndroid Build Coastguard Worker "Expected TestEnumSet() to be integral constant expression");
63*6777b538SAndroid Build Coastguard Worker static_assert(
64*6777b538SAndroid Build Coastguard Worker TestEnumSet::FromEnumBitmask(1 << static_cast<uint64_t>(TestEnum::TEST_2))
65*6777b538SAndroid Build Coastguard Worker .Has(TestEnum::TEST_2),
66*6777b538SAndroid Build Coastguard Worker "Expected TestEnumSet() to be integral constant expression");
67*6777b538SAndroid Build Coastguard Worker }
68*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,DefaultConstructor)69*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, DefaultConstructor) {
70*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums;
71*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.empty());
72*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, enums.size());
73*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_1));
74*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_2));
75*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_3));
76*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_4));
77*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_5));
78*6777b538SAndroid Build Coastguard Worker }
79*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,OneArgConstructor)80*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, OneArgConstructor) {
81*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums = {TestEnum::TEST_4};
82*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.empty());
83*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, enums.size());
84*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_1));
85*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_2));
86*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_3));
87*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.Has(TestEnum::TEST_4));
88*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_5));
89*6777b538SAndroid Build Coastguard Worker }
90*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,OneArgConstructorSize)91*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, OneArgConstructorSize) {
92*6777b538SAndroid Build Coastguard Worker TestEnumExtremeSet enums = {TestEnumExtreme::TEST_0};
93*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.Has(TestEnumExtreme::TEST_0));
94*6777b538SAndroid Build Coastguard Worker }
95*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,TwoArgConstructor)96*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, TwoArgConstructor) {
97*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums = {TestEnum::TEST_4, TestEnum::TEST_2};
98*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.empty());
99*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(2u, enums.size());
100*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_1));
101*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.Has(TestEnum::TEST_2));
102*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_3));
103*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.Has(TestEnum::TEST_4));
104*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_5));
105*6777b538SAndroid Build Coastguard Worker }
106*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,ThreeArgConstructor)107*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, ThreeArgConstructor) {
108*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums = {TestEnum::TEST_4, TestEnum::TEST_2,
109*6777b538SAndroid Build Coastguard Worker TestEnum::TEST_1};
110*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.empty());
111*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(3u, enums.size());
112*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.Has(TestEnum::TEST_1));
113*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.Has(TestEnum::TEST_2));
114*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_3));
115*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.Has(TestEnum::TEST_4));
116*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_5));
117*6777b538SAndroid Build Coastguard Worker }
118*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,DuplicatesInConstructor)119*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, DuplicatesInConstructor) {
120*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(
121*6777b538SAndroid Build Coastguard Worker TestEnumSet({TestEnum::TEST_4, TestEnum::TEST_2, TestEnum::TEST_1,
122*6777b538SAndroid Build Coastguard Worker TestEnum::TEST_4, TestEnum::TEST_2, TestEnum::TEST_4}),
123*6777b538SAndroid Build Coastguard Worker TestEnumSet({TestEnum::TEST_1, TestEnum::TEST_2, TestEnum::TEST_4}));
124*6777b538SAndroid Build Coastguard Worker }
125*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,All)126*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, All) {
127*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums(TestEnumSet::All());
128*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.empty());
129*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(5u, enums.size());
130*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.Has(TestEnum::TEST_1));
131*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.Has(TestEnum::TEST_2));
132*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.Has(TestEnum::TEST_3));
133*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.Has(TestEnum::TEST_4));
134*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.Has(TestEnum::TEST_5));
135*6777b538SAndroid Build Coastguard Worker }
136*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,AllExtreme)137*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, AllExtreme) {
138*6777b538SAndroid Build Coastguard Worker const TestEnumExtremeSet enums(TestEnumExtremeSet::All());
139*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.empty());
140*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(64u, enums.size());
141*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.Has(TestEnumExtreme::TEST_0));
142*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.Has(TestEnumExtreme::TEST_63));
143*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnumExtreme::TEST_64_OUT_OF_BOUNDS));
144*6777b538SAndroid Build Coastguard Worker }
145*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,FromRange)146*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, FromRange) {
147*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSet({TestEnum::TEST_2, TestEnum::TEST_3, TestEnum::TEST_4}),
148*6777b538SAndroid Build Coastguard Worker TestEnumSet::FromRange(TestEnum::TEST_2, TestEnum::TEST_4));
149*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSet::All(),
150*6777b538SAndroid Build Coastguard Worker TestEnumSet::FromRange(TestEnum::TEST_1, TestEnum::TEST_5));
151*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSet({TestEnum::TEST_2}),
152*6777b538SAndroid Build Coastguard Worker TestEnumSet::FromRange(TestEnum::TEST_2, TestEnum::TEST_2));
153*6777b538SAndroid Build Coastguard Worker
154*6777b538SAndroid Build Coastguard Worker using RestrictedRangeSet =
155*6777b538SAndroid Build Coastguard Worker EnumSet<TestEnum, TestEnum::TEST_2, TestEnum::TEST_MAX>;
156*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(RestrictedRangeSet(
157*6777b538SAndroid Build Coastguard Worker {TestEnum::TEST_2, TestEnum::TEST_3, TestEnum::TEST_4}),
158*6777b538SAndroid Build Coastguard Worker RestrictedRangeSet::FromRange(TestEnum::TEST_2, TestEnum::TEST_4));
159*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(RestrictedRangeSet::All(),
160*6777b538SAndroid Build Coastguard Worker RestrictedRangeSet::FromRange(TestEnum::TEST_2, TestEnum::TEST_5));
161*6777b538SAndroid Build Coastguard Worker }
162*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,Put)163*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, Put) {
164*6777b538SAndroid Build Coastguard Worker TestEnumSet enums = {TestEnum::TEST_4};
165*6777b538SAndroid Build Coastguard Worker enums.Put(TestEnum::TEST_3);
166*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSet({TestEnum::TEST_3, TestEnum::TEST_4}), enums);
167*6777b538SAndroid Build Coastguard Worker enums.Put(TestEnum::TEST_5);
168*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSet({TestEnum::TEST_3, TestEnum::TEST_4, TestEnum::TEST_5}),
169*6777b538SAndroid Build Coastguard Worker enums);
170*6777b538SAndroid Build Coastguard Worker }
171*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,PutAll)172*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, PutAll) {
173*6777b538SAndroid Build Coastguard Worker TestEnumSet enums = {TestEnum::TEST_4, TestEnum::TEST_5};
174*6777b538SAndroid Build Coastguard Worker enums.PutAll({TestEnum::TEST_3, TestEnum::TEST_4});
175*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSet({TestEnum::TEST_3, TestEnum::TEST_4, TestEnum::TEST_5}),
176*6777b538SAndroid Build Coastguard Worker enums);
177*6777b538SAndroid Build Coastguard Worker }
178*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,PutRange)179*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, PutRange) {
180*6777b538SAndroid Build Coastguard Worker TestEnumSet enums;
181*6777b538SAndroid Build Coastguard Worker enums.PutRange(TestEnum::TEST_2, TestEnum::TEST_4);
182*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSet({TestEnum::TEST_2, TestEnum::TEST_3, TestEnum::TEST_4}),
183*6777b538SAndroid Build Coastguard Worker enums);
184*6777b538SAndroid Build Coastguard Worker }
185*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,RetainAll)186*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, RetainAll) {
187*6777b538SAndroid Build Coastguard Worker TestEnumSet enums = {TestEnum::TEST_4, TestEnum::TEST_5};
188*6777b538SAndroid Build Coastguard Worker enums.RetainAll(TestEnumSet({TestEnum::TEST_3, TestEnum::TEST_4}));
189*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSet({TestEnum::TEST_4}), enums);
190*6777b538SAndroid Build Coastguard Worker }
191*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,Remove)192*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, Remove) {
193*6777b538SAndroid Build Coastguard Worker TestEnumSet enums = {TestEnum::TEST_4, TestEnum::TEST_5};
194*6777b538SAndroid Build Coastguard Worker enums.Remove(TestEnum::TEST_1);
195*6777b538SAndroid Build Coastguard Worker enums.Remove(TestEnum::TEST_3);
196*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSet({TestEnum::TEST_4, TestEnum::TEST_5}), enums);
197*6777b538SAndroid Build Coastguard Worker enums.Remove(TestEnum::TEST_4);
198*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSet({TestEnum::TEST_5}), enums);
199*6777b538SAndroid Build Coastguard Worker enums.Remove(TestEnum::TEST_5);
200*6777b538SAndroid Build Coastguard Worker enums.Remove(TestEnum::TEST_6_OUT_OF_BOUNDS);
201*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.empty());
202*6777b538SAndroid Build Coastguard Worker }
203*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,RemoveAll)204*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, RemoveAll) {
205*6777b538SAndroid Build Coastguard Worker TestEnumSet enums = {TestEnum::TEST_4, TestEnum::TEST_5};
206*6777b538SAndroid Build Coastguard Worker enums.RemoveAll(TestEnumSet({TestEnum::TEST_3, TestEnum::TEST_4}));
207*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSet({TestEnum::TEST_5}), enums);
208*6777b538SAndroid Build Coastguard Worker }
209*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,Clear)210*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, Clear) {
211*6777b538SAndroid Build Coastguard Worker TestEnumSet enums = {TestEnum::TEST_4, TestEnum::TEST_5};
212*6777b538SAndroid Build Coastguard Worker enums.Clear();
213*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.empty());
214*6777b538SAndroid Build Coastguard Worker }
215*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,Set)216*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, Set) {
217*6777b538SAndroid Build Coastguard Worker TestEnumSet enums;
218*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.empty());
219*6777b538SAndroid Build Coastguard Worker
220*6777b538SAndroid Build Coastguard Worker enums.PutOrRemove(TestEnum::TEST_3, false);
221*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.empty());
222*6777b538SAndroid Build Coastguard Worker
223*6777b538SAndroid Build Coastguard Worker enums.PutOrRemove(TestEnum::TEST_4, true);
224*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(enums, TestEnumSet({TestEnum::TEST_4}));
225*6777b538SAndroid Build Coastguard Worker
226*6777b538SAndroid Build Coastguard Worker enums.PutOrRemove(TestEnum::TEST_5, true);
227*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(enums, TestEnumSet({TestEnum::TEST_4, TestEnum::TEST_5}));
228*6777b538SAndroid Build Coastguard Worker enums.PutOrRemove(TestEnum::TEST_5, true);
229*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(enums, TestEnumSet({TestEnum::TEST_4, TestEnum::TEST_5}));
230*6777b538SAndroid Build Coastguard Worker
231*6777b538SAndroid Build Coastguard Worker enums.PutOrRemove(TestEnum::TEST_4, false);
232*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(enums, TestEnumSet({TestEnum::TEST_5}));
233*6777b538SAndroid Build Coastguard Worker }
234*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,Has)235*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, Has) {
236*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums = {TestEnum::TEST_4, TestEnum::TEST_5};
237*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_1));
238*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_2));
239*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_3));
240*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.Has(TestEnum::TEST_4));
241*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums.Has(TestEnum::TEST_5));
242*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums.Has(TestEnum::TEST_6_OUT_OF_BOUNDS));
243*6777b538SAndroid Build Coastguard Worker }
244*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,HasAll)245*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, HasAll) {
246*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums1 = {TestEnum::TEST_4, TestEnum::TEST_5};
247*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums2 = {TestEnum::TEST_3, TestEnum::TEST_4};
248*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums3 = Union(enums1, enums2);
249*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums1.HasAll(enums1));
250*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums1.HasAll(enums2));
251*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums1.HasAll(enums3));
252*6777b538SAndroid Build Coastguard Worker
253*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums2.HasAll(enums1));
254*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums2.HasAll(enums2));
255*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums2.HasAll(enums3));
256*6777b538SAndroid Build Coastguard Worker
257*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums3.HasAll(enums1));
258*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums3.HasAll(enums2));
259*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums3.HasAll(enums3));
260*6777b538SAndroid Build Coastguard Worker }
261*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,HasAny)262*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, HasAny) {
263*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums1 = {TestEnum::TEST_4, TestEnum::TEST_5};
264*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums2 = {TestEnum::TEST_3, TestEnum::TEST_4};
265*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums3 = {TestEnum::TEST_1, TestEnum::TEST_2};
266*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums1.HasAny(enums1));
267*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums1.HasAny(enums2));
268*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums1.HasAny(enums3));
269*6777b538SAndroid Build Coastguard Worker
270*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums2.HasAny(enums1));
271*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums2.HasAny(enums2));
272*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums2.HasAny(enums3));
273*6777b538SAndroid Build Coastguard Worker
274*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums3.HasAny(enums1));
275*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(enums3.HasAny(enums2));
276*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(enums3.HasAny(enums3));
277*6777b538SAndroid Build Coastguard Worker }
278*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,Iterators)279*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, Iterators) {
280*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums1 = {TestEnum::TEST_4, TestEnum::TEST_5};
281*6777b538SAndroid Build Coastguard Worker TestEnumSet enums2;
282*6777b538SAndroid Build Coastguard Worker for (TestEnum e : enums1) {
283*6777b538SAndroid Build Coastguard Worker enums2.Put(e);
284*6777b538SAndroid Build Coastguard Worker }
285*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(enums2, enums1);
286*6777b538SAndroid Build Coastguard Worker }
287*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,RangeBasedForLoop)288*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, RangeBasedForLoop) {
289*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums1 = {TestEnum::TEST_2, TestEnum::TEST_5};
290*6777b538SAndroid Build Coastguard Worker TestEnumSet enums2;
291*6777b538SAndroid Build Coastguard Worker for (TestEnum e : enums1) {
292*6777b538SAndroid Build Coastguard Worker enums2.Put(e);
293*6777b538SAndroid Build Coastguard Worker }
294*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(enums2, enums1);
295*6777b538SAndroid Build Coastguard Worker }
296*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,IteratorComparisonOperators)297*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, IteratorComparisonOperators) {
298*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums = {TestEnum::TEST_2, TestEnum::TEST_4};
299*6777b538SAndroid Build Coastguard Worker const auto first_it = enums.begin();
300*6777b538SAndroid Build Coastguard Worker const auto second_it = ++enums.begin();
301*6777b538SAndroid Build Coastguard Worker
302*6777b538SAndroid Build Coastguard Worker // Copy for equality testing.
303*6777b538SAndroid Build Coastguard Worker const auto first_it_copy = first_it;
304*6777b538SAndroid Build Coastguard Worker
305*6777b538SAndroid Build Coastguard Worker // Sanity check, as the rest of the test relies on |first_it| and
306*6777b538SAndroid Build Coastguard Worker // |first_it_copy| pointing to the same element and |first_it| and |second_it|
307*6777b538SAndroid Build Coastguard Worker // pointing to different elements.
308*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(*first_it, *first_it_copy);
309*6777b538SAndroid Build Coastguard Worker ASSERT_NE(*first_it, *second_it);
310*6777b538SAndroid Build Coastguard Worker
311*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(first_it == first_it_copy);
312*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(first_it != first_it_copy);
313*6777b538SAndroid Build Coastguard Worker
314*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(first_it != second_it);
315*6777b538SAndroid Build Coastguard Worker EXPECT_FALSE(first_it == second_it);
316*6777b538SAndroid Build Coastguard Worker }
317*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,IteratorIncrementOperators)318*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, IteratorIncrementOperators) {
319*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums = {TestEnum::TEST_2, TestEnum::TEST_4};
320*6777b538SAndroid Build Coastguard Worker const auto begin = enums.begin();
321*6777b538SAndroid Build Coastguard Worker
322*6777b538SAndroid Build Coastguard Worker auto post_inc_it = begin;
323*6777b538SAndroid Build Coastguard Worker auto pre_inc_it = begin;
324*6777b538SAndroid Build Coastguard Worker
325*6777b538SAndroid Build Coastguard Worker auto post_inc_return_it = post_inc_it++;
326*6777b538SAndroid Build Coastguard Worker auto pre_inc_return_it = ++pre_inc_it;
327*6777b538SAndroid Build Coastguard Worker
328*6777b538SAndroid Build Coastguard Worker // |pre_inc_it| and |post_inc_it| should point to the same element.
329*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(pre_inc_it, post_inc_it);
330*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(*pre_inc_it, *post_inc_it);
331*6777b538SAndroid Build Coastguard Worker
332*6777b538SAndroid Build Coastguard Worker // |pre_inc_it| should NOT point to the first element.
333*6777b538SAndroid Build Coastguard Worker EXPECT_NE(begin, pre_inc_it);
334*6777b538SAndroid Build Coastguard Worker EXPECT_NE(*begin, *pre_inc_it);
335*6777b538SAndroid Build Coastguard Worker
336*6777b538SAndroid Build Coastguard Worker // |post_inc_it| should NOT point to the first element.
337*6777b538SAndroid Build Coastguard Worker EXPECT_NE(begin, post_inc_it);
338*6777b538SAndroid Build Coastguard Worker EXPECT_NE(*begin, *post_inc_it);
339*6777b538SAndroid Build Coastguard Worker
340*6777b538SAndroid Build Coastguard Worker // Prefix increment should return new iterator.
341*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(pre_inc_return_it, post_inc_it);
342*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(*pre_inc_return_it, *post_inc_it);
343*6777b538SAndroid Build Coastguard Worker
344*6777b538SAndroid Build Coastguard Worker // Postfix increment should return original iterator.
345*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(post_inc_return_it, begin);
346*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(*post_inc_return_it, *begin);
347*6777b538SAndroid Build Coastguard Worker }
348*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,Union)349*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, Union) {
350*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums1 = {TestEnum::TEST_4, TestEnum::TEST_5};
351*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums2 = {TestEnum::TEST_3, TestEnum::TEST_4};
352*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums3 = Union(enums1, enums2);
353*6777b538SAndroid Build Coastguard Worker
354*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSet({TestEnum::TEST_3, TestEnum::TEST_4, TestEnum::TEST_5}),
355*6777b538SAndroid Build Coastguard Worker enums3);
356*6777b538SAndroid Build Coastguard Worker }
357*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,Intersection)358*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, Intersection) {
359*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums1 = {TestEnum::TEST_4, TestEnum::TEST_5};
360*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums2 = {TestEnum::TEST_3, TestEnum::TEST_4};
361*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums3 = Intersection(enums1, enums2);
362*6777b538SAndroid Build Coastguard Worker
363*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSet({TestEnum::TEST_4}), enums3);
364*6777b538SAndroid Build Coastguard Worker }
365*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,Difference)366*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, Difference) {
367*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums1 = {TestEnum::TEST_4, TestEnum::TEST_5};
368*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums2 = {TestEnum::TEST_3, TestEnum::TEST_4};
369*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums3 = Difference(enums1, enums2);
370*6777b538SAndroid Build Coastguard Worker
371*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSet({TestEnum::TEST_5}), enums3);
372*6777b538SAndroid Build Coastguard Worker }
373*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,ToFromEnumBitmask)374*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, ToFromEnumBitmask) {
375*6777b538SAndroid Build Coastguard Worker const TestEnumSet empty;
376*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(empty.ToEnumBitmask(), 0ULL);
377*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSet::FromEnumBitmask(0), empty);
378*6777b538SAndroid Build Coastguard Worker
379*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums1 = {TestEnum::TEST_2};
380*6777b538SAndroid Build Coastguard Worker const uint64_t val1 = 1ULL << static_cast<uint64_t>(TestEnum::TEST_2);
381*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(enums1.ToEnumBitmask(), val1);
382*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSet::FromEnumBitmask(val1), enums1);
383*6777b538SAndroid Build Coastguard Worker
384*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums2 = {TestEnum::TEST_3, TestEnum::TEST_4};
385*6777b538SAndroid Build Coastguard Worker const uint64_t val2 = 1ULL << static_cast<uint64_t>(TestEnum::TEST_3) |
386*6777b538SAndroid Build Coastguard Worker 1ULL << static_cast<uint64_t>(TestEnum::TEST_4);
387*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(enums2.ToEnumBitmask(), val2);
388*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSet::FromEnumBitmask(val2), enums2);
389*6777b538SAndroid Build Coastguard Worker }
390*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,ToFromEnumBitmaskExtreme)391*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, ToFromEnumBitmaskExtreme) {
392*6777b538SAndroid Build Coastguard Worker const TestEnumExtremeSet empty;
393*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(empty.ToEnumBitmask(), 0ULL);
394*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumExtremeSet::FromEnumBitmask(0ULL), empty);
395*6777b538SAndroid Build Coastguard Worker
396*6777b538SAndroid Build Coastguard Worker const TestEnumExtremeSet enums1 = {TestEnumExtreme::TEST_63};
397*6777b538SAndroid Build Coastguard Worker const uint64_t val1 = 1ULL << static_cast<uint64_t>(TestEnumExtreme::TEST_63);
398*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(enums1.ToEnumBitmask(), val1);
399*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumExtremeSet::FromEnumBitmask(val1), enums1);
400*6777b538SAndroid Build Coastguard Worker }
401*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,FromEnumBitmaskIgnoresExtraBits)402*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, FromEnumBitmaskIgnoresExtraBits) {
403*6777b538SAndroid Build Coastguard Worker const TestEnumSet kSets[] = {
404*6777b538SAndroid Build Coastguard Worker {},
405*6777b538SAndroid Build Coastguard Worker {TestEnum::TEST_MIN},
406*6777b538SAndroid Build Coastguard Worker {TestEnum::TEST_MAX},
407*6777b538SAndroid Build Coastguard Worker {TestEnum::TEST_MIN, TestEnum::TEST_MAX},
408*6777b538SAndroid Build Coastguard Worker {TestEnum::TEST_MIN, TestEnum::TEST_MAX},
409*6777b538SAndroid Build Coastguard Worker {TestEnum::TEST_2, TestEnum::TEST_4},
410*6777b538SAndroid Build Coastguard Worker };
411*6777b538SAndroid Build Coastguard Worker size_t i = 0;
412*6777b538SAndroid Build Coastguard Worker for (const TestEnumSet& set : kSets) {
413*6777b538SAndroid Build Coastguard Worker SCOPED_TRACE(i++);
414*6777b538SAndroid Build Coastguard Worker const uint64_t val = set.ToEnumBitmask();
415*6777b538SAndroid Build Coastguard Worker
416*6777b538SAndroid Build Coastguard Worker // Produce a bitstring for a single enum value. When `e` is in range
417*6777b538SAndroid Build Coastguard Worker // relative to TestEnumSet, this function behaves identically to
418*6777b538SAndroid Build Coastguard Worker // `single_val_bitstring`. When `e` is not in range, this function attempts
419*6777b538SAndroid Build Coastguard Worker // to compute a value, while `single_val_bitstring` intentionally crashes.
420*6777b538SAndroid Build Coastguard Worker auto single_val_bitstring = [](TestEnum e) -> uint64_t {
421*6777b538SAndroid Build Coastguard Worker uint64_t shift_amount = static_cast<uint64_t>(e);
422*6777b538SAndroid Build Coastguard Worker // Shifting left more than the number of bits in the lhs would be UB.
423*6777b538SAndroid Build Coastguard Worker CHECK_LT(shift_amount, sizeof(uint64_t) * 8);
424*6777b538SAndroid Build Coastguard Worker return 1ULL << shift_amount;
425*6777b538SAndroid Build Coastguard Worker };
426*6777b538SAndroid Build Coastguard Worker
427*6777b538SAndroid Build Coastguard Worker const uint64_t kJunkVals[] = {
428*6777b538SAndroid Build Coastguard Worker // Add junk bits above TEST_MAX.
429*6777b538SAndroid Build Coastguard Worker val | single_val_bitstring(TestEnum::TEST_6_OUT_OF_BOUNDS),
430*6777b538SAndroid Build Coastguard Worker val | single_val_bitstring(TestEnum::TEST_7_OUT_OF_BOUNDS),
431*6777b538SAndroid Build Coastguard Worker val | single_val_bitstring(TestEnum::TEST_6_OUT_OF_BOUNDS) |
432*6777b538SAndroid Build Coastguard Worker single_val_bitstring(TestEnum::TEST_7_OUT_OF_BOUNDS),
433*6777b538SAndroid Build Coastguard Worker // Add junk bits below TEST_MIN.
434*6777b538SAndroid Build Coastguard Worker val | single_val_bitstring(TestEnum::TEST_BELOW_MIN),
435*6777b538SAndroid Build Coastguard Worker };
436*6777b538SAndroid Build Coastguard Worker for (uint64_t junk_val : kJunkVals) {
437*6777b538SAndroid Build Coastguard Worker SCOPED_TRACE(junk_val);
438*6777b538SAndroid Build Coastguard Worker ASSERT_NE(val, junk_val);
439*6777b538SAndroid Build Coastguard Worker
440*6777b538SAndroid Build Coastguard Worker const TestEnumSet set_from_junk = TestEnumSet::FromEnumBitmask(junk_val);
441*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(set_from_junk, set);
442*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(set_from_junk.ToEnumBitmask(), set.ToEnumBitmask());
443*6777b538SAndroid Build Coastguard Worker
444*6777b538SAndroid Build Coastguard Worker // Iterating both sets should produce the same sequence.
445*6777b538SAndroid Build Coastguard Worker auto it1 = set.begin();
446*6777b538SAndroid Build Coastguard Worker auto it2 = set_from_junk.begin();
447*6777b538SAndroid Build Coastguard Worker while (it1 != set.end() && it2 != set_from_junk.end()) {
448*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(*it1, *it2);
449*6777b538SAndroid Build Coastguard Worker ++it1;
450*6777b538SAndroid Build Coastguard Worker ++it2;
451*6777b538SAndroid Build Coastguard Worker }
452*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(it1 == set.end());
453*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(it2 == set_from_junk.end());
454*6777b538SAndroid Build Coastguard Worker }
455*6777b538SAndroid Build Coastguard Worker }
456*6777b538SAndroid Build Coastguard Worker }
457*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,OneEnumValue)458*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, OneEnumValue) {
459*6777b538SAndroid Build Coastguard Worker enum class TestEnumOne {
460*6777b538SAndroid Build Coastguard Worker kTest1 = 1,
461*6777b538SAndroid Build Coastguard Worker kTestMin = kTest1,
462*6777b538SAndroid Build Coastguard Worker kTestMax = kTest1,
463*6777b538SAndroid Build Coastguard Worker };
464*6777b538SAndroid Build Coastguard Worker using TestEnumOneSet =
465*6777b538SAndroid Build Coastguard Worker EnumSet<TestEnumOne, TestEnumOne::kTestMin, TestEnumOne::kTestMax>;
466*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumOne::kTestMin, TestEnumOneSet::kMinValue);
467*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumOne::kTestMax, TestEnumOneSet::kMaxValue);
468*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, TestEnumOneSet::kValueCount);
469*6777b538SAndroid Build Coastguard Worker }
470*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,SparseEnum)471*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, SparseEnum) {
472*6777b538SAndroid Build Coastguard Worker enum class TestEnumSparse {
473*6777b538SAndroid Build Coastguard Worker TEST_1 = 1,
474*6777b538SAndroid Build Coastguard Worker TEST_MIN = 1,
475*6777b538SAndroid Build Coastguard Worker TEST_50 = 50,
476*6777b538SAndroid Build Coastguard Worker TEST_100 = 100,
477*6777b538SAndroid Build Coastguard Worker TEST_MAX = TEST_100,
478*6777b538SAndroid Build Coastguard Worker };
479*6777b538SAndroid Build Coastguard Worker using TestEnumSparseSet = EnumSet<TestEnumSparse, TestEnumSparse::TEST_MIN,
480*6777b538SAndroid Build Coastguard Worker TestEnumSparse::TEST_MAX>;
481*6777b538SAndroid Build Coastguard Worker TestEnumSparseSet sparse;
482*6777b538SAndroid Build Coastguard Worker sparse.Put(TestEnumSparse::TEST_MIN);
483*6777b538SAndroid Build Coastguard Worker sparse.Put(TestEnumSparse::TEST_MAX);
484*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(sparse.size(), 2u);
485*6777b538SAndroid Build Coastguard Worker
486*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSparseSet::All().size(), 100u);
487*6777b538SAndroid Build Coastguard Worker }
488*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,SparseEnumSmall)489*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, SparseEnumSmall) {
490*6777b538SAndroid Build Coastguard Worker enum class TestEnumSparse {
491*6777b538SAndroid Build Coastguard Worker TEST_1 = 1,
492*6777b538SAndroid Build Coastguard Worker TEST_MIN = 1,
493*6777b538SAndroid Build Coastguard Worker TEST_50 = 50,
494*6777b538SAndroid Build Coastguard Worker TEST_60 = 60,
495*6777b538SAndroid Build Coastguard Worker TEST_MAX = TEST_60,
496*6777b538SAndroid Build Coastguard Worker };
497*6777b538SAndroid Build Coastguard Worker using TestEnumSparseSet = EnumSet<TestEnumSparse, TestEnumSparse::TEST_MIN,
498*6777b538SAndroid Build Coastguard Worker TestEnumSparse::TEST_MAX>;
499*6777b538SAndroid Build Coastguard Worker TestEnumSparseSet sparse;
500*6777b538SAndroid Build Coastguard Worker sparse.Put(TestEnumSparse::TEST_MIN);
501*6777b538SAndroid Build Coastguard Worker sparse.Put(TestEnumSparse::TEST_MAX);
502*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(sparse.size(), 2u);
503*6777b538SAndroid Build Coastguard Worker
504*6777b538SAndroid Build Coastguard Worker // This may seem a little surprising! There are only 3 distinct values in
505*6777b538SAndroid Build Coastguard Worker // TestEnumSparse, so why does TestEnumSparseSet think it has 60 of them? This
506*6777b538SAndroid Build Coastguard Worker // is an artifact of EnumSet's design, as it has no way of knowing which
507*6777b538SAndroid Build Coastguard Worker // values between the min and max are actually named in the enum's definition.
508*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(TestEnumSparseSet::All().size(), 60u);
509*6777b538SAndroid Build Coastguard Worker }
510*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetDeathTest,CrashesOnOutOfRange)511*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetDeathTest, CrashesOnOutOfRange) {
512*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet({TestEnum::TEST_BELOW_MIN}));
513*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet({TestEnum::TEST_6_OUT_OF_BOUNDS}));
514*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet({TestEnum::TEST_7_OUT_OF_BOUNDS}));
515*6777b538SAndroid Build Coastguard Worker }
516*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetDeathTest,EnumWithNegatives)517*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetDeathTest, EnumWithNegatives) {
518*6777b538SAndroid Build Coastguard Worker enum class TestEnumNeg {
519*6777b538SAndroid Build Coastguard Worker TEST_BELOW_MIN = -3,
520*6777b538SAndroid Build Coastguard Worker TEST_A = -2,
521*6777b538SAndroid Build Coastguard Worker TEST_MIN = TEST_A,
522*6777b538SAndroid Build Coastguard Worker TEST_B = -1,
523*6777b538SAndroid Build Coastguard Worker TEST_C = 0,
524*6777b538SAndroid Build Coastguard Worker TEST_D = 1,
525*6777b538SAndroid Build Coastguard Worker TEST_E = 2,
526*6777b538SAndroid Build Coastguard Worker TEST_MAX = TEST_E,
527*6777b538SAndroid Build Coastguard Worker TEST_F = 3,
528*6777b538SAndroid Build Coastguard Worker };
529*6777b538SAndroid Build Coastguard Worker // This EnumSet starts negative and ends positive.
530*6777b538SAndroid Build Coastguard Worker using TestEnumWithNegSet =
531*6777b538SAndroid Build Coastguard Worker EnumSet<TestEnumNeg, TestEnumNeg::TEST_MIN, TestEnumNeg::TEST_MAX>;
532*6777b538SAndroid Build Coastguard Worker
533*6777b538SAndroid Build Coastguard Worker // Should crash because TEST_BELOW_MIN is not in range.
534*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumWithNegSet({TestEnumNeg::TEST_BELOW_MIN}));
535*6777b538SAndroid Build Coastguard Worker // TEST_D is in range, but note that TEST_MIN is negative. This should work.
536*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(
537*6777b538SAndroid Build Coastguard Worker TestEnumWithNegSet({TestEnumNeg::TEST_D}).Has(TestEnumNeg::TEST_D));
538*6777b538SAndroid Build Coastguard Worker // Even though TEST_A is negative, it is in range, so this should work.
539*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(
540*6777b538SAndroid Build Coastguard Worker TestEnumWithNegSet({TestEnumNeg::TEST_A}).Has(TestEnumNeg::TEST_A));
541*6777b538SAndroid Build Coastguard Worker }
542*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetDeathTest,EnumWithOnlyNegatives)543*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetDeathTest, EnumWithOnlyNegatives) {
544*6777b538SAndroid Build Coastguard Worker enum class TestEnumNeg {
545*6777b538SAndroid Build Coastguard Worker TEST_BELOW_MIN = -10,
546*6777b538SAndroid Build Coastguard Worker TEST_A = -9,
547*6777b538SAndroid Build Coastguard Worker TEST_MIN = TEST_A,
548*6777b538SAndroid Build Coastguard Worker TEST_B = -8,
549*6777b538SAndroid Build Coastguard Worker TEST_C = -7,
550*6777b538SAndroid Build Coastguard Worker TEST_D = -6,
551*6777b538SAndroid Build Coastguard Worker TEST_MAX = TEST_D,
552*6777b538SAndroid Build Coastguard Worker TEST_F = -5,
553*6777b538SAndroid Build Coastguard Worker };
554*6777b538SAndroid Build Coastguard Worker // This EnumSet starts negative and ends negative.
555*6777b538SAndroid Build Coastguard Worker using TestEnumWithNegSet =
556*6777b538SAndroid Build Coastguard Worker EnumSet<TestEnumNeg, TestEnumNeg::TEST_MIN, TestEnumNeg::TEST_MAX>;
557*6777b538SAndroid Build Coastguard Worker
558*6777b538SAndroid Build Coastguard Worker // Should crash because TEST_BELOW_MIN is not in range.
559*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumWithNegSet({TestEnumNeg::TEST_BELOW_MIN}));
560*6777b538SAndroid Build Coastguard Worker // TEST_A, TEST_D are in range, but note that TEST_MIN and values are
561*6777b538SAndroid Build Coastguard Worker // negative. This should work.
562*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(
563*6777b538SAndroid Build Coastguard Worker TestEnumWithNegSet({TestEnumNeg::TEST_A}).Has(TestEnumNeg::TEST_A));
564*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(
565*6777b538SAndroid Build Coastguard Worker TestEnumWithNegSet({TestEnumNeg::TEST_D}).Has(TestEnumNeg::TEST_D));
566*6777b538SAndroid Build Coastguard Worker }
567*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetDeathTest,VariadicConstructorCrashesOnOutOfRange)568*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetDeathTest, VariadicConstructorCrashesOnOutOfRange) {
569*6777b538SAndroid Build Coastguard Worker // Constructor should crash given out-of-range values.
570*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet({TestEnum::TEST_BELOW_MIN}).empty());
571*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet({TestEnum::TEST_BELOW_MIN_NEGATIVE}).empty());
572*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet({TestEnum::TEST_6_OUT_OF_BOUNDS}).empty());
573*6777b538SAndroid Build Coastguard Worker }
574*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetDeathTest,FromRangeCrashesOnBadInputs)575*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetDeathTest, FromRangeCrashesOnBadInputs) {
576*6777b538SAndroid Build Coastguard Worker // FromRange crashes when the bounds are in range, but out of order.
577*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(
578*6777b538SAndroid Build Coastguard Worker TestEnumSet().FromRange(TestEnum::TEST_3, TestEnum::TEST_1));
579*6777b538SAndroid Build Coastguard Worker
580*6777b538SAndroid Build Coastguard Worker // FromRange crashes when the start value is out of range.
581*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(
582*6777b538SAndroid Build Coastguard Worker TestEnumSet().FromRange(TestEnum::TEST_BELOW_MIN, TestEnum::TEST_1));
583*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet().FromRange(TestEnum::TEST_BELOW_MIN_NEGATIVE,
584*6777b538SAndroid Build Coastguard Worker TestEnum::TEST_1));
585*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet().FromRange(TestEnum::TEST_6_OUT_OF_BOUNDS,
586*6777b538SAndroid Build Coastguard Worker TestEnum::TEST_1));
587*6777b538SAndroid Build Coastguard Worker
588*6777b538SAndroid Build Coastguard Worker // FromRange crashes when the end value is out of range.
589*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(
590*6777b538SAndroid Build Coastguard Worker TestEnumSet().FromRange(TestEnum::TEST_3, TestEnum::TEST_BELOW_MIN));
591*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet().FromRange(
592*6777b538SAndroid Build Coastguard Worker TestEnum::TEST_3, TestEnum::TEST_BELOW_MIN_NEGATIVE));
593*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet().FromRange(TestEnum::TEST_3,
594*6777b538SAndroid Build Coastguard Worker TestEnum::TEST_6_OUT_OF_BOUNDS));
595*6777b538SAndroid Build Coastguard Worker
596*6777b538SAndroid Build Coastguard Worker // Crashes when start and end are both out of range.
597*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet().FromRange(TestEnum::TEST_7_OUT_OF_BOUNDS,
598*6777b538SAndroid Build Coastguard Worker TestEnum::TEST_6_OUT_OF_BOUNDS));
599*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet().FromRange(TestEnum::TEST_6_OUT_OF_BOUNDS,
600*6777b538SAndroid Build Coastguard Worker TestEnum::TEST_7_OUT_OF_BOUNDS));
601*6777b538SAndroid Build Coastguard Worker }
602*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetDeathTest,PutCrashesOnOutOfRange)603*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetDeathTest, PutCrashesOnOutOfRange) {
604*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet().Put(TestEnum::TEST_BELOW_MIN));
605*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet().Put(TestEnum::TEST_BELOW_MIN_NEGATIVE));
606*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet().Put(TestEnum::TEST_6_OUT_OF_BOUNDS));
607*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet().Put(TestEnum::TEST_7_OUT_OF_BOUNDS));
608*6777b538SAndroid Build Coastguard Worker }
609*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetDeathTest,PutRangeCrashesOnBadInputs)610*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetDeathTest, PutRangeCrashesOnBadInputs) {
611*6777b538SAndroid Build Coastguard Worker // Crashes when one input is out of range.
612*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet().PutRange(TestEnum::TEST_BELOW_MIN_NEGATIVE,
613*6777b538SAndroid Build Coastguard Worker TestEnum::TEST_BELOW_MIN));
614*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(
615*6777b538SAndroid Build Coastguard Worker TestEnumSet().PutRange(TestEnum::TEST_3, TestEnum::TEST_7_OUT_OF_BOUNDS));
616*6777b538SAndroid Build Coastguard Worker
617*6777b538SAndroid Build Coastguard Worker // Crashes when both inputs are out of range.
618*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(TestEnumSet().PutRange(TestEnum::TEST_6_OUT_OF_BOUNDS,
619*6777b538SAndroid Build Coastguard Worker TestEnum::TEST_7_OUT_OF_BOUNDS));
620*6777b538SAndroid Build Coastguard Worker
621*6777b538SAndroid Build Coastguard Worker // Crashes when inputs are out of order.
622*6777b538SAndroid Build Coastguard Worker EXPECT_CHECK_DEATH(
623*6777b538SAndroid Build Coastguard Worker TestEnumSet().PutRange(TestEnum::TEST_2, TestEnum::TEST_1));
624*6777b538SAndroid Build Coastguard Worker }
625*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,ToStringEmpty)626*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, ToStringEmpty) {
627*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums;
628*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(enums.ToString(), testing::Eq("00000"));
629*6777b538SAndroid Build Coastguard Worker }
630*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,ToString)631*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, ToString) {
632*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums = {TestEnum::TEST_4};
633*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(enums.ToString(), testing::Eq("01000"));
634*6777b538SAndroid Build Coastguard Worker }
635*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,ToVectorEmpty)636*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, ToVectorEmpty) {
637*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums;
638*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(ToVector(enums).empty());
639*6777b538SAndroid Build Coastguard Worker }
640*6777b538SAndroid Build Coastguard Worker
TEST_F(EnumSetTest,ToVector)641*6777b538SAndroid Build Coastguard Worker TEST_F(EnumSetTest, ToVector) {
642*6777b538SAndroid Build Coastguard Worker const TestEnumSet enums = {TestEnum::TEST_2, TestEnum::TEST_4};
643*6777b538SAndroid Build Coastguard Worker EXPECT_THAT(ToVector(enums),
644*6777b538SAndroid Build Coastguard Worker testing::ElementsAre(TestEnum::TEST_2, TestEnum::TEST_4));
645*6777b538SAndroid Build Coastguard Worker }
646*6777b538SAndroid Build Coastguard Worker
647*6777b538SAndroid Build Coastguard Worker } // namespace
648*6777b538SAndroid Build Coastguard Worker } // namespace base
649