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
14 changes: 14 additions & 0 deletions source/compatibility.tex
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,20 @@
}
\end{codeblock}

\rSec2[diff.cpp20.memory]{\ref{mem}: memory management library}

\diffref{allocator.traits.general}
\change
Forbid partial and explicit program-defined specializations
of \tcode{allocator_traits}.
\rationale
Allow addition of \tcode{allocate_at_least} to \tcode{allocator_traits},
and potentially other members in the future.
\effect
Valid \CppXX{} code
that partially or explicitly specializes \tcode{allocator_traits}
is ill-formed with no diagnostic required in this revision of \Cpp{}.

\rSec2[diff.cpp20.utilities]{\ref{utilities}: general utilities library}

\diffref{format}
Expand Down
16 changes: 7 additions & 9 deletions source/lib-intro.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2009,9 +2009,10 @@
given type or expression is specified.
Within the standard library \tcode{allocator_traits}
template, an optional requirement that is not supplied by an allocator is
replaced by the specified default type or expression. A user specialization of
\tcode{allocator_traits} may provide different defaults and may provide
defaults for different requirements than the primary template.
replaced by the specified default type or expression.
\begin{note}
There are no program-defined specializations of \tcode{allocator_traits}.
\end{note}

\begin{itemdecl}
typename X::pointer
Expand Down Expand Up @@ -2318,11 +2319,11 @@
\begin{itemdescr}
\pnum
\result
\tcode{allocation_result<XX::pointer>}
\tcode{allocation_result<XX::pointer, XX::size_type>}

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

\pnum
\remarks
An allocator need not support \tcode{allocate_at_least},
but no default is provided in \tcode{allocator_traits}.
If an allocator has an \tcode{allocate_at_least} member,
it shall satisfy the requirements.
Default: \tcode{\{a.allocate(n), n\}}.
\end{itemdescr}

\begin{itemdecl}
Expand Down
39 changes: 20 additions & 19 deletions source/memory.tex
Original file line number Diff line number Diff line change
Expand Up @@ -156,16 +156,12 @@
// \ref{allocator.traits}, allocator traits
template<class Alloc> struct allocator_traits; // freestanding

template<class Pointer>
template<class Pointer, class SizeType = size_t>
struct allocation_result { // freestanding
Pointer ptr;
size_t count;
SizeType count;
};

template<class Allocator>
[[nodiscard]] constexpr allocation_result<typename allocator_traits<Allocator>::pointer>
allocate_at_least(Allocator& a, size_t n); // freestanding

// \ref{default.allocator}, the default allocator
template<class T> class allocator;
template<class T, class U>
Expand Down Expand Up @@ -1351,6 +1347,9 @@
Thus, it is always possible to create
a derived class from an allocator.
\end{note}
If a program declares
an explicit or partial specialization of \tcode{allocator_traits},
the program is ill-formed, no diagnostic required.

\indexlibraryglobal{allocator_traits}%
\begin{codeblock}
Expand Down Expand Up @@ -1379,6 +1378,8 @@
[[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n);
[[nodiscard]] static constexpr pointer allocate(Alloc& a, size_type n,
const_void_pointer hint);
[[nodiscard]] static constexpr allocation_result<pointer, size_type>
allocate_at_least(Alloc& a, size_type n);

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

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

\indexlibrarymember{allocate_at_least}{allocator_traits}%
\begin{itemdecl}
[[nodiscard]] static constexpr allocation_result<pointer, size_type>
allocate_at_least(Alloc& a, size_type n);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{a.allocate_at_least(n)} if that expression is well-formed;
otherwise, \tcode{\{a.allocate(n), n\}}.
\end{itemdescr}

\indexlibrarymember{deallocate}{allocator_traits}%
\begin{itemdecl}
static constexpr void deallocate(Alloc& a, pointer p, size_type n);
Expand Down Expand Up @@ -1638,19 +1652,6 @@
the template parameters, data members, and special members specified above.
It has no base classes or members other than those specified.

\begin{itemdecl}
template<class Allocator>
[[nodiscard]] constexpr allocation_result<typename allocator_traits<Allocator>::pointer>
allocate_at_least(Allocator& a, size_t n);
\end{itemdecl}

\begin{itemdescr}
\pnum
\returns
\tcode{a.allocate_at_least(n)} if that expression is well-formed;
otherwise, \tcode{\{a.allocate(n), n\}}.
\end{itemdescr}

\rSec2[default.allocator]{The default allocator}

\rSec3[default.allocator.general]{General}
Expand Down