From Jason Turner

[meta]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpmvupy_aw/{from.md → to.md} +549 -157
tmp/tmpmvupy_aw/{from.md → to.md} RENAMED
@@ -10,35 +10,38 @@ taxonomy of all possible C++types, and state where in that taxonomy a
10
  given type belongs. The type property inspection traits allow important
11
  characteristics of types or of combinations of types to be inspected.
12
  The type transformations allow certain properties of types to be
13
  manipulated.
14
 
 
 
 
15
  ### Requirements <a id="meta.rqmts">[[meta.rqmts]]</a>
16
 
17
  A *UnaryTypeTrait* describes a property of a type. It shall be a class
18
  template that takes one template type argument and, optionally,
19
  additional arguments that help define the property being described. It
20
  shall be `DefaultConstructible`, `CopyConstructible`, and publicly and
21
- unambiguously derived, directly or indirectly, from its
22
- *BaseCharacteristic*, which is a specialization of the template
23
  `integral_constant` ([[meta.help]]), with the arguments to the template
24
  `integral_constant` determined by the requirements for the particular
25
- property being described. The member names of the BaseCharacteristic
26
  shall not be hidden and shall be unambiguously available in the
27
- UnaryTypeTrait.
28
 
29
  A *BinaryTypeTrait* describes a relationship between two types. It shall
30
  be a class template that takes two template type arguments and,
31
  optionally, additional arguments that help define the relationship being
32
  described. It shall be `DefaultConstructible`, `CopyConstructible`, and
33
  publicly and unambiguously derived, directly or indirectly, from its
34
- *BaseCharacteristic*, which is a specialization of the template
35
  `integral_constant` ([[meta.help]]), with the arguments to the template
36
  `integral_constant` determined by the requirements for the particular
37
- relationship being described. The member names of the BaseCharacteristic
38
- shall not be hidden and shall be unambiguously available in the
39
- BinaryTypeTrait.
40
 
41
  A *TransformationTrait* modifies a property of a type. It shall be a
42
  class template that takes one template type argument and, optionally,
43
  additional arguments that help define the modification. It shall define
44
  a publicly accessible nested type named `type`, which shall be a synonym
@@ -46,16 +49,19 @@ for the modified type.
46
 
47
  ### Header `<type_traits>` synopsis <a id="meta.type.synop">[[meta.type.synop]]</a>
48
 
49
  ``` cpp
50
  namespace std {
51
- // [meta.help], helper class:
52
  template <class T, T v> struct integral_constant;
53
- typedef integral_constant<bool, true> true_type;
54
- typedef integral_constant<bool, false> false_type;
55
 
56
- // [meta.unary.cat], primary type categories:
 
 
 
 
 
57
  template <class T> struct is_void;
58
  template <class T> struct is_null_pointer;
59
  template <class T> struct is_integral;
60
  template <class T> struct is_floating_point;
61
  template <class T> struct is_array;
@@ -67,31 +73,31 @@ namespace std {
67
  template <class T> struct is_enum;
68
  template <class T> struct is_union;
69
  template <class T> struct is_class;
70
  template <class T> struct is_function;
71
 
72
- // [meta.unary.comp], composite type categories:
73
  template <class T> struct is_reference;
74
  template <class T> struct is_arithmetic;
75
  template <class T> struct is_fundamental;
76
  template <class T> struct is_object;
77
  template <class T> struct is_scalar;
78
  template <class T> struct is_compound;
79
  template <class T> struct is_member_pointer;
80
 
81
- // [meta.unary.prop], type properties:
82
  template <class T> struct is_const;
83
  template <class T> struct is_volatile;
84
  template <class T> struct is_trivial;
85
  template <class T> struct is_trivially_copyable;
86
  template <class T> struct is_standard_layout;
87
  template <class T> struct is_pod;
88
- template <class T> struct is_literal_type;
89
  template <class T> struct is_empty;
90
  template <class T> struct is_polymorphic;
91
  template <class T> struct is_abstract;
92
  template <class T> struct is_final;
 
93
 
94
  template <class T> struct is_signed;
95
  template <class T> struct is_unsigned;
96
 
97
  template <class T, class... Args> struct is_constructible;
@@ -101,10 +107,13 @@ namespace std {
101
 
102
  template <class T, class U> struct is_assignable;
103
  template <class T> struct is_copy_assignable;
104
  template <class T> struct is_move_assignable;
105
 
 
 
 
106
  template <class T> struct is_destructible;
107
 
108
  template <class T, class... Args> struct is_trivially_constructible;
109
  template <class T> struct is_trivially_default_constructible;
110
  template <class T> struct is_trivially_copy_constructible;
@@ -122,24 +131,36 @@ namespace std {
122
 
123
  template <class T, class U> struct is_nothrow_assignable;
124
  template <class T> struct is_nothrow_copy_assignable;
125
  template <class T> struct is_nothrow_move_assignable;
126
 
 
 
 
127
  template <class T> struct is_nothrow_destructible;
 
128
  template <class T> struct has_virtual_destructor;
129
 
130
- // [meta.unary.prop.query], type property queries:
 
 
131
  template <class T> struct alignment_of;
132
  template <class T> struct rank;
133
  template <class T, unsigned I = 0> struct extent;
134
 
135
- // [meta.rel], type relations:
136
  template <class T, class U> struct is_same;
137
  template <class Base, class Derived> struct is_base_of;
138
  template <class From, class To> struct is_convertible;
139
 
140
- // [meta.trans.cv], const-volatile modifications:
 
 
 
 
 
 
141
  template <class T> struct remove_const;
142
  template <class T> struct remove_volatile;
143
  template <class T> struct remove_cv;
144
  template <class T> struct add_const;
145
  template <class T> struct add_volatile;
@@ -156,11 +177,11 @@ namespace std {
156
  template <class T>
157
  using add_volatile_t = typename add_volatile<T>::type;
158
  template <class T>
159
  using add_cv_t = typename add_cv<T>::type;
160
 
161
- // [meta.trans.ref], reference modifications:
162
  template <class T> struct remove_reference;
163
  template <class T> struct add_lvalue_reference;
164
  template <class T> struct add_rvalue_reference;
165
 
166
  template <class T>
@@ -168,54 +189,53 @@ namespace std {
168
  template <class T>
169
  using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;
170
  template <class T>
171
  using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
172
 
173
- // [meta.trans.sign], sign modifications:
174
  template <class T> struct make_signed;
175
  template <class T> struct make_unsigned;
176
 
177
  template <class T>
178
  using make_signed_t = typename make_signed<T>::type;
179
  template <class T>
180
  using make_unsigned_t = typename make_unsigned<T>::type;
181
 
182
- // [meta.trans.arr], array modifications:
183
  template <class T> struct remove_extent;
184
  template <class T> struct remove_all_extents;
185
 
186
  template <class T>
187
  using remove_extent_t = typename remove_extent<T>::type;
188
  template <class T>
189
  using remove_all_extents_t = typename remove_all_extents<T>::type;
190
 
191
- // [meta.trans.ptr], pointer modifications:
192
  template <class T> struct remove_pointer;
193
  template <class T> struct add_pointer;
194
 
195
  template <class T>
196
  using remove_pointer_t = typename remove_pointer<T>::type;
197
  template <class T>
198
  using add_pointer_t = typename add_pointer<T>::type;
199
 
200
- // [meta.trans.other], other transformations:
201
- template <std::size_t Len,
202
- std::size_t Align = default-alignment> // see [meta.trans.other]
203
  struct aligned_storage;
204
- template <std::size_t Len, class... Types> struct aligned_union;
205
  template <class T> struct decay;
206
  template <bool, class T = void> struct enable_if;
207
  template <bool, class T, class F> struct conditional;
208
  template <class... T> struct common_type;
209
  template <class T> struct underlying_type;
210
- template <class> class result_of; // not defined
211
- template <class F, class... ArgTypes> class result_of<F(ArgTypes...)>;
212
 
213
- template <std::size_t Len,
214
- std::size_t Align = default-alignment > // see [meta.trans.other]
215
  using aligned_storage_t = typename aligned_storage<Len, Align>::type;
216
- template <std::size_t Len, class... Types>
217
  using aligned_union_t = typename aligned_union<Len, Types...>::type;
218
  template <class T>
219
  using decay_t = typename decay<T>::type;
220
  template <bool b, class T = void>
221
  using enable_if_t = typename enable_if<b, T>::type;
@@ -223,311 +243,683 @@ namespace std {
223
  using conditional_t = typename conditional<b, T, F>::type;
224
  template <class... T>
225
  using common_type_t = typename common_type<T...>::type;
226
  template <class T>
227
  using underlying_type_t = typename underlying_type<T>::type;
228
- template <class T>
229
- using result_of_t = typename result_of<T>::type;
230
- } // namespace std
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  ```
232
 
