<html>

<head>
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Additional Type-Traits for C++0x</title>
<style type="text/css">
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
</style>
</head>

<body>

<div align="left">
  <table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="579">
    <tr>
      <td width="153" align="left" valign="top">Document number:</td>
      <td width="426">N2947=09-0137</td>
    </tr>
    <tr>
      <td width="153" align="left" valign="top">Date:</td>
      <td width="426">
      <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%Y-%m-%d" startspan -->2009-09-25<!--webbot bot="Timestamp" endspan i-checksum="12614" --></td>
    </tr>
    <tr>
      <td width="153" align="left" valign="top">Project:</td>
      <td width="426">Programming Language C++, Library Working Group</td>
    </tr>
    <tr>
      <td width="153" align="left" valign="top">Reply-to:</td>
      <td width="426">Beman Dawes &lt;bdawes at acm dot org&gt;<br>
      Daniel Krgler &lt;daniel.kruegler at googlemail dot.<wbr />com&gt;<br>
      Alisdair Meredith<span class="gI"><span class="go"> &lt;public at alisdairm 
      dot net&gt;</span></span></td>
    </tr>
  </table>
</div>

<h1>Additional Type Traits for C++0x</h1>

<h2>Introduction</h2>

<p>The C++ committee's Library Working Group (LWG) asked in Frankfurt for a 
proposal unifying LWG issues-list requests for additional type traits in light 
of the&nbsp; removal of the concepts language feature from C++0x.</p>

<h2>Rationale</h2>

<h3>is_trivially_copyable</h3>

<p>LWG issue 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2948.html#1174">1174</a>, submitted by Jason Merrill:</p>

<blockquote>
  <p>I've been implementing compiler support for <tt>is_standard_layout</tt>, 
  and noticed a few nits about 20.6.4.3 [meta.unary.prop]: </p>
  <ol>
    <li>There's no trait for &quot;trivially copyable type&quot;, which is now the 
    property that lets you do bitwise copying of a type, and therefore seems 
    useful to be able to query. <tt>has_trivial_assign</tt> &amp;&amp; <tt>
    has_trivial_copy_constructor</tt> &amp;&amp; <tt>has_trivial_destructor</tt> is 
    similar, but not identical, specifically with respect to const types. </li>
    <li><tt>has_trivial_copy_constructor</tt> and <tt>has_trivial_assign</tt> 
    lack the &quot;or an array of such a class type&quot; language that most other traits 
    in that section, including <tt>has_nothrow_copy_constructor</tt> and <tt>
    has_nothrow_assign</tt>, have; this seems like an oversight. </li>
  </ol>
</blockquote>
<p><i>[ See the thread starting with c++std-lib-24420 for further discussion. ]</i></p>

<h3>is_literal_type</h3>

<p>LWG issue 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2948.html#719">719</a>, submitted by Daniel Krgler:</p>

<blockquote>
  <p>Since the inclusion of <tt>constexpr</tt> in the standard draft N2369 we 
  have a new type category &quot;literal&quot;, which is defined in 3.9 [basic.types]/p.11:
  </p>
  <blockquote>
    <p>-11- A type is a <i>literal type</i> if it is: </p>
    <ul>
      <li>a scalar type; or</li>
      <li>a class type (clause 9) with<ul>
        <li>a trivial copy constructor,</li>
        <li>a trivial destructor,</li>
        <li>a trivial default constructor or at least one constexpr constructor 
        other than the copy constructor,<br>
        and</li>
        <li>all non-static data members and base classes of literal types; or</li>
      </ul>
      </li>
      <li>an array of literal type.</li>
    </ul>
  </blockquote>
  <p>I strongly suggest that the standard provides a type traits for literal 
  types in 20.6.4.3 [meta.unary.prop] for several reasons: </p>
  <ol type="a">
    <li>To keep the type traits in sync with the types defined in the core 
    language.</li>
    <li>I see many reasons for programmers to use this trait in template code to 
    provide optimized template definitions for these types, see below.</li>
    <li>A user-provided definition of this trait is practically impossible to 
    write portably.</li>
  </ol>
  <p>The special problem of reason (c) is that I don't see currently a way to 
  portably test the condition for literal class types: </p>
  <blockquote>
    <ul>
      <li>...at least one constexpr constructor other than the copy constructor,</li>
    </ul>
  </blockquote>
</blockquote>

<p>The proposed name is <code>is_literal_type</code>, rather than <code>
is_literal</code>, because <i>literal</i> and <i>literal type</i> have different 
core language meanings. It was judged better to be clear even at the cost of 
being inconsistent with the other names.</p>

