• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 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 &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    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&lt;&lt;</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 &lt;&lt; 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 &laquo; ( 007) &raquo;<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 &lt;&lt; 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 '&lt;&lt;' 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 &lt;&lt; format("%#x \n")  % ratio;  // -&gt; "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 &lt;&lt; format("%-8d")  % ratio;  // -&gt; "16/9    "      and not    "16      /9       "
713cerr &lt;&lt; format("%=8d")  % ratio;  // -&gt; "  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 &lt;&lt; format("%+08d \n")  % ratio;  // -&gt; "+00016/9"
726cerr &lt;&lt; format("% 08d \n")  % ratio;  // -&gt; "000 16/9"
727</pre>
728  </blockquote>It is possible to obtain a better behaviour by carefully
729  designing the Rational's <i>operator&lt;&lt;</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 &lt;&lt; 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 &lt;&lt; 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&lt;&lt;</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 &amp; 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 &lt;&lt; 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 &lt;&lt; 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 &lt;&lt; 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&lt;class charT, class Traits=std::char_traits&lt;charT&gt; &gt;
960class basic_format
961{
962public:
963  typedef std::basic_string&lt;charT, Traits&gt; 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 &amp; loc);
967  basic_format(const string_type&amp; s);
968  basic_format(const string_type&amp; s, const std::locale &amp; loc);
969  basic_format&amp; operator= (const basic_format&amp; x);
970
971  void clear(); // reset buffers
972  basic_format&amp; parse(const string_type&amp;); // 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&lt;class T&gt;  basic_format&amp;   operator%(T&amp; x);
979  template&lt;class T&gt;  basic_format&amp;   operator%(const T&amp; x);
980
981  // dump buffers to ostream :
982  friend std::basic_ostream&lt;charT, Traits&gt;&amp;
983  operator&lt;&lt; &lt;&gt; ( std::basic_ostream&lt;charT, Traits&gt;&amp; , basic_format&amp; );
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&lt;char &gt;          format;
993typedef basic_format&lt;wchar_t &gt;      wformat;
994
995
996// free function for ease of use :
997template&lt;class charT, class Traits&gt;
998std::basic_string&lt;charT,Traits&gt;  str(const basic_format&lt;charT,Traits&gt;&amp; 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. &nbsp; He used ideas from
1042  R&uuml;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 &copy; 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