forked from boostorg/mpl
Added libs/mpl
[SVN r15384]
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
|
||||
<title>4. Code generation facilities</title>
|
||||
<link rel="stylesheet" href="article.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.50.0">
|
||||
<meta name="keywords" content="template metaprogramming, generic programming, programming languages, C++, STL, type systems, polymorphism, compile-time">
|
||||
<link rel="home" href="index.html" title="the boost c++ metaprogramming library">
|
||||
<link rel="up" href="index.html" title="the boost c++ metaprogramming library">
|
||||
<link rel="previous" href="lambda.html" title="3. lambda facility">
|
||||
<link rel="next" href="example.html" title="5. example: a compile-time fsm generator">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<div class="navheader">
|
||||
<table width="100%" summary="Navigation header">
|
||||
<tr>
|
||||
<th colspan="3" align="center">4. Code generation facilities</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="20%" align="left"><a accesskey="p" href="lambda.html">Prev</a> </td>
|
||||
<th width="60%" align="center"> </th>
|
||||
<td width="20%" align="right"> <a accesskey="n" href="example.html">Next</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<div class="titlepage">
|
||||
<div>
|
||||
<h2 class="title" style="clear: both"><a name="codegeneration"></a>4. Code generation facilities</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>There are cases, especially in the domain of numeric computation, when one wants to perform some part of the calculations at compile-time, and then pass the results to a run-time part of the program for further processing. For example, suppose one has implemented a complex compile-time algorithm that works with fixed-point arithmetic:</p>
|
||||
|
||||
<pre class="programlisting">
|
||||
// fixed-point algorithm input
|
||||
typedef mpl::vector<
|
||||
mpl::fixed_c<-1,2345678>
|
||||
, mpl::fixed_c<9,0001>
|
||||
// ..
|
||||
, mpl::fixed_c<3,14159>
|
||||
> input_data;
|
||||
|
||||
/*
|
||||
complex compile-time algorithm
|
||||
*/
|
||||
typedef /*...*/ result_data;
|
||||
</pre>
|
||||
|
||||
<p>Suppose the <tt>result_data</tt> here is a sequence of <tt>mpl::fixed_c</tt> types that keeps the results of the algorithm, and now one wishes to feed that result to the run-time part of the algorithm. With MPL she can do this:</p>
|
||||
|
||||
<pre class="programlisting">
|
||||
double my_algorithm()
|
||||
{
|
||||
// passing the results to the run-time part of the program
|
||||
std::vector<double> results;
|
||||
results.reserve(mpl::size<result_data>::value);
|
||||
mpl::for_each<numbers,_>(
|
||||
boost::bind(&std::vector<double>::push_back, &results, _1)
|
||||
);
|
||||
// ...
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>The <tt>for_each<numbers,_>(...)</tt> call is what actually transfers the compile-time <tt>result_data</tt> into run-time <tt>results</tt>. <tt>for_each</tt> is a function template declared as:</p>
|
||||
|
||||
<pre class="programlisting">
|
||||
template<
|
||||
typename Seq
|
||||
, typename TransformOp
|
||||
, typename F
|
||||
>
|
||||
void for_each(F f)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>To call the function, one is required to explicitly provide two actual template parameters, a compile-time sequence <tt>Seq</tt> and a unary transformation metafunction <tt>TransformOp</tt>, plus a run-time function argument <tt>f</tt> (in our example, <tt>numbers</tt>, <tt>_</tt>, and <tt>boost::bind(...)</tt> correspondingly). <tt>f</tt> is a function object which <tt>operator()</tt> is called for every element in the <tt>Seq</tt> tranfromed by <tt>TransformOp</tt>.</p>
|
||||
|
||||
<p>Applying this to our example, the</p>
|
||||
|
||||
<pre class="programlisting">
|
||||
mpl::for_each<numbers,_>(
|
||||
boost::bind(&std::vector<double>::push_back, &results, _1)
|
||||
);
|
||||
</pre>
|
||||
|
||||
<p>call is roughly equivalent to this:</p>
|
||||
|
||||
<pre class="programlisting">
|
||||
f(mpl::apply< _,mpl::at_c<result_data,0>::type >::type());
|
||||
f(mpl::apply< _,mpl::at_c<result_data,1>::type >::type());
|
||||
// ...
|
||||
f(mpl::apply< _,mpl::at_c<result_data,n>::type >::type());
|
||||
</pre>
|
||||
|
||||
<p>where <tt>n == mpl::size<result_data>::type::value</tt>.</p>
|
||||
</div>
|
||||
|
||||
<div class="navfooter">
|
||||
<hr>
|
||||
<table width="100%" summary="Navigation footer">
|
||||
<tr>
|
||||
<td width="40%" align="left"><a accesskey="p" href="lambda.html">Prev</a> </td>
|
||||
<td width="20%" align="center"><a accesskey="u" href="index.html">Up</a></td>
|
||||
<td width="40%" align="right"> <a accesskey="n" href="example.html">Next</a></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="40%" align="left" valign="top">3. Lambda facility </td>
|
||||
<td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
|
||||
<td width="40%" align="right" valign="top"> 5. Example: a compile-time FSM generator</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user