1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
<html>
<head>
<title>local_iteration.html</title>
<link rel="stylesheet" type="text/css" href="../styles.css">
</head>
<body>
<h4>Local Iteration</h4>
<div>
Local iteration is a simple vertical repetition construct.
It expands a macro with each number in a user-specified range.
Each expansion is on a separate line.
</div>
<h4>Tutorial</h4>
<div>
This mechanism requires two pieces of information to operate:
a range to iterate over and a macro to expand on each iteration.
This information is obtained by the mechanism through two <i>named external arguments</i>.
These arguments are specified as user-defined macros named <b>BOOST_PP_LOCAL_LIMITS</b> and <b>BOOST_PP_LOCAL_MACRO</b>.
</div>
<div>
<b>BOOST_PP_LOCAL_LIMITS</b> specifies a range of values to iterate over.
It <i>must</i> expand to a <i>tuple</i> containing two elements--a lower and upper bound.
Both the upper and lower bounds must be numeric values in the range of <i>0</i> to <b>BOOST_PP_LIMIT_ITERATION</b>.
For example, if the user wishes a macro to be expanded with numbers ranging from <i>0</i> to <i>10</i>,
<b>BOOST_PP_LOCAL_LIMITS</b> would be defined like this:
</div>
<div class="code"><pre>
#define BOOST_PP_LOCAL_LIMITS (0, 10)
</pre></div>
<div>
Note that there is whitespace after the name of the macro.
The macro <i>does not</i> take <i>two</i> arguments.
In the case above, if there was no whitespace, a preprocessing error would occur because <i>0</i> and <i>10</i> are invalid identifiers.
</div>
<div>
Both the upper and lower bounds specified in the <b>BOOST_PP_LOCAL_LIMITS</b> macro are <i>evaluated parameters</i>.
This implies that they can include simple arithmetic or logical expressions.
For instance, the above definition could easily have been written like this:
</div>
<div class="code"><pre>
#define N() 5
#define BOOST_PP_LOCAL_LIMITS (0, N() + 5)
</pre></div>
<div>
Because of this, if the whitespace after the macro name is elided, it is possible for the definition to be syntactically valid:
</div>
<div class="code"><pre>
#define A 0
#define B 10
#define BOOST_PP_LOCAL_LIMITS(A, B)
// note: no whitespace ^
</pre></div>
<div>
If this happens, an error will occur inside the mechanism when it attempts to use this macro.
The error messages that result may be obscure, so always remember to include the whitespace.
A <i>correct</i> version of the above looks like this:
</div>
<div class="code"><pre>
#define A 0
#define B 10
#define BOOST_PP_LOCAL_LIMITS (A, B)
// note: has whitespace ^
</pre></div>
<div>
<b>BOOST_PP_LOCAL_MACRO</b> is the macro that is expanded by the mechanism.
This macro is expanded on each iteration with the current number of the iteration.
It must defined as a unary macro <i>or</i> result in a macro that can be called with one argument:
</div>
<div class="code"><pre>
#define BOOST_PP_LOCAL_MACRO(n) \
template<> struct sample<n> { }; \
/**/
</pre></div>
<div>
...or...
</div>
<div class="code"><pre>
#define SAMPLE(n) \
template<> struct sample<n> { }; \
/**/
#define BOOST_PP_LOCAL_MACRO SAMPLE
</pre></div>
<div>
Once these two macros are defined, the local iteration is initiated by <i>including</i> <b>BOOST_PP_LOCAL_ITERATE</b>().
</div>
<div class="code"><pre>
??=include BOOST_PP_LOCAL_ITERATE()
</pre></div>
<div>
(The <code>??=</code> token is a trigraph for <code>#</code>.
I use the trigraph to make it clear that I am <i>including</i> a file rather than defining or expanding a macro, but it is not necessary.
Even the digraph version, <code>%:</code>, could be used.
Some compilers do not readily accept trigraphs and digraphs, so keep that in mind.
Other than that, use whichever one you prefer.)
</div>
<div>
In order to repeat the <code>sample</code> specialization, the pieces must be put together....
</div>
<div class="code"><pre>
#define BOOST_PP_LOCAL_MACRO(n) \
template<> struct sample<n> { }; \
/**/
#define BOOST_PP_LOCAL_LIMITS (0, 10)
??=include BOOST_PP_LOCAL_ITERATE()
</pre></div>
<div>
This will result in a specialization of <code>sample</code> for each number in the range of <i>0</i> to <i>10</i>.
The output will look something like this:
</div>
<div class="code"><pre>
template<> struct sample<0> { };
template<> struct sample<1> { };
template<> struct sample<2> { };
// ...
template<> struct sample<10> { };
</pre></div>
<div>
After the local-iteration is complete, both <b>BOOST_PP_LOCAL_LIMITS</b> and <b>BOOST_PP_LOCAL_MACRO</b> are automatically undefined.
If the values need to be retained for a future local-iteration, they must be defined indirectly:
</div>
<div class="code"><pre>
#define LIMITS (0, 10)
#define SAMPLE(n) \
template<> struct sample<n> { }; \
/**/
#define BOOST_PP_LOCAL_LIMITS LIMITS
#define BOOST_PP_LOCAL_MACRO(n) SAMPLE(n)
??=include BOOST_PP_LOCAL_ITERATE()
</pre></div>
<h4>See Also</h4>
<ul>
<li><a href="../ref/local_iterate.html">BOOST_PP_LOCAL_ITERATE</a></li>
<li><a href="../ref/local_limits.html">BOOST_PP_LOCAL_LIMITS</a></li>
<li><a href="../ref/local_macro.html">BOOST_PP_LOCAL_MACRO</a></li>
</ul>
<div class="sig">- Paul Mensonides</div>
<hr size="1">
<div style="margin-left: 0px;">
<i> Copyright <a href="http://www.housemarque.com" target="_top">Housemarque Oy</a> 2002</i>
</br><i> Copyright Paul Mensonides 2002</i>
</div>
<div style="margin-left: 0px;">
<p><small>Distributed under the Boost Software License, Version 1.0. (See
accompanying file <a href="../../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
copy at <a href=
"http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</small></p>
</div>
</body>
</html>
|