<h3>is_explicitly_convertible</h3>

<p>LWG issue 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2942.html#750">750</a>, submitted by Alisdair Meredith:</p>

<blockquote>

<p>The current definition for <tt>is_convertible</tt> requires that the type be 
implicitly convertible, so explicit constructors are ignored.</p>

<p>With the pending arrival of explicit conversion functions though, I'm 
wondering if we want an additional trait, <tt>is_explictly_convertible</tt>?</p>

</blockquote>

<p><i>Several LWG members have commented that they believe such a trait would be 
useful.</i></p>

<h3>enum_base</h3>

<p>LWG issue 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2948.html#1055">1055</a>, addressing CD-1comment UK 98:</p>

<blockquote>

<p>It would be useful to be able to determine the underlying type of an 
arbitrary enumeration type. This would allow safe casting to an integral type 
(especially needed for scoped enums, which do not promote), and would allow use 
of <tt>numeric_limits</tt>. In general it makes generic programming with 
enumerations easier.</p>

</blockquote>

<h2>Proposed wording</h2>

<p><i>To 20.6.2 Header &lt;type_traits&gt; synopsis [meta.type.synop], add as 
indicated:</i></p>

<blockquote>

<pre>namespace std {

// 20.6.3, helper class:
template &lt;class T, T v&gt; struct integral_constant;
typedef integral_constant&lt;bool, true&gt; true_type;
typedef integral_constant&lt;bool, false&gt; false_type;

// 20.6.4.1, 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_floating_point;
template &lt;class T&gt; struct is_array;
template &lt;class T&gt; struct is_pointer;
template &lt;class T&gt; struct is_lvalue_reference;
template &lt;class T&gt; struct is_rvalue_reference;
template &lt;class T&gt; struct is_member_object_pointer;
template &lt;class T&gt; struct is_member_function_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;

// 20.6.4.2, composite type categories:
template &lt;class T&gt; struct is_reference;
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;
template &lt;class T&gt; struct is_member_pointer;

// 20.6.4.3, 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_trivial;
<ins>template &lt;class T&gt; struct is_trivially_copyable;</ins>
template &lt;class T&gt; struct is_standard_layout;
template &lt;class T&gt; struct is_pod;
<ins>template &lt;class T&gt; struct is_literal_type;</ins>
template &lt;class T&gt; struct is_empty;
template &lt;class T&gt; struct is_polymorphic;
template &lt;class T&gt; struct is_abstract;
template &lt;class T&gt; struct has_trivial_default_constructor;
template &lt;class T&gt; struct has_trivial_copy_constructor;
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_default_constructor;
template &lt;class T&gt; struct has_nothrow_copy_constructor;
template &lt;class T&gt; struct has_nothrow_assign;
template &lt;class T&gt; struct has_virtual_destructor;
template &lt;class T&gt; struct is_signed;
template &lt;class T&gt; struct is_unsigned;
template &lt;class T&gt; struct alignment_of;
template &lt;class T&gt; struct rank;
template &lt;class T, unsigned I = 0&gt; struct extent;

// 20.6.5, type relations:
template &lt;class T, class U&gt; struct is_same;
template &lt;class Base, class Derived&gt; struct is_base_of;
template &lt;class From, class To&gt; struct is_convertible;
<ins>template &lt;class From, class To&gt; struct is_explicitly_convertible;</ins>

// 20.6.6.1, 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;

// 20.6.6.2, reference modifications:
template &lt;class T&gt; struct remove_reference;
template &lt;class T&gt; struct add_lvalue_reference;
template &lt;class T&gt; struct add_rvalue_reference;

// 20.6.6.3, sign modifications:
template &lt;class T&gt; struct make_signed;
template &lt;class T&gt; struct make_unsigned;

// 20.6.6.4, array modifications:
template &lt;class T&gt; struct remove_extent;
template &lt;class T&gt; struct remove_all_extents;
// 20.6.6.5, pointer modifications:
template &lt;class T&gt; struct remove_pointer;
template &lt;class T&gt; struct add_pointer;

// 20.6.7, other transformations:
template &lt;std::size_t Len, std::size_t Align&gt; struct aligned_storage;
template &lt;std::size_t Len, class... Types&gt; struct aligned_union;
template &lt;class T&gt; struct decay;
template &lt;bool, class T = void&gt; struct enable_if;
template &lt;bool, class T, class F&gt; struct conditional;
template &lt;class... T&gt; struct common_type;
<ins>template &lt;class&nbsp;T&gt; struct enum_base;</ins>

} // namespace std</pre>

