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