<html>

<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<meta name="Version" content="8.0.3410">
<meta name="Date" content="10/11/96">
<meta name="Template"
content="C:\Program Files\Microsoft Office\Office\HTML.DOT">
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
<title>Type Traits Proposal (J16/02-0003 WG21/N1345)</title>
</head>

<body bgcolor="#FFFFFF" text="#000000" link="#0000FF"
vlink="#800080">

<h1>A Proposal to add Type Traits to the Standard Library</h1>

<p>Doc. no.: J16/02-0003 = WG21/N1345<br>
Date: 07 March 2002<br>
Project: Programming Language C++ <br>
Wiki: <a
href="http://www.research.att.com/~austern/cgi-bin/wiki?TypeTraits">http://www.research.att.com/~austern/cgi-bin/wiki?TypeTraits</a><br>
Reply to: John Maddock &lt;<a
href="mailto:john_maddock@compuserve.com"><font color="#0000FF"><em>john_maddock@compuserve.com</em></font></a>&gt;
</p>

<h2>I. Motivation </h2>

<p>This proposal forms part of the &quot;infrastructure&quot; of
the standard library; it attempts to standardize templates that
are often reinvented as bespoke solutions. These templates may be
used by the end user, and are often used heavily by library
implementers, including those who are writing third party
libraries. There are three main use cases that help explain the
motivation behind this proposal:</p>

<h5>a) Supporting the widest possible range of types</h5>

<p>Sometimes templates are not quite as &quot;generic&quot; as
one would wish. The problem is that not all types are created
equally, implying that some categories of types may need special
handling. One example of this is a version of std::pair that can
hold reference types[<a href="#ref1">1</a>]. The boost
compressed_pair class[<a href="#ref2">2</a>] is a more advanced
example of this; as well as being able to hold reference types,
it will inherit from, rather than contain, empty classes in order
to take advantage of the &quot;zero sized base class optimisation&quot;.</p>

<h5>b) For use with static (compile time) assertions</h5>

<p>Often there is a contract that the template parameters to a
class or function must obey. Usually if the template argument
does not conform to the contract then the template will fail to
compile. Often in such cases the position of the error may be
deep inside several layers of template code, and it is often not
at all easy for the user to deduce what the problem is, and
whether it is their problem or the library's. One solution
proposed for this is the idea of concept-checks[<a href="#ref3">3</a>],
however a simpler solution is often possible using a static
assertion[<a href="#ref4">4</a>]. For example the following code
uses the boost type traits library to insist that the iterator
arguments have random access semantics; if an error occurs then
it will be generated early on in the procedure being
instantiated, and can be commented with a description of the
problem:</p>

<pre>#include &lt;iterator&gt;
#include &lt;boost/static_assert.hpp&gt; 
#include &lt;boost/type_traits.hpp&gt; 

template &lt;class RandomAccessIterator &gt; 
RandomAccessIterator foo(RandomAccessIterator from, 
                         RandomAccessIterator to) 
{ 
   // this template can only be used with 
   // random access iterators, attempting to
   // use some other iterator type will result in
   // an error message here: 
   typedef typename std::iterator_traits
           &lt;RandomAccessIterator&gt;::iterator_category cat; 

   typedef int this_is_a_static_assertion[
         ::boost::is_convertible&lt;
             cat*, 
             std::random_access_iterator_tag*
         &gt;::value ? 1 : -1]; 
   // 
   // detail goes here... 
   //
   return from; 
}</pre>

<p>Static assertions do not form part of this proposal, however
they could easily form part of another proposal.</p>

<h5>c) Optimising code performance.</h5>

<p>The classic <a href="#Copy_example_code">example</a> here is
the algorithm <code>std::copy</code>; if the types being copied
are POD's, then <code>std::memcpy</code> can be used to copy the
data, rather than a slower &quot;object by object&quot; copy. The
boost library has one example of this approach[<a href="#ref1">1</a>].
However this is by no means the only example: the SGI standard
library[<a href="#ref7">7</a>] uses a type traits mechanism to
achieve the same effect, while the Dinkumware standard library
uses a function overloading approach to dispatch to the correct <code>std::copy
</code>implementation. The fact that several vendors have
reinvented this technique suggests that this is an area ripe for
standardisation. It should be noted that while it is easiest to
give examples of traits-based optimisations from the standard
library, both third party libraries and user code can (and do)
make use of these techniques. In the boost libraries for example,
17 of 57 top level headers make use of boost's type traits code
either directly or indirectly.</p>

<h2>II. Impact on the Standard</h2>

<p>This is basically a pure extension, it does not require any
modification to existing standard library headers, and does not
require any core language changes. However some of the templates
listed in this proposal can not be fully implemented without some
help from the compiler. The proposed text does not specify how
this help is provided, and it is possible to provide an
implementation that almost conforms to the semantics given,
without compiler help (see the boost reference implementation[<a
href="#ref5">5</a>]). Those templates that benefit from compiler
help are noted below.</p>

<h2>III. Design</h2>

<p>There are two key design decisions to be made in this proposal:</p>

<h3>Separate classes, or a single monolithic class?</h3>

<p>The boost type traits library (and this proposal) uses a
separate traits class for each <i>trait</i>, where as, for
example, both Loki[<a href="#ref6">6</a>] and the SGI type traits
library[<a href="#ref7">7</a>] use a single type_traits class
with multiple members. There are a number of advantages to the
separate traits class approach:</p>

<ul>
    <li>The library contains traits classes both to describe the
        properties of types, and to transform one type into
        another. There are also many more traits represented here
        than there are in competing libraries that use a single
        &quot;type_traits&quot; class (in other words a single
        class would be overly complex). </li>
    <li>This approach is extensible - it is easy to add new
        traits classes using the methodology shown. This is
        particularly important for type transformations, where
        user defined transformations may be written to extend the
        library. Also new traits that describe type properties
        may be added by refining, combining or extending the
        standard traits provided by this library. In other words
        we define a set of concepts to which each traits class
        must conform. </li>
    <li>Experience suggests that this approach is easier to
        maintain - some of the traits classes described here have
        non-trivial implementations - it is often easier to
        isolate the trickier cases in their own headers for ease
        of maintenance. </li>
    <li>Separate traits classes allow each trait to be isolated
        into a separate header. This proposal splits the traits
        classes into three headers (&lt;type_traits&gt;,
        &lt;type_compare&gt; and &lt;type_transform&gt;), but an
        implementation might use more (internally), to allow
        selective reuse of only those parts of the type traits
        library that are needed for a particular class/function
        implementation. </li>
    <li>Separate traits classes may be used as &quot;compile time
        predicates&quot; to metaprogramming libraries, for
        example with algorithms that operate on type lists[<a
        href="#ref8">8</a>]. </li>
</ul>

<p>Finally it should be noted that Loki's author has shifted away
from a single type_traits class and towards separate classes in a
type_traits namespace[<a href="#ref9">9</a>].</p>

<h3>Are Boolean properties integral-constant expressions or
types?</h3>

<p>The boost type traits library (and this proposal) uses a <code>static
const bool</code> to represent each true/false condition, where
as the SGI type traits library[<a href="#ref7">7</a>] uses a type
(__true_type or __false_type). The use of a type is more
convenient for use with function overloading, however the use of
an integral constant expression makes it much easier to combine
traits using logical expressions - something that has been often
found to be necessary during the development of the boost library.
In addition it is possible to convert a value to a type more
easily than a type can be converted to a value. In most cases
though conversion to a type should not be necessary - for example
the std::copy optimisation example does not require this:</p>

<pre><a name="Copy_example_code">/</a>/
// copy:
// same semantics as std::copy
// calls memcpy where appropriate.
//

namespace detail{

template &lt;bool b&gt;
struct copier
{
   template&lt;typename I1, typename I2&gt;
   static I2 do_copy(I1 first, I1 last, I2 out)
   {
      while(first != last)
      {
         *out = *first;
         ++out;
         ++first;
      }
      return out;
   }
};

template &lt;&gt;
struct copier&lt;true&gt;
{
   template&lt;typename I1, typename I2&gt;
   static I2* do_copy(I1* first, I1* last, I2* out)
   {
      memcpy(out, first, (last-first)*sizeof(I2));
      return out+(last-first);
   }
};


}

template&lt;typename I1, typename I2&gt;
inline I2 copy(I1 first, I1 last, I2 out)
{
   typedef typename boost::remove_cv&lt;typename std::iterator_traits&lt;I1&gt;::value_type&gt;::type v1_t;
   typedef typename boost::remove_cv&lt;typename std::iterator_traits&lt;I2&gt;::value_type&gt;::type v2_t;
   return detail::copier&lt;
         ::boost::is_same&lt;v1_t, v2_t&gt;::value
         &amp;&amp; ::boost::is_pointer&lt;I1&gt;::value
         &amp;&amp; ::boost::is_pointer&lt;I2&gt;::value
         &amp;&amp; ::boost::has_trivial_assign&lt;v1_t&gt;::value

       &gt;::do_copy(first, last, out);
}</pre>

<p>There is one potential problem with integral constant members
that should be raised: these require an out of line definition as
well as an inline initialisation (but see issues 48 and 82). One
implementation strategy that avoids the problem of having to
provide lots of definitions for these static members, would be to
have the traits classes inherit from a common base class:</p>

<pre>template &lt;bool b&gt; struct boolian_traits{ static const bool value = b; };
template &lt;bool b&gt; bool boolian_traits&lt;b&gt;::value;

typedef boolian_traits&lt;true&gt; true_type;
typedef boolian_traits&lt;false&gt; false_type;

template &lt;class T&gt; struct is_void : public false_type {};
template &lt;&gt; struct is_void&lt;void&gt; : public true_type {};
// etc</pre>

<p>This does not form part of this proposal, and this particular
issue is ignored in the boost library, however there may be
sufficient merit to this scheme to make it worth while adding to
the proposed text. This scheme also makes it trivial to select a
function overload based on whether a traits class inherits from <code>true_type</code>
or <code>false_type</code>.</p>

<h3>Selection of templates</h3>

