xref: /llvm-project/compiler-rt/lib/orc/tests/unit/bitmask_enum_test.cpp (revision dbd81ba2e85c2f244f22c983d96a106eae65c06a)
1 //===-- adt_test.cpp ------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file is a part of the ORC runtime.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "bitmask_enum.h"
14 #include "gtest/gtest.h"
15 
16 #include <sstream>
17 #include <string>
18 
19 using namespace orc_rt;
20 
21 namespace {
22 
23 enum Flags { F0 = 0, F1 = 1, F2 = 2, F3 = 4, F4 = 8 };
24 
25 } // namespace
26 
27 namespace orc_rt {
28 ORC_RT_DECLARE_ENUM_AS_BITMASK(Flags, F4);
29 } // namespace orc_rt
30 
31 static_assert(is_bitmask_enum<Flags>::value != 0);
32 static_assert(largest_bitmask_enum_bit<Flags>::value == Flags::F4);
33 
34 namespace {
35 
36 static_assert(is_bitmask_enum<Flags>::value != 0);
37 static_assert(largest_bitmask_enum_bit<Flags>::value == Flags::F4);
38 
39 TEST(BitmaskEnumTest, BitwiseOr) {
40   Flags f = F1 | F2;
41   EXPECT_EQ(3, f);
42 
43   f = f | F3;
44   EXPECT_EQ(7, f);
45 }
46 
47 TEST(BitmaskEnumTest, BitwiseOrEquals) {
48   Flags f = F1;
49   f |= F3;
50   EXPECT_EQ(5, f);
51 
52   // |= should return a reference to the LHS.
53   f = F2;
54   (f |= F3) = F1;
55   EXPECT_EQ(F1, f);
56 }
57 
58 TEST(BitmaskEnumTest, BitwiseAnd) {
59   Flags f = static_cast<Flags>(3) & F2;
60   EXPECT_EQ(F2, f);
61 
62   f = (f | F3) & (F1 | F2 | F3);
63   EXPECT_EQ(6, f);
64 }
65 
66 TEST(BitmaskEnumTest, BitwiseAndEquals) {
67   Flags f = F1 | F2 | F3;
68   f &= F1 | F2;
69   EXPECT_EQ(3, f);
70 
71   // &= should return a reference to the LHS.
72   (f &= F1) = F3;
73   EXPECT_EQ(F3, f);
74 }
75 
76 TEST(BitmaskEnumTest, BitwiseXor) {
77   Flags f = (F1 | F2) ^ (F2 | F3);
78   EXPECT_EQ(5, f);
79 
80   f = f ^ F1;
81   EXPECT_EQ(4, f);
82 }
83 
84 TEST(BitmaskEnumTest, BitwiseXorEquals) {
85   Flags f = (F1 | F2);
86   f ^= (F2 | F4);
87   EXPECT_EQ(9, f);
88 
89   // ^= should return a reference to the LHS.
90   (f ^= F4) = F3;
91   EXPECT_EQ(F3, f);
92 }
93 
94 TEST(BitmaskEnumTest, ConstantExpression) {
95   constexpr Flags f1 = ~F1;
96   constexpr Flags f2 = F1 | F2;
97   constexpr Flags f3 = F1 & F2;
98   constexpr Flags f4 = F1 ^ F2;
99   EXPECT_EQ(f1, ~F1);
100   EXPECT_EQ(f2, F1 | F2);
101   EXPECT_EQ(f3, F1 & F2);
102   EXPECT_EQ(f4, F1 ^ F2);
103 }
104 
105 TEST(BitmaskEnumTest, BitwiseNot) {
106   Flags f = ~F1;
107   EXPECT_EQ(14, f); // Largest value for f is 15.
108   EXPECT_EQ(15, ~F0);
109 }
110 
111 enum class FlagsClass {
112   F0 = 0,
113   F1 = 1,
114   F2 = 2,
115   F3 = 4,
116   ORC_RT_MARK_AS_BITMASK_ENUM(F3)
117 };
118 
119 TEST(BitmaskEnumTest, ScopedEnum) {
120   FlagsClass f = (FlagsClass::F1 & ~FlagsClass::F0) | FlagsClass::F2;
121   f |= FlagsClass::F3;
122   EXPECT_EQ(7, static_cast<int>(f));
123 }
124 
125 struct Container {
126   enum Flags {
127     F0 = 0,
128     F1 = 1,
129     F2 = 2,
130     F3 = 4,
131     ORC_RT_MARK_AS_BITMASK_ENUM(F3)
132   };
133 
134   static Flags getFlags() {
135     Flags f = F0 | F1;
136     f |= F2;
137     return f;
138   }
139 };
140 
141 TEST(BitmaskEnumTest, EnumInStruct) { EXPECT_EQ(3, Container::getFlags()); }
142 
143 } // namespace
144