Re: Struct initializer in UDA

2020-09-27 Thread realhet via Digitalmars-d-learn

On Sunday, 27 September 2020 at 11:59:49 UTC, Anonymouse wrote:

On Sunday, 27 September 2020 at 10:17:39 UTC, realhet wrote:
On Saturday, 26 September 2020 at 17:13:17 UTC, Anonymouse 
wrote:

On Saturday, 26 September 2020 at 16:05:58 UTC, realhet wrote:


That looks the closes to the python named parameters or the 
struct initializer.


For my use case this opDispatch trick seems to be more flexible 
than the named-parameters thing:


@(FieldProps().range(-360, 360).format("%.2f").caption("Turret 
rotation").unit("deg")) float alpha = 0;


for example if I use the name: "logRange" it can also set the 
isLogarithmic flag as a side effect to true inside the FieldProps 
struct. Just by choosing a slightly different name.


With this idealized format it would be not possible:
@FieldProps{ range: {-360, 360}, format:"%.2f", caption:"Turret 
rotation", unit:"deg"} float alpha = 0;


The more work inside the struct is not a problem, because I'm 
willing to use it from 1000 places. Also __traits(allMembers) can 
help.


Thank you!


Re: Struct initializer in UDA

2020-09-27 Thread Anonymouse via Digitalmars-d-learn

On Sunday, 27 September 2020 at 10:17:39 UTC, realhet wrote:
On Saturday, 26 September 2020 at 17:13:17 UTC, Anonymouse 
wrote:

On Saturday, 26 September 2020 at 16:05:58 UTC, realhet wrote:
The closest I can get is @(S.init.c(9).f(42)) with use of 
opDispatch, which is easier to read but still ugly.


All I can get is that the
- an identifier of a member is stronger than the opDispatch. -> 
Error: function expected before (), not S(0, 0).c of type int
- and if I prefix it with '_' it ruins toString. -> Error: no 
property toString for type onlineapp.S



import std.stdio, std.range, std.algorithm, std.traits, 
std.meta, std.conv, std.string, std.uni, std.meta, 
std.functional, std.exception;


struct S{
int a, b;

auto opDispatch(string name, T)(T value)
if(name.startsWith("_"))
{
mixin(name[1..$], "= value;");
return this;
}
}

void main(){
S.init._a(5).writeln;
}


Now I'm more confused, as the compiler completely ignores the 
if(name.startsWith("_")) constraint o.O


It works if you specialise opDispatch to take an int parameter 
instead of a type T. It smells like a bug but I don't know enough 
to say.


I used two opDispatches to be able to avoid having to use _a and 
_b, and std.algorithm.comparison.among to constrain them.


struct S{
private int _a, _b;

auto opDispatch(string name)(int value)
if (name.among("a", "b"))
{
mixin("_", name, "= value;");
return this;
}

auto opDispatch(string name)()
if (name.among("a", "b"))
{
mixin("return _", name, ";");
}
}

void main(){
S.init.a(123).b(456).writeln;
S().b(456).a(123).writeln;  // Alternative syntax, may not 
work if opCall is defined

}

It's brittle in that you have to update and sync the two 
among("a", "b") constraints every time you add or remove a field, 
but I can't seem to get the names by introspection without it 
endlessly recursing over opDispatch again.


Re: Struct initializer in UDA

2020-09-27 Thread realhet via Digitalmars-d-learn

On Saturday, 26 September 2020 at 17:13:17 UTC, Anonymouse wrote:

On Saturday, 26 September 2020 at 16:05:58 UTC, realhet wrote:
The closest I can get is @(S.init.c(9).f(42)) with use of 
opDispatch, which is easier to read but still ugly.


All I can get is that the
- an identifier of a member is stronger than the opDispatch. -> 
Error: function expected before (), not S(0, 0).c of type int
- and if I prefix it with '_' it ruins toString. -> Error: no 
property toString for type onlineapp.S



import std.stdio, std.range, std.algorithm, std.traits, std.meta, 
std.conv, std.string, std.uni, std.meta, std.functional, 
std.exception;


struct S{
int a, b;

auto opDispatch(string name, T)(T value)
if(name.startsWith("_"))
{
mixin(name[1..$], "= value;");
return this;
}
}

void main(){
S.init._a(5).writeln;
}


Now I'm more confused, as the compiler completely ignores the 
if(name.startsWith("_")) constraint o.O


Re: Struct initializer in UDA

2020-09-26 Thread Anonymouse via Digitalmars-d-learn

On Saturday, 26 September 2020 at 16:05:58 UTC, realhet wrote:

Hi,

  struct S{int a, b, c=9, d, e, f;}

Is there a way or a trick to declare an UDA by using a nice 
struct initializer?


It would be nice to be able to use the form:

  @S{f:42} int a;  //or something similar to this.

instead of this longer and error-prone way:

  @S(0, 0, 0, 9, 0, 42) int a;


I don't think you can currently, no, but I'd be happy to be 
proven wrong.


The closest I can get is @(S.init.c(9).f(42)) with use of 
opDispatch, which is easier to read but still ugly.


Struct initializer in UDA

2020-09-26 Thread realhet via Digitalmars-d-learn

Hi,

  struct S{int a, b, c=9, d, e, f;}

Is there a way or a trick to declare an UDA by using a nice 
struct initializer?


It would be nice to be able to use the form:

  @S{f:42} int a;  //or something similar to this.

instead of this longer and error-prone way:

  @S(0, 0, 0, 9, 0, 42) int a;