Thread overview
How to convert member function to free function?
Sep 18, 2020
Andrey Zherikov
Sep 18, 2020
H. S. Teoh
Sep 18, 2020
Andrey Zherikov
Sep 18, 2020
Andrey Zherikov
September 18, 2020
How can I rewrite foo() function as a free-function that won't cause struct copying? My simplified code is:
========
struct S
{
    ref S foo() return
    {
        return this;
    }
}

void main()
{
    S().foo().foo().foo();
}
========
If I write it like "auto foo(S s) { return s; }" then statement in main() will copy value of S three times and I want to avoid this.

September 18, 2020
On Fri, Sep 18, 2020 at 06:20:41PM +0000, Andrey Zherikov via Digitalmars-d-learn wrote:
> How can I rewrite foo() function as a free-function that won't cause
> struct copying? My simplified code is:
> ========
> struct S
> {
>     ref S foo() return
>     {
>         return this;
>     }
> }
> 
> void main()
> {
>     S().foo().foo().foo();
> }
> ========
> If I write it like "auto foo(S s) { return s; }" then statement in
> main() will copy value of S three times and I want to avoid this.

Why can't you return by ref, which would also avoid the copying?

	ref S foo(return ref S s) { return s; }


T

-- 
Let's not fight disease by killing the patient. -- Sean 'Shaleh' Perry
September 18, 2020
On Friday, 18 September 2020 at 18:43:38 UTC, H. S. Teoh wrote:
> Why can't you return by ref, which would also avoid the copying?
>
> 	ref S foo(return ref S s) { return s; }

Compiler errors out:
onlineapp.d(9): Error: function onlineapp.foo(return ref S s) is not callable using argument types (S)
onlineapp.d(9):        cannot pass rvalue argument S() of type S to parameter return ref S s


September 18, 2020
On Friday, 18 September 2020 at 18:20:41 UTC, Andrey Zherikov wrote:
> How can I rewrite foo() function as a free-function that won't cause struct copying?

I found solution:
========
struct S
{
    int i = -1;
    this(int n) {i=n;writeln(&this," ",i," ",__PRETTY_FUNCTION__);}
    this(ref return scope inout S rhs) inout {i=rhs.i+1;writeln(&this," ",i," ",__PRETTY_FUNCTION__);}
    ~this() {writeln(&this," ",i," ",__PRETTY_FUNCTION__);}
    ref auto getRef() return
    {
	    writeln(&this," ",i," ",__PRETTY_FUNCTION__);
        return this;
    }
}

ref auto foo(return ref S s)
{
    writeln(&s," ",s.i," ",__PRETTY_FUNCTION__);
    return s;
}

void main()
{
    S(5).getRef().foo().foo().foo();
}
========

Output confirms that there is no copying happens:
========
7FFDE98BDDF0 5 S onlineapp.S.this(int n) ref
7FFDE98BDDF0 5 onlineapp.S.getRef() ref return
7FFDE98BDDF0 5 onlineapp.foo(return ref S s) ref @system
7FFDE98BDDF0 5 onlineapp.foo(return ref S s) ref @system
7FFDE98BDDF0 5 onlineapp.foo(return ref S s) ref @system
7FFDE98BDDF0 5 void onlineapp.S.~this()
========