<b>Why:</b> Macro expansion proceeds recursively in "layers."
Stringization prevents the preprocessor from performing macro expansion, therefore it is often necessary to delay stringization.
</div>
<h4>Example<u> - Use BOOST_PP_ENUM_PARAMS (and its variants) or BOOST_PP_REPEAT and BOOST_PP_COMMA_IF to avoid <i>O</i>(<i>n</i>) repetition on lists in general.</u></h4>
<divclass="code"><pre>
struct make_type_list_end;
template<
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
MAKE_TYPE_LIST_MAX_LENGTH,
class T,
make_type_list_end
)
>
struct make_type_list {
private:
enum { end = is_same<T0, make_type_list_end>::value };
<i>Note: This is no longer how BOOST_PP_REPEAT is implemented, so the code above is illustrative only! </i>
</div>
<div>
BOOST_PP_ENUM_PARAMS and its variations use BOOST_PP_REPEAT.
BOOST_PP_COMMA_IF(I) expands to a comma if I != 0.
BOOST_PP_INC(I) essentially expands to "I+1," and BOOST_PP_DEC(I) essentially expands to "I-1.".
</div>
<h4>Example<u> - Use a <i>conditional macro definition</i> to enable user configuration of code repetition based on need rather than some "reasonable" upper limit.</u></h4>
<divclass="code"><pre>
#ifndef MAKE_TYPE_LIST_MAX_LENGTH
#define MAKE_TYPE_LIST_MAX_LENGTH 8
#endif
</pre></div>
<div>
Now the user can configure the <code>make_type_list</code> primitive without modifying library code.
</div>
<h4>Example<u> - Use BOOST_PP_REPEAT and a <i>token look-up function</i> to eliminate categorical repetition.</u></h4>
<divclass="code"><pre>
// CAVEAT: My compiler is not standard on arithmetic types.
<b>Note:</b> The repetition of the above example can be eliminated using template metaprogramming <ahref="../bibliography.html#czarnecki">[Czarnecki]</a> as well.
BOOST_PP_IF enables convenient generation of lists using BOOST_PP_REPEAT.
</div>
<div>
<b>Note:</b> <i>THEN</i> and <i>ELSE</i> don't have to be macros.
However, if at least one of them is a function-like macro, and you want it be expanded conditionally,
you have to make the other parameter a function-like macro too.
This can often be done using BOOST_PP_IDENTITY.
Consider the following example (by Aleksey Gurtovoy):
</div>
<div><pre>
#define NUMBERED_EXPRESSION(i, x) /* ... */ \
BOOST_PP_IF( \
i, \
BOOST_PP_IDENTITY(x ## i) \
BOOST_PP_EMPTY \
)() \
/**/
</pre></div>
<div>
<b>Note:</b> Like in the above implementation of COMMA_IF, the result of BOOST_PP_IF is often invoked and not the <i>THEN</i> and <i>ELSE</i> parameters.
If the parameters were invoked, the code would not expand correctly, because the BOOST_PP_EMPTY parameter would get expanded
to nothing before the <b>BOOST_PP_IF</b> would be properly expanded.
</div>
<div>
<b>How:</b> BOOST_PP_IF is defined for the entire repeat range (psuedo code):