forked from boostorg/utility
initial commitment
[SVN r1963]
This commit is contained in:
186
select_by_size.html
Normal file
186
select_by_size.html
Normal 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'><boost/utility/select_by_size.hpp></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_<0></SPAN>, <SPAN CLASS='code'>case_<1></SPAN>, <SPAN CLASS='code'>case_<2></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_<-1></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_<-1>, case_<0>, case_<1>, case_<2>, case_<3>, ...</PRE>
|
||||
form a strictly increasing sequence. With well-behaved implementations, <SPAN CLASS='code'>sizeof(case_<-1>)</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_<1></SPAN> and <SPAN CLASS='code'>case_<0></SPAN>. Naturally, <SPAN CLASS='code'>case_<true></SPAN> and <SPAN CLASS='code'>case_<false></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_<N>) >::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_<N></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'><boost/utility/select_by_size.hpp></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 <boost/static_assert.hpp>
|
||||
#define BOOST_SELECT_BY_SIZE_MAX_CASE 7
|
||||
#include <boost/utility/select_by_size.hpp>
|
||||
|
||||
using namespace boost::utility;
|
||||
|
||||
case_<0> helper(bool);
|
||||
case_<1> helper(int);
|
||||
case_<2> helper(unsigned);
|
||||
case_<3> helper(long);
|
||||
case_<4> helper(unsigned long);
|
||||
case_<5> helper(float);
|
||||
case_<6> helper(double);
|
||||
case_<7> helper(const char*);
|
||||
|
||||
struct test {
|
||||
static const int value =
|
||||
select_by_size< sizeof(helper("hello")) >::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'><boost/mpl/aux_/template_arity.hpp></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'><boost/utility/type_deduction.hpp></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'><boost/outfmt/detail/type_traits.hpp></SPAN>.
|
||||
</P>
|
||||
|
||||
<P>
|
||||
</P>
|
||||
|
||||
<A NAME='Synopsis'></A>
|
||||
<H2>Synopsis</H2>
|
||||
|
||||
<PRE> namespace boost {
|
||||
namespace utility {
|
||||
|
||||
template<int N> struct <B>case_</B>;
|
||||
|
||||
template<unsigned N>
|
||||
struct <B>select_by_size</B> {
|
||||
struct type {
|
||||
static const unsigned value =
|
||||
[M <I>such that</I> sizeof(case_<M>) == 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'><boost/utility/select_by_size.hpp></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'><libs/utility/select_by_size_test.cpp></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'>
|
||||
© 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>
|
Reference in New Issue
Block a user