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