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