<html>
<head>
<TITLE>
ISO/IEC JTC1/SC22/WG21
N3932
</TITLE>
</head>
<body>
<h1>
<img align=top src="/pics/iso44.gif" alt="ISO/">
<img align=top src="/pics/iec44.gif" alt="IEC">
JTC1/SC22/WG21
N3932
</h1>
<pre>
Document number: N3932
Date: 2014-02-14
Project: Programming Language C++, Library Working Group
Reply-to: Stephan T. Lavavej &lt;stl@microsoft.com>


Variable Templates For Type Traits (Revision 1)


I. Introduction

This updates <a hRef="../2014/n3854.htm">N3854</a> [1] in response to the resolution for LWG 2112 [2],
adding is_final_v between is_abstract_v and is_signed_v.
There are no other changes.


II. Standardese

1. In 20.10.2 [meta.type.synop], at the end of the
"// 20.10.4.1, primary type categories:" chunk, add:

template &lt;class T> constexpr bool is_void_v
  = is_void&lt;T>::value;
template &lt;class T> constexpr bool is_null_pointer_v
  = is_null_pointer&lt;T>::value;
template &lt;class T> constexpr bool is_integral_v
  = is_integral&lt;T>::value;
template &lt;class T> constexpr bool is_floating_point_v
  = is_floating_point&lt;T>::value;
template &lt;class T> constexpr bool is_array_v
  = is_array&lt;T>::value;
template &lt;class T> constexpr bool is_pointer_v
  = is_pointer&lt;T>::value;
template &lt;class T> constexpr bool is_lvalue_reference_v
  = is_lvalue_reference&lt;T>::value;
template &lt;class T> constexpr bool is_rvalue_reference_v
  = is_rvalue_reference&lt;T>::value;
template &lt;class T> constexpr bool is_member_object_pointer_v
  = is_member_object_pointer&lt;T>::value;
template &lt;class T> constexpr bool is_member_function_pointer_v
  = is_member_function_pointer&lt;T>::value;
template &lt;class T> constexpr bool is_enum_v
  = is_enum&lt;T>::value;
template &lt;class T> constexpr bool is_union_v
  = is_union&lt;T>::value;
template &lt;class T> constexpr bool is_class_v
  = is_class&lt;T>::value;
template &lt;class T> constexpr bool is_function_v
  = is_function&lt;T>::value;

2. In 20.10.2 [meta.type.synop], at the end of the
"// 20.10.4.2, composite type categories:" chunk, add:

template &lt;class T> constexpr bool is_reference_v
  = is_reference&lt;T>::value;
template &lt;class T> constexpr bool is_arithmetic_v
  = is_arithmetic&lt;T>::value;
template &lt;class T> constexpr bool is_fundamental_v
  = is_fundamental&lt;T>::value;
template &lt;class T> constexpr bool is_object_v
  = is_object&lt;T>::value;
template &lt;class T> constexpr bool is_scalar_v
  = is_scalar&lt;T>::value;
template &lt;class T> constexpr bool is_compound_v
  = is_compound&lt;T>::value;
template &lt;class T> constexpr bool is_member_pointer_v
  = is_member_pointer&lt;T>::value;

3. In 20.10.2 [meta.type.synop], at the end of the
"// 20.10.4.3, type properties:" chunk, add:

template &lt;class T> constexpr bool is_const_v
  = is_const&lt;T>::value;
template &lt;class T> constexpr bool is_volatile_v
  = is_volatile&lt;T>::value;
template &lt;class T> constexpr bool is_trivial_v
  = is_trivial&lt;T>::value;
template &lt;class T> constexpr bool is_trivially_copyable_v
  = is_trivially_copyable&lt;T>::value;
template &lt;class T> constexpr bool is_standard_layout_v
  = is_standard_layout&lt;T>::value;
template &lt;class T> constexpr bool is_pod_v
  = is_pod&lt;T>::value;
template &lt;class T> constexpr bool is_literal_type_v
  = is_literal_type&lt;T>::value;
template &lt;class T> constexpr bool is_empty_v
  = is_empty&lt;T>::value;
template &lt;class T> constexpr bool is_polymorphic_v
  = is_polymorphic&lt;T>::value;
template &lt;class T> constexpr bool is_abstract_v
  = is_abstract&lt;T>::value;
template &lt;class T> constexpr bool is_final_v
  = is_final&lt;T>::value;
template &lt;class T> constexpr bool is_signed_v
  = is_signed&lt;T>::value;
template &lt;class T> constexpr bool is_unsigned_v
  = is_unsigned&lt;T>::value;
template &lt;class T, class... Args> constexpr bool is_constructible_v
  = is_constructible&lt;T, Args...>::value;
template &lt;class T> constexpr bool is_default_constructible_v
  = is_default_constructible&lt;T>::value;
template &lt;class T> constexpr bool is_copy_constructible_v
  = is_copy_constructible&lt;T>::value;
template &lt;class T> constexpr bool is_move_constructible_v
  = is_move_constructible&lt;T>::value;
template &lt;class T, class U> constexpr bool is_assignable_v
  = is_assignable&lt;T, U>::value;
template &lt;class T> constexpr bool is_copy_assignable_v
  = is_copy_assignable&lt;T>::value;
template &lt;class T> constexpr bool is_move_assignable_v
  = is_move_assignable&lt;T>::value;
template &lt;class T> constexpr bool is_destructible_v
  = is_destructible&lt;T>::value;
template &lt;class T, class... Args> constexpr bool is_trivially_constructible_v
  = is_trivially_constructible&lt;T, Args...>::value;
template &lt;class T> constexpr bool is_trivially_default_constructible_v
  = is_trivially_default_constructible&lt;T>::value;
