1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 2 3<html> 4<head> 5 <meta http-equiv="Content-Language" content="en-us"> 6 <meta http-equiv="Content-Type" content="text/html; charset=us-ascii"> 7 8 <title>The Boost Format library</title> 9</head> 10 11<body bgcolor="white" text="black"> 12 <h1><img align="middle" alt="boost.png (6897 bytes)" height="86" src= 13 "../../../boost.png" width="277">The Boost Format library</h1> 14 15 <p>The <code><a href= 16 "../../../boost/format.hpp"><boost/format.hpp></a></code> format 17 class provides printf-like formatting, in a type-safe manner which allows 18 output of user-defined types.<br></p> 19 20 <ul> 21 <li><a href="#synopsis">Synopsis</a></li> 22 23 <li><a href="#how_it_works">How it works</a></li> 24 25 <li><a href="#examples">Examples</a></li> 26 27 <li> 28 <a href="#syntax">Syntax</a> 29 30 <ul> 31 <li><a href="#printf_directives">printf format-specification 32 syntax</a></li> 33 34 <li><a href="#printf_differences">Incompatibilities with 35 printf</a></li> 36 </ul> 37 </li> 38 39 <li><a href="#manipulators">Manipulators and the internal stream 40 state</a></li> 41 42 <li><a href="#user-defined">User-defined types</a></li> 43 44 <li><a href="#alternatives">Alternatives</a></li> 45 46 <li><a href="#exceptions">Exceptions</a></li> 47 48 <li><a href="#performance">Performance</a></li> 49 50 <li><a href="#extract">Class Interface Extract</a></li> 51 52 <li><a href="#rationale">Rationale</a></li> 53 </ul><a name="synopsis" id="synopsis"></a> 54 <hr> 55 56 <h2>Synopsis</h2> 57 58 <p>A format object is constructed from a format-string, and is then given 59 arguments through repeated calls to <i>operator%</i>.<br> 60 Each of those arguments are then converted to strings, who are in turn 61 combined into one string, according to the format-string.</p> 62 63 <blockquote> 64 <pre> 65cout << boost::format("writing %1%, x=%2% : %3%-th try") % "toto" % 40.23 % 50; 66 // prints "writing toto, x=40.230 : 50-th try" 67</pre> 68 </blockquote><a name="how_it_works" id="how_it_works"></a> 69 <hr> 70 71 <h2>How it works</h2> 72 73 <ol> 74 <li>When you call <i>format(s)</i>, where s is the format-string, it 75 constructs an object, which parses the format string and look for all 76 directives in it and prepares internal structures for the next step.</li> 77 78 <li>Then, either immediately, as in 79 80 <blockquote> 81 <pre> 82cout << format("%2% %1%") % 36 % 77; 83</pre> 84 </blockquote>or later on, as in 85 86 <blockquote> 87 <pre> 88format fmter("%2% %1%"); 89fmter % 36; fmter % 77; 90</pre> 91 </blockquote>you <i>feed</i> variables into the formatter.<br> 92 those variables are dumped into an internal stream, which state is set 93 according to the given formatting options in the format-string -if 94 there are any-, and the format object stores the string results for the 95 last step. 96 </li> 97 98 <li>Once all arguments have been fed you can dump the format object to a 99 stream, or get its string value by using the <i>str()</i> member 100 function, or the free function <i>str(const format& )</i> in 101 namespace <i>boost</i>. The result string stays accessible in the format 102 object until another argument is passed, at which time it is 103 reinitialised. 104 105 <blockquote> 106 <pre> 107 108// fmter was previously created and fed arguments, it can print the result : 109cout << fmter ; 110 111// You can take the string result : 112string s = fmter.str(); 113 114// possibly several times : 115s = fmter.str( ); 116 117// You can also do all steps at once : 118cout << boost::format("%2% %1%") % 36 % 77; 119 120// using the str free function : 121string s2 = str( format("%2% %1%") % 36 % 77 ); 122 123</pre> 124 </blockquote> 125 </li> 126 127 <li>Optionnally, after step 3, you can re-use a format object and restart 128 at step2 : <i>fmter % 18 % 39;</i><br> 129 to format new variables with the same format-string, saving the expensive 130 processing involved at step 1.</li> 131 </ol>All in all, the format class translates a format-string (with 132 eventually printf-like directives) into operations on an internal stream, 133 and finally returns the result of the formatting, as a string, or directly 134 into an output stream. <a name="examples" id="examples"></a> 135 <hr> 136 137 <h2>Examples</h2> 138 139 <blockquote> 140 <pre> 141using namespace std; 142using boost::format; 143using boost::io::group; 144</pre> 145 </blockquote> 146 147 <ul> 148 <li>Simple output, with reordering : 149 150 <blockquote> 151 <pre> 152 153cout << format("%1% %2% %3% %2% %1% \n") % "11" % "22" % "333"; // 'simple' style. 154 155</pre> 156 </blockquote>It prints : "11 22 333 22 11 \n" 157 </li> 158 159 <li>More precise formatting, with Posix-printf positional directives : 160 161 <blockquote> 162 <pre> 163 164cout << format("(x,y) = (%1$+5d,%2$+5d) \n") % -23 % 35; // Posix-Printf style 165 166</pre> 167 </blockquote>It prints : "(x,y) = ( -23, +35) \n" 168 </li> 169 170 <li>classical printf directive, no reordering : 171 172 <blockquote> 173 <pre> 174 175cout << format("writing %s, x=%s : %d-th step \n") % "toto" % 40.23 % 50; 176 177</pre> 178 </blockquote>It prints : "writing toto, x=40.23 : 50-th step \n" 179 </li> 180 181 <li>Several ways to express the same thing : 182 183 <blockquote> 184 <pre> 185 186cout << format("(x,y) = (%+5d,%+5d) \n") % -23 % 35; 187cout << format("(x,y) = (%|+5|,%|+5|) \n") % -23 % 35; 188 189cout << format("(x,y) = (%1$+5d,%2$+5d) \n") % -23 % 35; 190cout << format("(x,y) = (%|1$+5|,%|2$+5|) \n") % -23 % 35; 191 192</pre> 193 </blockquote>all those print : "(x,y) = ( -23, +35) \n" 194 </li> 195 196 <li>Using manipulators to modify the format-string : 197 198 <blockquote> 199 <pre> 200 201format fmter("_%1$+5d_ %1$d \n"); 202 203format fmter2("_%1%_ %1% \n"); 204fmter2.modify_item(1, group(showpos, setw(5)) ); 205 206cout << fmter % 101 ; 207cout << fmter2 % 101 ; 208 209</pre> 210 </blockquote>Both print the same : "_ +101_ 101 \n" 211 </li> 212 213 <li>Using manipulators with arguments : 214 215 <blockquote> 216 <pre> 217 218cout << format("_%1%_ %1% \n") % group(showpos, setw(5), 101); 219 220</pre> 221 </blockquote>The manipulators are applied at each occurrence of %1%, and 222 thus it prints : "_ +101_ +101 \n" 223 </li> 224 225 <li>New formatting feature : 'absolute tabulations', useful inside loops, 226 to insure a field is printed at the same position from one line to the 227 next, even if the widthes of the previous arguments can vary a lot. 228 229 <blockquote> 230 <pre> 231 232for(unsigned int i=0; i < names.size(); ++i) 233 cout << format("%1%, %2%, %|40t|%3%\n") % names[i] % surname[i] % tel[i]; 234 235</pre> 236 </blockquote>For some std::vector <i>names</i>, <i>surnames</i>, and 237 <i>tel</i> (see sample_new_features.cpp) it prints : 238 239 <blockquote> 240 <pre> 241Marc-François Michel, Durand, +33 (0) 123 456 789 242Jean, de Lattre de Tassigny, +33 (0) 987 654 321 243</pre> 244 </blockquote> 245 </li> 246 </ul> 247 <hr> 248 249 <h2>Sample Files</h2> 250 251 <p>The program <a href= 252 "../example/sample_formats.cpp">sample_formats.cpp</a> demonstrates simple 253 uses of <b>format</b>.<br></p> 254 255 <p><a href="../example/sample_new_features.cpp">sample_new_features.cpp</a> 256 illustrates the few formatting features that were added to printf's syntax 257 such as simple positional directives, centered alignment, and 258 'tabulations'.<br></p> 259 260 <p><a href="../example/sample_advanced.cpp">sample_advanced.cpp</a> 261 demonstrates uses of advanced features, like reusing, and modifying, format 262 objects, etc..<br></p> 263 264 <p>And <a href="../example/sample_userType.cpp">sample_userType.cpp</a> 265 shows the behaviour of the <b>format</b> library on user-defined 266 types.</p><a name="syntax" id="syntax"></a> 267 <hr> 268 269 <h2>Syntax</h2> 270 271 <p><b>boost::format(</b> format-string <b>) %</b> arg1 <b>%</b> arg2 272 <b>%</b> ... <b>%</b> argN</p> 273 274 <p>The <i>format-string</i> contains text in which special directives will 275 be replaced by strings resulting from the formatting of the given 276 arguments.<br> 277 The legacy syntax in the C and C++ worlds is the one used by printf, and 278 thus format can use directly printf format-strings, and produce the same 279 result (in almost all cases. see <a href= 280 "#printf_differences">Incompatibilities with printf</a> for details)<br> 281 This core syntax was extended, to allow new features, but also to adapt to 282 the C++ streams context. Thus, format accepts several forms of directives 283 in format-strings :</p> 284 285 <ul> 286 <li>Legacy printf format strings : <b>%</b><i>spec</i> where <i>spec</i> 287 is a <a href="#printf_directives">printf format specification</a><br> 288 <i>spec</i> passes formatting options, like width, alignment, numerical 289 base used for formatting numbers, as well as other specific flags. But 290 the classical <i>type-specification</i> flag of printf has a weaker 291 meaning in format. It merely sets the appropriate flags on the internal 292 stream, and/or formatting parameters, but does not require the 293 corresponding argument to be of a specific type.<br> 294 e.g. : the specification <i>2$x</i>, meaning "print argument number 2, 295 which is an integral number, in hexa" for printf, merely means "print 296 argument 2 with stream basefield flags set to <i>hex</i>" for 297 format.</li> 298 299 <li><b>%|</b><i>spec</i><b>|</b> where <i>spec</i> is a printf format 300 specification.<br> 301 This pipe-delimited syntax is introduced, to improve the readability of the 302 format-string, but primarily, to make the <i>type-conversion 303 character</i> optional in <i>spec</i>. This information is not necessary 304 with C++ variables, but with direct printf syntax, it is necessary to 305 always give a type-conversion character, merely because this character is 306 crucial to determine the end of a format-specification.<br> 307 e.g. : "%|-5|" will format the next variable with width set to 5, and 308 left-alignment just like the following printf directives : "%-5g", 309 "%-5f", "%-5s" ..</li> 310 311 <li><b>%</b><i>N</i><b>%</b><br> 312 This simple positional notation requests the formatting of the 313 <i>N</i>-th argument - wihout any formatting option.<br> 314 (It's merely a shortcut to Printf's positional directives (like 315 "%<i>N</i>$s"), but a major benefit is that it's much more readable, and 316 does not use a "type-conversion" character)</li> 317 </ul>On top of the standard printf format specifications, new features were 318 implemented, like centered alignment. See <a href="#new_directives">new 319 format specification</a> for details. <a name="printf_directives" id= 320 "printf_directives"></a> 321 322 <h3>printf format specifications</h3> 323 324 <p>The printf format specifications supported by Boost.format follows the 325 Unix98 <a href= 326 "http://www.opengroup.org/onlinepubs/7908799/xsh/fprintf.html">Open-group 327 printf</a> precise syntax, rather than the standard C printf, which does 328 not support positional arguments. (Common flags have the same meaning in 329 both, so it should not be a headache for anybody)<br> 330 <i>Note that it is an error to use positional format specifications</i> 331 (e.g. <i>%3$+d</i>) <i>mixed with non-positional ones</i> (e.g. <i>%+d</i>) 332 <i>in the same format string.</i><br> 333 In the Open-group specification, referring to the same argument several 334 times (e.g. <i>"%1$d %1$d"</i>) has undefined behaviour. Boost.format's 335 behaviour in such cases is to allow each argument to be reffered to any 336 number of times. The only constraint is that it expects exactly <i>P</i> 337 arguments, <i>P</i> being the maximum argument number used in the format 338 string. (e.g., for "%1$d %10$d", <i>P</i> == 10 ).<br> 339 Supplying more, or less, than <i>P</i> arguments raises an exception. 340 (unless it was set otherwise, see <a href="#exceptions">exceptions</a>)</p> 341 342 <p>A specification <i>spec</i> has the form: 343 <pre> [ <i>N</i><b>$</b> ] [ <i>flags</i> ] [ <i>width</i> ] [ <b>.</b> <i>precision</i> ] [ <i>argument-type</i> ] <i>conversion-specifier</i></pre> 344 345 Fields inside square brackets are optional. Each of those fields are 346 explained one by one in the following list:</p> 347 348 <ul> 349 <li><i>N</i> <b>$</b> (optional field) specifies that the format 350 specification applies to the <i>N</i>-th argument (it is called a 351 <i>positional format specification</i>).<br> 352 If this is not present, arguments are taken one by one. (and it is then 353 an error to later supply an argument number)</li><br /> 354 355 <li> 356 <i>flags</i> is a sequence of any of these: 357 358 <blockquote> 359 <table border="1" cellpadding="5" summary=""> 360 <tr> 361 <td><b>Flag</b></td> 362 363 <td><b>Meaning</b></td> 364 365 <td><b>effect on internal stream</b></td> 366 </tr> 367 368 <tr> 369 <td><b>'-'</b></td> 370 371 <td>left alignment</td> 372 373 <td>N/A (applied later on the string)</td> 374 </tr> 375 376 <tr> 377 <td><b>'='</b></td> 378 379 <td>centered alignment</td> 380 381 <td>N/A (applied later on the string)<br> 382 <i>- note : added feature, not in printf -</i></td> 383 </tr> 384 385 <tr> 386 <td><b>'_'</b></td> 387 388 <td>internal alignment</td> 389 390 <td>sets internal alignment<br> 391 <i>- note : added feature, not in printf -</i></td> 392 </tr> 393 394 <tr> 395 <td><b>'+'</b></td> 396 397 <td>show sign even for positive numbers</td> 398 399 <td>sets <i>showpos</i></td> 400 </tr> 401 402 <tr> 403 <td><b>'#'</b></td> 404 405 <td>show numerical base, and decimal point</td> 406 407 <td>sets <i>showbase</i> and <i>showpoint</i></td> 408 </tr> 409 410 <tr> 411 <td><b>'0'</b></td> 412 413 <td>pad with 0's (inserted after sign or base indicator)</td> 414 415 <td>if not left-aligned, calls <i>setfill('0')</i> and sets 416 <i>internal</i><br> 417 Extra actions are taken after stream conversion to handle 418 <a href="#user-defined">user-defined output</a>.</td> 419 </tr> 420 421 <tr> 422 <td><b>' '</b></td> 423 424 <td>if the string does not begin with <i>+</i> or <i>-</i>, 425 insert a <i>space</i> before the converted string</td> 426 427 <td>N/A (applied later on the string)<br> 428 Different to printf's behaviour : it is not affected by internal 429 alignment</td> 430 </tr> 431 </table> 432 </blockquote><br /> 433 </li> 434 435 <li><i>width</i> specifies a minimal width for the string resulting form 436 the conversion. If necessary, the string will be padded with alignment 437 and fill characters either set on the stream via manipulators, or 438 specified by the format-string (e.g. flags '0', '-', ..)<br> 439 Note that width is not just set on the conversion stream. To support 440 output of <a href="#user-defined">user-defined types</a> (that might call 441 <i>operator<<</i> many times on several members), the width is 442 handled after stream conversion of the whole argument object, in the 443 format class code.</li><br /> 444 445 <li> 446 <i>precision</i> (preceded by a point), sets the stream's 447 <i>precision</i> 448 449 <ul> 450 <li>When outputting a floatting type number, it sets the maximum 451 number of digits 452 453 <ul> 454 <li>after decimal point when in fixed or scientific mode</li> 455 456 <li>in total when in default mode ('<i>general mode</i>', like 457 <i>%g</i>)</li> 458 </ul> 459 </li> 460 461 <li>When used with type-char <b>s</b> or <b>S</b> it takes another 462 meaning : the conversion string is truncated to the <i>precision</i> 463 first chars. (Note that the eventual padding to <i>width</i> is done 464 after truncation.)</li> 465 </ul><br /> 466 </li> 467 468 <li> 469 <i>argument-type</i> is used by the printf family to properly process 470 the arguments being passed in through varargs. With <code>boost::format</code> 471 the arguments are fed into format through <code>operator %</code> which 472 allows the template to carry the argument type. Therefore the classical 473 printf style argument type is consumed and ignored. 474 Argument-types <code>hh</code>, <code>h</code>, <code>l</code>, <code>ll</code>, <code>j</code>, 475 <code>z</code>, and <code>L</code> are recognized, as are the Microsoft extensions <code>w</code>, 476 <code>I</code> (capital i), <code>I32</code>, and <code>I64</code>. Argument-type <code>t</code> 477 from the ISO C99 standard is not recognized as an argument type, as it has been in use as a 478 conversion specifier for tabular output for many years in <code>boost::format</code>. 479 </li><br /> 480 481 <li> 482 <i>conversion-specifier</i> does <b>not</b> impose the concerned argument 483 to be of a restricted set of types, but merely sets the ios flags that are 484 associated with a type specification: 485 486 <blockquote> 487 <table border="1" cellpadding="5" summary=""> 488 <tr> 489 <td><b>conversion-specifier</b></td> 490 491 <td><b>Meaning</b></td> 492 493 <td><b>effect on stream</b></td> 494 </tr> 495 496 <tr> 497 <td><b>b</b></td> 498 499 <td>boolean string output</td> 500 501 <td>sets <i>boolalpha</i>; only works for type <code>bool</code><br /> 502 To customize the resulting string, see 503 <a href="http://en.cppreference.com/w/cpp/locale/numpunct/truefalsename">std::numpunct</a>. 504 </tr> 505 506 <tr> 507 <td><b>p or x</b></td> 508 509 <td>hexadecimal output</td> 510 511 <td>sets <i>hex</i></td> 512 </tr> 513 514 <tr> 515 <td><b>o</b></td> 516 517 <td>octal output</td> 518 519 <td>sets <i>oct</i></td> 520 </tr> 521 522 <tr> 523 <td><b>a</b></td> 524 525 <td>hexadecimal exponent notation</td> 526 527 <td>sets floatfield bits to <i>scientific</i> | <i>fixed</i> (which is equivalent to <i>hexfloat</i>)</td> 528 </tr> 529 530 <tr> 531 <td><b>e</b></td> 532 533 <td>scientific float format</td> 534 535 <td>sets floatfield bits to <i>scientific</i></td> 536 </tr> 537 538 <tr> 539 <td><b>f</b></td> 540 541 <td>fixed float format</td> 542 543 <td>sets floatfield bits to <i>fixed</i></td> 544 </tr> 545 546 <tr> 547 <td><b>g</b></td> 548 549 <td>general -default- float format</td> 550 551 <td><b>unset</b> all floatfield bits</td> 552 </tr> 553 554 <tr> 555 <td><b>X, A, E, F</b> or <b>G</b></td> 556 557 <td>same effect as their lowercase counterparts, but using 558 uppercase letters for number outputs. (exponents, hex digits, 559 ..)</td> 560 561 <td>same effects as <i>'x'</i>, <i>'a'</i>, <i>'e'</i>, <i>'f'</i>, or <i>'g'</i> respectively, 562 <b>plus</b> <i>uppercase</i></td> 563 </tr> 564 565 <tr> 566 <td><b>d, i</b> or <b>u</b></td> 567 568 <td><b>decimal</b> type output</td> 569 570 <td>sets basefield bits to <i>dec</i></td> 571 </tr> 572 573 <tr> 574 <td><b>s</b> or <b>S</b></td> 575 576 <td>string output</td> 577 578 <td><i>precision</i> specification is unset, and its value goes 579 to an internal field for later 'truncation'. (see 580 <i>precision</i> explanation above)</td> 581 </tr> 582 583 <tr> 584 <td><b>c</b> or <b>C</b></td> 585 586 <td>1-character output</td> 587 588 <td>only the first character of the conversion string is 589 used.</td> 590 </tr> 591 592 <tr> 593 <td><b>%</b></td> 594 595 <td>print the character <i>%</i></td> 596 597 <td>N/A</td> 598 </tr> 599 </table> 600 </blockquote> 601 602 <p>Note that the 'n' conversion-specifier is ignored (and so is the 603 corresponding argument), because it does not fit in this context.</p> 604 </li> 605 </ul><a name="new_directives" id="new_directives"></a> 606 607 <h3>new format-specifications</h3> 608 609 <ul> 610 <li>as stated in the flags table, centered and internal alignment flags 611 (' <i>=</i> ', and ' <i>_</i> ') were added.</li> 612 613 <li><i><b>%{</b>n</i><b>t}</b> , where <i>n</i> is a positive number, 614 inserts an <i>absolute tabulation</i>. It means that format will, if 615 needed, fill the string with characters, until the length of the string 616 created so far reaches <i>n</i> characters. (see <a href= 617 "#examples">examples</a> )</li> 618 619 <li><b>%|</b><i>n</i><b>T</b><i>X</i><b>|</b> inserts a tabulation in the 620 same way, but using <i>X</i> as fill character instead of the current 621 'fill' char of the stream (which is <i>space</i> for a stream in default 622 state)</li> 623 </ul><a name="printf_differences" id="printf_differences"></a> 624 625 <h2>Differences of behaviour vs printf</h2>Suppose you have variables 626 <i>x1, x2</i> (built_in types, supported by C's printf),<br> 627 and a format string <i>s</i> intended for use with a printf function this 628 way : 629 630 <blockquote> 631 <pre> 632printf(s, x1, x2); 633</pre> 634 </blockquote><br> 635 In almost all cases, the result will be the same as with this command : 636 637 <blockquote> 638 <pre> 639cout << format(s) % x1 % x2; 640</pre> 641 </blockquote> 642 643 <p>But because some printf format specifications don't translate well into 644 stream formatting options, there are a few notable imperfections in the way 645 Boost.format emulates printf.<br> 646 In any case, the <i>format</i> class should quietly ignore the unsupported 647 options, so that printf format-strings are always accepted by format and 648 produce almost the same output as printf.</p><br> 649 Here is the full list of such differences : 650 651 <ul> 652 <li><b>'0'</b> and <b>' '</b> options : printf ignores these options for 653 non numeric conversions, but format applies them to all types of 654 variables. (so it is possible to use those options on user-defined types, 655 e.g. a Rational class, etc..)</li> 656 657 <li><b>precision</b> for integral types arguments has a special meaning 658 for printf :<br> 659 <i>printf( "(%5.3d)" , 7 ) ;</i> prints « ( 007) »<br> 660 While format, like streams, ignores the precision parameter for integral 661 types conversions.</li> 662 663 <li>the <b>'</b> printf option (<i>format with thousands grouping 664 characters)</i>) has no effect in format.</li> 665 666 <li>Width or precision set to asterisk (<i>*</i>) are used by printf to 667 read this field from an argument. e.g. 668 <i>printf("%1$d:%2$.*3$d:%4$.*3$d\n", hour, min, precision, sec);</i><br> 669 This class does not support this mechanism for now. so such precision or 670 width fields are quietly ignored by the parsing.</li> 671 672 <li>argument-type is ignored</li> 673 </ul>Also, note that the special <b>'n'</b> type-specification (used to 674 tell printf to save in a variable the number of characters output by the 675 formatting) has no effect in format.<br> 676 Thus format strings containing this type-specification should produce the 677 same converted string by printf or format. It will not cause differences in 678 the formatted strings between printf and format.<br> 679 To get the number of characters in the formatted string using Boost.Format, 680 you can use the <i>size()</i> member function : 681 682 <blockquote> 683 <pre> 684format formatter("%+5d"); 685cout << formatter % x; 686unsigned int n = formatter.size(); 687</pre> 688 </blockquote><a name="user-defined" id="user-defined"></a> 689 <hr> 690 691 <h2>User-defined types output</h2> 692 693 <p>All flags which are translated into modification to the stream state act 694 recursively within user-defined types. ( the flags remain active, and so 695 does the desired format option, for each of the '<<' operations that 696 might be called by the user-defined class)</p>e.g., with a Rational class, 697 we would have something like : 698 699 <blockquote> 700 <pre> 701Rational ratio(16,9); 702cerr << format("%#x \n") % ratio; // -> "0x10/0x9 \n" 703</pre> 704 </blockquote> 705 706 <p>It's a different story for other formatting options. For example, 707 setting width applies to the final output produced by the object, not to 708 each of its internal outputs, and that's fortunate :</p> 709 710 <blockquote> 711 <pre> 712cerr << format("%-8d") % ratio; // -> "16/9 " and not "16 /9 " 713cerr << format("%=8d") % ratio; // -> " 16/9 " and not " 16 / 9 " 714</pre> 715 </blockquote> 716 717 <p><br> 718 But so does the 0 and ' ' options (contrarily to '+' which is directly 719 translated to the stream state by <i>showpos</i>. But no such flags exist 720 for the zero and space printf options)<br> 721 and that is less natural :</p> 722 723 <blockquote> 724 <pre> 725cerr << format("%+08d \n") % ratio; // -> "+00016/9" 726cerr << format("% 08d \n") % ratio; // -> "000 16/9" 727</pre> 728 </blockquote>It is possible to obtain a better behaviour by carefully 729 designing the Rational's <i>operator<<</i> to handle the stream's 730 width, alignment and <i>showpos</i> paramaters by itself. This is 731 demonstrated in <a href= 732 "../example/sample_userType.cpp">sample_userType.cpp</a>. <a name= 733 "manipulators" id="manipulators"></a> 734 <hr> 735 736 <h3>Manipulators, and internal stream state</h3> 737 738 <p>The internal stream state of <b>format</b> is saved before and restored 739 after output of an argument; therefore, the modifiers are not sticky and 740 affect only the argument they are applied to.<br> 741 The default state for streams, as stated by the standard, is : precision 6, 742 width 0, right alignment, and decimal flag set.</p> 743 744 <p>The state of the internal <b>format</b> stream can be changed by 745 manipulators passed along with the argument; via the <i>group</i> function, 746 like that :</p> 747 748 <blockquote> 749 <pre> 750cout << format("%1% %2% %1%\n") % group(hex, showbase, 40) % 50; // prints "0x28 50 0x28\n" 751</pre> 752 </blockquote> 753 754 <p><br> 755 When passing N items inside a 'group' Boost.format needs to process 756 manipulators diferently from regular argument, and thus using group is 757 subject to the following constraints :</p> 758 759 <ol> 760 <li>the object to be printed must be passed as the last item in the 761 group</li> 762 763 <li>the first N-1 items are treated as manipulators, and if they do 764 produce output, it is discarded</li> 765 </ol> 766 767 <p>Such manipulators are passed to the streams right before the following 768 argument, at every occurrence. Note that formatting options specified within 769 the format string are overridden by stream state modifiers passed this way. 770 For instance in the following code, the <i>hex</i> manipulator has priority 771 over the <i>d</i> type-specification in the format-string which would set 772 decimal output :</p> 773 774 <blockquote> 775 <pre> 776cout << format("%1$d %2% %1%\n") % group(hex, showbase, 40) % 50; 777// prints "0x28 50 0x28\n" 778</pre> 779 </blockquote><a name="alternatives" id="alternatives"></a> 780 781 <h2>Alternatives</h2> 782 783 <ul> 784 <li><b>printf</b> is the classical alternative, that is not type safe and 785 not extendable to user-defined types.</li> 786 787 <li>ofrstream.cc by Karl Nelson's design was a big source of inspiration 788 to this format class.</li> 789 790 <li>James Kanze's library has a format class (in 791 <i>srcode/Extended/format</i> ) which looks very well polished. Its 792 design has in common with this class the use of internal stream for the 793 actual conversions, as well as using operators to pass arguments. (but 794 his class, as ofrstream, uses <i>operator<<</i> rather <i>than 795 operator%</i> )</li> 796 797 <li><a href="http://groups.yahoo.com/group/boost/files/format3/">Karl 798 Nelson's library</a> was intented as demonstration of alternative 799 solutions in discussions on Boost's list for the design of 800 Boost.format.</li> 801 802 <li><a href="http://fmtlib.net/latest/index.html">{fmt}</a> by Victor Zverovich.</li> 803 </ul><a name="exceptions" id="exceptions"></a> 804 <hr> 805 806 <h2>Exceptions</h2> 807 808 <p>Boost.format enforces a number of rules on the usage of format objects. 809 The format-string must obeys the syntax described above, the user must 810 supply exactly the right number of arguments before outputting to the final 811 destination, and if using modify_item or bind_arg, items and arguments 812 index must not be out of range.<br> 813 When format detects that one of these rules is not satisfied, it raises a 814 corresponding exception, so that the mistakes don't go unnoticed and 815 unhandled.<br> 816 But the user can change this behaviour to fit his needs, and select which 817 types of errors may raise exceptions using the following functions :</p> 818 819 <blockquote> 820 <pre> 821 822unsigned char exceptions(unsigned char newexcept); // query and set 823unsigned char exceptions() const; // just query 824 825</pre> 826 </blockquote> 827 828 <p>The user can compute the argument <i>newexcept</i> by combining the 829 following atoms using binary arithmetic :</p> 830 831 <ul> 832 <li><b>boost::io::bad_format_string_bit</b> selects errors due to 833 ill-formed format-strings.</li> 834 835 <li><b>boost::io::too_few_args_bit</b> selects errors due to asking for 836 the srting result before all arguments are passed.</li> 837 838 <li><b>boost::io::too_many_args_bit</b> selects errors due to passing too 839 many arguments.</li> 840 841 <li><b>boost::io::out_of_range_bit</b> select errors due to out of range 842 index supplied by the user when calling <i>modify_item</i> or other 843 functions taking an item index (or an argument index)</li> 844 845 <li><b>boost::io::all_error_bits</b> selects all errors</li> 846 847 <li><b>boost::io::no_error_bits</b> selects no error.</li> 848 </ul> 849 850 <p>For instance, if you don't want Boost.format to detect bad number of 851 arguments, you can define a specific wrapper function for building format 852 objects with the right exceptions settings :</p> 853 854 <blockquote> 855 <pre> 856 857boost::format my_fmt(const std::string & f_string) { 858 using namespace boost::io; 859 format fmter(f_string); 860 fmter.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) ); 861 return fmter; 862} 863 864</pre> 865 </blockquote>It is then allowed to give more arguments than needed (they 866 are simply ignored) : 867 868 <blockquote> 869 <pre> 870 871cout << my_fmt(" %1% %2% \n") % 1 % 2 % 3 % 4 % 5; 872 873</pre> 874 </blockquote>And if we ask for the result before all arguments are 875 supplied, the corresponding part of the result is simply empty 876 877 <blockquote> 878 <pre> 879 880cout << my_fmt(" _%2%_ _%1%_ \n") % 1 ; 881// prints " __ _1_ \n" 882 883</pre> 884 </blockquote><a name="performance" id="performance"></a> 885 <hr> 886 887 <h2>A Note about performance</h2> 888 889 <p>The performance of boost::format for formatting a few builtin type 890 arguments with reordering can be compared to that of Posix-printf, and of 891 the equivalent stream manual operations to give a measure of the overhead 892 incurred. The result may greatly depend on the compiler, standard library 893 implementation, and the precise choice of format-string and arguments.</p> 894 895 <p>Common stream implementations eventually call functions of the 896 printf family for the actual formatting of numbers. In general, printf 897 will be noticeably faster than the direct stream operations due to the 898 reordering overhead (allocations to store the pieces of string, stream 899 initialisation at each item formatting, ..). The direct stream operations 900 would be faster than boost::format - one can expect a ratio ranging from 2 901 to 5 or more.</p> 902 903 <p>When iterated formattings are a performance bottleneck, performance can 904 be slightly increased by parsing the format string into a format object, 905 and copying it at each formatting, in the following way:</p> 906 907 <blockquote> 908 <pre> 909 const boost::format fmter(fstring); 910 dest << boost::format(fmter) % arg1 % arg2 % arg3 ; 911 </pre> 912 </blockquote> 913 914 <p>As an example of performance results, the author measured the time of 915 execution of iterated formattings with 4 different methods:</p> 916 917 <ol> 918 <li>posix printf</li> 919 920 <li>manual stream output (to a dummy <i>nullStream</i> stream sending the 921 bytes into oblivion)</li> 922 923 <li>boost::format copied from a const object as shown above</li> 924 925 <li>the straight boost::format usage</li> 926 </ol> 927 928 <p>the test was compiled with g++-3.3.3 and the following timings were 929 measured (in seconds, and ratios):</p> 930 931 <blockquote> 932 <pre> 933string fstring="%3$0#6x %1$20.10E %2$g %3$0+5d \n"; 934double arg1=45.23; 935double arg2=12.34; 936int arg3=23; 937 938- release mode : 939printf : 2.13 940nullStream : 3.43, = 1.61033 * printf 941boost::format copied : 6.77, = 3.1784 * printf , = 1.97376 * nullStream 942boost::format straight :10.67, = 5.00939 * printf , = 3.11079 * nullStream 943 944- debug mode : 945printf : 2.12 946nullStream : 3.69, = 1.74057 * printf 947boost::format copied :10.02, = 4.72642 * printf , = 2.71545 * nullStream 948boost::format straight :17.03, = 8.03302 * printf , = 4.61518 * nullStream 949</pre> 950 </blockquote><a name="extract" id="extract"></a> 951 <hr> 952 953 <h2>Class Interface Extract</h2> 954 955 <blockquote> 956 <pre> 957namespace boost { 958 959template<class charT, class Traits=std::char_traits<charT> > 960class basic_format 961{ 962public: 963 typedef std::basic_string<charT, Traits> string_type; 964 typedef typename string_type::size_type size_type; 965 basic_format(const charT* str); 966 basic_format(const charT* str, const std::locale & loc); 967 basic_format(const string_type& s); 968 basic_format(const string_type& s, const std::locale & loc); 969 basic_format& operator= (const basic_format& x); 970 971 void clear(); // reset buffers 972 basic_format& parse(const string_type&); // clears and parse a new format string 973 974 string_type str() const; 975 size_type size() const; 976 977 // pass arguments through those operators : 978 template<class T> basic_format& operator%(T& x); 979 template<class T> basic_format& operator%(const T& x); 980 981 // dump buffers to ostream : 982 friend std::basic_ostream<charT, Traits>& 983 operator<< <> ( std::basic_ostream<charT, Traits>& , basic_format& ); 984 985 // Choosing which errors will throw exceptions : 986 unsigned char exceptions() const; 987 unsigned char exceptions(unsigned char newexcept); 988 989// ............ this is just an extract ....... 990}; // basic_format 991 992typedef basic_format<char > format; 993typedef basic_format<wchar_t > wformat; 994 995 996// free function for ease of use : 997template<class charT, class Traits> 998std::basic_string<charT,Traits> str(const basic_format<charT,Traits>& f) { 999 return f.str(); 1000} 1001 1002 1003} // namespace boost 1004</pre> 1005 </blockquote> 1006 <hr> 1007 <a name="rationale" id="rationale"></a> 1008 1009 <h2>Rationale</h2> 1010 1011 <p>This class's goal is to bring a better, C++, type-safe and 1012 type-extendable <i>printf</i> equivalent to be used with 1013 streams.</p>Precisely, <b>format</b> was designed to provide the following 1014 features : 1015 1016 <ul> 1017 <li>support positional arguments (required for internationalisation)</li> 1018 1019 <li>accept an unlimited number of arguments.</li> 1020 1021 <li>make formatting commands visually natural.</li> 1022 1023 <li>support the use of manipulators to modify the display of an argument. 1024 in addition to the format-string syntax.</li> 1025 1026 <li>accept any types of variables, by relying on streams for the actual 1027 conversion to string. This specifically concerns user-defined types, for 1028 which the formatting options effects should be intuitively natural.</li> 1029 1030 <li>provide printf-compatibility, as much as it makes sense in a 1031 type-safe and type-extendable context.</li> 1032 </ul> 1033 1034 <p>In the process of the design, many issues were faced, and some choices 1035 were made, that might not be intuitively right. But in each case they were 1036 taken for <a href="choices.html">some reasons</a>.</p> 1037 <hr> 1038 1039 <h2>Credits</h2> 1040 1041 <p>The author of Boost format is Samuel Krempp. He used ideas from 1042 Rüdiger Loos' format.hpp and Karl Nelson's formatting classes.</p> 1043 <hr> 1044 1045 <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src= 1046 "../../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional" 1047 height="31" width="88"></a></p> 1048 1049 <p>Revised 1050 <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->23 October, 2017<!--webbot bot="Timestamp" endspan i-checksum="38510" --></p> 1051 1052 <p><i>Copyright © 2002 Samuel Krempp</i></p> 1053 1054 <p><i>Distributed under the Boost Software License, Version 1.0. (See 1055 accompanying file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or 1056 copy at <a href= 1057 "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p> 1058</body> 1059</html> 1060