]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/format/doc/format.html
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / format / doc / format.html
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">&lt;boost/format.hpp&gt;</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>
65 cout &lt;&lt; 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>
82 cout &lt;&lt; format("%2% %1%") % 36 % 77;
83 </pre>
84 </blockquote>or later on, as in
85
86 <blockquote>
87 <pre>
88 format fmter("%2% %1%");
89 fmter % 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&amp; )</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 :
109 cout &lt;&lt; fmter ;
110
111 // You can take the string result :
112 string s = fmter.str();
113
114 // possibly several times :
115 s = fmter.str( );
116
117 // You can also do all steps at once :
118 cout &lt;&lt; boost::format("%2% %1%") % 36 % 77;
119
120 // using the str free function :
121 string 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>
141 using namespace std;
142 using boost::format;
143 using boost::io::group;
144 </pre>
145 </blockquote>
146
147 <ul>
148 <li>Simple output, with reordering :
149
150 <blockquote>
151 <pre>
152
153 cout &lt;&lt; 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
164 cout &lt;&lt; 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
175 cout &lt;&lt; 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
186 cout &lt;&lt; format("(x,y) = (%+5d,%+5d) \n") % -23 % 35;
187 cout &lt;&lt; format("(x,y) = (%|+5|,%|+5|) \n") % -23 % 35;
188
189 cout &lt;&lt; format("(x,y) = (%1$+5d,%2$+5d) \n") % -23 % 35;
190 cout &lt;&lt; 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
201 format fmter("_%1$+5d_ %1$d \n");
202
203 format fmter2("_%1%_ %1% \n");
204 fmter2.modify_item(1, group(showpos, setw(5)) );
205
206 cout &lt;&lt; fmter % 101 ;
207 cout &lt;&lt; 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
218 cout &lt;&lt; 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
232 for(unsigned int i=0; i &lt; names.size(); ++i)
233 cout &lt;&lt; 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>
241 Marc-Fran&ccedil;ois Michel, Durand, +33 (0) 123 456 789
242 Jean, 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><br>
343 <br>
344 A specification <i>spec</i> has the form : [ <i>N</i><b>$</b> ] [
345 <i>flags</i> ] [ <i>width</i> ] [ <b>.</b> <i>precision</i> ]
346 <i>type-char</i><br>
347 <br>
348 Fields insided square brackets are optional. Each of those fields are
349 explained one by one in the following list :</p>
350
351 <ul>
352 <li><i>N</i> <b>$</b> (optional field) specifies that the format
353 specification applies to the <i>N</i>-th argument. (it is called a
354 <i>positional format specification</i>)<br>
355 If this is not present, arguments are taken one by one. (and it is then
356 an error to later supply an argument number)</li>
357
358 <li>
359 <i>flags</i> is a sequences of any of those :
360
361 <blockquote>
362 <table border="1" cellpadding="5" summary="">
363 <tr>
364 <td><b>Flag</b></td>
365
366 <td><b>Meaning</b></td>
367
368 <td><b>effect on internal stream</b></td>
369 </tr>
370
371 <tr>
372 <td><b>'-'</b></td>
373
374 <td>left alignment</td>
375
376 <td>N/A (applied later on the string)</td>
377 </tr>
378
379 <tr>
380 <td><b>'='</b></td>
381
382 <td>centered alignment</td>
383
384 <td>N/A (applied later on the string)<br>
385 <i>- note : added feature, not in printf -</i></td>
386 </tr>
387
388 <tr>
389 <td><b>'_'</b></td>
390
391 <td>internal alignment</td>
392
393 <td>sets internal alignment<br>
394 <i>- note : added feature, not in printf -</i></td>
395 </tr>
396
397 <tr>
398 <td><b>'+'</b></td>
399
400 <td>show sign even for positive numbers</td>
401
402 <td>sets <i>showpos</i></td>
403 </tr>
404
405 <tr>
406 <td><b>'#'</b></td>
407
408 <td>show numerical base, and decimal point</td>
409
410 <td>sets <i>showbase</i> and <i>showpoint</i></td>
411 </tr>
412
413 <tr>
414 <td><b>'0'</b></td>
415
416 <td>pad with 0's (inserted after sign or base indicator)</td>
417
418 <td>if not left-aligned, calls <i>setfill('0')</i> and sets
419 <i>internal</i><br>
420 Extra actions are taken after stream conversion to handle
421 <a href="#user-defined">user-defined output</a>.</td>
422 </tr>
423
424 <tr>
425 <td><b>' '</b></td>
426
427 <td>if the string does not begin with <i>+</i> or <i>-</i>,
428 insert a <i>space</i> before the converted string</td>
429
430 <td>N/A (applied later on the string)<br>
431 Different to printf's behaviour : it is not affected by internal
432 alignment</td>
433 </tr>
434 </table>
435 </blockquote>
436 </li>
437
438 <li><i>width</i> specifies a minimal width for the string resulting form
439 the conversion. If necessary, the string will be padded with alignment
440 and fill characters either set on the stream via manipulators, or
441 specified by the format-string (e.g. flags '0', '-', ..)<br>
442 Note that width is not just set on the conversion stream. To support
443 output of <a href="#user-defined">user-defined types</a> (that might call
444 <i>operator&lt;&lt;</i> many times on several members), the width is
445 handled after stream conversion of the whole argument object, in the
446 format class code.</li>
447
448 <li>
449 <i>precision</i> (preceded by a point), sets the stream's
450 <i>precision</i>
451
452 <ul>
453 <li>When outputting a floatting type number, it sets the maximum
454 number of digits
455
456 <ul>
457 <li>after decimal point when in fixed or scientific mode</li>
458
459 <li>in total when in default mode ('<i>general mode</i>', like
460 <i>%g</i>)</li>
461 </ul>
462 </li>
463
464 <li>When used with type-char <b>s</b> or <b>S</b> it takes another
465 meaning : the conversion string is truncated to the <i>precision</i>
466 first chars. (Note that the eventual padding to <i>width</i> is done
467 after truncation.)</li>
468 </ul>
469 </li>
470
471 <li>
472 <i>type-char</i>. it does <b>not</b> impose the concerned argument to
473 be of a restricted set of types, but merely sets the flags that are
474 associated with this type specification.
475
476 <blockquote>
477 <table border="1" cellpadding="5" summary="">
478 <tr>
479 <td><b>Type-Char</b></td>
480
481 <td><b>Meaning</b></td>
482
483 <td><b>effect on stream</b></td>
484 </tr>
485
486 <tr>
487 <td><b>p or x</b></td>
488
489 <td>hexadecimal output</td>
490
491 <td>sets <i>hex</i></td>
492 </tr>
493
494 <tr>
495 <td><b>o</b></td>
496
497 <td>octal output</td>
498
499 <td>sets <i>oct</i></td>
500 </tr>
501
502 <tr>
503 <td><b>e</b></td>
504
505 <td>scientific float format</td>
506
507 <td>sets floatfield bits to <i>scientific</i></td>
508 </tr>
509
510 <tr>
511 <td><b>f</b></td>
512
513 <td>fixed float format</td>
514
515 <td>sets floatfield bits to <i>fixed</i></td>
516 </tr>
517
518 <tr>
519 <td><b>g</b></td>
520
521 <td>general -default- float format</td>
522
523 <td><b>unset</b> all floatfield bits</td>
524 </tr>
525
526 <tr>
527 <td><b>X, E</b> or <b>G</b></td>
528
529 <td>same effect as their lowercase counterparts, but using
530 uppercase letters for number outputs. (exponents, hex digits,
531 ..)</td>
532
533 <td>same effects as <i>'x'</i>, <i>'e'</i>, or <i>'g'</i>,
534 <b>plus</b> <i>uppercase</i></td>
535 </tr>
536
537 <tr>
538 <td><b>d, i</b> or <b>u</b></td>
539
540 <td><b>decimal</b> type output</td>
541
542 <td>sets basefield bits to <i>dec</i></td>
543 </tr>
544
545 <tr>
546 <td><b>s</b> or <b>S</b></td>
547
548 <td>string output</td>
549
550 <td><i>precision</i> specification is unset, and its value goes
551 to an internal field for later 'truncation'. (see
552 <i>precision</i> explanation above)</td>
553 </tr>
554
555 <tr>
556 <td><b>c</b> or <b>C</b></td>
557
558 <td>1-character output</td>
559
560 <td>only the first character of the conversion string is
561 used.</td>
562 </tr>
563
564 <tr>
565 <td><b>%</b></td>
566
567 <td>print the character <i>%</i></td>
568
569 <td>N/A</td>
570 </tr>
571 </table>
572 </blockquote>
573
574 <p>Note that the 'n' type specification is ignored (and so is the
575 corresponding argument), because it does not fit in this context.<br>
576 Also, printf 'l', 'L', or 'h' modifiers (to indicate wide, long or
577 short types) are supported (and simply have no effect on the internal
578 stream).</p>
579 </li>
580 </ul><a name="new_directives" id="new_directives"></a>
581
582 <h3>new format-specifications</h3>
583
584 <ul>
585 <li>as stated in the flags table, centered and internal alignment flags
586 (' <i>=</i> ', and ' <i>_</i> ') were added.</li>
587
588 <li><i><b>%{</b>n</i><b>t}</b> , where <i>n</i> is a positive number,
589 inserts an <i>absolute tabulation</i>. It means that format will, if
590 needed, fill the string with characters, until the length of the string
591 created so far reaches <i>n</i> characters. (see <a href=
592 "#examples">examples</a> )</li>
593
594 <li><b>%|</b><i>n</i><b>T</b><i>X</i><b>|</b> inserts a tabulation in the
595 same way, but using <i>X</i> as fill character instead of the current
596 'fill' char of the stream (which is <i>space</i> for a stream in default
597 state)</li>
598 </ul><a name="printf_differences" id="printf_differences"></a>
599
600 <h2>Differences of behaviour vs printf</h2>Suppose you have variables
601 <i>x1, x2</i> (built_in types, supported by C's printf),<br>
602 and a format string <i>s</i> intended for use with a printf function this
603 way :
604
605 <blockquote>
606 <pre>
607 printf(s, x1, x2);
608 </pre>
609 </blockquote><br>
610 In almost all cases, the result will be the same as with this command :
611
612 <blockquote>
613 <pre>
614 cout &lt;&lt; format(s) % x1 % x2;
615 </pre>
616 </blockquote>
617
618 <p>But because some printf format specifications don't translate well into
619 stream formatting options, there are a few notable imperfections in the way
620 Boost.format emulates printf.<br>
621 In any case, the <i>format</i> class should quietly ignore the unsupported
622 options, so that printf format-strings are always accepted by format and
623 produce almost the same output as printf.</p><br>
624 Here is the full list of such differences :
625
626 <ul>
627 <li><b>'0'</b> and <b>' '</b> options : printf ignores these options for
628 non numeric conversions, but format applies them to all types of
629 variables. (so it is possible to use those options on user-defined types,
630 e.g. a Rational class, etc..)</li>
631
632 <li><b>precision</b> for integral types arguments has a special meaning
633 for printf :<br>
634 <i>printf( "(%5.3d)" , 7 ) ;</i> prints &laquo; ( 007) &raquo;<br>
635 While format, like streams, ignores the precision parameter for integral
636 types conversions.</li>
637
638 <li>the <b>'</b> printf option (<i>format with thousands grouping
639 characters)</i>) has no effect in format.</li>
640
641 <li>Width or precision set to asterisk (<i>*</i>) are used by printf to
642 read this field from an argument. e.g.
643 <i>printf("%1$d:%2$.*3$d:%4$.*3$d\n", hour, min, precision, sec);</i><br>
644 This class does not support this mechanism for now. so such precision or
645 width fields are quietly ignored by the parsing.</li>
646 </ul>Also, note that the special <b>'n'</b> type-specification (used to
647 tell printf to save in a variable the number of characters output by the
648 formatting) has no effect in format.<br>
649 Thus format strings containing this type-specification should produce the
650 same converted string by printf or format. It will not cause differences in
651 the formatted strings between printf and format.<br>
652 To get the number of characters in the formatted string using Boost.Format,
653 you can use the <i>size()</i> member function :
654
655 <blockquote>
656 <pre>
657 format formatter("%+5d");
658 cout &lt;&lt; formatter % x;
659 unsigned int n = formatter.size();
660 </pre>
661 </blockquote><a name="user-defined" id="user-defined"></a>
662 <hr>
663
664 <h2>User-defined types output</h2>
665
666 <p>All flags which are translated into modification to the stream state act
667 recursively within user-defined types. ( the flags remain active, and so
668 does the desired format option, for each of the '&lt;&lt;' operations that
669 might be called by the user-defined class)</p>e.g., with a Rational class,
670 we would have something like :
671
672 <blockquote>
673 <pre>
674 Rational ratio(16,9);
675 cerr &lt;&lt; format("%#x \n") % ratio; // -&gt; "0x10/0x9 \n"
676 </pre>
677 </blockquote>
678
679 <p>It's a different story for other formatting options. For example,
680 setting width applies to the final output produced by the object, not to
681 each of its internal outputs, and that's fortunate :</p>
682
683 <blockquote>
684 <pre>
685 cerr &lt;&lt; format("%-8d") % ratio; // -&gt; "16/9 " and not "16 /9 "
686 cerr &lt;&lt; format("%=8d") % ratio; // -&gt; " 16/9 " and not " 16 / 9 "
687 </pre>
688 </blockquote>
689
690 <p><br>
691 But so does the 0 and ' ' options (contrarily to '+' which is directly
692 translated to the stream state by <i>showpos</i>. But no such flags exist
693 for the zero and space printf options)<br>
694 and that is less natural :</p>
695
696 <blockquote>
697 <pre>
698 cerr &lt;&lt; format("%+08d \n") % ratio; // -&gt; "+00016/9"
699 cerr &lt;&lt; format("% 08d \n") % ratio; // -&gt; "000 16/9"
700 </pre>
701 </blockquote>It is possible to obtain a better behaviour by carefully
702 designing the Rational's <i>operator&lt;&lt;</i> to handle the stream's
703 width, alignment and <i>showpos</i> paramaters by itself. This is
704 demonstrated in <a href=
705 "../example/sample_userType.cpp">sample_userType.cpp</a>. <a name=
706 "manipulators" id="manipulators"></a>
707 <hr>
708
709 <h3>Manipulators, and internal stream state</h3>
710
711 <p>The internal stream state of <b>format</b> is saved before and restored
712 after output of an argument; therefore, the modifiers are not sticky and
713 affect only the argument they are applied to.<br>
714 The default state for streams, as stated by the standard, is : precision 6,
715 width 0, right alignment, and decimal flag set.</p>
716
717 <p>The state of the internal <b>format</b> stream can be changed by
718 manipulators passed along with the argument; via the <i>group</i> function,
719 like that :</p>
720
721 <blockquote>
722 <pre>
723 cout &lt;&lt; format("%1% %2% %1%\n") % group(hex, showbase, 40) % 50; // prints "0x28 50 0x28\n"
724 </pre>
725 </blockquote>
726
727 <p><br>
728 When passing N items inside a 'group' Boost.format needs to process
729 manipulators diferently from regular argument, and thus using group is
730 subject to the following constraints :</p>
731
732 <ol>
733 <li>the object to be printed must be passed as the last item in the
734 group</li>
735
736 <li>the first N-1 items are treated as manipulators, and if they do
737 produce output, it is discarded</li>
738 </ol>
739
740 <p>Such manipulators are passed to the streams right before the following
741 argument, at every occurrence. Note that formatting options specified within
742 the format string are overridden by stream state modifiers passed this way.
743 For instance in the following code, the <i>hex</i> manipulator has priority
744 over the <i>d</i> type-specification in the format-string which would set
745 decimal output :</p>
746
747 <blockquote>
748 <pre>
749 cout &lt;&lt; format("%1$d %2% %1%\n") % group(hex, showbase, 40) % 50;
750 // prints "0x28 50 0x28\n"
751 </pre>
752 </blockquote><a name="alternatives" id="alternatives"></a>
753
754 <h2>Alternatives</h2>
755
756 <ul>
757 <li><b>printf</b> is the classical alternative, that is not type safe and
758 not extendable to user-defined types.</li>
759
760 <li>ofrstream.cc by Karl Nelson's design was a big source of inspiration
761 to this format class.</li>
762
763 <li>James Kanze's library has a format class (in
764 <i>srcode/Extended/format</i> ) which looks very well polished. Its
765 design has in common with this class the use of internal stream for the
766 actual conversions, as well as using operators to pass arguments. (but
767 his class, as ofrstream, uses <i>operator&lt;&lt;</i> rather <i>than
768 operator%</i> )</li>
769
770 <li><a href="http://groups.yahoo.com/group/boost/files/format3/">Karl
771 Nelson's library</a> was intented as demonstration of alternative
772 solutions in discussions on Boost's list for the design of
773 Boost.format.</li>
774 </ul><a name="exceptions" id="exceptions"></a>
775 <hr>
776
777 <h2>Exceptions</h2>
778
779 <p>Boost.format enforces a number of rules on the usage of format objects.
780 The format-string must obeys the syntax described above, the user must
781 supply exactly the right number of arguments before outputting to the final
782 destination, and if using modify_item or bind_arg, items and arguments
783 index must not be out of range.<br>
784 When format detects that one of these rules is not satisfied, it raises a
785 corresponding exception, so that the mistakes don't go unnoticed and
786 unhandled.<br>
787 But the user can change this behaviour to fit his needs, and select which
788 types of errors may raise exceptions using the following functions :</p>
789
790 <blockquote>
791 <pre>
792
793 unsigned char exceptions(unsigned char newexcept); // query and set
794 unsigned char exceptions() const; // just query
795
796 </pre>
797 </blockquote>
798
799 <p>The user can compute the argument <i>newexcept</i> by combining the
800 following atoms using binary arithmetic :</p>
801
802 <ul>
803 <li><b>boost::io::bad_format_string_bit</b> selects errors due to
804 ill-formed format-strings.</li>
805
806 <li><b>boost::io::too_few_args_bit</b> selects errors due to asking for
807 the srting result before all arguments are passed.</li>
808
809 <li><b>boost::io::too_many_args_bit</b> selects errors due to passing too
810 many arguments.</li>
811
812 <li><b>boost::io::out_of_range_bit</b> select errors due to out of range
813 index supplied by the user when calling <i>modify_item</i> or other
814 functions taking an item index (or an argument index)</li>
815
816 <li><b>boost::io::all_error_bits</b> selects all errors</li>
817
818 <li><b>boost::io::no_error_bits</b> selects no error.</li>
819 </ul>
820
821 <p>For instance, if you don't want Boost.format to detect bad number of
822 arguments, you can define a specific wrapper function for building format
823 objects with the right exceptions settings :</p>
824
825 <blockquote>
826 <pre>
827
828 boost::format my_fmt(const std::string &amp; f_string) {
829 using namespace boost::io;
830 format fmter(f_string);
831 fmter.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) );
832 return fmter;
833 }
834
835 </pre>
836 </blockquote>It is then allowed to give more arguments than needed (they
837 are simply ignored) :
838
839 <blockquote>
840 <pre>
841
842 cout &lt;&lt; my_fmt(" %1% %2% \n") % 1 % 2 % 3 % 4 % 5;
843
844 </pre>
845 </blockquote>And if we ask for the result before all arguments are
846 supplied, the corresponding part of the result is simply empty
847
848 <blockquote>
849 <pre>
850
851 cout &lt;&lt; my_fmt(" _%2%_ _%1%_ \n") % 1 ;
852 // prints " __ _1_ \n"
853
854 </pre>
855 </blockquote><a name="performance" id="performance"></a>
856 <hr>
857
858 <h2>A Note about performance</h2>
859
860 <p>The performance of boost::format for formatting a few builtin type
861 arguments with reordering can be compared to that of Posix-printf, and of
862 the equivalent stream manual operations to give a measure of the overhead
863 incurred. The result may greatly depend on the compiler, standard library
864 implementation, and the precise choice of format-string and arguments.</p>
865
866 <p>Since common stream implementations eventually call functions of the
867 printf family for the actual formatting of numbers, in general printf will
868 be noticeably faster than the direct stream operations And due to to the
869 reordering overhead (allocations to store the pieces of string, stream
870 initialisation at each item formatting, ..) the direct stream operations
871 would be faster than boost::format, (one cas expect a ratio ranging from 2
872 to 5 or more)</p>
873
874 <p>When iterated formattings are a performance bottleneck, performance can
875 be slightly increased by parsing the format string into a format object,
876 and copying it at each formatting, in the following way.</p>
877
878 <blockquote>
879 <pre>
880 const boost::format fmter(fstring);
881 dest &lt;&lt; boost::format(fmter) % arg1 % arg2 % arg3 ;
882 </pre>
883 </blockquote>
884
885 <p>As an example of performance results, the author measured the time of
886 execution of iterated formattings with 4 different methods</p>
887
888 <ol>
889 <li>posix printf</li>
890
891 <li>manual stream output (to a dummy <i>nullStream</i> stream sending the
892 bytes into oblivion)</li>
893
894 <li>boost::format copied from a const object as shown above</li>
895
896 <li>the straight boost::format usage</li>
897 </ol>
898
899 <p>the test was compiled with g++-3.3.3 and the following timings were
900 measured (in seconds, and ratios) :</p>
901
902 <blockquote>
903 <pre>
904 string fstring="%3$0#6x %1$20.10E %2$g %3$0+5d \n";
905 double arg1=45.23;
906 double arg2=12.34;
907 int arg3=23;
908
909 - release mode :
910 printf : 2.13
911 nullStream : 3.43, = 1.61033 * printf
912 boost::format copied : 6.77, = 3.1784 * printf , = 1.97376 * nullStream
913 boost::format straight :10.67, = 5.00939 * printf , = 3.11079 * nullStream
914
915 - debug mode :
916 printf : 2.12
917 nullStream : 3.69, = 1.74057 * printf
918 boost::format copied :10.02, = 4.72642 * printf , = 2.71545 * nullStream
919 boost::format straight :17.03, = 8.03302 * printf , = 4.61518 * nullStream
920 </pre>
921 </blockquote><a name="extract" id="extract"></a>
922 <hr>
923
924 <h2>Class Interface Extract</h2>
925
926 <blockquote>
927 <pre>
928 namespace boost {
929
930 template&lt;class charT, class Traits=std::char_traits&lt;charT&gt; &gt;
931 class basic_format
932 {
933 public:
934 typedef std::basic_string&lt;charT, Traits&gt; string_t;
935 typedef typename string_t::size_type size_type;
936 basic_format(const charT* str);
937 basic_format(const charT* str, const std::locale &amp; loc);
938 basic_format(const string_t&amp; s);
939 basic_format(const string_t&amp; s, const std::locale &amp; loc);
940 basic_format&amp; operator= (const basic_format&amp; x);
941
942 void clear(); // reset buffers
943 basic_format&amp; parse(const string_t&amp;); // clears and parse a new format string
944
945 string_t str() const;
946 size_type size() const;
947
948 // pass arguments through those operators :
949 template&lt;class T&gt; basic_format&amp; operator%(T&amp; x);
950 template&lt;class T&gt; basic_format&amp; operator%(const T&amp; x);
951
952 // dump buffers to ostream :
953 friend std::basic_ostream&lt;charT, Traits&gt;&amp;
954 operator&lt;&lt; &lt;&gt; ( std::basic_ostream&lt;charT, Traits&gt;&amp; , basic_format&amp; );
955
956 // Choosing which errors will throw exceptions :
957 unsigned char exceptions() const;
958 unsigned char exceptions(unsigned char newexcept);
959
960 // ............ this is just an extract .......
961 }; // basic_format
962
963 typedef basic_format&lt;char &gt; format;
964 typedef basic_format&lt;wchar_t &gt; wformat;
965
966
967 // free function for ease of use :
968 template&lt;class charT, class Traits&gt;
969 std::basic_string&lt;charT,Traits&gt; str(const basic_format&lt;charT,Traits&gt;&amp; f) {
970 return f.str();
971 }
972
973
974 } // namespace boost
975 </pre>
976 </blockquote>
977 <hr>
978 <a name="rationale" id="rationale"></a>
979
980 <h2>Rationale</h2>
981
982 <p>This class's goal is to bring a better, C++, type-safe and
983 type-extendable <i>printf</i> equivalent to be used with
984 streams.</p>Precisely, <b>format</b> was designed to provide the following
985 features :
986
987 <ul>
988 <li>support positional arguments (required for internationalisation)</li>
989
990 <li>accept an unlimited number of arguments.</li>
991
992 <li>make formatting commands visually natural.</li>
993
994 <li>support the use of manipulators to modify the display of an argument.
995 in addition to the format-string syntax.</li>
996
997 <li>accept any types of variables, by relying on streams for the actual
998 conversion to string. This specifically concerns user-defined types, for
999 which the formatting options effects should be intuitively natural.</li>
1000
1001 <li>provide printf-compatibility, as much as it makes sense in a
1002 type-safe and type-extendable context.</li>
1003 </ul>
1004
1005 <p>In the process of the design, many issues were faced, and some choices
1006 were made, that might not be intuitively right. But in each case they were
1007 taken for <a href="choices.html">some reasons</a>.</p>
1008 <hr>
1009
1010 <h2>Credits</h2>
1011
1012 <p>The author of Boost format is Samuel Krempp. &nbsp; He used ideas from
1013 R&uuml;diger Loos' format.hpp and Karl Nelson's formatting classes.</p>
1014 <hr>
1015
1016 <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
1017 "../../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
1018 height="31" width="88"></a></p>
1019
1020 <p>Revised
1021 <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->02 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38510" --></p>
1022
1023 <p><i>Copyright &copy; 2002 Samuel Krempp</i></p>
1024
1025 <p><i>Distributed under the Boost Software License, Version 1.0. (See
1026 accompanying file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
1027 copy at <a href=
1028 "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
1029 </body>
1030 </html>