www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - UDA magic?

reply "evilrat" <evilrat666 gmail.com> writes:
Greetings,

it is possible to put function as attribute, but is this possible 
to get "subject" of UDA's? so combining both could we should get 
something like this:
----------------
// module scope or static struct member
int[Variant] values; // should be typeinfo?

void registerStructVal(alias val)()
{
   alias symbol = ... some pragma or trait to get struct S ... // 
not any yet?
   static if ( is(symbol == struct) )
   {
     values[val] = Variant(symbol);
   }
}

 (registerStructVal!42())
struct S {}

 (registerClassVal!3())
class C
{
int x;
this(int val) { x = val; }
}


void main()
{
writeln(values); // 42 = S, 3 = C
auto a = values[3](123); // ok for class there typeinfo.create, 
but how to call specific ctor using it?
writeln(a.x) // 123
}
----------------

it may be hacked some way like defining any specific UDA as tag, 
use module ctor or template to inject code into structs with that 
tag, or maybe other ways which would be intrusive. what i'm 
looking for is to be able declare such function/template 
non-intrusive way.
Apr 17 2014
next sibling parent "Rikki Cattermole" <alphaglosined gmail.com> writes:
On Thursday, 17 April 2014 at 09:39:01 UTC, evilrat wrote:
 Greetings,

 it is possible to put function as attribute, but is this 
 possible to get "subject" of UDA's? so combining both could we 
 should get something like this:
 ----------------
 // module scope or static struct member
 int[Variant] values; // should be typeinfo?

 void registerStructVal(alias val)()
 {
   alias symbol = ... some pragma or trait to get struct S ... 
 // not any yet?
   static if ( is(symbol == struct) )
   {
     values[val] = Variant(symbol);
   }
 }

  (registerStructVal!42())
 struct S {}

  (registerClassVal!3())
 class C
 {
 int x;
 this(int val) { x = val; }
 }


 void main()
 {
 writeln(values); // 42 = S, 3 = C
 auto a = values[3](123); // ok for class there typeinfo.create, 
 but how to call specific ctor using it?
 writeln(a.x) // 123
 }
 ----------------

 it may be hacked some way like defining any specific UDA as 
 tag, use module ctor or template to inject code into structs 
 with that tag, or maybe other ways which would be intrusive. 
 what i'm looking for is to be able declare such 
 function/template non-intrusive way.
Theres no way right now to grab the type that a UDA is on. The only way I know how that is 100% going to work is: struct S(alias T) { alias T me; } S!(x) int x; void main() { assert(x == 0); __traits(getAttributes, x)[0].me = 5; assert(x == 5); } There may be another way.. But its not nice. By far. And thats to parse allMembers (not really reasonable). Either way I say, we need a new trait for this. Perhaps given that UDA's shouldn't be classes that we could repurpose parent for this as it kinda make sense imho.
Apr 17 2014
prev sibling parent reply "Dicebot" <public dicebot.lv> writes:
Right now it is impossible by the design of feature. UDA's are 
just bits of information attached to symbols. They don't affect 
type of symbol and their own type is affected by symbol either. 
Such enhancement is theoretically possible but that would have 
been a very big change.

Current idiomatic way to do such stuff is to have single mixin 
statement that iterates over all symbols of a module and does 
something for those that have specific UDA attached:

 token!42
void foo() {}

mixin registerAllTokens!modname;
Apr 17 2014
parent reply "evilrat" <evilrat666 gmail.com> writes:
On Thursday, 17 April 2014 at 13:22:01 UTC, Dicebot wrote:
 Right now it is impossible by the design of feature. UDA's are 
 just bits of information attached to symbols. They don't affect 
 type of symbol and their own type is affected by symbol either. 
 Such enhancement is theoretically possible but that would have 
 been a very big change.

 Current idiomatic way to do such stuff is to have single mixin 
 statement that iterates over all symbols of a module and does 
 something for those that have specific UDA attached:

  token!42
 void foo() {}

 mixin registerAllTokens!modname;
ok. i just thinking this is the way, but was hoped not only way though :( thanks everyone for clarification.
Apr 17 2014
parent "Dicebot" <public dicebot.lv> writes:
On Thursday, 17 April 2014 at 13:34:20 UTC, evilrat wrote:
 ok. i just thinking this is the way, but was hoped not only way 
 though :(

 thanks everyone for clarification.
I don't see anything inherently bad with this approach. Main problem is lack of some often used reflection utilities in Phobos but resulting code itself is pretty clean and maintainable.
Apr 17 2014