Files
cppdraft_translate/cppdraft/swappable/requirements.md
2025-10-25 03:02:53 +03:00

116 lines
5.0 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[swappable.requirements]
# 16 Library introduction [[library]](./#library)
## 16.4 Library-wide requirements [[requirements]](requirements#swappable.requirements)
### 16.4.4 Requirements on types and expressions [[utility.requirements]](utility.requirements#swappable.requirements)
#### 16.4.4.3 Swappable requirements [swappable.requirements]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L1913)
This subclause provides definitions for swappable types and expressions[.](#1.sentence-1)
In these
definitions, let t denote an expression of type T, and let u denote an expression of type U[.](#1.sentence-2)
[2](#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.3Swappable requirements[swappable.requirements]") an object u if and only if
- [(2.1)](#2.1)
the expressions swap(t, u) and swap(u, t) are valid when
evaluated in the context described below, and
- [(2.2)](#2.2)
these expressions have the following effects:
* [(2.2.1)](#2.2.1)
the object referred to by t has the value originally held by u and
* [(2.2.2)](#2.2.2)
the object referred to by u has the value originally held by t[.](#2.sentence-1)
[3](#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.2Overload resolution[over.match]") on a candidate set that includes:
- [(3.1)](#3.1)
the two swap function templates defined in[<utility>](utility.syn#header:%3cutility%3e "22.2.1Header <utility> synopsis[utility.syn]") and
- [(3.2)](#3.2)
the lookup set produced by [argument-dependent lookup](basic.lookup.argdep "6.5.4Argument-dependent name lookup[basic.lookup.argdep]")[.](#3.sentence-1)
[*Note [1](#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.1Header <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[.](#3.sentence-2)
— *end note*]
[*Note [2](#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.1Header <utility> synopsis[utility.syn]") to ensure an appropriate
evaluation context[.](#3.sentence-3)
— *end note*]
[4](#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.3Swappable requirements[swappable.requirements]") if and only if t is
swappable with any rvalue or lvalue, respectively, of type T[.](#4.sentence-1)
[5](#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[.](#5.sentence-1)
[6](#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.3Iterator requirements"))
meets the *Cpp17ValueSwappable* requirements if,
for any dereferenceable objectx of type X,*x is swappable[.](#6.sentence-1)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/lib-intro.tex#L1969)
[*Example [1](#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.3Swappable 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*]