type traits

Overview
trait template classes were first introduced in basic_string class so that the common operations such as finding the length of the string can be customized based on the character type and is injected separately during compile time. 
For example, the implementation of length() uses strlen() for char and wcslen() for wchar.
typedef basic_string<char, char_traits<char>, allocator<char> >
	string;
typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> >
	wstring;

Details
type_traits were introduced in C++11, basically defines templates for compile-time constants that give information about the properties of their type arguments, or produce transformed types. The classes and templates in type_traits are used to support type inference, classification, and transformation at compile time. 
type_traits  can be divided into four categories. 
NameDescription
Unary type traitsDescribe a property of a type
Binary type traitsDescribe a relationship between types.
Transformation traitsModify a property of a type.
Memory AllocationThese traits  allocate uninitialized memory of POD type.

Utility classes
type traits classes internally uses a number of utility classes  such as integral_constant in its implementation. 
The integral_constant is a template based class wraps a static constant of specified type in a member called value. It is the base class for the C++ type traits. 
For example, helper class true_type and false_type are basically typedefs of the classes based on  integral_constant of type bool, whose value member return true or false respectively.

NameDescription
integral_constantMakes an integral constant from a type and a value.
true_typeHolds integral constant with true value.
false_typeHolds integral constant with false value.

The following code depctis implementation of integral_constant class and typedefs true_type or false_type. It also defines a trait class is_void that checks if a type is void and returns true or false.
template <typename T, T val>
struct integral_constant
{
	static constexpr T value = val;
	typedef T value_type;
	typedef integral_constant<T, val> type;
	constexpr operator value_type() const
	{
		return value;
	}
};
typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;

//Example
//The following defines a trait class is_void 
//it checks if a type is void and returns true or false.

//default
template<class T>
struct is_void	: std::false_type {};

//specialization
template<>
struct is_void<void> : std::true_type {};

//Usage
is_void<int*>::value; //returns false
is_void<void>::value;  //returns true
It's depicted in this example.

Unary type traits
Unary Type Traits describe a property of a single type. Most Unary Type Traits return true or false and are derived from true_type or false_type.  For example, is_void discussed above.
A few of the Unary Type Traits are not based on bool. An example is the type trait extent, which gives the number of elements in an array type is based on size_t.
Unary type trats can be further classified as below. 
  1. Primary Type Categories
  2. Composite Type Traits
  3. Type Properties
  4. Type property queries
Primary type categories
These traits basically return true_type  or false_type based on evaluation.
NameDescription
is_voidTests whether the type is void.
is_null_pointerTests whether the type is nullptr_t.
is_integralTests whether the type is integral.
is_floating_pointTests whether the type is floating-point.
is_arrayTests whether the type is an array.
is_pointerTests whether the type is a pointer.
is_lvalue_referenceTests if type is an lvalue reference.
is_rvalue_referenceTests if type is an rvalue reference.
is_member_object_pointerTests whether the type is a pointer to a member object.
is_member_function_pointerTests whether the type is a pointer to a member function.
is_enumTests whether the type is an enumeration.
is_unionTests whether the type is a union.
is_classTests whether the type is a class.
is_functionTests whether the type is a function type.
The example 2 depicts the usage.

Composite type categories
These traits basically return Traits return  true_type  or false_type based on evaluation.
NameDescription
is_referenceTests whether the type is a reference.
is_arithmeticTests whether the type is arithmetic.
is_fundamentalTests whether the type is void or arithmetic.
is_objectTests whether the type is an object type.
is_scalarTests whether the type is scalar.
is_compoundTests whether the type is not scalar.
is_member_pointerTests whether the type is a pointer to a member.

Type properties
These traits basically return Traits return  true_type  or false_type based on evaluation.
NameDescription
is_constTests whether the type is const.
is_volatileTests whether the type is volatile.
is_trivialTests whether the type is trivial.
is_trivially_copyableTests whether the type is trivially copyable.
is_standard_layoutTests if type is a standard layout type.
is_pod Tests whether the type is a POD.
is_literal_typeTests whether the type can be a constexpr variable or used in a constexpr function.
is_emptyTests whether the type is an empty class.
is_polymorphicTests whether the type is a polymorphic class.
is_abstractTests whether the type is an abstract class.
is_finalTests whether the type is a class type marked final.
is_aggregateTests whether the type is a class type marked aggregate.
is_signedTests whether the type is a signed integer.
is_unsignedTests whether the type is an unsigned integer.
is_constructibleTests whether the type is constructible using the specified argument types.
is_default_constructibleTests whether the type has a default constructor.
is_copy_constructibleTests whether the type has a copy constructor.
is_move_constructibleTests whether the type has a move constructor.
is_assignableTests whether the first type can be assigned a value of the second type.
is_copy_assignableTests whether a type can be assigned a const reference value of the type.
is_move_assignableTests whether a type can be assigned an rvalue reference of the type.
is_destructibleTests whether the type is destructible.
is_trivially_constructibleTests whether the type uses no non-trivial operations when constructed using the specified types.
is_trivially_default_constructibleTests whether the type uses no non-trivial operations when default constructed.
is_trivially_copy_constructibleTests whether the type uses no non-trivial operations when copy constructed.
is_trivially_move_constructibleTests whether the type uses no non-trivial operations when move constructed.
is_trivially_assignableTests whether the types are assignable and the assignment uses no non-trivial operations.
is_trivially_copy_assignableTests whether the type is copy assignable and the assignment uses no non-trivial operations.
is_trivially_move_assignableTests whether the type is move assignable and the assignment uses no non-trivial operations.
is_trivially_destructibleTests whether the type is destructible and the destructor uses no non-trivial operations.
is_nothrow_constructibleTests whether the type is constructible and is known not to throw when constructed using the specified types.
is_nothrow_default_constructibleTests whether the type is default constructible and is known not to throw when default constructed.
is_nothrow_copy_constructibleTests whether the type is copy constructible and the copy constructor is known not to throw.
is_nothrow_move_constructibleTests whether the type is move constructible and the move constructor is known not to throw.
is_nothrow_assignableTests whether the type is assignable using the specified type and the assignment is known not to throw.
is_nothrow_copy_assignableTests whether the type is copy assignable and the assignment is known not to throw.
is_nothrow_move_assignableTests whether the type is move assignable and the assignment is known not to throw.
is_nothrow_destructibleTests whether the type is destructible and the destructor is known not to throw.
has_virtual_destructorTests whether the type has a virtual destructor.

Type property queries
These traits basically return a value based on evaluation.
NameDescription
alignment_ofGets the alignment of a type.
rankGets the number of array dimensions.
extentGets the number of elements in the specified array dimension.
The example 3 depicts the usage.

Binary Type Traits 
Binary Type Traits provide information about a relationship between two types. Every Binary Type Trait return  true_type  or false_type. based on the presence or absence of a specific relationship between the two argument types.

Type relations
These traits basically return Traits return  true_type  or false_type based on evaluation.

NameDescription
is_sameTests whether two types are the same.
is_base_ofTests whether one type is a base of another.
is_convertibleTests whether one type is convertible to another.

Transformation Type Traits
Transformation Type Traits modify a type. Every Transformation Type Trait possesses a nested typedef named type that represents the result of the modification. 

Transformation type trats can be further classified as below. 
  1. Const-volatile modifications
  2. Reference modifications
  3. Sign modifications
  4. Array modifications
  5. Pointer  modifications
  6. Other modifications
Const-volatile modifications
These traits basically return a type based on modification.
NameDescription
add_constProduces a const type from type.
add_volatileProduces a volatile type from type.
add_cvProduces a const volatile type from type.
remove_constProduces a non-const type from type.
remove_volatileProduces a non-volatile type from type.
remove_cvProduces a non-const non-volatile type from type.

Reference modifications
These traits basically return a type based on modification.
NameDescription
add_lvalue_referenceProduces a reference to type from type.
add_rvalue_referenceProduces an rvalue reference to type from type
remove_referenceProduces a non-reference type from type.

Sign modifications
These traits basically return a type based on modification.
NameDescription
make_signedProduces the type if signed or the smallest signed type greater than or equal in size to type.
make_unsignedProduces the type if unsigned or the smallest unsigned type greater than or equal in size to type.

Array modifications
These traits basically return a type based on modification.
NameDescription
remove_all_extentsProduces a non-array type from an array type.
remove_extentProduces the element type from an array type.

Pointer  modifications
These traits basically return a type based on modification.
NameDescription
add_pointerProduces a pointer to type from type.
remove_pointerProduces a type from a pointer to type.
The example 4  depicts the usage.

Other modifications
These traits basically return a type based on modification.
NameDescription
conditionalIf the condition is true, produces the first specified type, otherwise the second specified type.
decayProduces the type as passed by value. Makes non-reference, non-const, or non-volatile type, or makes a pointer to type.
enable_ifIf the condition is true, produces the specified type, otherwise no type.
underlying_typeProduces the underlying integral type for an enumeration type.
The example 5  depicts the usage.

Memory Allocation
These traits  allocate uninitialized memory of POD type.
NameDescription
aligned_storageAllocates uninitialized memory for an aligned type.
aligned_unionAllocates uninitialized memory for an aligned union with a non-trivial constructor or destructor.
The example 6  depicts the usage.


Summary of Examples

NameDescriptiongithubwandbox
  Example       Example Implementation   source    output   source + output    
  Example 2Primary Types   source    output    source + output
  Example 3Type Property Queries   source    output     source + output
  Example 4Pointer Modifications   source    output     source + output
  Example 5Other Modifications   source    output     source + output
  Example 6Memory Allocation   source    output     source + output


No comments:

Post a Comment