https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100249

            Bug ID: 100249
           Summary: missing forwarding std::__invoke result in
                    ranges::is_permutation and ranges::clamp
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: hewillk at gmail dot com
  Target Milestone: ---

Hey, in ranges::is_permutation in ranges_algo.h#L808:

    auto __proj_scan = std::__invoke(__proj1, *__scan);
    auto __comp_scan = [&] <typename _Tp> (_Tp&& __arg) {
      return std::__invoke(__pred, __proj_scan,
                           std::forward<_Tp>(__arg));
    };

the __proj_scan seems to forget to use auto&& to receive the std::__ invoke
call, which will cause compile failure if the return type is non-copyable:
https://godbolt.org/z/WaKc7bWM4

also, we should perfect forward the type of __proj_scan to the next
std::__invoke call, and ranges::clamp in ranges_algo.h#L3232 has the same
issue:

    auto&& __proj_val = std::__invoke(__proj, __val);
    if (std::__invoke(__comp, __proj_val, std::__invoke(__proj, __lo)))
      return __lo;

when the type of __proj_val is an rvalue reference, we need to convert it to
rvalue for the next std::__invoke call: https://godbolt.org/z/1G7aqxs3c.

So I think it should be relatively safe to inline all std::__invoke calls.

Reply via email to