233
- The behavior of a program that adds specializations for any of the class
234
  templates defined in this subclause is undefined unless otherwise
235
  specified.
236
 
 
 
 
237
  ### Helper classes <a id="meta.help">[[meta.help]]</a>
238
 
239
  ``` cpp
240
  namespace std {
241
  template <class T, T v>
242
  struct integral_constant {
243
  static constexpr T value = v;
244
- typedef T value_type;
245
- typedef integral_constant<T,v> type;
246
  constexpr operator value_type() const noexcept { return value; }
247
  constexpr value_type operator()() const noexcept { return value; }
248
  };
249
- typedef integral_constant<bool, true> true_type;
250
- typedef integral_constant<bool, false> false_type;
251
  }
252
  ```
253
 
254
- The class template `integral_constant` and its associated typedefs
255
- `true_type` and `false_type` are used as base classes to define the
256
- interface for various type traits.
257
 
258
  ### Unary type traits <a id="meta.unary">[[meta.unary]]</a>
259
 
260
- This sub-clause contains templates that may be used to query the
261
  properties of a type at compile time.
262
 
263
- Each of these templates shall be a UnaryTypeTrait ([[meta.rqmts]]) with
264
- a BaseCharacteristic of `true_type` if the corresponding condition is
265
- true, otherwise `false_type`.
266
 
267
  #### Primary type categories <a id="meta.unary.cat">[[meta.unary.cat]]</a>
268
 
269
  The primary type categories correspond to the descriptions given in
270
  section  [[basic.types]] of the C++standard.
271
 
272
  For any given type `T`, the result of applying one of these templates to
273
- `T` and to *cv-qualified* `T` shall yield the same result.
274
 
275
- For any given type `T`, exactly one of the primary type categories has a
276
- `value` member that evaluates to `true`.
277
 
278
  #### Composite type traits <a id="meta.unary.comp">[[meta.unary.comp]]</a>
279
 
280
  These templates provide convenient compositions of the primary type
281
  categories, corresponding to the descriptions given in section 
282
  [[basic.types]].
283
 
284
  For any given type `T`, the result of applying one of these templates to
285
- `T`, and to *cv-qualified* `T` shall yield the same result.
286
 
287
  #### Type properties <a id="meta.unary.prop">[[meta.unary.prop]]</a>
288
 
289
  These templates provide access to some of the more important properties
290
  of types.
291
 
292
  It is unspecified whether the library defines any full or partial
293
  specializations of any of these templates.
294
 
295
- For all of the class templates `X` declared in this Clause,
296
  instantiating that template with a template-argument that is a class
297
  template specialization may result in the implicit instantiation of the
298
  template argument if and only if the semantics of `X` require that the
299
  argument must be a complete type.
300
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  ``` cpp
302
- is_const<const volatile int>::value // true
303
- is_const<const int*>::value // false
304
- is_const<const int&>::value // false
305
- is_const<int[3]>::value // false
306
- is_const<const int[3]>::value // true
307
  ```
308
 
 
 
 
 
309
  ``` cpp
310
  remove_const_t<const volatile int> // volatile int
311
  remove_const_t<const int* const> // const int*
312
  remove_const_t<const int&> // const int&
313
  remove_const_t<const int[3]> // int[3]
314
  ```
315
 
 
 
 
 
316
  ``` cpp
317
  // Given:
318
  struct P final { };
319
  union U1 { };
320
  union U2 final { };
321
 
322
  // the following assertions hold:
323
- static_assert(!is_final<int>::value, "Error!");
324
- static_assert( is_final<P>::value, "Error!");
325
- static_assert(!is_final<U1>::value, "Error!");
326
- static_assert( is_final<U2>::value, "Error!");
327
  ```
328
 
329
- Given the following function prototype:
330
 
331
- ``` cpp
332
- template <class T>
333
- add_rvalue_reference_t<T> create() noexcept;
334
- ```
335
-
336
- the predicate condition for a template specialization
337
  `is_constructible<T, Args...>` shall be satisfied if and only if the
338
  following variable definition would be well-formed for some invented
339
  variable `t`:
340
 
341
  ``` cpp
342
- T t(create<Args>()...);
343
  ```
344
 
345
- These tokens are never interpreted as a function declaration. Access
346
- checking is performed as if in a context unrelated to `T` and any of the
347
- `Args`. Only the validity of the immediate context of the variable
348
- initialization is considered. The evaluation of the initialization can
349
- result in side effects such as the instantiation of class template
350
- specializations and function template specializations, the generation of
351
- implicitly-defined functions, and so on. Such side effects are not in
352
- the “immediate context” and can result in the program being ill-formed.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
 
354
  ### Type property queries <a id="meta.unary.prop.query">[[meta.unary.prop.query]]</a>
355
 
356
- This sub-clause contains templates that may be used to query properties
357
  of types at compile time.
358
 
359
  Each of these templates shall be a `UnaryTypeTrait` ([[meta.rqmts]])
360
- with a `BaseCharacteristic` of `integral_constant<size_t, Value>`.
 
 
361
 
362
  ``` cpp
363
  // the following assertions hold:
364
- assert(rank<int>::value == 0);
365
- assert(rank<int[2]>::value == 1);
366
- assert(rank<int[][4]>::value == 2);
367
  ```
368
 
 
 
 
 
369
  ``` cpp
370
  // the following assertions hold:
371
- assert(extent<int>::value == 0);
372
- assert(extent<int[2]>::value == 2);
373
- assert(extent<int[2][4]>::value == 2);
374
- assert(extent<int[][4]>::value == 0);
375
- assert((extent<int, 1>::value) == 0);
376
- assert((extent<int[2], 1>::value) == 0);
377
- assert((extent<int[2][4], 1>::value) == 4);
378
- assert((extent<int[][4], 1>::value) == 4);
379
  ```
380
 
 
 
381
  ### Relationships between types <a id="meta.rel">[[meta.rel]]</a>
382
 
383
- This sub-clause contains templates that may be used to query
384
  relationships between types at compile time.
385
 
386
- Each of these templates shall be a BinaryTypeTrait ([[meta.rqmts]])
387
- with a BaseCharacteristic of `true_type` if the corresponding condition
388
  is true, otherwise `false_type`.
389
 
 
 
 
 
 
 
 
 
 
 
 
 
