6bf7f10da5d4e83371b6371907600a31e6531a84
[platform/upstream/libzypp.git] / zypp / base / Flags.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/base/Flags.h
10  *
11 */
12 #ifndef ZYPP_BASE_FLAGS_H
13 #define ZYPP_BASE_FLAGS_H
14
15 #include "zypp/base/String.h"
16
17 ///////////////////////////////////////////////////////////////////
18 namespace zypp
19 { /////////////////////////////////////////////////////////////////
20   ///////////////////////////////////////////////////////////////////
21   namespace base
22   { /////////////////////////////////////////////////////////////////
23
24     ///////////////////////////////////////////////////////////////////
25     //
26     //  CLASS NAME : Flags<Enum>
27     //
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>
30      * \code
31      *  class RpmDb
32      *  {
33      *    public:
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
42      *      };
43      *
44      *      ZYPP_DECLARE_FLAGS(DbStateInfo,DbStateInfoBits);
45      *  };
46      *  ZYPP_DECLARE_OPERATORS_FOR_FLAGS(RpmDb::DbStateInfo);
47      *
48      *  ...
49      *  enum Other { OTHERVAL = 13 };
50      *  {
51      *    XRpmDb::DbStateInfo s;
52      *    s = XRpmDb::DbSI_MODIFIED_V4|XRpmDb::DbSI_HAVE_V4;
53      *    // s |= OTHERVAL; // As desired: it does not compile
54      *  }
55      * \endcode
56      */
57     template<typename _Enum>
58     class Flags
59     {
60       public:
61         typedef _Enum Enum;     ///< The underlying enum type
62         typedef typename std::underlying_type<Enum>::type Integral;     ///< The underlying integral type
63
64       public:
65         constexpr Flags()                               : _val( 0 ) {}
66         constexpr Flags( Enum flag_r )                  : _val( flag_r ) {}
67         explicit constexpr Flags( Integral flag_r )     : _val( flag_r ) {}
68
69         Flags & operator&=( Flags rhs )       { _val &= rhs._val; return *this; }
70         Flags & operator&=( Enum rhs )        { _val &= rhs;      return *this; }
71
72         Flags & operator|=( Flags rhs )       { _val |= rhs._val; return *this; }
73         Flags & operator|=( Enum rhs )        { _val |= rhs;      return *this; }
74
75         Flags & operator^=( Flags rhs )       { _val ^= rhs._val; return *this; }
76         Flags & operator^=( Enum rhs )        { _val ^= rhs;      return *this; }
77
78       public:
79         constexpr operator Integral() const             { return _val; }
80
81         constexpr Flags operator&( Flags rhs ) const    { return Flags( _val & rhs._val ); }
82         constexpr Flags operator&( Enum rhs ) const     { return Flags( _val & rhs ); }
83
84         constexpr Flags operator|( Flags rhs ) const    { return Flags( _val | rhs._val ); }
85         constexpr Flags operator|( Enum rhs ) const     { return Flags( _val | rhs ); }
86
87         constexpr Flags operator^( Flags rhs ) const    { return Flags( _val ^ rhs._val ); }
88         constexpr Flags operator^( Enum rhs ) const     { return Flags( _val ^ rhs ); }
89
90         constexpr Flags operator~() const               { return Flags( ~_val ); }
91
92       public:
93         Flags & setFlag( Flags flag_r, bool newval_r ) { return( newval_r ? setFlag(flag_r) : unsetFlag(flag_r) ); }
94         Flags & setFlag( Enum flag_r, bool newval_r )  { return( newval_r ? setFlag(flag_r) : unsetFlag(flag_r) ); }
95
96         Flags & setFlag( Flags flag_r )       { _val |= flag_r; return *this; }
97         Flags & setFlag( Enum flag_r )        { _val |= flag_r; return *this; }
98
99         Flags & unsetFlag( Flags flag_r )     { _val &= ~flag_r; return *this; }
100         Flags & unsetFlag( Enum flag_r )      { _val &= ~flag_r; return *this; }
101
102         bool testFlag( Flags flag_r ) const   { return ( _val & flag_r ) == flag_r; }
103         bool testFlag( Enum flag_r ) const    { return ( _val & flag_r ) == flag_r; }
104
105       private:
106         Integral _val;
107     };
108     ///////////////////////////////////////////////////////////////////
109
110     template<typename Enum>
111     inline std::ostream & operator<<( std::ostream & str, const Flags<Enum> & obj )
112     { return str << str::hexstring(obj); }
113
114     /** \relates Flags */
115 #define ZYPP_DECLARE_FLAGS(Name,Enum) typedef zypp::base::Flags<Enum> Name
116
117     /** \relates Flags */
118 #define ZYPP_DECLARE_OPERATORS_FOR_FLAGS(Name) \
119 inline constexpr Name operator&( Name::Enum lhs, Name::Enum rhs )       { return Name( lhs ) & rhs; }   \
120 inline constexpr Name operator&( Name::Enum lhs, Name rhs )             { return rhs & lhs; }           \
121 inline constexpr Name operator|( Name::Enum lhs, Name::Enum rhs )       { return Name( lhs ) | rhs; }   \
122 inline constexpr Name operator|( Name::Enum lhs, Name rhs )             { return rhs | lhs; }           \
123 inline constexpr Name operator^( Name::Enum lhs, Name::Enum rhs )       { return Name( lhs ) ^ rhs; }   \
124 inline constexpr Name operator^( Name::Enum lhs, Name rhs )             { return rhs ^ lhs; }           \
125 inline constexpr Name operator~( Name::Enum lhs )                       { return ~Name( lhs ); }
126
127     /** \relates Flags */
128 #define ZYPP_DECLARE_FLAGS_AND_OPERATORS(Name,Enum) \
129     ZYPP_DECLARE_FLAGS(Name,Enum); \
130     ZYPP_DECLARE_OPERATORS_FOR_FLAGS(Name)
131
132     /////////////////////////////////////////////////////////////////
133   } // namespace base
134   ///////////////////////////////////////////////////////////////////
135   /////////////////////////////////////////////////////////////////
136 } // namespace zypp
137 ///////////////////////////////////////////////////////////////////
138 #endif // ZYPP_BASE_FLAGS_H