[Kde-bindings] Qyoto: new features
Richard Dale
richard.dale at telefonica.net
Mon Apr 9 22:48:57 UTC 2012
On Monday, April 09, 2012 11:26:09 PM Richard Dale wrote:
> 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);
> }
> }
And another attempt:
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 override string ToString() {
return i.ToString();
}
public QFlags(uint flags) {
i = flags;
// Throw an exception if this conversion fails
}
public static QFlags<T> operator|(QFlags<T> f1, T f2) {
uint i2 = Convert.ToUInt32(f2);
// Throw an exception if this conversion fails
return new QFlags<T>(f1.i | i2);
}
public static QFlags<T> operator&(QFlags<T> f1, T f2) {
uint i2 = Convert.ToUInt32(f2);
// Throw an exception if this conversion fails
return new QFlags<T>(f1.i & i2);
}
}
public class FlagsTest
{
public enum MyEnum : uint {
ValA = 0x0,
ValB = 0x1,
ValC = 0x2,
ValD = 0x4
}
public void MyMethod(QFlags<MyEnum> flags) {
Console.WriteLine(flags);
}
static public void Main()
{
FlagsTest test = new FlagsTest();
QFlags<MyEnum> f1 = new QFlags<MyEnum>(MyEnum.ValB);
QFlags<MyEnum> f2 = f1 & MyEnum.ValC;
test.MyMethod(f2 | MyEnum.ValD);
}
}
-- Richard
More information about the Kde-bindings
mailing list