Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions stl/inc/deque
Original file line number Diff line number Diff line change
Expand Up @@ -1557,12 +1557,13 @@ private:

_Newsize *= 2;
}
_Count = _Newsize - _Mapsize();

size_type _Myboff = _Myoff() / _Block_size;
_Mapptr _Newmap = _Almap.allocate(_Mapsize() + _Count);
_Mapptr _Newmap = _Allocate_at_least_helper(_Almap, _Newsize);
_Mapptr _Myptr = _Newmap + _Myboff;

_Count = _Newsize - _Mapsize();

_Myptr = _STD uninitialized_copy(_Map() + _Myboff, _Map() + _Mapsize(), _Myptr); // copy initial to end
if (_Myboff <= _Count) { // increment greater than offset of initial block
_Myptr = _STD uninitialized_copy(_Map(), _Map() + _Myboff, _Myptr); // copy rest of old
Expand Down
9 changes: 5 additions & 4 deletions stl/inc/sstream
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ protected:
return _Traits::eof();
}

const auto _Newptr = _Unfancy(_Al.allocate(_Newsize));
const auto _Newptr = _Unfancy(_Allocate_at_least_helper(_Al, _Newsize));
_Traits::copy(_Newptr, _Oldptr, _Oldsize);

const auto _New_pnext = _Newptr + _Oldsize;
Expand Down Expand Up @@ -430,7 +430,7 @@ protected:
return pos_type{_Off};
}

