9#ifndef AVARA3D_UTIL_BITMASK_H
10#define AVARA3D_UTIL_BITMASK_H
14namespace a3d::util::bitmask {
20 using U = std::make_unsigned_t<std::underlying_type_t<E>>;
26 constexpr U<E> to_uint(E e)
noexcept {
27 static_assert(std::is_enum_v<E>,
"a3d::util::bitmask::to_uint() requires an enum type");
28 return static_cast<U<E>
>(
static_cast<std::underlying_type_t<E>
>(e));
33 constexpr bool any(E value, E bits)
noexcept {
34 return (to_uint(value) & to_uint(bits)) != 0;
39 constexpr bool all(E value, E bits)
noexcept {
40 const auto v = to_uint(value);
41 const auto b = to_uint(bits);
49 constexpr bool contains(E value, E bits)
noexcept {
50 return any(value, bits);
55 constexpr bool contains_all(E value, E bits)
noexcept {
56 return all(value, bits);
61 constexpr E add(E value, E bits)
noexcept {
62 return static_cast<E
>(to_uint(value) | to_uint(bits));
67 constexpr E remove(E value, E bits)
noexcept {
68 return static_cast<E
>(to_uint(value) & ~to_uint(bits));
73 constexpr void add_inplace(E& value, E bits)
noexcept {
74 value = add(value, bits);
79 constexpr void remove_inplace(E& value, E bits)
noexcept {
80 value = remove(value, bits);
86 struct enable_ops : std::false_type {};
89 constexpr bool enable_ops_v = enable_ops<E>::value;
92 concept MaskEnum = std::is_enum_v<E> && enable_ops_v<E>;
101 template<util::bitmask::MaskEnum E>
102 constexpr E operator|(E a, E b)
noexcept {
103 return static_cast<E
>(util::bitmask::to_uint(a) | util::bitmask::to_uint(b));
107 template<util::bitmask::MaskEnum E>
108 constexpr E operator&(E a, E b)
noexcept {
109 return static_cast<E
>(util::bitmask::to_uint(a) & util::bitmask::to_uint(b));
113 template<util::bitmask::MaskEnum E>
114 constexpr E operator^(E a, E b)
noexcept {
115 return static_cast<E
>(util::bitmask::to_uint(a) ^ util::bitmask::to_uint(b));
119 template<util::bitmask::MaskEnum E>
120 constexpr E operator~(E a)
noexcept {
121 return static_cast<E
>(~util::bitmask::to_uint(a));
125 template<util::bitmask::MaskEnum E>
126 constexpr E& operator|=(E& a, E b)
noexcept {
131 template<util::bitmask::MaskEnum E>
132 constexpr E& operator&=(E& a, E b)
noexcept {
137 template<util::bitmask::MaskEnum E>
138 constexpr E& operator^=(E& a, E b)
noexcept {