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 | |