enums.cpp (2809B)
1 #include <doctest/doctest.h> 2 3 // GCC < 5 breaks when trying to compare enums to integers when using std headers. 4 #if !defined(DOCTEST_CONFIG_USE_STD_HEADERS) || DOCTEST_GCC == 0 || DOCTEST_GCC >= DOCTEST_COMPILER(5, 0, 0) 5 #define RET_TYPE(x) x 6 #else 7 #define RET_TYPE(x) typename doctest::detail::types::underlying_type<x>::type 8 #endif 9 10 template <typename S> 11 static RET_TYPE(S) castToUnderlying(S in) { 12 return in; 13 } 14 15 #include "header.h" 16 17 DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN 18 #include <cstdint> 19 #include <sstream> 20 DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END 21 22 namespace 23 { 24 25 enum StandardEnum 26 { 27 Zero, 28 One, 29 Two, 30 }; 31 32 enum TypedEnum : int64_t 33 { 34 TypedZero, 35 TypedOne, 36 TypedTwo, 37 }; 38 39 enum class EnumClassC : char 40 { 41 Zero = '0', 42 One = '1', 43 Two = '2', 44 }; 45 46 enum class EnumClassSC : signed char 47 { 48 Zero = '0', 49 One = '1', 50 Two = '2', 51 }; 52 53 enum class EnumClassUC : unsigned char 54 { 55 Zero = '0', 56 One = '1', 57 Two = '2', 58 }; 59 60 enum class EnumClassU8 : uint8_t 61 { 62 Zero, 63 One, 64 Two, 65 }; 66 67 template<class E, class T = typename std::underlying_type<E>::type> 68 T printable(E val) 69 { 70 return static_cast<T>(val); 71 } 72 73 } 74 75 TEST_CASE("enum 1") 76 { 77 std::ostringstream ostr; 78 ostr << Zero << One << Two; 79 ostr << TypedZero << TypedOne << TypedTwo; 80 static_assert(std::is_enum<EnumClassSC>::value, ""); 81 ostr << printable(EnumClassSC::Zero) << printable(EnumClassSC::One) << printable(EnumClassSC::Two); 82 83 CHECK_EQ(castToUnderlying(Zero), 0); 84 CHECK_EQ(castToUnderlying(One), 1); 85 CHECK_EQ(castToUnderlying(Two), 2); 86 87 CHECK_EQ(castToUnderlying(TypedZero), 0); 88 CHECK_EQ(castToUnderlying(TypedOne), 1); 89 CHECK_EQ(castToUnderlying(TypedTwo), 2); 90 91 CHECK_EQ(EnumClassSC::Zero, EnumClassSC::Zero); 92 CHECK_EQ(EnumClassSC::One, EnumClassSC::One); 93 CHECK_EQ(EnumClassSC::Two, EnumClassSC::Two); 94 } 95 96 TEST_CASE("enum 2" * doctest::should_fail()) 97 { 98 CHECK_EQ(castToUnderlying(Zero), 1); 99 CHECK_EQ(castToUnderlying(One), 2); 100 CHECK_EQ(castToUnderlying(Two), 3); 101 102 CHECK_EQ(castToUnderlying(TypedZero), 1); 103 CHECK_EQ(castToUnderlying(TypedOne), 2); 104 CHECK_EQ(castToUnderlying(TypedTwo), 3); 105 106 CHECK_EQ(EnumClassC::Zero, EnumClassC::One); 107 CHECK_EQ(EnumClassC::One, EnumClassC::Two); 108 CHECK_EQ(EnumClassC::Two, EnumClassC::Zero); 109 110 CHECK_EQ(EnumClassSC::Zero, EnumClassSC::One); 111 CHECK_EQ(EnumClassSC::One, EnumClassSC::Two); 112 CHECK_EQ(EnumClassSC::Two, EnumClassSC::Zero); 113 114 CHECK_EQ(EnumClassUC::Zero, EnumClassUC::One); 115 CHECK_EQ(EnumClassUC::One, EnumClassUC::Two); 116 CHECK_EQ(EnumClassUC::Two, EnumClassUC::Zero); 117 118 CHECK_EQ(EnumClassU8::Zero, EnumClassU8::One); 119 CHECK_EQ(EnumClassU8::One, EnumClassU8::Two); 120 CHECK_EQ(EnumClassU8::Two, EnumClassU8::Zero); 121 }