File indexing completed on 2024-04-28 05:32:10

0001 #ifndef oxygenflags_h
0002 #define oxygenflags_h
0003 /*
0004 * this file is part of the oxygen gtk engine
0005 * SPDX-FileCopyrightText: 2010 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0006 *
0007 * largely inspired from Flags
0008 * SPDX-FileCopyrightText: 2010 Nokia Corporation and/or its subsidiary(-ies).
0009 *
0010 * SPDX-License-Identifier: LGPL-2.0-or-later
0011 */
0012 
0013 namespace Oxygen
0014 {
0015 
0016     template<typename Enum>
0017     class Flags
0018     {
0019 
0020         public:
0021 
0022         typedef Enum enum_type;
0023         typedef unsigned long ValueType;
0024 
0025         //! copy constructor
0026         Flags( const Flags &f ):
0027             i(f.i)
0028         {}
0029 
0030         //! constructor
0031         Flags(Enum f):
0032             i(f)
0033         {}
0034 
0035         //! constructor
0036         Flags():
0037             i(0)
0038         {}
0039 
0040         //! destructor
0041         virtual ~Flags( void )
0042         {}
0043 
0044         //! assignment
0045         Flags &operator=(const Flags &f)
0046         {
0047             i = f.i;
0048             return *this;
0049         }
0050 
0051         //!@name binary operators and assignment
0052         //@{
0053         Flags &operator&=( ValueType mask)
0054         {
0055             i &= mask;
0056             return *this;
0057         }
0058 
0059         Flags &operator|=(Flags f)
0060         {
0061             i |= f.i;
0062             return *this;
0063         }
0064 
0065         Flags &operator|=(Enum f)
0066         {
0067             i |= f;
0068             return *this;
0069         }
0070 
0071         Flags &operator^=(Flags f)
0072         {
0073             i ^= f.i;
0074             return *this;
0075         }
0076 
0077         Flags &operator^=(Enum f)
0078         {
0079             i ^= f;
0080             return *this;
0081         }
0082 
0083         //@}
0084 
0085         //! conversion to int
0086         operator ValueType() const
0087         { return i; }
0088 
0089         //!@name binary operations (non assigned)
0090         //@{
0091         Flags operator|(Flags f) const
0092         {
0093             Flags g;
0094             g.i = i | f.i;
0095             return g;
0096         }
0097 
0098         Flags operator|(Enum f) const
0099         {
0100             Flags g;
0101             g.i = i | f;
0102             return g;
0103         }
0104 
0105         Flags operator^(Flags f) const
0106         {
0107             Flags g;
0108             g.i = i ^ f.i;
0109             return g;
0110         }
0111 
0112         Flags operator^(Enum f) const
0113         {
0114             Flags g;
0115             g.i = i ^ f;
0116             return g;
0117         }
0118 
0119         Flags operator&(ValueType mask) const
0120         {
0121             Flags g;
0122             g.i = i & mask;
0123             return g;
0124         }
0125 
0126         Flags operator&(Enum f) const
0127         {
0128             Flags g;
0129             g.i = i & f;
0130             return g;
0131         }
0132 
0133         Flags operator~() const
0134         {
0135             Flags g;
0136             g.i = ~i;
0137             return g;
0138         }
0139         //@}
0140 
0141         bool operator!() const
0142         { return !i; }
0143 
0144         bool testFlag(Enum f) const
0145         { return (i & f) == f && (f != 0 || i == ValueType(f) ); }
0146 
0147         private:
0148         ValueType i;
0149 
0150     };
0151 
0152     //! bitwise or
0153     template<typename Enum>
0154     Flags<Enum> operator|(Enum f1, Enum f2)
0155     { return Flags<Enum>(f1) | f2; }
0156 
0157     //! used for bitwise or between incompatible flags
0158     class IncompatibleFlag
0159     {
0160         public:
0161 
0162         //! constructor
0163         inline explicit IncompatibleFlag(int ai):
0164             i(ai)
0165             {}
0166 
0167         //! cast to int
0168         inline operator int() const
0169         { return i; }
0170 
0171         private:
0172         int i;
0173 
0174     };
0175 
0176 }
0177 
0178 #define OX_DECLARE_FLAGS(F, Enum)\
0179 typedef Flags<Enum> F;
0180 
0181 #define OX_DECLARE_INCOMPATIBLE_FLAGS(F) \
0182 inline Oxygen::IncompatibleFlag operator|(F::enum_type f1, int f2) \
0183 { return Oxygen::IncompatibleFlag(int(f1) | f2); }
0184 
0185 
0186 #define OX_DECLARE_OPERATORS_FOR_FLAGS(F) \
0187 inline Oxygen::Flags<F::enum_type> operator|(F::enum_type f1, F::enum_type f2) \
0188 { return Oxygen::Flags<F::enum_type>(f1) | f2; } \
0189 inline Oxygen::Flags<F::enum_type> operator|(F::enum_type f1, Oxygen::Flags<F::enum_type> f2) \
0190 { return f2 | f1; } \
0191 OX_DECLARE_INCOMPATIBLE_FLAGS(F)
0192 
0193 #endif