# Header <boost/type_traits.hpp>

The contents of <boost/type_traits.hpp> are declared in namespace boost.

The file <boost/type_traits.hpp> contains various template classes that describe the fundamental properties of a type; each class represents a single type property or a single type transformation. This documentation is divided up into the following sections:

    Fundamental type operations
    Fundamental type properties
       Miscellaneous
       cv-Qualifiers
       Fundamental Types
       Compound Types
       Object/Scalar Types
    Compiler Support Information
    Example Code

## Fundamental type operations

Usage: "class_name<T>::type" performs indicated transformation on type T.

Expression. | Description. | Compiler.
`remove_volatile<T>::type` | Creates a type the same as T but with any top level volatile qualifier removed. For example "volatile int" would become "int". | P
`remove_const<T>::type` | Creates a type the same as T but with any top level const qualifier removed. For example "const int" would become "int". | P
`remove_cv<T>::type` | Creates a type the same as T but with any top level cv-qualifiers removed. For example "const int" would become "int", and "volatile double" would become "double". | P
`remove_reference<T>::type` | If T is a reference type then removes the reference, otherwise leaves T unchanged. For example "int&" becomes "int" but "int*" remains unchanged. | P
`add_reference<T>::type` | If T is a reference type then leaves T unchanged, otherwise converts T to a reference type. For example "int&" remains unchanged, but "double" becomes "double&". | P
`remove_bounds<T>::type` | If T is an array type then removes the top level array qualifier from T, otherwise leaves T unchanged. For example "int[2][3]" becomes "int[3]". | P

## Fundamental type properties

Usage: "class_name<T>::value" is true if indicated property is true, false otherwise. (Note that class_name<T>::value is always defined as a compile time constant).

### Miscellaneous

Expression | Description | Compiler
    is_same<T,U>::value
| True if T and U are the same type. |
    is_convertible<T,U>::value
| True if type T is convertible to type U. |
    alignment_of<T>::value
