digitalmars.D.learn - UDA status
- simendsjo (17/17) Mar 11 2013 I've been trying UDAs today, but I'm hitting roadblocks all the
- simendsjo (203/220) Mar 11 2013 Some update.. Using a custom Tuple(T...) makes things a bit
- Jacob Carlborg (6/10) Mar 17 2013 You need to use TypeTuple and not Tuple. This is my library functions
- simendsjo (21/32) Mar 17 2013 Thanks. I've gotten quite far already:
I've been trying UDAs today, but I'm hitting roadblocks all the time.. For instance: (10) struct A; pragma(msg, __traits(getAttributes, A)); // Empty (10) struct B {} pragma(msg, __traits(getAttributes, B)); // tuple(10) I've encountered several other things that has been difficult, especially when combining values and types and trying to manipulate these (might be some Tuple related stuff I'm not getting though). Are there many outstanding issues regarding UDAs? Many fixes in 2.063? I cannot find many tickets regarding UDAs in bugzilla. Seems std.traits isn't updated for UDAs either. So what's the status of UDAs? Anyone have experience using them yet?
Mar 11 2013
On Monday, 11 March 2013 at 19:03:49 UTC, simendsjo wrote:I've been trying UDAs today, but I'm hitting roadblocks all the time.. For instance: (10) struct A; pragma(msg, __traits(getAttributes, A)); // Empty (10) struct B {} pragma(msg, __traits(getAttributes, B)); // tuple(10) I've encountered several other things that has been difficult, especially when combining values and types and trying to manipulate these (might be some Tuple related stuff I'm not getting though). Are there many outstanding issues regarding UDAs? Many fixes in 2.063? I cannot find many tickets regarding UDAs in bugzilla. Seems std.traits isn't updated for UDAs either. So what's the status of UDAs? Anyone have experience using them yet?Some update.. Using a custom Tuple(T...) makes things a bit smoother. Here's my first working test with two templates: hasAttr to see if an attribute exists, and attrOfType to get all attributes matching a type (not sure if I should include values..) module uda; debug(UDA) import std.stdio; template attrOfType(alias OfType, alias Source) { alias _attrOfType!(OfType, AttributeTuple!Source) attrOfType; } template hasAttr(alias S, alias A) { bool _hasAttr() { version(none) { debug(UDA) pragma(msg, "hasAttr(", TypeOf!S, ", ", A, ")"); debug(UDA) pragma(msg, " attributes: ", __traits(getAttributes, TypeOf!S)); } foreach(attr; __traits(getAttributes, TypeOf!S)) { static if(isSameAttribute!(attr, A)) return true; } return false; } enum hasAttr = _hasAttr(); } unittest { struct A1 { int i; } struct NoAttr {} assert(!hasAttr!(NoAttr, A1)); NoAttr noAttr; assert(!hasAttr!(noAttr, A1)); A1 struct AttrType {} assert( hasAttr!(AttrType, A1)); AttrType attrType; assert( hasAttr!(attrType, A1)); A1(10) struct AttrValue {} assert( hasAttr!(AttrValue, A1(10))); assert(!hasAttr!(AttrValue, A1(0))); assert(!hasAttr!(AttrValue, A1)); AttrValue attrValue; assert( hasAttr!(attrValue, A1(10))); assert(!hasAttr!(attrValue, A1(0))); assert(!hasAttr!(attrValue, A1)); (10) struct AttrPrimitive {} assert( hasAttr!(AttrPrimitive, 10)); } //////////////////////////////////////////// //////////////////////////////////////////// /// /// PRIVATE /// //////////////////////////////////////////// //////////////////////////////////////////// private: template isInstanceOrLiteral(alias S) { enum isInstanceOrLiteral = __traits(compiles, typeof(S)); } template isInstanceOrLiteral(T) { enum isInstanceOrLiteral = false; } unittest { assert(!isInstanceOrLiteral!int); int i; assert( isInstanceOrLiteral!i); assert( isInstanceOrLiteral!10); struct S {} assert(!isInstanceOrLiteral!S); S s; assert( isInstanceOrLiteral!s); class C {} assert(!isInstanceOrLiteral!C); C c; assert(isInstanceOrLiteral!c); } template TypeOf(alias S) { static if(isInstanceOrLiteral!S) alias typeof(S) TypeOf; else alias S TypeOf; } unittest { struct S {} assert( is(TypeOf!S == S)); S s; assert( is(TypeOf!s == S)); } template Tuple(T...) { alias T Tuple; } template AttributeTuple(alias T) { alias Tuple!(__traits(getAttributes, T)) AttributeTuple; } unittest { struct NoAttrs {} assert( AttributeTuple!(NoAttrs).length == 0); struct A1 {} A1 struct S1 {} assert( AttributeTuple!(S1).length == 1); assert( is(AttributeTuple!(S1)[0] == A1)); (10, "aoeu", A1) struct S2 {} assert( AttributeTuple!(S2).length == 3); assert( AttributeTuple!(S2)[0] == 10); assert( AttributeTuple!(S2)[1] == "aoeu"); assert( is(AttributeTuple!(S2)[2] == A1)); struct A2 { int i; } A2 A2(10) struct S3 {} assert( AttributeTuple!(S3).length == 2); assert( is(AttributeTuple!(S3)[0] == A2)); assert(!is(AttributeTuple!(S3)[1] == A2)); // static type - not equal assert( AttributeTuple!(S3)[1] == A2(10)); } template isSameAttribute(alias A, alias B) { static if(isInstanceOrLiteral!A && isInstanceOrLiteral!B) static if(__traits(compiles, A == B)) enum isSameAttribute = A == B; else enum isSameAttribute = false; else static if(!isInstanceOrLiteral!A && !isInstanceOrLiteral!B && is(A == B)) enum isSameAttribute = true; else enum isSameAttribute = false; } template isSameAttribute(A, B) { enum isSameAttribute = is(A == B); } template isSameAttribute(alias A, B) { enum isSameAttribute = false; } template isSameAttribute(A, alias B) { enum isSameAttribute = false; } unittest { assert( isSameAttribute!(1, 1)); assert(!isSameAttribute!(1, 2)); assert( isSameAttribute!("aoeu", "aoeu")); assert(!isSameAttribute!("aoeu", "qwerty")); assert( isSameAttribute!(int, int)); assert(!isSameAttribute!(int, uint)); assert(!isSameAttribute!(int, 1)); assert(!isSameAttribute!(1, int)); struct S {int i;} assert(!isSameAttribute!(S(1), 1)); assert( isSameAttribute!(S(1), S(1))); } private template _attrOfType(alias OfType, Attrs...) { static if(Attrs.length == 0) { alias Tuple!() _attrOfType; } else static if(Attrs.length == 1) { static if(isSameAttribute!(Attrs[0], OfType)) alias Tuple!(Attrs[0]) _attrOfType; else alias Tuple!() _attrOfType; } else { alias _attrOfType!(OfType, Attrs[1..$]) Rest; static if(isSameAttribute!(Attrs[0], OfType)) alias Tuple!(Attrs[0], Rest) _attrOfType; else alias Tuple!(Rest) _attrOfType; } } unittest { struct A1 { int i; } (1, A1, A1(1), A1(2)) struct S1 {} assert(attrOfType!(2, S1).length == 0); assert(attrOfType!(1, S1).length == 1); assert(attrOfType!(1, S1)[0] == 1); assert(attrOfType!(A1, S1).length == 1); assert(is(attrOfType!(A1, S1)[0] == A1)); assert(attrOfType!(A1(1), S1).length == 1); assert(attrOfType!(A1(1), S1)[0] == A1(1)); assert(attrOfType!(A1(2), S1).length == 1); assert(attrOfType!(A1(2), S1)[0] == A1(2)); }
Mar 11 2013
On 2013-03-11 21:41, simendsjo wrote:Some update.. Using a custom Tuple(T...) makes things a bit smoother. Here's my first working test with two templates: hasAttr to see if an attribute exists, and attrOfType to get all attributes matching a type (not sure if I should include values..)You need to use TypeTuple and not Tuple. This is my library functions for UDA's: https://github.com/jacob-carlborg/orange/blob/master/orange/core/Attribute.d -- /Jacob Carlborg
Mar 17 2013
On Sunday, 17 March 2013 at 14:46:59 UTC, Jacob Carlborg wrote:On 2013-03-11 21:41, simendsjo wrote:Thanks. I've gotten quite far already: struct A { int i; } ("struct S") struct S { ("int i", 0, 1, S, A(-1)) int i; ("string a", "aoeu", 2, string, A(10)) string a; ("long f(int i)") long f(int i) { return i; } } alias TypeTuple!( TupleWrapper!(S, "struct S") , TupleWrapper!(S.i, "int i", 0, 1, S, A(-1)) , TupleWrapper!(S.a, "string a", "aoeu", 2, string, A(10)) , TupleWrapper!(S.f, "long f(int i)") ) Expected; alias getMembersAndAttributes!S Actual; static assert(isEqual!(TupleWrapper!Expected, TupleWrapper!Actual));Some update.. Using a custom Tuple(T...) makes things a bit smoother. Here's my first working test with two templates: hasAttr to see if an attribute exists, and attrOfType to get all attributes matching a type (not sure if I should include values..)You need to use TypeTuple and not Tuple. This is my library functions for UDA's: https://github.com/jacob-carlborg/orange/blob/master/orange/core/Attribute.d
Mar 17 2013