The header <AHREF='../../boost/utility/select_by_size.hpp'><SPANCLASS='code'><boost/utility/select_by_size.hpp></SPAN></A> provides template classes and macros for determining the results of overload resolution at compile time using <SPANCLASS='code'>sizeof</SPAN>. It is intended as an alternative to <AHREF='http://www.boost.org/boost/type_traits/detail/yes_no_type.hpp'><SPANCLASS='code'>type_traits::yes_type</SPAN></A> and <AHREF='http://www.boost.org/boost/type_traits/detail/yes_no_type.hpp'><SPANCLASS='code'>type_traits::no_type</SPAN></A> from the <AHREF='http://www.boost.org/libs/type_traits/index.html'>Type Traits</A> library. It provides an arbitrary number of types, <SPANCLASS='code'>case_<0></SPAN>, <SPANCLASS='code'>case_<1></SPAN>, <SPANCLASS='code'>case_<2></SPAN>, <SPANCLASS='code'>... </SPAN>, for use as the return types of helper functions, plus a template <SPANCLASS='code'>select_by_size</SPAN> which provides access to the result of the overload resolution. There is also a macro <SPANCLASS='code'>BOOST_SELECT_BY_SIZE</SPAN>, similar to <AHREF='http://www.boost.org/libs/config/config.htm'><SPANCLASS='code'>BOOST_STATIC_CONSTANT</SPAN></A>, for use with compilers which have trouble with integral constant expressions. (<I>See</I><AHREF='http://www.boost.org/more/int_const_guidelines.htm'>Coding Guidelines for Integral Constant Expressions</A>.)
</P>
<P>
The <SPANCLASS='code'>typedefs</SPAN><SPANCLASS='code'>yes_type</SPAN> and <SPANCLASS='code'>no_type</SPAN> are provided as shorthands for <SPANCLASS='code'>case_<1></SPAN> and <SPANCLASS='code'>case_<0></SPAN>. In some cases, <SPANCLASS='code'>case_<true></SPAN> and <SPANCLASS='code'>case_<false></SPAN> may be more suggestive. There is also a single return type representing a negative value: <SPANCLASS='code'>case_<-1></SPAN>.
form a strictly increasing sequence. With well-behaved implementations, <SPANCLASS='code'>sizeof(case_<-1>)</SPAN> will be small, as will be the difference in size between adjacent types in the sequence.
The defining property of the class template <SPANCLASS='code'>select_by_size</SPAN> is that for each integer <SPANCLASS='code'>N</SPAN> in the range <SPANCLASS='code'>select_by_size</SPAN> through <SPANCLASS='code'>BOOST_SELECT_BY_SIZE_MAX_CASE</SPAN>, we have the equality
The macro <SPANCLASS='code'>BOOST_SELECT_BY_SIZE(type, name, expr)</SPAN> can be used similarly to <SPANCLASS='code'>BOOST_STATIC_CONSTANT</SPAN> to define a <SPANCLASS='code'>static const</SPAN> intergral class member <SPANCLASS='code'>name</SPAN> of type <SPANCLASS='code'>type</SPAN> with value equal to <SPANCLASS='code'>select_by_size<sizeof(expr)>::value</SPAN>.
In order to make use of <SPANCLASS='code'>select_by_size</SPAN> with specializations <SPANCLASS='code'>case_<N></SPAN> for <SPANCLASS='code'>N</SPAN> other than <SPANCLASS='code'>-1</SPAN>, <SPANCLASS='code'>0</SPAN> and <SPANCLASS='code'>1</SPAN>,
the symbol <SPANCLASS='code'>BOOST_SELECT_BY_SIZE_MAX_CASE</SPAN> must be defined as an intergral value greater than or equal to <SPANCLASS='code'>N</SPAN> before including the header <SPANCLASS='code'><boost/utility/select_by_size.hpp></SPAN>. The header may be included multiple times with different values of <SPANCLASS='code'>BOOST_SELECT_BY_SIZE_MAX_CASE</SPAN>.
</P>
<P>
It is possible to implement <SPANCLASS='code'>select_by_size</SPAN> in such a way that this macro is not necessary. <I>See</I><AHREF='#implementation'>Implementation</A>, below, for a discussion.
The utility of <SPANCLASS='code'>type_traits::yes_type</SPAN> and <SPANCLASS='code'>type_traits::no_type</SPAN> is well-known. The advantages of using <SPANCLASS='code'>select_by_size</SPAN> are:
<ULtype='box'>
<LISTYLE='list-style-type: square'>It documents the fact that <SPANCLASS='code'>sizeof</SPAN> is being used to determine the result of overload resolution.
<LISTYLE='list-style-type: square'>It eliminates the need to compare a given <SPANCLASS='code'>sizeof</SPAN> expression with <SPANCLASS='code'>sizeof(type_traits::yes_type)</SPAN>.
<LISTYLE='list-style-type: square'>It allows the use of an aribtrary number of cases.</LI>
Until recently the author knew of only one use for <SPANCLASS='code'>select_by_size</SPAN> with more than two cases, and so regarded it as a <I>trick</I>. He then discovered a second use, elevating it to a <I>method</I>. With the discovery of a third use, it is now a <I>programming paradigm</I>. (The three known uses are determing template arity, as in <AHREF='http://www.boost.org/boost/mpl/aux_/template_arity.hpp'><SPANCLASS='code'><boost/mpl/aux_/template_arity.hpp></SPAN></A>, <AHREF='http://www.boost.org/people/joel_de_guzman.htm'>Joel de Guzman</A>'s type deduction system in the <AHREF='http://www.boost.org/more/mailing_lists.htm#sandbox'>Boost Sandbox</A> at <SPANCLASS='code'><boost/utility/type_deduction.hpp></SPAN>, and Reece Dunn's type deduction system for his Output Formatters library, also in the <AHREF='http://www.boost.org/more/mailing_lists.htm#sandbox'>Boost Sandbox</A>, at <SPANCLASS='code'><boost/outfmt/detail/type_traits.hpp></SPAN>. There are surely many more.)
</P>
<ANAME='implementation'></A>
<H2>Implementation</H2>
<P>
<SPANCLASS='code'>select_by_size</SPAN> is implemented by explicit specialization for the values
There are several ways to remove this restriction. For instance:
<UL>
<LISTYLE='list-style-type: square'><SPANCLASS='code'>select_by_size</SPAN> could be implemented to
iterate through the sequence <SPANCLASS='code'>case_<-1>, case_<0>, case_<1>, ... </SPAN> until it finds
a specialization whose size is equal to its template argument, or
<LISTYLE='list-style-type: square'>The template <SPANCLASS='code'>case_</SPAN> could be designed so
that its size is easy to compute, taking alignment issues into account.
</UL>
This first approach is computationally too expensive for a widely used utility. The second approach is feasable; a sample implementation using <AHREF='http://www.boost.org/boost/type_traits/alignment_of.hpp'><SPANCLASS='code'>alignment_of</SPAN></A> and <AHREF='http://www.boost.org/boost/type_traits/type_with_alignment.hpp'><SPANCLASS='code'>max_align</SPAN></A> from the <AHREF='http://www.boost.org/libs/config/config.htm'>Type Traits</A> library is given in the <AHREF='../../boost/utility/select_by_size.hpp'>source code</A>.
</P>
<P>
The present implementation was chosen to
reduce dependencies on other libraries. If defining the macro <SPANCLASS='code'>BOOST_SELECT_BY_SIZE_MAX_CASE</SPAN> is considered too inconvenient, the default number of cases could be set to <SPANCLASS='code'>10</SPAN> or <SPANCLASS='code'>20</SPAN> with little noticeable overhead.
The header <AHREF='../../boost/utility/select_by_size.hpp'><SPANCLASS='code'><boost/utility/select_by_size.hpp></SPAN></A> depends on <AHREF='http://www.boost.org/libs/config/config.htm'>Boost.Config</A> and the <AHREF='http://www.boost.org/libs/preprocessor/doc/index.html'>Boost Preprocessor Library</A>.
The program <AHREF='select_by_size_test.cpp'><SPANCLASS='code'><libs/utility/select_by_size_test.cpp></SPAN></A> has been tested successfully with the following compilers: