Don't assume that `_Hash_vec`'s size and capacity are always equal (#2774)

This commit is contained in:
Casey Carter 2022-06-12 03:17:51 -07:00 коммит произвёл GitHub
Родитель 1385898482
Коммит 77a9b2e99e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 10 добавлений и 3 удалений

Просмотреть файл

@ -269,6 +269,12 @@ struct _Hash_vec {
_Aliter_traits::max_size(_Mypair._Get_first()));
}
_NODISCARD size_type capacity() const noexcept {
// This implementation never has capacity() differ from size(), but the previous implementation could.
// We need to handle that situation gracefully since we may link to old code (See GH-2774).
return static_cast<size_type>(_Mypair._Myval2._Myend - _Mypair._Myval2._Myfirst);
}
void _Assign_grow(const size_type _Cells, const value_type _Val) {
// set the elements stored here to _Cells copies of _Val, leaving the value unchanged if an exception is thrown
const auto _Oldsize = size();
@ -277,9 +283,10 @@ struct _Hash_vec {
if (_Oldsize < _Cells) {
const auto _Newvec = _Alvec.allocate(_Cells); // throws
// nothrow hereafter
if (_Oldsize != 0) {
const auto _Oldcapacity = capacity();
if (_Oldcapacity != 0) {
_Destroy_range(_Mypair._Myval2._Myfirst, _Mypair._Myval2._Mylast);
_Alvec.deallocate(_Mypair._Myval2._Myfirst, _Oldsize);
_Alvec.deallocate(_Mypair._Myval2._Myfirst, _Oldcapacity);
}
_Mypair._Myval2._Myfirst = _Newvec;
@ -294,7 +301,7 @@ struct _Hash_vec {
void _Tidy() noexcept {
_Destroy_range(_Mypair._Myval2._Myfirst, _Mypair._Myval2._Mylast);
_Mypair._Get_first().deallocate(_Mypair._Myval2._Myfirst, size());
_Mypair._Get_first().deallocate(_Mypair._Myval2._Myfirst, capacity());
_Mypair._Myval2._Myfirst = nullptr;
_Mypair._Myval2._Mylast = nullptr;
_Mypair._Myval2._Myend = nullptr;