390
  ``` cpp
391
  struct B {};
392
  struct B1 : B {};
393
  struct B2 : B {};
394
  struct D : private B1, private B2 {};
395
 
396
- is_base_of<B, D>::value // true
397
- is_base_of<const B, D>::value // true
398
- is_base_of<B, const D>::value // true
399
- is_base_of<B, const B>::value // true
400
- is_base_of<D, B>::value // false
401
- is_base_of<B&, D&>::value // false
402
- is_base_of<B[3], D[3]>::value // false
403
- is_base_of<int, int>::value // false
404
  ```
405
 
406
- Given the following function prototype:
407
 
408
- ``` cpp
409
- template <class T>
410
- add_rvalue_reference_t<T> create() noexcept;
411
- ```
412
-
413
- the predicate condition for a template specialization
414
  `is_convertible<From, To>` shall be satisfied if and only if the return
415
  expression in the following code would be well-formed, including any
416
  implicit conversions to the return type of the function:
417
 
418
  ``` cpp
419
  To test() {
420
- return create<From>();
421
  }
422
  ```
423
 
424
- This requirement gives well defined results for reference types, void
425
- types, array types, and function types.Access checking is performed as
426
- if in a context unrelated to `To` and `From`. Only the validity of the
427
- immediate context of the expression of the *return-statement* (including
428
- conversions to the return type) is considered. The evaluation of the
429
- conversion can result in side effects such as the instantiation of class
430
- template specializations and function template specializations, the
431
- generation of implicitly-defined functions, and so on. Such side effects
432
- are not in the “immediate context” and can result in the program being
433
- ill-formed.
 
 
 
434
 
435
  ### Transformations between types <a id="meta.trans">[[meta.trans]]</a>
436
 
437
- This sub-clause contains templates that may be used to transform one
438
- type to another following some predefined rule.
439
 
440
  Each of the templates in this subclause shall be a
441
- *TransformationTrait* ([[meta.rqmts]]).
442
 
443
  #### Const-volatile modifications <a id="meta.trans.cv">[[meta.trans.cv]]</a>
444
 
 
 
 
 
445
  #### Reference modifications <a id="meta.trans.ref">[[meta.trans.ref]]</a>
446
 
 
 
 
447
  #### Sign modifications <a id="meta.trans.sign">[[meta.trans.sign]]</a>
448
 
449
  #### Array modifications <a id="meta.trans.arr">[[meta.trans.arr]]</a>
450
 
 
 
 
 
 
 
451
  ``` cpp
452
  // the following assertions hold:
453
- assert((is_same<remove_extent_t<int>, int>::value));
454
- assert((is_same<remove_extent_t<int[2]>, int>::value));
455
- assert((is_same<remove_extent_t<int[2][3]>, int[3]>::value));
456
- assert((is_same<remove_extent_t<int[][3]>, int[3]>::value));
457
  ```
458
 
 
 
 
 
459
  ``` cpp
460
  // the following assertions hold:
461
- assert((is_same<remove_all_extents_t<int>, int>::value));
462
- assert((is_same<remove_all_extents_t<int[2]>, int>::value));
463
- assert((is_same<remove_all_extents_t<int[2][3]>, int>::value));
464
- assert((is_same<remove_all_extents_t<int[][3]>, int>::value));
465
  ```
466
 
 
 
467
  #### Pointer modifications <a id="meta.trans.ptr">[[meta.trans.ptr]]</a>
468
 
469
  #### Other transformations <a id="meta.trans.other">[[meta.trans.other]]</a>
470
 
 
 
 
 
 
 
 
 
 
471
  A typical implementation would define `aligned_storage` as:
472
 
473
  ``` cpp
474
- template <std::size_t Len, std::size_t Alignment>
475
  struct aligned_storage {
476
  typedef struct {
477
  alignas(Alignment) unsigned char __data[Len];
478
  } type;
479
  };
480
  ```
481
 
 
 
482
  It is *implementation-defined* whether any extended alignment is
483
  supported ([[basic.align]]).
484
 
485
- The nested typedef `common_type::type` shall be defined as follows:
 
 
486
 
 
 
 
 
 
 
 
 
 
 
 
 
487
  ``` cpp
488
- template <class ...T> struct common_type;
489
-
490
- template <class T>
491
- struct common_type<T> {
492
- typedef decay_t<T> type;
493
- };
494
-
495
- template <class T, class U>
496
- struct common_type<T, U> {
497
- typedef decay_t<decltype(true ? declval<T>() : declval<U>())> type;
498
- };
499
-
500
- template <class T, class U, class... V>
501
- struct common_type<T, U, V...> {
502
- typedef common_type_t<common_type_t<T, U>, V...> type;
503
- };
504
  ```
505
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
506
  Given these definitions:
507
 
508
  ``` cpp
509
- typedef bool (&PF1)();
510
- typedef short (*PF2)(long);
511
 
512
  struct S {
513
  operator PF2() const;
514
  double operator()(char, int&);
515
  void fn(long) const;
516
  char data;
517
  };
518
 
519
- typedef void (S::*PMF)(long) const;
520
- typedef char S::*PMD;
521
  ```
522
 
523
  the following assertions will hold:
524
 
525
  ``` cpp
526
- static_assert(is_same<result_of_t<S(int)>, short>::value, "Error!");
527
- static_assert(is_same<result_of_t<S&(unsigned char, int&)>, double>::value, "Error!");
528
- static_assert(is_same<result_of_t<PF1()>, bool>::value, "Error!");
529
- static_assert(is_same<result_of_t<PMF(unique_ptr<S>, int)>, void>::value, "Error!");
530
- static_assert(is_same<result_of_t<PMD(S)>, char&&>::value, "Error!");
531
- static_assert(is_same<result_of_t<PMD(const S*)>, const char&>::value, "Error!");
532
  ```
533
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  given type belongs. The type property inspection traits allow important
11
  characteristics of types or of combinations of types to be inspected.
12
  The type transformations allow certain properties of types to be
13
  manipulated.
14
 
15
+ All functions specified in this subclause are signal-safe (
16
+ [[csignal.syn]]).
17
+
18
  ### Requirements <a id="meta.rqmts">[[meta.rqmts]]</a>
19
 
20
  A *UnaryTypeTrait* describes a property of a type. It shall be a class
21
  template that takes one template type argument and, optionally,
22
  additional arguments that help define the property being described. It
23
  shall be `DefaultConstructible`, `CopyConstructible`, and publicly and
24
+ unambiguously derived, directly or indirectly, from its *base
25
+ characteristic*, which is a specialization of the template
26
  `integral_constant` ([[meta.help]]), with the arguments to the template
27
  `integral_constant` determined by the requirements for the particular
28
+ property being described. The member names of the base characteristic
29
  shall not be hidden and shall be unambiguously available in the
30
+ `UnaryTypeTrait`.
31
 
32
  A *BinaryTypeTrait* describes a relationship between two types. It shall
33
  be a class template that takes two template type arguments and,
34
  optionally, additional arguments that help define the relationship being
35
  described. It shall be `DefaultConstructible`, `CopyConstructible`, and
36
  publicly and unambiguously derived, directly or indirectly, from its
37
+ *base characteristic*, which is a specialization of the template
38
  `integral_constant` ([[meta.help]]), with the arguments to the template
39
  `integral_constant` determined by the requirements for the particular
40
+ relationship being described. The member names of the base
41
+ characteristic shall not be hidden and shall be unambiguously available
42
+ in the `BinaryTypeTrait`.
43
 
44
  A *TransformationTrait* modifies a property of a type. It shall be a
45
  class template that takes one template type argument and, optionally,
46
  additional arguments that help define the modification. It shall define
