<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/132139>132139</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [libc++] `std::function` with small object optimization copies instead of moves
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            libc++
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          BenjaminSchaaf
      </td>
    </tr>
</table>

<pre>
    When using `std::function` I noticed that *sometimes* the captured data is copied even if the `std::function` is only ever moved.

I've tracked this down to the following code:
https://github.com/llvm/llvm-project/blob/6003c3055a4630be31cc3d459cdbb88248a007b9/libcxx/include/__functional/function.h#L394

It looks like when the small object optimization is in use for `std::function`, then the captured data is copied instead of moved whenever the function is moved. In extreme cases this could result in massively more work being done.

The issue reproduces trivially, see godbolt: https://godbolt.org/z/czTev8jfc

Note that the captured data needs to be < `3*sizeof(void *)` and have `noexcept` on its copy constructor to trigger the small object optimization. When that's the case the data is copied instead of moved.

</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJyUlE-L4zgQxT-NfCk2KJKdPwcf0jMYGpa97MAcB_0px-qWVUGSnU5_-kVKml1m6VkWAnFi67nq916VSsmdA2LPuifWfW3UkieK_ROGFzW78KeZlBobTfbWf58wwJJcOAPb8ZQtkycmT-MSTHYU2I7DMwTKzqCFPKkMTJwSzZjdjImJE-QJwahLXiJasCorcAkMXRxawBUDuLE-85m8S0DB38qzEWZa0W4YPzF-emZivyLkqMxrfblLYOkaIFMVHMl7upbKDVkswvw05XxJ5VIMTAxnl6dFbwzNTAzerx9fv10ivaDJTAzak2Zi2HEujeRdp9qd5Brl1hhp2-5orNaHg2gPivO9PhYBp83bGxODC8YvFpkYfvz4aEh5JoaPH5uJCfm7PLaPfjJ4otcE3r0iXAv40kaalfdAuhQEdMludu-qHC9kXDGntBo_48fElyITfumDCymjskDjnXB9ewVeQT7UyoG7AfAcAN9yxLloJkx3-oYWbyFiWnwupc0laCv6G8wUEa4UX0FjccRSwIeN3yYEl9KCEPESyS6myEW3OuX9rZSfEOFMVpPPTJ7gJw_vNzYUz0wM70wM5v0broeX0dz1_6CM92T-m0BAtKnkRSMw-aUwlCW_7h1pZOKwkrMl0EwcSxRVsDCptWY1EL4ZvOTyf0GTK8wbGAopx8VkijWI0Z3PD46fOrmB73eHVGZinx6FJqwX_2FVodjYXtqjPKoG--2-FW277TrZTH1rt_Zgd1LpztpWbq3gB9ONrdlzITu7bVwvuOi4FJxLKaTcyA7lrhtR291ouJGs5Tgr5zdlLgrkpnrVb6XYymPjlUaf6h4RoiSfiaf6EWWvxL5Ok17OibXcu5TT3zrZZV830D-OdV8_XQNXl6dfzEKlk36mk5ol-v5_D31tMTExPLpce_FXAAAA__962rsW">