Skip to content

Commit b0650b8

Browse files
committed
Revert "Revert "Utilize allocate_at_least (microsoft#3712)""
This reverts commit 8ad049e.
1 parent 8c1871f commit b0650b8

9 files changed

Lines changed: 210 additions & 59 deletions

File tree

stl/inc/deque

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,12 +1557,13 @@ private:
15571557

15581558
_Newsize *= 2;
15591559
}
1560-
_Count = _Newsize - _Mapsize();
15611560

15621561
size_type _Myboff = _Myoff() / _Block_size;
1563-
_Mapptr _Newmap = _Almap.allocate(_Mapsize() + _Count);
1562+
_Mapptr _Newmap = _Allocate_at_least_helper(_Almap, _Newsize);
15641563
_Mapptr _Myptr = _Newmap + _Myboff;
15651564

1565+
_Count = _Newsize - _Mapsize();
1566+
15661567
_Myptr = _STD uninitialized_copy(_Map() + _Myboff, _Map() + _Mapsize(), _Myptr); // copy initial to end
15671568
if (_Myboff <= _Count) { // increment greater than offset of initial block
15681569
_Myptr = _STD uninitialized_copy(_Map(), _Map() + _Myboff, _Myptr); // copy rest of old

stl/inc/sstream

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ protected:
261261
return _Traits::eof();
262262
}
263263

264-
const auto _Newptr = _Unfancy(_Al.allocate(_Newsize));
264+
const auto _Newptr = _Unfancy(_Allocate_at_least_helper(_Al, _Newsize));
265265
_Traits::copy(_Newptr, _Oldptr, _Oldsize);
266266

267267
const auto _New_pnext = _Newptr + _Oldsize;
@@ -430,7 +430,7 @@ protected:
430430
return pos_type{_Off};
431431
}
432432

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

@@ -440,9 +440,10 @@ protected:
440440

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

447448
if (!(_State & _Noread)) {
448449
_Mysb::setg(_Pnew, _Pnew, _Seekhigh); // setup read buffer

stl/inc/syncstream

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,10 @@ public:
120120
if (_Al != _Right_al) {
121121
_Tidy();
122122

123-
const _Size_type _Right_buf_size = _Right._Get_buffer_size();
123+
_Size_type _Right_buf_size = _Right._Get_buffer_size();
124124
const _Size_type _Right_data_size = _Right._Get_data_size();
125125

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

129129
streambuf_type::setp(_New_ptr, _New_ptr + _Right_data_size, _New_ptr + _Right_buf_size);
@@ -217,11 +217,11 @@ protected:
217217
return _Traits::eof();
218218
}
219219

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

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

239239
void _Init() {
240-
_Elem* const _New_ptr = _Unfancy(_Getal().allocate(_Min_size));
241-
streambuf_type::setp(_New_ptr, _New_ptr + _Min_size);
240+
_Size_type _New_capacity = _Min_size;
241+
_Elem* const _New_ptr = _Unfancy(_Allocate_at_least_helper(_Getal(), _New_capacity));
242+
streambuf_type::setp(_New_ptr, _New_ptr + _New_capacity);
242243
}
243244

244245
void _Tidy() noexcept {

stl/inc/vector

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -825,10 +825,10 @@ private:
825825
_Xlength();
826826
}
827827

828-
const size_type _Newsize = _Oldsize + 1;
829-
const size_type _Newcapacity = _Calculate_growth(_Newsize);
828+
const size_type _Newsize = _Oldsize + 1;
829+
size_type _Newcapacity = _Calculate_growth(_Newsize);
830830

831-
const pointer _Newvec = _Al.allocate(_Newcapacity);
831+
const pointer _Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
832832
const pointer _Constructed_last = _Newvec + _Whereoff + 1;
833833
pointer _Constructed_first = _Constructed_last;
834834

@@ -912,10 +912,10 @@ private:
912912
_Xlength();
913913
}
914914

915-
const size_type _Newsize = _Oldsize + _Count;
916-
const size_type _Newcapacity = _Calculate_growth(_Newsize);
915+
const size_type _Newsize = _Oldsize + _Count;
916+
size_type _Newcapacity = _Calculate_growth(_Newsize);
917917

918-
const pointer _Newvec = _Al.allocate(_Newcapacity);
918+
const pointer _Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
919919
const pointer _Constructed_last = _Newvec + _Oldsize + _Count;
920920
pointer _Constructed_first = _Constructed_last;
921921

@@ -1033,10 +1033,10 @@ public:
10331033
_Xlength();
10341034
}
10351035