47
  a publicly accessible nested type named `type`, which shall be a synonym
 
49
 
50
  ### Header `<type_traits>` synopsis <a id="meta.type.synop">[[meta.type.synop]]</a>
51
 
52
  ``` cpp
53
  namespace std {
54
+ // [meta.help], helper class
55
  template <class T, T v> struct integral_constant;
 
 
56
 
57
+ template <bool B>
58
+ using bool_constant = integral_constant<bool, B>;
59
+ using true_type = bool_constant<true>;
60
+ using false_type = bool_constant<false>;
61
+
62
+ // [meta.unary.cat], primary type categories
63
  template <class T> struct is_void;
64
  template <class T> struct is_null_pointer;
65
  template <class T> struct is_integral;
66
  template <class T> struct is_floating_point;
67
  template <class T> struct is_array;
 
73
  template <class T> struct is_enum;
74
  template <class T> struct is_union;
75
  template <class T> struct is_class;
76
  template <class T> struct is_function;
77
 
78
+ // [meta.unary.comp], composite type categories
79
  template <class T> struct is_reference;
80
  template <class T> struct is_arithmetic;
81
  template <class T> struct is_fundamental;
82
  template <class T> struct is_object;
83
  template <class T> struct is_scalar;
84
  template <class T> struct is_compound;
85
  template <class T> struct is_member_pointer;
86
 
87
+ // [meta.unary.prop], type properties
88
  template <class T> struct is_const;
89
  template <class T> struct is_volatile;
90
  template <class T> struct is_trivial;
91
  template <class T> struct is_trivially_copyable;
92
  template <class T> struct is_standard_layout;
93
  template <class T> struct is_pod;
 
94
  template <class T> struct is_empty;
95
  template <class T> struct is_polymorphic;
96
  template <class T> struct is_abstract;
97
  template <class T> struct is_final;
98
+ template <class T> struct is_aggregate;
99
 
100
  template <class T> struct is_signed;
101
  template <class T> struct is_unsigned;
102
 
103
  template <class T, class... Args> struct is_constructible;
 
107
 
108
  template <class T, class U> struct is_assignable;
109
  template <class T> struct is_copy_assignable;
110
  template <class T> struct is_move_assignable;
111
 
112
+ template <class T, class U> struct is_swappable_with;
113
+ template <class T> struct is_swappable;
114
+
115
  template <class T> struct is_destructible;
116
 
117
  template <class T, class... Args> struct is_trivially_constructible;
118
  template <class T> struct is_trivially_default_constructible;
119
  template <class T> struct is_trivially_copy_constructible;
 
131
 
132
  template <class T, class U> struct is_nothrow_assignable;
133
  template <class T> struct is_nothrow_copy_assignable;
134
  template <class T> struct is_nothrow_move_assignable;
135
 
136
+ template <class T, class U> struct is_nothrow_swappable_with;
137
+ template <class T> struct is_nothrow_swappable;
138
+
139
  template <class T> struct is_nothrow_destructible;
140
+
141
  template <class T> struct has_virtual_destructor;
142
 
143
+ template <class T> struct has_unique_object_representations;
144
+
145
+ // [meta.unary.prop.query], type property queries
146
  template <class T> struct alignment_of;
147
  template <class T> struct rank;
148
  template <class T, unsigned I = 0> struct extent;
149
 
150
+ // [meta.rel], type relations
151
  template <class T, class U> struct is_same;
152
  template <class Base, class Derived> struct is_base_of;
153
  template <class From, class To> struct is_convertible;
154
 
155
+ template <class Fn, class... ArgTypes> struct is_invocable;
156
+ template <class R, class Fn, class... ArgTypes> struct is_invocable_r;
157
+
158
+ template <class Fn, class... ArgTypes> struct is_nothrow_invocable;
159
+ template <class R, class Fn, class... ArgTypes> struct is_nothrow_invocable_r;
160
+
161
+ // [meta.trans.cv], const-volatile modifications
162
  template <class T> struct remove_const;
163
  template <class T> struct remove_volatile;
164
  template <class T> struct remove_cv;
165
  template <class T> struct add_const;
166
  template <class T> struct add_volatile;
 
177
  template <class T>
178
  using add_volatile_t = typename add_volatile<T>::type;
179
  template <class T>
180
  using add_cv_t = typename add_cv<T>::type;
181
 
182
+ // [meta.trans.ref], reference modifications
183
  template <class T> struct remove_reference;
184
  template <class T> struct add_lvalue_reference;
185
  template <class T> struct add_rvalue_reference;
186
 
187
  template <class T>
 
189
  template <class T>
190
  using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;
191
  template <class T>
192
  using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
193
 
194
+ // [meta.trans.sign], sign modifications
195
  template <class T> struct make_signed;
196
  template <class T> struct make_unsigned;
197
 
198
  template <class T>
199
  using make_signed_t = typename make_signed<T>::type;
200
  template <class T>
201
  using make_unsigned_t = typename make_unsigned<T>::type;
202
 
203
+ // [meta.trans.arr], array modifications
204
  template <class T> struct remove_extent;
205
  template <class T> struct remove_all_extents;
206
 
207
  template <class T>
208
  using remove_extent_t = typename remove_extent<T>::type;
209
  template <class T>
210
  using remove_all_extents_t = typename remove_all_extents<T>::type;
211
 
212
+ // [meta.trans.ptr], pointer modifications
213
  template <class T> struct remove_pointer;
214
  template <class T> struct add_pointer;
215
 
216
  template <class T>
217
  using remove_pointer_t = typename remove_pointer<T>::type;
218
  template <class T>
219
  using add_pointer_t = typename add_pointer<T>::type;
220
 
221
+ // [meta.trans.other], other transformations
222
+ template <size_t Len,
223
+ size_t Align = default-alignment> // see [meta.trans.other]
224
  struct aligned_storage;
225
+ template <size_t Len, class... Types> struct aligned_union;
226
  template <class T> struct decay;
227
  template <bool, class T = void> struct enable_if;
228
  template <bool, class T, class F> struct conditional;
229
  template <class... T> struct common_type;
230
  template <class T> struct underlying_type;
231
+ template <class Fn, class... ArgTypes> struct invoke_result;
 
232
 
233
+ template <size_t Len,
234
+ size_t Align = default-alignment> // see [meta.trans.other]
235
  using aligned_storage_t = typename aligned_storage<Len, Align>::type;
236
+ template <size_t Len, class... Types>
237
  using aligned_union_t = typename aligned_union<Len, Types...>::type;
238
  template <class T>
239
  using decay_t = typename decay<T>::type;
240
  template <bool b, class T = void>
241
  using enable_if_t = typename enable_if<b, T>::type;
 
243
  using conditional_t = typename conditional<b, T, F>::type;
244
  template <class... T>
245
  using common_type_t = typename common_type<T...>::type;
246
  template <class T>
247
  using underlying_type_t = typename underlying_type<T>::type;
248
+ template <class Fn, class... ArgTypes>
249
+ using invoke_result_t = typename invoke_result<Fn, ArgTypes...>::type;
250
+ template <class...>
251
+ using void_t = void;
252
+
253
+ // [meta.logical], logical operator traits
254
+ template<class... B> struct conjunction;
255
+ template<class... B> struct disjunction;
256
+ template<class B> struct negation;
257
+
258
+ // [meta.unary.cat], primary type categories
259
+ template <class T> inline constexpr bool is_void_v
260
+ = is_void<T>::value;
261
+ template <class T> inline constexpr bool is_null_pointer_v
262
+ = is_null_pointer<T>::value;
263
+ template <class T> inline constexpr bool is_integral_v
264
+ = is_integral<T>::value;
265
+ template <class T> inline constexpr bool is_floating_point_v
266
+ = is_floating_point<T>::value;
267
+ template <class T> inline constexpr bool is_array_v
268
+ = is_array<T>::value;
269
+ template <class T> inline constexpr bool is_pointer_v
270
+ = is_pointer<T>::value;
271
+ template <class T> inline constexpr bool is_lvalue_reference_v
272
+ = is_lvalue_reference<T>::value;
273
+ template <class T> inline constexpr bool is_rvalue_reference_v
274
+ = is_rvalue_reference<T>::value;
275
+ template <class T> inline constexpr bool is_member_object_pointer_v
276
+ = is_member_object_pointer<T>::value;
277
+ template <class T> inline constexpr bool is_member_function_pointer_v
278
+ = is_member_function_pointer<T>::value;
279
+ template <class T> inline constexpr bool is_enum_v
280
+ = is_enum<T>::value;
281
+ template <class T> inline constexpr bool is_union_v
282
+ = is_union<T>::value;
283
+ template <class T> inline constexpr bool is_class_v
284
+ = is_class<T>::value;
285
+ template <class T> inline constexpr bool is_function_v
286
+ = is_function<T>::value;
287
+
288
+ // [meta.unary.comp], composite type categories
289
+ template <class T> inline constexpr bool is_reference_v
290
+ = is_reference<T>::value;
291
+ template <class T> inline constexpr bool is_arithmetic_v
292
+ = is_arithmetic<T>::value;
293
+ template <class T> inline constexpr bool is_fundamental_v
294
+ = is_fundamental<T>::value;
295
+ template <class T> inline constexpr bool is_object_v
296
+ = is_object<T>::value;
297
+ template <class T> inline constexpr bool is_scalar_v
298
+ = is_scalar<T>::value;
299
+ template <class T> inline constexpr bool is_compound_v
300
+ = is_compound<T>::value;
301
+ template <class T> inline constexpr bool is_member_pointer_v
302
+ = is_member_pointer<T>::value;
303
+
304
+ // [meta.unary.prop], type properties
305
+ template <class T> inline constexpr bool is_const_v
306
+ = is_const<T>::value;
307
+ template <class T> inline constexpr bool is_volatile_v
308
+ = is_volatile<T>::value;
309
+ template <class T> inline constexpr bool is_trivial_v
310
+ = is_trivial<T>::value;
311
+ template <class T> inline constexpr bool is_trivially_copyable_v
312
+ = is_trivially_copyable<T>::value;
313
+ template <class T> inline constexpr bool is_standard_layout_v
314
+ = is_standard_layout<T>::value;
315
+ template <class T> inline constexpr bool is_pod_v
316
+ = is_pod<T>::value;
317
+ template <class T> inline constexpr bool is_empty_v
318
+ = is_empty<T>::value;
319
+ template <class T> inline constexpr bool is_polymorphic_v
320
+ = is_polymorphic<T>::value;
321
+ template <class T> inline constexpr bool is_abstract_v
322
+ = is_abstract<T>::value;
323
+ template <class T> inline constexpr bool is_final_v
324
+ = is_final<T>::value;
325
+ template <class T> inline constexpr bool is_aggregate_v
326
+ = is_aggregate<T>::value;
327
+ template <class T> inline constexpr bool is_signed_v
328
+ = is_signed<T>::value;
329
+ template <class T> inline constexpr bool is_unsigned_v
330
+ = is_unsigned<T>::value;
331
+ template <class T, class... Args> inline constexpr bool is_constructible_v
332
+ = is_constructible<T, Args...>::value;
333
+ template <class T> inline constexpr bool is_default_constructible_v
334
+ = is_default_constructible<T>::value;
335
+ template <class T> inline constexpr bool is_copy_constructible_v
336
+ = is_copy_constructible<T>::value;
337
+ template <class T> inline constexpr bool is_move_constructible_v
338
+ = is_move_constructible<T>::value;
339
+ template <class T, class U> inline constexpr bool is_assignable_v
340
+ = is_assignable<T, U>::value;
341
+ template <class T> inline constexpr bool is_copy_assignable_v
342
+ = is_copy_assignable<T>::value;
343
+ template <class T> inline constexpr bool is_move_assignable_v
344
+ = is_move_assignable<T>::value;
345
+ template <class T, class U> inline constexpr bool is_swappable_with_v
346
+ = is_swappable_with<T, U>::value;
347
+ template <class T> inline constexpr bool is_swappable_v
348
+ = is_swappable<T>::value;
349
+ template <class T> inline constexpr bool is_destructible_v
350
+ = is_destructible<T>::value;
351
+ template <class T, class... Args> inline constexpr bool is_trivially_constructible_v
352
+ = is_trivially_constructible<T, Args...>::value;
353
+ template <class T> inline constexpr bool is_trivially_default_constructible_v
354
+ = is_trivially_default_constructible<T>::value;
355
+ template <class T> inline constexpr bool is_trivially_copy_constructible_v
356
+ = is_trivially_copy_constructible<T>::value;
357
+ template <class T> inline constexpr bool is_trivially_move_constructible_v
358
+ = is_trivially_move_constructible<T>::value;
359
+ template <class T, class U> inline constexpr bool is_trivially_assignable_v
360
+ = is_trivially_assignable<T, U>::value;
361
+ template <class T> inline constexpr bool is_trivially_copy_assignable_v
362
+ = is_trivially_copy_assignable<T>::value;
363
+ template <class T> inline constexpr bool is_trivially_move_assignable_v
364
+ = is_trivially_move_assignable<T>::value;
365
+ template <class T> inline constexpr bool is_trivially_destructible_v
366
+ = is_trivially_destructible<T>::value;
367
+ template <class T, class... Args> inline constexpr bool is_nothrow_constructible_v
368
+ = is_nothrow_constructible<T, Args...>::value;
369
+ template <class T> inline constexpr bool is_nothrow_default_constructible_v
370
+ = is_nothrow_default_constructible<T>::value;
371
+ template <class T> inline constexpr bool is_nothrow_copy_constructible_v
372
+ = is_nothrow_copy_constructible<T>::value;
373
+ template <class T> inline constexpr bool is_nothrow_move_constructible_v
374
+ = is_nothrow_move_constructible<T>::value;
375
+ template <class T, class U> inline constexpr bool is_nothrow_assignable_v
376
+ = is_nothrow_assignable<T, U>::value;
377
+ template <class T> inline constexpr bool is_nothrow_copy_assignable_v
378
+ = is_nothrow_copy_assignable<T>::value;
379
+ template <class T> inline constexpr bool is_nothrow_move_assignable_v
380
+ = is_nothrow_move_assignable<T>::value;
381
+ template <class T, class U> inline constexpr bool is_nothrow_swappable_with_v
382
+ = is_nothrow_swappable_with<T, U>::value;
383
+ template <class T> inline constexpr bool is_nothrow_swappable_v
384
+ = is_nothrow_swappable<T>::value;
385
+ template <class T> inline constexpr bool is_nothrow_destructible_v
386
+ = is_nothrow_destructible<T>::value;
387
+ template <class T> inline constexpr bool has_virtual_destructor_v
388
+ = has_virtual_destructor<T>::value;
389
+ template <class T> inline constexpr bool has_unique_object_representations_v
390
+ = has_unique_object_representations<T>::value;
391
+
392
+ // [meta.unary.prop.query], type property queries
393
+ template <class T> inline constexpr size_t alignment_of_v
394
+ = alignment_of<T>::value;
395
+ template <class T> inline constexpr size_t rank_v
396
+ = rank<T>::value;
397
+ template <class T, unsigned I = 0> inline constexpr size_t extent_v
398
+ = extent<T, I>::value;
399
+
400
+ // [meta.rel], type relations
401
+ template <class T, class U> inline constexpr bool is_same_v
402
+ = is_same<T, U>::value;
403
+ template <class Base, class Derived> inline constexpr bool is_base_of_v
404
+ = is_base_of<Base, Derived>::value;
405
+ template <class From, class To> inline constexpr bool is_convertible_v
406
+ = is_convertible<From, To>::value;
407
+ template <class Fn, class... ArgTypes> inline constexpr bool is_invocable_v
408
+ = is_invocable<Fn, ArgTypes...>::value;
409
+ template <class R, class Fn, class... ArgTypes> inline constexpr bool is_invocable_r_v
410
+ = is_invocable_r<R, Fn, ArgTypes...>::value;
411
+ template <class Fn, class... ArgTypes> inline constexpr bool is_nothrow_invocable_v
412
+ = is_nothrow_invocable<Fn, ArgTypes...>::value;
413
+ template <class R, class Fn, class... ArgTypes> inline constexpr bool is_nothrow_invocable_r_v
414
+ = is_nothrow_invocable_r<R, Fn, ArgTypes...>::value;
415
+
416
+ // [meta.logical], logical operator traits
417
+ template<class... B> inline constexpr bool conjunction_v = conjunction<B...>::value;
418
+ template<class... B> inline constexpr bool disjunction_v = disjunction<B...>::value;
419
+ template<class B> inline constexpr bool negation_v = negation<B>::value;
420
+ }
421
  ```
422
 
423
+ The behavior of a program that adds specializations for any of the
424
  templates defined in this subclause is undefined unless otherwise
425
  specified.
426
 
427
+ Unless otherwise specified, an incomplete type may be used to
428
+ instantiate a template in this subclause.
429
+
430
  ### Helper classes <a id="meta.help">[[meta.help]]</a>
431
 
432
  ``` cpp
433
  namespace std {
434
  template <class T, T v>
435
  struct integral_constant {
436
  static constexpr T value = v;
437
+ using value_type = T;
438
+ using type = integral_constant<T, v>;
439
  constexpr operator value_type() const noexcept { return value; }
440
  constexpr value_type operator()() const noexcept { return value; }
441
  };
 
 
442
  }
443
  ```
444
 
445
+ The class template `integral_constant`, alias template `bool_constant`,
446
+ and its associated *typedef-name*s `true_type` and `false_type` are used
447
+ as base classes to define the interface for various type traits.
448
 
449
  ### Unary type traits <a id="meta.unary">[[meta.unary]]</a>
450
 
451
+ This subclause contains templates that may be used to query the
452
  properties of a type at compile time.
453
 
454
+ Each of these templates shall be a `UnaryTypeTrait` ([[meta.rqmts]])
455
+ with a base characteristic of `true_type` if the corresponding condition
456
+ is `true`, otherwise `false_type`.
457
 
458
  #### Primary type categories <a id="meta.unary.cat">[[meta.unary.cat]]</a>
459
 
460
  The primary type categories correspond to the descriptions given in
461
  section  [[basic.types]] of the C++standard.
462
 
463
  For any given type `T`, the result of applying one of these templates to
464
+ `T` and to cv `T` shall yield the same result.
465
 
466
+ [*Note 1*: For any given type `T`, exactly one of the primary type
467
+ categories has a `value` member that evaluates to `true`. — *end note*]
468
 
469
  #### Composite type traits <a id="meta.unary.comp">[[meta.unary.comp]]</a>
470
 
471
  These templates provide convenient compositions of the primary type
472
  categories, corresponding to the descriptions given in section 
473
  [[basic.types]].
474
 
475
  For any given type `T`, the result of applying one of these templates to
476
+ `T` and to cv `T` shall yield the same result.
477
 
478
  #### Type properties <a id="meta.unary.prop">[[meta.unary.prop]]</a>
479
 
480
  These templates provide access to some of the more important properties
481
  of types.
482
 
483
  It is unspecified whether the library defines any full or partial
484
  specializations of any of these templates.
485
 
486
+ For all of the class templates `X` declared in this subclause,
487
  instantiating that template with a template-argument that is a class
488
  template specialization may result in the implicit instantiation of the
489
  template argument if and only if the semantics of `X` require that the
490
  argument must be a complete type.
491
 
492
+ For the purpose of defining the templates in this subclause, a function
493
+ call expression `declval<T>()` for any type `T` is considered to be a
494
+ trivial ([[basic.types]], [[special]]) function call that is not an
495
+ odr-use ([[basic.def.odr]]) of `declval` in the context of the
496
+ corresponding definition notwithstanding the restrictions of 
497
+ [[declval]].
498
+
499
+ [*Note 1*: A union is a class type that can be marked with
500
+ `final`. — *end note*]
501
+
502
+ [*Example 1*:
503
+
504
  ``` cpp
505
+ is_const_v<const volatile int> // true
506
+ is_const_v<const int*> // false
507
+ is_const_v<const int&> // false
508
+ is_const_v<int[3]> // false
509
+ is_const_v<const int[3]> // true
510
  ```
511
 
512
+ — *end example*]
513
+
514
+ [*Example 2*:
515
+
516
  ``` cpp
517
  remove_const_t<const volatile int> // volatile int
518
  remove_const_t<const int* const> // const int*
519
  remove_const_t<const int&> // const int&
520
  remove_const_t<const int[3]> // int[3]
521
  ```
522
 
523
+ — *end example*]
524
+
525
+ [*Example 3*:
526
+
527
  ``` cpp
528
  // Given:
529
  struct P final { };
530
  union U1 { };
531
  union U2 final { };
532
 
533
  // the following assertions hold:
534
+ static_assert(!is_final_v<int>);
535
+ static_assert(is_final_v<P>);
536
+ static_assert(!is_final_v<U1>);
537
+ static_assert(is_final_v<U2>);
538
  ```
539
 
540
+ *end example*]
541
 
542
+ The predicate condition for a template specialization
 
 
 
 
 
543
  `is_constructible<T, Args...>` shall be satisfied if and only if the
544
  following variable definition would be well-formed for some invented
545
  variable `t`:
546
 
547
  ``` cpp
548
+ T t(declval<Args>()...);
549
  ```
550
 
551
+ [*Note 2*: These tokens are never interpreted as a function
552
+ declaration. *end note*]
553
+
554
+ Access checking is performed as if in a context unrelated to `T` and any
555
+ of the `Args`. Only the validity of the immediate context of the
556
+ variable initialization is considered.
557
+
558
+ [*Note 3*: The evaluation of the initialization can result in side
559
+ effects such as the instantiation of class template specializations and
560
+ function template specializations, the generation of implicitly-defined
561
+ functions, and so on. Such side effects are not in the “immediate
562
+ context” and can result in the program being ill-formed. — *end note*]
563
+
564
+ The predicate condition for a template specialization
565
+ `has_unique_object_representations<T>` shall be satisfied if and only
566
+ if:
567
+
568
+ - `T` is trivially copyable, and
569
+ - any two objects of type `T` with the same value have the same object
570
+ representation, where two objects of array or non-union class type are
571
+ considered to have the same value if their respective sequences of
572
+ direct subobjects have the same values, and two objects of union type
573
+ are considered to have the same value if they have the same active
574
+ member and the corresponding members have the same value.
575
+
576
+ The set of scalar types for which this condition holds is
577
+ *implementation-defined*.
578
+
579
+ [*Note 4*: If a type has padding bits, the condition does not hold;
580
+ otherwise, the condition holds true for unsigned integral
581
+ types. — *end note*]
582
 
