1375 lines
60 KiB
Markdown
1375 lines
60 KiB
Markdown
[utility.requirements]
|
||
|
||
# 16 Library introduction [[library]](./#library)
|
||
|
||
## 16.4 Library-wide requirements [[requirements]](requirements#utility.requirements)
|
||
|
||
### 16.4.4 Requirements on types and expressions [utility.requirements]
|
||
|
||
#### [16.4.4.1](#general) General [[utility.requirements.general]](utility.requirements.general)
|
||
|
||
[1](#general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L1766)
|
||
|
||
[[utility.arg.requirements]](#utility.arg.requirements "16.4.4.2 Template argument requirements") describes requirements on types and expressions used to instantiate templates
|
||
defined in the C++ standard library[.](#general-1.sentence-1)
|
||
|
||
[[swappable.requirements]](#swappable.requirements "16.4.4.3 Swappable requirements") describes the requirements on swappable types and
|
||
swappable expressions[.](#general-1.sentence-2)
|
||
|
||
[[nullablepointer.requirements]](#nullablepointer.requirements "16.4.4.4 Cpp17NullablePointer requirements") describes the requirements on pointer-like
|
||
types that support null values[.](#general-1.sentence-3)
|
||
|
||
[[hash.requirements]](#hash.requirements "16.4.4.5 Cpp17Hash requirements") describes the requirements on hash function objects[.](#general-1.sentence-4)
|
||
|
||
[[allocator.requirements]](#allocator.requirements "16.4.4.6 Cpp17Allocator requirements") describes the requirements on storage
|
||
allocators[.](#general-1.sentence-5)
|
||
|
||
#### [16.4.4.2](#utility.arg.requirements) Template argument requirements [[utility.arg.requirements]](utility.arg.requirements)
|
||
|
||
[1](#utility.arg.requirements-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L1780)
|
||
|
||
The template definitions in the C++ standard library
|
||
refer to various named requirements whose details are set out in
|
||
Tables [28](#tab:cpp17.equalitycomparable "Table 28: Cpp17EqualityComparable requirements")â[35](#tab:cpp17.destructible "Table 35: Cpp17Destructible requirements")[.](#utility.arg.requirements-1.sentence-1)
|
||
|
||
In these tables,
|
||
|
||
- [(1.1)](#utility.arg.requirements-1.1)
|
||
|
||
T denotes an object or reference type to be
|
||
supplied by a C++ program instantiating a template,
|
||
|
||
- [(1.2)](#utility.arg.requirements-1.2)
|
||
|
||
a,b, andc denote values of type (possibly const) T,
|
||
|
||
- [(1.3)](#utility.arg.requirements-1.3)
|
||
|
||
s and t denote modifiable lvalues of type T,
|
||
|
||
- [(1.4)](#utility.arg.requirements-1.4)
|
||
|
||
u denotes an identifier,
|
||
|
||
- [(1.5)](#utility.arg.requirements-1.5)
|
||
|
||
rv denotes an rvalue of type T, and
|
||
|
||
- [(1.6)](#utility.arg.requirements-1.6)
|
||
|
||
v denotes an lvalue of type (possibly const) T or an
|
||
rvalue of type const T[.](#utility.arg.requirements-1.sentence-2)
|
||
|
||
[2](#utility.arg.requirements-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L1804)
|
||
|
||
In general, a default constructor is not required[.](#utility.arg.requirements-2.sentence-1)
|
||
|
||
Certain container class
|
||
member function signatures specify T() as a default argument[.](#utility.arg.requirements-2.sentence-2)
|
||
|
||
T() shall be a well-defined expression ([[dcl.init]](dcl.init "9.5 Initializers")) if one of those
|
||
signatures is called using the [default argument](dcl.fct.default "9.3.4.7 Default arguments [dcl.fct.default]")[.](#utility.arg.requirements-2.sentence-3)
|
||
|
||
Table [28](#tab:cpp17.equalitycomparable) — *Cpp17EqualityComparable* requirements [[tab:cpp17.equalitycomparable]](./tab:cpp17.equalitycomparable)
|
||
|
||
| [ð](#tab:cpp17.equalitycomparable-row-1)<br>**Expression** | **Return type** | **Requirement** |
|
||
| --- | --- | --- |
|
||
| [ð](#tab:cpp17.equalitycomparable-row-2)<br>a == b | decltype(a == b) models *boolean-testable* | == is an equivalence relation, that is, it has the following properties: <br> <br>For all a, a == a[.](#tab:cpp17.equalitycomparable-row-2-column-3-sentence-1)<br> If a == b, then b == a[.](#tab:cpp17.equalitycomparable-row-2-column-3-sentence-1)<br> If a == b and b == c, then a == c[.](#tab:cpp17.equalitycomparable-row-2-column-3-sentence-1) |
|
||
|
||
Table [29](#tab:cpp17.lessthancomparable) — *Cpp17LessThanComparable* requirements [[tab:cpp17.lessthancomparable]](./tab:cpp17.lessthancomparable)
|
||
|
||
| [ð](#tab:cpp17.lessthancomparable-row-1)<br>**Expression** | **Return type** | **Requirement** |
|
||
| --- | --- | --- |
|
||
| [ð](#tab:cpp17.lessthancomparable-row-2)<br>a < b | decltype(a < b) models *boolean-testable* | < is a strict weak ordering relation ([[alg.sorting]](alg.sorting "26.8 Sorting and related operations")) |
|
||
|
||
Table [30](#tab:cpp17.defaultconstructible) — *Cpp17DefaultConstructible* requirements [[tab:cpp17.defaultconstructible]](./tab:cpp17.defaultconstructible)
|
||
|
||
| [ð](#tab:cpp17.defaultconstructible-row-1)<br>**Expression** | **Post-condition** |
|
||
| --- | --- |
|
||
| [ð](#tab:cpp17.defaultconstructible-row-2)<br>T t; | object t is default-initialized |
|
||
| [ð](#tab:cpp17.defaultconstructible-row-3)<br>T u{}; | object u is value-initialized or aggregate-initialized |
|
||
| [ð](#tab:cpp17.defaultconstructible-row-4)<br>T() T{} | an object of type T is value-initialized or aggregate-initialized |
|
||
|
||
Table [31](#tab:cpp17.moveconstructible) — *Cpp17MoveConstructible* requirements [[tab:cpp17.moveconstructible]](./tab:cpp17.moveconstructible)
|
||
|
||
| [ð](#tab:cpp17.moveconstructible-row-1)<br>**Expression** | **Post-condition** |
|
||
| --- | --- |
|
||
| [ð](#tab:cpp17.moveconstructible-row-2)<br>T u = rv; | u is equivalent to the value of rv before the construction |
|
||
| [ð](#tab:cpp17.moveconstructible-row-3)<br>T(rv) | T(rv) is equivalent to the value of rv before the construction |
|
||
| [ð](#tab:cpp17.moveconstructible-row-4)<br>rv's state is unspecified <br>[*Note [1](#tab:cpp17.moveconstructible-row-4-column-1-note-1)*:<br>rv must still meet the requirements of the library component that is using it[.](#tab:cpp17.moveconstructible-row-4-column-1-sentence-1)<br>The operations listed in those requirements must work as specified whether rv has been moved from or not[.](#tab:cpp17.moveconstructible-row-4-column-1-sentence-2) â *end note*] | |
|
||
|
||
Table [32](#tab:cpp17.copyconstructible) — *Cpp17CopyConstructible* requirements (in addition to [*Cpp17MoveConstructible*](#:Cpp17MoveConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]")) [[tab:cpp17.copyconstructible]](./tab:cpp17.copyconstructible)
|
||
|
||
| [ð](#tab:cpp17.copyconstructible-row-1)<br>**Expression** | **Post-condition** |
|
||
| --- | --- |
|
||
| [ð](#tab:cpp17.copyconstructible-row-2)<br>T u = v; | the value of v is unchanged and is equivalent to u |
|
||
| [ð](#tab:cpp17.copyconstructible-row-3)<br>T(v) | the value of v is unchanged and is equivalent to T(v) |
|
||
|
||
Table [33](#tab:cpp17.moveassignable) — *Cpp17MoveAssignable* requirements [[tab:cpp17.moveassignable]](./tab:cpp17.moveassignable)
|
||
|
||
| [ð](#tab:cpp17.moveassignable-row-1)<br>**Expression** | **Return type** | **Return value** | **Post-condition** |
|
||
| --- | --- | --- | --- |
|
||
| [ð](#tab:cpp17.moveassignable-row-2)<br>t = rv | T& | t | If t and rv do not refer to the same object, t is equivalent to the value of rv before the assignment |
|
||
| [ð](#tab:cpp17.moveassignable-row-3)<br>rv's state is unspecified[.](#tab:cpp17.moveassignable-row-3-column-1-sentence-1)<br>[*Note [2](#tab:cpp17.moveassignable-row-3-column-1-note-2)*:<br>rv must still meet the requirements of the library component that is using it, whether or not t and rv refer to the same object[.](#tab:cpp17.moveassignable-row-3-column-1-sentence-2)<br>The operations listed in those requirements must work as specified whether rv has been moved from or not[.](#tab:cpp17.moveassignable-row-3-column-1-sentence-3) â *end note*] | | | |
|
||
|
||
Table [34](#tab:cpp17.copyassignable) — *Cpp17CopyAssignable* requirements (in addition to [*Cpp17MoveAssignable*](#:Cpp17MoveAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]")) [[tab:cpp17.copyassignable]](./tab:cpp17.copyassignable)
|
||
|
||
| [ð](#tab:cpp17.copyassignable-row-1)<br>**Expression** | **Return type** | **Return value** | **Post-condition** |
|
||
| --- | --- | --- | --- |
|
||
| [ð](#tab:cpp17.copyassignable-row-2)<br>t = v | T& | t | t is equivalent to v, the value of v is unchanged |
|
||
|
||
Table [35](#tab:cpp17.destructible) — *Cpp17Destructible* requirements [[tab:cpp17.destructible]](./tab:cpp17.destructible)
|
||
|
||
| [ð](#tab:cpp17.destructible-row-1)<br>**Expression** | **Post-condition** |
|
||
| --- | --- |
|
||
| [ð](#tab:cpp17.destructible-row-2)<br>u.~T() | All resources owned by u are reclaimed, no exception is propagated[.](#tab:cpp17.destructible-row-2-column-2-sentence-1) |
|
||
| [ð](#tab:cpp17.destructible-row-3)<br>[*Note [3](#tab:cpp17.destructible-row-3-column-1-note-3)*:<br>Array types and non-object types are not [*Cpp17Destructible*](#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]")[.](#tab:cpp17.destructible-row-3-column-1-sentence-1) â *end note*] | |
|
||
|
||
#### [16.4.4.3](#swappable.requirements) Swappable requirements [[swappable.requirements]](swappable.requirements)
|
||
|
||
[1](#swappable.requirements-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L1913)
|
||
|
||
This subclause provides definitions for swappable types and expressions[.](#swappable.requirements-1.sentence-1)
|
||
|
||
In these
|
||
definitions, let t denote an expression of type T, and let u denote an expression of type U[.](#swappable.requirements-1.sentence-2)
|
||
|
||
[2](#swappable.requirements-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L1918)
|
||
|
||
An object t is [*swappable with*](#def:swappable_with "16.4.4.3 Swappable requirements [swappable.requirements]") an object u if and only if
|
||
|
||
- [(2.1)](#swappable.requirements-2.1)
|
||
|
||
the expressions swap(t, u) and swap(u, t) are valid when
|
||
evaluated in the context described below, and
|
||
|
||
- [(2.2)](#swappable.requirements-2.2)
|
||
|
||
these expressions have the following effects:
|
||
* [(2.2.1)](#swappable.requirements-2.2.1)
|
||
|
||
the object referred to by t has the value originally held by u and
|
||
|
||
* [(2.2.2)](#swappable.requirements-2.2.2)
|
||
|
||
the object referred to by u has the value originally held by t[.](#swappable.requirements-2.sentence-1)
|
||
|
||
[3](#swappable.requirements-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L1931)
|
||
|
||
The context in which swap(t, u) and swap(u, t) are evaluated shall
|
||
ensure that a binary non-member function named âswapâ is selected via [overload
|
||
resolution](over.match "12.2 Overload resolution [over.match]") on a candidate set that includes:
|
||
|
||
- [(3.1)](#swappable.requirements-3.1)
|
||
|
||
the two swap function templates defined in[<utility>](utility.syn#header:%3cutility%3e "22.2.1 Header <utility> synopsis [utility.syn]") and
|
||
|
||
- [(3.2)](#swappable.requirements-3.2)
|
||
|
||
the lookup set produced by [argument-dependent lookup](basic.lookup.argdep "6.5.4 Argument-dependent name lookup [basic.lookup.argdep]")[.](#swappable.requirements-3.sentence-1)
|
||
|
||
[*Note [1](#swappable.requirements-note-1)*:
|
||
|
||
If T and U are both fundamental types or arrays of
|
||
fundamental types and the declarations from the header [<utility>](utility.syn#header:%3cutility%3e "22.2.1 Header <utility> synopsis [utility.syn]") are in
|
||
scope, the overall lookup set described above is equivalent to that of the
|
||
qualified name lookup applied to the expression std::swap(t, u) orstd::swap(u, t) as appropriate[.](#swappable.requirements-3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[*Note [2](#swappable.requirements-note-2)*:
|
||
|
||
It is unspecified whether a library component that has a swappable
|
||
requirement includes the header [<utility>](utility.syn#header:%3cutility%3e "22.2.1 Header <utility> synopsis [utility.syn]") to ensure an appropriate
|
||
evaluation context[.](#swappable.requirements-3.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[4](#swappable.requirements-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L1954)
|
||
|
||
An rvalue or lvalue t is [*swappable*](#def:swappable "16.4.4.3 Swappable requirements [swappable.requirements]") if and only if t is
|
||
swappable with any rvalue or lvalue, respectively, of type T[.](#swappable.requirements-4.sentence-1)
|
||
|
||
[5](#swappable.requirements-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L1958)
|
||
|
||
A type X meets the *Cpp17Swappable* requirements
|
||
if lvalues of type X are swappable[.](#swappable.requirements-5.sentence-1)
|
||
|
||
[6](#swappable.requirements-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L1962)
|
||
|
||
A type X meeting any of the iterator requirements ([[iterator.requirements]](iterator.requirements "24.3 Iterator requirements"))
|
||
meets the *Cpp17ValueSwappable* requirements if,
|
||
for any dereferenceable objectx of type X,*x is swappable[.](#swappable.requirements-6.sentence-1)
|
||
|
||
[7](#swappable.requirements-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L1969)
|
||
|
||
[*Example [1](#swappable.requirements-example-1)*:
|
||
|
||
User code can ensure that the evaluation of swap calls
|
||
is performed in an appropriate context under the various conditions as follows:#include <cassert>#include <utility>// Preconditions: std::forward<T>(t) is swappable with std::forward<U>(u).template<class T, class U>void value_swap(T&& t, U&& u) {using std::swap;
|
||
swap(std::forward<T>(t), std::forward<U>(u)); // OK, uses âswappable with'' conditions// for rvalues and lvalues}// Preconditions: T meets the [*Cpp17Swappable*](#:Cpp17Swappable "16.4.4.3 Swappable requirements [swappable.requirements]") requirements.template<class T>void lv_swap(T& t1, T& t2) {using std::swap;
|
||
swap(t1, t2); // OK, uses swappable conditions for lvalues of type T}namespace N {struct A { int m; }; struct Proxy { A* a; };
|
||
Proxy proxy(A& a) { return Proxy{ &a }; }void swap(A& x, Proxy p) { std::swap(x.m, p.a->m); // OK, uses context equivalent to swappable// conditions for fundamental types}void swap(Proxy p, A& x) { swap(x, p); } // satisfy symmetry constraint}int main() {int i = 1, j = 2;
|
||
lv_swap(i, j);
|
||
assert(i == 2 && j == 1);
|
||
|
||
N::A a1 = { 5 }, a2 = { -5 };
|
||
value_swap(a1, proxy(a2));
|
||
assert(a1.m == -5 && a2.m == 5);}
|
||
|
||
â *end example*]
|
||
|
||
#### [16.4.4.4](#nullablepointer.requirements) *Cpp17NullablePointer* requirements [[nullablepointer.requirements]](nullablepointer.requirements)
|
||
|
||
[1](#nullablepointer.requirements-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2018)
|
||
|
||
A *Cpp17NullablePointer* type is a pointer-like type that supports null values[.](#nullablepointer.requirements-1.sentence-1)
|
||
|
||
A type P meets the *Cpp17NullablePointer* requirements if
|
||
|
||
- [(1.1)](#nullablepointer.requirements-1.1)
|
||
|
||
P meets the [*Cpp17EqualityComparable*](#:Cpp17EqualityComparable "16.4.4.2 Template argument requirements [utility.arg.requirements]"),[*Cpp17DefaultConstructible*](#:Cpp17DefaultConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"), [*Cpp17CopyConstructible*](#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]"), *Cpp17CopyAssignable*,[*Cpp17Swappable*](#:Cpp17Swappable "16.4.4.3 Swappable requirements [swappable.requirements]"), and [*Cpp17Destructible*](#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements,
|
||
|
||
- [(1.2)](#nullablepointer.requirements-1.2)
|
||
|
||
the expressions shown in Table [36](#tab:cpp17.nullablepointer "Table 36: Cpp17NullablePointer requirements") are
|
||
valid and have the indicated semantics, and
|
||
|
||
- [(1.3)](#nullablepointer.requirements-1.3)
|
||
|
||
P meets all the other requirements of this subclause[.](#nullablepointer.requirements-1.sentence-2)
|
||
|
||
[2](#nullablepointer.requirements-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2032)
|
||
|
||
A value-initialized object of type P produces the null value of the type[.](#nullablepointer.requirements-2.sentence-1)
|
||
|
||
The null value shall be equivalent only to itself[.](#nullablepointer.requirements-2.sentence-2)
|
||
|
||
A default-initialized object
|
||
of type P may have an indeterminate or erroneous value[.](#nullablepointer.requirements-2.sentence-3)
|
||
|
||
[*Note [1](#nullablepointer.requirements-note-1)*:
|
||
|
||
Operations involving indeterminate values can cause undefined behavior, and
|
||
operations involving erroneous values can cause erroneous behavior ([[basic.indet]](basic.indet "6.8.5 Indeterminate and erroneous values"))[.](#nullablepointer.requirements-2.sentence-4)
|
||
|
||
â *end note*]
|
||
|
||
[3](#nullablepointer.requirements-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2041)
|
||
|
||
An object p of type P can be[contextually converted to bool](conv#def:conversion,contextual_to_bool "7.3 Standard conversions [conv]")[.](#nullablepointer.requirements-3.sentence-1)
|
||
|
||
The effect shall be as if p != nullptr had been evaluated in place of p[.](#nullablepointer.requirements-3.sentence-2)
|
||
|
||
[4](#nullablepointer.requirements-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2047)
|
||
|
||
No operation which is part of the *Cpp17NullablePointer* requirements shall exit
|
||
via an exception[.](#nullablepointer.requirements-4.sentence-1)
|
||
|
||
[5](#nullablepointer.requirements-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2051)
|
||
|
||
In Table [36](#tab:cpp17.nullablepointer "Table 36: Cpp17NullablePointer requirements"), u denotes an identifier, t denotes a non-const lvalue of type P, a and b denote values of type (possibly const) P, and np denotes
|
||
a value of type (possibly const) std::nullptr_t[.](#nullablepointer.requirements-5.sentence-1)
|
||
|
||
Table [36](#tab:cpp17.nullablepointer) — *Cpp17NullablePointer* requirements [[tab:cpp17.nullablepointer]](./tab:cpp17.nullablepointer)
|
||
|
||
| [ð](#tab:cpp17.nullablepointer-row-1)<br>**Expression** | **Return type** | **Operational semantics** |
|
||
| --- | --- | --- |
|
||
| [ð](#tab:cpp17.nullablepointer-row-2)<br>P u(np); | | *Postconditions*: u == nullptr |
|
||
| [ð](#tab:cpp17.nullablepointer-row-3)<br>P u = np; | | |
|
||
| [ð](#tab:cpp17.nullablepointer-row-4)<br>P(np) | | *Postconditions*: P(np) == nullptr |
|
||
| [ð](#tab:cpp17.nullablepointer-row-5)<br>t = np | P& | *Postconditions*: t == nullptr |
|
||
| [ð](#tab:cpp17.nullablepointer-row-6)<br>a != b | decltype(a != b) models [*boolean-testable*](concept.booleantestable#concept:boolean-testable "18.5.2 Boolean testability [concept.booleantestable]") | !(a == b) |
|
||
| [ð](#tab:cpp17.nullablepointer-row-7)<br>a == np | decltype(a == np) and decltype(np == a) each model [*boolean-testable*](concept.booleantestable#concept:boolean-testable "18.5.2 Boolean testability [concept.booleantestable]") | a == P() |
|
||
| [ð](#tab:cpp17.nullablepointer-row-8)<br>np == a | | |
|
||
| [ð](#tab:cpp17.nullablepointer-row-9)<br>a != np | decltype(a != np) and decltype(np != a) each model [*boolean-testable*](concept.booleantestable#concept:boolean-testable "18.5.2 Boolean testability [concept.booleantestable]") | !(a == np) |
|
||
| [ð](#tab:cpp17.nullablepointer-row-10)<br>np != a | | |
|
||
|
||
#### [16.4.4.5](#hash.requirements) *Cpp17Hash* requirements [[hash.requirements]](hash.requirements)
|
||
|
||
[1](#hash.requirements-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2096)
|
||
|
||
A type H meets the *Cpp17Hash* requirements if
|
||
|
||
- [(1.1)](#hash.requirements-1.1)
|
||
|
||
it is a function object type ([[function.objects]](function.objects "22.10 Function objects")),
|
||
|
||
- [(1.2)](#hash.requirements-1.2)
|
||
|
||
it meets the [*Cpp17CopyConstructible*](#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") (Table [32](#tab:cpp17.copyconstructible "Table 32: Cpp17CopyConstructible requirements (in addition to Cpp17MoveConstructible)")) and [*Cpp17Destructible*](#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") (Table [35](#tab:cpp17.destructible "Table 35: Cpp17Destructible requirements")) requirements, and
|
||
|
||
- [(1.3)](#hash.requirements-1.3)
|
||
|
||
the expressions shown in Table [37](#tab:cpp17.hash "Table 37: Cpp17Hash requirements") are valid and have the indicated semantics[.](#hash.requirements-1.sentence-1)
|
||
|
||
[2](#hash.requirements-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2106)
|
||
|
||
Given Key is an argument type for function objects of type H, in
|
||
Table [37](#tab:cpp17.hash "Table 37: Cpp17Hash requirements") h is a value of type (possibly const) H,u is an lvalue of type Key, and k is a value of a type convertible to
|
||
(possibly const) Key[.](#hash.requirements-2.sentence-1)
|
||
|
||
Table [37](#tab:cpp17.hash) — *Cpp17Hash* requirements [[tab:cpp17.hash]](./tab:cpp17.hash)
|
||
|
||
| [ð](#tab:cpp17.hash-row-1)<br>**Expression** | **Return type** | **Requirement** |
|
||
| --- | --- | --- |
|
||
| [ð](#tab:cpp17.hash-row-2)<br>h(k) | size_t | The value returned shall depend only on the argument k for the duration of the program[.](#tab:cpp17.hash-row-2-column-3-sentence-1)<br>[*Note [1](#tab:cpp17.hash-row-2-column-3-note-1)*:<br>Thus all evaluations of the expression h(k) with the same value for k yield the same result for a given execution of the program[.](#tab:cpp17.hash-row-2-column-3-sentence-2) â *end note*]<br> For two different values t1 and t2, the probability that h(t1) and h(t2) compare equal should be very small, approaching 1.0 / numeric_limits<size_t>::max()[.](#tab:cpp17.hash-row-2-column-3-sentence-3) |
|
||
| [ð](#tab:cpp17.hash-row-3)<br>h(u) | size_t | Shall not modify u[.](#tab:cpp17.hash-row-3-column-3-sentence-1) |
|
||
|
||
#### [16.4.4.6](#allocator.requirements) *Cpp17Allocator* requirements [[allocator.requirements]](allocator.requirements)
|
||
|
||
#### [16.4.4.6.1](#allocator.requirements.general) General [[allocator.requirements.general]](allocator.requirements.general)
|
||
|
||
[1](#allocator.requirements.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2138)
|
||
|
||
The library describes a standard set of requirements for [*allocators*](#def:allocators),
|
||
which are class-type objects that encapsulate the information about an allocation model[.](#allocator.requirements.general-1.sentence-1)
|
||
|
||
This information includes the knowledge of pointer types, the type of their
|
||
difference, the type of the size of objects in this allocation model, as well
|
||
as the memory allocation and deallocation primitives for it[.](#allocator.requirements.general-1.sentence-2)
|
||
|
||
All of the
|
||
string types ([[strings]](strings "27 Strings library")),
|
||
containers ([[containers]](containers "23 Containers library")) (except array and inplace_vector),
|
||
string buffers and string streams ([[input.output]](input.output "31 Input/output library")), and[match_results](re "28.6 Regular expressions library [re]") are parameterized in terms of
|
||
allocators[.](#allocator.requirements.general-1.sentence-3)
|
||
|
||
[2](#allocator.requirements.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2150)
|
||
|
||
In [[allocator.requirements]](#allocator.requirements "16.4.4.6 Cpp17Allocator requirements"),
|
||
|
||
- [(2.1)](#allocator.requirements.general-2.1)
|
||
|
||
T, U, C denote
|
||
any cv-unqualified object type ([[basic.types.general]](basic.types.general#term.object.type "6.9.1 General")),
|
||
|
||
- [(2.2)](#allocator.requirements.general-2.2)
|
||
|
||
X denotes an allocator class for type T,
|
||
|
||
- [(2.3)](#allocator.requirements.general-2.3)
|
||
|
||
Y denotes the corresponding allocator class for type U,
|
||
|
||
- [(2.4)](#allocator.requirements.general-2.4)
|
||
|
||
XX denotes the type allocator_traits<X>,
|
||
|
||
- [(2.5)](#allocator.requirements.general-2.5)
|
||
|
||
YY denotes the type allocator_traits<Y>,
|
||
|
||
- [(2.6)](#allocator.requirements.general-2.6)
|
||
|
||
a, a1, a2 denote lvalues of type X,
|
||
|
||
- [(2.7)](#allocator.requirements.general-2.7)
|
||
|
||
u denotes the name of a variable being declared,
|
||
|
||
- [(2.8)](#allocator.requirements.general-2.8)
|
||
|
||
b denotes a value of type Y,
|
||
|
||
- [(2.9)](#allocator.requirements.general-2.9)
|
||
|
||
c denotes a pointer of type C* through which indirection is valid,
|
||
|
||
- [(2.10)](#allocator.requirements.general-2.10)
|
||
|
||
p denotes a value of type XX::pointer obtained by calling a1.allocate, where a1 == a,
|
||
|
||
- [(2.11)](#allocator.requirements.general-2.11)
|
||
|
||
q denotes a value of type XX::const_pointer obtained by conversion from a value p,
|
||
|
||
- [(2.12)](#allocator.requirements.general-2.12)
|
||
|
||
r denotes a value of type T& obtained by the expression *p,
|
||
|
||
- [(2.13)](#allocator.requirements.general-2.13)
|
||
|
||
w denotes a value of type XX::void_pointer obtained by conversion from a value p,
|
||
|
||
- [(2.14)](#allocator.requirements.general-2.14)
|
||
|
||
x denotes a value of type XX::const_void_pointer obtained by conversion from a value q or a value w,
|
||
|
||
- [(2.15)](#allocator.requirements.general-2.15)
|
||
|
||
y denotes a value of type XX::const_void_pointer obtained by conversion from a result value of YY::allocate, or else
|
||
a value of type (possibly const) std::nullptr_t,
|
||
|
||
- [(2.16)](#allocator.requirements.general-2.16)
|
||
|
||
n denotes a value of type XX::size_type,
|
||
|
||
- [(2.17)](#allocator.requirements.general-2.17)
|
||
|
||
Args denotes a template parameter pack, and
|
||
|
||
- [(2.18)](#allocator.requirements.general-2.18)
|
||
|
||
args denotes
|
||
a function parameter pack with the pattern Args&&[.](#allocator.requirements.general-2.sentence-1)
|
||
|
||
[3](#allocator.requirements.general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2201)
|
||
|
||
The class template allocator_traits ([[allocator.traits]](allocator.traits "20.2.9 Allocator traits")) supplies
|
||
a uniform interface to all allocator types[.](#allocator.requirements.general-3.sentence-1)
|
||
|
||
This subclause
|
||
describes the requirements on allocator types
|
||
and thus on types used to instantiate allocator_traits[.](#allocator.requirements.general-3.sentence-2)
|
||
|
||
A requirement is optional if a default for a
|
||
given type or expression is specified[.](#allocator.requirements.general-3.sentence-3)
|
||
|
||
Within the standard library allocator_traits template, an optional requirement that is not supplied by an allocator is
|
||
replaced by the specified default type or expression[.](#allocator.requirements.general-3.sentence-4)
|
||
|
||
[*Note [1](#allocator.requirements.general-note-1)*:
|
||
|
||
There are no program-defined specializations of allocator_traits[.](#allocator.requirements.general-3.sentence-5)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:1)
|
||
|
||
`typename X::pointer
|
||
`
|
||
|
||
[4](#allocator.requirements.general-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2221)
|
||
|
||
*Remarks*: Default: T*
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:2)
|
||
|
||
`typename X::const_pointer
|
||
`
|
||
|
||
[5](#allocator.requirements.general-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2231)
|
||
|
||
*Mandates*: XX::pointer is convertible to XX::const_pointer[.](#allocator.requirements.general-5.sentence-1)
|
||
|
||
[6](#allocator.requirements.general-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2235)
|
||
|
||
*Remarks*: Default: pointer_traits<XX::pointer>::rebind<const T>
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:3)
|
||
|
||
`typename X::void_pointer
|
||
typename Y::void_pointer
|
||
`
|
||
|
||
[7](#allocator.requirements.general-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2246)
|
||
|
||
*Mandates*: XX::pointer is convertible to XX::void_pointer[.](#allocator.requirements.general-7.sentence-1)
|
||
|
||
XX::void_pointer and YY::void_pointer are the same type[.](#allocator.requirements.general-7.sentence-2)
|
||
|
||
[8](#allocator.requirements.general-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2251)
|
||
|
||
*Remarks*: Default:pointer_traits<XX::pointer>::rebind<void>
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:4)
|
||
|
||
`typename X::const_void_pointer
|
||
typename Y::const_void_pointer
|
||
`
|
||
|
||
[9](#allocator.requirements.general-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2263)
|
||
|
||
*Mandates*: XX::pointer, XX::const_pointer, and XX::void_pointer are convertible to XX::const_void_pointer[.](#allocator.requirements.general-9.sentence-1)
|
||
|
||
XX::const_void_pointer and YY::const_void_pointer are the same type[.](#allocator.requirements.general-9.sentence-2)
|
||
|
||
[10](#allocator.requirements.general-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2270)
|
||
|
||
*Remarks*: Default:pointer_traits<XX::pointer>::rebind<const void>
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:5)
|
||
|
||
`typename X::value_type
|
||
`
|
||
|
||
[11](#allocator.requirements.general-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2281)
|
||
|
||
*Result*: Identical to T[.](#allocator.requirements.general-11.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:6)
|
||
|
||
`typename X::size_type
|
||
`
|
||
|
||
[12](#allocator.requirements.general-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2291)
|
||
|
||
*Result*: An unsigned integer type
|
||
that can represent the size of the largest object in the allocation model[.](#allocator.requirements.general-12.sentence-1)
|
||
|
||
[13](#allocator.requirements.general-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2296)
|
||
|
||
*Remarks*: Default:make_unsigned_t<XX::difference_type>
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:7)
|
||
|
||
`typename X::difference_type
|
||
`
|
||
|
||
[14](#allocator.requirements.general-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2307)
|
||
|
||
*Result*: A signed integer type that can represent
|
||
the difference between any two pointers in the allocation model[.](#allocator.requirements.general-14.sentence-1)
|
||
|
||
[15](#allocator.requirements.general-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2312)
|
||
|
||
*Remarks*: Default:pointer_traits<XX::pointer>::difference_type
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:8)
|
||
|
||
`typename X::rebind<U>::other
|
||
`
|
||
|
||
[16](#allocator.requirements.general-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2323)
|
||
|
||
*Result*: Y
|
||
|
||
[17](#allocator.requirements.general-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2327)
|
||
|
||
*Postconditions*: For all U (including T),YY::rebind_alloc<T> is X[.](#allocator.requirements.general-17.sentence-1)
|
||
|
||
[18](#allocator.requirements.general-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2332)
|
||
|
||
*Remarks*: If Allocator is a class template instantiation of the formSomeAllocator<T, Args>, where Args is zero or more type
|
||
arguments, and Allocator does not supply a rebind member
|
||
template, the standard allocator_traits template usesSomeAllocator<U, Args> in place of Allocator::rebind<U>::other by default[.](#allocator.requirements.general-18.sentence-1)
|
||
|
||
For allocator types that are not template instantiations of the
|
||
above form, no default is provided[.](#allocator.requirements.general-18.sentence-2)
|
||
|
||
[19](#allocator.requirements.general-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2342)
|
||
|
||
[*Note [2](#allocator.requirements.general-note-2)*:
|
||
|
||
The member class template rebind of X is
|
||
effectively a typedef template[.](#allocator.requirements.general-19.sentence-1)
|
||
|
||
In general, if
|
||
the name Allocator is bound to SomeAllocator<T>, thenAllocator::rebind<U>::other is the same type asSomeAllocator<U>, whereSomeAllocator<T>::value_type is T andSomeAllocator<U>::value_type is U[.](#allocator.requirements.general-19.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:9)
|
||
|
||
`*p
|
||
`
|
||
|
||
[20](#allocator.requirements.general-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2360)
|
||
|
||
*Result*: T&
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:10)
|
||
|
||
`*q
|
||
`
|
||
|
||
[21](#allocator.requirements.general-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2370)
|
||
|
||
*Result*: const T&
|
||
|
||
[22](#allocator.requirements.general-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2374)
|
||
|
||
*Postconditions*: *q refers to the same object as *p[.](#allocator.requirements.general-22.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:11)
|
||
|
||
`p->m
|
||
`
|
||
|
||
[23](#allocator.requirements.general-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2384)
|
||
|
||
*Result*: Type of T::m[.](#allocator.requirements.general-23.sentence-1)
|
||
|
||
[24](#allocator.requirements.general-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2388)
|
||
|
||
*Preconditions*: (*p).m is well-defined[.](#allocator.requirements.general-24.sentence-1)
|
||
|
||
[25](#allocator.requirements.general-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2392)
|
||
|
||
*Effects*: Equivalent to (*p).m[.](#allocator.requirements.general-25.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:12)
|
||
|
||
`q->m
|
||
`
|
||
|
||
[26](#allocator.requirements.general-26)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2402)
|
||
|
||
*Result*: Type of T::m[.](#allocator.requirements.general-26.sentence-1)
|
||
|
||
[27](#allocator.requirements.general-27)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2406)
|
||
|
||
*Preconditions*: (*q).m is well-defined[.](#allocator.requirements.general-27.sentence-1)
|
||
|
||
[28](#allocator.requirements.general-28)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2410)
|
||
|
||
*Effects*: Equivalent to (*q).m[.](#allocator.requirements.general-28.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:13)
|
||
|
||
`static_cast<XX::pointer>(w)
|
||
`
|
||
|
||
[29](#allocator.requirements.general-29)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2420)
|
||
|
||
*Result*: XX::pointer
|
||
|
||
[30](#allocator.requirements.general-30)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2424)
|
||
|
||
*Postconditions*: static_cast<XX::pointer>(w) == p[.](#allocator.requirements.general-30.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:14)
|
||
|
||
`static_cast<XX::const_pointer>(x)
|
||
`
|
||
|
||
[31](#allocator.requirements.general-31)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2434)
|
||
|
||
*Result*: XX::const_pointer
|
||
|
||
[32](#allocator.requirements.general-32)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2438)
|
||
|
||
*Postconditions*: static_cast<XX::const_pointer>(x) == q[.](#allocator.requirements.general-32.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:15)
|
||
|
||
`pointer_traits<XX::pointer>::pointer_to(r)
|
||
`
|
||
|
||
[33](#allocator.requirements.general-33)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2448)
|
||
|
||
*Result*: XX::pointer
|
||
|
||
[34](#allocator.requirements.general-34)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2452)
|
||
|
||
*Postconditions*: Same as p[.](#allocator.requirements.general-34.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:16)
|
||
|
||
`a.allocate(n)
|
||
`
|
||
|
||
[35](#allocator.requirements.general-35)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2462)
|
||
|
||
*Result*: XX::pointer
|
||
|
||
[36](#allocator.requirements.general-36)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2466)
|
||
|
||
*Effects*: Memory is allocated for an array of n T and such an object is created
|
||
but array elements are not constructed[.](#allocator.requirements.general-36.sentence-1)
|
||
|
||
[*Example [1](#allocator.requirements.general-example-1)*:
|
||
|
||
When reusing storage denoted by some pointer value p,launder(reinterpret_cast<T*>(new (p) byte[n * sizeof(T)])) can be used to implicitly create a suitable array object
|
||
and obtain a pointer to it[.](#allocator.requirements.general-36.sentence-2)
|
||
|
||
â *end example*]
|
||
|
||
[37](#allocator.requirements.general-37)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2478)
|
||
|
||
*Throws*: allocate may throw an appropriate exception[.](#allocator.requirements.general-37.sentence-1)
|
||
|
||
[38](#allocator.requirements.general-38)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2482)
|
||
|
||
[*Note [3](#allocator.requirements.general-note-3)*:
|
||
|
||
It is intended that a.allocate be an efficient means
|
||
of allocating a single object of type T, even when sizeof(T) is small[.](#allocator.requirements.general-38.sentence-1)
|
||
|
||
That is, there is no need for a container to maintain its own
|
||
free list[.](#allocator.requirements.general-38.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[39](#allocator.requirements.general-39)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2490)
|
||
|
||
*Remarks*: If n == 0, the return value is unspecified[.](#allocator.requirements.general-39.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:17)
|
||
|
||
`a.allocate(n, y)
|
||
`
|
||
|
||
[40](#allocator.requirements.general-40)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2500)
|
||
|
||
*Result*: XX::pointer
|
||
|
||
[41](#allocator.requirements.general-41)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2504)
|
||
|
||
*Effects*: Same as a.allocate(n)[.](#allocator.requirements.general-41.sentence-1)
|
||
|
||
The use of y is unspecified, but it is intended as an aid to locality[.](#allocator.requirements.general-41.sentence-2)
|
||
|
||
[42](#allocator.requirements.general-42)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2509)
|
||
|
||
*Remarks*: Default: a.allocate(n)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:18)
|
||
|
||
`a.allocate_at_least(n)
|
||
`
|
||
|
||
[43](#allocator.requirements.general-43)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2519)
|
||
|
||
*Result*: allocation_result<XX::pointer, XX::size_type>
|
||
|
||
[44](#allocator.requirements.general-44)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2523)
|
||
|
||
*Returns*: allocation_result<XX::pointer, XX::size_type>{ptr, count} where ptr is memory allocated for an array of count T and such an object is created but array elements are not constructed,
|
||
such that count ⥠n[.](#allocator.requirements.general-44.sentence-1)
|
||
|
||
If n == 0, the return value is unspecified[.](#allocator.requirements.general-44.sentence-2)
|
||
|
||
[45](#allocator.requirements.general-45)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2531)
|
||
|
||
*Throws*: allocate_at_least may throw an appropriate exception[.](#allocator.requirements.general-45.sentence-1)
|
||
|
||
[46](#allocator.requirements.general-46)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2535)
|
||
|
||
*Remarks*: Default: {a.allocate(n), n}[.](#allocator.requirements.general-46.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:19)
|
||
|
||
`a.deallocate(p, n)
|
||
`
|
||
|
||
[47](#allocator.requirements.general-47)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2545)
|
||
|
||
*Result*: (not used)
|
||
|
||
[48](#allocator.requirements.general-48)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2549)
|
||
|
||
*Preconditions*:
|
||
|
||
- [(48.1)](#allocator.requirements.general-48.1)
|
||
|
||
If p is memory
|
||
that was obtained by a call to a.allocate_at_least,
|
||
let ret be the value returned andreq be the value passed as the first argument of that call[.](#allocator.requirements.general-48.1.sentence-1)
|
||
p is equal to ret.ptr andn is a value such thatreq ⤠n ⤠ret.count[.](#allocator.requirements.general-48.1.sentence-2)
|
||
|
||
- [(48.2)](#allocator.requirements.general-48.2)
|
||
|
||
Otherwise, p is a pointer value obtained from allocate[.](#allocator.requirements.general-48.2.sentence-1)
|
||
n equals the value passed as the first argument
|
||
to the invocation of allocate which returned p[.](#allocator.requirements.general-48.2.sentence-2)
|
||
|
||
p has not been invalidated by
|
||
an intervening call to deallocate[.](#allocator.requirements.general-48.sentence-2)
|
||
|
||
[49](#allocator.requirements.general-49)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2568)
|
||
|
||
*Throws*: Nothing[.](#allocator.requirements.general-49.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:20)
|
||
|
||
`a.max_size()
|
||
`
|
||
|
||
[50](#allocator.requirements.general-50)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2578)
|
||
|
||
*Result*: XX::size_type
|
||
|
||
[51](#allocator.requirements.general-51)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2582)
|
||
|
||
*Returns*: The largest value n that can meaningfully be passed to a.allocate(n)[.](#allocator.requirements.general-51.sentence-1)
|
||
|
||
[52](#allocator.requirements.general-52)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2586)
|
||
|
||
*Remarks*: Default:numeric_limits<size_type>::max() / sizeof(value_type)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:21)
|
||
|
||
`a1 == a2
|
||
`
|
||
|
||
[53](#allocator.requirements.general-53)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2597)
|
||
|
||
*Result*: bool
|
||
|
||
[54](#allocator.requirements.general-54)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2601)
|
||
|
||
*Returns*: true only if storage allocated from each can
|
||
be deallocated via the other[.](#allocator.requirements.general-54.sentence-1)
|
||
|
||
[55](#allocator.requirements.general-55)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2606)
|
||
|
||
*Throws*: Nothing[.](#allocator.requirements.general-55.sentence-1)
|
||
|
||
[56](#allocator.requirements.general-56)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2610)
|
||
|
||
*Remarks*: operator== shall be reflexive, symmetric,
|
||
and transitive[.](#allocator.requirements.general-56.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:22)
|
||
|
||
`a1 != a2
|
||
`
|
||
|
||
[57](#allocator.requirements.general-57)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2621)
|
||
|
||
*Result*: bool
|
||
|
||
[58](#allocator.requirements.general-58)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2625)
|
||
|
||
*Returns*: !(a1 == a2)[.](#allocator.requirements.general-58.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:23)
|
||
|
||
`a == b
|
||
`
|
||
|
||
[59](#allocator.requirements.general-59)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2635)
|
||
|
||
*Result*: bool
|
||
|
||
[60](#allocator.requirements.general-60)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2639)
|
||
|
||
*Returns*: a == YY::rebind_alloc<T>(b)[.](#allocator.requirements.general-60.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:24)
|
||
|
||
`a != b
|
||
`
|
||
|
||
[61](#allocator.requirements.general-61)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2649)
|
||
|
||
*Result*: bool
|
||
|
||
[62](#allocator.requirements.general-62)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2653)
|
||
|
||
*Returns*: !(a == b)[.](#allocator.requirements.general-62.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:25)
|
||
|
||
`X u(a);
|
||
X u = a;
|
||
`
|
||
|
||
[63](#allocator.requirements.general-63)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2664)
|
||
|
||
*Postconditions*: u == a
|
||
|
||
[64](#allocator.requirements.general-64)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2668)
|
||
|
||
*Throws*: Nothing[.](#allocator.requirements.general-64.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:26)
|
||
|
||
`X u(b);
|
||
`
|
||
|
||
[65](#allocator.requirements.general-65)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2678)
|
||
|
||
*Postconditions*: Y(u) == b and u == X(b)[.](#allocator.requirements.general-65.sentence-1)
|
||
|
||
[66](#allocator.requirements.general-66)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2682)
|
||
|
||
*Throws*: Nothing[.](#allocator.requirements.general-66.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:27)
|
||
|
||
`X u(std::move(a));
|
||
X u = std::move(a);
|
||
`
|
||
|
||
[67](#allocator.requirements.general-67)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2693)
|
||
|
||
*Postconditions*: The value of a is unchanged and is equal to u[.](#allocator.requirements.general-67.sentence-1)
|
||
|
||
[68](#allocator.requirements.general-68)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2697)
|
||
|
||
*Throws*: Nothing[.](#allocator.requirements.general-68.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:28)
|
||
|
||
`X u(std::move(b));
|
||
`
|
||
|
||
[69](#allocator.requirements.general-69)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2707)
|
||
|
||
*Postconditions*: u is equal to the prior value of X(b)[.](#allocator.requirements.general-69.sentence-1)
|
||
|
||
[70](#allocator.requirements.general-70)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2711)
|
||
|
||
*Throws*: Nothing[.](#allocator.requirements.general-70.sentence-1)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:29)
|
||
|
||
`a.construct(c, args...)
|
||
`
|
||
|
||
[71](#allocator.requirements.general-71)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2721)
|
||
|
||
*Result*: (not used)
|
||
|
||
[72](#allocator.requirements.general-72)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2725)
|
||
|
||
*Effects*: Constructs an object of type C at c[.](#allocator.requirements.general-72.sentence-1)
|
||
|
||
[73](#allocator.requirements.general-73)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2729)
|
||
|
||
*Remarks*: Default:construct_at(c, std::forward<Args>(args)...)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:30)
|
||
|
||
`a.destroy(c)
|
||
`
|
||
|
||
[74](#allocator.requirements.general-74)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2740)
|
||
|
||
*Result*: (not used)
|
||
|
||
[75](#allocator.requirements.general-75)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2744)
|
||
|
||
*Effects*: Destroys the object at c[.](#allocator.requirements.general-75.sentence-1)
|
||
|
||
[76](#allocator.requirements.general-76)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2748)
|
||
|
||
*Remarks*: Default: destroy_at(c)
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:31)
|
||
|
||
`a.select_on_container_copy_construction()
|
||
`
|
||
|
||
[77](#allocator.requirements.general-77)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2758)
|
||
|
||
*Result*: X
|
||
|
||
[78](#allocator.requirements.general-78)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2762)
|
||
|
||
*Returns*: Typically returns either a or X()[.](#allocator.requirements.general-78.sentence-1)
|
||
|
||
[79](#allocator.requirements.general-79)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2766)
|
||
|
||
*Remarks*: Default: return a;
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:32)
|
||
|
||
`typename X::propagate_on_container_copy_assignment
|
||
`
|
||
|
||
[80](#allocator.requirements.general-80)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2776)
|
||
|
||
*Result*: Identical to or derived from true_type or false_type[.](#allocator.requirements.general-80.sentence-1)
|
||
|
||
[81](#allocator.requirements.general-81)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2780)
|
||
|
||
*Returns*: true_type only if an allocator of type X should be copied
|
||
when the client container is copy-assigned;
|
||
if so, X shall meet
|
||
the [*Cpp17CopyAssignable*](#:Cpp17CopyAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements (Table [34](#tab:cpp17.copyassignable "Table 34: Cpp17CopyAssignable requirements (in addition to Cpp17MoveAssignable)")) and
|
||
the copy operation shall not throw exceptions[.](#allocator.requirements.general-81.sentence-1)
|
||
|
||
[82](#allocator.requirements.general-82)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2788)
|
||
|
||
*Remarks*: Default: false_type
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:33)
|
||
|
||
`typename X::propagate_on_container_move_assignment
|
||
`
|
||
|
||
[83](#allocator.requirements.general-83)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2798)
|
||
|
||
*Result*: Identical to or derived from true_type or false_type[.](#allocator.requirements.general-83.sentence-1)
|
||
|
||
[84](#allocator.requirements.general-84)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2802)
|
||
|
||
*Returns*: true_type only if an allocator of type X should be moved
|
||
when the client container is move-assigned;
|
||
if so, X shall meet
|
||
the [*Cpp17MoveAssignable*](#:Cpp17MoveAssignable "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements (Table [33](#tab:cpp17.moveassignable "Table 33: Cpp17MoveAssignable requirements")) and
|
||
the move operation shall not throw exceptions[.](#allocator.requirements.general-84.sentence-1)
|
||
|
||
[85](#allocator.requirements.general-85)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2810)
|
||
|
||
*Remarks*: Default: false_type
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:34)
|
||
|
||
`typename X::propagate_on_container_swap
|
||
`
|
||
|
||
[86](#allocator.requirements.general-86)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2820)
|
||
|
||
*Result*: Identical to or derived from true_type or false_type[.](#allocator.requirements.general-86.sentence-1)
|
||
|
||
[87](#allocator.requirements.general-87)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2824)
|
||
|
||
*Returns*: true_type only if an allocator of type X should be swapped
|
||
when the client container is swapped;
|
||
if so,X shall meet the [*Cpp17Swappable*](#:Cpp17Swappable "16.4.4.3 Swappable requirements [swappable.requirements]") requirements ([[swappable.requirements]](#swappable.requirements "16.4.4.3 Swappable requirements")) and
|
||
the swap operation shall not throw exceptions[.](#allocator.requirements.general-87.sentence-1)
|
||
|
||
[88](#allocator.requirements.general-88)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2832)
|
||
|
||
*Remarks*: Default: false_type
|
||
|
||
[ð](#allocator.requirements.general-itemdecl:35)
|
||
|
||
`typename X::is_always_equal
|
||
`
|
||
|
||
[89](#allocator.requirements.general-89)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2842)
|
||
|
||
*Result*: Identical to or derived from true_type or false_type[.](#allocator.requirements.general-89.sentence-1)
|
||
|
||
[90](#allocator.requirements.general-90)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2846)
|
||
|
||
*Returns*: true_type only if the expression a1 == a2 is guaranteed
|
||
to be true for any two (possibly const) valuesa1, a2 of type X[.](#allocator.requirements.general-90.sentence-1)
|
||
|
||
[91](#allocator.requirements.general-91)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2852)
|
||
|
||
*Remarks*: Default: is_empty<X>::type
|
||
|
||
[92](#allocator.requirements.general-92)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2857)
|
||
|
||
An allocator type X shall meet the[*Cpp17CopyConstructible*](#:Cpp17CopyConstructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements (Table [32](#tab:cpp17.copyconstructible "Table 32: Cpp17CopyConstructible requirements (in addition to Cpp17MoveConstructible)"))[.](#allocator.requirements.general-92.sentence-1)
|
||
|
||
The XX::pointer, XX::const_pointer, XX::void_pointer, andXX::const_void_pointer types shall meet the*Cpp17NullablePointer* requirements (Table [36](#tab:cpp17.nullablepointer "Table 36: Cpp17NullablePointer requirements"))[.](#allocator.requirements.general-92.sentence-2)
|
||
|
||
No constructor,
|
||
comparison operator function, copy operation, move operation, or swap operation on
|
||
these pointer types shall exit via an exception[.](#allocator.requirements.general-92.sentence-3)
|
||
|
||
XX::pointer and XX::const_pointer shall also
|
||
meet the requirements for
|
||
a [*Cpp17RandomAccessIterator*](random.access.iterators#:Cpp17RandomAccessIterator "24.3.5.7 Random access iterators [random.access.iterators]") ([[random.access.iterators]](random.access.iterators "24.3.5.7 Random access iterators")) and
|
||
the additional requirement that, when p and (p + n) are
|
||
dereferenceable pointer values for some integral value n,addressof(*(p + n)) == addressof(*p) + n is true[.](#allocator.requirements.general-92.sentence-4)
|
||
|
||
[93](#allocator.requirements.general-93)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2875)
|
||
|
||
Let x1 and x2 denote objects of (possibly different) typesXX::void_pointer, XX::const_void_pointer, XX::pointer,
|
||
or XX::const_pointer[.](#allocator.requirements.general-93.sentence-1)
|
||
|
||
Then, x1 and x2 are[*equivalently-valued*](#def:equivalently-valued "16.4.4.6.1 General [allocator.requirements.general]") pointer values, if and only if both x1 and x2 can be explicitly converted to the two corresponding objects px1 and px2 of type XX::const_pointer, using a sequence of static_casts
|
||
using only these four types, and the expression px1 == px2 evaluates to true[.](#allocator.requirements.general-93.sentence-2)
|
||
|
||
[94](#allocator.requirements.general-94)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2885)
|
||
|
||
Let w1 and w2 denote objects of type XX::void_pointer[.](#allocator.requirements.general-94.sentence-1)
|
||
|
||
Then for the expressionsw1 == w2
|
||
w1 != w2 either or both objects may be replaced by an equivalently-valued object of typeXX::const_void_pointer with no change in semantics[.](#allocator.requirements.general-94.sentence-2)
|
||
|
||
[95](#allocator.requirements.general-95)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2895)
|
||
|
||
Let p1 and p2 denote objects of type XX::pointer[.](#allocator.requirements.general-95.sentence-1)
|
||
|
||
Then for the expressionsp1 == p2
|
||
p1 != p2
|
||
p1 < p2
|
||
p1 <= p2
|
||
p1 >= p2
|
||
p1 > p2
|
||
p1 - p2 either or both objects may be replaced by an equivalently-valued object of typeXX::const_pointer with no change in semantics[.](#allocator.requirements.general-95.sentence-2)
|
||
|
||
[96](#allocator.requirements.general-96)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2910)
|
||
|
||
An allocator may constrain the types on which it can be instantiated and the
|
||
arguments for which its construct or destroy members may be
|
||
called[.](#allocator.requirements.general-96.sentence-1)
|
||
|
||
If a type cannot be used with a particular allocator, the allocator
|
||
class or the call to construct or destroy may fail to instantiate[.](#allocator.requirements.general-96.sentence-2)
|
||
|
||
[97](#allocator.requirements.general-97)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2916)
|
||
|
||
If the alignment associated with a specific over-aligned type is not
|
||
supported by an allocator, instantiation of the allocator for that type may
|
||
fail[.](#allocator.requirements.general-97.sentence-1)
|
||
|
||
The allocator also may silently ignore the requested alignment[.](#allocator.requirements.general-97.sentence-2)
|
||
|
||
[*Note [4](#allocator.requirements.general-note-4)*:
|
||
|
||
Additionally, the member function allocate for that type can fail by throwing an object of typebad_alloc[.](#allocator.requirements.general-97.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[98](#allocator.requirements.general-98)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2926)
|
||
|
||
[*Example [2](#allocator.requirements.general-example-2)*:
|
||
|
||
The following is an allocator class template supporting the minimal
|
||
interface that meets the requirements of [[allocator.requirements.general]](#allocator.requirements.general "16.4.4.6.1 General"):template<class T>struct SimpleAllocator {using value_type = T;
|
||
SimpleAllocator(*ctor args*); template<class U> SimpleAllocator(const SimpleAllocator<U>& other);
|
||
|
||
T* allocate(std::size_t n); void deallocate(T* p, std::size_t n); template<class U> bool operator==(const SimpleAllocator<U>& rhs) const;};
|
||
|
||
â *end example*]
|
||
|
||
[99](#allocator.requirements.general-99)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2946)
|
||
|
||
The following exposition-only concept defines
|
||
the minimal requirements on an Allocator type[.](#allocator.requirements.general-99.sentence-1)
|
||
|
||
template<class Alloc>concept [*simple-allocator*](#concept:simple-allocator "16.4.4.6.1 General [allocator.requirements.general]") =requires(Alloc alloc, size_t n) {{ *alloc.allocate(n) } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<typename Alloc::value_type&>; { alloc.deallocate(alloc.allocate(n), n) }; } &&[copy_constructible](concept.copyconstructible#concept:copy_constructible "18.4.14 Concept copy_constructible [concept.copyconstructible]")<Alloc> &&[equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<Alloc>;
|
||
|
||
A type Alloc models [*simple-allocator*](#concept:simple-allocator "16.4.4.6.1 General [allocator.requirements.general]") if it meets the requirements of [[allocator.requirements.general]](#allocator.requirements.general "16.4.4.6.1 General")[.](#allocator.requirements.general-99.sentence-2)
|
||
|
||
#### [16.4.4.6.2](#allocator.requirements.completeness) Allocator completeness requirements [[allocator.requirements.completeness]](allocator.requirements.completeness)
|
||
|
||
[1](#allocator.requirements.completeness-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L2964)
|
||
|
||
If X is an allocator class for type T,X additionally meets the allocator completeness requirements if,
|
||
whether or not T is a complete type:
|
||
|
||
- [(1.1)](#allocator.requirements.completeness-1.1)
|
||
|
||
X is a complete type, and
|
||
|
||
- [(1.2)](#allocator.requirements.completeness-1.2)
|
||
|
||
all the member types of [allocator_traits<X>](allocator.traits "20.2.9 Allocator traits [allocator.traits]") other than value_type are complete types[.](#allocator.requirements.completeness-1.sentence-1)
|