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