1036-
const size_type _Newsize = _Oldsize + _Count;
1037-
const size_type _Newcapacity = _Calculate_growth(_Newsize);
1036+
const size_type _Newsize = _Oldsize + _Count;
1037+
size_type _Newcapacity = _Calculate_growth(_Newsize);
10381038

1039-
const pointer _Newvec = _Al.allocate(_Newcapacity);
1039+
const pointer _Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
10401040
const pointer _Constructed_last = _Newvec + _Whereoff + _Count;
10411041
pointer _Constructed_first = _Constructed_last;
10421042

@@ -1128,10 +1128,10 @@ private:
11281128
_Xlength();
11291129
}
11301130

1131-
const size_type _Newsize = _Oldsize + _Count;
1132-
const size_type _Newcapacity = _Calculate_growth(_Newsize);
1131+
const size_type _Newsize = _Oldsize + _Count;
1132+
size_type _Newcapacity = _Calculate_growth(_Newsize);
11331133

1134-
const pointer _Newvec = _Al.allocate(_Newcapacity);
1134+
const pointer _Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
11351135
const auto _Whereoff = static_cast<size_type>(_Whereptr - _Oldfirst);
11361136
const pointer _Constructed_last = _Newvec + _Whereoff + _Count;
11371137
pointer _Constructed_first = _Constructed_last;
@@ -1518,10 +1518,10 @@ private:
15181518
pointer& _Myfirst = _My_data._Myfirst;
15191519
pointer& _Mylast = _My_data._Mylast;
15201520

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

1524-
const pointer _Newvec = _Al.allocate(_Newcapacity);
1524+
const pointer _Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
15251525
const pointer _Appended_first = _Newvec + _Oldsize;
15261526
pointer _Appended_last = _Appended_first;
15271527

@@ -1598,7 +1598,10 @@ public:
15981598
}
15991599

16001600
private:
1601-
_CONSTEXPR20 void _Reallocate_exactly(const size_type _Newcapacity) {
1601+
enum class _Reallocation_policy { _At_least, _Exactly };
1602+
1603+
template <_Reallocation_policy _Policy>
1604+
_CONSTEXPR20 void _Reallocate(size_type& _Newcapacity) {
16021605
// set capacity to _Newcapacity (without geometric growth), provide strong guarantee
16031606
auto& _Al = _Getal();
16041607
auto& _My_data = _Mypair._Myval2;
@@ -1607,7 +1610,13 @@ private:
16071610

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

1610-
const pointer _Newvec = _Al.allocate(_Newcapacity);
1613+
pointer _Newvec;
1614+
if constexpr (_Policy == _Reallocation_policy::_At_least) {
1615+
_Newvec = _Allocate_at_least_helper(_Al, _Newcapacity);
1616+
} else {
1617+
_STL_INTERNAL_STATIC_ASSERT(_Policy == _Reallocation_policy::_Exactly);
1618+
_Newvec = _Al.allocate(_Newcapacity);
1619+
}
16111620

16121621
_TRY_BEGIN
16131622
if constexpr (is_nothrow_move_constructible_v<_Ty> || !is_copy_constructible_v<_Ty>) {
@@ -1675,14 +1684,14 @@ private:
16751684
}
16761685

16771686
public:
1678-
_CONSTEXPR20 void reserve(_CRT_GUARDOVERFLOW const size_type _Newcapacity) {
1687+
_CONSTEXPR20 void reserve(_CRT_GUARDOVERFLOW size_type _Newcapacity) {
16791688
// increase capacity to _Newcapacity (without geometric growth), provide strong guarantee
16801689
if (_Newcapacity > capacity()) { // something to do (reserve() never shrinks)
16811690
if (_Newcapacity > max_size()) {
16821691
_Xlength();
16831692
}
16841693

1685-
_Reallocate_exactly(_Newcapacity);
1694+
_Reallocate<_Reallocation_policy::_At_least>(_Newcapacity);
16861695
}
16871696
}
16881697

@@ -1694,7 +1703,8 @@ public:
16941703
if (_Oldfirst == _Oldlast) {
16951704
_Tidy();
16961705
} else {
1697-
_Reallocate_exactly(static_cast<size_type>(_Oldlast - _Oldfirst));
1706+
size_type _Newcapacity = static_cast<size_type>(_Oldlast - _Oldfirst);
1707+
_Reallocate<_Reallocation_policy::_Exactly>(_Newcapacity);
16981708
}
16991709
}
17001710
}
@@ -1976,7 +1986,7 @@ private:
19761986
return _Geometric; // geometric growth is sufficient
19771987
}
19781988

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

