Skip to content

Commit e6b521b

Browse files
committed
#134: Implement remaining enum operators, add tests
1 parent edd30ff commit e6b521b

File tree

3 files changed

+82
-1
lines changed

3 files changed

+82
-1
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/src/tests/tests.enumflags.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#include <gtest/gtest.h>
2+
#include <zasm/core/enumflags.hpp>
3+
4+
enum class TestFlags : std::uint32_t
5+
{
6+
none = 0,
7+
a = 1U << 0,
8+
b = 1U << 2,
9+
c = 1U << 4,
10+
d = 1U << 8,
11+
e = 1U << 16,
12+
f = 1U << 24,
13+
g = 1U << 31,
14+
};
15+
ZASM_ENABLE_ENUM_OPERATORS(TestFlags);
16+
17+
TEST(EnumFlagsTest, operatorOr)
18+
{
19+
constexpr TestFlags flags = TestFlags::a | TestFlags::c | TestFlags::d | TestFlags::g;
20+
constexpr auto value = static_cast<std::underlying_type_t<TestFlags>>(flags);
21+
ASSERT_EQ(value, 0b1000'0000'0000'0000'0000'0001'0001'0001);
22+
}
23+
24+
TEST(EnumFlagsTest, operatorAnd)
25+
{
26+
constexpr TestFlags flags = (TestFlags::a | TestFlags::c | TestFlags::d | TestFlags::g) & TestFlags::c;
27+
constexpr auto value = static_cast<std::underlying_type_t<TestFlags>>(flags);
28+
ASSERT_EQ(value, 0b0000'0000'0000'0000'0000'0000'0001'0000);
29+
}
30+
31+
TEST(EnumFlagsTest, operatorXor)
32+
{
33+
constexpr TestFlags flags = (TestFlags::a | TestFlags::c | TestFlags::d) ^ (TestFlags::a | TestFlags::c | TestFlags::d)
34+
^ TestFlags::f;
35+
constexpr auto value = static_cast<std::underlying_type_t<TestFlags>>(flags);
36+
ASSERT_EQ(value, 0b0000'0001'0000'0000'0000'0000'0000'0000);
37+
}
38+
39+
TEST(EnumFlagsTest, operatorOrInplace)
40+
{
41+
TestFlags flags = TestFlags::none;
42+
flags |= TestFlags::a;
43+
flags |= TestFlags::c;
44+
flags |= TestFlags::d;
45+
flags |= TestFlags::g;
46+
auto value = static_cast<std::underlying_type_t<TestFlags>>(flags);
47+
ASSERT_EQ(value, 0b1000'0000'0000'0000'0000'0001'0001'0001);
48+
}
49+
50+
TEST(EnumFlagsTest, operatorAndInplace)
51+
{
52+
TestFlags flags = (TestFlags::a | TestFlags::c | TestFlags::d | TestFlags::g);
53+
flags &= TestFlags::c;
54+
auto value = static_cast<std::underlying_type_t<TestFlags>>(flags);
55+
ASSERT_EQ(value, 0b0000'0000'0000'0000'0000'0000'0001'0000);
56+
}
57+
58+
TEST(EnumFlagsTest, operatorXorInplace)
59+
{
60+
TestFlags flags = (TestFlags::a | TestFlags::c | TestFlags::d);
61+
flags ^= (TestFlags::a | TestFlags::c | TestFlags::d);
62+
flags ^= TestFlags::f;
63+
auto value = static_cast<std::underlying_type_t<TestFlags>>(flags);
64+
ASSERT_EQ(value, 0b0000'0001'0000'0000'0000'0000'0000'0000);
65+
}

zasm/include/zasm/core/enumflags.hpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,34 @@ namespace zasm
1111
/// </summary>
1212
/// <typeparam name="ENM">Enum type</typeparam>
1313
#define ZASM_ENABLE_ENUM_OPERATORS(ENM) \
14-
static_assert(std::is_unsigned_v<std::underlying_type_t<ENM>> == true, "Underlying enum type must be unsignd"); \
14+
static_assert(std::is_unsigned_v<std::underlying_type_t<ENM>> == true, "Underlying enum type must be unsigned"); \
1515
inline constexpr ENM operator|(const ENM a, const ENM b) noexcept \
1616
{ \
1717
return static_cast<ENM>(static_cast<std::underlying_type_t<ENM>>(a) | static_cast<std::underlying_type_t<ENM>>(b)); \
1818
} \
19+
inline constexpr ENM operator|=(ENM& a, const ENM b) noexcept \
20+
{ \
21+
a = static_cast<ENM>(static_cast<std::underlying_type_t<ENM>>(a) | static_cast<std::underlying_type_t<ENM>>(b)); \
22+
return a; \
23+
} \
1924
inline constexpr ENM operator^(const ENM a, const ENM b) noexcept \
2025
{ \
2126
return static_cast<ENM>(static_cast<std::underlying_type_t<ENM>>(a) ^ static_cast<std::underlying_type_t<ENM>>(b)); \
2227
} \
28+
inline constexpr ENM operator^=(ENM& a, const ENM b) noexcept \
29+
{ \
30+
a = static_cast<ENM>(static_cast<std::underlying_type_t<ENM>>(a) ^ static_cast<std::underlying_type_t<ENM>>(b)); \
31+
return a; \
32+
} \
2333
inline constexpr ENM operator&(const ENM a, const ENM b) noexcept \
2434
{ \
2535
return static_cast<ENM>(static_cast<std::underlying_type_t<ENM>>(a) & static_cast<std::underlying_type_t<ENM>>(b)); \
2636
} \
37+
inline constexpr ENM operator&=(ENM& a, const ENM b) noexcept \
38+
{ \
39+
a = static_cast<ENM>(static_cast<std::underlying_type_t<ENM>>(a) & static_cast<std::underlying_type_t<ENM>>(b)); \
40+
return a; \
41+
} \
2742
inline constexpr ENM operator~(const ENM a) noexcept \
2843
{ \
2944
return static_cast<ENM>(~static_cast<std::underlying_type_t<ENM>>(a)); \

0 commit comments

Comments
 (0)