<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html;charset=iso-8859-1">
	<TITLE>two missing traits: enable_if and conditional</TITLE>
</HEAD>

<BODY>
<P ALIGN=LEFT>
Document number: J16/07-0100 = WG21 N2240<BR>
Date: 2007-04-17<BR>
Author: Benjamin Kosnik &lt;bkoz@redhat.com&gt; <BR>
Library Working Group<BR>
</P>

<H2 ALIGN=CENTER>Two missing traits: enable_if and conditional</H2>

<P><BR><BR>
</P>

<p></p>
<H3>Introduction.</H3>
<p> Similar to two other papers pointing out weaknesses or errors in
TR1's <code>type_traits</code> offerings, this paper presents two
notable omissions that are in wide use: traits:
<code>enable_if</code>, and <code>conditional</code>.
</p>


<p></p>
<H3>enable_if</H3>

<p> This is an object for compile-type conditional type existence,
useful for SFINAE and clean implementation of overload sets.
</p>

<pre>
  template&lt;bool _Cond, typename _Tp&gt;
    struct enable_if 
    { };

  template&lt;typename _Tp&gt;
    struct enable_if&lt;true, _Tp&gt;
    { typedef _Tp type; };
</pre>

<p> As defined above, <code>enable_if::type</code> is equal to the
second parameter only if the condition argument is true.
</p>

<p> There has been some murmuring in the greater C++ community that
this trait will prove less useful in the presence of
concepts. However, these voices are indistinct. It is not clear if
concepts will eliminate all uses of this trait.
</p>


<p></p>
<H3>conditional</H3>

<p> This is an object for compile-type conditional type selection.
</p>

<pre>
  template&lt;bool _Cond, typename _Iftrue, typename _Iffalse&gt;
    struct conditional
    { typedef _Iftrue type; };

  template&lt;typename _Iftrue, typename _Iffalse&gt;
    struct conditional&lt;false, _Iftrue, _Iffalse&gt;
    { typedef _Iffalse type; };
</pre>

<p> As defined above, <code>conditional::type</code> is equal to
the second parameter if the first (condition) parameter is true, and
is equal to the third parameter if the condition parameter is false.
</p>

<p></p>
<H3>Wording.</H3>

<p> Extend the synopsis of 20.4.2 to include the following:
</p>

<pre class="literal-block" STYLE="background:#ccccff">
// [20.4.2] other transformations:
template &lt;bool, typename Tp = void&gt; struct enable_if;
template &lt;bool, typename IfTrue, typename IfFalse&gt; struct conditional;
</pre>

<P>Add the following row to Table 46 (Other transformations):</P>
<table border="1" class="docutils">
<colgroup>
<col width="30%">
<col width="19%">
<col width="51%">
</colgroup>
<thead valign="bottom">
<tr><th class="head"><strong>Template</strong></th>
<th class="head"><strong>Condition</strong></th>
<th class="head"><strong>Comments</strong></th>
</tr>
</thead>
<tbody valign="top">
<tr><td>
template &lt;bool B, typename T = void&gt; struct enable_if;
</td>
<td>&nbsp;</td>
<td>If <code>B</code> is <code>true</code>, the member typedef <code>type</code> shall equal <code>T</code>
</td>
</tr>

<tr><td>
template &lt;bool B, typename IfTrue, typename IfFalse&gt; struct conditional;
</td>
<td>&nbsp;</td>
<td>If <code>B</code> is <code>true</code>, the member typedef <code>type</code> shall equal <code>IfTrue</code>. If <code>B</code> is <code>false</code>, the member typedef <code>type</code> shall equal <code>IfFalse</code>. 
</td>
</tr>
</tbody>
</table>
<p></p>

<H3>Implementation and usage notes.</H3>

<p> From a quick scan, the <code>enable_if</code> trait has been
formalized in the Boost type_traits utilities since 2003, and since
May 2003 in GNU libstdc++. Both spellings and signatures are the
same. In addition, Boost duplicates this functionality in the MPL
libraries with <code>eval_if_c</code> function. So, Boost really has
this trait twice: it must be that useful!
</p>

<p> Likewise, the <code>__conditional_type</code> trait has been used
since August, 2006 in GNU libstdc++, with earlier spellings of both
<code>cond_type</code> starting in June, 2005 and <code>IF</code> also
starting in 2005. Boost has had this functionality since approximately
2002 as part of the MPL library, and spells this as
<code>if_c</code>. In addition, Boost duplicates this functionality in
<code>boost/xpressive/proto/transform/conditional.hpp</code>, spelling
it <code>conditional</code>.  RogueWave may have some of this
functionality in the macro <code>RW_CONDITIONAL_TYPENAME</code>. Boost
documentation points to the discovery, use, and evolution of this
trait from 1995 to 2000 to the present day.
</p>

<p> google codesearch for <code>enable_if lang:"c++"</code> yields 100
hits, with users in boost, loki, k3d, lyx, polymake, LLVM,
gcc/libstdc++, cca-forum.org, cgal, inkscape, HepMC, orocos, QuantLib,
and so on and so on as this is up to page 5 of 10.
</p>

<p> google codesearch for <code>eval_if_c lang:"c++"</code> yields 9
hits, with all users in boost.
</p>

<p> google case-sensitive codesearch for <code>if_c lang:"c++"</code>
yields 300 hits but not all unique to this specific trait. Still,
verified uses in boost, k3d, in secondlife's linden sources, lyx, glite,
cca-forum.org, StatisticsTesting, CGAL, etc.
</p>

<p> google codesearch for <code>cond_type lang:"c++"</code> yields
nothing useful, due to a lot of hits for <code>second_type</code>.
</p>

<p> google codesearch for <code>conditional type lang:"c++"</code> yields
200 hits, with some likely candidates, but many false matches.
</p>

<p> google codesearch for <code>conditional_type lang:"c++"</code>
yields 9 hits, all users in gcc/libstdc++. More interesting searches
are possible with variations of "conditional" "__conditional," "type,"
and "trait." Some of these users are, on inspection, looking for ways to do
conditional type computation.
</p>


<p></p>
<H3>References.</H3>
<P> Howard E. Hinnant, Minor Modifications to the type traits Wording
Revision 1, N2157=07-0017, January 12,2007.
</P>

<P> Thorsten Ottosen, Yet another type-trait: decay, N2069, September 8, 2006
</P>

<P> Aleksey Gurtovo and David Abrahams, 2.1. Conditional type
selection, The Boost C++ Metaprogramming Library
</P>

<P> Pete Becker, Programming Languages C++, N2135 06-0205
</P>

<P> libstdc++ mailing list on missing traits, September 14, 2006
<a href="http://gcc.gnu.org/ml/libstdc++/2006-09/msg00099.html">discussion</a>
</P>


<P> libstdc++ <code>ext/type_traits</code>
<a href="http://gcc.gnu.org/viewcvs/*checkout*/trunk/libstdc%2B%2B-v3/include/ext/type_traits.h?revision=123692">file</a>
</P>

<P> boost <code>enable_if</code>
<a href="http://www.boost.org/libs/utility/enable_if.html">documentation</a>
</P>

<P> boost <code>eval_if_c</code> from MPL
<a href="http://boost.org/libs/mpl/doc/refmanual/eval-if-c.html">documentation</a>
</P

<P> boost <code>if_c</code> from MPL
<a href="http://boost.org/libs/mpl/doc/refmanual/if-c.html">documentation</a>
</P>

</BODY>
</HTML>
