Skip to content

Commit 6c14394

Browse files
committed
New issue from Barry: "expected<int, int> isn't specified to be trivially assignable"
1 parent 6c3bdae commit 6c14394

File tree

1 file changed

+131
-0
lines changed

1 file changed

+131
-0
lines changed

xml/issue4195.xml

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4195" status="New">
5+
<title><tt>expected&lt;int, int&gt;</tt> isn't specified to be trivially assignable</title>
6+
<section><sref ref="[expected.object.assign]"/><sref ref="[expected.void.assign]"/></section>
7+
<submitter>Barry Revzin</submitter>
8+
<date>21 Jan 2025</date>
9+
<priority>99</priority>
10+
11+
<discussion>
12+
<p>
13+
Currently, we specify that the copy constructor, move constructor, and destructor <tt>expected&lt;int, int&gt;</tt>
14+
are trivial operations. But we do not specify that the copy assignment operator or move assignment operator are.
15+
There is implementation divergence &mdash; MSVC's implementation is trivially copyable, but libstdc++'s and libc++'s
16+
are not (although, they are trivial for the purposes of calls, which is important for being able to return such a
17+
type in a register).
18+
<p/>
19+
I'm not sure there is any reason the assignment operators should not be trivial here. We should add the same kind
20+
of remarks in both cases: that the copy assignment operator is trivial if <tt>T</tt> and <tt>E</tt> are trivially
21+
copy assignable and the move assignment operator is trivial if <tt>T</tt> and <tt>E</tt> are trivially move assignable.
22+
</p>
23+
</discussion>
24+
25+
<resolution>
26+
<p>
27+
This wording is relative to <paper num="N5001"/>.
28+
</p>
29+
30+
<ol>
31+
32+
<li><p>Modify <sref ref="[expected.object.assign]"/> as indicated:</p>
33+
34+
<blockquote>
35+
<pre>
36+
constexpr expected&amp; operator=(const expected&amp; rhs);
37+
</pre>
38+
<blockquote>
39+
<p>
40+
-2- <i>Effects</i>: [&hellip;]
41+
<p/>
42+
-3- <i>Returns</i>: <tt>*this</tt>.
43+
<p/>
44+
-4- <i>Remarks</i>: This operator is defined as deleted unless:
45+
</p>
46+
<ol style="list-style-type: none">
47+
<li><p>(4.1) &mdash; [&hellip;]</p></li>
48+
<li><p>(4.2) &mdash; [&hellip;]</p></li>
49+
<li><p>(4.3) &mdash; [&hellip;]</p></li>
50+
<li><p>(4.4) &mdash; [&hellip;]</p></li>
51+
</ol>
52+
<p>
53+
<ins>-?- This operator is trivial if</ins>
54+
</p>
55+
<ol style="list-style-type: none">
56+
<li><p><ins>(?.1) &mdash; <tt>is_trivially_copy_assignable_v&lt;T&gt;</tt> is <tt>true</tt> and</ins></p></li>
57+
<li><p><ins>(?.2) &mdash; <tt>is_trivially_copy_assignable_v&lt;E&gt;</tt> is <tt>true</tt>.</ins></p></li>
58+
</ol>
59+
</blockquote>
60+
61+
<pre>
62+
constexpr expected&amp; operator=(expected&amp;&amp; rhs) noexcept(<i>see below</i>);
63+
</pre>
64+
<blockquote>
65+
<p>
66+
-5- <i>Constraints</i>: [&hellip;]
67+
<p/>
68+
-6- <i>Effects</i>: [&hellip;]
69+
<p/>
70+
-7- <i>Returns</i>: <tt>*this</tt>.
71+
<p/>
72+
-8- <i>Remarks</i>: The exception specification is equivalent to:
73+
</p>
74+
<blockquote><pre>
75+
is_nothrow_move_assignable_v&lt;T&gt; &amp;&amp; is_nothrow_move_constructible_v&lt;T&gt; &amp;&amp;
76+
is_nothrow_move_assignable_v&lt;E&gt; &amp;&amp; is_nothrow_move_constructible_v&lt;E&gt;
77+
</pre></blockquote>
78+
<p>
79+
<ins>-?- This operator is trivial if</ins>
80+
</p>
81+
<ol style="list-style-type: none">
82+
<li><p><ins>(?.1) &mdash; <tt>is_trivially_move_assignable_v&lt;T&gt;</tt> is <tt>true</tt> and</ins></p></li>
83+
<li><p><ins>(?.2) &mdash; <tt>is_trivially_move_assignable_v&lt;E&gt;</tt> is <tt>true</tt>.</ins></p></li>
84+
</ol>
85+
</blockquote>
86+
</blockquote>
87+
</li>
88+
89+
<li><p>Modify <sref ref="[expected.void.assign]"/> as indicated:</p>
90+
91+
<blockquote>
92+
<pre>
93+
constexpr expected&amp; operator=(const expected&amp; rhs);
94+
</pre>
95+
<blockquote>
96+
<p>
97+
-1- <i>Effects</i>: [&hellip;]
98+
<p/>
99+
-2- <i>Returns</i>: <tt>*this</tt>.
100+
<p/>
101+
-3- <i>Remarks</i>: This operator is defined as deleted unless <tt>is_copy_assignable_v&lt;E&gt;</tt>
102+
is <tt>true</tt> and <tt>is_copy_constructible_v&lt;E&gt;</tt> is <tt>true</tt>.
103+
<p/>
104+
<ins>-?- This operator is trivial if <tt>is_trivially_copy_assignable_v&lt;E&gt;</tt> is <tt>true</tt>.</ins>
105+
</p>
106+
</blockquote>
107+
108+
<pre>
109+
constexpr expected&amp; operator=(expected&amp;&amp; rhs) noexcept(<i>see below</i>);
110+
</pre>
111+
<blockquote>
112+
<p>
113+
-4- <i>Constraints</i>: [&hellip;]
114+
<p/>
115+
-5- <i>Effects</i>: [&hellip;]
116+
<p/>
117+
-6- <i>Returns</i>: <tt>*this</tt>.
118+
<p/>
119+
-7- <i>Remarks</i>: The exception specification is equivalent to <tt>is_nothrow_move_constructible_v&lt;E&gt; &amp;&amp;
120+
is_nothrow_move_assignable_v&lt;E&gt;</tt>.
121+
<p/>
122+
<ins>-?- This operator is trivial if <tt>is_trivially_move_assignable_v&lt;E&gt;</tt> is <tt>true</tt>.</ins>
123+
</p>
124+
</blockquote>
125+
</blockquote>
126+
</li>
127+
128+
</ol>
129+
</resolution>
130+
131+
</issue>

0 commit comments

Comments
 (0)