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
TEST(BitmaskEnumTest,BitwiseOr)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
TEST(BitmaskEnumTest,BitwiseOrEquals)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
TEST(BitmaskEnumTest,BitwiseAnd)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
TEST(BitmaskEnumTest,BitwiseAndEquals)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
TEST(BitmaskEnumTest,BitwiseXor)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
TEST(BitmaskEnumTest,BitwiseXorEquals)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
TEST(BitmaskEnumTest,ConstantExpression)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
TEST(BitmaskEnumTest,BitwiseNot)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
TEST(BitmaskEnumTest,ScopedEnum)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
getFlags__anone88cb0570211::Container134 static Flags getFlags() {
135 Flags f = F0 | F1;
136 f |= F2;
137 return f;
138 }
139 };
140
TEST(BitmaskEnumTest,EnumInStruct)141 TEST(BitmaskEnumTest, EnumInStruct) { EXPECT_EQ(3, Container::getFlags()); }
142
143 } // namespace
144