|
156 | 156 | // \ref{allocator.traits}, allocator traits
|
157 | 157 | template<class Alloc> struct allocator_traits; // freestanding
|
158 | 158 |
|
159 |
| - template<class Pointer> |
| 159 | + template<class Pointer, class SizeType = size_t> |
160 | 160 | struct allocation_result { // freestanding
|
161 | 161 | Pointer ptr;
|
162 |
| - size_t count; |
| 162 | + SizeType count; |
163 | 163 | };
|
164 | 164 |
|
165 |
| - template<class Allocator> |
166 |
| - [[nodiscard]] constexpr allocation_result<typename allocator_traits<Allocator>::pointer> |
167 |
| - allocate_at_least(Allocator& a, size_t n); // freestanding |
168 |
| - |
169 | 165 | // \ref{default.allocator}, the default allocator
|
170 | 166 | template<class T> class allocator;
|
171 | 167 | template<class T, class U>
|
|
1351 | 1347 | Thus, it is always possible to create
|
1352 | 1348 | a derived class from an allocator.
|
1353 | 1349 | \end{note}
|
| 1350 | +If a program declares |
| 1351 | +an explicit or partial specialization of \tcode{allocator_traits}, |
| 1352 | +the program is ill-formed, no diagnostic required. |
1354 | 1353 |
|
1355 | 1354 | \indexlibraryglobal{allocator_traits}%
|
1356 | 1355 | \begin{codeblock}
|
|
1379 | 1378 | [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n);
|
1380 | 1379 | [[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n,
|
1381 | 1380 | const_void_pointer hint);
|
| 1381 | + [[nodiscard]] static constexpr allocation_result<pointer, size_type> |
| 1382 | + allocate_at_least(Alloc& a, size_type n); |
1382 | 1383 |
|
1383 | 1384 | static constexpr void deallocate(Alloc& a, pointer p, size_type n);
|
1384 | 1385 |
|
|
1565 | 1566 | \tcode{a.allocate(n, hint)} if that expression is well-formed; otherwise, \tcode{a.allocate(n)}.
|
1566 | 1567 | \end{itemdescr}
|
1567 | 1568 |
|
| 1569 | +\indexlibrarymember{allocate_at_least}{allocator_traits}% |
| 1570 | +\begin{itemdecl} |
| 1571 | +[[nodiscard]] static constexpr allocation_result<pointer, size_type> |
| 1572 | + allocate_at_least(Alloc& a, size_type n); |
| 1573 | +\end{itemdecl} |
| 1574 | + |
| 1575 | +\begin{itemdescr} |
| 1576 | +\pnum |
| 1577 | +\returns |
| 1578 | +\tcode{a.allocate_at_least(n)} if that expression is well-formed; |
| 1579 | +otherwise, \tcode{\{a.allocate(n), n\}}. |
| 1580 | +\end{itemdescr} |
| 1581 | + |
1568 | 1582 | \indexlibrarymember{deallocate}{allocator_traits}%
|
1569 | 1583 | \begin{itemdecl}
|
1570 | 1584 | static constexpr void deallocate(Alloc& a, pointer p, size_type n);
|
|
1638 | 1652 | the template parameters, data members, and special members specified above.
|
1639 | 1653 | It has no base classes or members other than those specified.
|
1640 | 1654 |
|
1641 |
| -\begin{itemdecl} |
1642 |
| -template<class Allocator> |
1643 |
| -[[nodiscard]] constexpr allocation_result<typename allocator_traits<Allocator>::pointer> |
1644 |
| - allocate_at_least(Allocator& a, size_t n); |
1645 |
| -\end{itemdecl} |
1646 |
| - |
1647 |
| -\begin{itemdescr} |
1648 |
| -\pnum |
1649 |
| -\returns |
1650 |
| -\tcode{a.allocate_at_least(n)} if that expression is well-formed; |
1651 |
| -otherwise, \tcode{\{a.allocate(n), n\}}. |
1652 |
| -\end{itemdescr} |
1653 |
| - |
1654 | 1655 | \rSec2[default.allocator]{The default allocator}
|
1655 | 1656 |
|
1656 | 1657 | \rSec3[default.allocator.general]{General}
|
|
0 commit comments