1989-
const auto _Newvec = _Getal().allocate(_Newcapacity);
1990-
_Myfirst = _Newvec;
1991-
_Mylast = _Newvec;
1992-
_Myend = _Newvec + _Newcapacity;
1999+
const pointer _Newvec = _Allocate_at_least_helper(_Getal(), _Newcapacity);
2000+
_Myfirst = _Newvec;
2001+
_Mylast = _Newvec;
2002+
_Myend = _Newvec + _Newcapacity;
19932003
}
19942004

19952005
_CONSTEXPR20 void _Buy_nonzero(const size_type _Newcapacity) {

stl/inc/xmemory

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2174,6 +2174,18 @@ _NODISCARD constexpr bool _Allocators_equal(const _Alloc& _Lhs, const _Alloc& _R
21742174
}
21752175
}
21762176

2177+
template <class _Alloc>
2178+
_NODISCARD_RAW_PTR_ALLOC _CONSTEXPR20 typename allocator_traits<_Alloc>::pointer _Allocate_at_least_helper(
2179+
_Alloc& _Al, _CRT_GUARDOVERFLOW typename allocator_traits<_Alloc>::size_type& _Count) {
2180+
#if _HAS_CXX23
2181+
auto [_Ptr, _Allocated] = allocator_traits<_Alloc>::allocate_at_least(_Al, _Count);
2182+
_Count = _Allocated;
2183+
return _Ptr;
2184+
#else // _HAS_CXX23
2185+
return _Al.allocate(_Count);
2186+
#endif // _HAS_CXX23
2187+
}
2188+
21772189
_EXPORT_STD template <class _FwdIt, class _Ty>
21782190
_NODISCARD_REMOVE_ALG _CONSTEXPR20 _FwdIt remove(_FwdIt _First, const _FwdIt _Last, const _Ty& _Val) {
21792191
// remove each matching _Val

stl/inc/xstring

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2647,9 +2647,11 @@ private:
26472647
return;
26482648
}
26492649

2650-
_My_data._Myres = _BUF_SIZE - 1;
2651-
const size_type _New_capacity = _Calculate_growth(_Count);
2652-
const pointer _New_ptr = _Al.allocate(_New_capacity + 1); // throws
2650+
_My_data._Myres = _BUF_SIZE - 1;
2651+
size_type _New_capacity = _Calculate_growth(_Count);
2652+
++_New_capacity;
2653+
const pointer _New_ptr = _Allocate_at_least_helper(_Al, _New_capacity); // throws
2654+
--_New_capacity;
26532655
_Construct_in_place(_My_data._Bx._Ptr, _New_ptr);
26542656

26552657
_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);
@@ -2691,8 +2693,10 @@ private:
26912693
}
26922694

26932695
if (_Count >= _BUF_SIZE) {
2694-
const size_type _New_capacity = _Calculate_growth(_Count);
2695-
const pointer _New_ptr = _Al.allocate(_New_capacity + 1); // throws
2696+
size_type _New_capacity = _Calculate_growth(_Count);
2697+
++_New_capacity;
2698+
const pointer _New_ptr = _Allocate_at_least_helper(_Al, _New_capacity); // throws
2699+
--_New_capacity;
26962700
_Construct_in_place(_My_data._Bx._Ptr, _New_ptr);
26972701
_My_data._Myres = _New_capacity;
26982702

@@ -2708,9 +2712,11 @@ private:
27082712
_Xlen_string(); // result too long
27092713
}
27102714

2711-
const auto _Old_ptr = _My_data._Myptr();
2712-
const size_type _New_capacity = _Calculate_growth(_My_data._Mysize);
2713-
const pointer _New_ptr = _Al.allocate(_New_capacity + 1); // throws
2715+
const auto _Old_ptr = _My_data._Myptr();
2716+
size_type _New_capacity = _Calculate_growth(_My_data._Mysize);
2717+
++_New_capacity;
2718+
const pointer _New_ptr = _Allocate_at_least_helper(_Al, _New_capacity); // throws
2719+
--_New_capacity;
27142720

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

27942800
if (_New_capacity < _New_size) {
2795-
_New_capacity = _Calculate_growth(_New_size, _BUF_SIZE - 1, max_size());
2796-
const pointer _Fancyptr = _Getal().allocate(_New_capacity + 1); // throws
2797-
_Ptr = _Unfancy(_Fancyptr);
2801+
_New_capacity = _Calculate_growth(_New_size, _BUF_SIZE - 1, max_size());
2802+
++_New_capacity;
2803+
const pointer _Fancyptr = _Allocate_at_least_helper(_Getal(), _New_capacity); // throws
2804+
--_New_capacity;
2805+
_Ptr = _Unfancy(_Fancyptr);
27982806
_Construct_in_place(_My_data._Bx._Ptr, _Fancyptr);
27992807

28002808
_Start_element_lifetimes(_Ptr, _New_capacity + 1);
@@ -2863,10 +2871,12 @@ public:
28632871
_Xlen_string();
28642872
}
28652873

