diff --git a/enum.h b/enum.h index d1f61d3..bbbcde0 100644 --- a/enum.h +++ b/enum.h @@ -597,6 +597,8 @@ struct _Base { \ \ enum { __VA_ARGS__ }; \ \ +enum class _Case : Integral { __VA_ARGS__ }; \ + \ constexpr const _Base _value_array[] = \ { _ENUM_EAT_ASSIGN(_Base, __VA_ARGS__) }; \ \ @@ -618,19 +620,6 @@ constexpr const _Iterable _names{_name_array, _size}; \ #define _ENUM_NS(EnumType) _enum::_data_ ## EnumType -#ifndef BETTER_ENUMS_SAFER_SWITCH - -#define _ENUM_CONVERSION_FOR_SWITCH(Integral, ...) \ - constexpr operator _Enumerated() const { return _value; } - -#else - -#define _ENUM_CONVERSION_FOR_SWITCH(Integral, ...) \ - enum class _Case : Integral { __VA_ARGS__ }; \ - constexpr operator _Case() const { return (_Case)_value; } - -#endif // #ifndef BETTER_ENUMS_SAFER_SWITCH - #define _ENUM_TYPE(EnumType, Integral, ...) \ class EnumType : public _ENUM_NS(EnumType)::_Base { \ protected: \ @@ -727,7 +716,10 @@ class EnumType : public _ENUM_NS(EnumType)::_Base { \ return _from_string_nocase_loop(name); \ } \ \ - _ENUM_CONVERSION_FOR_SWITCH(Integral, __VA_ARGS__); \ + constexpr operator _ENUM_NS(EnumType)::_Case() const \ + { \ + return (_ENUM_NS(EnumType)::_Case)_value; \ + } \ \ constexpr static auto &_values = _ENUM_NS(EnumType)::_values; \ constexpr static auto &_names = _ENUM_NS(EnumType)::_names; \ diff --git a/example/3-switch.cc b/example/3-switch.cc index 7913b5b..dbab9f4 100644 --- a/example/3-switch.cc +++ b/example/3-switch.cc @@ -10,15 +10,15 @@ void respond_to_channel(Channel channel) // Try adding an extra case or removing one. Your compiler should issue a // warning. switch (channel) { - case Channel::Red: + case +Channel::Red: std::cout << "red channel" << std::endl; break; - case Channel::Green: + case +Channel::Green: std::cout << "green channel" << std::endl; break; - case Channel::Blue: + case +Channel::Blue: std::cout << "blue channel" << std::endl; break; diff --git a/example/7-bitset.cc b/example/7-bitset.cc index e643466..e1a35af 100644 --- a/example/7-bitset.cc +++ b/example/7-bitset.cc @@ -10,7 +10,7 @@ constexpr Enum maximum(Enum accumulator = Enum::_values[0], size_t index = 1) { return index >= Enum::_size ? accumulator : - Enum::_values[index] > accumulator ? + +Enum::_values[index] > accumulator ? maximum(+Enum::_values[index], index + 1) : maximum(accumulator, index + 1); } @@ -19,7 +19,7 @@ ENUM(Channel, int, Red, Green, Blue); int main() { - using ChannelSet = std::bitset() + 1>; + using ChannelSet = std::bitset().to_integral() + 1>; ChannelSet red_only; red_only.set(Channel::Red); @@ -33,7 +33,7 @@ int main() std::cout << channel.to_string() << " bit is set to " - << red_and_blue[channel] + << red_and_blue[channel.to_integral()] << std::endl; } diff --git a/test/cxxtest/tests.h b/test/cxxtest/tests.h index d691d35..7b96ef4 100644 --- a/test/cxxtest/tests.h +++ b/test/cxxtest/tests.h @@ -56,13 +56,21 @@ static_assert_1(!(std::is_constructible())); // Intended implicit conversions. static_assert_1((std::is_convertible())); -static_assert_1(!(std::is_convertible())); -static_assert_1(!(std::is_convertible())); -static_assert_1(!(std::is_convertible())); // Regrettable implicit conversions. -static_assert_1((std::is_convertible())); -static_assert_1((std::is_convertible())); +static_assert_1((std::is_convertible())); + +// Disallowed implicit conversions. +static_assert_1(!(std::is_convertible())); +static_assert_1(!(std::is_convertible())); +static_assert_1(!(std::is_convertible())); +static_assert_1(!(std::is_convertible())); +static_assert_1(!(std::is_convertible())); +static_assert_1(!(std::is_convertible())); +static_assert_1(!(std::is_convertible()));