void _Init(const _Elem* _Ptr, _Mysize_type _Count, int _State) {
void _Init(const _Elem* _Ptr, const _Mysize_type _Count, int _State) {
// initialize buffer to [_Ptr, _Ptr + _Count), set state
_State &= ~_From_rvalue;

Expand All @@ -440,9 +440,10 @@ protected:

if (_Count != 0 && (_State & (_Noread | _Constant)) != (_Noread | _Constant)) {
// finite buffer that can be read or written, set it up
const auto _Pnew = _Unfancy(_Al.allocate(_Count));
_Mysize_type _Newsize = _Count;
const auto _Pnew = _Unfancy(_Allocate_at_least_helper(_Al, _Newsize));
_Traits::copy(_Pnew, _Ptr, _Count);
_Seekhigh = _Pnew + _Count;
_Seekhigh = _Pnew + _Newsize;

if (!(_State & _Noread)) {
_Mysb::setg(_Pnew, _Pnew, _Seekhigh); // setup read buffer
Expand Down
13 changes: 7 additions & 6 deletions stl/inc/syncstream
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,10 @@ public:
if (_Al != _Right_al) {
_Tidy();

const _Size_type _Right_buf_size = _Right._Get_buffer_size();
_Size_type _Right_buf_size = _Right._Get_buffer_size();
const _Size_type _Right_data_size = _Right._Get_data_size();

_Elem* const _New_ptr = _Unfancy(_Al.allocate(_Right_buf_size));
_Elem* const _New_ptr = _Unfancy(_Allocate_at_least_helper(_Al, _Right_buf_size));
_Traits::copy(_New_ptr, _Right.pbase(), _Right_data_size);

streambuf_type::setp(_New_ptr, _New_ptr + _Right_data_size, _New_ptr + _Right_buf_size);
Expand Down Expand Up @@ -217,11 +217,11 @@ protected:
return _Traits::eof();
}

const _Size_type _New_capacity = _Calculate_growth(_Buf_size, _Buf_size + 1, _Max_allocation);
_Size_type _New_capacity = _Calculate_growth(_Buf_size, _Buf_size + 1, _Max_allocation);
_Elem* const _Old_ptr = streambuf_type::pbase();
const _Size_type _Old_data_size = _Get_data_size();

_Elem* const _New_ptr = _Unfancy(_Al.allocate(_New_capacity));
_Elem* const _New_ptr = _Unfancy(_Allocate_at_least_helper(_Al, _New_capacity));
_Traits::copy(_New_ptr, _Old_ptr, _Old_data_size);
if (0 < _Buf_size) {
_Al.deallocate(_Refancy<_Pointer>(_Old_ptr), _Buf_size);
Expand All @@ -237,8 +237,9 @@ private:
static constexpr _Size_type _Min_size = 32; // constant for minimum buffer size

void _Init() {
_Elem* const _New_ptr = _Unfancy(_Getal().allocate(_Min_size));
streambuf_type::setp(_New_ptr, _New_ptr + _Min_size);
_Size_type _New_capacity = _Min_size;
_Elem* const _New_ptr = _Unfancy(_Allocate_at_least_helper(_Getal(), _New_capacity));
streambuf_type::setp(_New_ptr, _New_ptr + _New_capacity);
}

void _Tidy() noexcept {
Expand Down
60 changes: 35 additions & 25 deletions stl/inc/vector
Original file line number Diff line number Diff line change
Expand Up @@ -825,10 +825,10 @@ private:
_Xlength();
}

const size_type _Newsize = _Oldsize + 1;
const size_type _Newcapacity = _Calculate_growth(_Newsize);
const size_type _Newsize = _Oldsize + 1;
size_type _Newcapacity = _Calculate_growth(_Newsize);

const pointer _Newvec = _Al.allocate(_Newcapacity);
const pointer _Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
const pointer _Constructed_last = _Newvec + _Whereoff + 1;
pointer _Constructed_first = _Constructed_last;

Expand Down Expand Up @@ -912,10 +912,10 @@ private:
_Xlength();
}

const size_type _Newsize = _Oldsize + _Count;
const size_type _Newcapacity = _Calculate_growth(_Newsize);
const size_type _Newsize = _Oldsize + _Count;
size_type _Newcapacity = _Calculate_growth(_Newsize);

const pointer _Newvec = _Al.allocate(_Newcapacity);
const pointer _Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
const pointer _Constructed_last = _Newvec + _Oldsize + _Count;
pointer _Constructed_first = _Constructed_last;

Expand Down Expand Up @@ -1033,10 +1033,10 @@ public:
_Xlength();
}

const size_type _Newsize = _Oldsize + _Count;
const size_type _Newcapacity = _Calculate_growth(_Newsize);
const size_type _Newsize = _Oldsize + _Count;
size_type _Newcapacity = _Calculate_growth(_Newsize);

const pointer _Newvec = _Al.allocate(_Newcapacity);
const pointer _Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
const pointer _Constructed_last = _Newvec + _Whereoff + _Count;
pointer _Constructed_first = _Constructed_last;

Expand Down Expand Up @@ -1128,10 +1128,10 @@ private:
_Xlength();
}

const size_type _Newsize = _Oldsize + _Count;
const size_type _Newcapacity = _Calculate_growth(_Newsize);
const size_type _Newsize = _Oldsize + _Count;
size_type _Newcapacity = _Calculate_growth(_Newsize);

const pointer _Newvec = _Al.allocate(_Newcapacity);
const pointer _Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
const auto _Whereoff = static_cast<size_type>(_Whereptr - _Oldfirst);
const pointer _Constructed_last = _Newvec + _Whereoff + _Count;
pointer _Constructed_first = _Constructed_last;
Expand Down Expand Up @@ -1518,10 +1518,10 @@ private:
pointer& _Myfirst = _My_data._Myfirst;
pointer& _Mylast = _My_data._Mylast;

const auto _Oldsize = static_cast<size_type>(_Mylast - _Myfirst);
const size_type _Newcapacity = _Calculate_growth(_Newsize);
const auto _Oldsize = static_cast<size_type>(_Mylast - _Myfirst);
size_type _Newcapacity = _Calculate_growth(_Newsize);

const pointer _Newvec = _Al.allocate(_Newcapacity);
const pointer _Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
const pointer _Appended_first = _Newvec + _Oldsize;
pointer _Appended_last = _Appended_first;

Expand Down Expand Up @@ -1598,7 +1598,10 @@ public:
}

private:
_CONSTEXPR20 void _Reallocate_exactly(const size_type _Newcapacity) {
enum class _Reallocation_policy { _At_least, _Exactly };

template <_Reallocation_policy _Policy>
_CONSTEXPR20 void _Reallocate(size_type& _Newcapacity) {
// set capacity to _Newcapacity (without geometric growth), provide strong guarantee
auto& _Al = _Getal();
auto& _My_data = _Mypair._Myval2;
Expand All @@ -1607,7 +1610,13 @@ private:

const auto _Size = static_cast<size_type>(_Mylast - _Myfirst);

const pointer _Newvec = _Al.allocate(_Newcapacity);
pointer _Newvec;
if constexpr (_Policy == _Reallocation_policy::_At_least) {
_Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
} else {
_STL_INTERNAL_STATIC_ASSERT(_Policy == _Reallocation_policy::_Exactly);
_Newvec = _Al.allocate(_Newcapacity);
}

_TRY_BEGIN
if constexpr (is_nothrow_move_constructible_v<_Ty> || !is_copy_constructible_v<_Ty>) {
Expand Down Expand Up @@ -1675,14 +1684,14 @@ private:
}

public:
_CONSTEXPR20 void reserve(_CRT_GUARDOVERFLOW const size_type _Newcapacity) {
_CONSTEXPR20 void reserve(_CRT_GUARDOVERFLOW size_type _Newcapacity) {
// increase capacity to _Newcapacity (without geometric growth), provide strong guarantee
if (_Newcapacity > capacity()) { // something to do (reserve() never shrinks)
if (_Newcapacity > max_size()) {
_Xlength();
}

_Reallocate_exactly(_Newcapacity);
_Reallocate<_Reallocation_policy::_At_least>(_Newcapacity);
}
}

Expand All @@ -1694,7 +1703,8 @@ public:
if (_Oldfirst == _Oldlast) {
_Tidy();
} else {
_Reallocate_exactly(static_cast<size_type>(_Oldlast - _Oldfirst));
size_type _Newcapacity = static_cast<size_type>(_Oldlast - _Oldfirst);
_Reallocate<_Reallocation_policy::_Exactly>(_Newcapacity);
}
}
}
Expand Down Expand Up @@ -1976,7 +1986,7 @@ private:
return _Geometric; // geometric growth is sufficient
}

_CONSTEXPR20 void _Buy_raw(const size_type _Newcapacity) {
_CONSTEXPR20 void _Buy_raw(size_type _Newcapacity) {
// allocate array with _Newcapacity elements
auto& _My_data = _Mypair._Myval2;
pointer& _Myfirst = _My_data._Myfirst;
Expand All @@ -1986,10 +1996,10 @@ private:
_STL_INTERNAL_CHECK(!_Myfirst && !_Mylast && !_Myend); // check that *this is tidy
_STL_INTERNAL_CHECK(0 < _Newcapacity && _Newcapacity <= max_size());

const auto _Newvec = _Getal().allocate(_Newcapacity);
_Myfirst = _Newvec;
_Mylast = _Newvec;
_Myend = _Newvec + _Newcapacity;
const pointer _Newvec = _Allocate_at_least_helper(_Getal(), _Newcapacity);
_Myfirst = _Newvec;
_Mylast = _Newvec;
_Myend = _Newvec + _Newcapacity;
}

_CONSTEXPR20 void _Buy_nonzero(const size_type _Newcapacity) {
Expand Down
12 changes: 12 additions & 0 deletions stl/inc/xmemory
Original file line number Diff line number Diff line change
Expand Up @@ -2179,6 +2179,18 @@ _NODISCARD constexpr bool _Allocators_equal(const _Alloc& _Lhs, const _Alloc& _R
}
}

template <class _Alloc>
_NODISCARD_RAW_PTR_ALLOC _CONSTEXPR20 typename allocator_traits<_Alloc>::pointer _Allocate_at_least_helper(
_Alloc& _Al, _CRT_GUARDOVERFLOW typename allocator_traits<_Alloc>::size_type& _Count) {
#if _HAS_CXX23
auto [_Ptr, _Allocated] = allocator_traits<_Alloc>::allocate_at_least(_Al, _Count);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we _STL_ASSERT(_Allocated >= _Count); here?

_Count = _Allocated;
return _Ptr;
#else // _HAS_CXX23
return _Al.allocate(_Count);
#endif // _HAS_CXX23
}

_EXPORT_STD template <class _FwdIt, class _Ty>
_NODISCARD_REMOVE_ALG _CONSTEXPR20 _FwdIt remove(_FwdIt _First, const _FwdIt _Last, const _Ty& _Val) {
// remove each matching _Val
Expand Down
63 changes: 40 additions & 23 deletions stl/inc/xstring
Original file line number Diff line number Diff line change
Expand Up @@ -2647,9 +2647,11 @@ private:
return;
}

_My_data._Myres = _BUF_SIZE - 1;
const size_type _New_capacity = _Calculate_growth(_Count);
const pointer _New_ptr = _Al.allocate(_New_capacity + 1); // throws
_My_data._Myres = _BUF_SIZE - 1;
size_type _New_capacity = _Calculate_growth(_Count);
++_New_capacity;
const pointer _New_ptr = _Allocate_at_least_helper(_Al, _New_capacity); // throws
--_New_capacity;
_Construct_in_place(_My_data._Bx._Ptr, _New_ptr);

_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);
Expand Down Expand Up @@ -2691,8 +2693,10 @@ private:
}

