From 9f3e682b89a6b0dbbdc1c4bf2c00d9262deabe82 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Fri, 7 Jan 2022 00:46:45 -0800 Subject: [PATCH] [util] Handle const better in enum_bitfields I just can't get enum_bitfields to work in boot. The same code works in other targets. None of the compiler options should change that. I gave up, but I'm leaving these changes in because they do actually handle const better. --- src/libraries/util/include/util/basic_types.h | 49 +++++++++++-------- .../util/include/util/enum_bitfields.h | 16 ++++-- 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/libraries/util/include/util/basic_types.h b/src/libraries/util/include/util/basic_types.h index 0a4f05f..3e7219d 100644 --- a/src/libraries/util/include/util/basic_types.h +++ b/src/libraries/util/include/util/basic_types.h @@ -7,29 +7,36 @@ namespace types { template struct enable_if {}; template struct enable_if { using type = T; }; +template struct non_const { using type = T; }; +template struct non_const { using type = T; }; + template struct is_integral { static constexpr bool value = false; }; -template <> struct is_integral { static constexpr bool value = true; }; -template <> struct is_integral { static constexpr bool value = true; }; -template <> struct is_integral { static constexpr bool value = true; }; -template <> struct is_integral { static constexpr bool value = true; }; -template <> struct is_integral { static constexpr bool value = true; }; -template <> struct is_integral { static constexpr bool value = true; }; -template <> struct is_integral { static constexpr bool value = true; }; -template <> struct is_integral { static constexpr bool value = true; }; -template <> struct is_integral { static constexpr bool value = true; }; -template <> struct is_integral { static constexpr bool value = true; }; - + +#define make_is_integral(n) \ + template <> struct is_integral< n > { static constexpr bool value = true; }; \ + template <> struct is_integral { static constexpr bool value = true; }; \ + template <> struct is_integral { static constexpr bool value = true; }; \ + template <> struct is_integral { static constexpr bool value = true; }; + +make_is_integral(char); +make_is_integral(short); +make_is_integral(int); +make_is_integral(long); +make_is_integral(long long); + template struct integral { using type = unsigned long long; }; -template <> struct integral { using type = char; }; -template <> struct integral { using type = unsigned char; }; -template <> struct integral { using type = short; }; -template <> struct integral { using type = unsigned short; }; -template <> struct integral { using type = int; }; -template <> struct integral { using type = unsigned int; }; -template <> struct integral { using type = long; }; -template <> struct integral { using type = unsigned long; }; -template <> struct integral { using type = long long; }; -template <> struct integral { using type = unsigned long long; }; + +#define make_integral(n) \ + template <> struct integral< n > { using type = n ; }; \ + template <> struct integral { using type = n ; }; \ + template <> struct integral { using type = unsigned n ; }; \ + template <> struct integral { using type = unsigned n ; }; + +make_integral(char); +make_integral(short); +make_integral(int); +make_integral(long); +make_integral(long long); template struct integral_constant diff --git a/src/libraries/util/include/util/enum_bitfields.h b/src/libraries/util/include/util/enum_bitfields.h index f4d4784..91ae191 100644 --- a/src/libraries/util/include/util/enum_bitfields.h +++ b/src/libraries/util/include/util/enum_bitfields.h @@ -11,7 +11,8 @@ constexpr bool is_enum_bitfield(E) { return false; } template struct enum_or_int { static constexpr bool value = - is_enum_bitfield(E{}) || types::is_integral::value; + is_enum_bitfield(typename types::non_const::type{}) + || types::is_integral::value; }; template @@ -20,6 +21,13 @@ struct both_enum_or_int { types::conjunction< enum_or_int, enum_or_int >::value; }; +template +struct enable_if_bitfield { + using enum_t = typename types::non_const::type; + using type = typename + types::enable_if< is_enum_bitfield(enum_t{}), R >::type; +}; + template constexpr typename types::enable_if::value,E>::type& operator |= (E &lhs, F rhs) @@ -60,16 +68,16 @@ constexpr typename types::enable_if::value,E>::type operator ^ (E lhs, F rhs) { return lhs ^= rhs; } template -constexpr typename types::enable_if::type +constexpr typename enable_if_bitfield::type operator ~ (E rhs) { return static_cast(~static_cast::type>(rhs)); } template -constexpr typename types::enable_if::type +constexpr typename enable_if_bitfield::type operator ! (E rhs) { return static_cast::type>(rhs) == 0; } /// Override logical-and to mean 'rhs contains all bits in lhs' template -constexpr typename types::enable_if::type +constexpr typename enable_if_bitfield::type operator && (E rhs, E lhs) { return (rhs & lhs) == lhs; } /// Generic 'has' for non-marked bitfields