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

    <tr>
        <th>Summary</th>
        <td>
            [libc++] `shrink_to_fit` never shrinks
        </td>
    </tr>

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

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

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

<pre>
    The current implementation of the `shrink_to_fit` function in `vector<bool>` effectively acts as a no-op, failing to shrink the capacity to fit the size. This can be demonstrated with the following example:

[Godbolt Link](https://godbolt.org/z/cYs9bMn9f)

```cpp
#include <iostream>
#include <vector>

int main() {
  std::vector<bool> v(1024, true);
  std::cout << "Before shrink: capacity = " << v.capacity() << '\n';

  v.erase(v.begin() + 512, v.end());
  v.shrink_to_fit();
  std::cout << "After shrink:  capacity = " << v.capacity() << '\n';

  v.erase(v.begin(), v.end());
  v.shrink_to_fit();
  std::cout << "After shrink:  capacity = " << v.capacity() << '\n';
}
```

Program output:

```
Before shrink: capacity = 1024
After shrink:  capacity = 1024
After shrink:  capacity = 1024
```


This is because the current implementation of `shrink_to_fit` checks the following condition

```cpp
if (__external_cap_to_internal(size()) > __cap_) {
  try {
    do_shrink();
  } catch (...) {
  }  
}
```

However, this condition is **always false**, as the number of used internal words `__external_cap_to_internal(size())` will never exceed the internal storage capacity `__cap_`. Thus, the above implementation is equivalent to 

```cpp
if (false) {
  ...
}
```

which will never shrink. 

While the current implementation of `shrink_to_fit` technically conforms to the standard—since the shrink-to-fit request is non-binding—it appears to be a logical error that messed up `>` and `<`, particularly since a similar logical error was found in the `__split_buffer::reserve`, where `<` was incorrectly used instead of `>` (an issue reported in #105681 and fixed in #115735).


#### Proposed Solution

If the intent is to keep the existing no-op behavior, the function should be modified to have an empty body. The current implementation, which is non-empty yet effectively behaves as empty, is misleading.

Another approach would be modifying `shrink_to_fit` to actually perform capacity reduction, aligning its behavior with the `shrink_to_fit` function of `std::vector<T>`. This approach is currently being pursued in #120495. 
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzMVl1v6zYP_jXKDVHDkeN8XOQiTU_ed8AGHGAFhl0FskzHWmXJR5Kd5vz6gbLz0aztPoABA4ymlijy4cNHNIX36mAQ1yx_ZPnTRHShtm59VMag47N8UtjytH6uEWTnHJoAqmk1NmiCCMoasBWEGoHNU187ZV72we4rFdg8haozMtooQ_s9ymAdy7aFtZplX8gEqwplUD3qEwgZPAgPAox9sC3jW6iE0socIFgYvMdYUrRCqnCi5UqFuObVd0zguVYepDBQIJTYWOODEwFLOKpQR7vKam2P5BNfBWXCsg1L45M__s-WhdUBflTmheVPjC_rEFpPJnzH-O4w7CfWHRjffWd8J3_1q-Ins6oYX41u5unwyLalV54pI3VXIrBsq6wPDkVD2d_vnen5MvhRJkAjlGF8yfgK2OKRpRsAH0qCk23u2YSe8eU05TPiLbgOCVF2d0jaLlAslm2Bcf6IlXU4UsuyzZVZlj2Rwdm2T847ZzhnHwuWbw39xFAxWp-gEx4ZX_ZJgYdrCvwR8iknfH2CphyWb2D2yVsJDft_ksOmCuhuUvhXc_jPY1883UpwyOarswcnGrBdaLtw1fuN1edCiKpKN5-j_TtGdwBZuokXV3koUIrO43DNP2w47zUbWaN88Xd3XFpTKjr17t1UFTC-3O_xNaAzQu-laMmjMsM740tqK5daA12zfbS6vZLBnS7_A5R2P2b_RgJs8QRSBFlTyCRJbh3QHnxUvf_bI_bo4q2O3e2cEtHF-IbxjdBHcfJQCU2K3cRnS52UyDBdU6Aj1jqPJZxzg6N1pScm_3r-RPNRaQ2GEAG-SsQyBrl49cE6cbhp0TFAZGyeUn_u_JAJgihsj_fFVR7wW6d6oanywcInhRvzvfJItH7A4rFWsr4FP9QoGf3_Uiv9T0QXUNZGSaH1iQpTWdd4Qh2_SEGYUriSfeFsmbLVzCsjhyCDn4dgH-jz5fBbhz5Q7saah0KZUpnD5ZgKINoWhYueCwQB2h4oKKBz1kGoRYAGPZW3awnn-HEVphzetvSXb6EVLijZaeH0CQY4ArxqlBbuzulReKhsZ0gx5w_8fu9brcK-6KoK3dDRHHp0PY4BjjU6vMaMXpSR1jmUQZ_OEvQBRTlyOmJlfCmo_L5DcNhaF6IlMJ5N03y-nMZsKvV6XZ7miyxnfJVcugjj2eWBr862luL9bHV37QE_VBfFmsh5sPCC2MZVfFU-UOOIEwgUWIteWXeW7GWg8bXtdEnFaGypKkXXwEItegRhAJs2nIAGJ1L8R5oa-CJZjoUfjp0wvJmKIgaMg1E0oGPKQ6O8RkFCGdPfGBtqdKQVZwWJ_Q3EE2X1roQtDV5dlHCLjiR8vb0Oy06ewQqtDobcqOAv1Fwnq08nwPH-_GF4eR7KP05uF-zU5wbSIgMUtO2c767F5-lslScwKddZucpWYoLr6SKb51m6XC0m9brK5-V0lpfLNJ2Xq0rm8wVfcLlYylnJl4t0otY85Xk6nabTxWyaLZJ8Vgo5k7OqynIp04LNUmyE0onWfUMj3ySqcz3lPE_5RIsCtY9jM-daFZLxx_hwGqPdmk49FN3Bs1mqlQ_-6ieooOPAfXMsf3qXwNtm5Sed0-u7iVSFuisSaRvGdxRg_Hlonf0NZWB8F1F7xncj8H7Nfw8AAP__Qou8ow">