if (_Count >= _BUF_SIZE) {
const size_type _New_capacity = _Calculate_growth(_Count);
const pointer _New_ptr = _Al.allocate(_New_capacity + 1); // throws
size_type _New_capacity = _Calculate_growth(_Count);
++_New_capacity;
const pointer _New_ptr = _Allocate_at_least_helper(_Al, _New_capacity); // throws
--_New_capacity;
_Construct_in_place(_My_data._Bx._Ptr, _New_ptr);
_My_data._Myres = _New_capacity;

Expand All @@ -2708,9 +2712,11 @@ private:
_Xlen_string(); // result too long
}

const auto _Old_ptr = _My_data._Myptr();
const size_type _New_capacity = _Calculate_growth(_My_data._Mysize);
const pointer _New_ptr = _Al.allocate(_New_capacity + 1); // throws
const auto _Old_ptr = _My_data._Myptr();
size_type _New_capacity = _Calculate_growth(_My_data._Mysize);
++_New_capacity;
const pointer _New_ptr = _Allocate_at_least_helper(_Al, _New_capacity); // throws
--_New_capacity;

_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);
_Traits::copy(_Unfancy(_New_ptr), _Old_ptr, _My_data._Mysize);
Expand Down Expand Up @@ -2792,9 +2798,11 @@ public:
_Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data); // throws

