Re: opDispatch and @property setters

2016-06-21 Thread Lodovico Giaretta via Digitalmars-d-learn

On Tuesday, 21 June 2016 at 21:11:39 UTC, ag0aep6g wrote:
Works when you change the return type of the the @property 
opDispatch to auto, so that it can return the result. It's a 
little weird, but D does support calling functions with 
assignment syntax.


Alternatively, maybe you can actually check for the @property 
attribute in hasAssignableProperty. See 
FunctionAttribute/functionAttributes in std.traits [1]. I 
haven't tested this.



[1] http://dlang.org/phobos/std_traits.html#.FunctionAttribute


Thank you very much!

I managed to get it to work by using this code:

@property auto opDispatch(string name, Arg)(Arg arg)
{
mixin("return _p_data." ~ name ~ " = arg;");
}

It's a little weird, but D does support calling functions with 
assignment syntax.


Definitely strange.


Re: opDispatch and @property setters

2016-06-21 Thread ag0aep6g via Digitalmars-d-learn

On 06/21/2016 10:48 PM, Lodovico Giaretta wrote:

 struct Wrapper(T)
 {
 private T wrapped;

 template hasAssignableProperty(string name, Arg)
 {
 enum bool hasAssignableProperty = is(typeof(
 (ref T val, ref Arg arg)
 {
 mixin("val." ~ name ~ " = arg;");
 }));
 }

 @property void opDispatch(string name, Arg)(Arg arg)
 if (hasAssignableProperty!(name, Arg))
 {
 pragma(msg, "@property ", name, " ", Arg);
 mixin("return wrapped." ~ name ~ " = arg;");
 }
 auto opDispatch(string name, Args...)(Args args)
 {

[...]

 }
 }

[...]

 struct Foo
 {

[...]

 int baz(int val) { return val; } // <-- method with exactly one
argument
 }

 void main()
 {

[...]

 int bazres = wf.baz(42); // ERROR: no property 'baz' (it's
trying to use the first opDispatch overload, while the second would be ok)
 }

Any way around this issue?


Works when you change the return type of the the @property opDispatch to 
auto, so that it can return the result. It's a little weird, but D does 
support calling functions with assignment syntax.


Alternatively, maybe you can actually check for the @property attribute 
in hasAssignableProperty. See FunctionAttribute/functionAttributes in 
std.traits [1]. I haven't tested this.



[1] http://dlang.org/phobos/std_traits.html#.FunctionAttribute


opDispatch and @property setters

2016-06-21 Thread Lodovico Giaretta via Digitalmars-d-learn

Hi,

I'm trying to achieve perfect forwarding of any invocation from 
the wrapper to the wrapped item, but I'm having a bad time with 
@property.


Suppose this is my wrapper (with all logic stripped):

struct Wrapper(T)
{
private T wrapped;

template hasAssignableProperty(string name, Arg)
{
enum bool hasAssignableProperty = is(typeof(
(ref T val, ref Arg arg)
{
mixin("val." ~ name ~ " = arg;");
}));
}

@property void opDispatch(string name, Arg)(Arg arg)
if (hasAssignableProperty!(name, Arg))
{
pragma(msg, "@property ", name, " ", Arg);
mixin("return wrapped." ~ name ~ " = arg;");
}
auto opDispatch(string name, Args...)(Args args)
{
static if (Args.length > 0)
{
pragma(msg, name, " ", Args);
mixin("return wrapped." ~ name ~ "(args);");
}
else
{
pragma(msg, name);
mixin("return wrapped." ~ name ~ ";");
}
}
}

It correctly handles any property, but the existence of the 
@property setter dispatcher makes me unable to use any method 
that accepts just one parameter, because the compiler tries to 
resolve it with the first opDispatch overload, misinterpreting it 
as a setter call.


Here is an example:

struct Foo
{
private int _x;
@property int x() { return _x; }
@property void x(int newx) { _x = newx; }

long foo(string a, double b) const { return 0; }
void bar() {}
int baz(int val) { return val; } // <-- method with 
exactly one argument

}

void main()
{
alias WrappedFoo = Wrapper!Foo;
WrappedFoo wf;

wf.x = 3;
assert(wf.x == 3);

long foores = wf.foo("hello", 3.14);
wf.bar;

int bazres = wf.baz(42); // ERROR: no property 'baz' 
(it's trying to use the first opDispatch overload, while the 
second would be ok)

}

Any way around this issue?

Thank you in advance, and sorry if the question is silly and I'm 
just missing something stupid.


Lodovico Giaretta