58#ifndef CXXUTILS_BITMASK_H
59#define CXXUTILS_BITMASK_H
70#define ATH_BITMASK IS_ATH_BITMASK=1
77 template <
typename T,
bool = std::is_enum_v<T>>
78 struct relaxed_underlying_type {
79 using type = std::underlying_type_t<T>;
82 struct relaxed_underlying_type<T, false> {
86 using relaxed_underlying_type_t =
typename relaxed_underlying_type<T>::type;
89 template <
class E,
class F>
90 constexpr bool has_same_underlying_v = std::is_same_v<relaxed_underlying_type_t<E>,
91 relaxed_underlying_type_t<F>>;
94 template <
class E,
class F>
95 struct enum_or_underlying {
96 using type = std::conditional_t<std::is_same_v<E,F> && has_same_underlying_v<E,F>,
97 E, relaxed_underlying_type_t<E>>;
99 template <
class E,
class F>
100 using enum_or_underlying_t =
typename enum_or_underlying<E,F>::type;
103 template <
class E,
typename Enable =
void>
104 constexpr bool is_bitmask_v =
false;
107# pragma nv_diagnostic push
109# pragma nv_diag_suppress 174
112 constexpr bool is_bitmask_v<E, std::enable_if_t<(E::IS_ATH_BITMASK,1)>> =
true;
114# pragma nv_diagnostic pop
131std::enable_if_t<is_bitmask_v<E>,
E>
134 typedef std::underlying_type_t<E> underlying;
135 return static_cast<E
> (~static_cast<underlying>(lhs));
144template <
class E,
class F,
145 typename = std::enable_if_t<(is_bitmask_v<E> || is_bitmask_v<F>) &&
146 has_same_underlying_v<E,F>>>
147constexpr auto operator& (E lhs,
F rhs)
149 typedef relaxed_underlying_type_t<E> underlying;
150 return static_cast<enum_or_underlying_t<E,F>
>(
static_cast<underlying
>(lhs) &
151 static_cast<underlying
>(rhs));
157template <
class E,
class F,
158 typename = std::enable_if_t<(is_bitmask_v<E> || is_bitmask_v<F>) &&
159 has_same_underlying_v<E,F>>>
160constexpr auto operator| (E lhs,
F rhs)
162 typedef relaxed_underlying_type_t<E> underlying;
163 return static_cast<enum_or_underlying_t<E,F>
>(
static_cast<underlying
>(lhs) |
164 static_cast<underlying
>(rhs));
170template <
class E,
class F,
171 typename = std::enable_if_t<(is_bitmask_v<E> || is_bitmask_v<F>) &&
172 has_same_underlying_v<E,F>>>
173constexpr auto operator^ (E lhs,
F rhs)
175 typedef relaxed_underlying_type_t<E> underlying;
176 return static_cast<enum_or_underlying_t<E,F>
>(
static_cast<underlying
>(lhs) ^
177 static_cast<underlying
>(rhs));
184std::enable_if_t<is_bitmask_v<E>,
E&>
187 typedef std::underlying_type_t<E> underlying;
188 lhs =
static_cast<E
> (
static_cast<underlying
>(lhs) &
static_cast<underlying
>(rhs));
196std::enable_if_t<is_bitmask_v<E>,
E&>
199 typedef std::underlying_type_t<E> underlying;
200 lhs =
static_cast<E
> (
static_cast<underlying
>(lhs) |
static_cast<underlying
>(rhs));
208std::enable_if_t<is_bitmask_v<E>,
E&>
211 typedef std::underlying_type_t<E> underlying;
212 lhs =
static_cast<E
> (
static_cast<underlying
>(lhs) ^
static_cast<underlying
>(rhs));
231std::enable_if_t<is_bitmask_v<E>,
E&>
250std::enable_if_t<is_bitmask_v<E>, E&>
269std::enable_if_t<is_bitmask_v<E>,
bool>
272 typedef std::underlying_type_t<E>underlying;
273 return static_cast<underlying
> (lhs & rhs) != 0;
constexpr std::enable_if_t< is_bitmask_v< E >, E & > operator&=(E &lhs, E rhs)
operator&=
constexpr std::enable_if_t< is_bitmask_v< E >, E & > operator^=(E &lhs, E rhs)
operator^=
constexpr std::enable_if_t< is_bitmask_v< E >, E & > operator|=(E &lhs, E rhs)
operator|=
constexpr std::enable_if_t< is_bitmask_v< E >, E > operator~(E lhs)
operator~
constexpr std::enable_if_t< is_bitmask_v< E >, bool > test(E lhs, E rhs)
Convenience function to test bits in a class enum bitmask.
constexpr std::enable_if_t< is_bitmask_v< E >, E & > reset(E &lhs, E rhs)
Convenience function to clear bits in a class enum bitmask.
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.