Skip to content

Comments

Fix capture of same variable twice - closes #237#245

Merged
hsutter merged 1 commit intohsutter:mainfrom
filipsajdak:fsajdak-fix-capture-same-variable-twice
Jan 29, 2023
Merged

Fix capture of same variable twice - closes #237#245
hsutter merged 1 commit intohsutter:mainfrom
filipsajdak:fsajdak-fix-capture-same-variable-twice

Conversation

@filipsajdak
Copy link
Contributor

In the current implementation, when the move from the last use happens to a variable captured, it will be captured twice: one by copy and one moved.

That means that the following code:

#include "boost/ut.hpp"
#include "html/html.h2"

using namespace boost::ut;
using namespace std::literals;

main: () -> int = {
    test("html::element") = :() = {
        e: html::element = ("tag");

        should("setting attribute") = :() = {
            mut(e$).set_attribute("name", "value");
            expect(eq(to_string(e$), std::string_view("<tag name=\"value\"></tag>")));
        };
    };
}

Will generate (skipping boilerplate):

[[nodiscard]] auto main() -> int{
    test("html::element") = [](){
        html::element e {"tag"}; 

        should("setting attribute") = [_0 = e, _1 = std::move(e)](){
            CPP2_UFCS(set_attribute, mut(_0), "name", "value");
            expect(eq(to_string(_1), std::string_view("<tag name=\"value\"></tag>")));
        };
    };
}

This change makes cppfront identify that variable is moved, capture it once by the move, and use it multiple times. That means that the above code will generate the following:

[[nodiscard]] auto main() -> int{
    test("html::element") = [](){
        html::element e {"tag"}; 

        should("setting attribute") = [_0 = std::move(e)](){
            CPP2_UFCS(set_attribute, mut(_0), "name", "value");
            expect(eq(to_string(_0), std::string_view("<tag name=\"value\"></tag>")));
        };
    };
}

In current implementation when move from last use happen to variable
that is captured it will be captured twice: one by copy and one moved.

This change makes cppfront indentify that variable is moved and capture
it once by the move and use multiple times.
@filipsajdak
Copy link
Contributor Author

There is only one change in regression tests - in mixed-function-expression-with-repeated-capture.cpp file. The following code:

    y := "\n";
    std::ranges::for_each
        ( view, :(x:_) = { std::cout << y$ << x << y$; } );

Generates:

     auto y {"\n"}; 
     std::ranges::for_each
         ( view, [_0 = std::move(y)](auto const& x){std::cout << _0 << x << _0;});

instead of the following:

     auto y {"\n"}; 
     std::ranges::for_each
         ( view, [_0 = y, _1 = std::move(y)](auto const& x){std::cout << _0 << x << _1;});

@filipsajdak
Copy link
Contributor Author

I have added overload of the print_to_string function that takes a pointer to std::string that will make it possible to eliminate an additional bunch of calls to printer.emit_to_string() that need to match earlier call to printer.emit_to_string(&str).

The new overload looks:

    void print_to_string(std::string* str, auto& i, auto... more) {
         printer.emit_to_string(str);
         emit(i, more...);
         printer.emit_to_string();
     };

@hsutter
Copy link
Owner

hsutter commented Jan 29, 2023

Looks good, thanks!

@hsutter hsutter merged commit 94f0796 into hsutter:main Jan 29, 2023
@filipsajdak filipsajdak deleted the fsajdak-fix-capture-same-variable-twice branch January 29, 2023 01:27
Azmah-Bad pushed a commit to Azmah-Bad/cppfront that referenced this pull request Feb 24, 2023
In current implementation when move from last use happen to variable
that is captured it will be captured twice: one by copy and one moved.

This change makes cppfront indentify that variable is moved and capture
it once by the move and use multiple times.
Azmah-Bad pushed a commit to Azmah-Bad/cppfront that referenced this pull request Feb 24, 2023
In current implementation when move from last use happen to variable
that is captured it will be captured twice: one by copy and one moved.

This change makes cppfront indentify that variable is moved and capture
it once by the move and use multiple times.
zaucy pushed a commit to zaucy/cppfront that referenced this pull request Dec 5, 2023
In current implementation when move from last use happen to variable
that is captured it will be captured twice: one by copy and one moved.

This change makes cppfront indentify that variable is moved and capture
it once by the move and use multiple times.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants