-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathp1357r1.html
213 lines (213 loc) · 9.48 KB
/
p1357r1.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
<!DOCTYPE html>
<html lang="en">
<head>
<title>Traits for [Un]bounded Arrays</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
ins { background-color: #CCFFCC; }
del { background-color: #FFCCCC; }
.insert { background-color: #CCFFCC; }
.edit { background-color: #F0F0F0; }
</style>
</head>
<body>
<p><strong>Document Number:</strong> P1357R1<br>
<strong>Date:</strong> 2019-02-22<br>
<strong>Project:</strong> Programming Language C++<br>
<strong>Audience:</strong> Library Working Group<sup>1</sup><br>
<strong>Authors:</strong> Walter E. Brown
(<a href="mailto:[email protected]">[email protected]</a>),
Glen Joseph Fernandes
(<a href="mailto:[email protected]">[email protected]</a>)</p>
<h1>Traits for [Un]bounded Arrays</h1>
<p><strong>Abstract:</strong> This paper proposes two new type traits that have
been demonstrated, in prior art, to provide a useful partition of the types for
which the <code>is_array</code> trait holds. The proposed partition is
analogous to that provided, when <code>is_integral</code> holds, by the
<code>is_signed</code>/<code>is_unsigned</code> traits.</p>
<h2>Introduction and background</h2>
<p>The type traits known as <em>primary type categories</em><sup>2</sup> serve
to partition the universe of C++ types into fourteen mutually exclusive
categories such that each type falls into exactly one category. In addition, we
have <em>composite type traits</em><sup>3</sup> to identify useful combinations
of these primary type categories. Finally, we have current and past
examples<sup>4</sup> of traits providing even more finely-grained
categorization.</p>
<p>This paper proposes to add two new type traits of this last kind, for each
of which there is significant prior art. The proposed traits will provide a
useful partition of types for which <code>is_array</code> holds.</p>
<h2>Discussion and proposal</h2>
<p>It is often necessary to distinguish types that are arrays of unknown bound
(i.e., where <code>T</code> is of the form <code>U[]</code>) from types that
are arrays of known bound (i.e., where <code>T</code> is of the form
<code>U[N]</code>) instead of just any array type. For example, such
distinctions are needed in the implementation of certain C++ standard library
facilities:</p>
<ul>
<li><code>std::unique_ptr</code> and <code>std::make_unique</code>: these
support use with arrays of unknown bound, but intentionally prohibit use with
arrays of known bound.</li>
<li><code>std::make_shared</code> and <code>std::allocate_shared</code>: these
provide different overloads for arrays of known bounds as well as for arrays of
unknown bound.</li>
</ul>
<p>Beyond use in implementation, it would also be useful to have these traits
in the standard library for the specifications of other facilities in the C++
standard. Several constraints could then be specified by a C++ expression using
traits, instead of by the equivalent (but less succinct) English prose.</p>
<p>We therefore propose to add two new traits named
<code>is_bounded_array</code> and <code>is_unbounded_array</code>. Other
possible name pairs for these traits include (a) <code>is_bound_array</code>
and <code>is_unbound_array</code>, (b) <code>is_known_bound_array</code> and
<code>is_unknown_bound_array</code>, or (c) <code>is_known_extent_array</code>
and <code>is_unknown_extent_array</code>.</p>
<p>Using these traits, wording for the following constraints in the C++
standard could be consistently simplified:</p>
<table>
<tr><th>Wording of this form</th><th>Could take this form instead</th></tr>
<tr><td><code>T</code> is not an array</td>
<td><code>!is_array_v<T></code></td></tr>
<tr><td><code>T</code> is an array of known bound</td>
<td><code>is_bounded_array_v<T></code></td></tr>
<tr><td><code>T</code> is not an array of unknown bound</td>
<td><code>!is_unbounded_array_v<T></code></td></tr>
<tr><td><code>T</code> is an array of unknown bound</td>
<td><code>is_unbounded_array_v<T></code></td></tr>
</table>
<p>No such rewording is herein proposed; we simply provide the above
possibilities by way of example and of motivation.</p>
<h2>Sample implementation</h2>
<p>Implementing the proposed traits is straightforward. Here is one possible
approach:</p>
<blockquote class="edit">
<code>
template<typename><br>
struct is_bounded_array : false_type { };<br>
<br>
template<typename U, size_t N><br>
struct is_bounded_array<U[N]> : true_type { };<br>
<br>
template<typename T><br>
inline constexpr bool
is_bounded_array_v = is_bounded_array<T>::value;<br>
<br>
template<typename><br>
struct is_unbounded_array : false_type { };<br>
<br>
template<typename U><br>
struct is_unbounded_array<U[]> : true_type { };<br>
<br>
template<typename T><br>
inline constexpr bool
is_unbounded_array_v = is_unbounded_array<T>::value;
</code>
</blockquote>
<h2>Proposed wording<sup>5</sup></h2>
<p class="edit">1. Insert the followng row into Table 35 - Standard library
feature-test macros. Adjust the placeholder Value as needed so as to denote
this proposal's date of adoption.</p>
<blockquote>
<table>
<tr><th>Macro name</th><th>Value</th><th>Header(s)</th></tr>
<tr><td colspan="3">[…]</td></tr>
<tr class="insert"><td><code>__cpp_lib_bounded_array_traits</code></td>
<td>201902L</td><td><code><type_traits></code></td></tr>
</table>
</blockquote>
<p class="edit">2. Augment [meta.type.synop] as shown:</p>
<blockquote>
<code>
template<class T> struct is_signed;<br>
template<class T> struct is_unsigned;<br>
<ins>template<class T> struct is_bounded_array;</ins><br>
<ins>template<class T> struct is_unbounded_array;</ins><br>
</code>
[…]<br>
<code>
template<class T> inline constexpr bool
is_signed_v = is_signed<T>::value;<br>
template<class T> inline constexpr bool
is_unsigned_v = is_unsigned<T>::value;<br>
<ins>template<class T> inline constexpr bool
is_bounded_array_v = is_bounded_array<T>::value;</ins><br>
<ins>template<class T> inline constexpr bool
is_unbounded_array_v = is_unbounded_array<T>::value;</ins><br>
</code>
</blockquote>
<p class="edit">3. Augment Table 46 - Type property predicates as shown:</p>
<blockquote>
<table>
<tr><th>Template</th><th>Condition</th><th>Preconditions</th></tr>
<tr><td colspan="3">[…]</td></tr>
<tr><td><code>template<class T> struct is_signed;</code></td>
<td>If <code>is_arithmetic_v<T></code>…</td>
<td></td></tr>
<tr><td><code>template<class T> struct is_unsigned;</code></td>
<td>If <code>is_arithmetic_v<T></code>…</td>
<td></td></tr>
<tr class="insert"><td><code>template<class T>
struct is_bounded_array;</code></td>
<td><code>T</code> is an array type of known bound [dcl.array]</td>
<td></td></tr>
<tr class="insert"><td><code>template<class T>
struct is_unbounded_array;</code></td>
<td><code>T</code> is an array type of unknown bound [dcl.array]</td>
<td></td></tr>
</table>
</blockquote>
<h2>Acknowledgments</h2>
<p>Many thanks to the readers of early drafts of this paper for their
thoughtful comments.</p>
<h2>Bibliography</h2>
<dl>
<dt id="N2028">[N2028]</dt>
<dd>Howard E. Hinnant: "Minor Modifications to the type traits Wording."
ISO/IEC JTC1/SC22/WG21 document N2028 (mid-Berlin/Portland mailing),
2006–06–12.
<a href="https://wg21.link/n2028">https://wg21.link/n2028</a>.</dd>
<dt id="N4778">[N4778]</dt>
<dd>Richard Smith: "Working Draft, Standard for Programming Language C++."
ISO/IEC JTC1/SC22/WG21 document N4778 (pre-San Diego mailing), 2018–10–08.
<a href="https://wg21.link/n4778">https://wg21.link/n4778</a>.</dd>
</dl>
<h2>Document history</h2>
<table>
<tr><th>Rev.</th><th>Date</th><th>Changes</th></tr>
<tr><td>-1</td><td>2018-11-09</td>
<td>Draft uploaded to San Diego LEWG wiki for post-San Diego review.</td></tr>
<tr><td>0</td><td>2019-01-06</td>
<td>Added footnote and adjusted audience to reflect favorable post-San Diego
review. Published as P1357R0, pre-Kona mailing.</td></tr>
<tr><td>1</td><td>2019-02-22</td>
<td>Revised per LWG guidance in Kona. Published as P1357R1, post-Kona
mailing.</td></tr>
</table>
<hr>
<ol>
<li>At its Saturday post-San Diego session, LEWG reviewed and tentatively
approved (9|3|2|1|0) a pre-publication draft of this paper. No substantive
changes have been applied since then.</li>
<li>Specified in in [meta.unary.cat]: <code>is_void</code>,
<code>is_null_pointer</code>, <code>is_integral</code>,
<code>is_floating_point</code>, <code>is_array</code>, <code>is_pointer</code>,
<code>is_lvalue_reference</code>, <code>is_rvalue_reference</code>,
<code>is_member_object_pointer</code>, <code>is_member_function_pointer</code>,
<code>is_enum</code>, <code>is_union</code>, <code>is_class</code>, and
<code>is_function</code>.</li>
<li>Specified in [meta.unary.comp]: <code>is_reference</code>,
<code>is_arithmetic</code>, <code>is_fundamental</code>,
<code>is_object</code>, <code>is_scalar</code>, <code>is_compound</code>, and
<code>is_member_pointer</code>.</li>
<li>Specified in [meta.unary.prop]: <code>is_signed</code> and
<code>is_unsigned</code>, providing a partition of types for which
<code>is_integral</code> holds. Also, the composite trait
<code>is_reference</code> was originally a primary trait before the
introduction, by [<a href="#N2028">N2028</a>], of rvalue references and the
corresponding then-new <code>is_rvalue_reference</code> trait.</li>
<li>Proposed <ins>additions</ins> and <del>deletions</del> are relative to
[<a href="#N4778">N4778</a>]. Editorial notes appear like
<span class="edit">this</span>.</li>
</ol>
</body>
</html>