forked from boostorg/type_traits
1280 lines
52 KiB
HTML
1280 lines
52 KiB
HTML
<html>
|
|
|
|
<head>
|
|
<meta http-equiv="Content-Type"
|
|
content="text/html; charset=iso-8859-1">
|
|
<meta name="Template"
|
|
content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">
|
|
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
|
|
<title>Type Traits</title>
|
|
</head>
|
|
|
|
<body bgcolor="#FFFFFF" link="#0000FF" vlink="#800080">
|
|
|
|
<h1><img src="../../c++boost.gif" width="276" height="86">Header
|
|
<<a href="../../boost/type_traits.hpp">boost/type_traits.hpp</a>></h1>
|
|
|
|
<p>The contents of <boost/type_traits.hpp> are declared in
|
|
namespace boost.</p>
|
|
|
|
<p>The file <<a href="../../boost/type_traits.hpp">boost/type_traits.hpp</a>>
|
|
contains various template classes that describe the fundamental
|
|
properties of a type; each class represents a single type
|
|
property or a single type transformation. If you are new to this
|
|
library then read the accompanying <a href="c++_type_traits.htm">article</a>
|
|
first. </p>
|
|
|
|
<p>This documentation is divided up into the following sections:</p>
|
|
|
|
<pre><a href="#primary">Primary Type Categorisation</a>
|
|
<a href="#secondary">Secondary Type Categorisation</a>
|
|
<a href="#properties">Type Properties</a>
|
|
<a href="#relationships">Relationships Between Types</a>
|
|
<a href="#transformations">Transformations Between Types</a>
|
|
<a href="#compiler">Compiler Support Information</a>
|
|
<a href="#headers">Type traits headers</a>
|
|
<a href="#example">Example Code</a></pre>
|
|
|
|
<p>All of the integral expressions in this library are <a
|
|
href="../../more/int_const_guidelines.htm"><em>integral constant
|
|
expressions</em></a>, these can sometimes cause compiler problems
|
|
in use, so there is a related set of <a
|
|
href="../../more/int_const_guidelines.htm">coding guidelines</a>
|
|
to help you write portable code using this library.</p>
|
|
|
|
<h2><a name="primary"></a>Primary Type Categorisation</h2>
|
|
|
|
<p>The following type traits templates identify which type
|
|
category the type belongs to. For any given type, exactly one of
|
|
the following expressions will evaluate to true. Note that this
|
|
means that <code>is_integral<T>::value</code> and <code>is_float<T>::value</code>
|
|
will only every be true for built-in types; if you want to check
|
|
for a user-defined type that may behave "as if" it is
|
|
an integral or floating point type, then use the std::numeric_limits
|
|
template instead.</p>
|
|
|
|
<table border="0" cellpadding="7" cellspacing="1" width="100%">
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#008080"><p
|
|
align="center">Expression</p>
|
|
</td>
|
|
<td valign="top" width="26%" bgcolor="#008080"><p
|
|
align="center">Description</p>
|
|
</td>
|
|
<td valign="top" width="16%" bgcolor="#008080"><p
|
|
align="center">Reference</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#008080"><p
|
|
align="center">Compiler requirements</p>
|
|
</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::is_void<T>::value</code></td>
|
|
<td valign="top" width="26%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is a cv-qualified void type.</td>
|
|
<td valign="top" width="16%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9.1p9</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::is_integral<T>::value</code></td>
|
|
<td valign="top" width="26%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is an cv-qualified integral type.</td>
|
|
<td valign="top" width="16%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9.1p7</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::is_float<T>::value</code></td>
|
|
<td valign="top" width="26%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is a cv-qualified floating point type.</td>
|
|
<td valign="top" width="16%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9.1p8</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::is_pointer<T>::value</code></td>
|
|
<td valign="top" width="26%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is cv-qualified pointer type (includes
|
|
function pointers, but excludes pointers to members).</td>
|
|
<td valign="top" width="16%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9.2p2</p>
|
|
<p align="center">8.3.1</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::is_reference<T>::value</code></td>
|
|
<td valign="top" width="26%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is a reference type.</td>
|
|
<td valign="top" width="16%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9.2</p>
|
|
<p align="center">8.3.2</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0">If the
|
|
compiler does not support partial-specialization of class
|
|
templates, then references to types that are both const
|
|
and volatile qualified will not be correctly identified.</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::is_member_pointer<T>::value</code></td>
|
|
<td valign="top" width="26%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is a cv-qualified pointer to a data-member
|
|
or member-function.</td>
|
|
<td valign="top" width="16%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9.2</p>
|
|
<p align="center">8.3.3</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0">On some
|
|
compilers, member function pointers may be incorrectly
|
|
identified as regular pointers.</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::is_array<T>::value</code></td>
|
|
<td valign="top" width="26%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is an array type.</td>
|
|
<td valign="top" width="16%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9.2</p>
|
|
<p align="center">8.3.4</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0">If the
|
|
compiler does not support partial-specialization of class
|
|
templates, then some types may be incorrectly identified
|
|
as arrays (mainly function types).</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::is_union<T>::value</code></td>
|
|
<td valign="top" width="26%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is of union type. Currently requires
|
|
some kind of compiler support, otherwise unions are
|
|
identified as classes.</td>
|
|
<td valign="top" width="16%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9.2</p>
|
|
<p align="center">9.5</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0">C</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::is_class<T>::value</code></td>
|
|
<td valign="top" width="26%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is of class/struct type.</td>
|
|
<td valign="top" width="16%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9.2</p>
|
|
<p align="center">9.2</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0">C</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::is_enum<T>::value</code></td>
|
|
<td valign="top" width="26%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is of enum type.</td>
|
|
<td valign="top" width="16%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9.2</p>
|
|
<p align="center">7.2</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0">Requires a
|
|
correctly functioning is_convertible template (this means
|
|
that is_enum is currently broken under Borland C++).</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td> </td>
|
|
<td valign="top" bgcolor="#C0C0C0"><code>::boost::is_function<T>::value</code></td>
|
|
<td valign="top" bgcolor="#C0C0C0">Evaluates to true only
|
|
if T is a function type (note not a reference or pointer
|
|
to function).</td>
|
|
<td valign="top" bgcolor="#C0C0C0"><p align="center">3.9.2p1</p>
|
|
<p align="center">8.3.5</p>
|
|
</td>
|
|
<td valign="top" bgcolor="#C0C0C0">Without partial
|
|
specialisation support, this template does not compile
|
|
for reference types.</td>
|
|
<td> </td>
|
|
</tr>
|
|
</table>
|
|
|
|
<p> </p>
|
|
|
|
<h2><a name="secondary"></a>Secondary Type Categorisation</h2>
|
|
|
|
<p>The following type categories are made up of the union of one
|
|
or more primary type categorisations. A type may belong to more
|
|
than one of these categories, in addition to one of the primary
|
|
categories.</p>
|
|
|
|
<table border="0" cellpadding="7" cellspacing="1" width="100%">
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="24%" bgcolor="#008080"><p
|
|
align="center">Expression</p>
|
|
</td>
|
|
<td valign="top" width="26%" bgcolor="#008080"><p
|
|
align="center">Description</p>
|
|
</td>
|
|
<td valign="top" width="15%" bgcolor="#008080"><p
|
|
align="center">Reference</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#008080"><p
|
|
align="center">Compiler requirements</p>
|
|
</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="24%" bgcolor="#C0C0C0"><code>::boost::is_arithmetic<T>::value</code></td>
|
|
<td valign="top" width="26%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is a cv-qualified arithmetic type. That
|
|
is either an integral or floating point type.</td>
|
|
<td valign="top" width="15%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9.1p8</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="24%" bgcolor="#C0C0C0"><code>::boost::is_fundamental<T>::value</code></td>
|
|
<td valign="top" width="26%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is an cv-qualified fundamental type.
|
|
That is either an integral, a floating point, or a void
|
|
type.</td>
|
|
<td valign="top" width="15%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9.1</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="24%" bgcolor="#C0C0C0"><code>::boost::is_object<T>::value</code></td>
|
|
<td valign="top" width="26%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is a cv-qualified object type. That is
|
|
not a function, reference, or void type.</td>
|
|
<td valign="top" width="15%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9p9</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="24%" bgcolor="#C0C0C0"><code>::boost::is_scalar<T>::value</code></td>
|
|
<td valign="top" width="26%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is cv-qualified scalar type. That is an
|
|
arithmetic, a pointer or a pointer to member type.</td>
|
|
<td valign="top" width="15%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9p10</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="24%" bgcolor="#C0C0C0"><code>::boost::is_compound<T>::value</code></td>
|
|
<td valign="top" width="26%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is a compound type. That is an array,
|
|
function, pointer, reference, enumerator, union, class or
|
|
member function type.</td>
|
|
<td valign="top" width="15%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9.2</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
</table>
|
|
|
|
<p> </p>
|
|
|
|
<h2><a name="properties"></a>Type Properties</h2>
|
|
|
|
<p>The following templates identify the properties that a type
|
|
has.</p>
|
|
|
|
<table border="0" cellpadding="7" cellspacing="1" width="100%">
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#008080"><p
|
|
align="center">Expression</p>
|
|
</td>
|
|
<td valign="top" width="28%" bgcolor="#008080"><p
|
|
align="center">Description</p>
|
|
</td>
|
|
<td valign="top" width="13%" bgcolor="#008080"><p
|
|
align="center">Reference</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#008080"><p
|
|
align="center">Compiler requirements</p>
|
|
</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::alignment_of<T>::value</code></td>
|
|
<td valign="top" width="28%" bgcolor="#C0C0C0">Identifies
|
|
the alignment requirements of T. Actually returns a value
|
|
that is only guaranteed to be a multiple of the actual
|
|
alignment requirements of T</td>
|
|
<td valign="top" width="13%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::is_empty<T>::value</code></td>
|
|
<td valign="top" width="28%" bgcolor="#C0C0C0">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. </td>
|
|
<td valign="top" width="13%" bgcolor="#C0C0C0"><p
|
|
align="center">10p5</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"><p
|
|
align="center">PCD</p>
|
|
</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::is_const<T>::value</code></td>
|
|
<td valign="top" width="28%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is top-level const-qualified.</td>
|
|
<td valign="top" width="13%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9.3</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::is_volatile<T>::value</code></td>
|
|
<td valign="top" width="28%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is volatile-qualified.</td>
|
|
<td valign="top" width="13%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9.3</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::is_POD<T>::value</code></td>
|
|
<td valign="top" width="28%" bgcolor="#C0C0C0">Evaluates
|
|
to true only if T is a cv-qualified POD type.</td>
|
|
<td valign="top" width="13%" bgcolor="#C0C0C0"><p
|
|
align="center">3.9p10</p>
|
|
<p align="center">9p4</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::has_trivial_constructor<T>::value</code></td>
|
|
<td valign="top" width="28%" bgcolor="#C0C0C0">True if T
|
|
has a trivial default constructor - that is T() is
|
|
equivalent to memset.</td>
|
|
<td valign="top" width="13%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"><p
|
|
align="center">PC</p>
|
|
</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::has_trivial_copy<T>::value</code></td>
|
|
<td valign="top" width="28%" bgcolor="#C0C0C0">True if T
|
|
has a trivial copy constructor - that is T(const T&)
|
|
is equivalent to memcpy.</td>
|
|
<td valign="top" width="13%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"><p
|
|
align="center">PC</p>
|
|
</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::has_trivial_assign<T>::value</code></td>
|
|
<td valign="top" width="28%" bgcolor="#C0C0C0">True if T
|
|
has a trivial assignment operator - that is if T::operator=(const
|
|
T&) is equivalent to memcpy.</td>
|
|
<td valign="top" width="13%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"><p
|
|
align="center">PC</p>
|
|
</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::has_trivial_destructor<T>::value</code></td>
|
|
<td valign="top" width="28%" bgcolor="#C0C0C0">True if T
|
|
has a trivial destructor - that is if T::~T() has no
|
|
effect.</td>
|
|
<td valign="top" width="13%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"><p
|
|
align="center">PC</p>
|
|
</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
</table>
|
|
|
|
<p> </p>
|
|
|
|
<h2><a name="relationships"></a>Relationships Between Types</h2>
|
|
|
|
<p>The following templates determine the whether there is a
|
|
relationship between two types:</p>
|
|
|
|
<table border="0" cellpadding="7" cellspacing="1" width="100%">
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#008080"><p
|
|
align="center">Expression</p>
|
|
</td>
|
|
<td valign="top" width="27%" bgcolor="#008080"><p
|
|
align="center">Description</p>
|
|
</td>
|
|
<td valign="top" width="15%" bgcolor="#008080"><p
|
|
align="center">Reference</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#008080"><p
|
|
align="center">Compiler requirements</p>
|
|
</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><div
|
|
align="center"><center><pre><code>::boost::is_same<T,U>::value</code></pre>
|
|
</center></div></td>
|
|
<td valign="top" width="27%" bgcolor="#C0C0C0"><p
|
|
align="center">Evaluates to true if T and U are the same
|
|
type.</p>
|
|
</td>
|
|
<td valign="top" width="15%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0"> </td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::is_convertible<T,U>::value</code></td>
|
|
<td valign="top" width="27%" bgcolor="#C0C0C0">Evaluates
|
|
to true if type T is convertible to type U.</td>
|
|
<td valign="top" width="15%" bgcolor="#C0C0C0"><p
|
|
align="center">4</p>
|
|
<p align="center">8.5</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#C0C0C0">Note that
|
|
this template is currently broken with Borland's
|
|
compiler, for constructor-based conversions.</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
</table>
|
|
|
|
<p> </p>
|
|
|
|
<h2><a name="transformations"></a>Transformations Between Types</h2>
|
|
|
|
<p>The following templates transform one type to another, based
|
|
upon some well-defined rule. Each template has a single member
|
|
called <i>type</i> that is the result of applying the
|
|
transformation to the template argument T:</p>
|
|
|
|
<table border="0" cellpadding="7" cellspacing="1" width="100%">
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#008080"><p
|
|
align="center">Expression</p>
|
|
</td>
|
|
<td valign="top" width="28%" bgcolor="#008080"><p
|
|
align="center">Description</p>
|
|
</td>
|
|
<td valign="top" width="13%" bgcolor="#008080"><p
|
|
align="center">Reference</p>
|
|
</td>
|
|
<td valign="top" width="25%" bgcolor="#008080"><p
|
|
align="center">Compiler requirements</p>
|
|
</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::remove_const<T>::type</code></td>
|
|
<td valign="top" width="28%" bgcolor="#C0C0C0">Creates a
|
|
type the same as T but with any top level const qualifier
|
|
removed. For example "const int" would become
|
|
"int", but "const int*" would remain
|
|
unchanged.</td>
|
|
<td valign="top" width="13%" bgcolor="#C0C0C0">3.9.3</td>
|
|
<td width="25%" bgcolor="#C0C0C0"><p align="center">P</p>
|
|
</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::remove_volatile<T>::type</code></td>
|
|
<td valign="top" width="28%" bgcolor="#C0C0C0">Creates a
|
|
type the same as T but with any top level volatile
|
|
qualifier removed. For example "volatile int"
|
|
would become "int".</td>
|
|
<td valign="top" width="13%" bgcolor="#C0C0C0"><p
|
|
align="left">3.9.3</p>
|
|
</td>
|
|
<td width="25%" bgcolor="#C0C0C0"><p align="center">P</p>
|
|
</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td> </td>
|
|
<td bgcolor="#C0C0C0"><code>::boost::remove_cv<T>::type</code></td>
|
|
<td bgcolor="#C0C0C0">Creates a type the same as T but
|
|
with any top level cv-qualifiers removed. For example
|
|
"const volatile int" would become "int".</td>
|
|
<td bgcolor="#C0C0C0">3.9.3</td>
|
|
<td bgcolor="#C0C0C0"><p align="center">P</p>
|
|
</td>
|
|
<td> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::remove_reference<T>::type</code></td>
|
|
<td valign="top" width="28%" bgcolor="#C0C0C0">If T is a
|
|
reference type then removes the reference, otherwise
|
|
leaves T unchanged. For example "int&"
|
|
becomes "int" but "int*" remains
|
|
unchanged.</td>
|
|
<td valign="top" width="13%" bgcolor="#C0C0C0">8.3.2</td>
|
|
<td width="25%" bgcolor="#C0C0C0"><p align="center">P</p>
|
|
</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::remove_bounds<T>::type</code></td>
|
|
<td valign="top" width="28%" bgcolor="#C0C0C0">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]".</td>
|
|
<td valign="top" width="13%" bgcolor="#C0C0C0">8.3.4</td>
|
|
<td width="25%" bgcolor="#C0C0C0"><p align="center">P</p>
|
|
</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::remove_pointer<T>::type</code></td>
|
|
<td valign="top" width="28%" bgcolor="#C0C0C0">If T is a
|
|
pointer type, then removes the top-level indirection from
|
|
T, otherwise leaves T unchanged. For example "int*"
|
|
becomes "int", but "int&" remains
|
|
unchanged.</td>
|
|
<td valign="top" width="13%" bgcolor="#C0C0C0">8.3.1</td>
|
|
<td width="25%" bgcolor="#C0C0C0"><p align="center">P</p>
|
|
</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::add_reference<T>::type</code></td>
|
|
<td valign="top" width="28%" bgcolor="#C0C0C0">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&".</td>
|
|
<td valign="top" width="13%" bgcolor="#C0C0C0">8.3.2</td>
|
|
<td width="25%" bgcolor="#C0C0C0"><p align="center">P</p>
|
|
</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="5%"> </td>
|
|
<td valign="top" width="23%" bgcolor="#C0C0C0"><code>::boost::add_pointer<T>::type</code></td>
|
|
<td valign="top" width="28%" bgcolor="#C0C0C0">If "t"
|
|
is an instance of T, then add_pointer<T>::type is
|
|
the type returned by "&t". For example
|
|
"int", "int&", "int[2]"
|
|
and "int (&)[2]" all become "int*".</td>
|
|
<td valign="top" width="13%" bgcolor="#C0C0C0">8.3.1</td>
|
|
<td width="25%" bgcolor="#C0C0C0"><p align="center">P</p>
|
|
</td>
|
|
<td valign="top" width="5%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td> </td>
|
|
<td valign="top" bgcolor="#C0C0C0"><code>::boost::add_const<T>::type</code></td>
|
|
<td valign="top" bgcolor="#C0C0C0">The same as "T
|
|
const" for all T.</td>
|
|
<td valign="top" bgcolor="#C0C0C0">3.9.3</td>
|
|
<td valign="top" bgcolor="#C0C0C0"> </td>
|
|
<td> </td>
|
|
</tr>
|
|
<tr>
|
|
<td> </td>
|
|
<td valign="top" bgcolor="#C0C0C0"><code>::boost::add_volatile<T>::type</code></td>
|
|
<td valign="top" bgcolor="#C0C0C0">The same as "T
|
|
volatile" for all T.</td>
|
|
<td valign="top" bgcolor="#C0C0C0">3.9.3</td>
|
|
<td valign="top" bgcolor="#C0C0C0"> </td>
|
|
<td> </td>
|
|
</tr>
|
|
</table>
|
|
|
|
<p>As the table above indicates, support for partial
|
|
specialization of class templates is required to correctly
|
|
implement the type transformation templates. On the other hand,
|
|
practice shows that many of the templates from this category are
|
|
very useful, and often essential for implementing some generic
|
|
libraries. Lack of these templates is often one of the major
|
|
limiting factors in porting those libraries to compilers that do
|
|
not yet support this language feature. As some of these compilers
|
|
are going to be around for a while, and at least one of them is
|
|
very wide-spread, it was decided that the library should provide
|
|
workarounds where possible. The basic idea behind the workaround
|
|
is</p>
|
|
|
|
<ol>
|
|
<li>To manually define full specializations of all type
|
|
transformation templates for all fundamental types, and
|
|
all their 1st and 2nd rank cv-[un]qualified derivative
|
|
pointer types, and to</li>
|
|
<li>Provide a user-level macro that will define such explicit
|
|
specializations for any user-defined type T.</li>
|
|
</ol>
|
|
|
|
<p>The first part guarantees the successful compilation of
|
|
something like this:</p>
|
|
|
|
<pre>BOOST_STATIC_ASSERT((is_same<char, remove_reference<char&>::type>::value));</pre>
|
|
|
|
<pre>BOOST_STATIC_ASSERT((is_same<char const, remove_reference<char const&>::type>::value));</pre>
|
|
|
|
<pre>BOOST_STATIC_ASSERT((is_same<char volatile, remove_reference<char volatile&>::type>::value));</pre>
|
|
|
|
<pre>BOOST_STATIC_ASSERT((is_same<char const volatile, remove_reference<char const volatile&>::type>::value));</pre>
|
|
|
|
<pre>BOOST_STATIC_ASSERT((is_same<char*, remove_reference<char*&>::type>::value));</pre>
|
|
|
|
<pre>BOOST_STATIC_ASSERT((is_same<char const*, remove_reference<char const*&>::type>::value));</pre>
|
|
|
|
<pre>...</pre>
|
|
|
|
<pre>BOOST_STATIC_ASSERT((is_same<char const volatile* const volatile* const volatile, remove_reference<char const volatile* const volatile* const volatile&>::type>::value));</pre>
|
|
|
|
<p>and the second part provides library's users with a mechanism
|
|
to make the above code work not only for 'char', 'int' or other
|
|
built-in type, but for they own types too:</p>
|
|
|
|
<pre>struct my {};</pre>
|
|
|
|
<pre>BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(my)</pre>
|
|
|
|
<pre>BOOST_STATIC_ASSERT((is_same<my, remove_reference<my&>::type>::value));</pre>
|
|
|
|
<pre>BOOST_STATIC_ASSERT((is_same<my, remove_const<my const>::type>::value));</pre>
|
|
|
|
<pre>// etc.</pre>
|
|
|
|
<p>Note that the macro
|
|
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION evaluates to
|
|
nothing on those compilers that do support partial specialization.</p>
|
|
|
|
<h2><a name="compiler"></a>Compiler Support Information</h2>
|
|
|
|
<p>The legends used in the tables above have the following
|
|
meanings:</p>
|
|
|
|
<table border="0" cellpadding="7" cellspacing="0" width="480">
|
|
<tr>
|
|
<td valign="top" width="50%"><p align="center">P</p>
|
|
</td>
|
|
<td valign="top" width="90%">Denotes that the class
|
|
requires support for partial specialization of class
|
|
templates to work correctly.</td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="50%"><p align="center">C</p>
|
|
</td>
|
|
<td valign="top" width="90%">Denotes that direct compiler
|
|
support for that traits class is required.</td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="50%"><p align="center">D</p>
|
|
</td>
|
|
<td valign="top" width="90%">Denotes that the traits
|
|
class is dependent upon a class that requires direct
|
|
compiler support.</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<p> </p>
|
|
|
|
<p>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 or T is a compiler-supplied scalar type
|
|
that is not specialised for in these type traits.</p>
|
|
|
|
<p><i>If there is no compiler support</i>, to ensure that these
|
|
traits <i>always</i> return the correct values, specialise
|
|
'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 <i>not</i> a POD.</p>
|
|
|
|
<p>The following rules are automatically enforced:</p>
|
|
|
|
<p>is_enum implies is_POD</p>
|
|
|
|
<p>is_POD implies has_*</p>
|
|
|
|
<p>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.</p>
|
|
|
|
<h2><a name="headers"></a>Type Traits Headers</h2>
|
|
|
|
<p>The type traits library is normally included with:</p>
|
|
|
|
<p>#include <boost/type_traits.hpp></p>
|
|
|
|
<p>However the library is actually split up into a number of
|
|
smaller headers, sometimes it can be convenient to include one of
|
|
these directly in order to get just those type traits classes you
|
|
actually need. Note however that the type traits classes are
|
|
highly interdependent - so you may not save as much as you think
|
|
this way. The following table lists the type traits classes in
|
|
alphabetical order, along with the header that contains each
|
|
template.</p>
|
|
|
|
<table border="0" cellpadding="7" cellspacing="1" width="100%">
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#008080">Template
|
|
class</td>
|
|
<td valign="top" width="41%" bgcolor="#008080">Header</td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td> </td>
|
|
<td valign="top" bgcolor="#C0C0C0"><code>add_const</code></td>
|
|
<td valign="top" bgcolor="#C0C0C0"><code><boost/type_traits/transform_traits.hpp></code></td>
|
|
<td> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>add_pointer</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/transform_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>add_reference</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/transform_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td> </td>
|
|
<td valign="top" bgcolor="#C0C0C0"><code>add_volatile</code></td>
|
|
<td valign="top" bgcolor="#C0C0C0"><code><boost/type_traits/transform_traits.hpp></code></td>
|
|
<td> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>alignment_of</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost.type_traits/alignment_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>has_trivial_assign</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/object_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>has_trivial_constructor</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/object_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>has_trivial_copy</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/object_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>has_trivial_destructor</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/object_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_arithmetic</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/arithmetic_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_array
|
|
</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/composite_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_class</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/object_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_compound</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/object_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_const</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/cv_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_convertible</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/conversion_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_empty</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/object_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_enum</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/composite_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_float</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/arithmetic_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td> </td>
|
|
<td valign="top" bgcolor="#C0C0C0"><code>is_function</code></td>
|
|
<td valign="top" bgcolor="#C0C0C0"><code><boost/type_traits/function_traits.hpp></code></td>
|
|
<td> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_fundamental</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/arithmetic_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_integral</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/arithmetic_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_member_pointer</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/composite_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_object
|
|
</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/object_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_POD</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/object_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_pointer</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/composite_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_reference</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/composite_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_same</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/same_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_scalar</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/object_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_union</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/composite_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_void</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/arithmetic_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>is_volatile</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/cv_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>remove_bounds</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/transform_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>remove_const</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/cv_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>remove_cv</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/cv_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>remove_pointer</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/transform_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>remove_reference
|
|
</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/transform_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
<tr>
|
|
<td valign="top" width="7%"> </td>
|
|
<td valign="top" width="43%" bgcolor="#C0C0C0"><code>remove_volatile</code></td>
|
|
<td valign="top" width="41%" bgcolor="#C0C0C0"><code><boost/type_traits/cv_traits.hpp></code></td>
|
|
<td valign="top" width="9%"> </td>
|
|
</tr>
|
|
</table>
|
|
|
|
<p> </p>
|
|
|
|
<h2>Example code</h2>
|
|
|
|
<p>Type-traits comes with four example programs that illustrate
|
|
some of the ways in which the type traits templates may be used:</p>
|
|
|
|
<h4>Copy_example.cpp</h4>
|
|
|
|
<p>Demonstrates a version of std::copy that uses memcpy where
|
|
appropriate to optimise the copy operation;</p>
|
|
|
|
<pre>//
|
|
// opt::copy
|
|
// same semantics as std::copy
|
|
// calls memcpy where appropiate.
|
|
//
|
|
|
|
namespace detail{
|
|
|
|
template<typename I1, typename I2>
|
|
I2 copy_imp(I1 first, I1 last, I2 out)
|
|
{
|
|
while(first != last)
|
|
{
|
|
*out = *first;
|
|
++out;
|
|
++first;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
template <bool b>
|
|
struct copier
|
|
{
|
|
template<typename I1, typename I2>
|
|
static I2 do_copy(I1 first, I1 last, I2 out)
|
|
{ return copy_imp(first, last, out); }
|
|
};
|
|
|
|
template <>
|
|
struct copier<true>
|
|
{
|
|
template<typename I1, typename I2>
|
|
static I2* do_copy(I1* first, I1* last, I2* out)
|
|
{
|
|
memcpy(out, first, (last-first)*sizeof(I2));
|
|
return out+(last-first);
|
|
}
|
|
};
|
|
|
|
|
|
}
|
|
|
|
template<typename I1, typename I2>
|
|
inline I2 copy(I1 first, I1 last, I2 out)
|
|
{
|
|
typedef typename boost::remove_cv<typename std::iterator_traits<I1>::value_type>::type v1_t;
|
|
typedef typename boost::remove_cv<typename std::iterator_traits<I2>::value_type>::type v2_t;
|
|
return detail::copier<
|
|
::boost::type_traits::ice_and<
|
|
::boost::is_same<v1_t, v2_t>::value,
|
|
::boost::is_pointer<I1>::value,
|
|
::boost::is_pointer<I2>::value,
|
|
::boost::has_trivial_assign<v1_t>::value
|
|
>::value>::do_copy(first, last, out);
|
|
}</pre>
|
|
|
|
<h4>fill_example.cpp</h4>
|
|
|
|
<p>Demonstrates a version of std::fill that uses memset where
|
|
appropriate to optimise fill operations. Also uses call_traits to
|
|
optimise parameter passing, to avoid aliasing issues:</p>
|
|
|
|
<pre>namespace opt{
|
|
//
|
|
// fill
|
|
// same as std::fill, uses memset where appropriate, along with call_traits
|
|
// to "optimise" parameter passing.
|
|
//
|
|
namespace detail{
|
|
|
|
template <typename I, typename T>
|
|
void do_fill_(I first, I last, typename boost::call_traits<T>::param_type val)
|
|
{
|
|
while(first != last)
|
|
{
|
|
*first = val;
|
|
++first;
|
|
}
|
|
}
|
|
|
|
template <bool opt>
|
|
struct filler
|
|
{
|
|
template <typename I, typename T>
|
|
struct rebind
|
|
{
|
|
static void do_fill(I first, I last, typename boost::call_traits<T>::param_type val)
|
|
{ do_fill_<I,T>(first, last, val); }
|
|
};
|
|
};
|
|
|
|
template <>
|
|
struct filler<true>
|
|
{
|
|
template <typename I, typename T>
|
|
struct rebind
|
|
{
|
|
static void do_fill(I first, I last, T val)
|
|
{
|
|
std::memset(first, val, last-first);
|
|
}
|
|
};
|
|
};
|
|
|
|
}
|
|
|
|
template <class I, class T>
|
|
inline void fill(I first, I last, const T& val)
|
|
{
|
|
typedef detail::filler<
|
|
::boost::type_traits::ice_and<
|
|
::boost::is_pointer<I>::value,
|
|
::boost::is_arithmetic<T>::value,
|
|
(sizeof(T) == 1)
|
|
>::value> filler_t;
|
|
typedef typename filler_t:: template rebind<I,T> binder;
|
|
binder::do_fill(first, last, val);
|
|
}
|
|
|
|
}; // namespace opt</pre>
|
|
|
|
<h4>iter_swap_example.cpp</h4>
|
|
|
|
<p>Demonstrates a version of std::iter_swap that works with
|
|
proxying iterators, as well as regular ones; calls std::swap for
|
|
regular iterators, otherwise does a "slow but safe"
|
|
swap:</p>
|
|
|
|
<pre>namespace opt{
|
|
//
|
|
// iter_swap:
|
|
// tests whether iterator is a proxying iterator or not, and
|
|
// uses optimal form accordingly:
|
|
//
|
|
namespace detail{
|
|
|
|
template <bool b>
|
|
struct swapper
|
|
{
|
|
template <typename I>
|
|
static void do_swap(I one, I two)
|
|
{
|
|
typedef typename std::iterator_traits<I>::value_type v_t;
|
|
v_t v = *one;
|
|
*one = *two;
|
|
*two = v;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct swapper<true>
|
|
{
|
|
template <typename I>
|
|
static void do_swap(I one, I two)
|
|
{
|
|
using std::swap;
|
|
swap(*one, *two);
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
template <typename I1, typename I2>
|
|
inline void iter_swap(I1 one, I2 two)
|
|
{
|
|
typedef typename std::iterator_traits<I1>::reference r1_t;
|
|
typedef typename std::iterator_traits<I2>::reference r2_t;
|
|
detail::swapper<
|
|
::boost::type_traits::ice_and<
|
|
::boost::is_reference<r1_t>::value,
|
|
::boost::is_reference<r2_t>::value,
|
|
::boost::is_same<r1_t, r2_t>::value
|
|
>::value>::do_swap(one, two);
|
|
}
|
|
|
|
}; // namespace opt</pre>
|
|
|
|
<h4>Trivial_destructor_example.cpp</h4>
|
|
|
|
<p>This algorithm is the reverse of std::unitialized_copy; it
|
|
takes a block of initialized memory and calls destructors on all
|
|
objects therein. This would typically be used inside container
|
|
classes that manage their own memory:</p>
|
|
|
|
<pre>namespace opt{
|
|
//
|
|
// algorithm destroy_array:
|
|
// The reverse of std::unitialized_copy, takes a block of
|
|
// initialized memory and calls destructors on all objects therein.
|
|
//
|
|
|
|
namespace detail{
|
|
|
|
template <bool>
|
|
struct array_destroyer
|
|
{
|
|
template <class T>
|
|
static void destroy_array(T* i, T* j){ do_destroy_array(i, j); }
|
|
};
|
|
|
|
template <>
|
|
struct array_destroyer<true>
|
|
{
|
|
template <class T>
|
|
static void destroy_array(T*, T*){}
|
|
};
|
|
|
|
template <class T>
|
|
void do_destroy_array(T* first, T* last)
|
|
{
|
|
while(first != last)
|
|
{
|
|
first->~T();
|
|
++first;
|
|
}
|
|
}
|
|
|
|
}; // namespace detail
|
|
|
|
template <class T>
|
|
inline void destroy_array(T* p1, T* p2)
|
|
{
|
|
detail::array_destroyer<boost::has_trivial_destructor<T>::value>::destroy_array(p1, p2);
|
|
}
|
|
} // namespace opt</pre>
|
|
|
|
<hr>
|
|
|
|
<p>Revised 22 April 2001</p>
|
|
|
|
<p>Documentation � Copyright John Maddock 2001. 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.</p>
|
|
|
|
<p>The type traits library is based on contributions by Steve
|
|
Cleary, Beman Dawes, Aleksey Gurtovoy, Howard Hinnant, Jesse
|
|
Jones, Mat Marcus, John Maddock and Jeremy Siek.</p>
|
|
|
|
<p>Mat Marcus and Jesse Jones have worked on, and published a <a
|
|
href="http://opensource.adobe.com/project4/project.shtml">paper</a>
|
|
describing the partial specialisation workarounds used in this
|
|
library.</p>
|
|
|
|
<p>The is_convertible template is based on code originally
|
|
devised by Andrei Alexandrescu, see "<a
|
|
href="http://www.cuj.com/experts/1810/alexandr.htm?topic=experts">Generic<Programming>:
|
|
Mappings between Types and Values</a>".</p>
|
|
|
|
<p>Maintained by <a href="../../people/john_maddock.htm">John
|
|
Maddock</a>, the latest version of this file can be found at <a
|
|
href="http://www.boost.org/">www.boost.org</a>, and the boost
|
|
discussion list at <a
|
|
href="http://www.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost</a>.</p>
|
|
</body>
|
|
</html>
|