Loading...
Searching...
No Matches
flags.h
Go to the documentation of this file.
1#ifndef _BBM_FLAGS_H_
2#define _BBM_FLAGS_H_
3
4#include <type_traits>
5#include "util/reflection.h"
6
7/***********************************************************************/
8/*! \file flags.h
9 \brief Scoped enum operators and methods
10
11 The defined operators are:
12
13 + is_set(val, flag): Check if all in 'flag' are set in 'val. Note this is
14 not a symmetric operation.
15 + operator| : performs OR operation of flags. __NOTE__: the combined flag
16 must be defined in the enum body.
17 + operator& : performs AND operation on flags.
18 + operator^ : XOR operator
19 + operator~ : NOT operator
20
21 Guarantees 'constexpr' when is_enum_v<FLAGNAME>
22
23*************************************************************************/
24
25namespace bbm {
26
27 /*********************************************************************/
28 /*! @{ \name Core Enum Operations
29 *********************************************************************/
30
31 //! \brief Concat two flags
32 template<typename FLAGNAME> requires std::is_enum_v<FLAGNAME>
33 inline constexpr FLAGNAME operator|(FLAGNAME a, FLAGNAME b)
34 {
35 return FLAGNAME(std::underlying_type_t<FLAGNAME>(a) | std::underlying_type_t<FLAGNAME>(b));
36 }
37
38 //! \brief Conact two flags
39 template<typename FLAGNAME> requires std::is_enum_v<FLAGNAME>
40 inline constexpr FLAGNAME operator+(FLAGNAME a, FLAGNAME b)
41 {
42 return FLAGNAME(std::underlying_type_t<FLAGNAME>(a) | std::underlying_type_t<FLAGNAME>(b));
43 }
44
45 //! \brief Get the shared flags
46 template<typename FLAGNAME> requires std::is_enum_v<FLAGNAME>
47 inline constexpr FLAGNAME operator&(FLAGNAME a, FLAGNAME b)
48 {
49 return FLAGNAME(std::underlying_type_t<FLAGNAME>(a) & std::underlying_type_t<FLAGNAME>(b));
50 }
51
52 //! \brief Get the flags from 'a' that are not in 'b'
53 template<typename FLAGNAME> requires std::is_enum_v<FLAGNAME>
54 inline constexpr FLAGNAME operator^(FLAGNAME a, FLAGNAME b)
55 {
56 return FLAGNAME(std::underlying_type_t<FLAGNAME>(a) ^ std::underlying_type_t<FLAGNAME>(b));
57 }
58
59 //! \brief Set/unset flag that are unset/set respectively.
60 template<typename FLAGNAME> requires std::is_enum_v<FLAGNAME>
61 inline constexpr FLAGNAME operator~(FLAGNAME a)
62 {
63 return FLAGNAME(~std::underlying_type_t<FLAGNAME>(a));
64 }
65
66 //! \brief Update 'a' with a & b
67 template<typename FLAGNAME> requires std::is_enum_v<FLAGNAME>
68 inline constexpr FLAGNAME& operator&=(FLAGNAME& a, FLAGNAME b)
69 {
70 a = a & b;
71 return a;
72 }
73
74 //! \brief Update 'a' with a | b
75 template<typename FLAGNAME> requires std::is_enum_v<FLAGNAME>
76 inline constexpr FLAGNAME& operator|=(FLAGNAME& a, FLAGNAME b)
77 {
78 a = a | b;
79 return a;
80 }
81
82 //! \brief Update 'a' with a+b
83 template<typename FLAGNAME> requires std::is_enum_v<FLAGNAME>
84 inline constexpr FLAGNAME& operator+=(FLAGNAME& a, FLAGNAME b)
85 {
86 a = a | b;
87 return a;
88 }
89
90 //! \brief Update 'a' with a^b,
91 template<typename FLAGNAME> requires std::is_enum_v<FLAGNAME>
92 inline constexpr FLAGNAME& operator^=(FLAGNAME& a, FLAGNAME b)
93 {
94 a = a ^ b;
95 return a;
96 }
97
98 //! \brief Check if all in 'flag' are also set in 'a'; compatible with packet types.
99 template<typename FLAGNAME, typename FLAG> requires std::is_enum_v<FLAG> && std::is_same_v<scalar_t<FLAGNAME>, FLAG>
100 inline constexpr auto is_set(const FLAGNAME& a, const FLAG& flag)
101 {
102 // Ensure constexpr when FLAGNAME == FLAG
103 if constexpr (std::is_same_v<FLAGNAME, FLAG>) return ((a & flag) == flag);
104
105 // Otherwise use eq function (does not guarantee constexpr)
106 else return eq((a & flag), flag);
107 }
108
109 //! @}
110
111 /**********************************************************************/
112 /*! \brief ostream output uses toString conversion
113 *********************************************************************/
114 template<typename ENUM> requires concepts::reflection::enumerate<ENUM>
115 std::ostream& operator<<(std::ostream& s, ENUM e)
116 {
117 s << bbm::toString(e);
118 return s;
119 }
120
121} // end bbm namespace
122
123
124
125#endif /* _BBM_FLAGS_H_ */
Definition: aggregatebsdf.h:29
constexpr FLAGNAME operator+(FLAGNAME a, FLAGNAME b)
Conact two flags.
Definition: flags.h:40
constexpr FLAGNAME & operator^=(FLAGNAME &a, FLAGNAME b)
Update 'a' with a^b,.
Definition: flags.h:92
constexpr FLAGNAME & operator+=(FLAGNAME &a, FLAGNAME b)
Update 'a' with a+b.
Definition: flags.h:84
constexpr FLAGNAME operator~(FLAGNAME a)
Set/unset flag that are unset/set respectively.
Definition: flags.h:61
constexpr FLAGNAME & operator|=(FLAGNAME &a, FLAGNAME b)
Update 'a' with a | b.
Definition: flags.h:76
constexpr FLAGNAME operator|(FLAGNAME a, FLAGNAME b)
Concat two flags.
Definition: flags.h:33
std::ostream & operator<<(std::ostream &s, const BSDF &bsdf)
Definition: bsdf_base.h:138
constexpr FLAGNAME & operator&=(FLAGNAME &a, FLAGNAME b)
Update 'a' with a & b.
Definition: flags.h:68
std::string toString(const T &)
toString alias
Definition: stringconvert.h:594
constexpr FLAGNAME operator&(FLAGNAME a, FLAGNAME b)
Get the shared flags.
Definition: flags.h:47
constexpr auto is_set(const FLAGNAME &a, const FLAG &flag)
Check if all in 'flag' are also set in 'a'; compatible with packet types.
Definition: flags.h:100
constexpr FLAGNAME operator^(FLAGNAME a, FLAGNAME b)
Get the flags from 'a' that are not in 'b'.
Definition: flags.h:54
Compile-time reflection of: