mirror of
https://github.com/boostorg/type_traits.git
synced 2026-01-27 19:32:13 +00:00
1203 lines
48 KiB
HTML
1203 lines
48 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/detail/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/detail/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> </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-specialisation 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-specialisation 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>
|
||
</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="center">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 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>
|
||
</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 maco
|
||
BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION evaluates to
|
||
nothing on those compilers that do support partial specialisation.</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 specialisation 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 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 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 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 01 Feb 2001</p>
|
||
|
||
<p><EFBFBD> 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, John
|
||
Maddock and Jeremy Siek.</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.egroups.com/list/boost">www.egroups.com/list/boost</a>.</p>
|
||
</body>
|
||
</html>
|