ISO/ IEC JTC1/SC22/WG21 N3932

Document number: N3932
Date: 2014-02-14
Project: Programming Language C++, Library Working Group
Reply-to: Stephan T. Lavavej <stl@microsoft.com>


Variable Templates For Type Traits (Revision 1)


I. Introduction

This updates N3854 [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 <class T> constexpr bool is_void_v
  = is_void<T>::value;
template <class T> constexpr bool is_null_pointer_v
  = is_null_pointer<T>::value;
template <class T> constexpr bool is_integral_v
  = is_integral<T>::value;
template <class T> constexpr bool is_floating_point_v
  = is_floating_point<T>::value;
template <class T> constexpr bool is_array_v
  = is_array<T>::value;
template <class T> constexpr bool is_pointer_v
  = is_pointer<T>::value;
template <class T> constexpr bool is_lvalue_reference_v
  = is_lvalue_reference<T>::value;
template <class T> constexpr bool is_rvalue_reference_v
  = is_rvalue_reference<T>::value;
template <class T> constexpr bool is_member_object_pointer_v
  = is_member_object_pointer<T>::value;
template <class T> constexpr bool is_member_function_pointer_v
  = is_member_function_pointer<T>::value;
template <class T> constexpr bool is_enum_v
  = is_enum<T>::value;
template <class T> constexpr bool is_union_v
  = is_union<T>::value;
template <class T> constexpr bool is_class_v
  = is_class<T>::value;
template <class T> constexpr bool is_function_v
  = is_function<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 <class T> constexpr bool is_reference_v
  = is_reference<T>::value;
template <class T> constexpr bool is_arithmetic_v
  = is_arithmetic<T>::value;
template <class T> constexpr bool is_fundamental_v
  = is_fundamental<T>::value;
template <class T> constexpr bool is_object_v
  = is_object<T>::value;
template <class T> constexpr bool is_scalar_v
  = is_scalar<T>::value;
template <class T> constexpr bool is_compound_v
  = is_compound<T>::value;
template <class T> constexpr bool is_member_pointer_v
  = is_member_pointer<T>::value;

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

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

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

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

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

template <class T, class U> constexpr bool is_same_v
  = is_same<T, U>::value;
template <class Base, class Derived> constexpr bool is_base_of_v
  = is_base_of<Base, Derived>::value;
template <class From, class To> constexpr bool is_convertible_v
  = is_convertible<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 <class T> constexpr size_t tuple_size_v
  = tuple_size<T>::value;
template <size_t I, class T> using tuple_element_t
  = typename tuple_element<I, T>::type;

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

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

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

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

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

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

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

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

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

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


III. References

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

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

[2] LWG 2112 "User-defined classes that cannot be derived from"
submitted by Daniel Krügler:
http://cplusplus.github.io/LWG/lwg-active.html#2112

(end)