| An integral value representing the minimum alignment requirements of type T (strictly speaking defines a multiple of the type's alignment requirement; for all compilers tested so far however it does return the actual alignment). |

### cv-Qualifiers

The following classes determine what cv-qualifiers are present on a type (see 3.93).

Expression. | Description. | Compiler.
`is_const<T>::value` | True if type T is top-level const qualified. |
`is_volatile<T>::value` | True if type T is top-level volatile qualified. |

### Fundamental Types

The following will only ever be true for cv-unqualified types; these are closely based on the section 3.9 of the C++ Standard.

Expression. | Description. | Compiler.
`is_void<T>::value` | True only if T is void. |
`is_standard_unsigned_integral<T>::value` | True only if T is one of the standard unsigned integral types (3.9.1 p3) - unsigned char, unsigned short, unsigned int, and unsigned long. |
`is_standard_signed_integral<T>::value` | True only if T is one of the standard signed integral types (3.9.1 p2) - signed char, short, int, and long. |
`is_standard_integral<T>::value` | True if T is a standard integral type(3.9.1 p7) - T is either char, wchar_t, bool or either is_standard_signed_integral<T>::value or is_standard_integral<T>::value is true. |
`is_standard_float<T>::value` | True if T is one of the standard floating point types(3.9.1 p8) - float, double or long double. |
`is_standard_arithmetic<T>::value` | True if T is a standard arithmetic type(3.9.1 p8) - implies is_standard_integral or is_standard_float is true. |
`is_standard_fundamental<T>::value` | True if T is a standard arithmetic type or if T is void. |
`is_extension_unsigned_integral<T>::value` | True for compiler specific unsigned integral types. |
`is_extension_signed_integral<T>>:value` | True for compiler specific signed integral types. |
`is_extension_integral<T>::value` | True if either is_extension_unsigned_integral<T>::value or is_extension_signed_integral<T>::value is true. |
`is_extension_float<T>::value` | True for compiler specific floating point types. |
`is_extension_arithmetic<T>::value` | True if either is_extension_integral<T>::value or is_extension_float<T>::value are true. |
`is_extension_fundamental<T>::value` | True if either is_extension_arithmetic<T>::value or is_void<T>::value are true. |
`is_unsigned_integral<T>::value` | True if either is_standard_unsigned_integral<T>::value or is_extention_unsigned_integral<T>::value are true. |
`is_signed_integral<T>::value` | True if either is_standard_signed_integral<T>::value or is_extention_signed_integral<T>>::value are true. |
`is_integral<T>::value` | True if either is_standard_integral<T>::value or is_extention_integral<T>::value are true. |
`is_float<T>::value` | True if either is_standard_float<T>::value or is_extention_float<T>::value are true. |
`is_arithmetic<T>::value` | True if either is_integral<T>::value or is_float<T>::value are true. |
`is_fundamental<T>::value` | True if either is_arithmetic<T>::value or is_void<T>::value are true. |

### Compound Types

The following will only ever be true for cv-unqualified types, as defined by the Standard.

Expression | Description | Compiler
`is_array<T>::value` | True if T is an array type. | P
`is_pointer<T>::value` | True if T is a regular pointer type - including function pointers - but excluding pointers to member functions (3.9.2 p1 and 8.3.1). |
`is_member_pointer<T>::value` | True if T is a pointer to a non-static class member (3.9.2 p1 and 8.3.1). |
`is_reference<T>::value` | True if T is a reference type (3.9.2 p1 and 8.3.2). |
`is_class<T>::value` | True if T is a class or struct type. | PD
`is_union<T>::value` | True if T is a union type. | C
`is_enum<T>::value` | True if T is an enumerator type. | C
`is_compound<T>::value` | True if T is any of the above compound types. | PD

### Object/Scalar Types

The following ignore any top level cv-qualifiers: if `class_name<T>::value` is true then `class_name<cv-qualified-T>::value` will also be true.

Expression | Description | Compiler
`is_object<T>::value` | True if T is not a reference type, or a (possibly cv-qualified) void type. | P
`is_standard_scalar<T>::value` | True if T is a standard arithmetic type, an enumerated type, a pointer or a member pointer. | PD
`is_extension_scalar<T>::value` | True if T is an extentions arithmetic type, an enumerated type, a pointer or a member pointer. | PD
`is_scalar<T>::value` | True if T is an arithmetic type, an enumerated type, a pointer or a member pointer. | PD
`is_POD<T>::value` | True if T is a "Plain Old Data" type (see 3.9 p2&p3). Note that although this requires compiler support to be correct in all cases, if T is a scalar or an array of scalars then we can correctly define T as a POD. | PC
`is_empty<T>::value` | True if T is an empty struct or class. If the compiler implements the "zero sized empty base classes" optimisation, then is_empty will correctly guess whether T is empty. Relies upon is_class to determine whether T is a class type. Screens out enum types by using is_convertible<T,int>, this means that empty classes that overload operator int(), will not be classified as empty. | PCD
`has_trivial_constructor<T>::value` | True if T has a trivial default constructor - that is T() is equivalent to memset. | PC
`has_trivial_copy<T>::value` | True if T has a trivial copy constructor - that is T(const T&) is equivalent to memcpy. | PC
`has_trivial_assign<T>::value` | True if T has a trivial assignment operator - that is if T::operator=(const T&) is equivalent to memcpy. | PC
`has_trivial_destructor<T>::value` | True if T has a trivial destructor - that is if T::~T() has no effect. | PC

## Compiler Support Information

The legends used in the tables above have the following meanings:

P | Denotes that the class requires support for partial specialisation of class templates to work correctly.
C | Denotes that direct compiler support for that traits class is required.
D | Denotes that the traits class is dependent upon a class that requires direct compiler support.

For those classes that are marked with a D or C, if compiler support is not provided, this type trait may return "false" when the correct value is actually "true". The single exception to this rule is "is_class", which attempts to guess whether or not T is really a class, and may return "true" when the correct value is actually "false". This can happen if: T is a union, T is an enum, or T is a compiler-supplied scalar type that is not specialised for in these type traits.

If there is no compiler support, to ensure that these traits always return the correct values, specialise 'is_enum' for each user-defined enumeration type, 'is_union' for each user-defined union type, 'is_empty' for each user-defined empty composite type, and 'is_POD' for each user-defined POD type. The 'has_*' traits should also be specialized if the user-defined type has those traits and is not a POD.

The following rules are automatically enforced:

is_enum implies is_POD

is_POD implies has_*

This means, for example, if you have an empty POD-struct, just specialize is_empty and is_POD, which will cause all the has_* to also return true.

## Example code

Type-traits comes with two sample programs: type_traits_test.cpp tests the type traits classes - mostly this is a test of your compiler's support for the concepts used in the type traits implementation, while algo_opt_examples.cpp uses the type traits classes to "optimise" some familiar standard library algorithms.

There are four algorithm examples in algo_opt_examples.cpp:

    opt::copy
| If the copy operation can be performed using memcpy then does so, otherwise uses a regular element by element copy (c.f. std::copy).
    opt::fill
| If the fill operation can be performed by memset, then does so, otherwise uses a regular element by element assign. Also uses call_traits to optimise how the parameters can be passed (c.f. std::fill).
    opt::destroy_array
| If the type in the array has a trivial destructor then does nothing, otherwise calls destructors for all elements in the array - this algorithm is the reverse of std::uninitialized_copy / std::uninitialized_fill.
    opt::iter_swap
| Determines whether the iterator is a proxy-iterator: if it is then does a "slow and safe" swap, otherwise calls std::swap on the assumption that std::swap may be specialised for the iterated type.

Revised 01 September 2000

© Copyright boost.org 2000. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.

Based on contributions by Steve Cleary, Beman Dawes, Howard Hinnant and John Maddock.

Maintained by John Maddock, the latest version of this file can be found at www.boost.org, and the boost discussion list at www.egroups.com/list/boost.