This is a draft proposal for a uniform interface between the C++ standard library and the C++ compiler regarding the <type_traits> header defined by TR1.
All of the following are compiler intrinsic functions that "execute" at compile time, returning compile time integral constants or types as appropriate. A violation of the Requires clause (if it exists) requires a diagnostic. Unlike the TR1 interface, these intrinsic functions will work with local types.
bool __is_member_object_pointer(type)
Returns: true if type is a (possibly cv-qualified) pointer to a non-static data member of a class or union, else returns false.
bool __is_member_function_pointer(type)
Returns: true if type is a (possibly cv-qualified) pointer to a non-static member function, else returns false.
bool __is_enum(type)
Returns: true if type is a (possibly cv-qualified) enum, else returns false.
bool __is_union(type)
Returns: true if type is a (possibly cv-qualified) union, else returns false.
bool __is_class(type)
Returns: true if type is a (possibly cv-qualified) class or struct, else returns false. __is_class returns false for union's even though the C++ standard refers to unions as a type of class.
bool __is_function(type)
Returns: true if type is a non-member function, else returns false. Note that __is_function returns false if type is a pointer to a function.
bool __is_pod(type)
Requires: type is a complete type, an array type of unknown bounds of a complete type, or cv-void.
Returns: true if type is a (possibly cv-qualified) POD type, else returns false. The definition of POD is that followed in the C++ standard. For convenience only, that definition is summarized here. In the event of a discrepancy between this definition and that found in the standard, the standard definition prevails.
All scalar types are PODs. This includes arithmetic types, member pointers, pointers and enums. It excludes void, references and function types. Some unions and class/structs are also POD types. To qualify as a POD such aggregates must have the following properties:
An array of POD types is also considered a POD type.
bool __is_empty(type)
Requires: type is a complete type, an array type of unknown bounds of a complete type, or cv-void.
Returns: false if __is_class(type) returns false. Returns true if when type is used as the sole base class of a class D no storage is added to the size of D, else returns false.
bool __is_polymorphic(type)
Requires: type is a complete type, an array type of unknown bounds of a complete type, or cv-void.
Returns: true if type has a virtual function (pure or not), else returns false.
bool __is_abstract(type)
Requires: type is a complete type, an array type of unknown bounds of a complete type, or cv-void.
Returns: true if type has a pure virtual function, else returns false.
bool __has_trivial_default(type)
Requires: type is a complete type, an array type of unknown bounds of a complete type, or cv-void.
Returns: true if type has a trivial default constructor, else returns false. For all types which __is_pod(type) returns true, __has_trivial_default(type) also returns true (e.g. all scalars have trivial default constructors).
For convenience only, the definition of trivial default constructor is given here. In the event of a discrepancy between this definition and that found in the standard, the standard definition prevails.
A default constructor is trivial if it is implicitly declared and:
bool __has_trivial_copy(type)
Requires: type is a complete type, an array type of unknown bounds of a complete type, or cv-void.
Returns: true if type has a trivial copy constructor, else returns false. For all types which __is_pod(type) returns true, __has_trivial_copy(type) also returns true (e.g. all scalars have trivial copy constructors). All reference types also have a trivial copy constructor.
For convenience only, the definition of trivial copy constructor is given here. In the event of a discrepancy between this definition and that found in the standard, the standard definition prevails.
A copy constructor is trivial if it is implicitly declared and:
bool __has_trivial_assign(type)
Requires: type is a complete type, an array type of unknown bounds of a complete type, or cv-void.
Returns: true if type has a trivial assignment operator, else returns false. No const-qualified type has a trivial assignment operator. For all non-const types which __is_pod(type) returns true, __has_trivial_assign(type) also returns true (e.g. all non-const scalars have trivial assignment operators). All reference types do not have a trivial assignment operator.
For convenience only, the definition of trivial assignment operator is given here. In the event of a discrepancy between this definition and that found in the standard, the standard definition prevails.
An assignment operator is trivial if it is implicitly declared and:
bool __has_trivial_destructor(type)
Requires: type is a complete type, an array type of unknown bounds of a complete type, or cv-void.
Returns: true if type has a trivial destructor, else returns false. For all types which __is_pod(type) returns true, __has_trivial_destructor(type) also returns true (e.g. all scalars have trivial destructors). All reference types also have a trivial destructor.
For convenience only, the definition of trivial destructor is given here. In the event of a discrepancy between this definition and that found in the standard, the standard definition prevails.
A destructor is trivial if it is implicitly declared and:
bool __has_nothrow_default(type)
Requires: type is a complete type, an array type of unknown bounds of a complete type, or cv-void.
Returns: true if type has a default constructor with an empty exception specification or if the compiler otherwise deduces that the default constructor can not throw an exception. Otherwise false is returned. For all types which __has_trivial_default(type) returns true, __has_nothrow_default(type) also returns true.
bool __has_nothrow_copy(type)
Requires: type is a complete type, an array type of unknown bounds of a complete type, or cv-void.
Returns: true if type has a copy constructor with an empty exception specification or if the compiler otherwise deduces that the copy constructor can not throw an exception. Otherwise false is returned. For all types which __has_trivial_copy(type) returns true, __has_nothrow_copy(type) also returns true.
bool __has_nothrow_assign(type)
Requires: type is a complete type, an array type of unknown bounds of a complete type, or cv-void.
Returns: true if type has an assignment operator with an empty exception specification or if the compiler otherwise deduces that the assignment operator can not throw an exception. Otherwise false is returned. For a const-qualified type to have a nothrow assignment operator, the assignment operator must be declared const. For all types which __has_trivial_assign(type) returns true, __has_nothrow_assign(type) also returns true.
bool __has_virtual_destructor(type)
Requires: type is a complete type, an array type of unknown bounds of a complete type, or cv-void.
Returns: true if type has a virtual destructor, else returns false.
bool __is_base_of(base_type, derived_type)
Requires: base_type and derived_type are complete types, an array type of unknown bounds of a complete type, or of type cv-void.
Returns: true if base_type is a base class of derived_type or if base_type and derived_type are the same type, else returns false.
cv-qualifed base_types always result in false result. cv qualifications on derived_type are discarded.
bool __is_convertible(from_type, to_type)
Requires: from_type and to_type are complete types, an array type of unknown bounds of a complete type, or of type cv-void.
Returns: true if an rvalue from_type is implicitly convertible to to_type via copy-initialization. More specifically assume the following template function prototye with an add_rvalue_reference helper:
template <class T> struct add_rvalue_reference {typedef T&& type;};
template <> struct add_rvalue_reference<void> {typedef void type;};
template <> struct add_rvalue_reference<const void> {typedef const void type;};
template <> struct add_rvalue_reference<volatile void> {typedef volatile void type;};
template <> struct add_rvalue_reference<const volatile void> {typedef const volatile void type;};
template <class T> typename add_rvalue_reference<T>::type create_from_type();
Then __is_convertible(from_type, to_type) returns true if and only if the following is well formed code using only publicly available functions:
to_type test()
{
return create_from_type<from_type>();
}
Note that this definition has explicitly defined behavior even for the cases that from_type or to_type are reference types, void types, array types, or function types.
size_t __alignof(type)
Requires: type is a complete type, or an array type of unknown bounds of a complete type,.
Returns: A value representing the number of bytes of the alignment of objects of type type; an object of type type may be allocated at an address that is a multiple of its alignment.
type __aligned_pod(size_t size)
Returns: A POD type which has an alignment of size, or if no such POD type exists, returns void.
size_t __max_alignment()
Returns: the maximum value which __alignof(type) can return.
__is_thread_local(object)
Requires: object is the name of an object visible and accessible in the current scope.
Returns: true if object has thread storage duration, else returns false. On implementations where thread-local declarations are not supported, false is always returned.
If the compiler provides this interface, it also defines the following macro:
#define __NATIVE_TYPE_TRAITS_SUPPORTED 1