Skip to content

Commit 227f7c4

Browse files
authored
Merge 2023-02 LWG Motion 16
P2652R2 Disallow User Specialization of allocator_traits
2 parents 3cfe300 + ceabdf1 commit 227f7c4

File tree

3 files changed

+41
-28
lines changed

3 files changed

+41
-28
lines changed

source/compatibility.tex

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,20 @@
189189
}
190190
\end{codeblock}
191191

192+
\rSec2[diff.cpp20.memory]{\ref{mem}: memory management library}
193+
194+
\diffref{allocator.traits.general}
195+
\change
196+
Forbid partial and explicit program-defined specializations
197+
of \tcode{allocator_traits}.
198+
\rationale
199+
Allow addition of \tcode{allocate_at_least} to \tcode{allocator_traits},
200+
and potentially other members in the future.
201+
\effect
202+
Valid \CppXX{} code
203+
that partially or explicitly specializes \tcode{allocator_traits}
204+
is ill-formed with no diagnostic required in this revision of \Cpp{}.
205+
192206
\rSec2[diff.cpp20.utilities]{\ref{utilities}: general utilities library}
193207

194208
\diffref{format}

source/lib-intro.tex

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,9 +2009,10 @@
20092009
given type or expression is specified.
20102010
Within the standard library \tcode{allocator_traits}
20112011
template, an optional requirement that is not supplied by an allocator is
2012-
replaced by the specified default type or expression. A user specialization of
2013-
\tcode{allocator_traits} may provide different defaults and may provide
2014-
defaults for different requirements than the primary template.
2012+
replaced by the specified default type or expression.
2013+
\begin{note}
2014+
There are no program-defined specializations of \tcode{allocator_traits}.
2015+
\end{note}
20152016

20162017
\begin{itemdecl}
20172018
typename X::pointer
@@ -2318,11 +2319,11 @@
23182319
\begin{itemdescr}
23192320
\pnum
23202321
\result
2321-
\tcode{allocation_result<XX::pointer>}
2322+
\tcode{allocation_result<XX::pointer, XX::size_type>}
23222323

23232324
\pnum
23242325
\returns
2325-
\tcode{allocation_result<XX::pointer>\{ptr, count\}}
2326+
\tcode{allocation_result<XX::pointer, XX::size_type>\{ptr, count\}}
23262327
where \tcode{ptr} is memory allocated for an array of \tcode{count} \tcode{T}
23272328
and such an object is created but array elements are not constructed,
23282329
such that $\tcode{count} \geq \tcode{n}$.
@@ -2334,10 +2335,7 @@
23342335

23352336
\pnum
23362337
\remarks
2337-
An allocator need not support \tcode{allocate_at_least},
2338-
but no default is provided in \tcode{allocator_traits}.
2339-
If an allocator has an \tcode{allocate_at_least} member,
2340-
it shall satisfy the requirements.
2338+
Default: \tcode{\{a.allocate(n), n\}}.
23412339
\end{itemdescr}
23422340

23432341
\begin{itemdecl}

source/memory.tex

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -156,16 +156,12 @@
156156
// \ref{allocator.traits}, allocator traits
157157
template<class Alloc> struct allocator_traits; // freestanding
158158

159-
template<class Pointer>
159+
template<class Pointer, class SizeType = size_t>
160160
struct allocation_result { // freestanding
161161
Pointer ptr;
162-
size_t count;
162+
SizeType count;
163163
};
164164

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-
169165
// \ref{default.allocator}, the default allocator
170166
template<class T> class allocator;
171167
template<class T, class U>
@@ -1351,6 +1347,9 @@
13511347
Thus, it is always possible to create
13521348
a derived class from an allocator.
13531349
\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.
13541353

13551354
\indexlibraryglobal{allocator_traits}%
13561355
\begin{codeblock}
@@ -1379,6 +1378,8 @@
13791378
[[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n);
13801379
[[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n,
13811380
const_void_pointer hint);
1381+
[[nodiscard]] static constexpr allocation_result<pointer, size_type>
1382+
allocate_at_least(Alloc& a, size_type n);
13821383

13831384
static constexpr void deallocate(Alloc& a, pointer p, size_type n);
13841385

@@ -1565,6 +1566,19 @@
15651566
\tcode{a.allocate(n, hint)} if that expression is well-formed; otherwise, \tcode{a.allocate(n)}.
15661567
\end{itemdescr}
15671568

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+
15681582
\indexlibrarymember{deallocate}{allocator_traits}%
15691583
\begin{itemdecl}
15701584
static constexpr void deallocate(Alloc& a, pointer p, size_type n);
@@ -1638,19 +1652,6 @@
16381652
the template parameters, data members, and special members specified above.
16391653
It has no base classes or members other than those specified.
16401654

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-
16541655
\rSec2[default.allocator]{The default allocator}
16551656

16561657
\rSec3[default.allocator.general]{General}

0 commit comments

Comments
 (0)