enum_mask_base_test.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "common/enum_mask_base.h"
  5. #include <gtest/gtest.h>
  6. #include "common/raw_string_ostream.h"
  7. namespace Carbon {
  8. namespace {
  9. #define CARBON_TEST_KIND(X) \
  10. X(Beep) \
  11. X(Boop) \
  12. X(Burr)
  13. CARBON_DEFINE_RAW_ENUM_MASK(TestKind, uint8_t) {
  14. CARBON_TEST_KIND(CARBON_RAW_ENUM_MASK_ENUMERATOR)
  15. };
  16. class TestKind : public CARBON_ENUM_MASK_BASE(TestKind) {
  17. public:
  18. CARBON_TEST_KIND(CARBON_ENUM_MASK_CONSTANT_DECL)
  19. using EnumMaskBase::AsInt;
  20. using EnumMaskBase::FromInt;
  21. };
  22. #define CARBON_TEST_KIND_WITH_TYPE(X) \
  23. CARBON_ENUM_MASK_CONSTANT_DEFINITION(TestKind, X)
  24. CARBON_TEST_KIND(CARBON_TEST_KIND_WITH_TYPE)
  25. #undef CARBON_TEST_KIND_WITH_TYPE
  26. CARBON_DEFINE_ENUM_MASK_NAMES(TestKind) {
  27. CARBON_TEST_KIND(CARBON_ENUM_MASK_NAME_STRING)
  28. };
  29. static_assert(sizeof(TestKind) == sizeof(uint8_t),
  30. "Class size doesn't match enum size!");
  31. TEST(EnumMaskBaseTest, Printing) {
  32. RawStringOstream stream;
  33. TestKind kind = TestKind::Beep;
  34. stream << kind;
  35. EXPECT_EQ("Beep", stream.TakeStr());
  36. kind = TestKind::Boop;
  37. stream << kind;
  38. EXPECT_EQ("Boop", stream.TakeStr());
  39. stream << TestKind::Beep;
  40. EXPECT_EQ("Beep", stream.TakeStr());
  41. stream << (TestKind::Beep | TestKind::Burr);
  42. EXPECT_EQ("Beep|Burr", stream.TakeStr());
  43. }
  44. // This just ensures it compiles, it's not validating what's printed.
  45. TEST(EnumMaskBaseTest, PrintToGoogletest) {
  46. EXPECT_TRUE(true) << TestKind::Beep;
  47. }
  48. TEST(EnumMaskBaseTest, Switch) {
  49. TestKind kind = TestKind::Boop;
  50. switch (kind) {
  51. case TestKind::Beep: {
  52. FAIL() << "Beep case selected!";
  53. break;
  54. }
  55. case TestKind::Boop: {
  56. EXPECT_EQ(kind, TestKind::Boop);
  57. break;
  58. }
  59. case TestKind::Burr: {
  60. FAIL() << "Burr case selected!";
  61. break;
  62. }
  63. }
  64. }
  65. TEST(EnumMaskBaseTest, Equality) {
  66. TestKind kind = TestKind::Beep;
  67. // Make sure all the different comparisons work, and also work with
  68. // GoogleTest expectations.
  69. EXPECT_EQ(TestKind::Beep, kind);
  70. EXPECT_NE(TestKind::Boop, kind);
  71. // These should also all be constexpr.
  72. constexpr TestKind Kind2 = TestKind::Beep;
  73. static_assert(Kind2 == TestKind::Beep);
  74. static_assert(Kind2 != TestKind::Boop);
  75. }
  76. TEST(EnumMaskBaseTest, AddRemove) {
  77. TestKind kind = TestKind::Beep;
  78. EXPECT_EQ(kind, TestKind::Beep);
  79. kind.Add(TestKind::Beep);
  80. EXPECT_EQ(kind, TestKind::Beep);
  81. kind.Add(TestKind::Burr);
  82. EXPECT_EQ(kind, TestKind::Beep | TestKind::Burr);
  83. kind.Remove(TestKind::Beep);
  84. EXPECT_EQ(kind, TestKind::Burr);
  85. kind.Remove(TestKind::Beep);
  86. EXPECT_EQ(kind, TestKind::Burr);
  87. kind.Remove(TestKind::Burr);
  88. EXPECT_EQ(kind, TestKind::None);
  89. }
  90. TEST(EnumMaskBaseTest, HasAnyOf) {
  91. static_assert(TestKind::Beep.HasAnyOf(TestKind::Beep));
  92. static_assert(TestKind::Beep.HasAnyOf(TestKind::Beep | TestKind::Burr));
  93. static_assert(!TestKind::Beep.HasAnyOf(TestKind::Burr));
  94. }
  95. TEST(EnumMaskBaseTest, MaskOperations) {
  96. TestKind kind =
  97. TestKind::Beep | (TestKind::Burr & (TestKind::Burr | TestKind::Beep));
  98. EXPECT_EQ(kind, TestKind::Beep | TestKind::Burr);
  99. // These should also all be constexpr.
  100. static_assert((TestKind::Beep & TestKind::Burr) == TestKind::None);
  101. static_assert((TestKind::Beep | TestKind::Burr) != TestKind::None);
  102. static_assert(TestKind::Beep == ~~TestKind::Beep);
  103. }
  104. TEST(EnumMaskBaseTest, IntConversion) {
  105. EXPECT_EQ(1, TestKind::Beep.AsInt());
  106. EXPECT_EQ(2, TestKind::Boop.AsInt());
  107. EXPECT_EQ(4, TestKind::Burr.AsInt());
  108. EXPECT_EQ(TestKind::Beep, TestKind::FromInt(1));
  109. EXPECT_EQ(TestKind::Boop, TestKind::FromInt(2));
  110. EXPECT_EQ(TestKind::Burr, TestKind::FromInt(4));
  111. }
  112. } // namespace
  113. } // namespace Carbon