if (_New_capacity < _New_size) {
_New_capacity = _Calculate_growth(_New_size, _BUF_SIZE - 1, max_size());
const pointer _Fancyptr = _Getal().allocate(_New_capacity + 1); // throws
_Ptr = _Unfancy(_Fancyptr);
_New_capacity = _Calculate_growth(_New_size, _BUF_SIZE - 1, max_size());
++_New_capacity;
const pointer _Fancyptr = _Allocate_at_least_helper(_Getal(), _New_capacity); // throws
--_New_capacity;
_Ptr = _Unfancy(_Fancyptr);
_Construct_in_place(_My_data._Bx._Ptr, _Fancyptr);

_Start_element_lifetimes(_Ptr, _New_capacity + 1);
Expand Down Expand Up @@ -2863,10 +2871,12 @@ public:
_Xlen_string();
}

const auto _New_capacity = _Calculate_growth(_New_size, _BUF_SIZE - 1, _Max);
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal());
auto _New_capacity = _Calculate_growth(_New_size, _BUF_SIZE - 1, _Max);
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal());
_Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data); // throws
const pointer _Fancyptr = _Getal().allocate(_New_capacity + 1); // throws
++_New_capacity;
const pointer _Fancyptr = _Allocate_at_least_helper(_Getal(), _New_capacity); // throws
--_New_capacity;
// nothrow hereafter
_Start_element_lifetimes(_Unfancy(_Fancyptr), _New_capacity + 1);
_Construct_in_place(_My_data._Bx._Ptr, _Fancyptr);
Expand Down Expand Up @@ -2946,9 +2956,10 @@ public:
_Result._Res = _My_data._Myres + 1;
} else {
// use _BUF_SIZE + 1 to avoid SSO, if the buffer is assigned back
_Result._Ptr = _Al.allocate(_BUF_SIZE + 1);
size_type _Allocated = _BUF_SIZE + 1;
_Result._Ptr = _Allocate_at_least_helper(_Al, _Allocated);
_Traits::copy(_Unfancy(_Result._Ptr), _My_data._Bx._Buf, _BUF_SIZE);
_Result._Res = _BUF_SIZE + 1;
_Result._Res = _Allocated;
}
_My_data._Orphan_all();
_Tidy_init();
Expand Down Expand Up @@ -3167,11 +3178,13 @@ public:

if (_Right._Mypair._Myval2._Large_string_engaged()) {
const auto _New_size = _Right._Mypair._Myval2._Mysize;
const auto _New_capacity = _Calculate_growth(_New_size, 0, _Right.max_size());
auto _New_capacity = _Calculate_growth(_New_size, 0, _Right.max_size());
auto _Right_al_non_const = _Right_al;
const auto _New_ptr = _Right_al_non_const.allocate(_New_capacity + 1); // throws
++_New_capacity;
const auto _New_ptr = _Allocate_at_least_helper(_Right_al_non_const, _New_capacity); // throws
--_New_capacity;

_Start_element_lifetimes(_Unfancy(_New_ptr), _New_size + 1);
_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);

_Traits::copy(_Unfancy(_New_ptr), _Unfancy(_Right._Mypair._Myval2._Bx._Ptr), _New_size + 1);
_Tidy_deallocate();
Expand Down Expand Up @@ -4736,9 +4749,11 @@ private:
}

const size_type _Old_capacity = _Mypair._Myval2._Myres;
const size_type _New_capacity = _Calculate_growth(_New_size);
size_type _New_capacity = _Calculate_growth(_New_size);
auto& _Al = _Getal();
const pointer _New_ptr = _Al.allocate(_New_capacity + 1); // throws
++_New_capacity;
const pointer _New_ptr = _Allocate_at_least_helper(_Al, _New_capacity); // throws
--_New_capacity;

_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);
_Mypair._Myval2._Orphan_all();
Expand Down Expand Up @@ -4769,9 +4784,11 @@ private:

const size_type _New_size = _Old_size + _Size_increase;
const size_type _Old_capacity = _My_data._Myres;
const size_type _New_capacity = _Calculate_growth(_New_size);
size_type _New_capacity = _Calculate_growth(_New_size);
auto& _Al = _Getal();
const pointer _New_ptr = _Al.allocate(_New_capacity + 1); // throws
++_New_capacity;
const pointer _New_ptr = _Allocate_at_least_helper(_Al, _New_capacity); // throws
--_New_capacity;

_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);
_My_data._Orphan_all();
Expand Down
1 change: 1 addition & 0 deletions tests/std/test.lst
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ tests\GH_003022_substr_allocator
tests\GH_003105_piecewise_densities
tests\GH_003119_error_category_ctor
tests\GH_003246_cmath_narrowing
tests\GH_003570_allocate_at_least
tests\GH_003617_vectorized_meow_element
tests\LWG2381_num_get_floating_point
tests\LWG2597_complex_branch_cut
Expand Down
4 changes: 4 additions & 0 deletions tests/std/tests/GH_003570_allocate_at_least/env.lst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

RUNALL_INCLUDE ..\usual_latest_matrix.lst
Loading