583
  ### Type property queries <a id="meta.unary.prop.query">[[meta.unary.prop.query]]</a>
584
 
585
+ This subclause contains templates that may be used to query properties
586
  of types at compile time.
587
 
588
  Each of these templates shall be a `UnaryTypeTrait` ([[meta.rqmts]])
589
+ with a base characteristic of `integral_constant<size_t, Value>`.
590
+
591
+ [*Example 1*:
592
 
593
  ``` cpp
594
  // the following assertions hold:
595
+ assert(rank_v<int> == 0);
596
+ assert(rank_v<int[2]> == 1);
597
+ assert(rank_v<int[][4]> == 2);
598
  ```
599
 
600
+ — *end example*]
601
+
602
+ [*Example 2*:
603
+
604
  ``` cpp
605
  // the following assertions hold:
606
+ assert(extent_v<int> == 0);
607
+ assert(extent_v<int[2]> == 2);
608
+ assert(extent_v<int[2][4]> == 2);
609
+ assert(extent_v<int[][4]> == 0);
610
+ assert((extent_v<int, 1>) == 0);
611
+ assert((extent_v<int[2], 1>) == 0);
612
+ assert((extent_v<int[2][4], 1>) == 4);
613
+ assert((extent_v<int[][4], 1>) == 4);
614
  ```
615
 
616
+ — *end example*]
617
+
618
  ### Relationships between types <a id="meta.rel">[[meta.rel]]</a>
619
 
620
+ This subclause contains templates that may be used to query
621
  relationships between types at compile time.
622
 
623
+ Each of these templates shall be a `BinaryTypeTrait` ([[meta.rqmts]])
624
+ with a base characteristic of `true_type` if the corresponding condition
625
  is true, otherwise `false_type`.
626
 
627
+ [*Note 1*: Base classes that are private, protected, or ambiguous are,
628
+ nonetheless, base classes. — *end note*]
629
+
630
+ For the purpose of defining the templates in this subclause, a function
631
+ call expression `declval<T>()` for any type `T` is considered to be a
632
+ trivial ([[basic.types]], [[special]]) function call that is not an
633
+ odr-use ([[basic.def.odr]]) of `declval` in the context of the
634
+ corresponding definition notwithstanding the restrictions of 
635
+ [[declval]].
636
+
637
+ [*Example 1*:
638
+
639
  ``` cpp
640
  struct B {};
641
  struct B1 : B {};
642
  struct B2 : B {};
643
  struct D : private B1, private B2 {};
644
 
645
+ is_base_of_v<B, D> // true
646
+ is_base_of_v<const B, D> // true
647
+ is_base_of_v<B, const D> // true
648
+ is_base_of_v<B, const B> // true
649
+ is_base_of_v<D, B> // false
650
+ is_base_of_v<B&, D&> // false
651
+ is_base_of_v<B[3], D[3]> // false
652
+ is_base_of_v<int, int> // false
653
  ```
654
 
655
+ *end example*]
656
 
657
+ The predicate condition for a template specialization
 
 
 
 
 
658
  `is_convertible<From, To>` shall be satisfied if and only if the return
659
  expression in the following code would be well-formed, including any
660
  implicit conversions to the return type of the function:
661
 
662
  ``` cpp
663
  To test() {
664
+ return declval<From>();
665
  }
666
  ```
667
 
668
+ [*Note 2*: This requirement gives well defined results for reference
669
+ types, void types, array types, and function types. *end note*]
670
+
671
+ Access checking is performed in a context unrelated to `To` and `From`.
672
+ Only the validity of the immediate context of the *expression* of the
673
+ `return` statement (including initialization of the returned object or
674
+ reference) is considered.
675
+
676
+ [*Note 3*: The initialization can result in side effects such as the
677
+ instantiation of class template specializations and function template
678
+ specializations, the generation of implicitly-defined functions, and so
679
+ on. Such side effects are not in the “immediate context” and can result
680
+ in the program being ill-formed. — *end note*]
681
 
682
  ### Transformations between types <a id="meta.trans">[[meta.trans]]</a>
683
 
684
+ This subclause contains templates that may be used to transform one type
685
+ to another following some predefined rule.
686
 
687
  Each of the templates in this subclause shall be a
688
+ `TransformationTrait` ([[meta.rqmts]]).
689
 
690
  #### Const-volatile modifications <a id="meta.trans.cv">[[meta.trans.cv]]</a>
691
 
692
+ [*Example 1*: `remove_const_t<const volatile int>` evaluates to
693
+ `volatile int`, whereas `remove_const_t<const int*>` evaluates to
694
+ `const int*`. — *end example*]
695
+
696
  #### Reference modifications <a id="meta.trans.ref">[[meta.trans.ref]]</a>
697
 
698
+ [*Note 1*: This rule reflects the semantics of reference collapsing (
699
+ [[dcl.ref]]). — *end note*]
700
+
701
  #### Sign modifications <a id="meta.trans.sign">[[meta.trans.sign]]</a>
702
 
703
  #### Array modifications <a id="meta.trans.arr">[[meta.trans.arr]]</a>
704
 
705
+ [*Note 1*: For multidimensional arrays, only the first array dimension
706
+ is removed. For a type “array of `const U`”, the resulting type is
707
+ `const U`. — *end note*]
708
+
709
+ [*Example 1*:
710
+
711
  ``` cpp
712
  // the following assertions hold:
713
+ assert((is_same_v<remove_extent_t<int>, int>));
714
+ assert((is_same_v<remove_extent_t<int[2]>, int>));
715
+ assert((is_same_v<remove_extent_t<int[2][3]>, int[3]>));
716
+ assert((is_same_v<remove_extent_t<int[][3]>, int[3]>));
717
  ```
718
 
719
+ — *end example*]
720
+
721
+ [*Example 2*:
722
+
723
  ``` cpp
724
  // the following assertions hold:
725
+ assert((is_same_v<remove_all_extents_t<int>, int>));
726
+ assert((is_same_v<remove_all_extents_t<int[2]>, int>));
727
+ assert((is_same_v<remove_all_extents_t<int[2][3]>, int>));
728
+ assert((is_same_v<remove_all_extents_t<int[][3]>, int>));
729
  ```
730
 
731
+ — *end example*]
732
+
733
  #### Pointer modifications <a id="meta.trans.ptr">[[meta.trans.ptr]]</a>
734
 
735
  #### Other transformations <a id="meta.trans.other">[[meta.trans.other]]</a>
736
 
737
+ [*Note 1*: This behavior is similar to the lvalue-to-rvalue (
738
+ [[conv.lval]]), array-to-pointer ([[conv.array]]), and
739
+ function-to-pointer ([[conv.func]]) conversions applied when an lvalue
740
+ expression is used as an rvalue, but also strips cv-qualifiers from
741
+ class types in order to more closely model by-value argument
742
+ passing. — *end note*]
743
+
744
+ [*Note 2*:
745
+
746
  A typical implementation would define `aligned_storage` as:
747
 
748
  ``` cpp
749
+ template <size_t Len, size_t Alignment>
750
  struct aligned_storage {
751
  typedef struct {
752
  alignas(Alignment) unsigned char __data[Len];
753
  } type;
754
  };
755
  ```
756
 
757
+ — *end note*]
758
+
759
  It is *implementation-defined* whether any extended alignment is
760
  supported ([[basic.align]]).
761
 
