types/description: add underlying_comparator for enum descriptions
This commit is contained in:
parent
fd64ca6bce
commit
3866249607
@ -5,7 +5,7 @@
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
enum an_enum_type { AN_ENUM_VALUE };
|
||||
enum an_enum_type : i16 { AN_ENUM_VALUE };
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -55,6 +55,19 @@ int main ()
|
||||
"enums are described as such"
|
||||
);
|
||||
|
||||
{
|
||||
auto const a = cruft::types::make_description<an_enum_type> ();
|
||||
auto const b = cruft::types::make_description<std::underlying_type_t<an_enum_type>> ();
|
||||
|
||||
tap.expect_neq (a, b, "enum and underlying_type_t raw equality");
|
||||
|
||||
cruft::types::underlying_comparator const cmp {};
|
||||
tap.expect (cmp (a, b), "enum and underlying_type equality");
|
||||
|
||||
auto const c = cruft::types::make_description<u32> ();
|
||||
static_assert (!std::is_same_v<u32, std::underlying_type_t<an_enum_type>>);
|
||||
tap.expect (!cmp (a, c), "enum and underlying_type inequality");
|
||||
}
|
||||
|
||||
auto const enum_type_descriptor = cruft::types::make_description<an_enum_type> ();
|
||||
tap.expect (
|
||||
|
@ -132,6 +132,45 @@ namespace cruft::types {
|
||||
}
|
||||
|
||||
|
||||
/// A comparator that compares values as equal if they are an enum and the
|
||||
/// underlying_type of said enum.
|
||||
///
|
||||
/// This is distinct from the raw equality operator so as to not pessimise
|
||||
/// the usability of the equality operator (for tasks that required strict
|
||||
/// equality).
|
||||
struct underlying_comparator {
|
||||
bool operator() (
|
||||
description const &a,
|
||||
description const &b
|
||||
) const noexcept {
|
||||
// If one of the descriptions is ENUM then both need to be either ENUM
|
||||
// or INTEGER (because we try to compare enums and their underlying
|
||||
// types as equal).
|
||||
if (a.category == category::ENUM || b.category == category::ENUM) {
|
||||
if (a.category != category::ENUM && a.category != category::INTEGER)
|
||||
return false;
|
||||
if (b.category != category::ENUM && b.category != category::INTEGER)
|
||||
return false;
|
||||
|
||||
// Indices only need to match if they're both an ENUM,
|
||||
// otherwise we're testing the underlying type.
|
||||
if (a.category == category::ENUM && b.category == category::ENUM)
|
||||
if (a.index != b.index)
|
||||
return false;
|
||||
} else {
|
||||
if (a.index != b.index)
|
||||
return false;
|
||||
}
|
||||
|
||||
// All details other must be identical;
|
||||
return a.signedness == b.signedness &&
|
||||
a.width == b.width &&
|
||||
a.arity == b.arity &&
|
||||
a.alignment == b.alignment;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
template <typename T, typename = void>
|
||||
struct category_traits;
|
||||
|
Loading…
Reference in New Issue
Block a user