[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.
This commit is contained in:
@@ -7,29 +7,36 @@ namespace types {
|
|||||||
template <bool B, typename T = void> struct enable_if {};
|
template <bool B, typename T = void> struct enable_if {};
|
||||||
template <typename T> struct enable_if<true, T> { using type = T; };
|
template <typename T> struct enable_if<true, T> { using type = T; };
|
||||||
|
|
||||||
|
template <typename T> struct non_const { using type = T; };
|
||||||
|
template <typename T> struct non_const<const T> { using type = T; };
|
||||||
|
|
||||||
template <typename T> struct is_integral { static constexpr bool value = false; };
|
template <typename T> struct is_integral { static constexpr bool value = false; };
|
||||||
template <> struct is_integral<char> { static constexpr bool value = true; };
|
|
||||||
template <> struct is_integral<unsigned char> { static constexpr bool value = true; };
|
#define make_is_integral(n) \
|
||||||
template <> struct is_integral<short> { static constexpr bool value = true; };
|
template <> struct is_integral< n > { static constexpr bool value = true; }; \
|
||||||
template <> struct is_integral<unsigned short> { static constexpr bool value = true; };
|
template <> struct is_integral<const n > { static constexpr bool value = true; }; \
|
||||||
template <> struct is_integral<int> { static constexpr bool value = true; };
|
template <> struct is_integral<unsigned n > { static constexpr bool value = true; }; \
|
||||||
template <> struct is_integral<unsigned int> { static constexpr bool value = true; };
|
template <> struct is_integral<const unsigned n > { static constexpr bool value = true; };
|
||||||
template <> struct is_integral<long> { static constexpr bool value = true; };
|
|
||||||
template <> struct is_integral<unsigned long> { static constexpr bool value = true; };
|
make_is_integral(char);
|
||||||
template <> struct is_integral<long long> { static constexpr bool value = true; };
|
make_is_integral(short);
|
||||||
template <> struct is_integral<unsigned long long> { static constexpr bool value = true; };
|
make_is_integral(int);
|
||||||
|
make_is_integral(long);
|
||||||
|
make_is_integral(long long);
|
||||||
|
|
||||||
template <typename E> struct integral { using type = unsigned long long; };
|
template <typename E> struct integral { using type = unsigned long long; };
|
||||||
template <> struct integral<char> { using type = char; };
|
|
||||||
template <> struct integral<unsigned char> { using type = unsigned char; };
|
#define make_integral(n) \
|
||||||
template <> struct integral<short> { using type = short; };
|
template <> struct integral< n > { using type = n ; }; \
|
||||||
template <> struct integral<unsigned short> { using type = unsigned short; };
|
template <> struct integral<const n > { using type = n ; }; \
|
||||||
template <> struct integral<int> { using type = int; };
|
template <> struct integral<unsigned n > { using type = unsigned n ; }; \
|
||||||
template <> struct integral<unsigned int> { using type = unsigned int; };
|
template <> struct integral<const unsigned n > { using type = unsigned n ; };
|
||||||
template <> struct integral<long> { using type = long; };
|
|
||||||
template <> struct integral<unsigned long> { using type = unsigned long; };
|
make_integral(char);
|
||||||
template <> struct integral<long long> { using type = long long; };
|
make_integral(short);
|
||||||
template <> struct integral<unsigned long long> { using type = unsigned long long; };
|
make_integral(int);
|
||||||
|
make_integral(long);
|
||||||
|
make_integral(long long);
|
||||||
|
|
||||||
template <typename T, T v>
|
template <typename T, T v>
|
||||||
struct integral_constant
|
struct integral_constant
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ constexpr bool is_enum_bitfield(E) { return false; }
|
|||||||
template <typename E>
|
template <typename E>
|
||||||
struct enum_or_int {
|
struct enum_or_int {
|
||||||
static constexpr bool value =
|
static constexpr bool value =
|
||||||
is_enum_bitfield(E{}) || types::is_integral<E>::value;
|
is_enum_bitfield(typename types::non_const<E>::type{})
|
||||||
|
|| types::is_integral<E>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename E, typename F>
|
template <typename E, typename F>
|
||||||
@@ -20,6 +21,13 @@ struct both_enum_or_int {
|
|||||||
types::conjunction< enum_or_int<E>, enum_or_int<F> >::value;
|
types::conjunction< enum_or_int<E>, enum_or_int<F> >::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename E, typename R>
|
||||||
|
struct enable_if_bitfield {
|
||||||
|
using enum_t = typename types::non_const<E>::type;
|
||||||
|
using type = typename
|
||||||
|
types::enable_if< is_enum_bitfield(enum_t{}), R >::type;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename E, typename F>
|
template <typename E, typename F>
|
||||||
constexpr typename types::enable_if<both_enum_or_int<E, F>::value,E>::type&
|
constexpr typename types::enable_if<both_enum_or_int<E, F>::value,E>::type&
|
||||||
operator |= (E &lhs, F rhs)
|
operator |= (E &lhs, F rhs)
|
||||||
@@ -60,16 +68,16 @@ constexpr typename types::enable_if<both_enum_or_int<E, F>::value,E>::type
|
|||||||
operator ^ (E lhs, F rhs) { return lhs ^= rhs; }
|
operator ^ (E lhs, F rhs) { return lhs ^= rhs; }
|
||||||
|
|
||||||
template <typename E>
|
template <typename E>
|
||||||
constexpr typename types::enable_if<is_enum_bitfield(E{}),E>::type
|
constexpr typename enable_if_bitfield<E,E>::type
|
||||||
operator ~ (E rhs) { return static_cast<E>(~static_cast<typename types::integral<E>::type>(rhs)); }
|
operator ~ (E rhs) { return static_cast<E>(~static_cast<typename types::integral<E>::type>(rhs)); }
|
||||||
|
|
||||||
template <typename E>
|
template <typename E>
|
||||||
constexpr typename types::enable_if<is_enum_bitfield(E{}),bool>::type
|
constexpr typename enable_if_bitfield<E,bool>::type
|
||||||
operator ! (E rhs) { return static_cast<typename types::integral<E>::type>(rhs) == 0; }
|
operator ! (E rhs) { return static_cast<typename types::integral<E>::type>(rhs) == 0; }
|
||||||
|
|
||||||
/// Override logical-and to mean 'rhs contains all bits in lhs'
|
/// Override logical-and to mean 'rhs contains all bits in lhs'
|
||||||
template <typename E>
|
template <typename E>
|
||||||
constexpr typename types::enable_if<is_enum_bitfield(E{}),bool>::type
|
constexpr typename enable_if_bitfield<E,bool>::type
|
||||||
operator && (E rhs, E lhs) { return (rhs & lhs) == lhs; }
|
operator && (E rhs, E lhs) { return (rhs & lhs) == lhs; }
|
||||||
|
|
||||||
/// Generic 'has' for non-marked bitfields
|
/// Generic 'has' for non-marked bitfields
|
||||||
|
|||||||
Reference in New Issue
Block a user