From 02f5e5e43890d40c792ac645100abae0cd88cd46 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 27 Feb 2022 22:22:30 +0100 Subject: [PATCH 1/3] [allocator.requirements.general] Replace table for descriptive variables --- source/lib-intro.tex | 89 ++++++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 37 deletions(-) diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 1a82d464f2..3ef4fd71ef 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -1840,43 +1840,61 @@ \tcode{match_results}\iref{re} are parameterized in terms of allocators. -\begin{shortlibreqtab2} -{Descriptive variable definitions} -{allocator.req.var} -\topline -\lhdr{Variable} & \rhdr{Definition} \\ \capsep -\tcode{T, U, C} & any \cv-unqualified object type\iref{term.object.type} \\ \rowsep -\tcode{X} & an allocator class for type \tcode{T} \\ \rowsep -\tcode{Y} & the corresponding allocator class for type \tcode{U} \\ \rowsep -\tcode{XX} & the type \tcode{allocator_traits} \\ \rowsep -\tcode{YY} & the type \tcode{allocator_traits} \\ \rowsep -\tcode{a, a1, a2} & lvalues of type \tcode{X} \\ \rowsep -\tcode{u} & the name of a variable being declared \\ \rowsep -\tcode{b} & a value of type \tcode{Y} \\ \rowsep -\tcode{c} & a pointer of type \tcode{C*} through which indirection is valid \\ \rowsep -\tcode{p} & a value of type \tcode{XX::pointer}, obtained -by calling \tcode{a1.allocate}, where \tcode{a1 == a} \\ \rowsep -\tcode{q} & a value of type \tcode{XX::const_pointer} -obtained by conversion from a value \tcode{p} \\ \rowsep -\tcode{r} & a value of type \tcode{T\&} -obtained by the expression \tcode{*p} \\ \rowsep -\tcode{w} & a value of type \tcode{XX::void_pointer} obtained by - conversion from a value \tcode{p} \\ \rowsep -\tcode{x} & a value of type \tcode{XX::const_void_pointer} obtained by - conversion from a value \tcode{q} or a value \tcode{w} \\ \rowsep -\tcode{y} & a value of type \tcode{XX::const_void_pointer} obtained by -conversion from a result value of \tcode{YY::allocate}, or else a value of -type (possibly \keyword{const}) \tcode{std::nullptr_t} \\ \rowsep -\tcode{n} & a value of type \tcode{XX::size_type} \\ \rowsep -\tcode{Args} & a template parameter pack \\ \rowsep -\tcode{args} & a function parameter pack with the pattern \tcode{Args\&\&} \\ -\end{shortlibreqtab2} +\pnum +In subclause \ref{allocator.requirements}, +\begin{itemize} +\item +\tcode{T}, \tcode{U}, \tcode{C} denote +any \cv-unqualified object type\iref{term.object.type}, +\item +\tcode{X} denotes an allocator class for type \tcode{T}, +\item +\tcode{Y} denotes the corresponding allocator class for type \tcode{U}, +\item +\tcode{XX} denotes the type \tcode{allocator_traits}, +\item +\tcode{YY} denotes the type \tcode{allocator_traits}, +\item +\tcode{a}, \tcode{a1}, \tcode{a2} denote lvalues of type \tcode{X}, +\item +\tcode{u} denotes the name of a variable being declared, +\item +\tcode{b} denotes a value of type \tcode{Y}, +\item +\tcode{c} denotes a pointer of type \tcode{C*} +through which indirection is valid, +\item +\tcode{p} denotes a value of type \tcode{XX::pointer} +obtained by calling \tcode{a1.allocate}, where \tcode{a1 == a}, +\item +\tcode{q} denotes a value of type \tcode{XX::const_pointer} +obtained by conversion from a value \tcode{p}, +\item +\tcode{r} denotes a value of type \tcode{T\&} +obtained by the expression \tcode{*p}, +\item +\tcode{w} denotes a value of type \tcode{XX::void_pointer} +obtained by conversion from a value \tcode{p}, +\item +\tcode{x} denotes a value of type \tcode{XX::const_void_pointer} +obtained by conversion from a value \tcode{q} or a value \tcode{w}, +\item +\tcode{y} denotes a value of type \tcode{XX::const_void_pointer} +obtained by conversion from a result value of \tcode{YY::allocate}, or else +a value of type (possibly \tcode{const}) \tcode{std::nullptr_t}, +\item +\tcode{n} denotes a value of type \tcode{XX::size_type}, +\item +\tcode{Args} denotes a template parameter pack, and +\item +\tcode{args} denotes +a function parameter pack with the pattern \tcode{Args\&\&}. +\end{itemize} \pnum The class template \tcode{allocator_traits}\iref{allocator.traits} supplies a uniform interface to all allocator types. -\tref{allocator.req.var} describes the types manipulated -through allocators. \tref{cpp17.allocator} +\tref{cpp17.allocator} describes the requirements on allocator types and thus on types used to instantiate \tcode{allocator_traits}. A requirement is optional if the last column of @@ -1885,10 +1903,7 @@ template, an optional requirement that is not supplied by an allocator is replaced by the specified default expression. A user specialization of \tcode{allocator_traits} may provide different defaults and may provide -defaults for different requirements than the primary template. Within -Tables~\ref{tab:allocator.req.var} and~\ref{tab:cpp17.allocator}, -the use of \tcode{move} and \tcode{forward} always refers to \tcode{std::move} -and \tcode{std::forward}, respectively. +defaults for different requirements than the primary template. \begin{libreqtab4d} {\oldconcept{Allocator} requirements} From 2bd0d16dae1cbe9dc06e614c83e84ddebd7dd4b7 Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Sun, 27 Feb 2022 23:59:42 +0100 Subject: [PATCH 2/3] [allocator.requirements.general] Dismantle requirements table --- source/lib-intro.tex | 876 ++++++++++++++++++++++++++++++------------- 1 file changed, 623 insertions(+), 253 deletions(-) diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 3ef4fd71ef..4028cdf3a4 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -1894,98 +1894,269 @@ \pnum The class template \tcode{allocator_traits}\iref{allocator.traits} supplies a uniform interface to all allocator types. -\tref{cpp17.allocator} +This subclause describes the requirements on allocator types -and thus on types used to instantiate \tcode{allocator_traits}. A requirement -is optional if the last column of -\tref{cpp17.allocator} specifies a default for a -given expression. Within the standard library \tcode{allocator_traits} +and thus on types used to instantiate \tcode{allocator_traits}. +A requirement is optional if a default for a +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 expression. A user specialization of +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. -\begin{libreqtab4d} -{\oldconcept{Allocator} requirements} -{cpp17.allocator} -\\ \topline -\lhdr{Expression} & \chdr{Return type} & \chdr{Assertion/note} & \rhdr{Default} \\ - & & \chdr{pre-/post-condition} & \\ \capsep -\endfirsthead -\continuedcaption\\ -\hline -\lhdr{Expression} & \chdr{Return type} & \chdr{Assertion/note} & \rhdr{Default} \\ - & & \chdr{pre-/post-condition} & \\ \capsep -\endhead -\tcode{X::pointer} & & & \tcode{T*} \\ \rowsep - -\tcode{X::const_pointer} & - & - \tcode{X::pointer} is convertible to \tcode{X::const_pointer} & - \tcode{pointer_traits::\brk{}rebind} \\ \rowsep - -\tcode{X::void_pointer}\br\tcode{Y::void_pointer} & - & - \tcode{X::pointer} is convertible to \tcode{X::void_pointer}. - \tcode{X::void_pointer} and \tcode{Y::void_pointer} are the same type. & - \tcode{pointer_traits::\brk{}rebind} \\ \rowsep - -\tcode{X::const_void_pointer}\br\tcode{Y::const_void_pointer} & - & - \tcode{X::pointer}, \tcode{X::const_pointer}, and \tcode{X::void_pointer} are convertible to \tcode{X::const_void_pointer}. - \tcode{X::const_void_pointer} and \tcode{Y::const_void_pointer} are the same type. & - \tcode{pointer_traits::\brk{}rebind} \\ \rowsep - -\tcode{X::value_type} & - Identical to \tcode{T} & & \\ \rowsep - -\tcode{X::size_type} & - unsigned integer type & - a type that can represent the size of the largest object in the allocation model & - \tcode{make_unsigned_t} \\ \rowsep - -\tcode{X::difference_type} & - signed integer type & - a type that can represent the difference between any two pointers - in the allocation model & - \tcode{pointer_traits::\brk{}difference_type} \\ \rowsep - -\tcode{typename X::template rebind::other} & - \tcode{Y} & - For all \tcode{U} (including \tcode{T}), \tcode{Y::template rebind::other} - is \tcode{X}. & - See Note A, below. \\ \rowsep - -\tcode{*p} & - \tcode{T\&} && \\ \rowsep - -\tcode{*q} & - \tcode{const T\&} & - \tcode{*q} refers to the same object as \tcode{*p}. & \\ \rowsep - -\tcode{p->m} & - type of \tcode{T::m} & - \expects \tcode{(*p).m} is well-defined.\br - equivalent to \tcode{(*p).m} & \\ \rowsep - -\tcode{q->m} & - type of \tcode{T::m} & - \expects \tcode{(*q).m} is well-defined.\br - equivalent to \tcode{(*q).m} & \\ \rowsep - -\tcode{static_cast<\brk{}X::pointer\brk{}>(w)} & - \tcode{X::pointer} & - \tcode{static_cast(w) == p} & \\ \rowsep - -\tcode{static_cast<\brk{}X::const_pointer\brk{}>(x)} & - \tcode{X::const_pointer} & - \tcode{static_cast<} \tcode{X::const_pointer\brk{}>(x) == q} & \\ \rowsep - -\tcode{pointer_traits<\brk{}X::pointer\brk{}>::pointer_to(r)} & - \tcode{X::pointer} & - same as \tcode{p} & \\ \rowsep - -\tcode{a.allocate(n)} & \tcode{X::pointer} & +\begin{itemdecl} +typename X::pointer +\end{itemdecl} + +\begin{itemdescr} +\pnum +\remarks +Default: \tcode{T*} +\end{itemdescr} + +\begin{itemdecl} +typename X::const_pointer +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{X::pointer} is convertible to \tcode{X::const_pointer}. + +\pnum +\remarks +Default: \tcode{pointer_traits::rebind} +\end{itemdescr} + +\begin{itemdecl} +typename X::void_pointer +typename Y::void_pointer +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{X::pointer} is convertible to \tcode{X::void_pointer}. +\tcode{X::void_pointer} and \tcode{Y::void_pointer} are the same type. + +\pnum +\remarks +Default: +\tcode{pointer_traits::rebind} +\end{itemdescr} + +\begin{itemdecl} +typename X::const_void_pointer +typename Y::const_void_pointer +\end{itemdecl} + +\begin{itemdescr} +\pnum +\mandates +\tcode{X::pointer}, \tcode{X::const_pointer}, and \tcode{X::void_pointer} +are convertible to \tcode{X::const_void_pointer}. +\tcode{X::const_void_pointer} and \tcode{Y::const_void_pointer} +are the same type. + +\pnum +\remarks +Default: +\tcode{pointer_traits::rebind} +\end{itemdescr} + +\begin{itemdecl} +typename X::value_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +Identical to \tcode{T}. +\end{itemdescr} + +\begin{itemdecl} +typename X::size_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +An unsigned integer type +that can represent the size of the largest object in the allocation model. + +\pnum +\remarks +Default: +\tcode{make_unsigned_t} +\end{itemdescr} + +\begin{itemdecl} +typename X::difference_type +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +A signed integer type that can represent +the difference between any two pointers in the allocation model. + +\pnum +\remarks +Default: +\tcode{pointer_traits::difference_type} +\end{itemdescr} + +\begin{itemdecl} +typename X::template rebind::other +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{Y} + +\pnum +\ensures +For all \tcode{U} (including \tcode{T}), +\tcode{Y::template rebind::other} is \tcode{X}. + +\pnum +\remarks +If \tcode{Allocator} is a class template instantiation of the form +\tcode{SomeAllocator}, where \tcode{Args} is zero or more type +arguments, and \tcode{Allocator} does not supply a \tcode{rebind} member +template, the standard \tcode{allocator_traits} template uses +\tcode{SomeAllocator} in place of \tcode{Allocator::re\-bind::other} +by default. For allocator types that are not template instantiations of the +above form, no default is provided. + +\pnum +\begin{note} +The member class template \tcode{rebind} of \tcode{X} is +effectively a typedef template. +In general, if +the name \tcode{Allocator} is bound to \tcode{SomeAllocator}, then +\tcode{Allocator::rebind::other} is the same type as +\tcode{SomeAllocator}, where +\tcode{SomeAllocator::value_type} is \tcode{T} and +\tcode{SomeAllocator::value_type} is \tcode{U}. +\end{note} +\end{itemdescr} + +\begin{itemdecl} +*p +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{T\&} +\end{itemdescr} + +\begin{itemdecl} +*q +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{const T\&} + +\pnum +\ensures +\tcode{*q} refers to the same object as \tcode{*p}. +\end{itemdescr} + +\begin{itemdecl} +p->m +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +Type of \tcode{T::m}. + +\pnum +\expects +\tcode{(*p).m} is well-defined. + +\pnum +\effects +Equivalent to \tcode{(*p).m}. +\end{itemdescr} + +\begin{itemdecl} +q->m +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +Type of \tcode{T::m}. + +\pnum +\expects +\tcode{(*q).m} is well-defined. + +\pnum +\effects +Equivalent to \tcode{(*q).m}. +\end{itemdescr} + +\begin{itemdecl} +static_cast(w) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X::pointer} + +\pnum +\ensures +\tcode{static_cast(w) == p}. +\end{itemdescr} + +\begin{itemdecl} +static_cast(x) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X::const_pointer} + +\pnum +\ensures +\tcode{static_cast(x) == q}. +\end{itemdescr} + +\begin{itemdecl} +pointer_traits::pointer_to(r) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X::pointer} + +\pnum +\ensures +Same as \tcode{p}. +\end{itemdescr} + +\begin{itemdecl} +a.allocate(n) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X::pointer} + +\pnum +\effects Memory is allocated for an array of \tcode{n} \tcode{T} and such an object is created but array elements are not constructed. @@ -1995,189 +2166,388 @@ can be used to implicitly create a suitable array object and obtain a pointer to it. \end{example} + +\pnum +\throws \tcode{allocate} may throw an appropriate exception. -\begin{footnote} + +\pnum +\begin{note} It is intended that \tcode{a.allocate} be an efficient means of allocating a single object of type \tcode{T}, even when \tcode{sizeof(T)} is small. That is, there is no need for a container to maintain its own free list. -\end{footnote} -See Note C, below. -& \\ \rowsep - -\tcode{a.allocate(n, y)} & - \tcode{X::pointer} & - Same as \tcode{a.allocate(n)}. The use of \tcode{y} is unspecified, but - it is intended as an aid to locality. & - \tcode{a.allocate(n)} \\ \rowsep - -\tcode{a.allocate_at_least(n)} & - \tcode{allocation_result} & - \returns - \tcode{allocation_result\{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}$. - \tcode{allocate_at_least} may throw an appropriate exception. - See Note C, below. & - See Note D, below. \\ \rowsep - -\tcode{a.deallocate(p,n)} & - (not used) & - \expects - \begin{itemize} - \item - If \tcode{p} is memory - that was obtained by a call to \tcode{a.allocate_at_least}, - let \tcode{ret} be the value returned and - \tcode{req} be the value passed as the first argument of that call. - \tcode{p} is equal to \tcode{ret.ptr} and - \tcode{n} is a value such that - $\tcode{req} \leq \tcode{n} \leq \tcode{ret.count}$. - \item - Otherwise, \tcode{p} is a pointer value obtained from \tcode{allocate}. - \tcode{n} equals the value passed as the first argument - to the invocation of \tcode{allocate} which returned \tcode{p}. - \end{itemize} - \tcode{p} has not been invalidated by - an intervening call to \tcode{deallocate}.\br - \throws Nothing. & \\ \rowsep - -\tcode{a.max_size()} & - \tcode{X::size_type} & - the largest value that can meaningfully be passed to \tcode{X::allocate()} & - \tcode{numeric_limits::max() / sizeof\brk{}(value_type)} \\ \rowsep - -\tcode{a1 == a2} & - \tcode{bool} & - Returns \tcode{true} only if storage allocated from each can - be deallocated via the other. \tcode{operator==} shall be reflexive, symmetric, - and transitive, and shall not exit via an exception. & \\ \rowsep - -\tcode{a1 != a2} & - \tcode{bool} & - same as \tcode{!(a1 == a2)} & \\ \rowsep - -\tcode{a == b} & - \tcode{bool} & - same as \tcode{a ==} \tcode{Y::rebind::other(b)} & \\ \rowsep - -\tcode{a != b} & - \tcode{bool} & - same as \tcode{!(a == b)} & \\ \rowsep - -\tcode{X u(a)}; \br -\tcode{X u = a;} & - & - Shall not exit via an exception.\br - \ensures \tcode{u == a} & \\ \rowsep - -\tcode{X u(b);} & - & - Shall not exit via an exception.\br - \ensures \tcode{Y(u) == b}, \tcode{u == X(b)} & \\ \rowsep - -\tcode{X u(std::move(a));} \br -\tcode{X u = std::move(a);} & - & - Shall not exit via an exception.\br - \ensures The value of \tcode{a} is unchanged and is equal to \tcode{u}. & \\ \rowsep - -\tcode{X u(std::move(b));} & - & - Shall not exit via an exception.\br - \ensures \tcode{u} is equal to the prior value of \tcode{X(b)}. & \\ \rowsep - -\tcode{a.construct(c, args)}& - (not used) & - \effects Constructs an object of type \tcode{C} at - \tcode{c}. & - \tcode{construct_at(c,~std::\brk{}forward\brk{}(args)...)} \\ \rowsep - -\tcode{a.destroy(c)} & - (not used) & - \effects Destroys the object at \tcode{c} & - \tcode{destroy_at(c)} \\ \rowsep - -\tcode{a.select_on_container_copy_construction()} & - \tcode{X} & - Typically returns either \tcode{a} or \tcode{X()}. & - \tcode{return a;} \\ \rowsep - -\tcode{X::propagate_on_container_copy_assignment} & - Identical to or derived from \tcode{true_type} or \tcode{false_type} & - \tcode{true_type} only if an allocator of type \tcode{X} should be copied - when the client container is copy-assigned. - See Note B, below. & - \tcode{false_type} \\ \rowsep - -\tcode{X::propagate_on_container_move_assignment} & - Identical to or derived from \tcode{true_type} or \tcode{false_type} & - \tcode{true_type} only if an allocator of type \tcode{X} should be moved - when the client container is move-assigned. - See Note B, below. & - \tcode{false_type} \\ \rowsep - -\tcode{X::propagate_on_-} \tcode{container_swap} & - Identical to or derived from \tcode{true_type} or \tcode{false_type} & - \tcode{true_type} only if an allocator of type \tcode{X} should be swapped - when the client container is swapped. - See Note B, below. & - \tcode{false_type} \\ \rowsep - -\tcode{X::is_always_equal} & - Identical to or derived from \tcode{true_type} or \tcode{false_type} & - \tcode{true_type} only if the expression \tcode{a1 == a2} is guaranteed - to be \tcode{true} for any two (possibly \keyword{const}) values - \tcode{a1}, \tcode{a2} of type \tcode{X}. & - \tcode{is_empty::\brk{}type} \\ - -\end{libreqtab4d} - -\pnum -Note A: The member class template \tcode{rebind} in the table above is -effectively a typedef template. -\begin{note} -In general, if -the name \tcode{Allocator} is bound to \tcode{SomeAllocator}, then -\tcode{Allocator::rebind::other} is the same type as -\tcode{SomeAllocator}, where -\tcode{SomeAllocator::value_type} is \tcode{T} and -\tcode{SomeAllocator::\brk{}value_type} is \tcode{U}. \end{note} -If -\tcode{Allocator} is a class template instantiation of the form -\tcode{SomeAllocator}, where \tcode{Args} is zero or more type -arguments, and \tcode{Allocator} does not supply a \tcode{rebind} member -template, the standard \tcode{allocator_traits} template uses -\tcode{SomeAllocator} in place of \tcode{Allocator::\brk{}rebind::other} -by default. For allocator types that are not template instantiations of the -above form, no default is provided. \pnum -Note B: -If \tcode{X::propagate_on_container_copy_assignment::value} is \tcode{true}, -\tcode{X} shall meet the -\oldconcept{\-Copy\-Assign\-able} requirements (\tref{cpp17.copyassignable}) -and the copy operation shall not throw exceptions. -If \tcode{X::propagate_on_container_move_assignment::value} is \tcode{true}, -\tcode{X} shall meet the -\oldconcept{\-Move\-Assign\-able} requirements (\tref{cpp17.moveassignable}) -and the move operation shall not throw exceptions. -If \tcode{X::propagate_on_container_swap::value} is \tcode{true}, -lvalues of type \tcode{X} shall be swappable\iref{swappable.requirements} -and the \tcode{swap} operation shall not throw exceptions. +\remarks +If \tcode{n == 0}, the return value is unspecified. +\end{itemdescr} + +\begin{itemdecl} +a.allocate(n, y) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X::pointer} + +\pnum +\effects +Same as \tcode{a.allocate(n)}. +The use of \tcode{y} is unspecified, but it is intended as an aid to locality. + +\pnum +\remarks +Default: \tcode{a.allocate(n)} +\end{itemdescr} + +\begin{itemdecl} +a.allocate_at_least(n) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{allocation_result} \pnum -Note C: +\returns +\tcode{allocation_result\{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}$. If \tcode{n == 0}, the return value is unspecified. \pnum -Note D: +\throws +\tcode{allocate_at_least} may throw an appropriate exception. + +\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. +\end{itemdescr} + +\begin{itemdecl} +a.deallocate(p, n) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +(not used) + +\pnum +\expects +\begin{itemize} +\item +If \tcode{p} is memory +that was obtained by a call to \tcode{a.allocate_at_least}, +let \tcode{ret} be the value returned and +\tcode{req} be the value passed as the first argument of that call. +\tcode{p} is equal to \tcode{ret.ptr} and +\tcode{n} is a value such that +$\tcode{req} \leq \tcode{n} \leq \tcode{ret.count}$. +\item +Otherwise, \tcode{p} is a pointer value obtained from \tcode{allocate}. +\tcode{n} equals the value passed as the first argument +to the invocation of \tcode{allocate} which returned \tcode{p}. +\end{itemize} +\tcode{p} has not been invalidated by +an intervening call to \tcode{deallocate}. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\begin{itemdecl} +a.max_size() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X::size_type} + +\pnum +\returns +The largest value that can meaningfully be passed to \tcode{X::allocate()}. + +\pnum +\remarks +Default: +\tcode{numeric_limits::max() / sizeof(value_type)} +\end{itemdescr} + +\begin{itemdecl} +a1 == a2 +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{bool} + +\pnum +\returns +\tcode{true} only if storage allocated from each can +be deallocated via the other. + +\pnum +\throws +Nothing. + +\pnum +\remarks +\tcode{operator==} shall be reflexive, symmetric, +and transitive. +\end{itemdescr} + +\begin{itemdecl} +a1 != a2 +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{bool} + +\pnum +\returns +\tcode{!(a1 == a2)}. +\end{itemdescr} + +\begin{itemdecl} +a == b +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{bool} + +\pnum +\returns +\tcode{a == Y::rebind::other(b)}. +\end{itemdescr} + +\begin{itemdecl} +a != b +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{bool} + +\pnum +\returns +\tcode{!(a == b)}. +\end{itemdescr} + +\begin{itemdecl} +X u(a); +X u = a; +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +\tcode{u == a} + +\pnum +\throws +Nothing. +\end{itemdescr} + +\begin{itemdecl} +X u(b); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +\tcode{Y(u) == b} and \tcode{u == X(b)}. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\begin{itemdecl} +X u(std::move(a)); +X u = std::move(a); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +The value of \tcode{a} is unchanged and is equal to \tcode{u}. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\begin{itemdecl} +X u(std::move(b)); +\end{itemdecl} + +\begin{itemdescr} +\pnum +\ensures +\tcode{u} is equal to the prior value of \tcode{X(b)}. + +\pnum +\throws +Nothing. +\end{itemdescr} + +\begin{itemdecl} +a.construct(c, args) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +(not used) + +\pnum +\effects +Constructs an object of type \tcode{C} at \tcode{c}. + +\pnum +\remarks +Default: +\tcode{construct_at(c, std::forward(args)...)} +\end{itemdescr} + +\begin{itemdecl} +a.destroy(c) +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +(not used) + +\pnum +\effects +Destroys the object at \tcode{c}. + +\pnum +\remarks +Default: \tcode{destroy_at(c)} +\end{itemdescr} + +\begin{itemdecl} +a.select_on_container_copy_construction() +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +\tcode{X} + +\pnum +\returns +Typically returns either \tcode{a} or \tcode{X()}. + +\pnum +\remarks +Default: \tcode{return a;} +\end{itemdescr} + +\begin{itemdecl} +X::propagate_on_container_copy_assignment +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +Identical to or derived from \tcode{true_type} or \tcode{false_type}. + +\pnum +\returns +\tcode{true_type} only if an allocator of type \tcode{X} should be copied +when the client container is copy-assigned; +if so, \tcode{X} shall meet +the \oldconcept{CopyAssignable} requirements (\tref{cpp17.copyassignable}) and +the copy operation shall not throw exceptions. + +\pnum +\remarks +Default: \tcode{false_type} +\end{itemdescr} + +\begin{itemdecl} +X::propagate_on_container_move_assignment +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +Identical to or derived from \tcode{true_type} or \tcode{false_type}. + +\pnum +\returns +\tcode{true_type} only if an allocator of type \tcode{X} should be moved +when the client container is move-assigned; +if so, \tcode{X} shall meet +the \oldconcept{MoveAssignable} requirements (\tref{cpp17.moveassignable}) and +the move operation shall not throw exceptions. + +\pnum +\remarks +Default: \tcode{false_type} +\end{itemdescr} + +\begin{itemdecl} +X::propagate_on_container_swap +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +Identical to or derived from \tcode{true_type} or \tcode{false_type}. + +\pnum +\returns +\tcode{true_type} only if an allocator of type \tcode{X} should be swapped +when the client container is swapped; +if so, +lvalues of type \tcode{X} shall be swappable\iref{swappable.requirements} and +the \tcode{swap} operation shall not throw exceptions. + +\pnum +\remarks +Default: \tcode{false_type} +\end{itemdescr} + +\begin{itemdecl} +X::is_always_equal +\end{itemdecl} + +\begin{itemdescr} +\pnum +\result +Identical to or derived from \tcode{true_type} or \tcode{false_type}. + +\pnum +\returns +\tcode{true_type} only if the expression \tcode{a1 == a2} is guaranteed +to be \tcode{true} for any two (possibly \tcode{const}) values +\tcode{a1}, \tcode{a2} of type \tcode{X}. + +\pnum +\remarks +Default: \tcode{is_empty::type} +\end{itemdescr} \pnum An allocator type \tcode{X} shall meet the From ed52520459f184b247126640b85b0c6757c049fb Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Mon, 28 Feb 2022 00:17:47 +0100 Subject: [PATCH 3/3] [lib] Fix cross-references to replaced table cpp17.allocator --- source/iostreams.tex | 8 ++++---- source/lib-intro.tex | 3 +-- source/memory.tex | 14 ++++++++------ source/threads.tex | 4 ++-- source/utilities.tex | 8 ++++---- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/source/iostreams.tex b/source/iostreams.tex index e7fa8f0516..bb586b70d6 100644 --- a/source/iostreams.tex +++ b/source/iostreams.tex @@ -12151,8 +12151,8 @@ \end{codeblock} \pnum -\tcode{Allocator} shall meet the \oldconcept{Allocator} requirements -(\tref{cpp17.allocator}). +\tcode{Allocator} shall meet +the \oldconcept{Allocator} requirements\iref{allocator.requirements.general}. \pnum \begin{example} @@ -12458,8 +12458,8 @@ \end{note} \pnum -Template parameters named \tcode{Allocator} shall meet the -\oldconcept{Allocator} requirements (\tref{cpp17.allocator}). +Template parameters named \tcode{Allocator} shall meet +the \oldconcept{Allocator} requirements\iref{allocator.requirements.general}. \rSec2[fs.filesystem.syn]{Header \tcode{} synopsis} diff --git a/source/lib-intro.tex b/source/lib-intro.tex index 4028cdf3a4..04ada51d52 100644 --- a/source/lib-intro.tex +++ b/source/lib-intro.tex @@ -2621,8 +2621,7 @@ \pnum \begin{example} The following is an allocator class template supporting the minimal -interface that meets the requirements of -\tref{cpp17.allocator}: +interface that meets the requirements of \ref{allocator.requirements.general}: \begin{codeblock} template diff --git a/source/memory.tex b/source/memory.tex index 668bdf2667..576a28b9fc 100644 --- a/source/memory.tex +++ b/source/memory.tex @@ -815,7 +815,7 @@ disambiguate constructor and function overloading. Specifically, several types (see \tcode{tuple}~\ref{tuple}) have constructors with \tcode{allocator_arg_t} as the first argument, immediately followed by an argument of a type that meets the -\oldconcept{Allocator} requirements (\tref{cpp17.allocator}). +\oldconcept{Allocator} requirements\iref{allocator.requirements.general}. \rSec2[allocator.uses]{\tcode{uses_allocator}} @@ -1913,7 +1913,7 @@ \pnum \begin{example} -Given an allocator type \tcode{X} (\tref{cpp17.allocator}) and +Given an allocator type \tcode{X}\iref{allocator.requirements.general} and letting \tcode{A} be a synonym for \tcode{allocator_traits}, the types \tcode{A::pointer}, \tcode{A::const_pointer}, \tcode{A::void_pointer}, and \tcode{A::const_void_pointer} may be used as \tcode{unique_ptr::pointer}. @@ -3188,7 +3188,8 @@ initialized with \tcode{std::move(d)} do not throw exceptions. The expression \tcode{d(p)} has well-defined behavior and does not throw exceptions. -\tcode{A} meets the \oldconcept{Allocator} requirements (\tref{cpp17.allocator}). +\tcode{A} meets +the \oldconcept{Allocator} requirements\iref{allocator.requirements.general}. \pnum \effects @@ -3673,7 +3674,8 @@ \begin{itemdescr} \pnum \expects -\tcode{A} meets the \oldconcept{Allocator} requirements (\tref{cpp17.allocator}). +\tcode{A} meets +the \oldconcept{Allocator} requirements\iref{allocator.requirements.general}. \pnum \effects @@ -5389,8 +5391,8 @@ \rSec3[mem.poly.allocator.class.general]{General} \pnum -A specialization of class template \tcode{pmr::polymorphic_allocator} -meets the \oldconcept{Allocator} requirements (\tref{cpp17.allocator}). +A specialization of class template \tcode{pmr::polymorphic_allocator} meets +the \oldconcept{Allocator} requirements\iref{allocator.requirements.general}. Constructed with different memory resources, different instances of the same specialization of \tcode{pmr::polymorphic_allocator} can exhibit entirely different allocation behavior. diff --git a/source/threads.tex b/source/threads.tex index 6a59070e5a..b2a90ea8d3 100644 --- a/source/threads.tex +++ b/source/threads.tex @@ -10137,8 +10137,8 @@ \begin{itemdescr} \pnum \expects -\tcode{Alloc} meets the \oldconcept{Allocator} -requirements (\tref{cpp17.allocator}). +\tcode{Alloc} meets +the \oldconcept{Allocator} requirements\iref{allocator.requirements.general}. \end{itemdescr} \indexlibraryctor{promise}% diff --git a/source/utilities.tex b/source/utilities.tex index 0ea252fc38..b85cbf93e1 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -1861,8 +1861,8 @@ \begin{itemdescr} \pnum \expects -\tcode{Alloc} meets the -\oldconcept{Allocator} requirements (\tref{cpp17.allocator}). +\tcode{Alloc} meets +the \oldconcept{Allocator} requirements\iref{allocator.requirements.general}. \pnum \effects @@ -2675,8 +2675,8 @@ \begin{itemdescr} \pnum \expects -\tcode{Alloc} meets the \oldconcept{Allocator} -requirements (\tref{cpp17.allocator}). +\tcode{Alloc} meets +the \oldconcept{Allocator} requirements\iref{allocator.requirements.general}. \pnum \begin{note}