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).
This commit is contained in:
Anton Bachin 2015-06-15 19:04:16 -05:00
parent a493e90ac4
commit aa34aad468
2 changed files with 42 additions and 21 deletions

32
enum.h
View File

@ -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<Enum::_underlying> \
::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(); }

View File

@ -31,10 +31,6 @@ struct underlying_traits<html_color_1> {
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
}
};