Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/format/doc/format.html @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

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