-
Notifications
You must be signed in to change notification settings - Fork 0
/
EnumClassBinaryOperator.h
66 lines (64 loc) · 4.87 KB
/
EnumClassBinaryOperator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#pragma once
#include <type_traits>
#define ENUM_BINARY_OPERATE_ENABLE(Enum) \
static_assert( \
std::is_enum_v< \
Enum> && std::is_integral_v<std::underlying_type_t<Enum>>); \
template <typename T> \
concept Enum##OperatorType = \
std::is_same_v<T, Enum> || std::is_integral_v<T>; \
template <typename T, typename U> \
concept Enum##atLeastOneArg = \
std::is_same_v<T, Enum> || std::is_same_v<U, Enum>; \
constexpr inline Enum &operator|=(Enum &x, \
Enum##OperatorType auto &&y) noexcept { \
return x = static_cast<Enum>( \
static_cast<std::underlying_type_t<Enum>>(x) \
| static_cast<std::underlying_type_t<Enum>>(y)); \
} \
constexpr inline Enum &operator&=(Enum &x, \
Enum##OperatorType auto &&y) noexcept { \
return x = static_cast<Enum>( \
static_cast<std::underlying_type_t<Enum>>(x) \
& static_cast<std::underlying_type_t<Enum>>(y)); \
} \
constexpr inline Enum &operator^=(Enum &x, \
Enum##OperatorType auto &&y) noexcept { \
return x = static_cast<Enum>( \
static_cast<std::underlying_type_t<Enum>>(x) \
^ static_cast<std::underlying_type_t<Enum>>(y)); \
} \
template <Enum##OperatorType T, Enum##OperatorType U> \
requires Enum##atLeastOneArg< \
T, U> constexpr inline std::underlying_type_t<Enum> \
operator|(T x, U y) noexcept { \
return static_cast<std::underlying_type_t<Enum>>(x) \
| static_cast<std::underlying_type_t<Enum>>(y); \
} \
template <Enum##OperatorType T, Enum##OperatorType U> \
requires Enum##atLeastOneArg< \
T, U> constexpr inline std::underlying_type_t<Enum> \
operator&(T x, U y) noexcept { \
return static_cast<std::underlying_type_t<Enum>>(x) \
& static_cast<std::underlying_type_t<Enum>>(y); \
} \
template <Enum##OperatorType T, Enum##OperatorType U> \
requires Enum##atLeastOneArg< \
T, U> constexpr inline std::underlying_type_t<Enum> \
operator^(T x, U y) noexcept { \
return static_cast<std::underlying_type_t<Enum>>(x) \
^ static_cast<std::underlying_type_t<Enum>>(y); \
} \
constexpr inline bool operator!(Enum x) noexcept { \
return !static_cast<std::underlying_type_t<Enum>>(x); \
} \
constexpr inline Enum operator~(Enum x) noexcept { \
return static_cast<Enum>( \
~static_cast<std::underlying_type_t<Enum>>(x)); \
} \
template <Enum##OperatorType T, Enum##OperatorType U> \
requires Enum##atLeastOneArg<T, U> constexpr inline bool operator>( \
T x, U y) noexcept { \
return static_cast<std::underlying_type_t<Enum>>(x) \
> static_cast<std::underlying_type_t<Enum>>(y); \
}