Skip to content

Commit e37227e

Browse files
Saalvagefrederick-vs-jaStephanTLavavej
authored
Utilize allocate_at_least (microsoft#3712)
Co-authored-by: A. Jiang <[email protected]> Co-authored-by: Stephan T. Lavavej <[email protected]>
1 parent e856227 commit e37227e

File tree

9 files changed

+211
-60
lines changed

9 files changed

+211
-60
lines changed

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: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2646,9 +2646,11 @@ private:
26462646
return;
26472647
}
26482648

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

26542656
_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);
@@ -2690,8 +2692,10 @@ private:
26902692
}
26912693

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

@@ -2707,9 +2711,11 @@ private:
27072711
_Xlen_string(); // result too long
27082712
}
27092713

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

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

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

27992807
_Start_element_lifetimes(_Ptr, _New_capacity + 1);
@@ -2862,10 +2870,12 @@ public:
28622870
_Xlen_string();
28632871
}
28642872

2865-
const auto _New_capacity = _Calculate_growth(_New_size, _BUF_SIZE - 1, _Max);
2866-
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal());
2873+
auto _New_capacity = _Calculate_growth(_New_size, _BUF_SIZE - 1, _Max);
2874+
auto&& _Alproxy = _GET_PROXY_ALLOCATOR(_Alty, _Getal());
28672875
_Container_proxy_ptr<_Alty> _Proxy(_Alproxy, _My_data); // throws
2868-
const pointer _Fancyptr = _Getal().allocate(_New_capacity + 1); // throws
2876+
++_New_capacity;
2877+
const pointer _Fancyptr = _Allocate_at_least_helper(_Getal(), _New_capacity); // throws
2878+
--_New_capacity;
28692879
// nothrow hereafter
28702880
_Start_element_lifetimes(_Unfancy(_Fancyptr), _New_capacity + 1);
28712881
_Construct_in_place(_My_data._Bx._Ptr, _Fancyptr);
@@ -2945,9 +2955,10 @@ public:
29452955
_Result._Res = _My_data._Myres + 1;
29462956
} else {
29472957
// use _BUF_SIZE + 1 to avoid SSO, if the buffer is assigned back
2948-
_Result._Ptr = _Al.allocate(_BUF_SIZE + 1);
2958+
size_type _Allocated = _BUF_SIZE + 1;
2959+
_Result._Ptr = _Allocate_at_least_helper(_Al, _Allocated);
29492960
_Traits::copy(_Unfancy(_Result._Ptr), _My_data._Bx._Buf, _BUF_SIZE);
2950-
_Result._Res = _BUF_SIZE + 1;
2961+
_Result._Res = _Allocated;
29512962
}
29522963
_My_data._Orphan_all();
29532964
_Tidy_init();
@@ -3166,11 +3177,13 @@ public:
31663177

31673178
if (_Right._Mypair._Myval2._Large_string_engaged()) {
31683179
const auto _New_size = _Right._Mypair._Myval2._Mysize;
3169-
const auto _New_capacity = _Calculate_growth(_New_size, 0, _Right.max_size());
3180+
auto _New_capacity = _Calculate_growth(_New_size, 0, _Right.max_size());
31703181
auto _Right_al_non_const = _Right_al;
3171-
const auto _New_ptr = _Right_al_non_const.allocate(_New_capacity + 1); // throws
3182+
++_New_capacity;
3183+
const auto _New_ptr = _Allocate_at_least_helper(_Right_al_non_const, _New_capacity); // throws
3184+
--_New_capacity;
31723185

3173-
_Start_element_lifetimes(_Unfancy(_New_ptr), _New_size + 1);
3186+
_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);
31743187

31753188
_Traits::copy(_Unfancy(_New_ptr), _Unfancy(_Right._Mypair._Myval2._Bx._Ptr), _New_size + 1);
31763189
_Tidy_deallocate();
@@ -4735,9 +4748,11 @@ private:
47354748
}
47364749

47374750
const size_type _Old_capacity = _Mypair._Myval2._Myres;
4738-
const size_type _New_capacity = _Calculate_growth(_New_size);
4751+
size_type _New_capacity = _Calculate_growth(_New_size);
47394752
auto& _Al = _Getal();
4740-
const pointer _New_ptr = _Al.allocate(_New_capacity + 1); // throws
4753+
++_New_capacity;
4754+
const pointer _New_ptr = _Allocate_at_least_helper(_Al, _New_capacity); // throws
4755+
--_New_capacity;
47414756

47424757
_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);
47434758
_Mypair._Myval2._Orphan_all();
@@ -4768,9 +4783,11 @@ private:
47684783

47694784
const size_type _New_size = _Old_size + _Size_increase;
47704785
const size_type _Old_capacity = _My_data._Myres;
4771-
const size_type _New_capacity = _Calculate_growth(_New_size);
4786+
size_type _New_capacity = _Calculate_growth(_New_size);
47724787
auto& _Al = _Getal();
4773-
const pointer _New_ptr = _Al.allocate(_New_capacity + 1); // throws
4788+
++_New_capacity;
4789+
const pointer _New_ptr = _Allocate_at_least_helper(_Al, _New_capacity); // throws
4790+
--_New_capacity;
47744791

47754792
_Start_element_lifetimes(_Unfancy(_New_ptr), _New_capacity + 1);
47764793
_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\LWG2381_num_get_floating_point
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)