<!-- ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| section -->
<section id="if">
<title>Compile-time if</>

<para>
The most interesting template metaprograms often contain a lot of decision-making code. Some of conditional decisions/behavior can be handled directly by (partial) class template specialization or function overloading <citation><xref linkend="ref.Vel95a"></>, <citation><xref linkend="ref.Ale00"></>, but in general there is a need for a standalone library primitive that would allow one to choose between two types basing on a compile-time expression. In <literal>boost::mpl</> such primitive is called <literal>if_</>:
</>

<programlisting>
<![CDATA[
template< typename T >
struct heap_holder
{
 // ... 
 private:
    boost::scoped_ptr<T> m_object;
};

template< typename T >
struct stack_holder
{
 // ... 
 private:
    T m_object;
};

template< typename T >
struct can_be_on_stack
    : mpl::bool_c< (sizeof(T) <= sizeof(double)) >
{
};

// use 'if_' to choose where to store 'T' member
template< typename T >
struct lightweight
   : private mpl::if_<
          can_be_on_stack<T>
        , stack_holder<T>
        , heap_holder<T>
        >::type
{
   // ...
};
]]>
</>

<para>
Note that the first template parameter of the <literal>if_</> template is a type that should be a model of Integral Constant concept. The library also provides a less generic but sometimes more convenient form that accepts a condition in form of non-type <literal>bool</> template parameter:
</>

<programlisting>
<![CDATA[
template< typename T >
struct lightweight
   : private mpl::if_c<
          (sizeof(T) <= sizeof(double))
        , stack_holder<T>
        , heap_holder<T>
        >::type
{
   // ...
};
]]>
</>

</section>
