parse/enum: we don't need to strictly enforce 'enumness'

This commit is contained in:
Danny Robson 2019-08-29 13:18:13 +10:00
parent 2a4401da98
commit e4c224ceaa

View File

@ -18,6 +18,25 @@
namespace cruft::parse::enumeration {
namespace detail {
/// Map a type to the underlying enum type if it is an enum, else
/// provided the identity mapping. Useful so simplify template logic
/// when dealing with types that aren't quite enums proper.
template <typename EnumT, typename = void>
struct underlying_else_identity { using type = EnumT; };
// Specialise for the enum case.
template <typename EnumT>
struct underlying_else_identity<
EnumT,
std::enable_if_t<std::is_enum_v<EnumT>>
> { using type = std::underlying_type_t<EnumT>; };
template <typename EnumT>
using underlying_else_identity_t = typename underlying_else_identity<EnumT>::type;
/// Abstract base class for lookups from string names to typed
/// integers.
///
@ -45,9 +64,7 @@ namespace cruft::parse::enumeration {
/// specialised on the EnumT that the lookup is targetting.
template <typename EnumT>
struct lookup_concrete : public lookup_base {
static_assert (std::is_enum_v<EnumT>);
using underlying_type = std::underlying_type_t<EnumT>;
using underlying_type = underlying_else_identity_t<EnumT>;
using cache_type = std::map<std::string_view, EnumT>;
lookup_concrete (cache_type _cache)
@ -101,21 +118,6 @@ namespace cruft::parse::enumeration {
std::unique_ptr<lookup_base>
>&
cache (void);
/// Map a type to the underlying enum type if it is an enum, else
/// provided the identity mapping. Useful so simplify template logic
/// when dealing with types that aren't quite enums proper.
template <typename EnumT, typename = void>
struct underlying_else_identity { using type = EnumT; };
// Specialise for the enum case.
template <typename EnumT>
struct underlying_else_identity<
EnumT,
std::enable_if_t<std::is_enum_v<EnumT>>
> { using type = std::underlying_type_t<EnumT>; };
};
@ -165,7 +167,7 @@ namespace cruft::parse::enumeration {
sizeof (EnumT) == 8
);
using underlying_type = typename detail::underlying_else_identity<EnumT>::type;
using underlying_type = detail::underlying_else_identity_t<EnumT>;
static_assert (std::is_integral_v<underlying_type>);
if constexpr (std::is_signed_v<underlying_type>) {