initial commitment

[SVN r1963]
This commit is contained in:
Jonathan Turkanis
2004-02-11 20:16:05 +00:00
parent 06cb0cac42
commit 464fef1efa

186
select_by_size.html Normal file
View File

@@ -0,0 +1,186 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<STYLE>
.code { font-family:monospace; font-size: 10pt }
H1 {text-align:center }
P { color: black; font-size: 10p }
TH { text-align:left }
A { text-decoration:none }
A:visited { color: #005E20 }
A.contact { color: black; text-decoration:none }
.code { font-family:monospace; font-size: 10pt }
.headingCode { font-family:monospace; font-size: 12pt }
.concept { font-weight: bold }
</STYLE>
</HEAD>
<BODY>
<H1>Select By Size</H1>
<P STYLE='margin-left:30px'>
<TABLE>
<COLS WIDTH='*,10,*'>
<TR><TH>Author:</TH><TD></TD><TD>Jonathan Turkanis</TD></TR>
<TR><TH>Contact:</TH><TD></TD><TD><A CLASS='contact' HREF='mailto:turkanis@kangaroologic.com'>turkanis@kangaroologic.com</A></TD></TR>
<TR><TH>Date:</TH><TD></TD><TD>2004-02-11</TD></TR>
<TR><TH>Copyright:</TH><TD></TD><TD>Copyright Jonathan Turkanis 2004. All rights reserved</TD></TR>
</TABLE>
</P>
<H2>Contents</H2>
<DL STYLE='margin-left:1em'>
<DT>1. <A HREF='#overview'>Overview</A>
<DT>2. <A HREF='#usage'>Usage</A>
<DT>3. <A HREF='#rationale'>Rationale</A>
<DT>4. <A HREF='#synopsis'>Synopsis</A>
<DT>5. <A HREF='#dependencies'>Dependencies</A>
<DT>6. <A HREF='#portability'>Portability</A>
</DL>
<A NAME='overview'></A>
<H2>Overview</H2>
<P>
The header <A HREF='../../boost/utility/select_by_size.hpp'><SPAN CLAS='code'>&lt;boost/utility/select_by_size.hpp&gt;</SPAN></A> provides template classes and macros for determining the results of overload resolution at compile time using <SPAN CLASS='code'>sizeof</SPAN>. It is intended as an alternative to <A HREF='http://www.boost.org/boost/type_traits/detail/yes_no_type.hpp'><SPAN CLASS='code'>type_traits::yes_type</SPAN></A> and <A HREF='http://www.boost.org/boost/type_traits/detail/yes_no_type.hpp'><SPAN CLASS='code'>type_traits::no_type</SPAN></A> from the <A HREF='http://www.boost.org/libs/type_traits/index.html'>Type Traits</A> library. It provides an arbitrary number of types, <SPAN CLASS='code'>case_&lt;0&gt;</SPAN>, <SPAN CLASS='code'>case_&lt;1&gt;</SPAN>, <SPAN CLASS='code'>case_&lt;2&gt;</SPAN>, <SPAN CLASS='code'>... </SPAN>, for use as the return types of helper functions, plus a template <SPAN CLASS='code'>select_by_size</SPAN> which provides access to the result of the overload resolution. There is also a macro <SPAN CLASS='code'>BOOST_SELECT_BY_SIZE</SPAN>, similar to <A HREF='http://www.boost.org/libs/config/config.htm'><SPAN CLASS='code'>BOOST_STATIC_CONSTANT</SPAN></A>, for use with compilers which have trouble with integral constant expressions. (<I>See</I> <A HREF='http://www.boost.org/more/int_const_guidelines.htm'>Coding Guidelines for Integral Constant Expressions</A>.) For convenience, a single return type representing a negative value is also provided: <SPAN CLASS='code'>case_&lt;-1&gt;</SPAN>.
</P>
<P>All types decribes in this document reside in the namespace <SPAN CLASS='code'>boost::utility</SPAN>.
<H3>The template <SPAN CLASS='headingCode'>case_</SPAN></H3>
<P>
The defining property of the class template <SPAN CLASS='code'>case_</SPAN> is that the sizes of the types
<PRE> case_&lt;-1&gt;, case_&lt;0&gt;, case_&lt;1&gt;, case_&lt;2&gt;, case_&lt;3&gt;, ...</PRE>
form a strictly increasing sequence. With well-behaved implementations, <SPAN CLASS='code'>sizeof(case_&lt;-1&gt;)</SPAN> will be small, as will be the difference in size between adjacent types in the sequence.
</P>
<P>
The <SPAN CLASS='code'>typedefs</SPAN> <SPAN CLASS='code'>yes_type</SPAN> and <SPAN CLASS='code'>no_type</SPAN> are provided as shorthands for <SPAN CLASS='code'>case_&lt;1&gt;</SPAN> and <SPAN CLASS='code'>case_&lt;0&gt;</SPAN>. Naturally, <SPAN CLASS='code'>case_&lt;true&gt;</SPAN> and <SPAN CLASS='code'>case_&lt;false&gt;</SPAN> may also be used.
</P>
<H3>The template <SPAN CLASS='headingCode'>select_by_size</SPAN></H3>
<P>
The defining property of the class template <SPAN CLASS='code'>select_by_size</SPAN> is that for each integer <SPAN CLASS='code'>N</SPAN> in the range <SPAN CLASS='code'>select_by_size</SPAN> through <SPAN CLASS='code'>BOOST_SELECT_BY_SIZE_MAX_CASE</SPAN>, we have the equality
<PRE> select_by_size< sizeof(case_&lt;N&gt;) >::value == N</PRE>
</P>
<H3>The macro <SPAN CLASS='headingCode'>BOOST_SELECT_BY_SIZE_MAX_CASE</SPAN></H3>
<P>
In order to make use of <SPAN CLASS='code'>select_by_size</SPAN> with specializations <SPAN CLASS='code'>case_&lt;N&gt;</SPAN> for <SPAN CLASS='code'>N</SPAN> other than <SPAN CLASS='code'>-1</SPAN>, <SPAN CLASS='code'>0</SPAN> and <SPAN CLASS='code'>1</SPAN>,
the symbol <SPAN CLASS='code'>BOOST_SELECT_BY_SIZE_MAX_CASE</SPAN> must be defined as an intergral value greater than or equal to <SPAN CLASS='code'>N</SPAN> before including the header <SPAN CLAS='code'>&lt;boost/utility/select_by_size.hpp&gt;</SPAN>. The header may be included multiple times with different values of <SPAN CLASS='code'>BOOST_SELECT_BY_SIZE_MAX_CASE</SPAN>.
</P>
<H3>The macro <SPAN CLASS='headingCode'>BOOST_SELECT_BY_SIZE</SPAN></H3>
<P>
The macro <SPAN CLASS='code'>BOOST_SELECT_BY_SIZE(type, name, expr)</SPAN> can be used similarly to <SPAN CLASS='code'>BOOST_STATIC_CONSTANT</SPAN> to define a <SPAN CLASS='code'>static const</SPAN> intergral class member <SPAN CLASS='code'>name</SPAN> of type <SPAN CLASS='code'>type</SPAN> with value equal to <SPAN CLASS='code'>select_by_size< sizeof(expr) >::value</SPAN>.
</P>
<A NAME='usage'></A>
<H2>Usage</H2>
<PRE> #include &lt;boost/static_assert.hpp&gt;
#define BOOST_SELECT_BY_SIZE_MAX_CASE 7
#include &lt;boost/utility/select_by_size.hpp&gt;
using namespace boost::utility;
case_&lt;0&gt; helper(bool);
case_&lt;1&gt; helper(int);
case_&lt;2&gt; helper(unsigned);
case_&lt;3&gt; helper(long);
case_&lt;4&gt; helper(unsigned long);
case_&lt;5&gt; helper(float);
case_&lt;6&gt; helper(double);
case_&lt;7&gt; helper(const char*);
struct test {
static const int value =
select_by_size&lt; sizeof(helper("hello")) &gt;::value;
BOOST_STATIC_ASSERT(value == 7);
};
struct test2 {
BOOST_SELECT_BY_SIZE(int, value, helper("hello"));
BOOST_STATIC_ASSERT(value == 7);
};</PRE>
<A NAME='rationale'></A>
<H2>Rationale</H2>
The utility of <SPAN CLASS='code'>type_traits::yes_type</SPAN> and <SPAN CLASS='code'>type_traits::no_type</SPAN> is well-known. The advantages of using <SPAN CLASS='code'>select_by_size</SPAN> are:
<UL type='box'>
<LI STYLE='list-style-type: square'>It documents the fact that <SPAN CLASS='code'>sizeof</SPAN> is being used to determine the result of overload resolution.
<LI STYLE='list-style-type: square'>It eliminates the need to compare a given <SPAN CLASS='code'>sizeof</SPAN> expression with <SPAN CLASS='code'>sizeof(type_traits::yes_type)</SPAN>.
<LI STYLE='list-style-type: square'>It allows the use of an aribtrary number of cases.</LI>
</UL>
<P>
Until recently the author was aware of only one use for item (3). Thus he regarded the use of <SPAN CLASS='code'>select_by_size</SPAN> with more than two cases 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 <A HREF='../../boost/mpl/aux_/template_arity.hpp'><SPAN CLAS='code'>&lt;boost/mpl/aux_/template_arity.hpp&gt;</SPAN></A>, Joel de Guzman's type deduction system in the <A HREF='http://www.boost.org/more/mailing_lists.htm#sandbox'>Boost Sandbox</A> at <SPAN CLAS='code'>&lt;boost/utility/type_deduction.hpp&gt;</SPAN>, and Reece Dunn's type deduction system for his Output Formatters library, also in the <A HREF='http://www.boost.org/more/mailing_lists.htm#sandbox'>Boost Sandbox</A>, at <SPAN CLAS='code'>&lt;boost/outfmt/detail/type_traits.hpp&gt;</SPAN>.
</P>
<P>
</P>
<A NAME='Synopsis'></A>
<H2>Synopsis</H2>
<PRE> namespace boost {
namespace utility {
template&lt;int N&gt; struct <B>case_</B>;
template&lt;unsigned N&gt;
struct <B>select_by_size</B> {
struct type {
static const unsigned value =
[M <I>such that</I> sizeof(case_&lt;M&gt;) == N];
};
static const unsigned value = type::value;
};
#define <B>BOOST_SELECT_BY_SIZE</B>(type, name, expr) [<I>implementation-defined</I>]
}
}</PRE>
<A NAME='dependencies'></A>
<H2>Dependencies</H2>
The header <A HREF='../../boost/utility/select_by_size.hpp'><SPAN CLAS='code'>&lt;boost/utility/select_by_size.hpp&gt;</SPAN></A> depends on <A HREF='http://www.boost.org/libs/config/config.htm'>Boost.Config</A> and <A HREF='http://www.boost.org/libs/preprocessor/doc/index.html'>Boost.Preprocessor</A>.
<A NAME='portability'></A>
<H2>Portability</H2>
<P>
The program <A HREF='select_by_size_test.cpp'><SPAN CLAS='code'>&lt;libs/utility/select_by_size_test.cpp&gt;</SPAN></A> has been tested successfully with the following compilers:
<UL type='box'>
<LI STYLE='list-style-type: square'>Microsoft Visual C++ 6.0, SP 5</LI>
<LI STYLE='list-style-type: square'>Microsoft Visual C++ 7.1</LI>
<LI STYLE='list-style-type: square'>Metrowerks CodeWariror 8.0</LI>
<LI STYLE='list-style-type: square'>Intel C++ Compiler for Windows 7.1 and 8.0</LI>
<LI STYLE='list-style-type: square'>GCC 2.95.3-10 (cygwin special)</LI>
<LI STYLE='list-style-type: square'>GCC 3.2 (MinGW)</LI>
<LI STYLE='list-style-type: square'>GCC 3.3.1 (cygming special)</LI>
<LI STYLE='list-style-type: square'>Comeau C/C++ 4.3.3</LI>
<LI STYLE='list-style-type: square'>Borland C++ 5.5.1 and 5.6.4</LI>
<LI STYLE='list-style-type: square'>DigitalMars 8.38n</LI>
</UL>
</P>
<HR STYLE='margin:20,0,0'>
<P STYLE='font-size:8pt'>
&copy; Copyright Jonathan Turkanis 2004.
Permission to copy, use, modify, sell and distribute this document
is granted provided this copyright notice appears in all copies. This
document is provided "as is" without express or implied warranty, and
with no claim as to its suitability for any purpose.
</P>
</BODY>