template &lt;class T> constexpr bool is_trivially_copy_constructible_v
  = is_trivially_copy_constructible&lt;T>::value;
template &lt;class T> constexpr bool is_trivially_move_constructible_v
  = is_trivially_move_constructible&lt;T>::value;
template &lt;class T, class U> constexpr bool is_trivially_assignable_v
  = is_trivially_assignable&lt;T, U>::value;
template &lt;class T> constexpr bool is_trivially_copy_assignable_v
  = is_trivially_copy_assignable&lt;T>::value;
template &lt;class T> constexpr bool is_trivially_move_assignable_v
  = is_trivially_move_assignable&lt;T>::value;
template &lt;class T> constexpr bool is_trivially_destructible_v
  = is_trivially_destructible&lt;T>::value;
template &lt;class T, class... Args> constexpr bool is_nothrow_constructible_v
  = is_nothrow_constructible&lt;T, Args...>::value;
template &lt;class T> constexpr bool is_nothrow_default_constructible_v
  = is_nothrow_default_constructible&lt;T>::value;
template &lt;class T> constexpr bool is_nothrow_copy_constructible_v
  = is_nothrow_copy_constructible&lt;T>::value;
template &lt;class T> constexpr bool is_nothrow_move_constructible_v
  = is_nothrow_move_constructible&lt;T>::value;
template &lt;class T, class U> constexpr bool is_nothrow_assignable_v
  = is_nothrow_assignable&lt;T, U>::value;
template &lt;class T> constexpr bool is_nothrow_copy_assignable_v
  = is_nothrow_copy_assignable&lt;T>::value;
template &lt;class T> constexpr bool is_nothrow_move_assignable_v
  = is_nothrow_move_assignable&lt;T>::value;
template &lt;class T> constexpr bool is_nothrow_destructible_v
  = is_nothrow_destructible&lt;T>::value;
template &lt;class T> constexpr bool has_virtual_destructor_v
  = has_virtual_destructor&lt;T>::value;

4. In 20.10.2 [meta.type.synop], at the end of the
"// 20.10.5, type property queries:" chunk, add:

template &lt;class T> constexpr size_t alignment_of_v
  = alignment_of&lt;T>::value;
template &lt;class T> constexpr size_t rank_v
  = rank&lt;T>::value;
template &lt;class T, unsigned I = 0> constexpr size_t extent_v
  = extent&lt;T, I>::value;

5. In 20.10.2 [meta.type.synop], at the end of the
"// 20.10.6, type relations:" chunk, add:

template &lt;class T, class U> constexpr bool is_same_v
  = is_same&lt;T, U>::value;
template &lt;class Base, class Derived> constexpr bool is_base_of_v
  = is_base_of&lt;Base, Derived>::value;
template &lt;class From, class To> constexpr bool is_convertible_v
  = is_convertible&lt;From, To>::value;

6. In 20.4.1 [tuple.general]/2, at the end of the
"// 20.4.2.5, tuple helper classes:" chunk, add:

template &lt;class T> constexpr size_t tuple_size_v
  = tuple_size&lt;T>::value;
template &lt;size_t I, class T> using tuple_element_t
  = typename tuple_element&lt;I, T>::type;

7. In 20.11.2 [ratio.syn], at the end of the
"// 20.11.5, ratio comparison" chunk, add:

template &lt;class R1, class R2> constexpr bool ratio_equal_v
  = ratio_equal&lt;R1, R2>::value;
template &lt;class R1, class R2> constexpr bool ratio_not_equal_v
  = ratio_not_equal&lt;R1, R2>::value;
template &lt;class R1, class R2> constexpr bool ratio_less_v
  = ratio_less&lt;R1, R2>::value;
template &lt;class R1, class R2> constexpr bool ratio_less_equal_v
  = ratio_less_equal&lt;R1, R2>::value;
template &lt;class R1, class R2> constexpr bool ratio_greater_v
  = ratio_greater&lt;R1, R2>::value;
template &lt;class R1, class R2> constexpr bool ratio_greater_equal_v
  = ratio_greater_equal&lt;R1, R2>::value;

8. In 19.5 [syserr]/2, after the definition of is_error_condition_enum, add:

template &lt;class T> constexpr bool is_error_code_enum_v
  = is_error_code_enum&lt;T>::value;
template &lt;class T> constexpr bool is_error_condition_enum_v
  = is_error_condition_enum&lt;T>::value;

9. In 20.7.2 [memory.syn]/1, at the end of the
"// 20.7.7, uses_allocator" chunk, add:

template &lt;class T, class Alloc> constexpr bool uses_allocator_v
  = uses_allocator&lt;T, Alloc>::value;

10. In 20.9 [function.objects]/2, after the declaration of is_placeholder, add:

template &lt;class T> constexpr bool is_bind_expression_v
  = is_bind_expression&lt;T>::value;
template &lt;class T> constexpr int is_placeholder_v
  = is_placeholder&lt;T>::value;

11. In 20.12.2 [time.syn], at the end of the
"// 20.12.4, customization traits" chunk, add:

template &lt;class Rep> constexpr bool treat_as_floating_point_v
  = treat_as_floating_point&lt;Rep>::value;


III. References

All of the Standardese citations in this proposal are to Working Paper <a hRef="../2013/n3797.pdf">N3797</a>:
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf
">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf</a>

[1] <a hRef="../2014/n3854.htm">N3854</a> "Variable Templates For Type Traits" by Stephan T. Lavavej:
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3854.htm
">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3854.htm</a>

[2] LWG 2112 "User-defined classes that cannot be derived from"
submitted by Daniel Krgler:
<a href="http://cplusplus.github.io/LWG/lwg-active.html#2112
">http://cplusplus.github.io/LWG/lwg-active.html#2112</a>

(end)
</pre>
</body>
</html>
