1 // Copyright 2017 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "brillo/enum_flags.h" 6 7 #include <gtest/gtest.h> 8 9 namespace brillo { 10 11 class EnumFlagsTest : public testing::Test {}; 12 13 enum SomeFlagsEnum /* : int */ { 14 FLAG_NONE = 0, 15 FLAG_ONE = 1, 16 FLAG_TWO = 2, 17 FLAG_THREE = 4, 18 }; 19 20 enum class SomeFlagsEnumClass /* : int */ { 21 NONE = 0, 22 ONE = 1, 23 TWO = 2, 24 THREE = 4, 25 }; 26 27 enum SomeBigFlagsEnum : int64_t { 28 BIG_FLAG_NONE = 0, 29 BIG_FLAG_ONE = 1, 30 BIG_FLAG_TWO = 2, 31 BIG_FLAG_THREE = 4, 32 BIG_FLAG_FOUR = 8, 33 }; 34 35 DECLARE_FLAGS_ENUM(SomeFlagsEnum); 36 DECLARE_FLAGS_ENUM(SomeFlagsEnumClass); 37 DECLARE_FLAGS_ENUM(SomeBigFlagsEnum); 38 39 // These first tests show how these operators are meant to be used. 40 41 TEST_F(EnumFlagsTest, SampleUsage) { 42 SomeFlagsEnum value = FLAG_NONE; 43 44 // Set a flag. 45 value |= FLAG_ONE; 46 EXPECT_EQ(FLAG_ONE, value); 47 48 // Set another 49 value |= FLAG_THREE; 50 EXPECT_EQ(FLAG_ONE | FLAG_THREE, value); 51 52 // Clear a flag 53 value &= ~FLAG_ONE; 54 EXPECT_EQ(FLAG_THREE, value); 55 56 // Toggle a flag 57 value ^= FLAG_TWO; 58 EXPECT_EQ(FLAG_THREE | FLAG_TWO, value); 59 } 60 61 TEST_F(EnumFlagsTest, SampleUsageOfMasks) { 62 SomeFlagsEnum flags = FLAG_ONE | FLAG_THREE; 63 64 EXPECT_TRUE(flags & FLAG_ONE); 65 EXPECT_TRUE(flags & FLAG_THREE); 66 EXPECT_FALSE(flags & FLAG_TWO); 67 EXPECT_TRUE(flags & ~FLAG_TWO); 68 } 69 70 TEST_F(EnumFlagsTest, SampleUsageWithEnumClass) { 71 SomeFlagsEnumClass value = SomeFlagsEnumClass::NONE; 72 73 // Set a flag. 74 value |= SomeFlagsEnumClass::ONE; 75 EXPECT_EQ(SomeFlagsEnumClass::ONE, value); 76 77 // Set another 78 value |= SomeFlagsEnumClass::THREE; 79 EXPECT_EQ(SomeFlagsEnumClass::ONE | SomeFlagsEnumClass::THREE, value); 80 81 // Clear a flag 82 value &= ~SomeFlagsEnumClass::ONE; 83 EXPECT_EQ(SomeFlagsEnumClass::THREE, value); 84 85 // Toggle a flag 86 value ^= SomeFlagsEnumClass::TWO; 87 EXPECT_EQ(SomeFlagsEnumClass::THREE | SomeFlagsEnumClass::TWO, value); 88 } 89 90 TEST_F(EnumFlagsTest, SampleUsageWithBigEnumType) { 91 SomeBigFlagsEnum value = BIG_FLAG_NONE; 92 93 // Set a flag. 94 value |= BIG_FLAG_ONE; 95 EXPECT_EQ(BIG_FLAG_ONE, value); 96 97 // Set another 98 value |= BIG_FLAG_THREE; 99 EXPECT_EQ(FLAG_ONE | BIG_FLAG_THREE, value); 100 101 // Clear a flag 102 value &= ~BIG_FLAG_ONE; 103 EXPECT_EQ(BIG_FLAG_THREE, value); 104 105 // Toggle a flag 106 value ^= BIG_FLAG_TWO; 107 EXPECT_EQ(BIG_FLAG_THREE | BIG_FLAG_TWO, value); 108 } 109 110 // These following tests verify the binary behavior of the operators. They do 111 // not demonstrate standard usage. 112 113 TEST_F(EnumFlagsTest, BinaryBehaviorOfAssignmentOperators) { 114 SomeFlagsEnum value = FLAG_NONE; 115 116 // Set a flag. 117 value |= FLAG_ONE; 118 EXPECT_EQ(1, value); 119 120 // Set another 121 value |= FLAG_THREE; 122 EXPECT_EQ(5, value); 123 124 // Clear a flag 125 value &= ~FLAG_ONE; 126 EXPECT_EQ(4, value); 127 128 // Toggle a flag 129 value ^= FLAG_TWO; 130 EXPECT_EQ(6, value); 131 } 132 133 TEST_F(EnumFlagsTest, BinaryBehaviorOfAssignmentOperatorsWithEnumClass) { 134 SomeFlagsEnumClass value = SomeFlagsEnumClass::NONE; 135 136 // Set a flag. 137 value |= SomeFlagsEnumClass::ONE; 138 EXPECT_EQ(1, static_cast<int>(value)); // 139 140 // Set another 141 value |= SomeFlagsEnumClass::THREE; 142 EXPECT_EQ(5, static_cast<int>(value)); 143 144 // Clear a flag 145 value &= ~SomeFlagsEnumClass::ONE; 146 EXPECT_EQ(4, static_cast<int>(value)); 147 148 // Toggle a flag 149 value ^= SomeFlagsEnumClass::TWO; 150 EXPECT_EQ(6, static_cast<int>(value)); 151 } 152 153 TEST_F(EnumFlagsTest, BinaryBehaviorOfSimpleOperations) { 154 // These values are set directly with a cast for clarity. 155 const int all_bits_int = -1; 156 const SomeFlagsEnum all_bits = static_cast<SomeFlagsEnum>(all_bits_int); 157 const SomeFlagsEnum just_2_bits = static_cast<SomeFlagsEnum>(3); 158 159 // Inverting a flag should result in all bits set in the base type but that 160 // one. 161 EXPECT_EQ(-2, ~FLAG_ONE); 162 EXPECT_EQ(-3, ~FLAG_TWO); 163 164 // OR'ing two flags should result in both being set. 165 EXPECT_EQ(3, FLAG_ONE | FLAG_TWO); 166 167 // AND'ing two flags should result in 0. 168 EXPECT_EQ(FLAG_NONE, FLAG_ONE & FLAG_TWO); 169 170 // AND'ing a mask with a flag should result in that flag. 171 EXPECT_EQ(FLAG_ONE, all_bits & FLAG_ONE); 172 173 // XOR'ing two flags should result in both being set. 174 EXPECT_EQ(3, FLAG_ONE ^ FLAG_TWO); 175 176 // XOR'ing a mask with a flag should toggle that flag in the mask. 177 EXPECT_EQ(FLAG_ONE, FLAG_NONE ^ FLAG_ONE); 178 EXPECT_EQ(FLAG_TWO, just_2_bits ^ FLAG_ONE); 179 } 180 181 TEST_F(EnumFlagsTest, BinaryBehaviorOfSimpleOperationsOnEnumClass) { 182 // These values are set directly with a cast for clarity. 183 const int all_bits_int = -1; 184 const SomeFlagsEnumClass all_bits = 185 static_cast<SomeFlagsEnumClass>(all_bits_int); 186 const SomeFlagsEnumClass just_2_bits = static_cast<SomeFlagsEnumClass>(3); 187 188 // Inverting a flag should result in all bits set in the base type but that 189 // one. 190 EXPECT_EQ(-2, static_cast<int>(~SomeFlagsEnumClass::ONE)); 191 EXPECT_EQ(-3, static_cast<int>(~SomeFlagsEnumClass::TWO)); 192 193 // OR'ing two flags should result in both being set. 194 EXPECT_EQ( 195 3, static_cast<int>(SomeFlagsEnumClass::ONE | SomeFlagsEnumClass::TWO)); 196 197 // AND'ing two flags should result in 0. 198 EXPECT_EQ(SomeFlagsEnumClass::NONE, 199 SomeFlagsEnumClass::ONE & SomeFlagsEnumClass::TWO); 200 201 // AND'ing a mask with a flag should result in that flag. 202 EXPECT_EQ(SomeFlagsEnumClass::ONE, all_bits & SomeFlagsEnumClass::ONE); 203 204 // XOR'ing two flags should result in both being set. 205 EXPECT_EQ( 206 3, static_cast<int>(SomeFlagsEnumClass::ONE ^ SomeFlagsEnumClass::TWO)); 207 208 // XOR'ing a mask with a flag should toggle that flag in the mask. 209 EXPECT_EQ(SomeFlagsEnumClass::ONE, 210 SomeFlagsEnumClass::NONE ^ SomeFlagsEnumClass::ONE); 211 EXPECT_EQ(SomeFlagsEnumClass::TWO, just_2_bits ^ SomeFlagsEnumClass::ONE); 212 } 213 214 TEST_F(EnumFlagsTest, BinaryBehaviorOfSimpleOperationsWithBaseType) { 215 // These values are set directly with a cast for clarity. 216 const int64_t all_bits_int = -1; 217 const SomeBigFlagsEnum all_bits = static_cast<SomeBigFlagsEnum>(all_bits_int); 218 const SomeBigFlagsEnum just_2_bits = static_cast<SomeBigFlagsEnum>(3); 219 220 // Inverting a flag should result in all bits set in the base type but that 221 // one. 222 EXPECT_EQ(all_bits ^ BIG_FLAG_ONE, ~BIG_FLAG_ONE); 223 224 // OR'ing two flags should result in both being set. 225 EXPECT_EQ(3, BIG_FLAG_ONE | BIG_FLAG_TWO); 226 227 // AND'ing two flags should result in 0. 228 EXPECT_EQ(BIG_FLAG_NONE, BIG_FLAG_ONE & BIG_FLAG_TWO); 229 230 // AND'ing a mask with a flag should result in that flag. 231 EXPECT_EQ(BIG_FLAG_ONE, all_bits & BIG_FLAG_ONE); 232 233 // XOR'ing two flags should result in both being set. 234 EXPECT_EQ(3, BIG_FLAG_ONE ^ BIG_FLAG_TWO); 235 236 // XOR'ing a mask with a flag should toggle that flag in the mask. 237 EXPECT_EQ(BIG_FLAG_ONE, BIG_FLAG_NONE ^ BIG_FLAG_ONE); 238 EXPECT_EQ(BIG_FLAG_TWO, just_2_bits ^ BIG_FLAG_ONE); 239 } 240 241 } // namespace brillo 242