[Kde-bindings] Qyoto: new features

Richard Dale richard.dale at telefonica.net
Mon Apr 9 22:26:09 UTC 2012


On Monday, April 09, 2012 09:35:31 PM Richard Dale wrote:
> On Monday, April 09, 2012 01:27:35 PM Dimitar Dobrev wrote:
> 
> It works because while QFlags are not technically enums, they do nothing but
> provide type safety for C++ enums, that is, practically they are enums. On
> the C# side, enums are natively type-safe so it is completely correct to
> replace QFlags with Enum.
> 
> 
> Well no I don't think that's right. If you pass 'EnumA & EnumB' as a
> argument that value isn't an enum, it is an unsigned int. The QFlags stuff
> is about constructing unsigned ints from enums that are AND'd and OR'd
> together in a type safe manner.
> 

Here is my crappy attempt to do something like the Qt QFlags class in C#:

/*
C++ QFlags class from qglobal.h:

template<typename Enum>
class QFlags
{
    typedef void **Zero;
    int i;
public:
    typedef Enum enum_type;
    inline QFlags(const QFlags &f) : i(f.i) {}
    inline QFlags(Enum f) : i(f) {}
    inline QFlags(Zero = 0) : i(0) {}
    inline QFlags(QFlag f) : i(f) {}

    inline QFlags &operator=(const QFlags &f) { i = f.i; return *this; }
    inline QFlags &operator&=(int mask) { i &= mask; return *this; }
    inline QFlags &operator&=(uint mask) { i &= mask; return *this; }
    inline QFlags &operator|=(QFlags f) { i |= f.i; return *this; }
    inline QFlags &operator|=(Enum f) { i |= f; return *this; }
    inline QFlags &operator^=(QFlags f) { i ^= f.i; return *this; }
    inline QFlags &operator^=(Enum f) { i ^= f; return *this; }

    inline operator int() const { return i; }

    inline QFlags operator|(QFlags f) const { QFlags g; g.i = i | f.i; return 
g; }
    inline QFlags operator|(Enum f) const { QFlags g; g.i = i | f; return g; }
    inline QFlags operator^(QFlags f) const { QFlags g; g.i = i ^ f.i; return 
g; }
    inline QFlags operator^(Enum f) const { QFlags g; g.i = i ^ f; return g; }
    inline QFlags operator&(int mask) const { QFlags g; g.i = i & mask; return 
g; }
    inline QFlags operator&(uint mask) const { QFlags g; g.i = i & mask; 
return g; }
    inline QFlags operator&(Enum f) const { QFlags g; g.i = i & f; return g; }
    inline QFlags operator~() const { QFlags g; g.i = ~i; return g; }

    inline bool operator!() const { return !i; }

    inline bool testFlag(Enum f) const { return (i & f) == f && (f != 0 || i 
== int(f) ); }
};
*/


using System;

public class QFlags<T> where T : struct
{
    public uint i;
    public QFlags(T flags) {
        i = Convert.ToUInt32(flags); 
	// Throw an exception if this conversion fails
    }

    public static uint operator|(QFlags<T> f1, T f2) { 
      uint i2 = Convert.ToUInt32(f2);    
	// Throw an exception if this conversion fails
      return f1.i | i2;
    }    

    public static uint operator&(QFlags<T> f1, T f2) { 
      uint i2 = Convert.ToUInt32(f2);    
	// Throw an exception if this conversion fails
      return f1.i & i2;
    }    
}


public class FlagsTest
{
    public enum MyEnum : uint {
        ValA = 0x0,
        ValB = 0x1,
        ValC = 0x2,
        ValD = 0x4
    }
      
    static public void Main()
    {
        QFlags<MyEnum> f1 = new QFlags<MyEnum>(MyEnum.ValB);
        uint f2 = f1 | MyEnum.ValC;
        Console.WriteLine(f2);
    }
}

-- Richard



More information about the Kde-bindings mailing list