• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2016 Google Inc.
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 "source/enum_set.h"
16 
17 #include <algorithm>
18 #include <array>
19 #include <random>
20 #include <utility>
21 #include <vector>
22 
23 #include "gmock/gmock.h"
24 #include "test/unit_spirv.h"
25 
26 namespace spvtools {
27 namespace {
28 
29 using spvtest::ElementsIn;
30 using ::testing::Eq;
31 using ::testing::Values;
32 using ::testing::ValuesIn;
33 
34 enum class TestEnum : uint32_t {
35   ZERO = 0,
36   ONE = 1,
37   TWO = 2,
38   THREE = 3,
39   FOUR = 4,
40   FIVE = 5,
41   EIGHT = 8,
42   TWENTY = 20,
43   TWENTY_FOUR = 24,
44   THIRTY = 30,
45   ONE_HUNDRED = 100,
46   ONE_HUNDRED_FIFTY = 150,
47   TWO_HUNDRED = 200,
48   THREE_HUNDRED = 300,
49   FOUR_HUNDRED = 400,
50   FIVE_HUNDRED = 500,
51   SIX_HUNDRED = 600,
52 };
53 
54 constexpr std::array kCapabilities{
55     spv::Capability::Matrix,
56     spv::Capability::Shader,
57     spv::Capability::Geometry,
58     spv::Capability::Tessellation,
59     spv::Capability::Addresses,
60     spv::Capability::Linkage,
61     spv::Capability::Kernel,
62     spv::Capability::Vector16,
63     spv::Capability::Float16Buffer,
64     spv::Capability::Float16,
65     spv::Capability::Float64,
66     spv::Capability::Int64,
67     spv::Capability::Int64Atomics,
68     spv::Capability::ImageBasic,
69     spv::Capability::ImageReadWrite,
70     spv::Capability::ImageMipmap,
71     spv::Capability::Pipes,
72     spv::Capability::Groups,
73     spv::Capability::DeviceEnqueue,
74     spv::Capability::LiteralSampler,
75     spv::Capability::AtomicStorage,
76     spv::Capability::Int16,
77     spv::Capability::TessellationPointSize,
78     spv::Capability::GeometryPointSize,
79     spv::Capability::ImageGatherExtended,
80     spv::Capability::StorageImageMultisample,
81     spv::Capability::UniformBufferArrayDynamicIndexing,
82     spv::Capability::SampledImageArrayDynamicIndexing,
83     spv::Capability::StorageBufferArrayDynamicIndexing,
84     spv::Capability::StorageImageArrayDynamicIndexing,
85     spv::Capability::ClipDistance,
86     spv::Capability::CullDistance,
87     spv::Capability::ImageCubeArray,
88     spv::Capability::SampleRateShading,
89     spv::Capability::ImageRect,
90     spv::Capability::SampledRect,
91     spv::Capability::GenericPointer,
92     spv::Capability::Int8,
93     spv::Capability::InputAttachment,
94     spv::Capability::SparseResidency,
95     spv::Capability::MinLod,
96     spv::Capability::Sampled1D,
97     spv::Capability::Image1D,
98     spv::Capability::SampledCubeArray,
99     spv::Capability::SampledBuffer,
100     spv::Capability::ImageBuffer,
101     spv::Capability::ImageMSArray,
102     spv::Capability::StorageImageExtendedFormats,
103     spv::Capability::ImageQuery,
104     spv::Capability::DerivativeControl,
105     spv::Capability::InterpolationFunction,
106     spv::Capability::TransformFeedback,
107     spv::Capability::GeometryStreams,
108     spv::Capability::StorageImageReadWithoutFormat,
109     spv::Capability::StorageImageWriteWithoutFormat,
110     spv::Capability::MultiViewport,
111     spv::Capability::SubgroupDispatch,
112     spv::Capability::NamedBarrier,
113     spv::Capability::PipeStorage,
114     spv::Capability::GroupNonUniform,
115     spv::Capability::GroupNonUniformVote,
116     spv::Capability::GroupNonUniformArithmetic,
117     spv::Capability::GroupNonUniformBallot,
118     spv::Capability::GroupNonUniformShuffle,
119     spv::Capability::GroupNonUniformShuffleRelative,
120     spv::Capability::GroupNonUniformClustered,
121     spv::Capability::GroupNonUniformQuad,
122     spv::Capability::ShaderLayer,
123     spv::Capability::ShaderViewportIndex,
124     spv::Capability::UniformDecoration,
125     spv::Capability::CoreBuiltinsARM,
126     spv::Capability::FragmentShadingRateKHR,
127     spv::Capability::SubgroupBallotKHR,
128     spv::Capability::DrawParameters,
129     spv::Capability::WorkgroupMemoryExplicitLayoutKHR,
130     spv::Capability::WorkgroupMemoryExplicitLayout8BitAccessKHR,
131     spv::Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR,
132     spv::Capability::SubgroupVoteKHR,
133     spv::Capability::StorageBuffer16BitAccess,
134     spv::Capability::StorageUniformBufferBlock16,
135     spv::Capability::StorageUniform16,
136     spv::Capability::UniformAndStorageBuffer16BitAccess,
137     spv::Capability::StoragePushConstant16,
138     spv::Capability::StorageInputOutput16,
139     spv::Capability::DeviceGroup,
140     spv::Capability::MultiView,
141     spv::Capability::VariablePointersStorageBuffer,
142     spv::Capability::VariablePointers,
143     spv::Capability::AtomicStorageOps,
144     spv::Capability::SampleMaskPostDepthCoverage,
145     spv::Capability::StorageBuffer8BitAccess,
146     spv::Capability::UniformAndStorageBuffer8BitAccess,
147     spv::Capability::StoragePushConstant8,
148     spv::Capability::DenormPreserve,
149     spv::Capability::DenormFlushToZero,
150     spv::Capability::SignedZeroInfNanPreserve,
151     spv::Capability::RoundingModeRTE,
152     spv::Capability::RoundingModeRTZ,
153     spv::Capability::RayQueryProvisionalKHR,
154     spv::Capability::RayQueryKHR,
155     spv::Capability::RayTraversalPrimitiveCullingKHR,
156     spv::Capability::RayTracingKHR,
157     spv::Capability::Float16ImageAMD,
158     spv::Capability::ImageGatherBiasLodAMD,
159     spv::Capability::FragmentMaskAMD,
160     spv::Capability::StencilExportEXT,
161     spv::Capability::ImageReadWriteLodAMD,
162     spv::Capability::Int64ImageEXT,
163     spv::Capability::ShaderClockKHR,
164     spv::Capability::SampleMaskOverrideCoverageNV,
165     spv::Capability::GeometryShaderPassthroughNV,
166     spv::Capability::ShaderViewportIndexLayerEXT,
167     spv::Capability::ShaderViewportIndexLayerNV,
168     spv::Capability::ShaderViewportMaskNV,
169     spv::Capability::ShaderStereoViewNV,
170     spv::Capability::PerViewAttributesNV,
171     spv::Capability::FragmentFullyCoveredEXT,
172     spv::Capability::MeshShadingNV,
173     spv::Capability::ImageFootprintNV,
174     spv::Capability::MeshShadingEXT,
175     spv::Capability::FragmentBarycentricKHR,
176     spv::Capability::FragmentBarycentricNV,
177     spv::Capability::ComputeDerivativeGroupQuadsNV,
178     spv::Capability::FragmentDensityEXT,
179     spv::Capability::ShadingRateNV,
180     spv::Capability::GroupNonUniformPartitionedNV,
181     spv::Capability::ShaderNonUniform,
182     spv::Capability::ShaderNonUniformEXT,
183     spv::Capability::RuntimeDescriptorArray,
184     spv::Capability::RuntimeDescriptorArrayEXT,
185     spv::Capability::InputAttachmentArrayDynamicIndexing,
186     spv::Capability::InputAttachmentArrayDynamicIndexingEXT,
187     spv::Capability::UniformTexelBufferArrayDynamicIndexing,
188     spv::Capability::UniformTexelBufferArrayDynamicIndexingEXT,
189     spv::Capability::StorageTexelBufferArrayDynamicIndexing,
190     spv::Capability::StorageTexelBufferArrayDynamicIndexingEXT,
191     spv::Capability::UniformBufferArrayNonUniformIndexing,
192     spv::Capability::UniformBufferArrayNonUniformIndexingEXT,
193     spv::Capability::SampledImageArrayNonUniformIndexing,
194     spv::Capability::SampledImageArrayNonUniformIndexingEXT,
195     spv::Capability::StorageBufferArrayNonUniformIndexing,
196     spv::Capability::StorageBufferArrayNonUniformIndexingEXT,
197     spv::Capability::StorageImageArrayNonUniformIndexing,
198     spv::Capability::StorageImageArrayNonUniformIndexingEXT,
199     spv::Capability::InputAttachmentArrayNonUniformIndexing,
200     spv::Capability::InputAttachmentArrayNonUniformIndexingEXT,
201     spv::Capability::UniformTexelBufferArrayNonUniformIndexing,
202     spv::Capability::UniformTexelBufferArrayNonUniformIndexingEXT,
203     spv::Capability::StorageTexelBufferArrayNonUniformIndexing,
204     spv::Capability::StorageTexelBufferArrayNonUniformIndexingEXT,
205     spv::Capability::RayTracingNV,
206     spv::Capability::RayTracingMotionBlurNV,
207     spv::Capability::VulkanMemoryModel,
208     spv::Capability::VulkanMemoryModelKHR,
209     spv::Capability::VulkanMemoryModelDeviceScope,
210     spv::Capability::VulkanMemoryModelDeviceScopeKHR,
211     spv::Capability::PhysicalStorageBufferAddresses,
212     spv::Capability::PhysicalStorageBufferAddressesEXT,
213     spv::Capability::ComputeDerivativeGroupLinearNV,
214     spv::Capability::RayTracingProvisionalKHR,
215     spv::Capability::CooperativeMatrixNV,
216     spv::Capability::FragmentShaderSampleInterlockEXT,
217     spv::Capability::FragmentShaderShadingRateInterlockEXT,
218     spv::Capability::ShaderSMBuiltinsNV,
219     spv::Capability::FragmentShaderPixelInterlockEXT,
220     spv::Capability::DemoteToHelperInvocation,
221     spv::Capability::DemoteToHelperInvocationEXT,
222     spv::Capability::RayTracingOpacityMicromapEXT,
223     spv::Capability::ShaderInvocationReorderNV,
224     spv::Capability::BindlessTextureNV,
225     spv::Capability::SubgroupShuffleINTEL,
226     spv::Capability::SubgroupBufferBlockIOINTEL,
227     spv::Capability::SubgroupImageBlockIOINTEL,
228     spv::Capability::SubgroupImageMediaBlockIOINTEL,
229     spv::Capability::RoundToInfinityINTEL,
230     spv::Capability::FloatingPointModeINTEL,
231     spv::Capability::IntegerFunctions2INTEL,
232     spv::Capability::FunctionPointersINTEL,
233     spv::Capability::IndirectReferencesINTEL,
234     spv::Capability::AsmINTEL,
235     spv::Capability::AtomicFloat32MinMaxEXT,
236     spv::Capability::AtomicFloat64MinMaxEXT,
237     spv::Capability::AtomicFloat16MinMaxEXT,
238     spv::Capability::VectorComputeINTEL,
239     spv::Capability::VectorAnyINTEL,
240     spv::Capability::ExpectAssumeKHR,
241     spv::Capability::SubgroupAvcMotionEstimationINTEL,
242     spv::Capability::SubgroupAvcMotionEstimationIntraINTEL,
243     spv::Capability::SubgroupAvcMotionEstimationChromaINTEL,
244     spv::Capability::VariableLengthArrayINTEL,
245     spv::Capability::FunctionFloatControlINTEL,
246     spv::Capability::FPGAMemoryAttributesINTEL,
247     spv::Capability::FPFastMathModeINTEL,
248     spv::Capability::ArbitraryPrecisionIntegersINTEL,
249     spv::Capability::ArbitraryPrecisionFloatingPointINTEL,
250     spv::Capability::UnstructuredLoopControlsINTEL,
251     spv::Capability::FPGALoopControlsINTEL,
252     spv::Capability::KernelAttributesINTEL,
253     spv::Capability::FPGAKernelAttributesINTEL,
254     spv::Capability::FPGAMemoryAccessesINTEL,
255     spv::Capability::FPGAClusterAttributesINTEL,
256     spv::Capability::LoopFuseINTEL,
257     spv::Capability::FPGADSPControlINTEL,
258     spv::Capability::MemoryAccessAliasingINTEL,
259     spv::Capability::FPGAInvocationPipeliningAttributesINTEL,
260     spv::Capability::FPGABufferLocationINTEL,
261     spv::Capability::ArbitraryPrecisionFixedPointINTEL,
262     spv::Capability::USMStorageClassesINTEL,
263     spv::Capability::RuntimeAlignedAttributeINTEL,
264     spv::Capability::IOPipesINTEL,
265     spv::Capability::BlockingPipesINTEL,
266     spv::Capability::FPGARegINTEL,
267     spv::Capability::DotProductInputAll,
268     spv::Capability::DotProductInputAllKHR,
269     spv::Capability::DotProductInput4x8Bit,
270     spv::Capability::DotProductInput4x8BitKHR,
271     spv::Capability::DotProductInput4x8BitPacked,
272     spv::Capability::DotProductInput4x8BitPackedKHR,
273     spv::Capability::DotProduct,
274     spv::Capability::DotProductKHR,
275     spv::Capability::RayCullMaskKHR,
276     spv::Capability::BitInstructions,
277     spv::Capability::GroupNonUniformRotateKHR,
278     spv::Capability::AtomicFloat32AddEXT,
279     spv::Capability::AtomicFloat64AddEXT,
280     spv::Capability::LongConstantCompositeINTEL,
281     spv::Capability::OptNoneINTEL,
282     spv::Capability::AtomicFloat16AddEXT,
283     spv::Capability::DebugInfoModuleINTEL,
284     spv::Capability::SplitBarrierINTEL,
285     spv::Capability::GroupUniformArithmeticKHR,
286     spv::Capability::Max,
287 };
288 
289 namespace {
enumerateValuesFromToWithStep(size_t start,size_t end,size_t step)290 std::vector<TestEnum> enumerateValuesFromToWithStep(size_t start, size_t end,
291                                                     size_t step) {
292   assert(end > start && "end > start");
293   std::vector<TestEnum> orderedValues;
294   for (size_t i = start; i < end; i += step) {
295     orderedValues.push_back(static_cast<TestEnum>(i));
296   }
297   return orderedValues;
298 }
299 
createSetUnorderedInsertion(const std::vector<TestEnum> & values)300 EnumSet<TestEnum> createSetUnorderedInsertion(
301     const std::vector<TestEnum>& values) {
302   std::vector shuffledValues(values.cbegin(), values.cend());
303   std::mt19937 rng(0);
304   std::shuffle(shuffledValues.begin(), shuffledValues.end(), rng);
305   EnumSet<TestEnum> set;
306   for (auto value : shuffledValues) {
307     set.insert(value);
308   }
309   return set;
310 }
311 }  // namespace
312 
TEST(EnumSet,IsEmpty1)313 TEST(EnumSet, IsEmpty1) {
314   EnumSet<TestEnum> set;
315   EXPECT_TRUE(set.empty());
316   set.insert(TestEnum::ZERO);
317   EXPECT_FALSE(set.empty());
318 }
319 
TEST(EnumSet,IsEmpty2)320 TEST(EnumSet, IsEmpty2) {
321   EnumSet<TestEnum> set;
322   EXPECT_TRUE(set.empty());
323   set.insert(TestEnum::ONE_HUNDRED_FIFTY);
324   EXPECT_FALSE(set.empty());
325 }
326 
TEST(EnumSet,IsEmpty3)327 TEST(EnumSet, IsEmpty3) {
328   EnumSet<TestEnum> set(TestEnum::FOUR);
329   EXPECT_FALSE(set.empty());
330 }
331 
TEST(EnumSet,IsEmpty4)332 TEST(EnumSet, IsEmpty4) {
333   EnumSet<TestEnum> set(TestEnum::THREE_HUNDRED);
334   EXPECT_FALSE(set.empty());
335 }
336 
TEST(EnumSetHasAnyOf,EmptySetEmptyQuery)337 TEST(EnumSetHasAnyOf, EmptySetEmptyQuery) {
338   const EnumSet<TestEnum> set;
339   const EnumSet<TestEnum> empty;
340   EXPECT_TRUE(set.HasAnyOf(empty));
341   EXPECT_TRUE(EnumSet<TestEnum>().HasAnyOf(EnumSet<TestEnum>()));
342 }
343 
TEST(EnumSetHasAnyOf,MaskSetEmptyQuery)344 TEST(EnumSetHasAnyOf, MaskSetEmptyQuery) {
345   EnumSet<TestEnum> set;
346   const EnumSet<TestEnum> empty;
347   set.insert(TestEnum::FIVE);
348   set.insert(TestEnum::EIGHT);
349   EXPECT_TRUE(set.HasAnyOf(empty));
350 }
351 
TEST(EnumSetHasAnyOf,OverflowSetEmptyQuery)352 TEST(EnumSetHasAnyOf, OverflowSetEmptyQuery) {
353   EnumSet<TestEnum> set;
354   const EnumSet<TestEnum> empty;
355   set.insert(TestEnum::TWO_HUNDRED);
356   set.insert(TestEnum::THREE_HUNDRED);
357   EXPECT_TRUE(set.HasAnyOf(empty));
358 }
359 
TEST(EnumSetHasAnyOf,EmptyQuery)360 TEST(EnumSetHasAnyOf, EmptyQuery) {
361   EnumSet<TestEnum> set;
362   const EnumSet<TestEnum> empty;
363   set.insert(TestEnum::FIVE);
364   set.insert(TestEnum::EIGHT);
365   set.insert(TestEnum::TWO_HUNDRED);
366   set.insert(TestEnum::THREE_HUNDRED);
367   EXPECT_TRUE(set.HasAnyOf(empty));
368 }
369 
TEST(EnumSetHasAnyOf,EmptyQueryAlwaysTrue)370 TEST(EnumSetHasAnyOf, EmptyQueryAlwaysTrue) {
371   EnumSet<TestEnum> set;
372   const EnumSet<TestEnum> empty;
373   EXPECT_TRUE(set.HasAnyOf(empty));
374   set.insert(TestEnum::FIVE);
375   EXPECT_TRUE(set.HasAnyOf(empty));
376 
377   EXPECT_TRUE(
378       EnumSet<TestEnum>(TestEnum::ONE_HUNDRED).HasAnyOf(EnumSet<TestEnum>()));
379 }
380 
TEST(EnumSetHasAnyOf,ReflexiveMask)381 TEST(EnumSetHasAnyOf, ReflexiveMask) {
382   EnumSet<TestEnum> set(TestEnum::THREE);
383   set.insert(TestEnum::TWENTY_FOUR);
384   set.insert(TestEnum::THIRTY);
385   EXPECT_TRUE(set.HasAnyOf(set));
386 }
387 
TEST(EnumSetHasAnyOf,ReflexiveOverflow)388 TEST(EnumSetHasAnyOf, ReflexiveOverflow) {
389   EnumSet<TestEnum> set(TestEnum::TWO_HUNDRED);
390   set.insert(TestEnum::TWO_HUNDRED);
391   set.insert(TestEnum::FOUR_HUNDRED);
392   EXPECT_TRUE(set.HasAnyOf(set));
393 }
394 
TEST(EnumSetHasAnyOf,Reflexive)395 TEST(EnumSetHasAnyOf, Reflexive) {
396   EnumSet<TestEnum> set(TestEnum::THREE);
397   set.insert(TestEnum::TWENTY_FOUR);
398   set.insert(TestEnum::THREE_HUNDRED);
399   set.insert(TestEnum::FOUR_HUNDRED);
400   EXPECT_TRUE(set.HasAnyOf(set));
401 }
402 
TEST(EnumSetHasAnyOf,EmptySetHasNone)403 TEST(EnumSetHasAnyOf, EmptySetHasNone) {
404   EnumSet<TestEnum> set;
405   EnumSet<TestEnum> items;
406   for (uint32_t i = 0; i < 200; ++i) {
407     TestEnum enumValue = static_cast<TestEnum>(i);
408     items.insert(enumValue);
409     EXPECT_FALSE(set.HasAnyOf(items));
410     EXPECT_FALSE(set.HasAnyOf(EnumSet<TestEnum>(enumValue)));
411   }
412 }
413 
TEST(EnumSetHasAnyOf,MaskSetMaskQuery)414 TEST(EnumSetHasAnyOf, MaskSetMaskQuery) {
415   EnumSet<TestEnum> set(TestEnum::ZERO);
416   EnumSet<TestEnum> items(TestEnum::ONE);
417   EXPECT_FALSE(set.HasAnyOf(items));
418   set.insert(TestEnum::TWO);
419   items.insert(TestEnum::THREE);
420   EXPECT_FALSE(set.HasAnyOf(items));
421   set.insert(TestEnum::THREE);
422   EXPECT_TRUE(set.HasAnyOf(items));
423   set.insert(TestEnum::FOUR);
424   EXPECT_TRUE(set.HasAnyOf(items));
425 }
426 
TEST(EnumSetHasAnyOf,OverflowSetOverflowQuery)427 TEST(EnumSetHasAnyOf, OverflowSetOverflowQuery) {
428   EnumSet<TestEnum> set(TestEnum::ONE_HUNDRED);
429   EnumSet<TestEnum> items(TestEnum::TWO_HUNDRED);
430   EXPECT_FALSE(set.HasAnyOf(items));
431   set.insert(TestEnum::THREE_HUNDRED);
432   items.insert(TestEnum::FOUR_HUNDRED);
433   EXPECT_FALSE(set.HasAnyOf(items));
434   set.insert(TestEnum::TWO_HUNDRED);
435   EXPECT_TRUE(set.HasAnyOf(items));
436   set.insert(TestEnum::FIVE_HUNDRED);
437   EXPECT_TRUE(set.HasAnyOf(items));
438 }
439 
TEST(EnumSetHasAnyOf,GeneralCase)440 TEST(EnumSetHasAnyOf, GeneralCase) {
441   EnumSet<TestEnum> set(TestEnum::ZERO);
442   EnumSet<TestEnum> items(TestEnum::ONE_HUNDRED);
443   EXPECT_FALSE(set.HasAnyOf(items));
444   set.insert(TestEnum::THREE_HUNDRED);
445   items.insert(TestEnum::FOUR);
446   EXPECT_FALSE(set.HasAnyOf(items));
447   set.insert(TestEnum::FIVE);
448   items.insert(TestEnum::FIVE_HUNDRED);
449   EXPECT_FALSE(set.HasAnyOf(items));
450   set.insert(TestEnum::FIVE_HUNDRED);
451   EXPECT_TRUE(set.HasAnyOf(items));
452   EXPECT_FALSE(set.HasAnyOf(EnumSet<TestEnum>(TestEnum::TWENTY)));
453   EXPECT_FALSE(set.HasAnyOf(EnumSet<TestEnum>(TestEnum::SIX_HUNDRED)));
454   EXPECT_TRUE(set.HasAnyOf(EnumSet<TestEnum>(TestEnum::FIVE)));
455   EXPECT_TRUE(set.HasAnyOf(EnumSet<TestEnum>(TestEnum::THREE_HUNDRED)));
456   EXPECT_TRUE(set.HasAnyOf(EnumSet<TestEnum>(TestEnum::ZERO)));
457 }
458 
TEST(EnumSet,DefaultIsEmpty)459 TEST(EnumSet, DefaultIsEmpty) {
460   EnumSet<TestEnum> set;
461   for (uint32_t i = 0; i < 1000; ++i) {
462     EXPECT_FALSE(set.contains(static_cast<TestEnum>(i)));
463   }
464 }
465 
TEST(EnumSet,EqualityCompareEmpty)466 TEST(EnumSet, EqualityCompareEmpty) {
467   EnumSet<TestEnum> set1;
468   EnumSet<TestEnum> set2;
469 
470   EXPECT_TRUE(set1 == set2);
471   EXPECT_FALSE(set1 != set2);
472 }
473 
TEST(EnumSet,EqualityCompareSame)474 TEST(EnumSet, EqualityCompareSame) {
475   EnumSet<TestEnum> set1;
476   EnumSet<TestEnum> set2;
477 
478   set1.insert(TestEnum::ONE);
479   set1.insert(TestEnum::TWENTY);
480   set2.insert(TestEnum::TWENTY);
481   set2.insert(TestEnum::ONE);
482 
483   EXPECT_TRUE(set1 == set2);
484   EXPECT_FALSE(set1 != set2);
485 }
486 
TEST(EnumSet,EqualityCompareDifferent)487 TEST(EnumSet, EqualityCompareDifferent) {
488   EnumSet<TestEnum> set1;
489   EnumSet<TestEnum> set2;
490 
491   set1.insert(TestEnum::ONE);
492   set1.insert(TestEnum::TWENTY);
493   set2.insert(TestEnum::FIVE);
494   set2.insert(TestEnum::ONE);
495 
496   EXPECT_FALSE(set1 == set2);
497   EXPECT_TRUE(set1 != set2);
498 }
499 
TEST(EnumSet,ConstructFromIterators)500 TEST(EnumSet, ConstructFromIterators) {
501   auto orderedValues = enumerateValuesFromToWithStep(0, 2, /* step= */ 1);
502   EnumSet<TestEnum> set1 = createSetUnorderedInsertion(orderedValues);
503 
504   EnumSet<TestEnum> set2(orderedValues.cbegin(), orderedValues.cend());
505 
506   EXPECT_EQ(set1, set2);
507 }
508 
TEST(EnumSet,InsertUsingIteratorRange)509 TEST(EnumSet, InsertUsingIteratorRange) {
510   auto orderedValues = enumerateValuesFromToWithStep(0, 2, /* step= */ 1);
511   EnumSet<TestEnum> set1 = createSetUnorderedInsertion(orderedValues);
512 
513   EnumSet<TestEnum> set2;
514   set2.insert(orderedValues.cbegin(), orderedValues.cend());
515 
516   EXPECT_EQ(set1, set2);
517 }
518 
TEST(CapabilitySet,RangeBasedLoopOrderIsEnumOrder)519 TEST(CapabilitySet, RangeBasedLoopOrderIsEnumOrder) {
520   auto orderedValues = enumerateValuesFromToWithStep(0, 2, /* step= */ 1);
521   auto set = createSetUnorderedInsertion(orderedValues);
522 
523   size_t index = 0;
524   for (auto value : set) {
525     ASSERT_THAT(value, Eq(orderedValues[index]));
526     index++;
527   }
528 }
529 
TEST(CapabilitySet,ConstructSingleMemberMatrix)530 TEST(CapabilitySet, ConstructSingleMemberMatrix) {
531   CapabilitySet s(spv::Capability::Matrix);
532   EXPECT_TRUE(s.contains(spv::Capability::Matrix));
533   EXPECT_FALSE(s.contains(spv::Capability::Shader));
534   EXPECT_FALSE(s.contains(static_cast<spv::Capability>(1000)));
535 }
536 
TEST(CapabilitySet,ConstructSingleMemberMaxInMask)537 TEST(CapabilitySet, ConstructSingleMemberMaxInMask) {
538   CapabilitySet s(static_cast<spv::Capability>(63));
539   EXPECT_FALSE(s.contains(spv::Capability::Matrix));
540   EXPECT_FALSE(s.contains(spv::Capability::Shader));
541   EXPECT_TRUE(s.contains(static_cast<spv::Capability>(63)));
542   EXPECT_FALSE(s.contains(static_cast<spv::Capability>(64)));
543   EXPECT_FALSE(s.contains(static_cast<spv::Capability>(1000)));
544 }
545 
TEST(CapabilitySet,ConstructSingleMemberMinOverflow)546 TEST(CapabilitySet, ConstructSingleMemberMinOverflow) {
547   // Check the first one that forces overflow beyond the mask.
548   CapabilitySet s(static_cast<spv::Capability>(64));
549   EXPECT_FALSE(s.contains(spv::Capability::Matrix));
550   EXPECT_FALSE(s.contains(spv::Capability::Shader));
551   EXPECT_FALSE(s.contains(static_cast<spv::Capability>(63)));
552   EXPECT_TRUE(s.contains(static_cast<spv::Capability>(64)));
553   EXPECT_FALSE(s.contains(static_cast<spv::Capability>(1000)));
554 }
555 
TEST(CapabilitySet,ConstructSingleMemberMaxOverflow)556 TEST(CapabilitySet, ConstructSingleMemberMaxOverflow) {
557   // Check the max 32-bit signed int.
558   CapabilitySet s(static_cast<spv::Capability>(0x7fffffffu));
559   EXPECT_FALSE(s.contains(spv::Capability::Matrix));
560   EXPECT_FALSE(s.contains(spv::Capability::Shader));
561   EXPECT_FALSE(s.contains(static_cast<spv::Capability>(1000)));
562   EXPECT_TRUE(s.contains(static_cast<spv::Capability>(0x7fffffffu)));
563 }
564 
TEST(CapabilitySet,AddEnum)565 TEST(CapabilitySet, AddEnum) {
566   CapabilitySet s(spv::Capability::Shader);
567   s.insert(spv::Capability::Kernel);
568   s.insert(static_cast<spv::Capability>(42));
569   EXPECT_FALSE(s.contains(spv::Capability::Matrix));
570   EXPECT_TRUE(s.contains(spv::Capability::Shader));
571   EXPECT_TRUE(s.contains(spv::Capability::Kernel));
572   EXPECT_TRUE(s.contains(static_cast<spv::Capability>(42)));
573 }
574 
TEST(CapabilitySet,InsertReturnsIteratorToInserted)575 TEST(CapabilitySet, InsertReturnsIteratorToInserted) {
576   CapabilitySet set;
577 
578   auto[it, inserted] = set.insert(spv::Capability::Kernel);
579 
580   EXPECT_TRUE(inserted);
581   EXPECT_EQ(*it, spv::Capability::Kernel);
582 }
583 
TEST(CapabilitySet,InsertReturnsIteratorToElementOnDoubleInsertion)584 TEST(CapabilitySet, InsertReturnsIteratorToElementOnDoubleInsertion) {
585   CapabilitySet set;
586   EXPECT_FALSE(set.contains(spv::Capability::Shader));
587   {
588     auto[it, inserted] = set.insert(spv::Capability::Shader);
589     EXPECT_TRUE(inserted);
590     EXPECT_EQ(*it, spv::Capability::Shader);
591   }
592   EXPECT_TRUE(set.contains(spv::Capability::Shader));
593 
594   auto[it, inserted] = set.insert(spv::Capability::Shader);
595 
596   EXPECT_FALSE(inserted);
597   EXPECT_EQ(*it, spv::Capability::Shader);
598   EXPECT_TRUE(set.contains(spv::Capability::Shader));
599 }
600 
TEST(CapabilitySet,InsertWithHintWorks)601 TEST(CapabilitySet, InsertWithHintWorks) {
602   CapabilitySet set;
603   EXPECT_FALSE(set.contains(spv::Capability::Shader));
604 
605   auto it = set.insert(set.begin(), spv::Capability::Shader);
606 
607   EXPECT_EQ(*it, spv::Capability::Shader);
608   EXPECT_TRUE(set.contains(spv::Capability::Shader));
609 }
610 
TEST(CapabilitySet,InsertWithEndHintWorks)611 TEST(CapabilitySet, InsertWithEndHintWorks) {
612   CapabilitySet set;
613   EXPECT_FALSE(set.contains(spv::Capability::Shader));
614 
615   auto it = set.insert(set.end(), spv::Capability::Shader);
616 
617   EXPECT_EQ(*it, spv::Capability::Shader);
618   EXPECT_TRUE(set.contains(spv::Capability::Shader));
619 }
620 
TEST(CapabilitySet,IteratorCanBeCopied)621 TEST(CapabilitySet, IteratorCanBeCopied) {
622   CapabilitySet set;
623   set.insert(spv::Capability::Matrix);
624   set.insert(spv::Capability::Shader);
625   set.insert(spv::Capability::Geometry);
626   set.insert(spv::Capability::Float64);
627   set.insert(spv::Capability::Float16);
628 
629   auto a = set.begin();
630   ++a;
631   auto b = a;
632 
633   EXPECT_EQ(*b, *a);
634   ++b;
635   EXPECT_NE(*b, *a);
636 
637   ++a;
638   EXPECT_EQ(*b, *a);
639 
640   ++a;
641   EXPECT_NE(*b, *a);
642 }
643 
TEST(CapabilitySet,IteratorBeginToEndPostfix)644 TEST(CapabilitySet, IteratorBeginToEndPostfix) {
645   auto orderedValues = enumerateValuesFromToWithStep(0, 100, /* step= */ 1);
646   auto set = createSetUnorderedInsertion(orderedValues);
647 
648   size_t index = 0;
649   for (auto it = set.cbegin(); it != set.cend(); it++, index++) {
650     EXPECT_EQ(*it, orderedValues[index]);
651   }
652 }
653 
TEST(CapabilitySet,IteratorBeginToEndPrefix)654 TEST(CapabilitySet, IteratorBeginToEndPrefix) {
655   auto orderedValues = enumerateValuesFromToWithStep(0, 100, /* step= */ 1);
656   auto set = createSetUnorderedInsertion(orderedValues);
657 
658   size_t index = 0;
659   for (auto it = set.cbegin(); it != set.cend(); ++it, index++) {
660     EXPECT_EQ(*it, orderedValues[index]);
661   }
662 }
663 
TEST(CapabilitySet,IteratorBeginToEndPrefixStep)664 TEST(CapabilitySet, IteratorBeginToEndPrefixStep) {
665   auto orderedValues = enumerateValuesFromToWithStep(0, 100, /* step= */ 8);
666   auto set = createSetUnorderedInsertion(orderedValues);
667 
668   size_t index = 0;
669   for (auto it = set.cbegin(); it != set.cend(); ++it, index++) {
670     ASSERT_EQ(*it, orderedValues[index]);
671   }
672 }
673 
TEST(CapabilitySet,IteratorBeginOnEmpty)674 TEST(CapabilitySet, IteratorBeginOnEmpty) {
675   CapabilitySet set;
676 
677   auto begin = set.begin();
678   auto end = set.end();
679   ASSERT_EQ(begin, end);
680 }
681 
TEST(CapabilitySet,IteratorBeginOnSingleNonZeroValue)682 TEST(CapabilitySet, IteratorBeginOnSingleNonZeroValue) {
683   CapabilitySet set;
684   set.insert(spv::Capability::Shader);
685 
686   auto begin = set.begin();
687   auto end = set.end();
688 
689   ASSERT_NE(begin, end);
690   ASSERT_EQ(*begin, spv::Capability::Shader);
691 }
692 
TEST(CapabilitySet,IteratorForLoopNonZeroValue)693 TEST(CapabilitySet, IteratorForLoopNonZeroValue) {
694   CapabilitySet set;
695   set.insert(spv::Capability::Shader);
696   set.insert(spv::Capability::Tessellation);
697 
698   auto begin = set.begin();
699   auto end = set.end();
700 
701   ASSERT_NE(begin, end);
702   ASSERT_EQ(*begin, spv::Capability::Shader);
703 
704   begin++;
705   ASSERT_NE(begin, end);
706   ASSERT_EQ(*begin, spv::Capability::Tessellation);
707 
708   begin++;
709   ASSERT_EQ(begin, end);
710 }
711 
TEST(CapabilitySet,IteratorPastEnd)712 TEST(CapabilitySet, IteratorPastEnd) {
713   CapabilitySet set;
714   set.insert(spv::Capability::Shader);
715 
716   auto begin = set.begin();
717   auto end = set.end();
718 
719   ASSERT_NE(begin, end);
720   ASSERT_EQ(*begin, spv::Capability::Shader);
721 
722   begin++;
723   ASSERT_EQ(begin, end);
724 
725   begin++;
726   ASSERT_EQ(begin, end);
727 }
728 
TEST(CapabilitySet,CompatibleWithSTLFind)729 TEST(CapabilitySet, CompatibleWithSTLFind) {
730   CapabilitySet set;
731   set.insert(spv::Capability::Matrix);
732   set.insert(spv::Capability::Shader);
733   set.insert(spv::Capability::Geometry);
734   set.insert(spv::Capability::Tessellation);
735   set.insert(spv::Capability::Addresses);
736   set.insert(spv::Capability::Linkage);
737   set.insert(spv::Capability::Kernel);
738   set.insert(spv::Capability::Vector16);
739   set.insert(spv::Capability::Float16Buffer);
740   set.insert(spv::Capability::Float64);
741 
742   {
743     auto it = std::find(set.cbegin(), set.cend(), spv::Capability::Vector16);
744     ASSERT_NE(it, set.end());
745     ASSERT_EQ(*it, spv::Capability::Vector16);
746   }
747 
748   {
749     auto it = std::find(set.cbegin(), set.cend(), spv::Capability::Float16);
750     ASSERT_EQ(it, set.end());
751   }
752 }
753 
TEST(CapabilitySet,CompatibleWithSTLForEach)754 TEST(CapabilitySet, CompatibleWithSTLForEach) {
755   auto orderedValues = enumerateValuesFromToWithStep(0, 100, /* step= */ 15);
756   auto set = createSetUnorderedInsertion(orderedValues);
757 
758   size_t index = 0;
759   std::for_each(set.cbegin(), set.cend(), [&](auto item) {
760     ASSERT_EQ(item, orderedValues[index]);
761     index++;
762   });
763 }
764 
TEST(CapabilitySet,InitializerListEmpty)765 TEST(CapabilitySet, InitializerListEmpty) {
766   CapabilitySet s{};
767   for (uint32_t i = 0; i < 1000; i++) {
768     EXPECT_FALSE(s.contains(static_cast<spv::Capability>(i)));
769   }
770 }
771 
TEST(CapabilitySet,LargeSetHasInsertedElements)772 TEST(CapabilitySet, LargeSetHasInsertedElements) {
773   CapabilitySet set;
774   for (auto c : kCapabilities) {
775     EXPECT_FALSE(set.contains(c));
776   }
777 
778   for (auto c : kCapabilities) {
779     set.insert(c);
780     EXPECT_TRUE(set.contains(c));
781   }
782 
783   for (auto c : kCapabilities) {
784     EXPECT_TRUE(set.contains(c));
785   }
786 }
787 
TEST(CapabilitySet,LargeSetHasUnsortedInsertedElements)788 TEST(CapabilitySet, LargeSetHasUnsortedInsertedElements) {
789   std::vector shuffledCapabilities(kCapabilities.cbegin(),
790                                    kCapabilities.cend());
791   std::mt19937 rng(0);
792   std::shuffle(shuffledCapabilities.begin(), shuffledCapabilities.end(), rng);
793   CapabilitySet set;
794   for (auto c : shuffledCapabilities) {
795     EXPECT_FALSE(set.contains(c));
796   }
797 
798   for (auto c : shuffledCapabilities) {
799     set.insert(c);
800     EXPECT_TRUE(set.contains(c));
801   }
802 
803   for (auto c : shuffledCapabilities) {
804     EXPECT_TRUE(set.contains(c));
805   }
806 }
807 
TEST(CapabilitySet,LargeSetHasUnsortedRemovedElement)808 TEST(CapabilitySet, LargeSetHasUnsortedRemovedElement) {
809   std::vector shuffledCapabilities(kCapabilities.cbegin(),
810                                    kCapabilities.cend());
811   std::mt19937 rng(0);
812   std::shuffle(shuffledCapabilities.begin(), shuffledCapabilities.end(), rng);
813   CapabilitySet set;
814   for (auto c : shuffledCapabilities) {
815     set.insert(c);
816     EXPECT_TRUE(set.contains(c));
817   }
818 
819   for (auto c : kCapabilities) {
820     set.erase(c);
821   }
822 
823   for (auto c : shuffledCapabilities) {
824     EXPECT_FALSE(set.contains(c));
825   }
826 }
827 
828 struct ForEachCase {
829   CapabilitySet capabilities;
830   std::vector<spv::Capability> expected;
831 };
832 
833 using CapabilitySetForEachTest = ::testing::TestWithParam<ForEachCase>;
834 
TEST_P(CapabilitySetForEachTest,CallsAsExpected)835 TEST_P(CapabilitySetForEachTest, CallsAsExpected) {
836   EXPECT_THAT(ElementsIn(GetParam().capabilities), Eq(GetParam().expected));
837 }
838 
TEST_P(CapabilitySetForEachTest,CopyConstructor)839 TEST_P(CapabilitySetForEachTest, CopyConstructor) {
840   CapabilitySet copy(GetParam().capabilities);
841   EXPECT_THAT(ElementsIn(copy), Eq(GetParam().expected));
842 }
843 
TEST_P(CapabilitySetForEachTest,MoveConstructor)844 TEST_P(CapabilitySetForEachTest, MoveConstructor) {
845   // We need a writable copy to move from.
846   CapabilitySet copy(GetParam().capabilities);
847   CapabilitySet moved(std::move(copy));
848   EXPECT_THAT(ElementsIn(moved), Eq(GetParam().expected));
849 
850   // The moved-from set is empty.
851   EXPECT_THAT(ElementsIn(copy), Eq(std::vector<spv::Capability>{}));
852 }
853 
TEST_P(CapabilitySetForEachTest,OperatorEquals)854 TEST_P(CapabilitySetForEachTest, OperatorEquals) {
855   CapabilitySet assigned = GetParam().capabilities;
856   EXPECT_THAT(ElementsIn(assigned), Eq(GetParam().expected));
857 }
858 
TEST_P(CapabilitySetForEachTest,OperatorEqualsSelfAssign)859 TEST_P(CapabilitySetForEachTest, OperatorEqualsSelfAssign) {
860   CapabilitySet assigned{GetParam().capabilities};
861   assigned = assigned;
862   EXPECT_THAT(ElementsIn(assigned), Eq(GetParam().expected));
863 }
864 
865 INSTANTIATE_TEST_SUITE_P(
866     Samples, CapabilitySetForEachTest,
867     ValuesIn(std::vector<ForEachCase>{
868         {{}, {}},
869         {{spv::Capability::Matrix}, {spv::Capability::Matrix}},
870         {{spv::Capability::Kernel, spv::Capability::Shader},
871          {spv::Capability::Shader, spv::Capability::Kernel}},
872         {{static_cast<spv::Capability>(999)},
873          {static_cast<spv::Capability>(999)}},
874         {{static_cast<spv::Capability>(0x7fffffff)},
875          {static_cast<spv::Capability>(0x7fffffff)}},
876         // Mixture and out of order
877         {{static_cast<spv::Capability>(0x7fffffff),
878           static_cast<spv::Capability>(100), spv::Capability::Shader,
879           spv::Capability::Matrix},
880          {spv::Capability::Matrix, spv::Capability::Shader,
881           static_cast<spv::Capability>(100),
882           static_cast<spv::Capability>(0x7fffffff)}},
883     }));
884 
885 using BoundaryTestWithParam = ::testing::TestWithParam<spv::Capability>;
886 
TEST_P(BoundaryTestWithParam,InsertedContains)887 TEST_P(BoundaryTestWithParam, InsertedContains) {
888   CapabilitySet set;
889   set.insert(GetParam());
890   EXPECT_TRUE(set.contains(GetParam()));
891 }
892 
893 INSTANTIATE_TEST_SUITE_P(
894     Samples, BoundaryTestWithParam,
895     Values(static_cast<spv::Capability>(0), static_cast<spv::Capability>(63),
896            static_cast<spv::Capability>(64), static_cast<spv::Capability>(65),
897            static_cast<spv::Capability>(127), static_cast<spv::Capability>(128),
898            static_cast<spv::Capability>(129)));
899 
900 }  // namespace
901 }  // namespace spvtools
902