1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/base/Flags.h
12 #ifndef ZYPP_BASE_FLAGS_H
13 #define ZYPP_BASE_FLAGS_H
15 #include "zypp/base/String.h"
17 ///////////////////////////////////////////////////////////////////
19 { /////////////////////////////////////////////////////////////////
20 ///////////////////////////////////////////////////////////////////
22 { /////////////////////////////////////////////////////////////////
24 ///////////////////////////////////////////////////////////////////
26 // CLASS NAME : Flags<Enum>
28 /** A type-safe way of storing OR-combinations of enum values (like QTs QFlags).
29 * \see <a href="http://doc.trolltech.com/4.1/qflags.html">QFlags Class Reference</a>
34 * enum DbStateInfoBits {
35 * DbSI_NO_INIT = 0x0000,
36 * DbSI_HAVE_V4 = 0x0001,
37 * DbSI_MADE_V4 = 0x0002,
38 * DbSI_MODIFIED_V4 = 0x0004,
39 * DbSI_HAVE_V3 = 0x0008,
40 * DbSI_HAVE_V3TOV4 = 0x0010,
41 * DbSI_MADE_V3TOV4 = 0x0020
44 * ZYPP_DECLARE_FLAGS(DbStateInfo,DbStateInfoBits);
46 * ZYPP_DECLARE_OPERATORS_FOR_FLAGS(RpmDb::DbStateInfo);
49 * enum Other { OTHERVAL = 13 };
51 * XRpmDb::DbStateInfo s;
52 * s = XRpmDb::DbSI_MODIFIED_V4|XRpmDb::DbSI_HAVE_V4;
53 * // s |= OTHERVAL; // As desired: it does not compile
57 template<typename TEnum>
61 typedef TEnum Enum; ///< The underlying enum type
62 typedef typename std::underlying_type<Enum>::type Integral; ///< The underlying integral type
65 constexpr Flags() : _val( 0 ) {}
66 constexpr Flags( Enum flag_r ) : _val( integral(flag_r) ) {}
67 constexpr explicit Flags( Integral flag_r ) : _val( flag_r ) {}
69 constexpr static Flags none() { return Flags( Integral(0) ); }
70 constexpr static Flags all() { return Flags( ~Integral(0) ); }
72 constexpr bool isNone() const { return _val == Integral(0); }
73 constexpr bool isAll() const { return _val == ~Integral(0); }
75 Flags & operator&=( Flags rhs ) { _val &= integral(rhs); return *this; }
76 Flags & operator&=( Enum rhs ) { _val &= integral(rhs); return *this; }
78 Flags & operator|=( Flags rhs ) { _val |= integral(rhs); return *this; }
79 Flags & operator|=( Enum rhs ) { _val |= integral(rhs); return *this; }
81 Flags & operator^=( Flags rhs ) { _val ^= integral(rhs); return *this; }
82 Flags & operator^=( Enum rhs ) { _val ^= integral(rhs); return *this; }
85 constexpr operator Integral() const { return _val; }
87 constexpr Flags operator&( Flags rhs ) const { return Flags( _val & integral(rhs) ); }
88 constexpr Flags operator&( Enum rhs ) const { return Flags( _val & integral(rhs) ); }
90 constexpr Flags operator|( Flags rhs ) const { return Flags( _val | integral(rhs) ); }
91 constexpr Flags operator|( Enum rhs ) const { return Flags( _val | integral(rhs) ); }
93 constexpr Flags operator^( Flags rhs ) const { return Flags( _val ^ integral(rhs) ); }
94 constexpr Flags operator^( Enum rhs ) const { return Flags( _val ^ integral(rhs) ); }
96 constexpr Flags operator~() const { return Flags( ~_val ); }
98 constexpr bool operator==( Enum rhs ) const { return( _val == integral(rhs) ); }
99 constexpr bool operator!=( Enum rhs ) const { return( _val != integral(rhs) ); }
102 Flags & setFlag( Flags flag_r, bool newval_r ) { return( newval_r ? setFlag(flag_r) : unsetFlag(flag_r) ); }
103 Flags & setFlag( Enum flag_r, bool newval_r ) { return( newval_r ? setFlag(flag_r) : unsetFlag(flag_r) ); }
105 Flags & setFlag( Flags flag_r ) { _val |= integral(flag_r); return *this; }
106 Flags & setFlag( Enum flag_r ) { _val |= integral(flag_r); return *this; }
108 Flags & unsetFlag( Flags flag_r ) { _val &= ~integral(flag_r); return *this; }
109 Flags & unsetFlag( Enum flag_r ) { _val &= ~integral(flag_r); return *this; }
111 constexpr bool testFlag( Flags flag_r ) const { return testFlag( integral(flag_r) ); }
112 constexpr bool testFlag( Enum flag_r ) const { return testFlag( integral(flag_r) ); }
115 constexpr bool testFlag( Integral flag ) { return flag ? ( _val & flag ) == flag : !_val; }
117 constexpr static Integral integral( Flags obj ) { return obj._val; }
118 constexpr static Integral integral( Enum obj ) { return static_cast<Integral>(obj); }
122 ///////////////////////////////////////////////////////////////////
124 /** \relates Flags Stringify
125 * Build a string of OR'ed names of each flag value set in \a flag_r.
126 * Remaining bits in \a flag_r are added as hexstring.
128 * enum E { a=1, b=2, c=4 };
129 * ZYPP_DECLARE_FLAGS( E, MyFlags );
132 * cout << f << " = " << stringify( f, { {a,"A"}, {b,"B"} } ) << endl;
133 * // prints: 0x0007 = [A|B|0x4]
136 template<typename Enum>
137 std::string stringify( const Flags<Enum> & flag_r, const std::initializer_list<std::pair<Flags<Enum>,std::string> > & flaglist_r = {},
138 std::string intro_r = "[", std::string sep_r = "|", std::string extro_r = "]" )
140 std::string ret( std::move(intro_r) );
144 for ( const auto & pair : flaglist_r )
146 if ( flag_r.testFlag( pair.first ) )
151 if ( sep.empty() && !sep_r.empty() )
152 { sep = std::move(sep_r); }
155 mask = flag_r & ~mask;
159 ret += str::hexstring( mask, 0 );
161 ret += std::move(extro_r);
165 template<typename TEnum>
166 inline std::ostream & operator<<( std::ostream & str, const Flags<TEnum> & obj )
167 { return str << str::hexstring(obj); }
169 template<typename TEnum>
170 inline std::ostream & operator<<( std::ostream & str, const typename Flags<TEnum>::Enum & obj )
171 { return str << Flags<TEnum>(obj); }
173 /** \relates Flags */
174 #define ZYPP_DECLARE_FLAGS(Name,Enum) typedef zypp::base::Flags<Enum> Name
176 /** \relates Flags */
177 #define ZYPP_DECLARE_OPERATORS_FOR_FLAGS(Name) \
178 inline constexpr bool operator==( Name::Enum lhs, Name rhs ) { return( rhs == lhs ); } \
179 inline constexpr bool operator!=(Name:: Enum lhs, Name rhs ) { return( rhs != lhs ); } \
180 inline constexpr Name operator&( Name::Enum lhs, Name::Enum rhs ) { return Name( lhs ) & rhs; } \
181 inline constexpr Name operator&( Name::Enum lhs, Name rhs ) { return rhs & lhs; } \
182 inline constexpr Name operator|( Name::Enum lhs, Name::Enum rhs ) { return Name( lhs ) | rhs; } \
183 inline constexpr Name operator|( Name::Enum lhs, Name rhs ) { return rhs | lhs; } \
184 inline constexpr Name operator^( Name::Enum lhs, Name::Enum rhs ) { return Name( lhs ) ^ rhs; } \
185 inline constexpr Name operator^( Name::Enum lhs, Name rhs ) { return rhs ^ lhs; } \
186 inline constexpr Name operator~( Name::Enum lhs ) { return ~Name( lhs ); }
188 /** \relates Flags */
189 #define ZYPP_DECLARE_FLAGS_AND_OPERATORS(Name,Enum) \
190 ZYPP_DECLARE_FLAGS(Name,Enum); \
191 ZYPP_DECLARE_OPERATORS_FOR_FLAGS(Name)
193 /////////////////////////////////////////////////////////////////
195 ///////////////////////////////////////////////////////////////////
196 /////////////////////////////////////////////////////////////////
198 ///////////////////////////////////////////////////////////////////
199 #endif // ZYPP_BASE_FLAGS_H