Skip to content

Commit 82e2584

Browse files
Add more bitset operators and trait-based opt-in
Add new operator overloads to enhance the functionality of bitsets, and introduce a type trait that enables enums to opt in to being used as bitsets.
1 parent c2e1c58 commit 82e2584

1 file changed

Lines changed: 42 additions & 11 deletions

File tree

libs/common/include/s25util/enumUtils.h

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,47 @@
66

77
#include <type_traits>
88

9+
template<typename Enum>
10+
struct IsBitset : std::false_type
11+
{};
12+
13+
template<typename Enum>
14+
constexpr bool IsValidBitset = IsBitset<Enum>::value && std::is_unsigned<std::underlying_type_t<Enum>>::value;
15+
16+
template<typename Enum>
17+
using require_validBitset = std::enable_if_t<IsValidBitset<Enum>>;
18+
19+
template<typename Enum, typename = require_validBitset<Enum>>
20+
constexpr auto operator&(Enum lhs, Enum rhs) noexcept
21+
{
22+
using Int = std::underlying_type_t<Enum>;
23+
return Enum(static_cast<Int>(lhs) & static_cast<Int>(rhs));
24+
}
25+
26+
template<typename Enum, typename = require_validBitset<Enum>>
27+
constexpr auto operator|(Enum lhs, Enum rhs) noexcept
28+
{
29+
using Int = std::underlying_type_t<Enum>;
30+
return Enum(static_cast<Int>(lhs) | static_cast<Int>(rhs));
31+
}
32+
33+
template<typename Enum, typename = require_validBitset<Enum>>
34+
constexpr auto operator&=(Enum& lhs, Enum rhs) noexcept
35+
{
36+
return lhs = lhs & rhs;
37+
}
38+
39+
template<typename Enum, typename = require_validBitset<Enum>>
40+
constexpr auto operator|=(Enum& lhs, Enum rhs) noexcept
41+
{
42+
return lhs = lhs | rhs;
43+
}
44+
945
/// Makes a strongly typed enum usable as a bitset
10-
#define MAKE_BITSET_STRONG(Type) \
11-
inline auto operator&(Type lhs, Type rhs) \
12-
{ \
13-
return Type(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs)); \
14-
} \
15-
inline auto operator|(Type lhs, Type rhs) \
16-
{ \
17-
return Type(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); \
18-
} \
19-
/* NOLINTNEXTLINE(bugprone-macro-parentheses) */ \
20-
static_assert(std::is_unsigned<std::underlying_type_t<Type>>::value, \
46+
#define MAKE_BITSET_STRONG(Type) \
47+
template<> \
48+
struct IsBitset<Type> : std::true_type \
49+
{}; \
50+
/* NOLINTNEXTLINE(bugprone-macro-parentheses) */ \
51+
static_assert(std::is_unsigned<std::underlying_type_t<Type>>::value, \
2152
#Type " must use unsigned type as the underlying type")

0 commit comments

Comments
 (0)