Skip to content

Commit 7e236bd

Browse files
committed
Apply resolution of LWG 2451 (from motion 3).
1 parent 38cd9b4 commit 7e236bd

File tree

1 file changed

+108
-2
lines changed

1 file changed

+108
-2
lines changed

Diff for: optional.html

+108-2
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ <h1><code>optional</code> for object types</h1>
105105
template &lt;class... Args&gt; constexpr explicit optional(in_place_t, Args&amp;&amp;...);
106106
template &lt;class U, class... Args&gt;
107107
constexpr explicit optional(in_place_t, initializer_list&lt;U&gt;, Args&amp;&amp;...);
108+
template &lt;class U&gt; constexpr optional(U&amp;&amp;);
109+
template &lt;class U&gt; constexpr optional(const optional&lt;U&gt;&amp;);
110+
template &lt;class U&gt; constexpr optional(optional&lt;U&gt;&amp;&amp;);
108111

109112
<cxx-ref insynopsis="" to="optional.object.dtor"></cxx-ref>
110113
~optional();
@@ -114,6 +117,8 @@ <h1><code>optional</code> for object types</h1>
114117
optional&amp; operator=(const optional&amp;);
115118
optional&amp; operator=(optional&amp;&amp;) noexcept(<em>see below</em>);
116119
template &lt;class U&gt; optional&amp; operator=(U&amp;&amp;);
120+
template &lt;class U&gt; optional&amp; operator=(const optional&lt;U&gt;&amp;);
121+
template &lt;class U&gt; optional&amp; operator=(optional&lt;U&gt;&amp;&amp;);
117122
template &lt;class... Args&gt; void emplace(Args&amp;&amp;...);
118123
template &lt;class U, class... Args&gt;
119124
void emplace(initializer_list&lt;U&gt;, Args&amp;&amp;...);
@@ -232,6 +237,44 @@ <h1>Constructors</h1>
232237
<cxx-remarks>The function shall not participate in overload resolution unless <code>is_constructible_v&lt;T, initializer_list&lt;U&gt;&amp;, Args&amp;&amp;...&gt;</code> is <code>true</code>.
233238
If <code>T</code>'s constructor selected for the initialization is a <code>constexpr</code> constructor, this constructor shall be a <code>constexpr</code> constructor.</cxx-remarks>
234239
</cxx-function>
240+
241+
<cxx-note>The following constructors are conditionally specified as <code>explicit</code>. This is typically implemented by declaring two such constructors, of which at most one participates in overload resolution.</cxx-note>
242+
243+
<cxx-function>
244+
<cxx-signature>template &lt;class U&gt;
245+
constexpr optional(U&amp;&amp; v);</cxx-signature>
246+
247+
<cxx-effects>Initializes the contained value as if direct-non-list-initializing an object of type <code>T</code> with the expression <code>std::forward&lt;U&gt;(v)</code>.</cxx-effects>
248+
<cxx-postconditions><code>*this</code> contains a value.</cxx-postconditions>
249+
<cxx-throws>Any exception thrown by the selected constructor of <code>T</code>.</cxx-throws>
250+
<cxx-remarks>If <code>T</code>'s selected constructor is a <code>constexpr</code> constructor, this constructor shall be a <code>constexpr</code> constructor.
251+
This constructor shall not participate in overload resolution unless <code>is_constructible_v&lt;T, U&amp;&amp;&gt;</code> is <code>true</code> and <code>U</code> is not the same type as <code>T</code>.
252+
The constructor is <code>explicit</code> if and only if <code>is_convertible_v&lt;U&amp;&amp;, T&gt;</code> is <code>false</code>.</cxx-remarks>
253+
</cxx-function>
254+
255+
<cxx-function>
256+
<cxx-signature>template &lt;class U&gt;
257+
constexpr optional(const optional&lt;U&gt;&amp; rhs);</cxx-signature>
258+
259+
<cxx-effects>If <code>rhs</code> contains a value, initializes the contained value as if direct-non-list-initializing an object of type <code>T</code> with the expression <code>*rhs</code>.</cxx-effects>
260+
<cxx-postconditions><code>bool(rhs) == bool(*this)</code>.</cxx-postconditions>
261+
<cxx-throws>Any exception thrown by the selected constructor of <code>T</code>.</cxx-throws>
262+
<cxx-remarks>If <code>T</code>'s selected constructor is a <code>constexpr</code> constructor, this constructor shall be a <code>constexpr</code> constructor.
263+
This constructor shall not participate in overload resolution unless <code>is_constructible_v&lt;T, const U&amp;&gt;</code> is <code>true</code>, <code>is_same&lt;decay_t&lt;U&gt;, T&gt;</code> is <code>false</code>, <code>is_constructible_v&lt;T, const optional&lt;U&gt;&amp;&gt;</code> is <code>false</code> and <code>is_convertible_v&lt;const optional&lt;U&gt;&amp;, T&gt;</code> is <code>false</code>.
264+
The constructor is <code>explicit</code> if and only if <code>is_convertible_v&lt;const U&amp;, T&gt;</code> is <code>false</code>.</cxx-remarks>
265+
</cxx-function>
266+
267+
<cxx-function>
268+
<cxx-signature>template &lt;class U&gt;
269+
constexpr optional(optional&lt;U&gt;&amp;&amp; rhs);</cxx-signature>
270+
271+
<cxx-effects>If <code>rhs</code> contains a value, initializes the contained value as if direct-non-list-initializing an object of type <code>T</code> with the expression <code>std::move(*rhs)</code>. <code>bool(rhs)</code> is unchanged.</cxx-effects>
272+
<cxx-postconditions><code>bool(rhs) == bool(*this)</code>.</cxx-postconditions>
273+
<cxx-throws>Any exception thrown by the selected constructor of <code>T</code>.</cxx-throws>
274+
<cxx-remarks>If <code>T</code>'s selected constructor is a <code>constexpr</code> constructor, this constructor shall be a <code>constexpr</code> constructor.
275+
This constructor shall not participate in overload resolution unless <code>is_constructible_v&lt;T, U&amp;&amp;&gt;</code> is <code>true</code>, <code>is_same&lt;decay_t&lt;U&gt;, T&gt;</code> is <code>false</code>, <code>is_constructible_v&lt;T, optional&lt;U&gt;&amp;&amp;&gt;</code> is <code>false</code> and <code>is_convertible_v&lt;optional&lt;U&gt;&amp;&amp;, T&gt;</code> is <code>false</code> and <code>U</code> is not the same type as <code>T</code>.
276+
The constructor is <code>explicit</code> if and only if <code>is_convertible_v&lt;U&amp;&amp;, T&gt;</code> is <code>false</code>.</cxx-remarks>
277+
</cxx-function>
235278
</cxx-section>
236279

