1/*
2 * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27
28#include "Test.h"
29#include <wtf/OptionSet.h>
30
31namespace TestWebKitAPI {
32
33enum class ExampleFlags : uint64_t {
34 A = 1 << 0,
35 B = 1 << 1,
36 C = 1 << 2,
37 D = 1ULL << 31,
38 E = 1ULL << 63,
39};
40
41TEST(WTF_OptionSet, EmptySet)
42{
43 OptionSet<ExampleFlags> set;
44 EXPECT_TRUE(set.isEmpty());
45 EXPECT_FALSE(set.contains(ExampleFlags::A));
46 EXPECT_FALSE(set.contains(ExampleFlags::B));
47 EXPECT_FALSE(set.contains(ExampleFlags::C));
48 EXPECT_FALSE(set.contains(ExampleFlags::D));
49 EXPECT_FALSE(set.contains(ExampleFlags::E));
50}
51
52TEST(WTF_OptionSet, ContainsOneFlag)
53{
54 OptionSet<ExampleFlags> set = ExampleFlags::A;
55 EXPECT_FALSE(set.isEmpty());
56 EXPECT_TRUE(set.contains(ExampleFlags::A));
57 EXPECT_FALSE(set.contains(ExampleFlags::B));
58 EXPECT_FALSE(set.contains(ExampleFlags::C));
59 EXPECT_FALSE(set.contains(ExampleFlags::D));
60 EXPECT_FALSE(set.contains(ExampleFlags::E));
61}
62
63TEST(WTF_OptionSet, Equal)
64{
65 OptionSet<ExampleFlags> set { ExampleFlags::A, ExampleFlags::B };
66
67 EXPECT_TRUE((set == OptionSet<ExampleFlags> { ExampleFlags::A, ExampleFlags::B }));
68 EXPECT_TRUE((set == OptionSet<ExampleFlags> { ExampleFlags::B, ExampleFlags::A }));
69 EXPECT_FALSE(set == ExampleFlags::B);
70}
71
72TEST(WTF_OptionSet, NotEqual)
73{
74 OptionSet<ExampleFlags> set = ExampleFlags::A;
75
76 EXPECT_TRUE(set != ExampleFlags::B);
77 EXPECT_FALSE(set != ExampleFlags::A);
78}
79
80TEST(WTF_OptionSet, Or)
81{
82 OptionSet<ExampleFlags> set { ExampleFlags::A, ExampleFlags::B, ExampleFlags::C };
83 OptionSet<ExampleFlags> set2 { ExampleFlags::C, ExampleFlags::D };
84
85 EXPECT_TRUE(((set | ExampleFlags::A) == OptionSet<ExampleFlags> { ExampleFlags::A, ExampleFlags::B, ExampleFlags::C }));
86 EXPECT_TRUE(((set | ExampleFlags::D) == OptionSet<ExampleFlags> { ExampleFlags::A, ExampleFlags::B, ExampleFlags::C, ExampleFlags::D }));
87 EXPECT_TRUE(((set | set2) == OptionSet<ExampleFlags> { ExampleFlags::A, ExampleFlags::B, ExampleFlags::C, ExampleFlags::D }));
88}
89
90TEST(WTF_OptionSet, Minus)
91{
92 OptionSet<ExampleFlags> set { ExampleFlags::A, ExampleFlags::B, ExampleFlags::C };
93
94 EXPECT_TRUE(((set - ExampleFlags::A) == OptionSet<ExampleFlags> { ExampleFlags::B, ExampleFlags::C }));
95 EXPECT_TRUE(((set - ExampleFlags::D) == OptionSet<ExampleFlags> { ExampleFlags::A, ExampleFlags::B, ExampleFlags::C }));
96 EXPECT_TRUE((set - set).isEmpty());
97}
98
99TEST(WTF_OptionSet, AddAndRemove)
100{
101 OptionSet<ExampleFlags> set;
102
103 set.add(ExampleFlags::A);
104 EXPECT_TRUE(set.contains(ExampleFlags::A));
105 EXPECT_FALSE(set.contains(ExampleFlags::B));
106 EXPECT_FALSE(set.contains(ExampleFlags::C));
107
108 set.add({ ExampleFlags::B, ExampleFlags::C });
109 EXPECT_TRUE(set.contains(ExampleFlags::A));
110 EXPECT_TRUE(set.contains(ExampleFlags::B));
111 EXPECT_TRUE(set.contains(ExampleFlags::C));
112
113 set.remove(ExampleFlags::B);
114 EXPECT_TRUE(set.contains(ExampleFlags::A));
115 EXPECT_FALSE(set.contains(ExampleFlags::B));
116 EXPECT_TRUE(set.contains(ExampleFlags::C));
117
118 set.remove({ ExampleFlags::A, ExampleFlags::C });
119 EXPECT_FALSE(set.contains(ExampleFlags::A));
120 EXPECT_FALSE(set.contains(ExampleFlags::B));
121 EXPECT_FALSE(set.contains(ExampleFlags::C));
122}
123
124TEST(WTF_OptionSet, ContainsTwoFlags)
125{
126 OptionSet<ExampleFlags> set { ExampleFlags::A, ExampleFlags::B };
127 EXPECT_FALSE(set.isEmpty());
128 EXPECT_TRUE(set.contains(ExampleFlags::A));
129 EXPECT_TRUE(set.contains(ExampleFlags::B));
130 EXPECT_FALSE(set.contains(ExampleFlags::C));
131 EXPECT_FALSE(set.contains(ExampleFlags::D));
132 EXPECT_FALSE(set.contains(ExampleFlags::E));
133}
134
135TEST(WTF_OptionSet, ContainsTwoFlags2)
136{
137 OptionSet<ExampleFlags> set { ExampleFlags::A, ExampleFlags::D };
138 EXPECT_FALSE(set.isEmpty());
139 EXPECT_TRUE(set.contains(ExampleFlags::A));
140 EXPECT_TRUE(set.contains(ExampleFlags::D));
141 EXPECT_FALSE(set.contains(ExampleFlags::B));
142 EXPECT_FALSE(set.contains(ExampleFlags::C));
143 EXPECT_FALSE(set.contains(ExampleFlags::E));
144}
145
146TEST(WTF_OptionSet, ContainsTwoFlags3)
147{
148 OptionSet<ExampleFlags> set { ExampleFlags::D, ExampleFlags::E };
149 EXPECT_FALSE(set.isEmpty());
150 EXPECT_TRUE(set.contains(ExampleFlags::D));
151 EXPECT_TRUE(set.contains(ExampleFlags::E));
152 EXPECT_FALSE(set.contains(ExampleFlags::A));
153 EXPECT_FALSE(set.contains(ExampleFlags::B));
154 EXPECT_FALSE(set.contains(ExampleFlags::C));
155}
156
157TEST(WTF_OptionSet, EmptyOptionSetToRawValueToOptionSet)
158{
159 OptionSet<ExampleFlags> set;
160 EXPECT_TRUE(set.isEmpty());
161 EXPECT_FALSE(set.contains(ExampleFlags::A));
162 EXPECT_FALSE(set.contains(ExampleFlags::B));
163 EXPECT_FALSE(set.contains(ExampleFlags::C));
164
165 auto set2 = OptionSet<ExampleFlags>::fromRaw(set.toRaw());
166 EXPECT_TRUE(set2.isEmpty());
167 EXPECT_FALSE(set2.contains(ExampleFlags::A));
168 EXPECT_FALSE(set2.contains(ExampleFlags::B));
169 EXPECT_FALSE(set2.contains(ExampleFlags::C));
170}
171
172TEST(WTF_OptionSet, OptionSetThatContainsOneFlagToRawValueToOptionSet)
173{
174 OptionSet<ExampleFlags> set = ExampleFlags::A;
175 EXPECT_FALSE(set.isEmpty());
176 EXPECT_TRUE(set.contains(ExampleFlags::A));
177 EXPECT_FALSE(set.contains(ExampleFlags::B));
178 EXPECT_FALSE(set.contains(ExampleFlags::C));
179 EXPECT_FALSE(set.contains(ExampleFlags::D));
180 EXPECT_FALSE(set.contains(ExampleFlags::E));
181
182 auto set2 = OptionSet<ExampleFlags>::fromRaw(set.toRaw());
183 EXPECT_FALSE(set2.isEmpty());
184 EXPECT_TRUE(set2.contains(ExampleFlags::A));
185 EXPECT_FALSE(set2.contains(ExampleFlags::B));
186 EXPECT_FALSE(set2.contains(ExampleFlags::C));
187 EXPECT_FALSE(set2.contains(ExampleFlags::D));
188 EXPECT_FALSE(set2.contains(ExampleFlags::E));
189}
190
191TEST(WTF_OptionSet, OptionSetThatContainsOneFlagToRawValueToOptionSet2)
192{
193 OptionSet<ExampleFlags> set = ExampleFlags::E;
194 EXPECT_FALSE(set.isEmpty());
195 EXPECT_TRUE(set.contains(ExampleFlags::E));
196 EXPECT_FALSE(set.contains(ExampleFlags::A));
197 EXPECT_FALSE(set.contains(ExampleFlags::B));
198 EXPECT_FALSE(set.contains(ExampleFlags::C));
199 EXPECT_FALSE(set.contains(ExampleFlags::D));
200
201 auto set2 = OptionSet<ExampleFlags>::fromRaw(set.toRaw());
202 EXPECT_FALSE(set2.isEmpty());
203 EXPECT_TRUE(set2.contains(ExampleFlags::E));
204 EXPECT_FALSE(set2.contains(ExampleFlags::A));
205 EXPECT_FALSE(set2.contains(ExampleFlags::B));
206 EXPECT_FALSE(set2.contains(ExampleFlags::C));
207 EXPECT_FALSE(set2.contains(ExampleFlags::D));
208}
209
210TEST(WTF_OptionSet, OptionSetThatContainsTwoFlagsToRawValueToOptionSet)
211{
212 OptionSet<ExampleFlags> set { ExampleFlags::A, ExampleFlags::C };
213 EXPECT_FALSE(set.isEmpty());
214 EXPECT_TRUE(set.contains(ExampleFlags::A));
215 EXPECT_TRUE(set.contains(ExampleFlags::C));
216 EXPECT_FALSE(set.contains(ExampleFlags::B));
217
218 auto set2 = OptionSet<ExampleFlags>::fromRaw(set.toRaw());
219 EXPECT_FALSE(set2.isEmpty());
220 EXPECT_TRUE(set2.contains(ExampleFlags::A));
221 EXPECT_TRUE(set2.contains(ExampleFlags::C));
222 EXPECT_FALSE(set2.contains(ExampleFlags::B));
223}
224
225TEST(WTF_OptionSet, OptionSetThatContainsTwoFlagsToRawValueToOptionSet2)
226{
227 OptionSet<ExampleFlags> set { ExampleFlags::D, ExampleFlags::E };
228 EXPECT_FALSE(set.isEmpty());
229 EXPECT_TRUE(set.contains(ExampleFlags::D));
230 EXPECT_TRUE(set.contains(ExampleFlags::E));
231 EXPECT_FALSE(set.contains(ExampleFlags::A));
232 EXPECT_FALSE(set.contains(ExampleFlags::B));
233 EXPECT_FALSE(set.contains(ExampleFlags::C));
234
235 auto set2 = OptionSet<ExampleFlags>::fromRaw(set.toRaw());
236 EXPECT_FALSE(set2.isEmpty());
237 EXPECT_TRUE(set2.contains(ExampleFlags::D));
238 EXPECT_TRUE(set2.contains(ExampleFlags::E));
239 EXPECT_FALSE(set2.contains(ExampleFlags::A));
240 EXPECT_FALSE(set2.contains(ExampleFlags::B));
241 EXPECT_FALSE(set2.contains(ExampleFlags::C));
242}
243
244TEST(WTF_OptionSet, TwoIteratorsIntoSameOptionSet)
245{
246 OptionSet<ExampleFlags> set { ExampleFlags::C, ExampleFlags::B };
247 OptionSet<ExampleFlags>::iterator it1 = set.begin();
248 OptionSet<ExampleFlags>::iterator it2 = it1;
249 ++it1;
250 EXPECT_STRONG_ENUM_EQ(ExampleFlags::C, *it1);
251 EXPECT_STRONG_ENUM_EQ(ExampleFlags::B, *it2);
252}
253
254TEST(WTF_OptionSet, IterateOverOptionSetThatContainsTwoFlags)
255{
256 OptionSet<ExampleFlags> set { ExampleFlags::A, ExampleFlags::C };
257 OptionSet<ExampleFlags>::iterator it = set.begin();
258 OptionSet<ExampleFlags>::iterator end = set.end();
259 EXPECT_TRUE(it != end);
260 EXPECT_STRONG_ENUM_EQ(ExampleFlags::A, *it);
261 ++it;
262 EXPECT_STRONG_ENUM_EQ(ExampleFlags::C, *it);
263 ++it;
264 EXPECT_TRUE(it == end);
265}
266
267TEST(WTF_OptionSet, IterateOverOptionSetThatContainsFlags2)
268{
269 OptionSet<ExampleFlags> set { ExampleFlags::D, ExampleFlags::E };
270 OptionSet<ExampleFlags>::iterator it = set.begin();
271 OptionSet<ExampleFlags>::iterator end = set.end();
272 EXPECT_TRUE(it != end);
273 EXPECT_STRONG_ENUM_EQ(ExampleFlags::D, *it);
274 ++it;
275 EXPECT_STRONG_ENUM_EQ(ExampleFlags::E, *it);
276 ++it;
277 EXPECT_TRUE(it == end);
278}
279
280TEST(WTF_OptionSet, NextItemAfterLargestIn32BitFlagSet)
281{
282 enum class ThirtyTwoBitFlags : uint32_t {
283 A = 1UL << 31,
284 };
285 OptionSet<ThirtyTwoBitFlags> set { ThirtyTwoBitFlags::A };
286 OptionSet<ThirtyTwoBitFlags>::iterator it = set.begin();
287 OptionSet<ThirtyTwoBitFlags>::iterator end = set.end();
288 EXPECT_TRUE(it != end);
289 ++it;
290 EXPECT_TRUE(it == end);
291}
292
293TEST(WTF_OptionSet, NextItemAfterLargestIn64BitFlagSet)
294{
295 enum class SixtyFourBitFlags : uint64_t {
296 A = 1ULL << 63,
297 };
298 OptionSet<SixtyFourBitFlags> set { SixtyFourBitFlags::A };
299 OptionSet<SixtyFourBitFlags>::iterator it = set.begin();
300 OptionSet<SixtyFourBitFlags>::iterator end = set.end();
301 EXPECT_TRUE(it != end);
302 ++it;
303 EXPECT_TRUE(it == end);
304}
305
306TEST(WTF_OptionSet, IterationOrderTheSameRegardlessOfInsertionOrder)
307{
308 OptionSet<ExampleFlags> set1 = ExampleFlags::C;
309 set1.add(ExampleFlags::A);
310
311 OptionSet<ExampleFlags> set2 = ExampleFlags::A;
312 set2.add(ExampleFlags::C);
313
314 OptionSet<ExampleFlags>::iterator it1 = set1.begin();
315 OptionSet<ExampleFlags>::iterator it2 = set2.begin();
316
317 EXPECT_TRUE(*it1 == *it2);
318 ++it1;
319 ++it2;
320 EXPECT_TRUE(*it1 == *it2);
321}
322
323TEST(WTF_OptionSet, OperatorAnd)
324{
325 OptionSet<ExampleFlags> a { ExampleFlags::A };
326 OptionSet<ExampleFlags> ac { ExampleFlags::A, ExampleFlags::C };
327 OptionSet<ExampleFlags> bc { ExampleFlags::B, ExampleFlags::C };
328 {
329 auto set = a & ac;
330 EXPECT_TRUE(!!set);
331 EXPECT_FALSE(set.isEmpty());
332 EXPECT_TRUE(set.contains(ExampleFlags::A));
333 EXPECT_FALSE(set.contains(ExampleFlags::B));
334 EXPECT_FALSE(set.contains(ExampleFlags::C));
335 }
336 {
337 auto set = a & bc;
338 EXPECT_FALSE(!!set);
339 EXPECT_TRUE(set.isEmpty());
340 EXPECT_FALSE(set.contains(ExampleFlags::A));
341 EXPECT_FALSE(set.contains(ExampleFlags::B));
342 EXPECT_FALSE(set.contains(ExampleFlags::C));
343 }
344 {
345 auto set = ac & bc;
346 EXPECT_TRUE(!!set);
347 EXPECT_FALSE(set.isEmpty());
348 EXPECT_FALSE(set.contains(ExampleFlags::A));
349 EXPECT_FALSE(set.contains(ExampleFlags::B));
350 EXPECT_TRUE(set.contains(ExampleFlags::C));
351 }
352 {
353 auto set = ExampleFlags::A & bc;
354 EXPECT_FALSE(!!set);
355 EXPECT_TRUE(set.isEmpty());
356 EXPECT_FALSE(set.contains(ExampleFlags::A));
357 EXPECT_FALSE(set.contains(ExampleFlags::B));
358 EXPECT_FALSE(set.contains(ExampleFlags::C));
359 }
360 {
361 auto set = ExampleFlags::A & ac;
362 EXPECT_TRUE(!!set);
363 EXPECT_FALSE(set.isEmpty());
364 EXPECT_TRUE(set.contains(ExampleFlags::A));
365 EXPECT_FALSE(set.contains(ExampleFlags::B));
366 EXPECT_FALSE(set.contains(ExampleFlags::C));
367 }
368 {
369 auto set = bc & ExampleFlags::A;
370 EXPECT_FALSE(!!set);
371 EXPECT_TRUE(set.isEmpty());
372 EXPECT_FALSE(set.contains(ExampleFlags::A));
373 EXPECT_FALSE(set.contains(ExampleFlags::B));
374 EXPECT_FALSE(set.contains(ExampleFlags::C));
375 }
376 {
377 auto set = ac & ExampleFlags::A;
378 EXPECT_TRUE(!!set);
379 EXPECT_FALSE(set.isEmpty());
380 EXPECT_TRUE(set.contains(ExampleFlags::A));
381 EXPECT_FALSE(set.contains(ExampleFlags::B));
382 EXPECT_FALSE(set.contains(ExampleFlags::C));
383 }
384}
385
386TEST(WTF_OptionSet, OperatorXor)
387{
388 OptionSet<ExampleFlags> a { ExampleFlags::A };
389 OptionSet<ExampleFlags> ac { ExampleFlags::A, ExampleFlags::C };
390 OptionSet<ExampleFlags> bc { ExampleFlags::B, ExampleFlags::C };
391 {
392 auto set = a ^ ac;
393 EXPECT_FALSE(set.contains(ExampleFlags::A));
394 EXPECT_FALSE(set.contains(ExampleFlags::B));
395 EXPECT_TRUE(set.contains(ExampleFlags::C));
396 }
397 {
398 auto set = a ^ bc;
399 EXPECT_TRUE(set.contains(ExampleFlags::A));
400 EXPECT_TRUE(set.contains(ExampleFlags::B));
401 EXPECT_TRUE(set.contains(ExampleFlags::C));
402 }
403 {
404 auto set = ac ^ bc;
405 EXPECT_TRUE(set.contains(ExampleFlags::A));
406 EXPECT_TRUE(set.contains(ExampleFlags::B));
407 EXPECT_FALSE(set.contains(ExampleFlags::C));
408 }
409}
410
411TEST(WTF_OptionSet, ContainsAny)
412{
413 OptionSet<ExampleFlags> set { ExampleFlags::A, ExampleFlags::B };
414
415 EXPECT_TRUE(set.containsAny({ ExampleFlags::A }));
416 EXPECT_TRUE(set.containsAny({ ExampleFlags::B }));
417 EXPECT_FALSE(set.containsAny({ ExampleFlags::C }));
418 EXPECT_FALSE(set.containsAny({ ExampleFlags::C, ExampleFlags::D }));
419 EXPECT_TRUE(set.containsAny({ ExampleFlags::A, ExampleFlags::B }));
420 EXPECT_TRUE(set.containsAny({ ExampleFlags::B, ExampleFlags::C }));
421 EXPECT_TRUE(set.containsAny({ ExampleFlags::A, ExampleFlags::C }));
422 EXPECT_TRUE(set.containsAny({ ExampleFlags::A, ExampleFlags::B, ExampleFlags::C }));
423}
424
425TEST(WTF_OptionSet, ContainsAll)
426{
427 OptionSet<ExampleFlags> set { ExampleFlags::A, ExampleFlags::B };
428
429 EXPECT_TRUE(set.containsAll({ ExampleFlags::A }));
430 EXPECT_TRUE(set.containsAll({ ExampleFlags::B }));
431 EXPECT_FALSE(set.containsAll({ ExampleFlags::C }));
432 EXPECT_FALSE(set.containsAll({ ExampleFlags::C, ExampleFlags::D }));
433 EXPECT_TRUE(set.containsAll({ ExampleFlags::A, ExampleFlags::B }));
434 EXPECT_FALSE(set.containsAll({ ExampleFlags::B, ExampleFlags::C }));
435 EXPECT_FALSE(set.containsAll({ ExampleFlags::A, ExampleFlags::C }));
436 EXPECT_FALSE(set.containsAll({ ExampleFlags::A, ExampleFlags::B, ExampleFlags::C }));
437}
438
439} // namespace TestWebKitAPI
440