Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/format/doc/format.html @ 47

Last change on this file since 47 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 34.5 KB
Line 
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>
65cout &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>
82cout &lt;&lt; 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&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 :
109cout &lt;&lt; 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 &lt;&lt; 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 &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
164cout &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
175cout &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
186cout &lt;&lt; format("(x,y) = (%+5d,%+5d) \n") % -23 % 35;
187cout &lt;&lt; format("(x,y) = (%|+5|,%|+5|) \n") % -23 % 35;
188
189cout &lt;&lt; format("(x,y) = (%1$+5d,%2$+5d) \n") % -23 % 35;
190cout &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
201format fmter("_%1$+5d_ %1$d \n");
202
203format fmter2("_%1%_ %1% \n");
204fmter2.modify_item(1, group(showpos, setw(5)) );
205
206cout &lt;&lt; fmter % 101 ;
207cout &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
218cout &lt;&lt; format("_%1%_ %1% \n") % group(showpos, setw(5), 101);
219
220</pre>
221      </blockquote>The manipulators are applied at each occurence 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 &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>
241Marc-Fran&ccedil;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    The brackets are 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>
607printf(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>
614cout &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>
657format formatter("%+5d");
658cout &lt;&lt; formatter % x;
659unsigned 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>
674Rational ratio(16,9);
675cerr &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>
685cerr &lt;&lt; format("%-8d")  % ratio;  // -&gt; "16/9    "      and not    "16      /9       "
686cerr &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>
698cerr &lt;&lt; format("%+08d \n")  % ratio;  // -&gt; "+00016/9"
699cerr &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>
723cout &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 occurence. 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>
749cout &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
793unsigned char exceptions(unsigned char newexcept); // query and set
794unsigned 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
828boost::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
842cout &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
851cout &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 straigt 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>
904string     fstring="%3$0#6x %1$20.10E %2$g %3$0+5d \n";
905double     arg1=45.23;
906double     arg2=12.34;
907int        arg3=23;
908
909- release mode :
910printf                 : 2.13
911nullStream             : 3.43,  = 1.61033 * printf
912boost::format copied   : 6.77,  = 3.1784  * printf ,  = 1.97376 * nullStream
913boost::format straight :10.67,  = 5.00939 * printf ,  = 3.11079 * nullStream
914
915- debug mode :
916printf                 : 2.12
917nullStream             : 3.69,  = 1.74057 * printf
918boost::format copied   :10.02,  = 4.72642 * printf ,  = 2.71545 * nullStream
919boost::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>
928namespace boost {
929
930template&lt;class charT, class Traits=std::char_traits&lt;charT&gt; &gt; 
931class basic_format
932{
933public:
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
963typedef basic_format&lt;char &gt;          format;
964typedef basic_format&lt;wchar_t &gt;      wformat;
965
966
967// free function for ease of use :
968template&lt;class charT, class Traits&gt; 
969std::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  "http://www.w3.org/Icons/valid-html401" 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>
Note: See TracBrowser for help on using the repository browser.