Skip to content

Commit 7a57324

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 7a57324

1 file changed

Lines changed: 56 additions & 11 deletions

File tree

libs/common/include/s25util/enumUtils.h

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

77
#include <type_traits>
88

9+
template<typename Enum>
10+
struct IsBitset : std::false_type
11+
{};
12+
13+
template<typename Enum>
14+
using IsValidBitset =
15+
std::integral_constant<bool, IsBitset<Enum>::value && std::is_unsigned<std::underlying_type_t<Enum>>::value>;
16+
17+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
18+
constexpr auto operator&(Enum lhs, Enum rhs) noexcept
19+
{
20+
using T = std::underlying_type_t<Enum>;
21+
return Enum(static_cast<T>(lhs) & static_cast<T>(rhs));
22+
}
23+
24+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
25+
constexpr auto operator|(Enum lhs, Enum rhs) noexcept
26+
{
27+
using T = std::underlying_type_t<Enum>;
28+
return Enum(static_cast<T>(lhs) | static_cast<T>(rhs));
29+
}
30+
31+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
32+
constexpr auto operator^(Enum lhs, Enum rhs) noexcept
33+
{
34+
using T = std::underlying_type_t<Enum>;
35+
return Enum(static_cast<T>(lhs) ^ static_cast<T>(rhs));
36+
}
37+
38+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
39+
constexpr auto operator&=(Enum& lhs, Enum rhs) noexcept
40+
{
41+
lhs = lhs & rhs;
42+
return lhs;
43+
}
44+
45+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
46+
constexpr auto operator|=(Enum& lhs, Enum rhs) noexcept
47+
{
48+
lhs = lhs | rhs;
49+
return lhs;
50+
}
51+
52+
template<typename Enum, std::enable_if_t<IsValidBitset<Enum>::value, int> = 0>
53+
constexpr auto operator^=(Enum& lhs, Enum rhs) noexcept
54+
{
55+
lhs = lhs ^ rhs;
56+
return lhs;
57+
}
58+
959
/// 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, \
60+
#define MAKE_BITSET_STRONG(Type) \
61+
template<> \
62+
struct IsBitset<Type> : std::true_type \
63+
{}; \
64+
/* NOLINTNEXTLINE(bugprone-macro-parentheses) */ \
65+
static_assert(std::is_unsigned<std::underlying_type_t<Type>>::value, \
2166
#Type " must use unsigned type as the underlying type")

0 commit comments

Comments
 (0)