</blockquote>

<p><i>To 20.6.4.3 Type properties [meta.unary.prop], table </i>Type property 
predicates<i>, add:</i></p>

<blockquote>

<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="95%">
  <tr>
    <td width="33%"><b>Template</b></td>
    <td width="33%"><b>Condition</b></td>
    <td width="34%"><b>Preconditions</b></td>
  </tr>
  <tr>
    <td valign="top" width="33%"><code>template &lt;class T&gt;<br>
    struct is_trivially_copyable;</code></td>
    <td valign="top" width="33%"><code>T</code> is a trivially copyable type ([basic.types]) </td>
    <td width="34%"><code>T</code> shall be a complete type,
    an array of unknown
    bound, or (possibly
    cv-qualified) <code>void</code>.</td>
  </tr>
  <tr>
    <td valign="top" width="33%"><code>template &lt;class T&gt;<br>
    struct is_literal_type;</code></td>
    <td valign="top" width="33%"><code>T</code> is a literal type ([basic.types]) </td>
    <td width="34%"><code>T</code> shall be a complete type,
    an array of unknown
    bound, or (possibly
    cv-qualified) <code>void</code>.</td>
  </tr>
</table>

</blockquote>

<p><i>To 20.6.5 Relationships between types [meta.rel], table  </i>Type 
relationship predicates<i>, add:</i></p>

<blockquote>

<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="95%">
  <blockquote>
    <blockquote>
  <tr>
    <td width="33%"><b>Template</b></td>
    <td width="33%"><b>Condition</b></td>
    <td width="34%"><b>Comments</b></td>
  </tr>
  <tr>
    <td valign="top" width="33%"><code>template &lt;class From, class To&gt;<br>
    struct is_explicitly_convertible;</code></td>
    <td valign="top" width="33%">See below.</td>
    <td width="34%" valign="top"><tt>From</tt> and <tt>To</tt> shall be complete 
    types, arrays of unknown bound, or (possibly cv-qualified) <code>void</code> types.</td>
  </tr>
    </blockquote>
  </blockquote>
  </table>

</blockquote>

<p><i>At the end of 20.6.5 Relationships between types [meta.rel], change as 
indicated. (Assumes issue 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2941.html#975">975</a> has been applied to the WP. 
Editor please note change to bulleted list):</i></p>

<blockquote>

<p>Given the following function prototype:</p>

  <blockquote>
    <pre>template &lt;class T&gt;
typename add_rvalue_reference&lt;T&gt;::type create();</pre>
  </blockquote>

<ul>
  <li>the predicate condition for a template specialization <tt>is_convertible&lt;From, 
  To&gt;</tt> shall be satisfied, if and only if the return expression in the 
  following code would be well-formed, including any implicit conversions to the 
  return type of the function.</li>
</ul>

  <blockquote>
    <blockquote>
    <pre>To test() {
  return create&lt;From&gt;();
}</pre>
    </blockquote>
  <p><i>[ Note:</i> This requirement gives well defined results for reference 
  types, void types, array types, and function<br>
  types.<i>end note ]</i></p>

  </blockquote>
  <ul>
    <li><ins>the predicate condition for a 
    template specialization
    <code>is_explicitly_convertible&lt;From, To&gt;</code> 
    shall be satisfied, if and only if the following expression would be 
    well-formed.</ins></li>
</ul>

  <blockquote>
    <blockquote>
    <pre><ins>static_cast&lt;To&gt;(create&lt;From&gt;())</ins></pre>
    </blockquote>
  </blockquote>
</blockquote>

<p><i>To 20.6.7 Other transformations [meta.trans.other], table  </i>Other 
transformations<i>, add:</i></p>

<blockquote>

<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="95%">
  <tr>
    <td width="349"><b>Template</b></td>
    <td width="350"><b>Condition</b></td>
    <td width="350"><b>Comments</b></td>
  </tr>
  <tr>
    <td valign="top" width="349"><code>template &lt;class T&gt;<br>
    struct enum_base;</code></td>
    <td valign="top" width="350"><tt>T</tt> shall be an enumeration type ([dcl.enum])</td>
    <td width="350">The member typedef <tt>type</tt> shall name the underlying 
    type of the enum <tt>T</tt>.</td>
  </tr>
  </table>

</blockquote>

<hr>
<p>&nbsp;</p>

</body>

</html>