tcbrindle / flux

A C++20 library for sequence-orientated programming
https://tristanbrindle.com/flux/
Boost Software License 1.0
513 stars 30 forks source link

Trim implemented by two drop_while and reverse not working #52

Closed jnytra closed 1 year ago

jnytra commented 1 year ago

I'm trying to implement trim by two drop_while and reverse, but I am getting compilation error.

    std::string s = "   abc     ";
    flux::write_to(flux::from(s).drop_while(isspace)
                                .reverse()
                                .drop_while(isspace)
                                .reverse(), std::cout);

https://godbolt.org/z/TPqT6dec7

tcbrindle commented 1 year ago

Thanks for the bug report.

I can see the problem -- in reverse_adaptor we wrap the underlying cursor type in a rev_cur<cursor_t<Base>> object. But when constructing a rev_cur in reverse_adaptor's first() and last() implementations we are relying on CTAD, and when cursor_t<Base> is itself a specialisation of rev_cur then this is going to copy/move construct an object of the same type!

The solution is for reverse_adaptor to correctly explicitly instantiate a rev_cur<cursor_t<Base>>(base_cur) rather than me being lazy and just saying rev_cur(base_cur).

(It occurs to me that unwrapping rev_curs isn't necessarily a terrible idea, but I'd have to work out how this could be done without breaking other stuff.)