Re: opDispatch and @property setters
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
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
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