<p>Perhaps the most difficult part of this proposal is deciding
which traits classes should be included. The boost type traits
library has undergone several revisions, with some templates
being removed and others added. This proposal&nbsp;includes all
of the current boost type traits classes along with a small
number of others that are motivated by Loki[<a href="#ref6">6</a>].
The assumption is that the committee will find it easier to
strike out templates from the proposal, than to add new templates
(although the latter isn't necessarily ruled out). Some specific
comments that have been made include:</p>

<blockquote>
    <p>From Andrei Alexandrescu:</p>
</blockquote>

<blockquote>
    <p>&quot;I understand the symmetry argument for adding
    add_const, add_volatile, add_cv, and add_pointer, however I
    would argue in favor of eliminating them. The language-provided
    equivalents are just simpler and nicer.&quot;</p>
</blockquote>

<p>The names chosen for these templates is inevitably somewhat
arbitrary, it may be that some could be better named:</p>

<blockquote>
    <p>From Howard Hinnant:</p>
</blockquote>

<blockquote>
    <p>&quot;<code>template &lt;class T&gt; struct is_float;</code></p>
</blockquote>

<blockquote>
    <p>I think is_floating is a better name. Since we have a
    built-in type named float, I'm not sure if is_float refers to
    all floating types or just to float. It makes me wonder if
    there is also an is_double. As this library closely mirrors 3.9
    [basic.types], and 3.9.1/8 refers to these types as &quot;floating
    point&quot;, then is_floating_point might be another good
    name.&quot;</p>
</blockquote>

<p>There have been one or two requests that haven't made it into
the proposed text, mainly because these are templates that either
don't sit well into the current design structure, or because
they're usefulness isn't clear. These are documented here in case
the committee wants to discuss and/or add these to the text.</p>

<blockquote>
    <p>From Dave Abrahams:</p>
</blockquote>

<blockquote>
    <p>&quot;Here's another one we need:</p>
</blockquote>

<blockquote>
    <p><code>has_common_base_class&lt;T,U&gt;::value</code></p>
</blockquote>

<blockquote>
    <p>This is the one which allows us to explicitly construct
    empty classes on top of one another. I suppose you could
    argue that the compiler should just do this automatically
    with the empty base optimization, but the ABIs of many
    compilers are now fixed and they will never (for practical
    purposes) be able to do it.&quot;</p>
</blockquote>

<blockquote>
    <p>From Andrei Alexandrescu:</p>
</blockquote>

<blockquote>
    <p>&quot;An important trait that's missing is the
    transformation same_align_pod, which would yield a POD type
    with the same alignment requirements as the passed-in type.
    This type would allow one to build a union that obeys
    specific alignment requirements.&quot;</p>
</blockquote>

<h3>Compiler Support</h3>

<p>The following templates require compiler support in order to
be implemented:</p>

<pre>template &lt;class T&gt; struct is_class;
template &lt;class T&gt; struct is_union;
template &lt;class T&gt; struct is_polymorphic;</pre>

<p>The following template has an implementation that is likely to
be dependent upon the above:</p>

<pre>template &lt;class T&gt; struct is_empty;</pre>

<p>The following templates do not require compiler support in
order to conform to the letter of this proposal, however they
greatly benefit from having such support:</p>

<pre>template &lt;class T&gt; struct has_trivial_constructor;
template &lt;class T&gt; struct has_trivial_copy;
template &lt;class T&gt; struct has_trivial_assign;
template &lt;class T&gt; struct has_trivial_destructor;
template &lt;class T&gt; struct has_nothrow_construct;
template &lt;class T&gt; struct has_nothrow_copy;
template &lt;class T&gt; struct has_nothrow_assign;
template &lt;class T&gt; struct is_POD;
template &lt;class T&gt; struct is_empty;
</pre>

<p>The mechanism of compiler support is not given in the proposal
text, however several people have asked that this be specified,
and there are a number of possibilities for this:</p>

<ol>
    <li>The mechanism is left unspecified - it is up to each
        individual implemention to decide how best to support
        these templates - this option has the disadvantage that
        portable standard library implementations become much
        more difficult than they would otherwise be.</li>
    <li>For each template that requires compiler support, define
        an associated operator (<code>__is_class__</code>, <code>__is_union__</code>
        etc) that returns a Boolean integral constant expression
        giving the value for that trait. The main disadvantage of
        this approach is that which templates have compiler
        support has to be fixed in advance; so for example, we
        can't decide to provide compiler support for <code>is_pointer
        </code>in order to provide extra support for compiler
        specific (and non-standard) pointer types. In addition
        each trait has to be documented twice - once for the
        template class, and once for its associated operator.</li>
    <li>Define a single operator (<code>__traits_of__</code>)
        which returns an integral constant expression bitmask,
        containing the traits of that type. Like option 2, this
        requires duplicating the documentation of each trait.</li>
    <li>Provide compiler support for the traits classes directly:
        when a type traits template is to be instantiated, look
        first for matching full or partial specialisations of
        that template, if none is found and the compiler would
        normally instantiate the primary template, instead
        generate (and use) a full specialisation based on the
        compiler's knowledge of the template and its template
        argument(s). This option allows compiler independence for
        library vendors, while at the same time allowing compiler
        vendors to tailor the extent of their support for type
        traits. This option also has precedent in the way in
        which SGI's compiler handles their <code>__type_traits</code>
        class template.</li>
</ol>

<p>Since it is unclear which (if any) of these options should be
adopted, some guidance from both compiler vendors and library
authors, on the best way to handle type traits compiler support,
would be welcome.</p>

<hr>

<h1 align="center">Proposed Text</h1>

<hr>

<h2>Type Library</h2>

<p>This clause describes components used by C++ programs,
particularly in templates, to: support the widest possible range
of types, to optimise template code usage, and to detect type
related user errors.</p>

<p>The type library provides three facilities: access to the
properties of a particular type, access to the relationships (if
any) between two types, and transformations from one type to
another; as summarised in table TT1</p>

<h6 align="center">Table TT1 - Type Library Summary</h6>
<div align="center"><center>

<table border="1" cellpadding="7" cellspacing="1" width="638">
    <tr>
        <td valign="top" width="50%">Clause</td>
        <td valign="top" width="50%">Header</td>
    </tr>
    <tr>
        <td valign="top" width="50%"><a href="#Requirements">Requirements</a></td>
        <td valign="top" width="50%">&nbsp;</td>
    </tr>
    <tr>
        <td valign="top" width="50%"><a href="#Unary_type_traits">Unary
        type traits</a></td>
        <td valign="top" width="50%">&lt;type_traits&gt;</td>
    </tr>
    <tr>
        <td valign="top" width="50%"><a
        href="#Binary_type_traits">Relationships between types</a></td>
        <td valign="top" width="50%">&lt;type_compare&gt;</td>
    </tr>
    <tr>
        <td valign="top" width="50%"><a
        href="#transformation_traits">Transformations between
        types</a></td>
        <td valign="top" width="50%">&lt;type_transform&gt;</td>
    </tr>
</table>
</center></div>

<p>&nbsp;</p>

<h3><a name="Requirements"></a>Requirements</h3>

<h4>Unary Type Traits</h4>

<p>In table TT2, X is a class template that is a unary type trait
and T is any arbitrary type.</p>

<h6 align="center">Table TT2 - UnaryTypeTrait requirements</h6>
<div align="center"><center>

<table border="1" cellpadding="7" cellspacing="1" width="638">
    <tr>
        <td valign="top" width="33%">Expression</td>
        <td valign="top" width="33%">Return type</td>
        <td valign="top" width="33%">Requirement</td>
    </tr>
    <tr>
        <td valign="top" width="33%">X&lt;T&gt;::value</td>
        <td valign="top" width="33%">bool</td>
        <td valign="top" width="33%">An integral constant
        expression that is true if T has the specified trait, and
        false otherwise.</td>
    </tr>
</table>
</center></div>

<h4>Binary Type Traits</h4>

<p>In table TT3, X is a class template that is a binary type
trait and T and U are any arbitrary types.</p>

<h6 align="center">Table TT3 - BinaryTypeTrait requirements</h6>
<div align="center"><center>

<table border="1" cellpadding="7" cellspacing="1" width="638">
    <tr>
        <td valign="top" width="33%">Expression</td>
        <td valign="top" width="33%">Return type</td>
        <td valign="top" width="33%">Requirement</td>
    </tr>
    <tr>
        <td valign="top" width="33%">X&lt;T,U&gt;::value</td>
        <td valign="top" width="33%">bool</td>
        <td valign="top" width="33%">An integral constant
        expression that is true if T is related to U by the
        relation specified, and false otherwise.</td>
    </tr>
</table>
</center></div>

<h4>Transformation Traits</h4>

<p>In table TT4, X is a class template that is a transformation
trait and T is any arbitrary type.</p>

<h6 align="center">Table TT4 - TransformationTrait requirements</h6>
<div align="center"><center>

<table border="1" cellpadding="7" cellspacing="1" width="421">
    <tr>
        <td valign="top" width="50%">Expression</td>
        <td valign="top" width="50%">Requirement</td>
    </tr>
    <tr>
        <td valign="top" width="50%">X&lt;T&gt;::type</td>
        <td valign="top" width="50%">The result is a type that is
        the result of applying transformation X to type T.</td>
    </tr>
</table>
</center></div>

<p>&nbsp;</p>

<h3><a name="Unary_type_traits"></a>Unary Type Traits</h3>

<p>This sub-clause contains templates that may be used to query
the properties of a type at compile time.</p>

<p>All of the class templates defined in this header satisfy the
UnaryTypeTrait requirements.</p>

<h4>Header &lt;type_traits&gt; synopsis</h4>

<pre>namespace std{

// Primary type categories:
template &lt;class T&gt; struct is_void;
template &lt;class T&gt; struct is_integral;
template &lt;class T&gt; struct is_float;
template &lt;class T&gt; struct is_array;
template &lt;class T&gt; struct is_pointer;
template &lt;class T&gt; struct is_reference;
template &lt;class T&gt; struct is_member_pointer;
template &lt;class T&gt; struct is_enum;
template &lt;class T&gt; struct is_union;
template &lt;class T&gt; struct is_class;
template &lt;class T&gt; struct is_function;

// composite type categories:
template &lt;class T&gt; struct is_arithmetic;
template &lt;class T&gt; struct is_fundamental;
template &lt;class T&gt; struct is_object;
template &lt;class T&gt; struct is_scalar;
template &lt;class T&gt; struct is_compound;

// type properties:
template &lt;class T&gt; struct is_const;
template &lt;class T&gt; struct is_volatile;
template &lt;class T&gt; struct is_POD;
template &lt;class T&gt; struct is_empty;
template &lt;class T&gt; struct is_polymorphic;
template &lt;class T&gt; struct has_trivial_constructor;
template &lt;class T&gt; struct has_trivial_copy;
template &lt;class T&gt; struct has_trivial_assign;
template &lt;class T&gt; struct has_trivial_destructor;
template &lt;class T&gt; struct has_nothrow_construct;
template &lt;class T&gt; struct has_nothrow_copy;
template &lt;class T&gt; struct has_nothrow_assign;

} // namespace std</pre>

<h4><br>
Primary Type Categories</h4>

<p>The primary type categories correspond to the descriptions
given in section 3.9.</p>

<p>For any given type T, exactly one of the primary type
categories shall have its member <code>value</code> evaluate to
true.</p>

<p>For any given type T, the result of applying one of these
templates to <code>T</code>, and to <code>const volatile T</code>
shall yield the same result.</p>

<p>It is unspecified whether any of these templates have any full
or partial specialisations defined. It is permitted for the user
to specialise any of these templates on a user-defined type,
provided the semantics of the specialisation match those given
for the template in its description.</p>

<blockquote>
    <p><font color="#FF0000"><i>Author's Note: Some of these
    templates require help from the compiler, specifically:
    is_union and is_class. However, this list can be trimmed
    down; only one of is_union and is_class need compiler help,
    since the other can then be implemented by a process of
    elimination.</i></font></p>
</blockquote>

<pre>
template &lt;class T&gt; struct is_void {
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if T is void or a cv-qualified
void.</p>

<pre>template &lt;class T&gt; struct is_integral {
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if T is an integral
type (3.9.1).</p>

<pre>template &lt;class T&gt; struct is_float {
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if T is a floating
point type (3.9.1).</p>

<pre>template &lt;class T&gt; struct is_array {
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if T is an array type (3.9.2).</p>

<pre>template &lt;class T&gt; struct is_pointer {
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if T is a pointer type
(3.9.2), this includes all function pointer types, but not
pointers to members or member functions.</p>

<pre>template &lt;class T&gt; struct is_reference {
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if T is a reference
type (3.9.2), this includes all reference to function types.</p>

<pre>template &lt;class T&gt; struct is_member_pointer {
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if T is a pointer to
member or a pointer to member function.</p>

<pre>template &lt;class T&gt; struct is_enum {
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if T is an enumeration
type (3.9.2).</p>

<blockquote>
    <p><font color="#FF0000"><i>Author's Note: It may not be
    immediately obvious how to implement this template without
    compiler help. In fact enumeration types may be detected by
    virtue of the fact that they are not integral types, but do
    have a non-user defined conversion to type </i><code><em><strong>int</strong></em></code><i>
    (see</i><em> boost type_traits implementation[</em></font><a
    href="#ref5"><font color="#FF0000"><em>5</em></font></a><font
    color="#FF0000"><em>]</em><i>).</i></font></p>
</blockquote>

<pre>template &lt;class T&gt; struct is_union {
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if T is a union type (3.9.2).</p>

<blockquote>
    <p><font color="#FF0000"><i>Author's Note: This is the only
    template in this proposal for which there is no known (or
    foreseeable) use; except that it can be used in the
    implementation of is_class, and that its omission would imply
    that there are some types that do not fit into any of the
    categories given.</i></font></p>
</blockquote>

<pre>template &lt;class T&gt; struct is_class {
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if T is a class type (3.9.2).</p>

<pre>template &lt;class T&gt; struct is_function {
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if T is a function type
(3.9.2).</p>

<blockquote>
    <p><font color="#FF0000"><i>[Author's Note- The template
    is_function can be implemented as follows:</i></font></p>
</blockquote>

<blockquote>
    <pre>template &lt;class T&gt; struct is_function{
   static const bool value = !is_convertible&lt;T*, const voilatile void*&gt;::value;
};
template &lt;class T&gt; struct is_function&lt;T&amp;&gt;{
   static const bool value = false;
};</pre>
</blockquote>

<blockquote>
    <p><font color="#FF0000"><i>Function types (as distinct from
    function pointers or references) can be introduced either via
    a typedef or via template argument deduction:</i></font></p>
</blockquote>

<blockquote>
    <pre>#include &lt;cassert&gt;
#include &lt;type_traits&gt;

typedef int function_type(int);

template &lt;class T&gt;
void deduce_function_type(T&amp; t)
{ assert(std::is_function&lt;T&gt;::value); }

void foo(){}

int main()
{
   assert(std::is_function&lt; function_type&gt;::value); 
   deduce_function_type(foo);
   return 0;
}</pre>
</blockquote>

<blockquote>
    <p><font color="#FF0000"><i>- Author's note].</i></font></p>
</blockquote>

<h4>Composite type traits</h4>

<p>These templates provide convenient compositions of the primary
type categories, corresponding to the descriptions given in
section 3.9.</p>

<p>For any given type T, the result of applying one of these
templates to <code>T</code>, and to <code>const volatile T</code>
shall yield the same result.</p>

<p>It is unspecified whether any of these templates have any full
or partial specialisations defined. It is permitted for the user
to specialise any of these templates on a user-defined type,
provided the semantics of the specialisation match those given
for the template in its description.</p>

<pre>template &lt;class T&gt; struct is_arithmetic {
   static const bool value = 
      is_integral&lt;T&gt;::value 
      || is_float&lt;T&gt;::value; 
};</pre>

<p><code>value</code>: defined to be true if T is an arithmetic
type (3.9.1).</p>

<pre>template &lt;class T&gt; struct is_fundamental{
   static const bool value = 
      is_integral&lt;T&gt;::value 
      || is_float&lt;T&gt;::value 
      || is_void&lt;T&gt;::value; 
};</pre>

<p><code>value</code>: defined to be true if T is a fundamental
type (3.9.1).</p>

<pre>template &lt;class T&gt; struct is_object{
   static const bool value = 
      !(is_function&lt;T&gt;::value 
         || is_reference&lt;T&gt;::value 
         || is_void&lt;T&gt;::value); 
};</pre>

<p><code>value</code>: defined to be true if T is an object type
(3.9).</p>

<pre>template &lt;class T&gt; struct is_scalar{
   static const bool value = 
      is_arithmetic&lt;T&gt;::value 

      || is_enum&lt;T&gt;::value
      || is_pointer&lt;T&gt;::value 
      || is_member_pointer&lt;T&gt;::value; 
};</pre>

<p><code>value</code>: defined to be true if T is a scalar type (3.9).</p>

<pre>template &lt;class T&gt; struct is_compound{
   static const bool value = 
      is_array&lt;T&gt;::value 
      || is_function&lt;T&gt;::value 
      || is_pointer&lt;T&gt;::value 
      || is_reference&lt;T&gt;::value 
      || is_enum&lt;T&gt;::value 
      || is_union&lt;T&gt;::value 
      || is_class&lt;T&gt;::value 
      || is_member_pointer&lt;T&gt;::value; 
};</pre>

<p><code>value</code>: defined to be true if T is a compound type
(3.9.2).</p>

<h4>Type properties</h4>

<p>These templates provide access to some of the more important
properties of types; they reveal information which is available
to the compiler, but which would not otherwise be detectable in C++
code.</p>

<p>Except where specified, it is undefined whether any of these
templates have any full or partial specialisations defined. It is
permitted for the user to specialise any of these templates on a
user-defined type, provided the semantics of the specialisation
match those given for the template in its description.</p>

<p>The template <code>is_const</code> shall have its member <code>value</code>
defined to be true for all types <code>const T</code>, the
template <code>is_volatile</code> shall have its member <code>value</code>
defined to be true for all <code>volatile T</code>. It is
unspecified whether the remaining templates ever define their <code>value</code>
members to be true, except that the following conditions shall
always hold true for all T:</p>

<pre>has_nothrow_*&lt;T&gt;::value == has_nothrow_*&lt;remove_bounds&lt;T&gt;::type&gt;::value
has_nothrow_*&lt;T&gt;::value &gt;= has_trivial_*&lt;T&gt;::value
has_trivial_*&lt;T&gt;::value == has_trivial_*&lt;remove_bounds&lt;T&gt;::type&gt;::value
has_trivial_*&lt;T&gt;::value &gt;= is_POD&lt;T&gt;::value
is_POD&lt;T&gt;::value == is_POD&lt;remove_bounds&lt;T&gt;::type&gt;::value
is_POD&lt;T&gt;::value &gt;= (is_scalar&lt;T&gt;::value || is_void&lt;T&gt;::value)</pre>

<blockquote>
    <p><font color="#FF0000"><i>Author's Note: is this the best
    and/or correct way to specify these relationships? Are
    volatile qualified types POD's? Section 3.9p10 says clearly
    that they are - however is a volatile qualifier compatible
    with applying memcpy to the type as in section 3.9p2?</i></font></p>
</blockquote>

<pre>template &lt;class T&gt; struct is_const{
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if T is const-qualified
(3.9.3).</p>

<pre>template &lt;class T&gt; struct is_volatile{
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if T is volatile-qualified
(3.9.3).</p>

<pre>template &lt;class T&gt; struct is_POD{
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if T is a POD type (3.9).</p>

<pre>template &lt;class T&gt; struct is_empty{
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if T is an empty class
(10).</p>

<blockquote>
    <p><font color="#FF0000"><i>Author's Note: Although it is
    unspecified whether there is any T for which
    is_empty&lt;T&gt;::value is true, in practice it is possible
    to implement is_empty so that it gives the correct answer,
    provided that the compiler implements zero sized empty base
    classes - see the boost reference implementation[</i></font><a
    href="#ref5">5</a><font color="#FF0000"><i>].</i></font></p>
</blockquote>

<pre>template &lt;class T&gt; struct is_polymorphic{
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if T is a polymorphic
class (10.3).</p>

<pre>template &lt;class T&gt; struct has_trivial_constructor{
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if the default
constructor for T is trivial(12.1).</p>

<pre>template &lt;class T&gt; struct has_trivial_copy{
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if the copy constructor
for T is trivial (12.8).</p>

<pre>template &lt;class T&gt; struct has_trivial_assign{
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if the assignment
operator for T is trivial (12.8).</p>

<pre>template &lt;class T&gt; struct has_trivial_destructor{
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if the destructor for T
is trivial (12.4).</p>

<blockquote>
    <p><font color="#FF0000"><i>Author's Note: Although it is
    unspecified whether there is any T for which has_trivial_*&lt;T&gt;::value
    is true, in practice it is possible to implement these
    templates so that they do give the correct answer with just a
    little compiler help. For example the SGI compiler provides
    automatic specialisations of the SGI __type_traits class[</i></font><a
    href="#ref7">7</a><font color="#FF0000"><i>], the boost type
    traits classes hook into this mechanism, converting SGI style
    type traits to the boost style[</i></font><a href="#ref5">5</a><font
    color="#FF0000"><i>].</i></font></p>
</blockquote>

<pre>template &lt;class T&gt; struct has_nothrow_construct{
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if the default
constructor for T is guaranteed not to throw.</p>

<pre>template &lt;class T&gt; struct has_nothrow_copy{
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if the copy constructor
for T is guaranteed not to throw.</p>

<pre>template &lt;class T&gt; struct has_nothrow_assign{
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true if the assignment
operator for T is guaranteed not to throw.</p>

<h3><a name="Binary_type_traits"></a>Relationships between Types</h3>

<p>This sub-clause contains templates that may be used to query
the relationships between two types at compile time.</p>

<p>All of the templates in this header satisfy the
BinaryTypeTrait requirements.</p>

<h4>Header &lt;type_compare&gt; synopsis</h4>

<pre>namespace std{

// type relations:
template &lt;class T, class U&gt; struct is_same;
template &lt;class From, class To&gt; struct is_convertible;
template &lt;class Base, class Derived&gt; struct is_base_and_derived;

} // namespace std</pre>

<h4>Type Relationships</h4>

<pre>template &lt;class T, class U&gt; struct is_same{
   static const bool value = false; 
};
template &lt;class T&gt; struct is_same&lt;T,T&gt;{
   static const bool value = true; 
};</pre>

<p><code>value</code>: defined to be true if T and U are the same
type.</p>

<pre>template &lt;class From, class To&gt; struct is_convertible {
   static const bool value = implementation_defined; 
};</pre>

<p><code>value</code>: defined to be true only if type <code>From</code>
is implicitly-convertible to type <code>To</code> (4).</p>

<pre>template &lt; class Base, class Derived&gt; struct is_base_and_derived {
   static const bool value = <code>is_convertible&lt;Derived*,Base*&gt;::value</code>; 
};</pre>

<p><code>value</code>: defined to be true only if type <code>Base</code>
is a base class of type <code>Derived</code> (10). Equivalent to <code>is_convertible&lt;Derived*,Base*&gt;::value</code>.</p>

<h3><a name="transformation_traits"></a>Transformations between
Types</h3>

<p>This sub-clause contains templates that may be used to
transform one type to another following some predefined rule.</p>

<p>All of the templates in this header satisfy the
TransformationTrait requirements.</p>

<h4>Header &lt;type_transform&gt; synopsis</h4>

<pre>namespace std{

// const-volatile modifications:
template &lt;class T&gt; struct remove_const;
template &lt;class T&gt; struct remove_volatile;
template &lt;class T&gt; struct remove_cv;
template &lt;class T&gt; struct add_const;
template &lt;class T&gt; struct add_volatile;
template &lt;class T&gt; struct add_cv;

// reference modifications:
template &lt;class T&gt; struct remove_reference;
template &lt;class T&gt; struct add_reference;

// array modifications:
template &lt;class T&gt; struct remove_bounds;

// pointer modifications:
template &lt;class T&gt; struct remove_pointer;
template &lt;class T&gt; struct add_pointer;

} // namespace std</pre>

<h4>Const-volatile Modifications</h4>

<pre>template &lt;class T&gt; struct remove_const{
   typedef T type; 
};
template &lt;class T&gt; struct remove_const&lt;T const&gt;{
   typedef T type; 
};</pre>

<p><code>type</code>: defined to be a type that is the same as T,
except that any top level const-qualifier has been removed. For
example: <code>remove_const&lt;const volatile int&gt;::type</code>&nbsp;evaluates
to <code>volatile int,</code> where as <code>remove_const&lt;const
int*&gt;</code> is <code>const int*</code>.</p>

<pre>template &lt;class T&gt; struct remove_volatile{
   typedef T type; 
};
template &lt;class T&gt; struct remove_volatile&lt;T volatile&gt;{
   typedef T type; 
};</pre>

<p><code>type</code>: defined to be a type that is the same as T,
except that any top level volatile-qualifier has been removed.
For example: <code>remove_const&lt;const volatile int&gt;::type</code>&nbsp;evaluates
to <code>const int,</code> where as <code>remove_const&lt;volatile
int*&gt;</code> is <code>volatile int*</code>.</p>

<pre>template &lt;class T&gt; struct remove_cv{
   typedef typename remove_const&lt;typename remove_volatile&lt;T&gt;::type&gt;::type type; 
};</pre>

<p><code>type</code>: defined to be a type that is the same as T,
except that any top level cv-qualifiers have been removed. For
example: <code>remove_cv&lt;const volatile int&gt;::type</code>&nbsp;evaluates
to <code>int,</code> where as <code>remove_cv&lt;const volatile
int*&gt;</code> is <code>const volatile int*</code>.</p>

<pre>template &lt;class T&gt; struct add_const{
   typedef T const type; 
};</pre>

<p><code>type</code>: defined to be a type that is the same as T,
except that a top level const-qualifier has been added, provided
that T is not already const-qualified or a reference or function
type.</p>

<pre>template &lt;class T&gt; struct add_volatile{
   typedef T volatile type; 
};</pre>

<p><code>type</code>: defined to be a type that is the same as T,
except that a top level volatile-qualifier has been added,
provided that T is not already volatile-qualified or a reference
or function type.</p>

<pre>template &lt;class T&gt; struct add_cv{
   typedef T const volatile type; 
};</pre>

<p><code>type</code>: defined to be a type that is the same as T,
except that top level const- and volatile-qualifiers have been
added, provided that T is not already const-volatile-qualified or
a reference or function type.</p>

<blockquote>
    <p><font color="#FF0000"><i>Author's Note: superficially the
    add_const, add_volatile and add_cv classes are irrelevant,
    since, for example, </i><code>add_const&lt;T&gt;::type</code><i>
    is the same as </i><code>T const</code><i>, for all T (currently
    this does not apply to function types - but issue 295
    addresses this). However the experience from boost is that
    several users have asked for these templates to be present in
    the library for the following reasons: (a) Some users find
    these more explicit - when combining transformation templates
    in particular, users like the kind of &quot;built in
    documentation&quot; that these templates provide. (b) Not all
    users are aware that cv-qualifying a reference is allowed and
    has no effect, or that cv-qualifying a type that is already
    cv-qualified is allowed and has no effect. (c) Compilers may
    emit warnings when cv-qualifying a type that is a reference,
    or already has a cv-qualifier, these templates can be
    implemented such that these messages are suppressed in these
    cases.</i></font></p>
</blockquote>

<h4>Reference Modifications</h4>

<pre>template &lt;class T&gt; struct remove_reference{
   typedef T type;
};
template &lt;class T&gt; struct remove_reference&lt;T&amp;&gt;{
   typedef T type;
};</pre>

<p><code>type</code>: defined to be a type that is the same as T,
except any reference qualifier has been removed.</p>

<pre>template &lt;class T&gt; struct add_reference{
   typedef T&amp; type;
};
template &lt;class T&gt; struct add_reference&lt;T&amp;&gt;{
   typedef T&amp; type;
};</pre>

<p><code>type</code>: defined to be a type that is the same as
T&amp;.</p>

<blockquote>
    <p><font color="#FF0000"><i>Author's Note: the add_reference
    template was one of the original motivations behind the boost
    type traits library. However the resolution to issue 106
    makes the template appear largely redundant. In spite of that
    add_reference may well be useful in suppressing compiler
    warnings when inadvertently creating references to references
    in template code.</i></font></p>
</blockquote>

<h4>Array Modifications</h4>

<pre>template &lt;class T&gt; struct remove_bounds{
   typedef T type;
};
template &lt;class T, std::size_t N&gt; struct remove_bounds&lt;T[N]&gt;{
   typedef T type;
};</pre>

<p><code>type</code>: defined to be a type that is the same as T,
except any top level array bounds have been removed.</p>

<blockquote>
    <p><font color="#FF0000"><i>Author's Note: there is no
    add_bounds template, basically because there are several
    different meanings that could be applied to this. For example
    what happens when you add bounds to a reference type, and if
    you add bounds to a pointer should you get an array of
    pointers, or an array of the thing being pointed to. For
    these reasons the author believes that it is better to
    deliberately omit this template, and leave it to users to
    define their own add_bounds template if they need it, that
    gives the particular semantics that they require.</i></font></p>
</blockquote>

<h4>Pointer Modifications</h4>

<pre>template &lt;class T&gt; struct remove_pointer{
   typedef T type;
};
template &lt;class T&gt; struct remove_pointer&lt;T*&gt;{
   typedef T type;
};
template &lt;class T&gt; struct remove_pointer&lt;T* const&gt;{
   typedef T type;
};
template &lt;class T&gt; struct remove_pointer&lt;T* volatile&gt;{
   typedef T type;
};
template &lt;class T&gt; struct remove_pointer&lt;T* const volatile&gt;{
   typedef T type;
};</pre>

<p><code>type</code>: defined to be a type that is the same as T,
except any top level indirection has been removed.</p>

<pre>template &lt;class T&gt; struct add_pointer{
   typedef typename remove_bounds&lt;typename remove_reference&lt;T&gt;::type&gt;::type* type;
};</pre>

<p><code>type</code>: defined to be a type that is the result of
the expression <code>&amp;t</code>, where <code>t </code>is an
instance of T.</p>

<hr>

<h2>References</h2>

<ol>
    <li><a name="ref1"></a>John Maddock and Steve Cleary, &quot;<a
        href="http://www.boost.org/libs/type_traits/c++_type_traits.htm">C++
        Type Traits</a>&quot;, <a href="http://www.ddj.com/">Dr
        Dobbs Journal</a>, October 2000.</li>
    <li><a name="ref2"></a>Steve Cleary, Beman Dawes, Howard
        Hinnant and John Maddock, &quot;<a
        href="http://www.boost.org/libs/utility/compressed_pair.htm">compressed_pair</a>&quot;,
        <a href="http://www.boost.org/libs/libraries.htm">Boost
        library documentation</a>.</li>
    <li><a name="ref3"></a>Jeremy Siek, &quot;Concept Checking&quot;,
        <a href="http://www.oonumerics.org/tmpw00/">C++ Template
        Workshop 2000</a>.</li>
    <li><a name="ref4"></a>John Maddock, &quot;<a
        href="http://www.boost.org/libs/static_assert/static_assert.htm">static
        assert</a>&quot;, <a
        href="http://www.boost.org/libs/libraries.htm">Boost
        library documentation</a>.</li>
    <li><a name="ref5"></a>Steve Cleary, Beman Dawes, Aleksey
        Gurtovoy, Howard Hinnant, Jesse Jones, Mat Marcus, John
        Maddock and Jeremy Siek, &quot;<a
        href="http://www.boost.org/libs/type_traits/index.htm">Type
        traits</a>&quot;, <a
        href="http://www.boost.org/libs/libraries.htm">Boost
        library documentation</a>.</li>
    <li><a name="ref6"></a>Andrei Alexandrescu, &quot;<a
        href="http://moderncppdesign.com/">Modern C++ Design:
        Generic Programming and Design Patterns Applied</a>&quot;,
        Addison-Wesley, 2001.</li>
    <li><a name="ref7"></a>SGI, &quot;The SGI standard template
        library&quot;.</li>
    <li><a name="ref8"></a>Emily Winch, <a
        href="http://www.oonumerics.org/tmpw01/winch.pdf">Heterogenous
        lists of named objects</a>, <a
        href="http://www.oonumerics.org/tmpw01/schedule.html">Second
        C++ Template Programming Workshop 2001</a>.</li>
    <li><a name="ref9"></a>Andrei Alexandrescu, &quot;<a
        href="http://www.cuj.com/experts/1910/alexandr.htm?topic=experts&amp;topic=experts">Generic&lt;Programming&gt;:
        Typed Buffers (II)</a>&quot;, <a
        href="http://www.cuj.com/experts/?topic=experts">Oct CUJ
        C++ Experts</a>, 2001.</li>
</ol>

<h2>Acknowledgements</h2>

<p>The author is particularly indebted to everyone who as worked
on the boost type traits library[<a href="#ref5">5</a>], but also
to David Abrahams, Darin Adler, Beman Dawes and Emily Winch for
their helpful comments on an early draft of this document.</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>
</body>
</html>
