From aa34aad468dad87dfef82fd079577535bf23a9fe Mon Sep 17 00:00:00 2001 From: Anton Bachin Date: Mon, 15 Jun 2015 19:04:16 -0500 Subject: [PATCH] Simplified underlying type traits. Removed the function are_equal. Comparison is now done by converting operands to their integral representation, and comparing those. Also restored ordering of enum values along the same lines (according to integral representation). --- enum.h | 32 +++++++++++++++----------------- test/cxxtest/underlying.h | 31 +++++++++++++++++++++++++++---- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/enum.h b/enum.h index 848e27b..2863a06 100644 --- a/enum.h +++ b/enum.h @@ -506,8 +506,6 @@ struct underlying_traits { to_integral(const T &v) { return (integral_representation)v; } BETTER_ENUMS__CONSTEXPR static T from_integral(integral_representation n) { return T(n); } - BETTER_ENUMS__CONSTEXPR static bool - are_equal(const T& u, const T& v) { return u == v; } }; @@ -597,10 +595,8 @@ constexpr const char *_final_ ## index = \ // The enums proper. // TODO Convert integral to underlying only at the last possible moment, if the -// integral value is valid. This should prevent unexpected behavior. For this to -// work, the underlying values array must store the integral equivalents. That -// would also eliminate the need for "are_equal", but would increase overhead -// during iteration. +// integral value is valid. This should prevent unexpected behavior (conversions +// during scans). // TODO Choose the right return type semantics once the _values array // representation is chosen: values if integral, const references if underlying. @@ -876,10 +872,9 @@ Enum::_from_value_loop(const Enum::_underlying &value, std::size_t index) \ { \ return \ index == _size ? _optional_index() : \ - _traits::are_equal( \ - BETTER_ENUMS__NS(Enum)::value_array[index]._value, value) ? \ - _optional_index(index) : \ - _from_value_loop(value, index + 1); \ + _traits::to_integral(BETTER_ENUMS__NS(Enum)::value_array[index]._value)\ + == _traits::to_integral(value) ? _optional_index(index) : \ + _from_value_loop(value, index + 1); \ } \ \ BETTER_ENUMS__CONSTEXPR inline Enum::_optional_index \ @@ -905,14 +900,17 @@ Enum::_from_string_nocase_loop(const char *name, std::size_t index) \ } \ \ BETTER_ENUMS__CONSTEXPR inline bool operator ==(const Enum &a, const Enum &b) \ - { \ - return \ - ::better_enums::underlying_traits \ - ::are_equal(a._value, b._value); \ - } \ - \ + { return a._to_integral() == b._to_integral(); } \ BETTER_ENUMS__CONSTEXPR inline bool operator !=(const Enum &a, const Enum &b) \ - { return !(a == b); } + { return a._to_integral() != b._to_integral(); } \ +BETTER_ENUMS__CONSTEXPR inline bool operator <(const Enum &a, const Enum &b) \ + { return a._to_integral() < b._to_integral(); } \ +BETTER_ENUMS__CONSTEXPR inline bool operator <=(const Enum &a, const Enum &b) \ + { return a._to_integral() <= b._to_integral(); } \ +BETTER_ENUMS__CONSTEXPR inline bool operator >(const Enum &a, const Enum &b) \ + { return a._to_integral() > b._to_integral(); } \ +BETTER_ENUMS__CONSTEXPR inline bool operator >=(const Enum &a, const Enum &b) \ + { return a._to_integral() >= b._to_integral(); } diff --git a/test/cxxtest/underlying.h b/test/cxxtest/underlying.h index 2f95441..8760ed2 100644 --- a/test/cxxtest/underlying.h +++ b/test/cxxtest/underlying.h @@ -31,10 +31,6 @@ struct underlying_traits { BETTER_ENUMS__CONSTEXPR static unsigned int to_integral(html_color_1 v) { return (unsigned int)v.r << 16 | (unsigned int)v.g << 8 | v.b; } - - BETTER_ENUMS__CONSTEXPR static bool - are_equal(const html_color_1 &u, const html_color_1 &v) - { return u.r == v.r && u.g == v.g && u.b == v.b; } }; } @@ -151,4 +147,31 @@ class UnderlyingTypeTests : public CxxTest::TestSuite { TS_ASSERT_EQUALS(color_1->g, color_1_underlying.g); TS_ASSERT_EQUALS(color_1->b, color_1_underlying.b); } + + void test_switch() + { +#ifndef BETTER_ENUMS_STRICT_CONVERSION + + HtmlColor1 html_color_1 = HtmlColor1::purplemimosa; + + switch (html_color_1) { + case HtmlColor1::darksalmon: TS_ASSERT(false); break; + case HtmlColor1::purplemimosa: TS_ASSERT(true); break; + case HtmlColor1::slimegreen: TS_ASSERT(false); break; + } + +#else +# ifdef BETTER_ENUMS__HAVE_CONSTEXPR + + HtmlColor1 html_color_1 = HtmlColor1::purplemimosa; + + switch (html_color_1) { + case +HtmlColor1::darksalmon: TS_ASSERT(false); break; + case +HtmlColor1::purplemimosa: TS_ASSERT(true); break; + case +HtmlColor1::slimegreen: TS_ASSERT(false); break; + } + +# endif +#endif + } };