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

Reply via email to