mirror of
https://github.com/boostorg/mpl.git
synced 2026-01-27 09:22:19 +01:00
125 lines
4.6 KiB
HTML
125 lines
4.6 KiB
HTML
<!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>
|
|
|