Skip to content

Commit

Permalink
Improve proposed wording by replacing operator*() by directly referri…
Browse files Browse the repository at this point in the history
…ng to the corresponding union member.
  • Loading branch information
Dani-Hub committed Sep 19, 2023
1 parent ae0ba11 commit d3a872c
Showing 1 changed file with 38 additions and 32 deletions.
70 changes: 38 additions & 32 deletions xml/issue3973.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ don't direct use <tt>**this</tt>, but use the name of the union member instead.
Moreover, <paper num="P2407R5"/> will change the monadic operations of <tt>std::optional</tt> to use <tt>**this</tt>,
which is also problematic.
</p>

<note>2023-09-19; Wording update</note>
<p>
Several people preferred to replace <tt>operator*()</tt> by the corresponding union members, so this part of the proposed wording
has been adjusted, which is a rather mechanical replacement.
</p>
</discussion>

<resolution>
Expand All @@ -33,7 +39,7 @@ This wording is relative to <paper num="N4958"/>.

<blockquote class="note">
<p>
[<i>Drafting note:</i> Effectively replace all occurrences of <tt>**this</tt> by <tt>operator*()</tt>.]
[<i>Drafting note:</i> Effectively replace all occurrences of <tt>**this</tt> by <tt><i>val</i></tt>.]
</p>
</blockquote>

Expand All @@ -44,7 +50,7 @@ template&lt;class F&gt; constexpr auto and_then(F&amp;&amp; f) const &amp;;
</pre>
<blockquote>
<p>
-1- Let <tt>U</tt> be <tt>remove_cvref_t&lt;invoke_result_t&lt;F, decltype(<del>**this</del><ins>operator*()</ins>)&gt;&gt;</tt>.
-1- Let <tt>U</tt> be <tt>remove_cvref_t&lt;invoke_result_t&lt;F, decltype(<del>**this</del><ins><i>val</i></ins>)&gt;&gt;</tt>.
<p/>
-2- [&hellip;]
<p/>
Expand All @@ -54,7 +60,7 @@ template&lt;class F&gt; constexpr auto and_then(F&amp;&amp; f) const &amp;;
</p>
<blockquote><pre>
if (has_value())
return invoke(std::forward&lt;F&gt;(f), <del>**this</del><ins>operator*()</ins>);
return invoke(std::forward&lt;F&gt;(f), <del>**this</del><ins><i>val</i></ins>);
else
return U(unexpect, error());
</pre></blockquote>
Expand All @@ -65,7 +71,7 @@ template&lt;class F&gt; constexpr auto and_then(F&amp;&amp; f) const &amp;&amp;;
</pre>
<blockquote>
<p>
-5- Let <tt>U</tt> be <tt>remove_cvref_t&lt;invoke_result_t&lt;F, decltype((std::move(<del>**this</del><ins>operator*()</ins>))&gt;&gt;</tt>.
-5- Let <tt>U</tt> be <tt>remove_cvref_t&lt;invoke_result_t&lt;F, decltype((std::move(<del>**this</del><ins><i>val</i></ins>))&gt;&gt;</tt>.
<p/>
-6- [&hellip;]
<p/>
Expand All @@ -75,7 +81,7 @@ template&lt;class F&gt; constexpr auto and_then(F&amp;&amp; f) const &amp;&amp;;
</p>
<blockquote><pre>
if (has_value())
return invoke(std::forward&lt;F&gt;(f), std::move(<del>**this</del><ins>operator*()</ins>));
return invoke(std::forward&lt;F&gt;(f), std::move(<del>**this</del><ins><i>val</i></ins>));
else
return U(unexpect, std::move(error()));
</pre></blockquote>
Expand All @@ -88,15 +94,15 @@ template&lt;class F&gt; constexpr auto or_else(F&amp;&amp; f) const &amp;;
<p>
-9- Let <tt>G</tt> be <tt>remove_cvref_t&lt;invoke_result_t&lt;F, decltype(error())&gt;&gt;</tt>.
<p/>
-10- <i>Constraints</i>: <tt>is_constructible_v&lt;T, decltype(<del>**this</del><ins>operator*()</ins>)&gt;</tt> is <tt>true</tt>.
-10- <i>Constraints</i>: <tt>is_constructible_v&lt;T, decltype(<del>**this</del><ins><i>val</i></ins>)&gt;</tt> is <tt>true</tt>.
<p/>
-11- [&hellip;]
<p/>
-12- <i>Effects</i>: Equivalent to:
</p>
<blockquote><pre>
if (has_value())
return G(in_place, <del>**this</del><ins>operator*()</ins>);
return G(in_place, <del>**this</del><ins><i>val</i></ins>);
else
return invoke(std::forward&lt;F&gt;(f), error());
</pre></blockquote>
Expand All @@ -109,15 +115,15 @@ template&lt;class F&gt; constexpr auto or_else(F&amp;&amp; f) const &amp;&amp;;
<p>
-13- Let <tt>G</tt> be <tt>remove_cvref_t&lt;invoke_result_t&lt;F, decltype(std::move(error()))&gt;&gt;</tt>.
<p/>
-14- <i>Constraints</i>: <tt>is_constructible_v&lt;T, decltype(std::move(<del>**this</del><ins>operator*()</ins>))&gt;</tt> is <tt>true</tt>.
-14- <i>Constraints</i>: <tt>is_constructible_v&lt;T, decltype(std::move(<del>**this</del><ins><i>val</i></ins>))&gt;</tt> is <tt>true</tt>.
<p/>
-15- [&hellip;]
<p/>
-16- <i>Effects</i>: Equivalent to:
</p>
<blockquote><pre>
if (has_value())
return G(in_place, std::move(<del>**this</del><ins>operator*()</ins>));
return G(in_place, std::move(<del>**this</del><ins><i>val</i></ins>));
else
return invoke(std::forward&lt;F&gt;(f), std::move(error()));
</pre></blockquote>
Expand All @@ -128,15 +134,15 @@ template&lt;class F&gt; constexpr auto transform(F&amp;&amp; f) const &amp;;
</pre>
<blockquote>
<p>
-17- Let <tt>U</tt> be <tt>remove_cvref_t&lt;invoke_result_t&lt;F, decltype(<del>**this</del><ins>operator*()</ins>)&gt;&gt;</tt>.
-17- Let <tt>U</tt> be <tt>remove_cvref_t&lt;invoke_result_t&lt;F, decltype(<del>**this</del><ins><i>val</i></ins>)&gt;&gt;</tt>.
<p/>
-18- [&hellip;]
<p/>
-19- <i>Mandates</i>: <tt>U</tt> is a valid value type for <tt>expected</tt>. If <tt>is_void_v&lt;U&gt;</tt> is <tt>false</tt>,
the declaration
</p>
<blockquote><pre>
U u(invoke(std::forward&lt;F&gt;(f), <del>**this</del><ins>operator*()</ins>));
U u(invoke(std::forward&lt;F&gt;(f), <del>**this</del><ins><i>val</i></ins>));
</pre></blockquote>
<p>
is well-formed.
Expand All @@ -147,8 +153,8 @@ is well-formed.
<li><p>(20.1) &mdash; [&hellip;]</p></li>
<li><p>(20.2) &mdash; Otherwise, if <tt>is_void_v&lt;U&gt;</tt> is <tt>false</tt>, returns an <tt>expected&lt;U, E&gt;</tt>
object whose <tt><i>has_val</i></tt> member is <tt>true</tt> and <tt><i>val</i></tt> member is direct-non-list-initialized
with <tt>invoke(std::forward&lt;F&gt;(f), <del>**this</del><ins>operator*()</ins>)</tt>.</p></li>
<li><p>(20.3) &mdash; Otherwise, evaluates <tt>invoke(std::forward&lt;F&gt;(f), <del>**this</del><ins>operator*()</ins>)</tt>
with <tt>invoke(std::forward&lt;F&gt;(f), <del>**this</del><ins><i>val</i></ins>)</tt>.</p></li>
<li><p>(20.3) &mdash; Otherwise, evaluates <tt>invoke(std::forward&lt;F&gt;(f), <del>**this</del><ins><i>val</i></ins>)</tt>
and then returns <tt>expected&lt;U, E&gt;()</tt>.</p></li>
</ol>
</blockquote>
Expand All @@ -158,15 +164,15 @@ template&lt;class F&gt; constexpr auto transform(F&amp;&amp; f) const &amp;&amp;
</pre>
<blockquote>
<p>
-21- Let <tt>U</tt> be <tt>remove_cvref_t&lt;invoke_result_t&lt;F, decltype(std::move(<del>**this</del><ins>operator*()</ins>))&gt;&gt;</tt>.
-21- Let <tt>U</tt> be <tt>remove_cvref_t&lt;invoke_result_t&lt;F, decltype(std::move(<del>**this</del><ins><i>val</i></ins>))&gt;&gt;</tt>.
<p/>
-22- [&hellip;]
<p/>
-23- <i>Mandates</i>: <tt>U</tt> is a valid value type for <tt>expected</tt>. If <tt>is_void_v&lt;U&gt;</tt> is <tt>false</tt>,
the declaration
</p>
<blockquote><pre>
U u(invoke(std::forward&lt;F&gt;(f), std::move(<del>**this</del><ins>operator*()</ins>)));
U u(invoke(std::forward&lt;F&gt;(f), std::move(<del>**this</del><ins><i>val</i></ins>)));
</pre></blockquote>
<p>
is well-formed.
Expand All @@ -177,8 +183,8 @@ is well-formed.
<li><p>(24.1) &mdash; [&hellip;]</p></li>
<li><p>(24.2) &mdash; Otherwise, if <tt>is_void_v&lt;U&gt;</tt> is <tt>false</tt>, returns an <tt>expected&lt;U, E&gt;</tt>
object whose <tt><i>has_val</i></tt> member is <tt>true</tt> and <tt><i>val</i></tt> member is direct-non-list-initialized
with <tt>invoke(std::forward&lt;F&gt;(f), std::move(<del>**this</del><ins>operator*()</ins>))</tt>.</p></li>
<li><p>(24.3) &mdash; Otherwise, evaluates <tt>invoke(std::forward&lt;F&gt;(f), std::move(<del>**this</del><ins>operator*()</ins>))</tt>
with <tt>invoke(std::forward&lt;F&gt;(f), std::move(<del>**this</del><ins><i>val</i></ins>))</tt>.</p></li>
<li><p>(24.3) &mdash; Otherwise, evaluates <tt>invoke(std::forward&lt;F&gt;(f), std::move(<del>**this</del><ins><i>val</i></ins>))</tt>
and then returns <tt>expected&lt;U, E&gt;()</tt>.</p></li>
</ol>
</blockquote>
Expand All @@ -190,11 +196,11 @@ template&lt;class F&gt; constexpr auto transform_error(F&amp;&amp; f) const &amp
<p>
-25- Let <tt>G</tt> be <tt>remove_cvref_t&lt;invoke_result_t&lt;F, decltype(error())&gt;&gt;</tt>.
<p/>
-26- <i>Constraints</i>: <tt>is_constructible_v&lt;T, decltype(<del>**this</del><ins>operator*()</ins>)&gt;</tt> is <tt>true</tt>.
-26- <i>Constraints</i>: <tt>is_constructible_v&lt;T, decltype(<del>**this</del><ins><i>val</i></ins>)&gt;</tt> is <tt>true</tt>.
<p/>
-27- <i>Mandates</i>: [&hellip;]
<p/>
-28- <i>Returns</i>: If <tt>has_value()</tt> is <tt>true</tt>, <tt>expected&lt;T, G&gt;(in_place, <del>**this</del><ins>operator*()</ins>)</tt>;
-28- <i>Returns</i>: If <tt>has_value()</tt> is <tt>true</tt>, <tt>expected&lt;T, G&gt;(in_place, <del>**this</del><ins><i>val</i></ins>)</tt>;
otherwise, an <tt>expected&lt;T, G&gt;</tt> object whose <tt><i>has_val</i></tt> member is <tt>false</tt> and
<tt><i>unex</i></tt> member is direct-non-list-initialized with <tt>invoke(std::forward&lt;F&gt;(f), error())</tt>.
</p>
Expand All @@ -207,11 +213,11 @@ template&lt;class F&gt; constexpr auto transform_error(F&amp;&amp; f) const &amp
<p>
-29- Let <tt>G</tt> be <tt>remove_cvref_t&lt;invoke_result_t&lt;F, decltype(std::move(error()))&gt;&gt;</tt>.
<p/>
-30- <i>Constraints</i>: <tt>is_constructible_v&lt;T, decltype(std::move(<del>**this</del><ins>operator*()</ins>))&gt;</tt> is <tt>true</tt>.
-30- <i>Constraints</i>: <tt>is_constructible_v&lt;T, decltype(std::move(<del>**this</del><ins><i>val</i></ins>))&gt;</tt> is <tt>true</tt>.
<p/>
-31- <i>Mandates</i>: [&hellip;]
<p/>
-32- <i>Returns</i>: If <tt>has_value()</tt> is <tt>true</tt>, <tt>expected&lt;T, G&gt;(in_place, std::move(<del>**this</del><ins>operator*()</ins>))</tt>;
-32- <i>Returns</i>: If <tt>has_value()</tt> is <tt>true</tt>, <tt>expected&lt;T, G&gt;(in_place, std::move(<del>**this</del><ins><i>val</i></ins>))</tt>;
otherwise, an <tt>expected&lt;T, G&gt;</tt> object whose <tt><i>has_val</i></tt> member is <tt>false</tt> and
<tt><i>unex</i></tt> member is direct-non-list-initialized with <tt>invoke(std::forward&lt;F&gt;(f), std::move(error()))</tt>.
</p>
Expand All @@ -224,7 +230,7 @@ otherwise, an <tt>expected&lt;T, G&gt;</tt> object whose <tt><i>has_val</i></tt>

<blockquote class="note">
<p>
[<i>Drafting note:</i> Effectively replace all occurrences of <tt>value()</tt> by <tt>operator*()</tt>.]
[<i>Drafting note:</i> Effectively replace all occurrences of <tt>value()</tt> by <tt>*val</tt>.]
</p>
</blockquote>

Expand All @@ -235,15 +241,15 @@ template&lt;class F&gt; constexpr auto and_then(F&amp;&amp; f) const &amp;;
</pre>
<blockquote>
<p>
-1- Let <tt>U</tt> be <tt>invoke_result_t&lt;F, decltype(<del>value()</del><ins>operator*()</ins>)&gt;</tt>.
-1- Let <tt>U</tt> be <tt>invoke_result_t&lt;F, decltype(<del>value()</del><ins>*val</ins>)&gt;</tt>.
<p/>
-2- [&hellip;]
<p/>
-3- <i>Effects</i>: Equivalent to:
</p>
<blockquote><pre>
if (*this) {
return invoke(std::forward&lt;F&gt;(f), <del>value()</del><ins>operator*()</ins>);
return invoke(std::forward&lt;F&gt;(f), <del>value()</del><ins>*val</ins>);
} else {
return remove_cvref_t&lt;U&gt;();
}
Expand All @@ -255,15 +261,15 @@ template&lt;class F&gt; constexpr auto and_then(F&amp;&amp; f) const &amp;&amp;;
</pre>
<blockquote>
<p>
-4- Let <tt>U</tt> be <tt>invoke_result_t&lt;F, decltype(std::move(<del>value()</del><ins>operator*()</ins>))&gt;</tt>.
-4- Let <tt>U</tt> be <tt>invoke_result_t&lt;F, decltype(std::move(<del>value()</del><ins>*val</ins>))&gt;</tt>.
<p/>
-5- [&hellip;]
<p/>
-6- <i>Effects</i>: Equivalent to:
</p>
<blockquote><pre>
if (*this) {
return invoke(std::forward&lt;F&gt;(f), std::move(<del>value()</del><ins>operator*()</ins>));
return invoke(std::forward&lt;F&gt;(f), std::move(<del>value()</del><ins>*val</ins>));
} else {
return remove_cvref_t&lt;U&gt;();
}
Expand All @@ -275,20 +281,20 @@ template&lt;class F&gt; constexpr auto transform(F&amp;&amp; f) const &amp;;
</pre>
<blockquote>
<p>
-7- Let <tt>U</tt> be <tt>remove_cv_t&lt;invoke_result_t&lt;F, decltype(<del>value()</del><ins>operator*()</ins>)&gt;&gt;</tt>.
-7- Let <tt>U</tt> be <tt>remove_cv_t&lt;invoke_result_t&lt;F, decltype(<del>value()</del><ins>*val</ins>)&gt;&gt;</tt>.
<p/>
-8- <i>Mandates</i>: <tt>U</tt> is a non-array object type other than <tt>in_place_t</tt> or <tt>nullopt_t</tt>. The declaration
</p>
<blockquote><pre>
U u(invoke(std::forward&lt;F&gt;(f), <del>value()</del><ins>operator*()</ins>));
U u(invoke(std::forward&lt;F&gt;(f), <del>value()</del><ins>*val</ins>));
</pre></blockquote>
<p>
is well-formed for some invented variable <tt>u</tt>.
<p/>
[&hellip;]
<p/>
-9- <i>Returns</i>: If <tt>*this</tt> contains a value, an <tt>optional&lt;U&gt;</tt> object whose contained value is
direct-non-list-initialized with <tt>invoke(std::forward&lt;F&gt;(f), <del>value()</del><ins>operator*()</ins>)</tt>; otherwise,
direct-non-list-initialized with <tt>invoke(std::forward&lt;F&gt;(f), <del>value()</del><ins>*val</ins>)</tt>; otherwise,
<tt>optional&lt;U&gt;()</tt>.
</p>
</blockquote>
Expand All @@ -298,20 +304,20 @@ template&lt;class F&gt; constexpr auto transform(F&amp;&amp; f) const &amp;&amp;
</pre>
<blockquote>
<p>
-10- Let <tt>U</tt> be <tt>remove_cv_t&lt;invoke_result_t&lt;F, decltype(std::move(<del>value()</del><ins>operator*()</ins>))&gt;&gt;</tt>.
-10- Let <tt>U</tt> be <tt>remove_cv_t&lt;invoke_result_t&lt;F, decltype(std::move(<del>value()</del><ins>*val</ins>))&gt;&gt;</tt>.
<p/>
-11- <i>Mandates</i>: <tt>U</tt> is a non-array object type other than <tt>in_place_t</tt> or <tt>nullopt_t</tt>. The declaration
</p>
<blockquote><pre>
U u(invoke(std::forward&lt;F&gt;(f), std::move(<del>value()</del><ins>operator*()</ins>)));
U u(invoke(std::forward&lt;F&gt;(f), std::move(<del>value()</del><ins>*val</ins>)));
</pre></blockquote>
<p>
is well-formed for some invented variable <tt>u</tt>.
<p/>
[&hellip;]
<p/>
-12- <i>Returns</i>: If <tt>*this</tt> contains a value, an <tt>optional&lt;U&gt;</tt> object whose contained value is
direct-non-list-initialized with <tt>invoke(std::forward&lt;F&gt;(f), std::move(<del>value()</del><ins>operator*()</ins>))</tt>; otherwise,
direct-non-list-initialized with <tt>invoke(std::forward&lt;F&gt;(f), std::move(<del>value()</del><ins>*val</ins>))</tt>; otherwise,
<tt>optional&lt;U&gt;()</tt>.
</p>
</blockquote>
Expand Down

0 comments on commit d3a872c

Please sign in to comment.