NUMA++ 0.11.0
Loading...
Searching...
No Matches
flags.hpp
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup numapp
4 * @copyright ESO 2024 - European Southern Observatory
5 *
6 * @brief Contains definitions for bitwise operators for enums
7 */
8#ifndef NUMAPP_FLAGS_HPP_
9#define NUMAPP_FLAGS_HPP_
10#include <type_traits>
11
12/**
13 * Enables numapp bitwise operators in overload set for the specified enumeration @a enum.
14 *
15 * @note This macro must be used inside the namespace @c numapp.
16 */
17#define NUMAPP_ENABLE_BITFLAG(enum) \
18 template <>\
19 struct IsFlagEnum<enum> : std::true_type { \
20 static_assert(std::is_enum_v<enum>); \
21 };
22
23namespace numapp {
24// @cond INTERNAL
25namespace detail {
26template<class Enum>
27constexpr std::underlying_type_t<Enum> ToUnderlying(Enum value) noexcept {
28 return static_cast<std::underlying_type_t<Enum>>(value);
29}
30template<class Enum>
31constexpr Enum FromUnderlying(std::underlying_type_t<Enum> value) noexcept {
32 return static_cast<Enum>(value);
33}
34} // namespace detail
35// @endcond
36
37/**
38 * Trait type that should be specialized for an enumeration to enable use of bitwise operators.
39 *
40 * @note Use macro NUMAPP_ENABLE_BITFLAG instead.
41 *
42 * Example to enable Flags for enum MyEnum:
43 *
44 * namespace numapp {
45 * template<>
46 * struct IsFlagEnum<MyEnum> : std::true_type {};
47 * }
48 */
49template <class Enum>
51
52
53/**
54 * @name Bitwise operators for enabled enums
55 *
56 * Convenience function to compose bit flags using bitwise OR and AND operators.
57 *
58 * Example:
59 *
60 * @code
61 * using numapp::operator|; // Bring in numapp::operator| in this scope
62 *
63 * MyEnum f = MyEnum::A | MyEnum::B;
64 * f &= MyEnum::A;
65 * MyFunc(f);
66 * MyFunc(MyEnum::A | MyEnum::B);
67 * @endcode
68 */
69// @{
70/**
71 * @returns logical OR between @a lhs and @a rhs
72 */
73template <class Enum, typename = typename std::enable_if<IsFlagEnum<Enum>::value>::type>
74[[nodiscard]] constexpr Enum operator|(Enum lhs, Enum rhs) noexcept {
75 return detail::FromUnderlying<Enum>(detail::ToUnderlying(lhs) | detail::ToUnderlying(rhs));
76}
77
78/**
79 * Sets @a lhs with logical OR between @a lhs and @a rhs
80 */
81template <class Enum, typename = typename std::enable_if<IsFlagEnum<Enum>::value>::type>
82constexpr Enum& operator|=(Enum& lhs, Enum rhs) noexcept {
83 lhs = lhs | rhs;
84 return lhs;
85}
86
87/**
88 * @returns logical AND between @a lhs and @a rhs
89 */
90template <class Enum, typename = typename std::enable_if<IsFlagEnum<Enum>::value>::type>
91[[nodiscard]] constexpr Enum operator&(Enum lhs, Enum rhs) noexcept {
92 return detail::FromUnderlying<Enum>(detail::ToUnderlying(lhs) & detail::ToUnderlying(rhs));
93}
94
95/**
96 * Sets @a lhs with logical AND between @a lhs and @a rhs
97 */
98template <class Enum, typename = typename std::enable_if<IsFlagEnum<Enum>::value>::type>
99constexpr Enum& operator&=(Enum& lhs, Enum rhs) noexcept {
100 lhs = lhs & rhs;
101 return lhs;
102}
103// @}
104
105} // namespace numapp
106#endif // #define NUMAPP_FLAGS_HPP_
constexpr Enum operator|(Enum lhs, Enum rhs) noexcept
Definition flags.hpp:74
constexpr Enum & operator&=(Enum &lhs, Enum rhs) noexcept
Sets lhs with logical AND between lhs and rhs.
Definition flags.hpp:99
constexpr Enum operator&(Enum lhs, Enum rhs) noexcept
Definition flags.hpp:91
constexpr Enum & operator|=(Enum &lhs, Enum rhs) noexcept
Sets lhs with logical OR between lhs and rhs.
Definition flags.hpp:82
Trait type that should be specialized for an enumeration to enable use of bitwise operators.
Definition flags.hpp:50