Skip to content

Commit 99c61f6

Browse files
committed
New issue from Arthur O'Dwyer: "bitset::reference should be const-assignable"
1 parent a2a6a61 commit 99c61f6

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

xml/issue4187.xml

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4187" status="New">
5+
<title>`bitset::reference` should be const-assignable</title>
6+
<section><sref ref="[template.bitset]"/></section>
7+
<submitter>Arthur O'Dwyer</submitter>
8+
<date>21 Dec 2024</date>
9+
<priority>99</priority>
10+
11+
<discussion>
12+
<p>
13+
LWG <iref ref="3638"/>, which proposes changes to <tt>vector&lt;bool&gt;::reference</tt>, is related.
14+
Should <tt>vector&lt;bool&gt;::reference</tt> and <tt>bitset&lt;N&gt;::reference</tt> behave differently
15+
in any respect? I think there's no good reason for them to behave differently, and good technical
16+
incentives to permit them to behave the same. We already have implementation divergence: libc++ makes
17+
`bitset::reference` const-assignable, whereas libstdc++ and MS STL do not. This means that libc++'s
18+
`bitset::reference` successfully avoids false positives from Arthur's proposed -Wassign-to-class-rvalue
19+
diagnostic, while libstdc++'s does not (See <a href="https://godbolt.org/z/4e96j7rvv">Godbolt</a>).
20+
<p/>
21+
The proposed resolution applies <a href="https://wg21.link/P2321#vectorboolreference">P2321</a>'s approach. We
22+
can't just insert `const` into the existing spec, because ABI. But also, since our goal is consistency
23+
with the post-P2321 <tt>vector&lt;bool&gt;::reference</tt>, we should do the same thing here as P2321, not invent anything novel.
24+
<p/>
25+
Open questions related to the current P/R:
26+
</p>
27+
<ol>
28+
<li><p>LWG 3638 proposes to add these three `swap` overloads to <tt>vector&lt;bool&gt;::reference</tt>.
29+
Should we also, consistently, add them to `bitset::reference`? I think we should.</p>
30+
<blockquote><pre>
31+
friend constexpr void swap(reference x, reference y) noexcept;
32+
friend constexpr void swap(reference x, bool&amp; y) noexcept;
33+
friend constexpr void swap(bool&amp; x, reference y) noexcept;
34+
</pre></blockquote>
35+
</li>
36+
<li><p>Both <tt>vector&lt;bool&gt;::reference</tt> and `bitset::reference` right now are specified with</p>
37+
<blockquote><pre>
38+
constexpr reference(const reference&amp;) = default;
39+
</pre></blockquote>
40+
<p>which is meaningless because we don't know the data members of `reference`. So this isn't actually
41+
specifying that the constructor is trivial, let alone that it's `noexcept`. I think we should re-specify
42+
both types' copy constructors as simply `constexpr` and `noexcept`; and then if we want them to be trivial,
43+
we should say so in English prose.</p>
44+
</li>
45+
</ol>
46+
</discussion>
47+
48+
<resolution>
49+
<p>
50+
This wording is relative to <paper num="N5001"/>.
51+
</p>
52+
53+
<ol>
54+
<li><p>Modify <sref ref="[template.bitset.general]"/> as indicated:</p>
55+
56+
<blockquote>
57+
<pre>
58+
namespace std {
59+
template&lt;size_t N&gt; class bitset {
60+
public:
61+
// <i>bit reference</i>
62+
class reference {
63+
public:
64+
constexpr reference(const reference&amp;) = default;
65+
constexpr ~reference();
66+
constexpr reference&amp; operator=(bool x) noexcept; // <i>for b[i] = x;</i>
67+
constexpr reference&amp; operator=(const reference&amp;) noexcept; // <i>for b[i] = b[j];</i>
68+
<ins>constexpr const reference&amp; operator=(bool x) const noexcept;</ins>
69+
constexpr bool operator~() const noexcept; // <i>flips the bit</i>
70+
constexpr operator bool() const noexcept; // <i>for x = b[i];</i>
71+
constexpr reference&amp; flip() noexcept; // <i>for b[i].flip();</i>
72+
<ins>friend constexpr void swap(reference x, reference y) noexcept;
73+
friend constexpr void swap(reference x, bool&amp; y) noexcept;
74+
friend constexpr void swap(bool&amp; x, reference y) noexcept;</ins>
75+
};
76+
[&hellip;]
77+
};
78+
[&hellip;]
79+
}
80+
</pre>
81+
</blockquote>
82+
83+
84+
</li>
85+
86+
</ol>
87+
</resolution>
88+
89+
</issue>

0 commit comments

Comments
 (0)