Create template expression sequence
Menshikov
mensikovk817 at gmail.com
Thu Dec 2 15:54:17 UTC 2021
```d
import std.meta, std.stdio;
auto get0(A...)() => A[0];
struct A{int a = 4; int b = 2;}
void main(){
AliasSeq!(4, 2)[0].writeln;
get0!(4, 2).writeln;
A a;
a.tupleof[0].writeln;
get0!(a.tupleof).writeln;//error :(
}
```
I think this is a very, very big problem. Because of this
problem, there is literally a hell of string mixins going on. For
example, I have a structure A, it has some methods that I mark
with the Attr attribute. The task is to write a function that
will call each method of the argument a with such an attribute
and write its all attributes.
```d
enum Attr;
struct A{
int sample(float a) => cast(int) a + 1;//nope
@Attr int sample(int a) => a;//yep
}
void func(A)(in A a, int arg){
static foreach(symbol; getSymbolsByUDA!(A, Attr)){
/* and so, I need to call the `symbol` method via a.
This is where the problems begin,
because if I just can't do this mixin ("a." ~
Field.stringof)
I lose which overload I need to use */
}
}
```
Something terrible is usually written here.
OR the information about the field/method will be divided
literally into a separate variable that stores the value, and
into alias, which stores only information for introspection.
OR declare `enum` (already a problem specifically for static
foreach, if you want to declare something else outside the
scope), which contains` "a." ~ Symbol.stringof`, and each time
the variable is accessed, it is enclosed in mixin().
You also take into account that overloads are important here,
which will increase unreadability.
It is not normal.
Even so, if I replace A with a class that inherits from another
class that has @Attr, then getSymbolsByUDA literally breaks.
```d
enum Attr;
class B{
@Attr int a;
}
class A: B{
@Attr int b;
}
void main(){
pragma(msg, getSymbolsByUDA!(A, Attr));//ERROR!
}
```
If we could pass through the template parameter AND information
for introspection AND reference to runtime data, then there would
be no such hell.
If it were ExprSeq for example, then it would be solved simply:
```d
void func(A)(in A a, int arg){
static foreach(expr; getByUDA!(A, Attr)){
expr(arg).writeln;//expr.stringof == q{a.sample};
write("all UDAs: ");
static foreach(uda; __traits(getAttributes, expr)){
uda.stringof.write();
}
writeln();
}
}
```
I came across this when I was trying to bind D data to a script
language.
More information about the Digitalmars-d
mailing list