237280
<cxx-section id="optional.object.dtor">
@@ -340,9 +383,72 @@ <h1>Assignment</h1>
340383
<cxx-remarks>
341384
<p>If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged. If an exception is thrown during the call to <code>T</code>'s constructor, the state of <code><var>v</var></code> is determined by the exception safety guarantee of <code>T</code>'s constructor. If an exception is thrown during the call to <code>T</code>'s assignment, the state of <code><var>*val</var></code> and <code><var>v</var></code> is determined by the exception safety guarantee of <code>T</code>'s assignment.</p>
342385
<p>The function shall not participate in overload resolution unless
343-
<code>is_same_v&lt;decay_t&lt;U&gt;, T&gt;</code> is <code>true</code>.</p>
386+
<code>decay_t&lt;U&gt;</code> is not <code>nullopt_t</code> and <code>decay_t&lt;U&gt;</code> is not a specialization of <code>optional</code>.</p>
344387
</cxx-remarks>
345-
<cxx-notes>The reason for providing such generic assignment and then constraining it so that effectively <code>T</code> == <code>U</code> is to guarantee that assignment of the form <code>o = {}</code> is unambiguous.</cxx-notes>
388+
</cxx-function>
389+
390+
<cxx-function>
391+
<cxx-signature>template &lt;class U&gt; optional&lt;T&gt;&amp; operator=(const optional&lt;U&gt;&amp; rhs);</cxx-signature>
392+
393+
<cxx-requires><code>is_constructible_v&lt;T, const U&amp;&gt;</code> is <code>true</code> and <code>is_assignable_v&lt;T&amp;, const U&amp&gt;</code> is <code>true</code>.</cxx-requires>
394+
<cxx-effects>
395+
<table is="cxx-table" class="single-border column-rules">
396+
<caption><code>optional::operator=(const optional&lt;U&gt;&amp;)</code> effects</caption>
397+
<tr>
398+
<th></th>
399+
<th><code>*this</code> contains a value</th>
400+
<th><code>*this</code> does not contain a value</th>
401+
</tr>
402+
<tr>
403+
<th><code>rhs</code> contains a value</th>
404+
<td>assigns <code>*rhs</code> to the contained value</td>
405+
<td>initializes the contained value as if direct-non-list-initializing an object of type <code>T</code> with <code>*rhs</code></td>
406+
</tr>
407+
<tr>
408+
<th><code>rhs</code> does not contain a value</th>
409+
<td>destroys the contained value by calling <code>val-&gt;T::~T()</code></td>
410+
<td>no effect</td>
411+
</tr>
412+
</table>
413+
</cxx-effects>
414+
<cxx-returns><code>*this</code>.</cxx-returns>
415+
<cxx-postconditions><code>bool(rhs) == bool(*this)</code>.</cxx-postconditions>
416+
<cxx-remarks>If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged.
417+
If an exception is thrown during the call to <code>T</code>'s constructor, the state of <code>*rhs.val</code> is determined by the exception safety guarantee of <code>T</code>'s constructor.
418+
If an exception is thrown during the call to <code>T</code>'s assignment, the state of <code>*val</code> and <code>*rhs.val</code> is determined by the exception safety guarantee of <code>T</code>'s assignment.
419+
The function shall not participate in overload resolution unless <code>is_same_v&lt;decay_t&lt;U&gt;, T&gt;</code> is <code>false</code>.</cxx-remarks>
420+
</cxx-function>
421+
422+
<cxx-function>
423+
<cxx-signature>template &lt;class U&gt; optional&lt;T&gt;&amp; operator=(optional&lt;U&gt;&amp;&amp; rhs);</cxx-signature>
424+
425+
<cxx-requires><code>is_constructible_v&lt;T, U&gt;</code> is <code>true</code> and <code>is_assignable_v&lt;T&amp;, U&gt;</code> is <code>true</code>.</cxx-requires>
426+
<cxx-effects>The result of the expression <code>bool(rhs)</code> remains unchanged.
427+
<table is="cxx-table" class="single-border column-rules">
428+
<caption><code>optional::operator=(optional&lt;U&gt;&amp;&amp;)</code> effects</caption>
429+
<tr>
430+
<th></th>
431+
<th><code>*this</code> contains a value</th>
432+
<th><code>*this</code> does not contain a value</th>
433+
</tr>
434+
<tr>
435+
<th><code>rhs</code> contains a value</th>
436+
<td>assigns <code>std::move(*rhs)</code> to the contained value</td>
437+
<td>initializes the contained value as if direct-non-list-initializing an object of type <code>T</code> with <code>std::move(*rhs)</code></td>
438+
</tr>
439+
<tr>
440+
<th><code>rhs</code> does not contain a value</th>
441+
<td>destroys the contained value by calling <code>val-&gt;T::~T()</code></td>
442+
<td>no effect</td>
443+
</tr>
444+
</table>
445+
</cxx-effects>
446+
<cxx-returns><code>*this</code>.</cxx-returns>
447+
<cxx-postconditions><code>bool(rhs) == bool(*this)</code>.</cxx-postconditions>
448+
<cxx-remarks>If any exception is thrown, the result of the expression <code>bool(*this)</code> remains unchanged.
449+
If an exception is thrown during the call to <code>T</code>'s constructor, the state of <code>*rhs.val</code> is determined by the exception safety guarantee of <code>T</code>'s constructor.
450+
If an exception is thrown during the call to <code>T</code>'s assignment, the state of <code>*val</code> and <code>*rhs.val</code> is determined by the exception safety guarantee of <code>T</code>'s assignment.
451+
The function shall not participate in overload resolution unless <code>is_same_v&lt;decay_t&lt;U&gt;, T&gt;</code> is false.</cxx-remarks>
346452
</cxx-function>
347453

348454
<cxx-function>

0 commit comments

Comments
 (0)