2866-
const auto _New_capacity = _Calculate_growth(_New_size, _BUF_SIZE - 1, _Max);
2867-
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal());
2874+
auto _New_capacity = _Calculate_growth(_New_size, _BUF_SIZE - 1, _Max);
2875+
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal());
28682876
_Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data); // throws
2869-
const pointer _Fancyptr = _Getal().allocate(_New_capacity + 1); // throws
2877+
++_New_capacity;
2878+
const pointer _Fancyptr = _Allocate_at_least_helper(_Getal(), _New_capacity); // throws
2879+
--_New_capacity;
28702880
// nothrow hereafter
28712881
_Start_element_lifetimes(_Unfancy(_Fancyptr), _New_capacity + 1);
28722882
_Construct_in_place(_My_data._Bx._Ptr, _Fancyptr);
@@ -2946,9 +2956,10 @@ public:
29462956
_Result._Res = _My_data._Myres + 1;
29472957
} else {
29482958
// use _BUF_SIZE + 1 to avoid SSO, if the buffer is assigned back
2949-
_Result._Ptr = _Al.allocate(_BUF_SIZE + 1);
2959+
size_type _Allocated = _BUF_SIZE + 1;
2960+
_Result._Ptr = _Allocate_at_least_helper(_Al, _Allocated);
29502961
_Traits::copy(_Unfancy(_Result._Ptr), _My_data._Bx._Buf, _BUF_SIZE);
2951-
_Result._Res = _BUF_SIZE + 1;
2962+
_Result._Res = _Allocated;
29522963
}
29532964
_My_data._Orphan_all();
29542965
_Tidy_init();
@@ -3167,9 +3178,11 @@ public:
31673178

31683179
if (_Right._Mypair._Myval2._Large_string_engaged()) {
31693180
const auto _New_size = _Right._Mypair._Myval2._Mysize;
3170-
const auto _New_capacity = _Calculate_growth(_New_size, 0, _Right.max_size());
3181+
auto _New_capacity = _Calculate_growth(_New_size, 0, _Right.max_size());
31713182
auto _Right_al_non_const = _Right_al;
3172-
const auto _New_ptr = _Right_al_non_const.allocate(_New_capacity + 1); // throws
3183+
++_New_capacity;
3184+
const auto _New_ptr = _Allocate_at_least_helper(_Right_al_non_const, _New_capacity); // throws
3185+
--_New_capacity;
31733186

31743187
_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);
31753188

@@ -4736,9 +4749,11 @@ private:
47364749
}
47374750

47384751
const size_type _Old_capacity = _Mypair._Myval2._Myres;
4739-
const size_type _New_capacity = _Calculate_growth(_New_size);
4752+
size_type _New_capacity = _Calculate_growth(_New_size);
47404753
auto& _Al = _Getal();
4741-
const pointer _New_ptr = _Al.allocate(_New_capacity + 1); // throws
4754+
++_New_capacity;
4755+
const pointer _New_ptr = _Allocate_at_least_helper(_Al, _New_capacity); // throws
4756+
--_New_capacity;
47424757

47434758
_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);
47444759
_Mypair._Myval2._Orphan_all();
@@ -4769,9 +4784,11 @@ private:
47694784

47704785
const size_type _New_size = _Old_size + _Size_increase;
47714786
const size_type _Old_capacity = _My_data._Myres;
4772-
const size_type _New_capacity = _Calculate_growth(_New_size);
4787+
size_type _New_capacity = _Calculate_growth(_New_size);
47734788
auto& _Al = _Getal();
4774-
const pointer _New_ptr = _Al.allocate(_New_capacity + 1); // throws
4789+
++_New_capacity;
4790+
const pointer _New_ptr = _Allocate_at_least_helper(_Al, _New_capacity); // throws
4791+
--_New_capacity;
47754792

47764793
_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);
47774794
_My_data._Orphan_all();

tests/std/test.lst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ tests\GH_003022_substr_allocator
222222
tests\GH_003105_piecewise_densities
223223
tests\GH_003119_error_category_ctor
224224
tests\GH_003246_cmath_narrowing
225+
tests\GH_003570_allocate_at_least
225226
tests\GH_003617_vectorized_meow_element
226227
tests\GH_003676_format_large_hh_mm_ss_values
227228
tests\GH_003735_char_traits_signatures
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3+
4+
RUNALL_INCLUDE ..\usual_latest_matrix.lst

0 commit comments

Comments
 (0)