From Jason Turner

[concept.swappable]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpslv6pl7h/{from.md → to.md} +14 -10
tmp/tmpslv6pl7h/{from.md → to.md} RENAMED
@@ -21,31 +21,35 @@ if the operation modifies neither `t2` nor `u2` and:
21
  The name `ranges::swap` denotes a customization point object
22
  [[customization.point.object]]. The expression `ranges::swap(E1, E2)`
23
  for subexpressions `E1` and `E2` is expression-equivalent to an
24
  expression `S` determined as follows:
25
 
26
- - `S` is `(void)swap(E1, E2)`[^1] if `E1` or `E2` has class or
27
- enumeration type [[basic.compound]] and that expression is valid, with
28
- overload resolution performed in a context that includes the
29
- declaration
30
  ``` cpp
31
  template<class T>
32
  void swap(T&, T&) = delete;
33
  ```
34
 
35
  and does not include a declaration of `ranges::swap`. If the function
36
  selected by overload resolution does not exchange the values denoted
37
  by `E1` and `E2`, the program is ill-formed, no diagnostic required.
 
 
 
 
38
  - Otherwise, if `E1` and `E2` are lvalues of array types
39
  [[basic.compound]] with equal extent and `ranges::swap(*E1, *E2)` is a
40
  valid expression, `S` is `(void)ranges::swap_ranges(E1, E2)`, except
41
  that `noexcept(S)` is equal to `noexcept({}ranges::swap(*E1, *E2))`.
42
  - Otherwise, if `E1` and `E2` are lvalues of the same type `T` that
43
  models `move_constructible<T>` and `assignable_from<T&, T>`, `S` is an
44
  expression that exchanges the denoted values. `S` is a constant
45
  expression if
46
- - `T` is a literal type [[basic.types]],
47
  - both `E1 = std::move(E2)` and `E2 = std::move(E1)` are constant
48
  subexpressions [[defns.const.subexpr]], and
49
  - the full-expressions of the initializers in the declarations
50
  ``` cpp
51
  T t1(std::move(E1));
@@ -54,15 +58,15 @@ expression `S` determined as follows:
54
 
55
  are constant subexpressions.
56
 
57
  `noexcept(S)` is equal to
58
  `is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T>`.
59
- - Otherwise, `ranges::swap(E1, E2)` is ill-formed. \[*Note 2*: This case
60
  can result in substitution failure when `ranges::swap(E1, E2)` appears
61
  in the immediate context of a template instantiation. — *end note*]
62
 
63
- [*Note 3*: Whenever `ranges::swap(E1, E2)` is a valid expression, it
64
  exchanges the values denoted by `E1` and `E2` and has type
65
  `void`. — *end note*]
66
 
67
  ``` cpp
68
  template<class T>
@@ -79,13 +83,13 @@ template<class T, class U>
79
  ranges::swap(std::forward<T>(t), std::forward<U>(u));
80
  ranges::swap(std::forward<U>(u), std::forward<T>(t));
81
  };
82
  ```
83
 
84
- [*Note 4*: The semantics of the `swappable` and `swappable_with`
85
- concepts are fully defined by the `ranges::swap` customization
86
- point. — *end note*]
87
 
88
  [*Example 1*:
89
 
90
  User code can ensure that the evaluation of `swap` calls is performed in
91
  an appropriate context under the various conditions as follows:
 
21
  The name `ranges::swap` denotes a customization point object
22
  [[customization.point.object]]. The expression `ranges::swap(E1, E2)`
23
  for subexpressions `E1` and `E2` is expression-equivalent to an
24
  expression `S` determined as follows:
25
 
26
+ - `S` is `(void)swap(E1, E2)`[^1]
27
+ if `E1` or `E2` has class or enumeration type [[basic.compound]] and
28
+ that expression is valid, with overload resolution performed in a
29
+ context that includes the declaration
30
  ``` cpp
31
  template<class T>
32
  void swap(T&, T&) = delete;
33
  ```
34
 
35
  and does not include a declaration of `ranges::swap`. If the function
36
  selected by overload resolution does not exchange the values denoted
37
  by `E1` and `E2`, the program is ill-formed, no diagnostic required.
38
+ \[*Note 2*: This precludes calling unconstrained program-defined
39
+ overloads of `swap`. When the deleted overload is viable,
40
+ program-defined overloads need to be more specialized
41
+ [[temp.func.order]] to be selected. — *end note*]
42
  - Otherwise, if `E1` and `E2` are lvalues of array types
43
  [[basic.compound]] with equal extent and `ranges::swap(*E1, *E2)` is a
44
  valid expression, `S` is `(void)ranges::swap_ranges(E1, E2)`, except
45
  that `noexcept(S)` is equal to `noexcept({}ranges::swap(*E1, *E2))`.
46
  - Otherwise, if `E1` and `E2` are lvalues of the same type `T` that
47
  models `move_constructible<T>` and `assignable_from<T&, T>`, `S` is an
48
  expression that exchanges the denoted values. `S` is a constant
49
  expression if
50
+ - `T` is a literal type [[term.literal.type]],
51
  - both `E1 = std::move(E2)` and `E2 = std::move(E1)` are constant
52
  subexpressions [[defns.const.subexpr]], and
53
  - the full-expressions of the initializers in the declarations
54
  ``` cpp
55
  T t1(std::move(E1));
 
58
 
59
  are constant subexpressions.
60
 
61
  `noexcept(S)` is equal to
62
  `is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T>`.
63
+ - Otherwise, `ranges::swap(E1, E2)` is ill-formed. \[*Note 3*: This case
64
  can result in substitution failure when `ranges::swap(E1, E2)` appears
65
  in the immediate context of a template instantiation. — *end note*]
66
 
67
+ [*Note 4*: Whenever `ranges::swap(E1, E2)` is a valid expression, it
68
  exchanges the values denoted by `E1` and `E2` and has type
69
  `void`. — *end note*]
70
 
71
  ``` cpp
72
  template<class T>
 
83
  ranges::swap(std::forward<T>(t), std::forward<U>(u));
84
  ranges::swap(std::forward<U>(u), std::forward<T>(t));
85
  };
86
  ```
87
 
88
+ [*Note 5*: The semantics of the `swappable` and `swappable_with`
89
+ concepts are fully defined by the `ranges::swap` customization point
90
+ object. — *end note*]
91
 
92
  [*Example 1*:
93
 
94
  User code can ensure that the evaluation of `swap` calls is performed in
95
  an appropriate context under the various conditions as follows: