1<?xml version="1.0" encoding="utf-8" ?> 2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html 3 4 lang="en" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> 5 <head> 6 <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" /> 7 <meta name="generator" content="Docutils 0.3.8: http://docutils.sourceforge.net/" /> 8 <title>Appendix A - An Introduction to Preprocessor Metaprogramming</title> 9 <meta name="copyright" content="From "C++ Template Metaprogramming," by David Abrahams and Aleksey Gurtovoy. Copyright (c) 2005 by Pearson Education, Inc. Reprinted with permission." /> 10 <style type="text/css"> 11 12/* 13:Author: David Goodger 14:Contact: goodger@users.sourceforge.net 15:date: $Date: 2004/06/23 13:31:26 $ 16:version: $Revision: 1.37 $ 17:copyright: This stylesheet has been placed in the public domain. 18 19Default cascading style sheet for the HTML output of Docutils. 20*/ 21 22.first { 23 margin-top: 0 } 24 25.last { 26 margin-bottom: 0 } 27 28a.toc-backref { 29 text-decoration: none ; 30 color: black } 31 32blockquote.epigraph { 33 margin: 2em 5em ; } 34 35dd { 36 margin-bottom: 0.5em } 37 38/* Uncomment (& remove this text!) to get bold-faced definition list terms 39dt { 40 font-weight: bold } 41*/ 42 43div.abstract { 44 margin: 2em 5em } 45 46div.abstract p.topic-title { 47 font-weight: bold ; 48 text-align: center } 49 50div.attention, div.caution, div.danger, div.error, div.hint, 51div.important, div.note, div.tip, div.warning, div.admonition { 52 margin: 2em ; 53 border: medium outset ; 54 padding: 1em } 55 56div.attention p.admonition-title, div.caution p.admonition-title, 57div.danger p.admonition-title, div.error p.admonition-title, 58div.warning p.admonition-title { 59 color: red ; 60 font-weight: bold ; 61 font-family: sans-serif } 62 63div.hint p.admonition-title, div.important p.admonition-title, 64div.note p.admonition-title, div.tip p.admonition-title, 65div.admonition p.admonition-title { 66 font-weight: bold ; 67 font-family: sans-serif } 68 69div.dedication { 70 margin: 2em 5em ; 71 text-align: center ; 72 font-style: italic } 73 74div.dedication p.topic-title { 75 font-weight: bold ; 76 font-style: normal } 77 78div.figure { 79 margin-left: 2em } 80 81div.footer, div.header { 82 font-size: smaller } 83 84div.sidebar { 85 margin-left: 1em ; 86 border: medium outset ; 87 padding: 0em 1em ; 88 background-color: #ffffee ; 89 width: 40% ; 90 float: right ; 91 clear: right } 92 93div.sidebar p.rubric { 94 font-family: sans-serif ; 95 font-size: medium } 96 97div.system-messages { 98 margin: 5em } 99 100div.system-messages h1 { 101 color: red } 102 103div.system-message { 104 border: medium outset ; 105 padding: 1em } 106 107div.system-message p.system-message-title { 108 color: red ; 109 font-weight: bold } 110 111div.topic { 112 margin: 2em } 113 114h1.title { 115 text-align: center } 116 117h2.subtitle { 118 text-align: center } 119 120hr { 121 width: 75% } 122 123ol.simple, ul.simple { 124 margin-bottom: 1em } 125 126ol.arabic { 127 list-style: decimal } 128 129ol.loweralpha { 130 list-style: lower-alpha } 131 132ol.upperalpha { 133 list-style: upper-alpha } 134 135ol.lowerroman { 136 list-style: lower-roman } 137 138ol.upperroman { 139 list-style: upper-roman } 140 141p.attribution { 142 text-align: right ; 143 margin-left: 50% } 144 145p.caption { 146 font-style: italic } 147 148p.credits { 149 font-style: italic ; 150 font-size: smaller } 151 152p.label { 153 white-space: nowrap } 154 155p.rubric { 156 font-weight: bold ; 157 font-size: larger ; 158 color: maroon ; 159 text-align: center } 160 161p.sidebar-title { 162 font-family: sans-serif ; 163 font-weight: bold ; 164 font-size: larger } 165 166p.sidebar-subtitle { 167 font-family: sans-serif ; 168 font-weight: bold } 169 170p.topic-title { 171 font-weight: bold } 172 173pre.address { 174 margin-bottom: 0 ; 175 margin-top: 0 ; 176 font-family: serif ; 177 font-size: 100% } 178 179pre.line-block { 180 font-family: serif ; 181 font-size: 100% } 182 183pre.literal-block, pre.doctest-block { 184 margin-left: 2em ; 185 margin-right: 2em ; 186 background-color: #eeeeee } 187 188span.classifier { 189 font-family: sans-serif ; 190 font-style: oblique } 191 192span.classifier-delimiter { 193 font-family: sans-serif ; 194 font-weight: bold } 195 196span.interpreted { 197 font-family: sans-serif } 198 199span.option { 200 white-space: nowrap } 201 202span.option-argument { 203 font-style: italic } 204 205span.pre { 206 white-space: pre } 207 208span.problematic { 209 color: red } 210 211table { 212 margin-top: 0.5em ; 213 margin-bottom: 0.5em } 214 215table.citation { 216 border-left: solid thin gray ; 217 padding-left: 0.5ex } 218 219table.docinfo { 220 margin: 2em 4em } 221 222table.footnote { 223 border-left: solid thin black ; 224 padding-left: 0.5ex } 225 226dt { 227 font-weight: bold } 228 229td, th { 230 padding-left: 0.5em ; 231 padding-right: 0.5em ; 232 vertical-align: top } 233 234th.docinfo-name, th.field-name { 235 font-weight: bold ; 236 text-align: left ; 237 white-space: nowrap } 238 239h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { 240 font-size: 100% } 241 242tt { 243 background-color: #eeeeee } 244 245ul.auto-toc { 246 list-style-type: none } 247 248</style> </head> 249 <body><br /> 250 <div class="document" id="preprocessor-title"> 251 <h1 class="title">Appendix A - An Introduction to Preprocessor 252 Metaprogramming</h1> 253 <table class="docinfo" frame="void" rules="none"> 254 <colgroup><col class="docinfo-name" /> <col class="docinfo-content" /> 255 </colgroup> 256 <tbody valign="top"> 257 <tr> 258 <th class="docinfo-name">Copyright:</th> 259 <td>From "C++ Template Metaprogramming," by David Abrahams and 260 Aleksey Gurtovoy. Copyright (c) 2005 by Pearson Education, Inc. 261 Reprinted with permission.</td> 262 </tr> 263 <tr class="field"> 264 <th class="docinfo-name">ISBN:</th> 265 <td class="field-body">0321227255</td> 266 </tr> 267 </tbody> 268 </table> 269 <div class="section" id="motivation"> 270 <h1><a name="motivation">A.1 Motivation</a></h1> 271 <p>Even with the full power of template metaprogramming and the <a class="reference" 272 273 href="http://www.boost.org/libs/mpl">Boost Metaprogramming library</a> 274 at our disposal, some C++ coding jobs still require a great deal of 275 boilerplate code repetition. We saw one example in Chapter 5, when we 276 implemented <tt class="docutils literal"><span class="pre">tiny_size</span></tt>:</p> 277 <pre class="literal-block">template <class T0, class T1, class T2> 278struct tiny_size 279 : mpl::int_<3> {}; 280</pre> 281 <!-- : rst-mode hack --> 282 <!-- @prefix.append('struct none {};') --> 283 <p>Aside from the repeated pattern in the parameter list of the primary 284 template above, there are three partial specializations below, which 285 also follow a predictable pattern:</p> 286 <pre class="literal-block">template <class T0, class T1> 287struct tiny_size<T0,T1,none> 288 : mpl::int_<2> {}; 289 290template <class T0> 291struct tiny_size<T0,none,none> 292 : mpl::int_<1> {}; 293 294template <> 295struct tiny_size<none,none,none> 296 : mpl::int_<0> {}; 297</pre> 298 <!-- : rst-mode hack --> 299 <!-- @compile('all') --> 300 <p>In this case there is only a small amount of code with such a 301 "mechanical" flavor, but had we been implementing <tt class="docutils literal"><span 302 303 class="pre">large</span></tt> instead of <tt class="docutils literal"><span 304 305 class="pre">tiny</span></tt>, there might easily have been a great 306 deal more. When the number of instances of a pattern grows beyond two 307 or three, writing them by hand tends to become error-prone. Perhaps 308 more importantly, the code gets hard to read, because the important 309 abstraction in the code is really the pattern, not the individual 310 instances.</p> 311 <div class="section" id="code-generation"> 312 <h2><a name="code-generation">A.1.1 Code Generation</a></h2> 313 <p>Rather than being written out by hand, mechanical-looking code 314 should really be generated mechanically. Having written a program to 315 spit out instances of the code pattern, a library author has two 316 choices: She can either ship pre-generated source code files, or she 317 can ship the generator itself. Either approach has drawbacks. If 318 clients only get the generated source, they are stuck with whatever 319 the library author generated—and experience shows that if they are 320 happy with three instances of a pattern today, someone will need 321 four tomorrow. If clients get the generator program, on the other 322 hand, they also need the resources to execute it (e.g., 323 interpreters), and they must integrate the generator into their 324 build processes...</p> 325 </div> 326 <div class="section" id="enter-the-preprocessor"> 327 <h2><a name="enter-the-preprocessor">A.1.2 Enter the Preprocessor</a></h2> 328 <p>...unless the generator is a preprocessor metaprogram. Though not 329 designed for that purpose, the C and C++ preprocessors can be made 330 to execute sophisticated programs during the preprocessing phase of 331 compilation. Users can control the code generation process with 332 preprocessor <tt class="docutils literal"><span class="pre">#define</span></tt>s 333 in code or <tt class="docutils literal"><span class="pre">-D</span></tt> 334 options on the compiler's command line, making build integration 335 trivial. For example, we might parameterize the primary <tt class="docutils literal"><span 336 337 class="pre">tiny_size</span></tt> template above as follows:</p> 338 <pre class="literal-block">#include <<strong>boost/preprocessor/repetition/enum_params</strong>.hpp> 339 340#ifndef TINY_MAX_SIZE 341# define TINY_MAX_SIZE 3 // default maximum size is 3 342#endif 343 344template <<strong>BOOST_PP_ENUM_PARAMS(TINY_MAX_SIZE, class T)</strong>> 345struct tiny_size 346 : mpl::int_<TINY_MAX_SIZE> 347{}; 348</pre> 349 <!-- : rst-mode hack --> 350 <!-- @compile(pop = None) --> 351 <p>To test the metaprogram, run your compiler in its "preprocessing" 352 mode (usually the <tt class="docutils literal"><span class="pre">-E</span></tt> 353 option), with the Boost root directory in your <tt class="docutils literal"><span 354 355 class="pre">#include</span></tt> path. For instance:<a class="footnote-reference" 356 357 href="#minusp" id="id2" name="id2">[1]</a></p> 358 <pre class="literal-block">g++ -P -E -Ipath/to/boost_1_32_0 -I. test.cpp 359</pre> 360 <!-- @ignore() --> 361 <table class="docutils footnote" frame="void" id="minusp" rules="none"> 362 <colgroup><col class="label" /><col /></colgroup> 363 <tbody valign="top"> 364 <tr> 365 <td class="label"><a class="fn-backref" href="#id2" name="minusp">[1]</a></td> 366 <td>GCC's <tt class="docutils literal"><span class="pre">-P</span></tt> 367 option inhibits the generation of source file and line number 368 markers in preprocessed output.</td> 369 </tr> 370 </tbody> 371 </table> 372 <p>Given the appropriate metaprograms, users would be able to adjust 373 not only the number of parameters to <tt class="docutils literal"><span 374 375 class="pre">tiny_size</span></tt>, but the maximum size of the 376 entire <tt class="docutils literal"><span class="pre">tiny</span></tt> 377 implementation just by <tt class="docutils literal"><span class="pre">#define</span></tt>-ing 378 <tt class="docutils literal"><span class="pre">TINY_MAX_SIZE</span></tt>.</p> 379 <p>The Boost Preprocessor library <a class="citation-reference" href="#mk04" 380 381 id="id3" name="id3">[MK04]</a> plays a role in preprocessor 382 metaprogramming similar to the one played by the MPL in template 383 metaprogramming: It supplies a framework of high-level components 384 (like <tt class="docutils literal"><span class="pre">BOOST_PP_ENUM_PARAMS</span></tt>) 385 that make otherwise-painful metaprogramming jobs approachable. In 386 this appendix we won't attempt to cover nitty-gritty details of how 387 the preprocessor works, nor principles of preprocessor 388 metaprogramming in general, nor even many details of how the 389 Preprocessor <em>library</em> works. We <em>will</em> show you 390 enough at a high level that you'll be able to use the library 391 productively and learn the rest on your own.</p> 392 <table class="docutils citation" frame="void" id="mk04" rules="none"> 393 <colgroup><col class="label" /><col /></colgroup> 394 <tbody valign="top"> 395 <tr> 396 <td class="label"><a class="fn-backref" href="#id3" name="mk04">[MK04]</a></td> 397 <td>Paul Mensonides and Vesa Karvonen. "The Boost Preprocessor 398 Library." <a class="reference" href="http://www.boost.org/libs/preprocessor">http://www.boost.org/libs/preprocessor</a>.</td> 399 </tr> 400 </tbody> 401 </table> 402 </div> 403 </div> 404 <div class="section" id="fundamental-abstractions-of-the-preprocessor"> 405 <h1><a name="fundamental-abstractions-of-the-preprocessor">A.2 Fundamental 406 Abstractions of the Preprocessor</a></h1> 407 <p>We began our discussion of template metaprogramming in Chapter 2 by 408 describing its metadata (potential template arguments) and 409 metafunctions (class templates). On the basis of those two fundamental 410 abstractions, we built up the entire picture of compile-time 411 computation covered in the rest of this book. In this section we'll 412 lay a similar foundation for the preprocessor metaprogrammer. Some of 413 what we cover here may be a review for you, but it's important to 414 identify the basic concepts going into detail.</p> 415 <div class="section" id="preprocessing-tokens"> 416 <h2><a name="preprocessing-tokens">A.2.1 Preprocessing Tokens</a></h2> 417 <p>The fundamental unit of data in the preprocessor is the <strong>preprocessing 418 token</strong>. Preprocessing tokens correspond roughly to the 419 tokens you're used to working with in C++, such as identifiers, 420 operator symbols, and literals. Technically, there are some 421 differences between <em>preprocessing tokens</em> and regular <em>tokens</em> 422 (see section 2 of the C++ standard for details), but they can be 423 ignored for the purposes of this discussion. In fact, we'll be using 424 the terms interchangeably here.</p> 425 </div> 426 <div class="section" id="macros"> 427 <h2><a name="macros">A.2.2 Macros</a></h2> 428 <p>Preprocessor macros come in two flavors. <strong>Object-like 429 macros</strong> can be defined this way:</p> 430 <blockquote> 431 <div class="line-block"> 432 <div class="line"><tt class="docutils literal"><span class="pre">#define</span></tt> 433 <em>identifier</em> <em>replacement-list</em></div> 434 </div> 435 </blockquote> 436 <!-- @litre_translator.line_offset -= 7 --> 437 <p>where the <em>identifier</em> names the macro being defined, and <em>replacement-list</em> 438 is a sequence of zero or more tokens. Where the <em>identifier</em> 439 appears in subsequent program text, it is <strong>expanded</strong> 440 by the preprocessor into its <em>replacement-list</em>.</p> 441 <p><strong>Function-like macros</strong>, which act as the 442 "metafunctions of the preprocessing phase," are defined as follows:</p> 443 <blockquote> 444 <div class="line-block"> 445 <div class="line"><tt class="docutils literal"><span class="pre">#define</span></tt> 446 <em>identifier</em>(<em>a</em><sub>1</sub>, <em>a</em><sub>2</sub>, 447 ... <em>a</em><sub>n</sub>) <em>replacement-list</em></div> 448 </div> 449 </blockquote> 450 <!-- @litre_translator.line_offset -= 7 --> 451 <p>where each <em>a</em><sub>i</sub> is an identifier naming a <strong>macro 452 parameter</strong>. When the macro name appears in subsequent 453 program text followed by a suitable argument list, it is expanded 454 into its <em>replacement-list</em>, except that each argument is 455 substituted for the corresponding parameter where it appears in the 456 <em>replacement-list</em>.<a class="footnote-reference" href="#expansion" 457 458 id="id4" name="id4">[2]</a></p> 459 <table class="docutils footnote" frame="void" id="expansion" rules="none"> 460 <colgroup><col class="label" /><col /></colgroup> 461 <tbody valign="top"> 462 <tr> 463 <td class="label"><a class="fn-backref" href="#id4" name="expansion">[2]</a></td> 464 <td>We have omitted many details of how macro expansion works. 465 We encourage you to take a few minutes to study section 16.3 466 of the C++ standard, which describes that process in 467 straightforward terms.</td> 468 </tr> 469 </tbody> 470 </table> 471 </div> 472 <div class="section" id="macro-arguments"> 473 <h2><a name="macro-arguments">A.2.3 Macro Arguments</a></h2> 474 <div class="admonition-definition admonition"> 475 <p class="first admonition-title">Definition</p> 476 <p>A <strong>macro argument</strong> is a nonempty sequence of:</p> 477 <ul class="last simple"> 478 <li>Preprocessing tokens other than commas or parentheses, <em>and/or</em></li> 479 <li>Preprocessing tokens surrounded by matched pairs of 480 parentheses.</li> 481 </ul> 482 </div> 483 <p>This definition has consequences for preprocessor metaprogramming 484 that must not be underestimated. Note, first of all, that the 485 following tokens have special status:</p> 486 <blockquote> 487 <pre class="literal-block">, ( ) 488</pre> </blockquote> 489 <!-- @ignore() --> 490 <p>As a result, a macro argument can never contain an unmatched 491 parenthesis, or a comma that is not surrounded by matched 492 parentheses. For example, both lines following the definition of FOO 493 below are ill-formed:</p> 494 <pre class="literal-block">#define FOO(X) X // Unary identity macro 495FOO(,) // un-parenthesized comma or two empty arguments 496FOO()) // unmatched parenthesis or missing argument 497</pre> 498 <!-- @def pp_failure(options = ['-E'], **kw): 499 compile( expect_error = not 'mwcc' in config.compiler , options = options, **kw)pp_failure() --> 500 <p>Note also that the following tokens do <em>not</em> have special 501 status; the preprocessor knows nothing about matched pairs of 502 braces, brackets, or angle brackets:</p> 503 <blockquote> 504 <pre class="literal-block">{ } [ ] < > 505</pre> </blockquote> 506 <!-- @ignore() --> 507 <p>As a result, these lines are also ill-formed:</p> 508 <pre class="literal-block">FOO(std::pair<int<strong>,</strong> long>) // two arguments 509FOO({ int x = 1<strong>,</strong> y = 2; return x+y; }) // two arguments 510</pre> 511 <!-- @example.prepend('#define FOO(X) X') 512pp_failure() --> 513 <p>It <em>is</em> possible to pass either string of tokens above as 514 part of a single macro argument, provided it is parenthesized:</p> 515 <pre class="literal-block">FOO(<strong>(</strong>std::pair<int,int><strong>)</strong>) // one argument 516FOO(<strong>(</strong>{ int x = 1, y = 2; return x+y; }<strong>)</strong>) // one argument 517</pre> 518 <!-- @example.prepend('#define FOO(X) X') 519compile(options = ['-E']) --> 520 <p>However, because of the special status of commas, it is impossible 521 to strip parentheses from a macro argument without knowing the 522 number of comma-separated token sequences it contains.<a class="footnote-reference" 523 524 href="#c99" id="id5" name="id5">[3]</a> If you are writing a macro 525 that needs to be able to accept an argument containing a variable 526 number of commas, your users will either have to parenthesize that 527 argument <em>and</em> pass you the number of comma-separated token 528 sequences as an additional argument, or they will have to encode the 529 same information in one of the preprocessor data structures covered 530 later in this appendix.</p> 531 <table class="docutils footnote" frame="void" id="c99" rules="none"> 532 <colgroup><col class="label" /><col /></colgroup> 533 <tbody valign="top"> 534 <tr> 535 <td class="label"><a name="c99">[3]</a></td> 536 <td><em>(<a class="fn-backref" href="#id5">1</a>, <a class="fn-backref" 537 538 href="#id12">2</a>)</em> The C99 preprocessor, by virtue 539 of its variadic macros, can do that and more. The C++ 540 standardization committee is likely to adopt C99's 541 preprocessor extensions for the next version of the C++ 542 standard.</td> 543 </tr> 544 </tbody> 545 </table> 546 </div> 547 </div> 548 <div class="section" id="preprocessor-library-structure"> 549 <h1><a name="preprocessor-library-structure">A.3 Preprocessor Library 550 Structure</a></h1> 551 <p>Since in-depth coverage of the Boost Preprocessor library is beyond 552 the scope of this book, we'll try to give you the <em>tools</em> to 553 gain an in-depth understanding of the library here. To do that, you'll 554 need to use the electronic Preprocessor library documentation, which 555 begins with the index.html file in the <tt class="docutils literal"><span 556 557 class="pre">libs/preprocessor/</span></tt> subdirectory of your 558 Boost installation.</p> 559 <p>On the left of your browser window you'll see an index, and if you 560 follow the "Headers" link, it will reveal the structure of the <tt class="docutils literal"><span 561 562 class="pre">boost/preprocessor/</span></tt> directory. Most of the 563 library's headers are grouped into subdirectories according to related 564 functionality. The top-level directory contains only a few headers 565 that provide general-purpose macros, along with a header for each 566 subdirectory that simply <tt class="docutils literal"><span class="pre">#include</span></tt>s 567 all the headers in that subdirectory. For example, <tt class="docutils literal"><span 568 569 class="pre">boost/preprocessor/selection.hpp</span></tt> does 570 nothing more than to <tt class="docutils literal"><span class="pre">#include</span></tt> 571 the <tt class="docutils literal"><span class="pre">min.hpp</span></tt> 572 and <tt class="docutils literal"><span class="pre">max.hpp</span></tt> 573 headers that comprise the contents of <tt class="docutils literal"><span 574 575 class="pre">boost/preprocessor/selection/</span></tt>. The headers 576 whose names <em>don't</em> correspond to subdirectories generally 577 declare a macro whose name is the same as the name of the header, 578 without the extension, and with a <tt class="docutils literal"><span 579 580 class="pre">BOOST_PP_</span></tt> prefix. For example, <tt class="docutils literal"><span 581 582 class="pre">boost/preprocessor/selection/max.hpp</span></tt> 583 declares <tt class="docutils literal"><span class="pre">BOOST_PP_MAX</span></tt>.</p> 584 <p>You'll also notice that often a header will declare an additional 585 macro with a <tt class="docutils literal"><span class="pre">_D</span></tt>, 586 <tt class="docutils literal"><span class="pre">_R</span></tt>, or <tt 587 588 class="docutils literal"><span class="pre">_Z</span></tt> suffix.<a 589 590 class="footnote-reference" href="#suffix" id="id6" name="id6">[4]</a> 591 For instance, <tt class="docutils literal"><span class="pre">boost/preprocessor/selection/max.hpp</span></tt> 592 also declares <tt class="docutils literal"><span class="pre">BOOST_PP_MAX_D</span></tt>. 593 For the purposes of this appendix, you should ignore those macros. 594 Eventually you will want to understand how they can be used to 595 optimize preprocessing speed; consult the Topics section of the 596 library documentation under the subheading "reentrancy" for that 597 information.</p> 598 <table class="docutils footnote" frame="void" id="suffix" rules="none"> 599 <colgroup><col class="label" /><col /></colgroup> 600 <tbody valign="top"> 601 <tr> 602 <td class="label"><a class="fn-backref" href="#id6" name="suffix">[4]</a></td> 603 <td>Macros with <tt class="docutils literal"><span class="pre">_1ST</span></tt>, 604 <tt class="docutils literal"><span class="pre">_2ND</span></tt>, 605 or <tt class="docutils literal"><span class="pre">_3RD</span></tt> 606 suffixes, if they appear, should be ignored for a different 607 reason: They are deprecated and will be removed from the library 608 soon.</td> 609 </tr> 610 </tbody> 611 </table> 612 </div> 613 <div class="section" id="preprocessor-library-abstractions"> 614 <h1><a name="preprocessor-library-abstractions">A.4 Preprocessor 615 Library Abstractions</a></h1> 616 <p>In this section we'll discuss the basic abstractions of the 617 Preprocessor library, and give some simple examples of each.</p> 618 <div class="section" id="repetition"> 619 <h2><a name="repetition">A.4.1 Repetition</a></h2> 620 <p>The repeated generation of <tt class="docutils literal"><span class="pre">class</span> 621 <span class="pre">T0</span></tt>, <tt class="docutils literal"><span 622 623 class="pre">class</span> <span class="pre">T1</span></tt>... <tt 624 625 class="docutils literal"><span class="pre">class</span> <span class="pre">T</span></tt><em>n</em> 626 that we achieved using <tt class="docutils literal"><span class="pre">BOOST_PP_ENUM_PARAMS</span></tt> 627 was a specific case of the general concept of <strong>horizontal 628 repetition</strong>. The library also has a concept of vertical 629 repetition, which we'll get to in a moment. Horizontal repetition 630 macros are all found in the library's <tt class="docutils literal"><span 631 632 class="pre">repetition/</span></tt> subdirectory.</p> 633 <div class="section" id="horizontal-repetition"> 634 <h3><a name="horizontal-repetition">A.4.1.1 Horizontal Repetition</a></h3> 635 <p>To generate the <tt class="docutils literal"><span class="pre">tiny_size</span></tt> 636 specializations using horizontal repetition, we might write the 637 following:</p> 638 <pre class="literal-block">#include <boost/preprocessor/repetition.hpp> 639#include <boost/preprocessor/arithmetic/sub.hpp> 640#include <boost/preprocessor/punctuation/comma_if.hpp> 641 642#define TINY_print(z, n, data) data 643 644#define TINY_size(z, n, unused) \ 645 template <BOOST_PP_ENUM_PARAMS(n, class T)> \ 646 struct tiny_size< \ 647 BOOST_PP_ENUM_PARAMS(n,T) \ 648 BOOST_PP_COMMA_IF(n) \ 649 BOOST_PP_ENUM( \ 650 BOOST_PP_SUB(TINY_MAX_SIZE,n), TINY_print, none) \ 651 > \ 652 : mpl::int_<n> {}; 653 654BOOST_PP_REPEAT(TINY_MAX_SIZE, TINY_size, ~) 655 656#undef TINY_size 657#undef TINY_print 658</pre> 659 <!-- @import re 660compile('all', pop = None)example.sub('BOOST_PP_REPEAT.*', '', flags = re.DOTALL) --> 661 <p>The code generation process is kicked off by calling <tt class="docutils literal"><span 662 663 class="pre">BOOST_PP_REPEAT</span></tt>, a <strong>higher-order 664 macro</strong> that repeatedly invokes the macro named by its 665 second argument (<tt class="docutils literal"><span class="pre">TINY_size</span></tt>). 666 The first argument specifies the number of repeated invocations, 667 and the third one can be any data; it is passed on unchanged to 668 the macro being invoked. In this case, <tt class="docutils literal"><span 669 670 class="pre">TINY_size</span></tt> doesn't use that data, so 671 the choice to pass <tt class="docutils literal"><span class="pre">~</span></tt> 672 was arbitrary.<a class="footnote-reference" href="#markers" id="id7" 673 674 name="id7">[5]</a></p> 675 <table class="docutils footnote" frame="void" id="markers" rules="none"> 676 <colgroup><col class="label" /><col /></colgroup> 677 <tbody valign="top"> 678 <tr> 679 <td class="label"><a class="fn-backref" href="#id7" name="markers">[5]</a></td> 680 <td><tt class="docutils literal"><span class="pre">~</span></tt> 681 is not an <em>entirely</em> arbitrary choice. Both <tt class="docutils literal"><span 682 683 class="pre">@</span></tt> and <tt class="docutils literal"><span 684 685 class="pre">$</span></tt> might have been good choices, 686 except that they are technically not part of the basic 687 character set that C++ implementations are required to 688 support. An identifier like <tt class="docutils literal"><span 689 690 class="pre">ignored</span></tt> might be subject to 691 macro expansion, leading to unexpected results.</td> 692 </tr> 693 </tbody> 694 </table> 695 <p>Each time the <tt class="docutils literal"><span class="pre">TINY_size</span></tt> 696 macro is invoked by <tt class="docutils literal"><span class="pre">BOOST_PP_REPEAT</span></tt>, 697 it generates a different specialization of <tt class="docutils literal"><span 698 699 class="pre">tiny_size</span></tt>. The macro accepts three 700 parameters.</p> 701 <ul class="simple"> 702 <li><tt class="docutils literal"><span class="pre">z</span></tt> 703 is related to the <tt class="docutils literal"><span class="pre">_Z</span></tt> 704 macro suffix we mentioned earlier. You'll never need to use it 705 except for optimization purposes, and can safely ignore it for 706 now.</li> 707 <li><tt class="docutils literal"><span class="pre">n</span></tt> 708 is the repetition index. In repeated invocations of <tt class="docutils literal"><span 709 710 class="pre">TINY_size</span></tt>, <tt class="docutils literal"><span 711 712 class="pre">n</span></tt> will be <tt class="docutils literal"><span 713 714 class="pre">0</span></tt>, then <tt class="docutils literal"><span 715 716 class="pre">1</span></tt>, then <tt class="docutils literal"><span 717 718 class="pre">2</span></tt>, and so on.</li> 719 <li><tt class="docutils literal"><span class="pre">unused</span></tt>, 720 in this case, will be <tt class="docutils literal"><span class="pre">~</span></tt> 721 on each repetition. In general, the final argument to a macro 722 invoked by <tt class="docutils literal"><span class="pre">BOOST_PP_REPEAT</span></tt> 723 is always the same as its invoker's final argument.</li> 724 </ul> 725 <p>Because its <em>replacement-list</em> covers several lines, all 726 but the last line of <tt class="docutils literal"><span class="pre">TINY_size</span></tt> 727 is continued with a trailing backslash. The first few of those 728 lines just invoke <tt class="docutils literal"><span class="pre">BOOST_PP_ENUM_PARAMS</span></tt> 729 (which we already used in the primary template) to generate 730 comma-separated lists, so each invocation of <tt class="docutils literal"><span 731 732 class="pre">TINY_size</span></tt> produces something 733 equivalent to:<a class="footnote-reference" href="#cont" id="id8" 734 735 name="id8">[6]</a></p> 736 <pre class="literal-block">template <<strong>class T0, class T1, ... class T</strong><em>n-1</em>> 737struct tiny_size< 738 <strong>T0, T1, ... T</strong><em>n-1</em> 739 <em>...more...</em> 740> 741 : mpl::int_<n> {}; 742</pre> 743 <table class="docutils footnote" frame="void" id="cont" rules="none"> 744 <colgroup><col class="label" /><col /></colgroup> 745 <tbody valign="top"> 746 <tr> 747 <td class="label"><a class="fn-backref" href="#id8" name="cont">[6]</a></td> 748 <td>Note that the line continuation characters <em>and</em> 749 the newlines following them are removed by the preprocessor, 750 so the resulting code actually appears on a single line in 751 the preprocessed output.</td> 752 </tr> 753 </tbody> 754 </table> 755 <!-- @ignore() --> 756 <p><tt class="docutils literal"><span class="pre">BOOST_PP_COMMA_IF</span></tt> 757 generates a comma if its numeric argument is not <tt class="docutils literal"><span 758 759 class="pre">0</span></tt>. When <tt class="docutils literal"><span 760 761 class="pre">n</span></tt> is <tt class="docutils literal"><span 762 763 class="pre">0</span></tt>, the list generated by the preceding 764 line will be empty, and a leading comma directly following the <tt 765 766 class="docutils literal"><span class="pre"><</span></tt> 767 character would be ill-formed.</p> 768 <p>The next line uses <tt class="docutils literal"><span class="pre">BOOST_PP_ENUM</span></tt> 769 to generate <tt class="docutils literal"><span class="pre">TINY_MAX_SIZE-n</span></tt> 770 comma-separated copies of <tt class="docutils literal"><span class="pre">none</span></tt>. 771 <tt class="docutils literal"><span class="pre">BOOST_PP_ENUM</span></tt> 772 is just like <tt class="docutils literal"><span class="pre">BOOST_PP_REPEAT</span></tt> 773 except that it generates commas between repetitions, so its second 774 argument (<tt class="docutils literal"><span class="pre">TINY_print</span></tt>, 775 here) must have the same signature as <tt class="docutils literal"><span 776 777 class="pre">TINY_size</span></tt>. In this case, <tt class="docutils literal"><span 778 779 class="pre">TINY_print</span></tt> ignores its repetition 780 index <tt class="docutils literal"><span class="pre">n</span></tt>, 781 and simply yields its third argument, <tt class="docutils literal"><span 782 783 class="pre">none</span></tt>.</p> 784 <p><tt class="docutils literal"><span class="pre">BOOST_PP_SUB</span></tt> 785 implements token subtraction. It's crucial to understand that 786 although the preprocessor <em>itself</em> can evaluate ordinary 787 arithmetic expressions:</p> 788 <pre class="literal-block">#define X 3 789... 790#if <strong>X - 1 > 0</strong> // OK 791 <em>whatever</em> 792#endif 793</pre> 794 <!-- @compile() --> 795 <!-- @litre_translator.line_offset -= 7 --> 796 <p>preprocessor <em>metaprograms</em> can only operate on tokens. 797 Normally, when a macro in the Preprocessor library expects a 798 numeric argument, it must be passed as a single token. If we had 799 written <tt class="docutils literal"><span class="pre">TINY_MAX_SIZE-n</span></tt> 800 instead of <tt class="docutils literal"><span class="pre">BOOST_PP_SUB(TINY_MAX_SIZE,n)</span></tt> 801 above, the first argument to <tt class="docutils literal"><span class="pre">BOOST_PP_ENUM</span></tt> 802 would have contained three tokens at each invocation: first <tt class="docutils literal"><span 803 804 class="pre">3-0</span></tt>, then <tt class="docutils literal"><span 805 806 class="pre">3-1</span></tt>, and finally <tt class="docutils literal"><span 807 808 class="pre">3-2</span></tt>. <tt class="docutils literal"><span 809 810 class="pre">BOOST_PP_SUB</span></tt>, though, generates 811 single-token results: first <tt class="docutils literal"><span class="pre">3</span></tt>, 812 then <tt class="docutils literal"><span class="pre">2</span></tt>, 813 and finally <tt class="docutils literal"><span class="pre">1</span></tt>, 814 in successive repetitions.</p> 815 <div class="sidebar"> 816 <p class="first sidebar-title">Naming Conventions</p> 817 <p class="last">Note that <tt class="docutils literal"><span class="pre">TINY_print</span></tt> 818 and <tt class="docutils literal"><span class="pre">TINY_size</span></tt> 819 are <tt class="docutils literal"><span class="pre">#undef</span></tt>'d 820immediately 821 after they're used, with no intervening <tt class="docutils literal"><span 822 823 class="pre">#include</span></tt>s. They can therefore be 824 thought of as "local" macro definitions. Because the 825 preprocessor doesn't respect scope boundaries, it's important to 826 choose names carefully to prevent clashes. We recommend <tt class="docutils literal"><span 827 828 class="pre">PREFIXED_lower_case</span></tt> names for local 829 macros and <tt class="docutils literal"><span class="pre">PREFIXED_UPPER_CASE</span></tt> 830 names for global ones. The only exceptions are one-letter 831 lowercase names, which are safe to use for local macros: No 832 other header is likely to <tt class="docutils literal"><span class="pre">#define</span></tt> 833 a global single-letter lowercase macro—that would be <em>very</em> 834 bad manners.</p> 835 </div> 836 </div> 837 <div class="section" id="vertical-repetition"> 838 <h3><a name="vertical-repetition">A.4.1.2 Vertical Repetition</a></h3> 839 <p>If you send the previous example through your preprocessor, 840 you'll see one long line containing something like this:</p> 841 <pre class="literal-block">template <> struct tiny_size< none , none , none > : mpl::int_<0> 842 {}; template < class T0> struct tiny_size< T0 , none , none > : 843mpl::int_<1> {}; template < class T0 , class T1> struct tiny_size 844< T0 , T1 , none > : mpl::int_<2> {}; 845</pre> 846 <!-- @compile('all', pop = 1) --> 847 <p>The distinguishing feature of horizontal repetition is that all 848 instances of the repeated pattern are generated on the same line 849 of preprocessed output. For some jobs, like generating the primary 850 <tt class="docutils literal"><span class="pre">tiny_size</span></tt> 851 template, that's perfectly appropriate. In this case, however, 852 there are at least two disadvantages.</p> 853 <ol class="arabic simple"> 854 <li>It's hard to verify that our metaprogram is doing the right 855 thing without reformatting the resulting code by hand.</li> 856 <li>The efficiency of nested horizontal repetitions varies widely 857 across preprocessors. Each specialization generated by means of 858 horizontal repetition contains three other horizontal 859 repetitions: two invocations of <tt class="docutils literal"><span 860 861 class="pre">BOOST_PP_ENUM_PARAMS</span></tt> and one 862 invocation of <tt class="docutils literal"><span class="pre">BOOST_PP_ENUM</span></tt>. 863 When <tt class="docutils literal"><span class="pre">TINY_MAX_SIZE</span></tt> 864 is <tt class="docutils literal"><span class="pre">3</span></tt>, 865 you'll probably never care, but on at least one preprocessor 866 still in use today, compilation begins to slow noticeably when <tt 867 868 class="docutils literal"><span class="pre">TINY_MAX_SIZE</span></tt> 869 reaches <tt class="docutils literal"><span class="pre">8</span></tt>.<a 870 871 class="footnote-reference" href="#nest" id="id9" name="id9">[7]</a></li> 872 </ol> 873 <blockquote> 874 <table class="docutils footnote" frame="void" id="nest" rules="none"> 875 <colgroup><col class="label" /><col /></colgroup> 876 <tbody valign="top"> 877 <tr> 878 <td class="label"><a class="fn-backref" href="#id9" name="nest">[7]</a></td> 879 <td>That said, other preprocessors can handle 256 * 256 880 nested repetitions without any speed problems whatsoever.</td> 881 </tr> 882 </tbody> 883 </table> 884 </blockquote> 885 <p>The solution to these problems, naturally, is <strong>vertical 886 repetition</strong>, which generates instances of a pattern 887 across multiple lines. The Preprocessor library provides two means 888 of vertical repetition: <strong>local iteration</strong> and <strong>file 889 iteration</strong>.</p> 890 <div class="section" id="local-iteration"> 891 <h4><a name="local-iteration">Local Iteration</a></h4> 892 <p>The most expedient way to demonstrate local iteration in our 893 example is to replace the invocation of <tt class="docutils literal"><span 894 895 class="pre">BOOST_PP_REPEAT</span></tt> with the following:</p> 896 <pre class="literal-block">#include <boost/preprocessor/<strong>iteration/local.hpp</strong>> 897 898#define BOOST_PP_LOCAL_MACRO(n) TINY_size(~, n, ~) 899#define BOOST_PP_LOCAL_LIMITS (0, <strong>TINY_MAX_SIZE - 1</strong>) 900<strong>#include</strong> BOOST_PP_LOCAL_ITERATE() 901</pre> 902 <!-- @compile('all', pop = 1) --> 903 <p>Local iteration repeatedly invokes the user-defined macro with 904 the special name <tt class="docutils literal"><span class="pre">BOOST_PP_LOCAL_MACRO</span></tt>, 905 whose argument will be an iteration index. Since we already had 906 <tt class="docutils literal"><span class="pre">TINY_size</span></tt> 907 lying around, we've just defined <tt class="docutils literal"><span 908 909 class="pre">BOOST_PP_LOCAL_MACRO</span></tt> to invoke it. 910 The range of iteration indices are given by another user-defined 911 macro, <tt class="docutils literal"><span class="pre">BOOST_PP_LOCAL_LIMITS</span></tt>, 912 which must expand to a parenthesized pair of integer values 913 representing the <em>inclusive</em> range of index values 914 passed to <tt class="docutils literal"><span class="pre">BOOST_PP_LOCAL_MACRO</span></tt>. 915 Note that this is one of the rare places where the library 916 expects a numeric argument that can be an expression consisting 917 of multiple tokens.</p> 918 <p>Finally, the repetition is initiated by <tt class="docutils literal"><span 919 920 class="pre">#include</span></tt>-ing the result of invoking 921 <tt class="docutils literal"><span class="pre">BOOST_PP_LOCAL_ITERATE</span></tt>, 922 which will ultimately be a file in the Preprocessor library 923 itself. You may find it surprising that many preprocessors can 924 handle repeated file inclusion more quickly than nested 925 horizontal repetition, but that is in fact the case.</p> 926 <p>If we throw the new example at our preprocessor, we'll see the 927 following, on three separate lines in the output:</p> 928 <pre class="literal-block">template <> struct tiny_size< none , none , none > : mpl::int_<0> 929 {}; 930 931template < class T0> struct tiny_size< T0 , none , none > : mpl:: 932int_<1> {}; 933 934template < class T0 , class T1> struct tiny_size< T0 , T1 , none 935> : mpl::int_<2> {}; 936</pre> 937 <!-- @compile('all', pop = 1) --> 938 <p>That represents a great improvement in verifiability, but it's 939 still not ideal. As <tt class="docutils literal"><span class="pre">TINY_MAX_SIZE</span></tt> 940 grows, it gets harder and harder to see that the pattern is 941 generating what we'd like. If we could get some more line breaks 942 into the output it would retain a more recognizable form.</p> 943 <p>Both repetition methods we've used so far have another 944 drawback, though it doesn't show up in this example. Consider 945 what would happen if <tt class="docutils literal"><span class="pre">tiny_size</span></tt> 946 had a member function that we wanted to debug. If you've ever 947 tried to use a debugger to step through a function generated by 948 a preprocessor macro, you know that it's a frustrating 949 experience at best: The debugger shows you the line from which 950 the macro was ultimately invoked, which usually looks nothing at 951 all like the code that was generated. Worse, as far as the 952 debugger is concerned, <em>every</em> statement in that 953 generated function occupies that same line.</p> 954 </div> 955 <div class="section" id="file-iteration"> 956 <h4><a name="file-iteration">File Iteration</a></h4> 957 <p>Clearly, debuggability depends on preserving the association 958 between generated code and the lines in the source file that 959 describe the code pattern. File iteration generates pattern 960 instances by repeatedly <tt class="docutils literal"><span class="pre">#include</span></tt>-ing 961 the same source file. The effect of file iteration on 962 debuggability is similar to that of templates: Although separate 963 instances appear to occupy the same source lines in the 964 debugger, we do have the experience of stepping through the 965 function's source code.</p> 966 <p>To apply file iteration in our example, we can replace our 967 earlier local iteration code and the definition of <tt class="docutils literal"><span 968 969 class="pre">TINY_size</span></tt>, with:</p> 970 <pre class="literal-block">#include <boost/preprocessor/iteration/iterate.hpp> 971#define BOOST_PP_ITERATION_LIMITS (0, TINY_MAX_SIZE - 1) 972#define BOOST_PP_FILENAME_1 "tiny_size_spec.hpp" 973#include BOOST_PP_ITERATE() 974</pre> 975 <p><tt class="docutils literal"><span class="pre">BOOST_PP_ITERATION_LIMITS</span></tt> 976 follows the same pattern as <tt class="docutils literal"><span 977 978 class="pre">BOOST_PP_LOCAL_LIMITS</span></tt> did, allowing 979 us to specify an inclusive range of iteration indices. <tt class="docutils literal"><span 980 981 class="pre">BOOST_PP_FILENAME_1</span></tt> specifies the 982 name of the file to repeatedly <tt class="docutils literal"><span 983 984 class="pre">#include</span></tt> (we'll show you that file 985 in a moment). The trailing <tt class="docutils literal"><span class="pre">1</span></tt> 986 indicates that this is the first nesting level of file 987 iteration—should we need to invoke file iteration again from 988 within <tt class="docutils literal"><span class="pre">tiny_size_spec.hpp</span></tt>, 989 we'd need to use <tt class="docutils literal"><span class="pre">BOOST_PP_FILENAME_2</span></tt> 990 instead.</p> 991 <p>The contents of <tt class="docutils literal"><span class="pre">tiny_size_spec.hpp</span></tt> 992 should look familiar to you; most of it is the same as <tt class="docutils literal"><span 993 994 class="pre">TINY_size</span></tt>'s <em>replacement-list</em>, 995 without the backslashes:</p> 996 <pre class="literal-block">#define n BOOST_PP_ITERATION() 997 998template <BOOST_PP_ENUM_PARAMS(n, class T)> 999struct tiny_size< 1000 BOOST_PP_ENUM_PARAMS(n,T) 1001 BOOST_PP_COMMA_IF(n) 1002 BOOST_PP_ENUM(BOOST_PP_SUB(TINY_MAX_SIZE,n), TINY_print, none) 1003> 1004 : mpl::int_<n> {}; 1005 1006#undef n 1007</pre> 1008 <!-- @import tempfile, os 1009open(os.path.join(tempfile.gettempdir(),'tiny_size_spec.hpp'), 'w' ).write(str(example))ignore()vertical_options = ['-I'+tempfile.gettempdir(), '-c'] 1010compile('all', options = vertical_options, pop = 1) --> 1011 <p>The Library transmits the iteration index to us in the result 1012 of <tt class="docutils literal"><span class="pre">BOOST_PP_ITERATION()</span></tt>; 1013 <tt class="docutils literal"><span class="pre">n</span></tt> is 1014 nothing more than a convenient local macro used to reduce 1015 syntactic noise. Note that we didn't use <tt class="docutils literal"><span 1016 1017 class="pre">#include</span></tt> guards because we need <tt 1018 1019 class="docutils literal"><span class="pre">tiny_size_spec.hpp</span></tt> 1020 to be processed multiple times.</p> 1021 <p>The preprocessed result should now preserve the line structure 1022 of the pattern and be more verifiable for larger values of <tt 1023 1024 class="docutils literal"><span class="pre">TINY_MAX_SIZE</span></tt>. 1025 For instance, when <tt class="docutils literal"><span class="pre">TINY_MAX_SIZE</span></tt> 1026 is <tt class="docutils literal"><span class="pre">8</span></tt>, 1027 the following excerpt appears in the output of GCC's 1028 preprocessing phase:</p> 1029 <pre class="literal-block"><em>...</em> 1030template < class T0 , class T1 , class T2 , class T3> 1031struct tiny_size< 1032 T0 , T1 , T2 , T3 1033 , 1034 none , none , none , none 1035> 1036 : mpl::int_<4> {}; 1037 1038template < class T0 , class T1 , class T2 , class T3 , class T4> 1039struct tiny_size< 1040 T0 , T1 , T2 , T3 , T4 1041 , 1042 none , none , none 1043> 1044 : mpl::int_<5> {}; 1045<em>...etc.</em> 1046</pre> 1047 <!-- @compile('all', options = vertical_options + ['-DTINY_MAX_SIZE=8']) --> 1048 </div> 1049 <div class="section" id="self-iteration"> 1050 <h4><a name="self-iteration">Self-Iteration</a></h4> 1051 <p>Creating an entirely new file like <tt class="docutils literal"><span 1052 1053 class="pre">tiny_size_spec.hpp</span></tt> each time we want 1054 to express a trivial code pattern for file repetition can be 1055 inconvenient. Fortunately, the library provides a macro that 1056 allows us to place the pattern right in the file that invokes 1057 the iteration. <tt class="docutils literal"><span class="pre">BOOST_PP_IS_ITERATING</span></tt> 1058 is defined to a nonzero value whenever we're inside an 1059 iteration. We can use that value to select between the part of a 1060 file that invokes the iteration and the part that provides the 1061 repeated pattern. Here's a complete <tt class="docutils literal"><span 1062 1063 class="pre">tiny_size.hpp</span></tt> file that demonstrates 1064 self-iteration. Note in particular the placement and use of the 1065 <tt class="docutils literal"><span class="pre">#include</span></tt> 1066 guard <tt class="docutils literal"><span class="pre">TINY_SIZE_HPP_INCLUDED</span></tt>:</p> 1067 <pre class="literal-block">#ifndef <strong>BOOST_PP_IS_ITERATING</strong> 1068 1069# ifndef TINY_SIZE_HPP_INCLUDED 1070# define TINY_SIZE_HPP_INCLUDED 1071 1072# include <boost/preprocessor/repetition.hpp> 1073# include <boost/preprocessor/arithmetic/sub.hpp> 1074# include <boost/preprocessor/punctuation/comma_if.hpp> 1075# include <boost/preprocessor/iteration/iterate.hpp> 1076 1077# ifndef TINY_MAX_SIZE 1078# define TINY_MAX_SIZE 3 // default maximum size is 3 1079# endif 1080 1081// primary template 1082template <BOOST_PP_ENUM_PARAMS(TINY_MAX_SIZE, class T)> 1083struct tiny_size 1084 : mpl::int_<TINY_MAX_SIZE> 1085{}; 1086 1087// generate specializations 1088# define BOOST_PP_ITERATION_LIMITS (0, TINY_MAX_SIZE - 1) 1089# define BOOST_PP_FILENAME_1 "tiny_size.hpp" // this file 1090# include BOOST_PP_ITERATE() 1091 1092# endif // TINY_SIZE_HPP_INCLUDED 1093 1094#else // <strong>BOOST_PP_IS_ITERATING</strong> 1095 1096# define n BOOST_PP_ITERATION() 1097 1098# define TINY_print(z, n, data) data 1099 1100// specialization pattern 1101template <BOOST_PP_ENUM_PARAMS(n, class T)> 1102struct tiny_size< 1103 BOOST_PP_ENUM_PARAMS(n,T) 1104 BOOST_PP_COMMA_IF(n) 1105 BOOST_PP_ENUM(BOOST_PP_SUB(TINY_MAX_SIZE,n), TINY_print, none) 1106> 1107 : mpl::int_<n> {}; 1108 1109# undef TINY_print 1110# undef n 1111 1112#endif // <strong>BOOST_PP_IS_ITERATING</strong> 1113</pre> 1114 <!-- @compile(source_file = 'tiny_size.hpp') --> </div> 1115 <div class="section" id="more"> 1116 <h4><a name="more">More</a></h4> 1117 <p>There's a good deal more to file iteration than what we've been 1118 able to show you here. For more details, we encourage you to 1119 delve into the library's electronic documentation of <tt class="docutils literal"><span 1120 1121 class="pre">BOOST_PP_ITERATE</span></tt> and friends. Also, 1122 it's important to note that no single technique for repetition 1123 is superior to any other: Your choice may depend on convenience, 1124 verifiability, debuggability, compilation speed, and your own 1125 sense of "logical coherence."</p> 1126 </div> 1127 </div> 1128 </div> 1129 <div class="section" id="arithmetic-logical-and-comparison-operations"> 1130 <h2><a name="arithmetic-logical-and-comparison-operations">A.4.2 Arithmetic, 1131 Logical, and Comparison Operations</a></h2> 1132 <p>As we mentioned earlier, many of the Preprocessor library 1133 interfaces require single-token numeric arguments, and when those 1134 numbers need to be computed arithmetically, straightforward 1135 arithmetic expressions are inappropriate. We used <tt class="docutils literal"><span 1136 1137 class="pre">BOOST_PP_SUB</span></tt> to subtract two numeric 1138 tokens in our <tt class="docutils literal"><span class="pre">tiny_size</span></tt> 1139 examples. The library contains a suite of operations for 1140 non-negative integral token arithmetic in its <tt class="docutils literal"><span 1141 1142 class="pre">arithmetic/</span></tt> subdirectory, as shown in 1143 Table A.1</p> 1144 <table border="1" class="docutils"> 1145 <caption>Preprocessor Library Arithmetic Operations</caption> <colgroup> 1146 <col width="44%" /> <col width="56%" /> </colgroup> 1147 <thead valign="bottom"> 1148 <tr> 1149 <th>Expression</th> 1150 <th>Value of Single Token Result</th> 1151 </tr> 1152 </thead> 1153 <tbody valign="top"> 1154 <tr> 1155 <td><tt class="docutils literal"><span class="pre">BOOST_PP_ADD(x,y)</span></tt></td> 1156 <td><tt class="docutils literal"><span class="pre">x</span> <span 1157 1158 class="pre">+</span> <span class="pre">y</span></tt></td> 1159 </tr> 1160 <tr> 1161 <td><tt class="docutils literal"><span class="pre">BOOST_PP_DEC(x)</span></tt></td> 1162 <td><tt class="docutils literal"><span class="pre">x</span> <span 1163 1164 class="pre">-</span> <span class="pre">1</span></tt></td> 1165 </tr> 1166 <tr> 1167 <td><tt class="docutils literal"><span class="pre">BOOST_PP_DIV(x,y)</span></tt></td> 1168 <td><tt class="docutils literal"><span class="pre">x</span> <span 1169 1170 class="pre">/</span> <span class="pre">y</span></tt></td> 1171 </tr> 1172 <tr> 1173 <td><tt class="docutils literal"><span class="pre">BOOST_PP_INC(x)</span></tt></td> 1174 <td><tt class="docutils literal"><span class="pre">x</span> <span 1175 1176 class="pre">+</span> <span class="pre">1</span></tt></td> 1177 </tr> 1178 <tr> 1179 <td><tt class="docutils literal"><span class="pre">BOOST_PP_MOD(x,y)</span></tt></td> 1180 <td><tt class="docutils literal"><span class="pre">x</span> <span 1181 1182 class="pre">%</span> <span class="pre">y</span></tt></td> 1183 </tr> 1184 <tr> 1185 <td><tt class="docutils literal"><span class="pre">BOOST_PP_MUL(x,y)</span></tt></td> 1186 <td><tt class="docutils literal"><span class="pre">x</span> <span 1187 1188 class="pre">*</span> <span class="pre">y</span></tt></td> 1189 </tr> 1190 <tr> 1191 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SUB(x,y)</span></tt></td> 1192 <td><tt class="docutils literal"><span class="pre">x</span> <span 1193 1194 class="pre">-</span> <span class="pre">y</span></tt></td> 1195 </tr> 1196 </tbody> 1197 </table> 1198 <p>The <tt class="docutils literal"><span class="pre">logical/</span></tt> 1199 subdirectory contains the convenient Boolean token operations shown 1200 in Table A.2 and the more efficient operations shown in Table A.3, 1201 which require that their operands are either <tt class="docutils literal"><span 1202 1203 class="pre">0</span></tt> or <tt class="docutils literal"><span 1204 1205 class="pre">1</span></tt> (a single bit).</p> 1206 <table border="1" class="docutils"> 1207 <caption>Preprocessor Library Integer Logical Operations</caption> <colgroup> 1208 <col width="44%" /> <col width="56%" /> </colgroup> 1209 <thead valign="bottom"> 1210 <tr> 1211 <th>Expression</th> 1212 <th>Value of Single Token Result</th> 1213 </tr> 1214 </thead> 1215 <tbody valign="top"> 1216 <tr> 1217 <td><tt class="docutils literal"><span class="pre">BOOST_PP_AND(x,y)</span></tt></td> 1218 <td><tt class="docutils literal"><span class="pre">x</span> <span 1219 1220 class="pre">&&</span> <span class="pre">y</span></tt></td> 1221 </tr> 1222 <tr> 1223 <td><tt class="docutils literal"><span class="pre">BOOST_PP_NOR(x,y)</span></tt></td> 1224 <td><tt class="docutils literal"><span class="pre">!(x</span> <span 1225 1226 class="pre">||</span> <span class="pre">y)</span></tt></td> 1227 </tr> 1228 <tr> 1229 <td><tt class="docutils literal"><span class="pre">BOOST_PP_OR(x,y)</span></tt></td> 1230 <td><tt class="docutils literal"><span class="pre">x</span> <span 1231 1232 class="pre">||</span> <span class="pre">y</span></tt></td> 1233 </tr> 1234 <tr> 1235 <td><tt class="docutils literal"><span class="pre">BOOST_PP_XOR(x,y)</span></tt></td> 1236 <td><tt class="docutils literal"><span class="pre">(bool)x</span> 1237 <span class="pre">!=</span> <span class="pre">(bool)y</span> 1238 <span class="pre">?</span> <span class="pre">1</span> <span 1239 1240 class="pre">:</span> <span class="pre">0</span></tt></td> 1241 </tr> 1242 <tr> 1243 <td><tt class="docutils literal"><span class="pre">BOOST_PP_NOT(x)</span></tt></td> 1244 <td><tt class="docutils literal"><span class="pre">x</span> <span 1245 1246 class="pre">?</span> <span class="pre">0</span> <span class="pre">:</span> 1247 <span class="pre">1</span></tt></td> 1248 </tr> 1249 <tr> 1250 <td><tt class="docutils literal"><span class="pre">BOOST_PP_BOOL(x)</span></tt></td> 1251 <td><tt class="docutils literal"><span class="pre">x</span> <span 1252 1253 class="pre">?</span> <span class="pre">1</span> <span class="pre">:</span> 1254 <span class="pre">0</span></tt></td> 1255 </tr> 1256 </tbody> 1257 </table> 1258 <table border="1" class="docutils"> 1259 <caption>Preprocessor Library Bit Logical Operations</caption> <colgroup> 1260 <col width="44%" /> <col width="56%" /> </colgroup> 1261 <thead valign="bottom"> 1262 <tr> 1263 <th>Expression</th> 1264 <th>Value of Single Token Result</th> 1265 </tr> 1266 </thead> 1267 <tbody valign="top"> 1268 <tr> 1269 <td><tt class="docutils literal"><span class="pre">BOOST_PP_BITAND(x,y)</span></tt></td> 1270 <td><tt class="docutils literal"><span class="pre">x</span> <span 1271 1272 class="pre">&&</span> <span class="pre">y</span></tt></td> 1273 </tr> 1274 <tr> 1275 <td><tt class="docutils literal"><span class="pre">BOOST_PP_BITNOR(x,y)</span></tt></td> 1276 <td><tt class="docutils literal"><span class="pre">!(x</span> <span 1277 1278 class="pre">||</span> <span class="pre">y)</span></tt></td> 1279 </tr> 1280 <tr> 1281 <td><tt class="docutils literal"><span class="pre">BOOST_PP_BITOR(x,y)</span></tt></td> 1282 <td><tt class="docutils literal"><span class="pre">x</span> <span 1283 1284 class="pre">||</span> <span class="pre">y</span></tt></td> 1285 </tr> 1286 <tr> 1287 <td><tt class="docutils literal"><span class="pre">BOOST_PP_BITXOR(x,y)</span></tt></td> 1288 <td><tt class="docutils literal"><span class="pre">(bool)x</span> 1289 <span class="pre">!=</span> <span class="pre">(bool)y</span> 1290 <span class="pre">?</span> <span class="pre">1</span> <span 1291 1292 class="pre">:</span> <span class="pre">0</span></tt></td> 1293 </tr> 1294 <tr> 1295 <td><tt class="docutils literal"><span class="pre">BOOST_PP_COMPL(x)</span></tt></td> 1296 <td><tt class="docutils literal"><span class="pre">x</span> <span 1297 1298 class="pre">?</span> <span class="pre">0</span> <span class="pre">:</span> 1299 <span class="pre">1</span></tt></td> 1300 </tr> 1301 </tbody> 1302 </table> 1303 <p>Finally, the <tt class="docutils literal"><span class="pre">comparison/</span></tt> 1304 subdirectory provides the token integral comparison operations shown 1305 in Table A.4.</p> 1306 <table border="1" class="docutils"> 1307 <caption>Preprocessor Library Comparison Operations</caption> <colgroup> 1308 <col width="46%" /> <col width="54%" /> </colgroup> 1309 <thead valign="bottom"> 1310 <tr> 1311 <th>Expression</th> 1312 <th>Value of Single Token Result</th> 1313 </tr> 1314 </thead> 1315 <tbody valign="top"> 1316 <tr> 1317 <td><tt class="docutils literal"><span class="pre">BOOST_PP_EQUAL(x,y)</span></tt></td> 1318 <td><tt class="docutils literal"><span class="pre">x</span> <span 1319 1320 class="pre">==</span> <span class="pre">y</span> <span 1321 1322 class="pre">?</span> <span class="pre">1</span> <span class="pre">:</span> 1323 <span class="pre">0</span></tt></td> 1324 </tr> 1325 <tr> 1326 <td><tt class="docutils literal"><span class="pre">BOOST_PP_NOT_EQUAL(x,y)</span></tt></td> 1327 <td><tt class="docutils literal"><span class="pre">x</span> <span 1328 1329 class="pre">!=</span> <span class="pre">y</span> <span 1330 1331 class="pre">?</span> <span class="pre">1</span> <span class="pre">:</span> 1332 <span class="pre">0</span></tt></td> 1333 </tr> 1334 <tr> 1335 <td><tt class="docutils literal"><span class="pre">BOOST_PP_LESS(x,y)</span></tt></td> 1336 <td><tt class="docutils literal"><span class="pre">x</span> <span 1337 1338 class="pre"><</span> <span class="pre">y</span> <span 1339 1340 class="pre">?</span> <span class="pre">1</span> <span class="pre">:</span> 1341 <span class="pre">0</span></tt></td> 1342 </tr> 1343 <tr> 1344 <td><tt class="docutils literal"><span class="pre">BOOST_PP_LESS_EQUAL(x,y)</span></tt></td> 1345 <td><tt class="docutils literal"><span class="pre">x</span> <span 1346 1347 class="pre"><=</span> <span class="pre">y</span> <span 1348 1349 class="pre">?</span> <span class="pre">1</span> <span class="pre">:</span> 1350 <span class="pre">0</span></tt></td> 1351 </tr> 1352 <tr> 1353 <td><tt class="docutils literal"><span class="pre">BOOST_PP_GREATER(x,y)</span></tt></td> 1354 <td><tt class="docutils literal"><span class="pre">x</span> <span 1355 1356 class="pre">></span> <span class="pre">y</span> <span 1357 1358 class="pre">?</span> <span class="pre">1</span> <span class="pre">:</span> 1359 <span class="pre">0</span></tt></td> 1360 </tr> 1361 <tr> 1362 <td><tt class="docutils literal"><span class="pre">BOOST_PP_GREATER_EQUAL(x,y)</span></tt></td> 1363 <td><tt class="docutils literal"><span class="pre">x</span> <span 1364 1365 class="pre">>=</span> <span class="pre">y</span> <span 1366 1367 class="pre">?</span> <span class="pre">1</span> <span class="pre">:</span> 1368 <span class="pre">0</span></tt></td> 1369 </tr> 1370 </tbody> 1371 </table> 1372 <p>Because it's common to have a choice among several workable 1373 comparison operators, it may be useful to know that <tt class="docutils literal"><span 1374 1375 class="pre">BOOST_PP_EQUAL</span></tt> and <tt class="docutils literal"><span 1376 1377 class="pre">BOOST_PP_NOT_EQUAL</span></tt> are likely to be O(1) 1378 while the other comparison operators are generally slower.</p> 1379 </div> 1380 <div class="section" id="control-structures"> 1381 <h2><a name="control-structures">A.4.3 Control Structures</a></h2> 1382 <p>In its <tt class="docutils literal"><span class="pre">control/</span></tt> 1383 directory, the Preprocessor Library supplies a macro <tt class="docutils literal"><span 1384 1385 class="pre">BOOST_PP_IF(c,t,f)</span></tt> that fulfills a 1386 similar role to the one filled by <tt class="docutils literal"><span 1387 1388 class="pre">mpl::if_</span></tt>. To explore the "control" 1389 group, we'll generate code for a framework of generic function 1390 objects: the Boost Function Library.<a class="footnote-reference" href="#function" 1391 1392 id="id10" name="id10">[8]</a> <tt class="docutils literal"><span 1393 1394 class="pre">boost::function</span></tt> is partially specialized 1395 to match function type arguments of each arity up to the maximum 1396 supported by the library:</p> 1397 <pre class="literal-block">template <class Signature> struct function; // primary template 1398 1399template <class R> // arity = 0 1400struct function<R()> 1401 <em>definition not shown...</em> 1402 1403template <class R, class A0> // arity = 1 1404struct function<R(A0)> 1405 <em>definition not shown...</em> 1406 1407template <class R, class A0, class A1> // arity = 2 1408struct function<R(A0,A1)> 1409 <em>definition not shown...</em> 1410 1411template <class R, class A0, class A1, class A2> // arity = 3 1412struct function<R(A0,A1,A2)> 1413 <em>definition not shown...</em> 1414 1415<em>etc.</em> 1416</pre> 1417 <!-- @example.replace(')>', ')>;') 1418compile() --> 1419 <table class="docutils footnote" frame="void" id="function" rules="none"> 1420 <colgroup><col class="label" /><col /></colgroup> 1421 <tbody valign="top"> 1422 <tr> 1423 <td class="label"><a class="fn-backref" href="#id10" name="function">[8]</a></td> 1424 <td>We touched briefly on the design of Boost Function when we 1425 discussed type erasure in Chapter 9. See the Function library 1426 documentation at <tt class="docutils literal"><span class="pre">boost_1_32_0/libs/function/index.html</span></tt> 1427 on the CD that accompanies this book for more information.</td> 1428 </tr> 1429 </tbody> 1430 </table> 1431 <p>We've already covered a few strategies that can be used to generate 1432 the pattern above, so we won't belabor that part of the problem; the 1433 file iteration approach we used for <tt class="docutils literal"><span 1434 1435 class="pre">tiny_size</span></tt> would be fine:</p> 1436 <pre class="literal-block">#ifndef BOOST_PP_IS_ITERATING 1437 1438# ifndef BOOST_FUNCTION_HPP_INCLUDED 1439# define BOOST_FUNCTION_HPP_INCLUDED 1440 1441# include <boost/preprocessor/repetition.hpp> 1442# include <boost/preprocessor/iteration/iterate.hpp> 1443 1444# ifndef FUNCTION_MAX_ARITY 1445# define FUNCTION_MAX_ARITY 15 1446# endif 1447 1448<strong>template <class Signature> struct function;</strong> // primary template 1449 1450// generate specializations 1451# define BOOST_PP_ITERATION_LIMITS (0, FUNCTION_MAX_ARITY) 1452# define BOOST_PP_FILENAME_1 "boost/function.hpp" // this file 1453# include BOOST_PP_ITERATE() 1454 1455# endif // BOOST_FUNCTION_HPP_INCLUDED 1456 1457#else // BOOST_PP_IS_ITERATING 1458 1459# define n BOOST_PP_ITERATION() 1460 1461// specialization pattern 1462<strong>template <class R BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)></strong> 1463<strong>struct function<R ( BOOST_PP_ENUM_PARAMS(n,A) )></strong> 1464 <em>definition not shown...</em> 1465 1466# undef n 1467 1468#endif // BOOST_PP_IS_ITERATING 1469</pre> 1470 <p><tt class="docutils literal"><span class="pre">BOOST_PP_ENUM_TRAILING_PARAMS</span></tt>, 1471 used above, is just like <tt class="docutils literal"><span class="pre">BOOST_PP_ENUM_PARAMS</span></tt> 1472 except that when its first argument is not <tt class="docutils literal"><span 1473 1474 class="pre">0</span></tt>, it generates a leading comma.</p> 1475 <!-- @example.replace_emphasis(';//') 1476tmpdir = tempfile.gettempdir()tmpboost = os.path.join(tmpdir,'boost')try: os.mkdir(tmpboost)except: pass 1477tmp_boost_function = os.path.join(tmpdir, 'boost/function.hpp')compile( options = vertical_options , source_file = tmp_boost_function 1478 , pop = None) --> 1479 <div class="section" id="argument-selection"> 1480 <h3><a name="argument-selection">A.4.3.1 Argument Selection</a></h3> 1481 <p>For the sake of interoperability with C++ standard library 1482 algorithms, it might be nice if <tt class="docutils literal"><span 1483 1484 class="pre">function</span></tt>s of one or two arguments were 1485 derived from appropriate specializations of <tt class="docutils literal"><span 1486 1487 class="pre">std::unary_function</span></tt> or <tt class="docutils literal"><span 1488 1489 class="pre">std::binary_function</span></tt>, respectively.<a 1490 1491 class="footnote-reference" href="#ebo" id="id11" name="id11">[9]</a> 1492 <tt class="docutils literal"><span class="pre">BOOST_PP_IF</span></tt> 1493 is a great tool for dealing with special cases:</p> 1494 <pre class="literal-block"># include <boost/preprocessor/control/if.hpp> 1495# include <boost/preprocessor/comparison/equal.hpp> 1496 1497// specialization pattern 1498template <class R BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)> 1499struct function<R ( BOOST_PP_ENUM_PARAMS(n,A) )> 1500 BOOST_PP_IF( 1501 BOOST_PP_EQUAL(n,2), <strong>: std::binary_function<A0, A1, R></strong> 1502 , BOOST_PP_IF( 1503 BOOST_PP_EQUAL(n,1), <strong>: std::unary_function<A0, R></strong> 1504 , <em>...empty argument...</em> 1505 ) 1506 ) 1507{ <em>...class body omitted...</em> }; 1508</pre> 1509 <!-- @pp_failure() --> 1510 <table class="docutils footnote" frame="void" id="ebo" rules="none"> 1511 <colgroup><col class="label" /><col /></colgroup> 1512 <tbody valign="top"> 1513 <tr> 1514 <td class="label"><a class="fn-backref" href="#id11" name="ebo">[9]</a></td> 1515 <td>While derivation from <tt class="docutils literal"><span 1516 1517 class="pre">std::unary_function</span></tt> or <tt class="docutils literal"><span 1518 1519 class="pre">std::binary_function</span></tt> might be 1520 necessary for interoperability with some older library 1521 implementations, it may inhibit the Empty Base Optimization 1522 (EBO) from taking effect when two such derived classes are 1523 part of the same object. For more information, see section 1524 9.4. In general, it's better to expose <tt class="docutils literal"><span 1525 1526 class="pre">first_argument_type</span></tt>, <tt class="docutils literal"><span 1527 1528 class="pre">second_argument_type</span></tt>, and <tt class="docutils literal"><span 1529 1530 class="pre">result_type</span></tt> <tt class="docutils literal"><span 1531 1532 class="pre">typedef</span></tt>s directly.</td> 1533 </tr> 1534 </tbody> 1535 </table> 1536 <p>Well, our first attempt has run into several problems. First off, 1537 you're not allowed to pass an empty argument to the preprocessor.<a 1538 1539 class="footnote-reference" href="#c99" id="id12" name="id12">[3]</a> 1540 Secondly, because angle brackets don't get special treatment, the 1541 commas in the <tt class="docutils literal"><span class="pre">std::unary_function</span></tt> 1542 and <tt class="docutils literal"><span class="pre">std::binary_function</span></tt> 1543 specializations above are treated as macro argument separators, 1544 and the preprocessor will complain that we've passed the wrong 1545 number of arguments to <tt class="docutils literal"><span class="pre">BOOST_PP_IF</span></tt> 1546 in two places.</p> 1547 <p>Because it captures all of the issues, let's focus on the inner <tt 1548 1549 class="docutils literal"><span class="pre">BOOST_PP_IF</span></tt> 1550 invocation for a moment. The strategy that <tt class="docutils literal"><span 1551 1552 class="pre">mpl::eval_if</span></tt> uses, of selecting a 1553 nullary function to invoke, could work nicely here. The 1554 preprocessor doesn't have a direct analogue for <tt class="docutils literal"><span 1555 1556 class="pre">mpl::eval_if</span></tt>, but it doesn't really 1557 need one: We can get the right effect by adding a second set of 1558 parentheses to <tt class="docutils literal"><span class="pre">BOOST_PP_IF</span></tt>.</p> 1559 <pre class="literal-block">#define BOOST_FUNCTION_unary() : std::unary_function<A0,R> 1560#define BOOST_FUNCTION_empty() // nothing 1561 1562... 1563 1564 , BOOST_PP_IF( 1565 BOOST_PP_EQUAL(n,1), BOOST_FUNCTION_unary 1566 , BOOST_FUNCTION_empty 1567 )<strong>()</strong> 1568 1569#undef BOOST_FUNCTION_empty 1570#undef BOOST_FUNCTION_unary 1571</pre> 1572 <!-- @ignore() --> 1573 <p>A nullary macro that generates nothing is so commonly needed that 1574 the library's "facilities" group provides one: <tt class="docutils literal"><span 1575 1576 class="pre">BOOST_PP_EMPTY</span></tt>. To complete the 1577 example we'll need to delay evaluation all the way to the outer <tt 1578 1579 class="docutils literal"><span class="pre">BOOST_PP_IF</span></tt> 1580 invocation, because <tt class="docutils literal"><span class="pre">std::binary_function<A0,A1,R></span></tt> 1581 also has a "comma problem":</p> 1582 <pre class="literal-block"># include <boost/preprocessor/<strong>facilities/empty.hpp</strong>> 1583 1584# define BOOST_FUNCTION_binary() : std::binary_function<A0,A1,R> 1585# define BOOST_FUNCTION_unary() : std::unary_function<A0,R> 1586 1587// specialization pattern 1588template <class R BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)> 1589struct function<R ( BOOST_PP_ENUM_PARAMS(n,A) )> 1590 BOOST_PP_IF( 1591 BOOST_PP_EQUAL(n,2), BOOST_FUNCTION_binary 1592 , BOOST_PP_IF( 1593 BOOST_PP_EQUAL(n,1), BOOST_FUNCTION_unary 1594 , <strong>BOOST_PP_EMPTY</strong> 1595 ) 1596 )<strong>()</strong> 1597{ 1598 <em>...class body omitted...</em> 1599}; 1600 1601# undef BOOST_FUNCTION_unary 1602# undef BOOST_FUNCTION_binary 1603# undef n 1604</pre> 1605 <!-- @stack.pop() 1606stack[-1].replace('// specialization pattern', '////\n%s\n////' % str(example))compile(source_file = tmp_boost_function, pop = None) --> 1607 <p>Note that because we happened to be using file iteration, we 1608 could have also used <tt class="docutils literal"><span class="pre">#if</span></tt> 1609 on <tt class="docutils literal"><span class="pre">n</span></tt>'s 1610 value directly:</p> 1611 <pre class="literal-block"> template <class R BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)> 1612 struct function<R ( BOOST_PP_ENUM_PARAMS(n,A) )> 1613<strong>#if n == 2</strong> 1614 : std::binary_function<A0, A1, R> 1615<strong>#elif n == 1</strong> 1616 : std::unary_function<A0, R> 1617<strong>#endif</strong> 1618</pre> 1619 <!-- @stack.pop() 1620stack[-1].sub( r'////.*////', '////\n%s\n////' % str(example), flags = re.DOTALL)compile(source_file = tmp_boost_function, pop = None) --> 1621 <p><tt class="docutils literal"><span class="pre">BOOST_PP_IF</span></tt> 1622 has the advantage of enabling us to encapsulate the logic in a 1623 reusable macro, parameterized on <tt class="docutils literal"><span 1624 1625 class="pre">n</span></tt>, that is compatible with all 1626 repetition constructs:</p> 1627 <pre class="literal-block">#define BOOST_FUNCTION_BASE(n) \ 1628 BOOST_PP_IF(BOOST_PP_EQUAL(n,2), BOOST_FUNCTION_binary \ 1629 , BOOST_PP_IF(BOOST_PP_EQUAL(n,1), BOOST_FUNCTION_unary \ 1630 , BOOST_PP_EMPTY \ 1631 ) \ 1632 )() 1633</pre> 1634 <!-- @compile(options = ['-E']) --> </div> 1635 <div class="section" id="other-selection-constructs"> 1636 <h3><a name="other-selection-constructs">A.4.3.2 Other Selection 1637 Constructs</a></h3> 1638 <p><tt class="docutils literal"><span class="pre">BOOST_PP_IDENTITY</span></tt>, 1639 also in the "facilities" group, is an interesting cousin of <tt class="docutils literal"><span 1640 1641 class="pre">BOOST_PP_EMPTY</span></tt>:</p> 1642 <pre class="literal-block">#define BOOST_PP_IDENTITY(tokens) tokens BOOST_PP_EMPTY 1643</pre> 1644 <!-- @ignore() --> 1645 <p>You can think of it as creating a nullary macro that returns <tt 1646 1647 class="docutils literal"><span class="pre">tokens</span></tt>: 1648 When empty parentheses are appended, the trailing <tt class="docutils literal"><span 1649 1650 class="pre">BOOST_PP_EMPTY</span></tt> is expanded leaving 1651 just <tt class="docutils literal"><span class="pre">tokens</span></tt> 1652 behind. If we had wanted inheritance from <tt class="docutils literal"><span 1653 1654 class="pre">mpl::empty_base</span></tt> when <tt class="docutils literal"><span 1655 1656 class="pre">function</span></tt>'s arity is not one or two, we 1657 could have used <tt class="docutils literal"><span class="pre">BOOST_PP_IDENTITY</span></tt>:</p> 1658 <pre class="literal-block">// specialization pattern 1659template <class R BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)> 1660struct function<R ( BOOST_PP_ENUM_PARAMS(n,A) )> 1661 BOOST_PP_IF( 1662 BOOST_PP_EQUAL(n,2), BOOST_FUNCTION_binary 1663 , BOOST_PP_IF( 1664 BOOST_PP_EQUAL(n,1), BOOST_FUNCTION_unary 1665 , <strong>BOOST_PP_IDENTITY(: mpl::empty_base)</strong> 1666 ) 1667 )<strong>()</strong> 1668{ 1669 <em>...class body omitted...</em> 1670}; 1671</pre> 1672 <!-- @stack.pop() 1673stack[-1].sub( r'////.*////', '////\n%s\n////' % str(example), flags = re.DOTALL)compile(source_file = tmp_boost_function, pop = None) --> 1674 <p>It's also worth knowing about <tt class="docutils literal"><span 1675 1676 class="pre">BOOST_PP_EXPR_IF</span></tt>, which generates its 1677 second argument or nothing, depending on the Boolean value of its 1678 first:</p> 1679 <pre class="literal-block">#define BOOST_PP_EXPR_IF(c,tokens) \ 1680 BOOST_PP_IF(c,BOOST_PP_IDENTITY(tokens),BOOST_PP_EMPTY)() 1681</pre> 1682 <!-- @example.append( 1683 'int BOOST_PP_EXPR_IF(1,main) BOOST_PP_EXPR_IF(0,quack) () {}')compile() --> 1684 <p>So <tt class="docutils literal"><span class="pre">BOOST_PP_EXPR_IF(1,foo)</span></tt> 1685 expands to <tt class="docutils literal"><span class="pre">foo</span></tt>, 1686 while <tt class="docutils literal"><span class="pre">BOOST_PP_EXPR_IF(0,foo)</span></tt> 1687 expands to nothing.</p> 1688 </div> 1689 </div> 1690 <div class="section" id="token-pasting"> 1691 <h2><a name="token-pasting">A.4.4 Token Pasting</a></h2> 1692 <p>It would be nice if there were a generic way to access the return 1693 and parameter types of <em>all</em> function objects, rather than 1694 just the unary and binary ones. A metafunction returning the 1695 signature as an MPL sequence would do the trick. We could just 1696 specialize <tt class="docutils literal"><span class="pre">signature</span></tt> 1697 for each <tt class="docutils literal"><span class="pre">function</span></tt> 1698 arity:</p> 1699 <pre class="literal-block">template <class F> struct signature; // primary template 1700 1701// partial specializations for boost::function 1702template <class R> 1703struct signature<function<R()> > 1704 : mpl::vector1<R> {}; 1705 1706template <class R, class A0> 1707struct signature<function<R(A0)> > 1708 : mpl::vector2<R,A0> {}; 1709 1710template <class R, class A0, class A1> 1711struct signature<function<R(A0,A1)> > 1712 : mpl::vector3<R,A0,A1> {}; 1713 1714... 1715</pre> 1716 <!-- @example.prepend('template <class T> struct function;') 1717compile() --> 1718 <p>To generate these specializations, we might add the following to 1719 our pattern:</p> 1720 <pre class="literal-block">template <class R BOOST_PP_ENUM_TRAILING_PARAMS(n, class A)> 1721struct signature<function<R( BOOST_PP_ENUM_PARAMS(n,A) )> > 1722 : mpl::<strong>BOOST_PP_CAT</strong>(vector,n)< 1723 R BOOST_PP_ENUM_TRAILING_PARAMS(n,A) 1724 > {}; 1725</pre> 1726 <!-- @stack.pop() 1727stack[-1].replace( ';//', ''';// template <class T> struct signature; %s''' % example) 1728compile(source_file = tmp_boost_function) --> 1729 <p><tt class="docutils literal"><span class="pre">BOOST_PP_CAT</span></tt> 1730 implements <strong>token pasting</strong>; its two arguments are 1731 "glued" together into a single token. Since this is a 1732 general-purpose macro, it sits in <tt class="docutils literal"><span 1733 1734 class="pre">cat.hpp</span></tt> at the top level of the 1735 library's directory tree.</p> 1736 <p>Although the preprocessor has a built-in token-pasting operator, <tt 1737 1738 class="docutils literal"><span class="pre">##</span></tt>, it only 1739 works within a macro definition. If we'd used it here, it wouldn't 1740 have taken effect at all:</p> 1741 <pre class="literal-block">template <class R> 1742struct signature<function<R()> > 1743 : mpl::<strong>vector##1</strong><R> {}; 1744 1745template <class R, class A0> 1746struct signature<function<R(A0)> > 1747 : mpl::<strong>vector##2</strong><R,A0> {}; 1748 1749template <class R, class A0, class A1> 1750struct signature<function<R(A0,A1)> > 1751 : mpl::<strong>vector##3</strong><R,A0,A1> {}; 1752 1753... 1754</pre> 1755 <!-- @example.replace('##','') 1756example.prepend(''' template <class T> struct function; template <class T> struct signature;''') 1757compile() --> 1758 <p>Also, <tt class="docutils literal"><span class="pre">##</span></tt> 1759 often yields surprising results by taking effect before its 1760 arguments have been expanded:</p> 1761 <pre class="literal-block">#define N 10 1762#define VEC(i) vector##i 1763 1764VEC(N) // vectorN 1765</pre> 1766 <!-- @example.wrap('typedef int vectorN;', 'x;') 1767compile() --> 1768 <p>By contrast, <tt class="docutils literal"><span class="pre">BOOST_PP_CAT</span></tt> 1769 delays concatenation until after its arguments have been fully 1770 evaluated:</p> 1771 <pre class="literal-block">#define N 10 1772#define VEC(i) BOOST_PP_CAT(vector,i) 1773 1774VEC(N) // vector10 1775</pre> 1776 <!-- @example.wrap(''' 1777 #include <boost/preprocessor/cat.hpp> typedef int vector10; ''', 'x;')compile() --> 1778 </div> 1779 <div class="section" id="data-types"> 1780 <h2><a name="data-types">A.4.5 Data Types</a></h2> 1781 <p>The Preprocessor library also provides <strong>data types</strong>, 1782 which you can think of as being analogous to the MPL's type 1783 sequences. Preprocessor data types store <em>macro arguments</em> 1784 instead of C++ types.</p> 1785 <div class="section" id="sequences"> 1786 <h3><a name="sequences">A.4.5.1 Sequences</a></h3> 1787 <p>A <strong>sequence</strong> (or <strong>seq</strong> for short) 1788 is any string of nonempty parenthesized <em>macro arguments</em>. 1789 For instance, here's a three-element sequence:</p> 1790 <pre class="literal-block">#define MY_SEQ (f(12))(a + 1)(foo) 1791</pre> 1792 <!-- @ignore() --> 1793 <p>Here's how we might use a sequence to generate specializations of 1794 the <tt class="docutils literal"><span class="pre">is_integral</span></tt> 1795 template from the Boost Type Traits library (see Chapter 2):</p> 1796 <pre class="literal-block">#include <boost/preprocessor/seq.hpp> 1797 1798template <class T> 1799struct is_integral : mpl::false_ {}; 1800 1801// a seq of integral types with unsigned counterparts 1802#define BOOST_TT_basic_ints (char)(short)(int)(long) 1803 1804// generate a seq containing "signed t" and "unsigned t" 1805#define BOOST_TT_int_pair(r,data,t) (signed t)(unsigned t) 1806 1807// a seq of all the integral types 1808#define BOOST_TT_ints \ 1809 (bool)(char) \ 1810 BOOST_PP_SEQ_FOR_EACH(BOOST_TT_int_pair, ~, BOOST_TT_basic_ints) 1811 1812// generate an is_integral specialization for type t 1813#define BOOST_TT_is_integral_spec(r,data,t) \ 1814 template <> \ 1815 struct is_integral<t> : mpl::true_ {}; 1816 1817BOOST_PP_SEQ_FOR_EACH(BOOST_TT_is_integral_spec, ~, BOOST_TT_ints) 1818 1819#undef BOOST_TT_is_integral_spec 1820#undef BOOST_TT_ints 1821#undef BOOST_TT_int_pair 1822#undef BOOST_TT_basic_ints 1823</pre> 1824 <!-- @compile() --> 1825 <p><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_FOR_EACH</span></tt> 1826 is a higher-order macro, similar to <tt class="docutils literal"><span 1827 1828 class="pre">BOOST_PP_REPEAT</span></tt>, that invokes its 1829 first argument on each element of its third argument.</p> 1830 <p>Sequences are the most efficient, most flexible, and 1831 easiest-to-use of the library's data structures, provided that you 1832 never need to make an empty one: An empty sequence would contain 1833 no tokens, and so couldn't be passed as a macro argument. The 1834 other data structures covered here all have an empty 1835 representation.</p> 1836 <p>The facilities for manipulating sequences are all in the 1837 library's <tt class="docutils literal"><span class="pre">seq/</span></tt> 1838 subdirectory. They are summarized in Table A.5, where <tt class="docutils literal"><span 1839 1840 class="pre">t</span></tt> is the sequence <tt class="docutils literal"><span 1841 1842 class="pre">(</span></tt><em>t</em><sub>0</sub><tt class="docutils literal"><span 1843 1844 class="pre">)(</span></tt><em>t</em><sub>1</sub><tt class="docutils literal"><span 1845 1846 class="pre">)...(</span></tt><em>t</em><sub>k</sub><tt class="docutils literal"><span 1847 1848 class="pre">)</span></tt>. Where <em>s</em>, <em>r</em>, and 1849 <em>d</em> appear, they have a similar purpose to the <tt class="docutils literal"><span 1850 1851 class="pre">z</span></tt> parameters we discussed earlier (and 1852 suggested you ignore for now).</p> 1853 <table border="1" class="docutils"> 1854 <caption>Preprocessor Sequence Operations</caption> <colgroup> <col 1855 1856 width="51%" /> <col width="49%" /> </colgroup> 1857 <thead valign="bottom"> 1858 <tr> 1859 <th>Expression</th> 1860 <th>Result</th> 1861 </tr> 1862 </thead> 1863 <tbody valign="top"> 1864 <tr> 1865 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_CAT(t)</span></tt></td> 1866 <td><em>t</em><sub>0</sub><em>t</em><sub>1</sub>...<em>t</em><sub>k</sub></td> 1867 </tr> 1868 <tr> 1869 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_ELEM(n,t)</span></tt></td> 1870 <td><em>t</em><sub>n</sub></td> 1871 </tr> 1872 <tr> 1873 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_ENUM(t)</span></tt></td> 1874 <td><em>t</em><sub>0</sub>, <em>t</em><sub>1</sub>, ...<em>t</em><sub>k</sub></td> 1875 </tr> 1876 <tr> 1877 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_FILTER(pred,data,t)</span></tt></td> 1878 <td><tt class="docutils literal"><span class="pre">t</span></tt> 1879 without the elements that don't satisfy <tt class="docutils literal"><span 1880 1881 class="pre">pred</span></tt></td> 1882 </tr> 1883 <tr> 1884 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_FIRST_N(n,t)</span></tt></td> 1885 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>0</sub><tt 1886 1887 class="docutils literal"><span class="pre">)(</span></tt><em>t</em><sub>1</sub><tt 1888 1889 class="docutils literal"><span class="pre">)</span></tt>...<tt 1890 1891 class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>n-1</sub><tt 1892 1893 class="docutils literal"><span class="pre">)</span></tt></td> 1894 </tr> 1895 <tr> 1896 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_FOLD_LEFT(op,</span> 1897 <span class="pre">x,</span> <span class="pre">t)</span></tt></td> 1898 <td>...<tt class="docutils literal"><span class="pre">op(</span></tt><em>s</em><tt 1899 1900 class="docutils literal"><span class="pre">,op(</span></tt><em>s</em><tt 1901 1902 class="docutils literal"><span class="pre">,op(</span></tt><em>s</em><tt 1903 1904 class="docutils literal"><span class="pre">,x</span></tt>,<em>t</em><sub>0</sub><tt 1905 1906 class="docutils literal"><span class="pre">),</span></tt><em>t</em><sub>1</sub><tt 1907 1908 class="docutils literal"><span class="pre">),</span></tt><em>t</em><sub>2</sub><tt 1909 1910 class="docutils literal"><span class="pre">)</span></tt>...</td> 1911 </tr> 1912 <tr> 1913 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_FOLD_RIGHT(op,</span> 1914 <span class="pre">x,</span> <span class="pre">t)</span></tt></td> 1915 <td>...<tt class="docutils literal"><span class="pre">op(</span></tt><em>s</em><tt 1916 1917 class="docutils literal"><span class="pre">,op(</span></tt><em>s</em><tt 1918 1919 class="docutils literal"><span class="pre">,op(</span></tt><em>s</em><tt 1920 1921 class="docutils literal"><span class="pre">,x</span></tt>,<em>t</em><sub>k</sub><tt 1922 1923 class="docutils literal"><span class="pre">),</span></tt><em>t</em><sub>k-1</sub><tt 1924 1925 class="docutils literal"><span class="pre">),</span></tt> 1926 <em>t</em><sub>k-2</sub><tt class="docutils literal"><span class="pre">)</span></tt>...</td> 1927 </tr> 1928 <tr> 1929 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_FOR_EACH(f,</span> 1930 <span class="pre">x,</span> <span class="pre">t)</span></tt></td> 1931 <td><tt class="docutils literal"><span class="pre">f(</span></tt><em>r</em><tt 1932 1933 class="docutils literal"><span class="pre">,</span> <span 1934 1935 class="pre">x,</span></tt><em>t</em><sub>0</sub><tt class="docutils literal"><span 1936 1937 class="pre">)</span> <span class="pre">f(</span></tt><em>r</em><tt 1938 1939 class="docutils literal"><span class="pre">,</span> <span 1940 1941 class="pre">x,</span></tt><em>t</em><sub>1</sub><tt class="docutils literal"><span 1942 1943 class="pre">)</span></tt>...<tt class="docutils literal"><span 1944 1945 class="pre">f(</span></tt><em>r</em><tt class="docutils literal"><span 1946 1947 class="pre">,</span> <span class="pre">x,</span></tt><em>t</em><sub>k</sub><tt 1948 1949 class="docutils literal"><span class="pre">)</span></tt></td> 1950 </tr> 1951 <tr> 1952 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_FOR_EACH_I(g,</span> 1953 <span class="pre">x,</span> <span class="pre">t)</span></tt></td> 1954 <td><tt class="docutils literal"><span class="pre">g(</span></tt><em>r</em><tt 1955 1956 class="docutils literal"><span class="pre">,</span> <span 1957 1958 class="pre">x,</span> <span class="pre">0,</span></tt> 1959 <em>t</em><sub>0</sub><tt class="docutils literal"><span class="pre">)</span> 1960 <span class="pre">g(</span></tt><em>r</em><tt class="docutils literal"><span 1961 1962 class="pre">,</span> <span class="pre">x,</span> <span 1963 1964 class="pre">1,</span></tt> <em>t</em><sub>1</sub><tt class="docutils literal"><span 1965 1966 class="pre">)</span></tt>... <tt class="docutils literal"><span 1967 1968 class="pre">g(</span></tt><em>r</em><tt class="docutils literal"><span 1969 1970 class="pre">,</span> <span class="pre">x,</span> <span 1971 1972 class="pre">k,</span></tt> <em>t</em><sub>k</sub><tt class="docutils literal"><span 1973 1974 class="pre">)</span></tt></td> 1975 </tr> 1976 <tr> 1977 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_FOR_EACH_PRODUCT(h,</span> 1978 <span class="pre">x,</span> <span class="pre">t)</span></tt></td> 1979 <td> 1980 <dl class="first last docutils"> 1981 <dt>Cartesian product—</dt> 1982 <dd>see online docs</dd> 1983 </dl> 1984 </td> 1985 </tr> 1986 <tr> 1987 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_INSERT(t,i,tokens)</span></tt></td> 1988 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>0</sub><tt 1989 1990 class="docutils literal"><span class="pre">)(</span></tt><em>t</em><sub>1</sub><tt 1991 1992 class="docutils literal"><span class="pre">)</span></tt>...<tt 1993 1994 class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>i-1</sub><tt 1995 1996 class="docutils literal"><span class="pre">)(tokens)</span> 1997 <span class="pre">(</span></tt><em>t</em><sub>i</sub><tt class="docutils literal"><span 1998 1999 class="pre">)(</span></tt><em>t</em><sub>i+1</sub><tt class="docutils literal"><span 2000 2001 class="pre">)</span></tt>...<tt class="docutils literal"><span 2002 2003 class="pre">(</span></tt><em>t</em><sub>k</sub><tt class="docutils literal"><span 2004 2005 class="pre">)</span></tt></td> 2006 </tr> 2007 <tr> 2008 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_POP_BACK(t)</span></tt></td> 2009 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>0</sub><tt 2010 2011 class="docutils literal"><span class="pre">)(</span></tt><em>t</em><sub>1</sub><tt 2012 2013 class="docutils literal"><span class="pre">)</span></tt>...<tt 2014 2015 class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>k-1</sub><tt 2016 2017 class="docutils literal"><span class="pre">)</span></tt></td> 2018 </tr> 2019 <tr> 2020 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_POP_FRONT(t)</span></tt></td> 2021 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>1</sub><tt 2022 2023 class="docutils literal"><span class="pre">)(</span></tt><em>t</em><sub>2</sub><tt 2024 2025 class="docutils literal"><span class="pre">)</span></tt>...<tt 2026 2027 class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>k</sub><tt 2028 2029 class="docutils literal"><span class="pre">)</span></tt></td> 2030 </tr> 2031 <tr> 2032 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_PUSH_BACK(t,tokens)</span></tt></td> 2033 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>0</sub><tt 2034 2035 class="docutils literal"><span class="pre">)(</span></tt><em>t</em><sub>1</sub><tt 2036 2037 class="docutils literal"><span class="pre">)</span></tt>...<tt 2038 2039 class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>k</sub><tt 2040 2041 class="docutils literal"><span class="pre">)(tokens)</span></tt></td> 2042 </tr> 2043 <tr> 2044 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_PUSH_FRONT(t,tokens)</span></tt></td> 2045 <td><tt class="docutils literal"><span class="pre">(tokens)(</span></tt><em>t</em><sub>0</sub><tt 2046 2047 class="docutils literal"><span class="pre">)(</span></tt><em>t</em><sub>1</sub><tt 2048 2049 class="docutils literal"><span class="pre">)</span></tt>...<tt 2050 2051 class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>k</sub><tt 2052 2053 class="docutils literal"><span class="pre">)</span></tt></td> 2054 </tr> 2055 <tr> 2056 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_REMOVE(t,i)</span></tt></td> 2057 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>0</sub><tt 2058 2059 class="docutils literal"><span class="pre">)(</span></tt><em>t</em><sub>1</sub><tt 2060 2061 class="docutils literal"><span class="pre">)</span></tt>...<tt 2062 2063 class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>i-1</sub><tt 2064 2065 class="docutils literal"><span class="pre">)(</span></tt><em>t</em><sub>i+1</sub><tt 2066 2067 class="docutils literal"><span class="pre">)</span></tt>...<tt 2068 2069 class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>k</sub><tt 2070 2071 class="docutils literal"><span class="pre">)</span></tt></td> 2072 </tr> 2073 <tr> 2074 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_REPLACE(t,i,tokens)</span></tt></td> 2075 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>0</sub><tt 2076 2077 class="docutils literal"><span class="pre">)(</span></tt><em>t</em><sub>1</sub><tt 2078 2079 class="docutils literal"><span class="pre">)</span></tt>...<tt 2080 2081 class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>i-1</sub><tt 2082 2083 class="docutils literal"><span class="pre">)(tokens)(</span></tt><em>t</em><sub>i+1</sub><tt 2084 2085 class="docutils literal"><span class="pre">)</span></tt>...<tt 2086 2087 class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>k</sub><tt 2088 2089 class="docutils literal"><span class="pre">)</span></tt></td> 2090 </tr> 2091 <tr> 2092 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_REST_N(n,t)</span></tt></td> 2093 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>n</sub><tt 2094 2095 class="docutils literal"><span class="pre">)(</span></tt><em>t</em><sub>n+1</sub><tt 2096 2097 class="docutils literal"><span class="pre">)</span></tt>...<tt 2098 2099 class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>k</sub><tt 2100 2101 class="docutils literal"><span class="pre">)</span></tt></td> 2102 </tr> 2103 <tr> 2104 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_REVERSE(t)</span></tt></td> 2105 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>k</sub><tt 2106 2107 class="docutils literal"><span class="pre">)(</span></tt><em>t</em><sub>k-1</sub><tt 2108 2109 class="docutils literal"><span class="pre">)</span></tt>...<tt 2110 2111 class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>0</sub><tt 2112 2113 class="docutils literal"><span class="pre">)</span></tt></td> 2114 </tr> 2115 <tr> 2116 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_HEAD(t)</span></tt></td> 2117 <td><em>t</em><sub>0</sub></td> 2118 </tr> 2119 <tr> 2120 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_TAIL(t)</span></tt></td> 2121 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>1</sub><tt 2122 2123 class="docutils literal"><span class="pre">)(</span></tt><em>t</em><sub>2</sub><tt 2124 2125 class="docutils literal"><span class="pre">)</span></tt>...<tt 2126 2127 class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>k</sub><tt 2128 2129 class="docutils literal"><span class="pre">)</span></tt></td> 2130 </tr> 2131 <tr> 2132 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_SIZE(t)</span></tt></td> 2133 <td><em>k+1</em></td> 2134 </tr> 2135 <tr> 2136 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_SUBSEQ(t,i,m)</span></tt></td> 2137 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>i</sub><tt 2138 2139 class="docutils literal"><span class="pre">)(</span></tt><em>t</em><sub>i+1</sub><tt 2140 2141 class="docutils literal"><span class="pre">)</span></tt>...<tt 2142 2143 class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>i+m-1</sub><tt 2144 2145 class="docutils literal"><span class="pre">)</span></tt></td> 2146 </tr> 2147 <tr> 2148 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_TO_ARRAY(t)</span></tt></td> 2149 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>k+1</em> 2150 <tt class="docutils literal"><span class="pre">,(</span></tt><em>t</em><sub>0</sub><tt 2151 2152 class="docutils literal"><span class="pre">,</span></tt><em>t</em><sub>1</sub><tt 2153 2154 class="docutils literal"><span class="pre">,</span></tt>...<em>t</em><sub>k</sub><tt 2155 2156 class="docutils literal"><span class="pre">))</span></tt></td> 2157 </tr> 2158 <tr> 2159 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_TO_TUPLE(t)</span></tt></td> 2160 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>t</em><sub>0</sub><tt 2161 2162 class="docutils literal"><span class="pre">,</span></tt> <em>t</em><sub>1</sub><tt 2163 2164 class="docutils literal"><span class="pre">,</span></tt>...<em>t</em><sub>k</sub><tt 2165 2166 class="docutils literal"><span class="pre">)</span></tt></td> 2167 </tr> 2168 <tr> 2169 <td><tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_TRANSFORM(f,</span> 2170 <span class="pre">x,</span> <span class="pre">t)</span></tt></td> 2171 <td><tt class="docutils literal"><span class="pre">(f(</span></tt><em>r</em><tt 2172 2173 class="docutils literal"><span class="pre">,x,</span></tt><em>t</em><sub>0</sub><tt 2174 2175 class="docutils literal"><span class="pre">))</span> <span 2176 2177 class="pre">(f(</span></tt><em>r</em><tt class="docutils literal"><span 2178 2179 class="pre">,x,</span></tt><em>t</em><sub>1</sub><tt class="docutils literal"><span 2180 2181 class="pre">))</span></tt>...<tt class="docutils literal"><span 2182 2183 class="pre">(f(</span></tt><em>r</em><tt class="docutils literal"><span 2184 2185 class="pre">,x,</span></tt><em>t</em><sub>k</sub><tt class="docutils literal"><span 2186 2187 class="pre">))</span></tt></td> 2188 </tr> 2189 </tbody> 2190 </table> 2191 <p>It's worth noting that while there is no upper limit on the 2192 length of a sequence, operations such as <tt class="docutils literal"><span 2193 2194 class="pre">BOOST_PP_SEQ_ELEM</span></tt> that take numeric 2195 arguments will only work with values up to 256.</p> 2196 </div> 2197 <div class="section" id="tuples"> 2198 <h3><a name="tuples">A.4.5.2 Tuples</a></h3> 2199 <p>A <strong>tuple</strong> is a very simple data structure for 2200 which the library provides random access and a few other basic 2201 operations. A tuple takes the form of a parenthesized, 2202 comma-separated list of <em>macro arguments</em>. For example, 2203 this is a three-element tuple:</p> 2204 <pre class="literal-block">#define TUPLE3 (f(12), a + 1, foo) 2205</pre> 2206 <p>The operations in the library's <tt class="docutils literal"><span 2207 2208 class="pre">tuple/</span></tt> subdirectory can handle tuples 2209 of up to 25 elements. For example, a tuple's <tt class="docutils literal"><span 2210 2211 class="pre">N</span></tt>th element can be accessed via <tt class="docutils literal"><span 2212 2213 class="pre">BOOST_PP_TUPLE_ELEM</span></tt>, as follows:</p> 2214 <pre class="literal-block"> // length index tuple 2215BOOST_PP_TUPLE_ELEM( 3 , 1 , TUPLE3) // a + 1 2216</pre> 2217 <!-- @def gen_id(id = 'a', hdr = 'tuple'): 2218 example.wrap(''' #include <boost/preprocessor/%s.hpp> int const %s = 0; int const x =''' % (hdr,id), ';') 2219 compile('all', pop = 1)gen_id() --> 2220 <p>Notice that we had to pass the tuple's length as the second 2221 argument to <tt class="docutils literal"><span class="pre">BOOST_PP_TUPLE_ELEM</span></tt>; 2222 in fact, <em>all</em> tuple operations require explicit 2223 specification of the tuple's length. We're not going to summarize 2224 the other four operations in the "tuple" group here—you can 2225 consult the Preprocessor library's electronic documentation for 2226 more details. We note, however, that sequences can be transformed 2227 into tuples with <tt class="docutils literal"><span class="pre">BOOST_PP_SEQ_TO_TUPLE</span></tt>, 2228 and nonempty tuples can be transformed back into sequences with <tt 2229 2230 class="docutils literal"><span class="pre">BOOST_PP_TUPLE_TO_SEQ</span></tt>.</p> 2231 <p>The greatest strength of tuples is that they conveniently take 2232 the same representation as a macro argument list:</p> 2233 <pre class="literal-block">#define FIRST_OF_THREE(a1,a2,a3) a1 2234#define SECOND_OF_THREE(a1,a2,a3) a2 2235#define THIRD_OF_THREE(a1,a2,a3) a3 2236 2237// uses tuple as an argument list 2238# define SELECT(selector, tuple) <strong>selector tuple</strong> 2239 2240SELECT(THIRD_OF_THREE, TUPLE3) // foo 2241</pre> 2242 <!-- @gen_id('foo') --> </div> 2243 <div class="section" id="arrays"> 2244 <h3><a name="arrays">A.4.5.3 Arrays</a></h3> 2245 <p>An <strong>array</strong> is just a tuple containing a 2246 non-negative integer and a tuple of that length:</p> 2247 <pre class="literal-block">#define ARRAY3 ( 3, TUPLE3 ) 2248</pre> 2249 <p>Because an array carries its length around with it, the library's 2250 interface for operating on arrays is much more convenient than the 2251 one used for tuples:</p> 2252 <pre class="literal-block">BOOST_PP_ARRAY_ELEM(1, ARRAY3) // a + 1 2253</pre> 2254 <!-- @gen_id(hdr = 'array') 2255del stack[-2:] --> 2256 <p>The facilities for manipulating arrays of up to 25 elements are 2257 all in the library's <tt class="docutils literal"><span class="pre">array/</span></tt> 2258 subdirectory. They are summarized in Table A.6, where <tt class="docutils literal"><span 2259 2260 class="pre">a</span></tt> is the array <tt class="docutils literal"><span 2261 2262 class="pre">(</span></tt><em>k</em><tt class="docutils literal"><span 2263 2264 class="pre">,</span> <span class="pre">(</span></tt><em>a</em><sub>0</sub><tt 2265 2266 class="docutils literal"><span class="pre">,</span></tt><em>a</em><sub>1</sub><tt 2267 2268 class="docutils literal"><span class="pre">,...</span></tt><em>a</em><sub>k-1</sub><tt 2269 2270 class="docutils literal"><span class="pre">))</span></tt>.</p> 2271 <table border="1" class="docutils"> 2272 <caption>Preprocessor Array Operations</caption> <colgroup> <col 2273 2274 width="52%" /> <col width="48%" /> </colgroup> 2275 <thead valign="bottom"> 2276 <tr> 2277 <th>Expression</th> 2278 <th>Result</th> 2279 </tr> 2280 </thead> 2281 <tbody valign="top"> 2282 <tr> 2283 <td><tt class="docutils literal"><span class="pre">BOOST_PP_ARRAY_DATA(a)</span></tt></td> 2284 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>a</em><sub>0</sub><tt 2285 2286 class="docutils literal"><span class="pre">,</span></tt><em>a</em><sub>1</sub><tt 2287 2288 class="docutils literal"><span class="pre">,</span></tt>... 2289 <em>a</em><sub>k-1</sub><tt class="docutils literal"><span class="pre">)</span></tt></td> 2290 </tr> 2291 <tr> 2292 <td><tt class="docutils literal"><span class="pre">BOOST_PP_ARRAY_ELEM(i,a)</span></tt></td> 2293 <td><em>a</em><sub>i</sub></td> 2294 </tr> 2295 <tr> 2296 <td><tt class="docutils literal"><span class="pre">BOOST_PP_ARRAY_INSERT(a,</span> 2297 <span class="pre">i,</span> <span class="pre">tokens)</span></tt></td> 2298 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>k+1</em><tt 2299 2300 class="docutils literal"><span class="pre">,(</span></tt><em>a</em><sub>0</sub><tt 2301 2302 class="docutils literal"><span class="pre">,</span></tt><em>a</em><sub>1</sub><tt 2303 2304 class="docutils literal"><span class="pre">,</span></tt>...<em>a</em><sub>i-1</sub><tt 2305 2306 class="docutils literal"><span class="pre">,</span> <span 2307 2308 class="pre">tokens,</span></tt> <em>a</em><sub>i</sub><tt 2309 2310 class="docutils literal"><span class="pre">,</span></tt><em>a</em><sub>i+1</sub><tt 2311 2312 class="docutils literal"><span class="pre">,</span></tt>... 2313 <em>a</em><sub>k-1</sub><tt class="docutils literal"><span class="pre">))</span></tt></td> 2314 </tr> 2315 <tr> 2316 <td><tt class="docutils literal"><span class="pre">BOOST_PP_ARRAY_POP_BACK(a)</span></tt></td> 2317 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>k-1</em><tt 2318 2319 class="docutils literal"><span class="pre">,(</span></tt><em>a</em><sub>0</sub><tt 2320 2321 class="docutils literal"><span class="pre">,</span></tt><em>a</em><sub>1</sub><tt 2322 2323 class="docutils literal"><span class="pre">,</span></tt>... 2324 <em>a</em><sub>k-2</sub><tt class="docutils literal"><span class="pre">))</span></tt></td> 2325 </tr> 2326 <tr> 2327 <td><tt class="docutils literal"><span class="pre">BOOST_PP_ARRAY_POP_FRONT(a)</span></tt></td> 2328 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>k-1</em><tt 2329 2330 class="docutils literal"><span class="pre">,(</span></tt><em>a</em><sub>1</sub><tt 2331 2332 class="docutils literal"><span class="pre">,</span></tt><em>a</em><sub>2</sub><tt 2333 2334 class="docutils literal"><span class="pre">,</span></tt>... 2335 <em>a</em><sub>k-1</sub><tt class="docutils literal"><span class="pre">))</span></tt></td> 2336 </tr> 2337 <tr> 2338 <td><tt class="docutils literal"><span class="pre">BOOST_PP_ARRAY_PUSH_BACK(a,</span> 2339 <span class="pre">tokens)</span></tt></td> 2340 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>k+1</em><tt 2341 2342 class="docutils literal"><span class="pre">,(</span></tt><em>a</em><sub>0</sub><tt 2343 2344 class="docutils literal"><span class="pre">,</span></tt><em>a</em><sub>1</sub><tt 2345 2346 class="docutils literal"><span class="pre">,</span></tt>... 2347 <em>a</em><sub>k-1</sub><tt class="docutils literal"><span class="pre">,</span> 2348 <span class="pre">tokens))</span></tt></td> 2349 </tr> 2350 <tr> 2351 <td><tt class="docutils literal"><span class="pre">BOOST_PP_ARRAY_PUSH_FRONT(a,</span> 2352 <span class="pre">tokens)</span></tt></td> 2353 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>k+1</em><tt 2354 2355 class="docutils literal"><span class="pre">,(tokens,</span></tt> 2356 <em>a</em><sub>1</sub><tt class="docutils literal"><span class="pre">,</span></tt><em>a</em><sub>2</sub><tt 2357 2358 class="docutils literal"><span class="pre">,</span></tt>... 2359 <em>a</em><sub>k-1</sub><tt class="docutils literal"><span class="pre">))</span></tt></td> 2360 </tr> 2361 <tr> 2362 <td><tt class="docutils literal"><span class="pre">BOOST_PP_ARRAY_REMOVE(a,</span> 2363 <span class="pre">i)</span></tt></td> 2364 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>k-1</em><tt 2365 2366 class="docutils literal"><span class="pre">,(</span></tt><em>a</em><sub>0</sub><tt 2367 2368 class="docutils literal"><span class="pre">,</span></tt><em>a</em><sub>1</sub><tt 2369 2370 class="docutils literal"><span class="pre">,</span></tt>... 2371 <em>a</em><sub>i-1</sub><tt class="docutils literal"><span class="pre">,</span></tt><em>a</em><sub>i+1</sub><tt 2372 2373 class="docutils literal"><span class="pre">,</span></tt>... 2374 <em>a</em><sub>k-1</sub><tt class="docutils literal"><span class="pre">))</span></tt></td> 2375 </tr> 2376 <tr> 2377 <td><tt class="docutils literal"><span class="pre">BOOST_PP_ARRAY_REPLACE(a,</span> 2378 <span class="pre">i,</span> <span class="pre">tokens)</span></tt></td> 2379 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>k</em><tt 2380 2381 class="docutils literal"><span class="pre">,(</span></tt><em>a</em><sub>0</sub><tt 2382 2383 class="docutils literal"><span class="pre">,</span></tt><em>a</em><sub>1</sub><tt 2384 2385 class="docutils literal"><span class="pre">,</span></tt>... 2386 <em>a</em><sub>i-1</sub><tt class="docutils literal"><span class="pre">,</span> 2387 <span class="pre">tokens,</span></tt> <em>a</em><sub>i+1</sub><tt 2388 2389 class="docutils literal"><span class="pre">,</span></tt>... 2390 <em>a</em><sub>k-1</sub><tt class="docutils literal"><span class="pre">))</span></tt></td> 2391 </tr> 2392 <tr> 2393 <td><tt class="docutils literal"><span class="pre">BOOST_PP_ARRAY_REVERSE(a)</span></tt></td> 2394 <td><tt class="docutils literal"><span class="pre">(</span></tt><em>k</em><tt 2395 2396 class="docutils literal"><span class="pre">,(</span></tt><em>a</em><sub>k-1</sub><tt 2397 2398 class="docutils literal"><span class="pre">,</span></tt><em>a</em><sub>k-2</sub><tt 2399 2400 class="docutils literal"><span class="pre">,</span></tt>... 2401 <em>a</em><sub>1</sub><tt class="docutils literal"><span class="pre">,</span></tt><em>a</em><sub>0</sub><tt 2402 2403 class="docutils literal"><span class="pre">))</span></tt></td> 2404 </tr> 2405 <tr> 2406 <td><tt class="docutils literal"><span class="pre">BOOST_PP_ARRAY_SIZE(a)</span></tt></td> 2407 <td><em>k</em></td> 2408 </tr> 2409 </tbody> 2410 </table> 2411 </div> 2412 <div class="section" id="lists"> 2413 <h3><a name="lists">A.4.5.4 Lists</a></h3> 2414 <p>A <strong>list</strong> is a two-element tuple whose first 2415 element is the first element of the list, and whose second element 2416 is a list of the remaining elements, or <tt class="docutils literal"><span 2417 2418 class="pre">BOOST_PP_NIL</span></tt> if there are no remaining 2419 elements. Lists have access characteristics similar to those of a 2420 runtime linked list. Here is a three-element list:</p> 2421 <pre class="literal-block">#define LIST3 (<strong>f(12)</strong>, (<strong>a + 1</strong>, (<strong>foo</strong>, BOOST_PP_NIL))) 2422</pre> 2423 <!-- @ignore() --> 2424 <p>The facilities for manipulating lists are all in the library's <tt 2425 2426 class="docutils literal"><span class="pre">list/</span></tt> 2427 subdirectory. Because the operations are a subset of those 2428 provided for sequences, we're not going to summarize them here—it 2429 should be easy to understand the list operations by reading the 2430 documentation on the basis of our coverage of sequences.</p> 2431 <p>Like sequences, lists have no fixed upper length bound. Unlike 2432 sequences, lists can also be empty. It's rare to need more than 25 2433 elements in a preprocessor data structure, and lists tend to be 2434 slower to manipulate and harder to read than any of the other 2435 structures, so they should normally be used only as a last resort.</p> 2436 </div> 2437 </div> 2438 </div> 2439 <div class="section" id="exercise"> 2440 <h1><a name="exercise">A.5 Exercise</a></h1> 2441 <dl class="docutils"> 2442 <dt>A-0</dt> 2443 <dd>Fully preprocessor-ize the <tt class="docutils literal"><span class="pre">tiny</span></tt> 2444 type sequence implemented in Chapter 5 so that all boilerplate code 2445 is eliminated and the maximum size of a <tt class="docutils literal"><span 2446 2447 class="pre">tiny</span></tt> sequence can be adjusted by 2448 changing <tt class="docutils literal"><span class="pre">TINY_MAX_SIZE</span></tt>.</dd> 2449 </dl> 2450 <!-- on hold: 2451It isn't uncommon to need token-wise arithmetic operations forpurposes other than invoking Preprocessor Library repetitionmacros. For example, let's write a metafunction to generate 2452function types from "signature" type sequences that specify thefunction's return and parameter types:: template <unsigned Size, class Signature> 2453 struct to_function_impl; template <class Signature> struct to_function 2454 : to_function_impl<mpl::size<Signature>::type, Signature> {};The challenge now is to implement ``to_function_impl``. For 2455``Size == 3``, an appropriate specialization might look like this:: template <class Signature> struct to_function_impl<3,Signature> 2456 { typedef mpl::begin<Signature>::type i0; typedef mpl::deref<i0>::type t0; 2457 typedef mpl::next<i0>::type i1; typedef mpl::deref<i1>::type t1; typedef mpl::next<i1>::type i2; 2458 typedef mpl::deref<i2>::type t2; typedef t0 type(t1,t2); }; 2459A local macro to generate a single ``to_function_impl``specialization would look something like this: 2460.. parsed-literal:: #define to_function_impl_spec(size) \\ template <class Signature> \\ 2461 struct to_function_impl<3,Signature> \\ { \\ typedef mpl::begin<Signature>::type i0; \\ typedef mpl::deref<i0>::type t0; \\ 2462 \\ BOOST_PP_REPEAT_FROM_TO(1, size, to_function_t, ~) \\ \\ typedef t0 type(BOOST_PP_ENUM_SHIFTED_PARAMS(size,t)); \\ 2463 }; #define to_function_t(z, n, unused) \\ typedef mpl::next<BOOST_PP_CAT(i,\ **BOOST_PP_DEC(n)**)>::type \\ 2464 BOOST_PP_CAT(i,n); \\ \\ typedef mpl::deref<BOOST_PP_CAT(i,n)>::type BOOST_PP_CAT(t,n); 2465We've used some new library macros above; here is a brief rundown:* ``BOOST_PP_REPEAT_FROM_TO`` is just like ``BOOST_PP_REPEAT``, except that it accepts an initial repetition index. Since every 2466 function has a return type, we don't need to worry about the case where ``Size == 0``.* ``BOOST_PP_ENUM_SHIFTED_PARAMS`` is just like 2467 ``BOOST_PP_ENUM_PARAMS``, except that repetition indices start at ``1`` instead of ``0``.* ``BOOST_PP_CAT`` implements token pasting; its two arguments are 2468 "glued" together into a single token. Since this is a general-purpose macro, it sits in ``cat.hpp`` at the top level of the library's directory tree. [#paste]_ 2469.. [#paste] The preprocessor's built-in token-pasting operator, ``##``, often yields surprising results by taking effect before its arguments have been expanded. By contrast, ``BOOST_PP_CAT`` delays concatenation until after its arguments have been fully 2470 evaluated.* Finally, though it only performs trivial arithmetic, ``BOOST_PP_DEC`` plays a crucial role in generating an 2471 appropriate prior iterator identifier for our own code in ``to_function_t``.If we didn't have ``BOOST_PP_REPEAT_FROM_TO`` at our disposal in 2472the previous example, we might've had to use ``BOOST_PP_REPEAT``,which always starts iterating at ``0``. Consequently``to_function_t`` would've been responsible for producing thedeclarations of ``i0`` and ``t0`` as well as those of the other 2473nested types. To manage that, it would need a way to selectdifferent expansions depending on the value of ``n``.In its ``control/`` directory, the Preprocessor Library supplies a 2474macro ``BOOST_PP_IF(c,t,f)`` that fulfills a similar role to theone filled by ``mpl::if_``. Rewriting the example accordingly, weget: 2475.. parsed-literal:: #define to_function_impl_spec(size) \\ template <class Signature> \\ 2476 struct to_function_impl<3,Signature> \\ { \\ BOOST_PP_REPEAT_FROM_TO(1, size, to_function_t, ~) \\ \\ 2477 typedef t0 type(BOOST_PP_ENUM_SHIFTED_PARAMS(size,t)); \\ }; #define to_function_t(z, n, unused) \\ 2478 typedef BOOST_PP_IF( \\ n, \\ mpl::next<BOOST_PP_CAT(i,BOOST_PP_DEC(n))>::type, \\ typedef mpl::begin<Signature>::type i0; \\ 2479 ) \\ BOOST_PP_CAT(i,n); \\ \\ typedef mpl::deref<BOOST_PP_CAT(i,n)>::type BOOST_PP_CAT(t,n); 2480Although the formulation above will work, it does unnecessary workwhen ``n == 0``, evaluating the "true" branch of the conditionalonly to discard it. --> 2481 </div> 2482 </div> 2483 <hr class="docutils footer" /> 2484 <div class="footer"> Generated on: 2005-10-17 19:34 UTC. Generated by <a class="reference" 2485 2486 href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" 2487 2488 href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> 2489 source. </div> 2490 </body> 2491</html> 2492<!-- 2493 FILE ARCHIVED ON 19:59:10 Mar 30, 2013 AND RETRIEVED FROM THE INTERNET ARCHIVE ON 21:06:19 May 19, 2015. JAVASCRIPT APPENDED BY WAYBACK MACHINE, COPYRIGHT INTERNET ARCHIVE. 2494 ALL OTHER CONTENT MAY ALSO BE PROTECTED BY COPYRIGHT (17 U.S.C. SECTION 108(a)(3)).--> 2495