762
+ Note A: For the `common_type` trait applied to a parameter pack `T` of
763
+ types, the member `type` shall be either defined or not present as
764
+ follows:
765
 
766
+ - If `sizeof...(T)` is zero, there shall be no member `type`.
767
+ - If `sizeof...(T)` is one, let `T0` denote the sole type constituting
768
+ the pack `T`. The member *typedef-name* `type` shall denote the same
769
+ type, if any, as `common_type_t<T0, T0>`; otherwise there shall be no
770
+ member `type`.
771
+ - If `sizeof...(T)` is two, let the first and second types constituting
772
+ `T` be denoted by `T1` and `T2`, respectively, and let `D1` and `D2`
773
+ denote the same types as `decay_t<T1>` and `decay_t<T2>`,
774
+ respectively.
775
+ - If `is_same_v<T1, D1>` is `false` or `is_same_v<T2, D2>` is `false`,
776
+ let `C` denote the same type, if any, as `common_type_t<D1, D2>`.
777
+ - Otherwise, let `C` denote the same type, if any, as
778
  ``` cpp
779
+ decay_t<decltype(false ? declval<D1>() : declval<D2>())>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
780
  ```
781
 
782
+ \[*Note 3*: This will not apply if there is a specialization
783
+ `common_type<D1, D2>`. — *end note*]
784
+
785
+ In either case, the member *typedef-name* `type` shall denote the same
786
+ type, if any, as `C`. Otherwise, there shall be no member `type`.
787
+ - If `sizeof...(T)` is greater than two, let `T1`, `T2`, and `R`,
788
+ respectively, denote the first, second, and (pack of) remaining types
789
+ constituting `T`. Let `C` denote the same type, if any, as
790
+ `common_type_t<T1, T2>`. If there is such a type `C`, the member
791
+ *typedef-name* `type` shall denote the same type, if any, as
792
+ `common_type_t<C, R...>`. Otherwise, there shall be no member `type`.
793
+
794
+ Note B: Notwithstanding the provisions of [[meta.type.synop]], and
795
+ pursuant to [[namespace.std]], a program may specialize
796
+ `common_type<T1, T2>` for types `T1` and `T2` such that
797
+ `is_same_v<T1, decay_t<T1>>` and `is_same_v<T2, decay_t<T2>>` are each
798
+ `true`.
799
+
800
+ [*Note 4*: Such specializations are needed when only explicit
801
+ conversions are desired between the template arguments. — *end note*]
802
+
803
+ Such a specialization need not have a member named `type`, but if it
804
+ does, that member shall be a *typedef-name* for an accessible and
805
+ unambiguous cv-unqualified non-reference type `C` to which each of the
806
+ types `T1` and `T2` is explicitly convertible. Moreover,
807
+ `common_type_t<T1, T2>` shall denote the same type, if any, as does
808
+ `common_type_t<T2, T1>`. No diagnostic is required for a violation of
809
+ this Note’s rules.
810
+
811
+ [*Example 1*:
812
+
813
  Given these definitions:
814
 
815
  ``` cpp
816
+ using PF1 = bool (&)();
817
+ using PF2 = short (*)(long);
818
 
819
  struct S {
820
  operator PF2() const;
821
  double operator()(char, int&);
822
  void fn(long) const;
823
  char data;
824
  };
825
 
826
+ using PMF = void (S::*)(long) const;
827
+ using PMD = char S::*;
828
  ```
829
 
830
  the following assertions will hold:
831
 
832
  ``` cpp
833
+ static_assert(is_same_v<invoke_result_t<S, int>, short>);
834
+ static_assert(is_same_v<invoke_result_t<S&, unsigned char, int&>, double>);
835
+ static_assert(is_same_v<invoke_result_t<PF1>, bool>);
836
+ static_assert(is_same_v<invoke_result_t<PMF, unique_ptr<S>, int>, void>);
837
+ static_assert(is_same_v<invoke_result_t<PMD, S>, char&&>);
838
+ static_assert(is_same_v<invoke_result_t<PMD, const S*>, const char&>);
839
  ```
840
 
841
+ — *end example*]
842
+
843
+ ### Logical operator traits <a id="meta.logical">[[meta.logical]]</a>
844
+
845
+ This subclause describes type traits for applying logical operators to
846
+ other type traits.
847
+
848
+ ``` cpp
849
+ template<class... B> struct conjunction : see below { };
850
+ ```
851
+
852
+ The class template `conjunction` forms the logical conjunction of its
853
+ template type arguments.
854
+
855
+ For a specialization `conjunction<B1, ..., BN>`, if there is a template
856
+ type argument `Bi` for which `bool(Bi::value)` is `false`, then
857
+ instantiating `conjunction<B1, ..., BN>::value` does not require the
858
+ instantiation of `Bj::value` for `j > i`.
859
+
860
+ [*Note 1*: This is analogous to the short-circuiting behavior of the
861
+ built-in operator `&&`. — *end note*]
862
+
863
+ Every template type argument for which `Bi::value` is instantiated shall
864
+ be usable as a base class and shall have a member `value` which is
865
+ convertible to `bool`, is not hidden, and is unambiguously available in
866
+ the type.
867
+
868
+ The specialization `conjunction<B1, ..., BN>` has a public and
869
+ unambiguous base that is either
870
+
871
+ - the first type `Bi` in the list `true_type, B1, ..., BN` for which
872
+ `bool(Bi::value)` is `false`, or
873
+ - if there is no such `Bi`, the last type in the list.
874
+
875
+ [*Note 2*: This means a specialization of `conjunction` does not
876
+ necessarily inherit from either `true_type` or
877
+ `false_type`. — *end note*]
878
+
879
+ The member names of the base class, other than `conjunction` and
880
+ `operator=`, shall not be hidden and shall be unambiguously available in
881
+ `conjunction`.
882
+
883
+ ``` cpp
884
+ template<class... B> struct disjunction : see below { };
885
+ ```
886
+
887
+ The class template `disjunction` forms the logical disjunction of its
888
+ template type arguments.
889
+
890
+ For a specialization `disjunction<B1, ..., BN>`, if there is a template
891
+ type argument `Bi` for which `bool(Bi::value)` is `true`, then
892
+ instantiating `disjunction<B1, ..., BN>::value` does not require the
893
+ instantiation of `Bj::value` for `j > i`.
894
+
895
+ [*Note 3*: This is analogous to the short-circuiting behavior of the
896
+ built-in operator `||`. — *end note*]
897
+
898
+ Every template type argument for which `Bi::value` is instantiated shall
899
+ be usable as a base class and shall have a member `value` which is
900
+ convertible to `bool`, is not hidden, and is unambiguously available in
901
+ the type.
902
+
903
+ The specialization `disjunction<B1, ..., BN>` has a public and
904
+ unambiguous base that is either
905
+
906
+ - the first type `Bi` in the list `false_type, B1, ..., BN` for which
907
+ `bool(Bi::value)` is `true`, or
908
+ - if there is no such `Bi`, the last type in the list.
909
+
910
+ [*Note 4*: This means a specialization of `disjunction` does not
911
+ necessarily inherit from either `true_type` or
912
+ `false_type`. — *end note*]
913
+
914
+ The member names of the base class, other than `disjunction` and
915
+ `operator=`, shall not be hidden and shall be unambiguously available in
916
+ `disjunction`.
917
+
918
+ ``` cpp
919
+ template<class B> struct negation : see below { };
920
+ ```
921
+
922
+ The class template `negation` forms the logical negation of its template
923
+ type argument. The type `negation<B>` is a `UnaryTypeTrait` with a base
924
+ characteristic of `bool_constant<!bool(B::value)>`.
925
+