<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta http-equiv="Content-Language" content="en-us"><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"><title>The Boost Format library</title></head><body bgcolor="white" text="black"><h1><img align="middle" alt="boost.png (6897 bytes)" height="86" src="../../../boost.png" width="277">The Boost Format library</h1><p>The <code><a href="../../../boost/format.hpp"><boost/format.hpp></a></code> formatclass provides printf-like formatting, in a type-safe manner which allowsoutput of user-defined types.<br></p><ul><li><a href="#synopsis">Synopsis</a></li><li><a href="#how_it_works">How it works</a></li><li><a href="#examples">Examples</a></li><li><a href="#syntax">Syntax</a><ul><li><a href="#printf_directives">printf format-specificationsyntax</a></li><li><a href="#printf_differences">Incompatibilities withprintf</a></li></ul></li><li><a href="#manipulators">Manipulators and the internal streamstate</a></li><li><a href="#user-defined">User-defined types</a></li><li><a href="#alternatives">Alternatives</a></li><li><a href="#exceptions">Exceptions</a></li><li><a href="#performance">Performance</a></li><li><a href="#extract">Class Interface Extract</a></li><li><a href="#rationale">Rationale</a></li></ul><a name="synopsis" id="synopsis"></a><hr><h2>Synopsis</h2><p>A format object is constructed from a format-string, and is then givenarguments through repeated calls to <i>operator%</i>.<br>Each of those arguments are then converted to strings, who are in turncombined into one string, according to the format-string.</p><blockquote><pre>cout << boost::format("writing %1%, x=%2% : %3%-th try") % "toto" % 40.23 % 50;// prints "writing toto, x=40.230 : 50-th try"</pre></blockquote><a name="how_it_works" id="how_it_works"></a><hr><h2>How it works</h2><ol><li>When you call <i>format(s)</i>, where s is the format-string, itconstructs an object, which parses the format string and look for alldirectives in it and prepares internal structures for the next step.</li><li>Then, either immediately, as in<blockquote><pre>cout << format("%2% %1%") % 36 % 77;</pre></blockquote>or later on, as in<blockquote><pre>format fmter("%2% %1%");fmter % 36; fmter % 77;</pre></blockquote>you <i>feed</i> variables into the formatter.<br>those variables are dumped into an internal stream, which state is setaccording to the given formatting options in the format-string -ifthere are any-, and the format object stores the string results for thelast step.</li><li>Once all arguments have been fed you can dump the format object to astream, or get its string value by using the <i>str()</i> memberfunction, or the free function <i>str(const format& )</i> innamespace <i>boost</i>. The result string stays accessible in the formatobject until another argument is passed, at which time it isreinitialised.<blockquote><pre>// fmter was previously created and fed arguments, it can print the result :cout << fmter ;// You can take the string result :string s = fmter.str();// possibly several times :s = fmter.str( );// You can also do all steps at once :cout << boost::format("%2% %1%") % 36 % 77;// using the str free function :string s2 = str( format("%2% %1%") % 36 % 77 );</pre></blockquote></li><li>Optionnally, after step 3, you can re-use a format object and restartat step2 : <i>fmter % 18 % 39;</i><br>to format new variables with the same format-string, saving the expensiveprocessing involved at step 1.</li></ol>All in all, the format class translates a format-string (witheventually printf-like directives) into operations on an internal stream,and finally returns the result of the formatting, as a string, or directlyinto an output stream. <a name="examples" id="examples"></a><hr><h2>Examples</h2><blockquote><pre>using namespace std;using boost::format;using boost::io::group;</pre></blockquote><ul><li>Simple output, with reordering :<blockquote><pre>cout << format("%1% %2% %3% %2% %1% \n") % "11" % "22" % "333"; // 'simple' style.</pre></blockquote>It prints : "11 22 333 22 11 \n"</li><li>More precise formatting, with Posix-printf positional directives :<blockquote><pre>cout << format("(x,y) = (%1$+5d,%2$+5d) \n") % -23 % 35; // Posix-Printf style</pre></blockquote>It prints : "(x,y) = ( -23, +35) \n"</li><li>classical printf directive, no reordering :<blockquote><pre>cout << format("writing %s, x=%s : %d-th step \n") % "toto" % 40.23 % 50;</pre></blockquote>It prints : "writing toto, x=40.23 : 50-th step \n"</li><li>Several ways to express the same thing :<blockquote><pre>cout << format("(x,y) = (%+5d,%+5d) \n") % -23 % 35;cout << format("(x,y) = (%|+5|,%|+5|) \n") % -23 % 35;cout << format("(x,y) = (%1$+5d,%2$+5d) \n") % -23 % 35;cout << format("(x,y) = (%|1$+5|,%|2$+5|) \n") % -23 % 35;</pre></blockquote>all those print : "(x,y) = ( -23, +35) \n"</li><li>Using manipulators to modify the format-string :<blockquote><pre>format fmter("_%1$+5d_ %1$d \n");format fmter2("_%1%_ %1% \n");fmter2.modify_item(1, group(showpos, setw(5)) );cout << fmter % 101 ;cout << fmter2 % 101 ;</pre></blockquote>Both print the same : "_ +101_ 101 \n"</li><li>Using manipulators with arguments :<blockquote><pre>cout << format("_%1%_ %1% \n") % group(showpos, setw(5), 101);</pre></blockquote>The manipulators are applied at each occurrence of %1%, andthus it prints : "_ +101_ +101 \n"</li><li>New formatting feature : 'absolute tabulations', useful inside loops,to insure a field is printed at the same position from one line to thenext, even if the widthes of the previous arguments can vary a lot.<blockquote><pre>for(unsigned int i=0; i < names.size(); ++i)cout << format("%1%, %2%, %|40t|%3%\n") % names[i] % surname[i] % tel[i];</pre></blockquote>For some std::vector <i>names</i>, <i>surnames</i>, and<i>tel</i> (see sample_new_features.cpp) it prints :<blockquote><pre>Marc-François Michel, Durand, +33 (0) 123 456 789Jean, de Lattre de Tassigny, +33 (0) 987 654 321</pre></blockquote></li></ul><hr><h2>Sample Files</h2><p>The program <a href="../example/sample_formats.cpp">sample_formats.cpp</a> demonstrates simpleuses of <b>format</b>.<br></p><p><a href="../example/sample_new_features.cpp">sample_new_features.cpp</a>illustrates the few formatting features that were added to printf's syntaxsuch as simple positional directives, centered alignment, and'tabulations'.<br></p><p><a href="../example/sample_advanced.cpp">sample_advanced.cpp</a>demonstrates uses of advanced features, like reusing, and modifying, formatobjects, etc..<br></p><p>And <a href="../example/sample_userType.cpp">sample_userType.cpp</a>shows the behaviour of the <b>format</b> library on user-definedtypes.</p><a name="syntax" id="syntax"></a><hr><h2>Syntax</h2><p><b>boost::format(</b> format-string <b>) %</b> arg1 <b>%</b> arg2<b>%</b> ... <b>%</b> argN</p><p>The <i>format-string</i> contains text in which special directives willbe replaced by strings resulting from the formatting of the givenarguments.<br>The legacy syntax in the C and C++ worlds is the one used by printf, andthus format can use directly printf format-strings, and produce the sameresult (in almost all cases. see <a href="#printf_differences">Incompatibilities with printf</a> for details)<br>This core syntax was extended, to allow new features, but also to adapt tothe C++ streams context. Thus, format accepts several forms of directivesin format-strings :</p><ul><li>Legacy printf format strings : <b>%</b><i>spec</i> where <i>spec</i>is a <a href="#printf_directives">printf format specification</a><br><i>spec</i> passes formatting options, like width, alignment, numericalbase used for formatting numbers, as well as other specific flags. Butthe classical <i>type-specification</i> flag of printf has a weakermeaning in format. It merely sets the appropriate flags on the internalstream, and/or formatting parameters, but does not require thecorresponding argument to be of a specific type.<br>e.g. : the specification <i>2$x</i>, meaning "print argument number 2,which is an integral number, in hexa" for printf, merely means "printargument 2 with stream basefield flags set to <i>hex</i>" forformat.</li><li><b>%|</b><i>spec</i><b>|</b> where <i>spec</i> is a printf formatspecification.<br>This pipe-delimited syntax is introduced, to improve the readability of theformat-string, but primarily, to make the <i>type-conversioncharacter</i> optional in <i>spec</i>. This information is not necessarywith C++ variables, but with direct printf syntax, it is necessary toalways give a type-conversion character, merely because this character iscrucial to determine the end of a format-specification.<br>e.g. : "%|-5|" will format the next variable with width set to 5, andleft-alignment just like the following printf directives : "%-5g","%-5f", "%-5s" ..</li><li><b>%</b><i>N</i><b>%</b><br>This simple positional notation requests the formatting of the<i>N</i>-th argument - wihout any formatting option.<br>(It's merely a shortcut to Printf's positional directives (like"%<i>N</i>$s"), but a major benefit is that it's much more readable, anddoes not use a "type-conversion" character)</li></ul>On top of the standard printf format specifications, new features wereimplemented, like centered alignment. See <a href="#new_directives">newformat specification</a> for details. <a name="printf_directives" id="printf_directives"></a><h3>printf format specifications</h3><p>The printf format specifications supported by Boost.format follows theUnix98 <a href="http://www.opengroup.org/onlinepubs/7908799/xsh/fprintf.html">Open-groupprintf</a> precise syntax, rather than the standard C printf, which doesnot support positional arguments. (Common flags have the same meaning inboth, so it should not be a headache for anybody)<br><i>Note that it is an error to use positional format specifications</i>(e.g. <i>%3$+d</i>) <i>mixed with non-positional ones</i> (e.g. <i>%+d</i>)<i>in the same format string.</i><br>In the Open-group specification, referring to the same argument severaltimes (e.g. <i>"%1$d %1$d"</i>) has undefined behaviour. Boost.format'sbehaviour in such cases is to allow each argument to be reffered to anynumber of times. The only constraint is that it expects exactly <i>P</i>arguments, <i>P</i> being the maximum argument number used in the formatstring. (e.g., for "%1$d %10$d", <i>P</i> == 10 ).<br>Supplying more, or less, than <i>P</i> arguments raises an exception.(unless it was set otherwise, see <a href="#exceptions">exceptions</a>)</p><p>A specification <i>spec</i> has the form:<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>Fields inside square brackets are optional. Each of those fields areexplained one by one in the following list:</p><ul><li><i>N</i> <b>$</b> (optional field) specifies that the formatspecification applies to the <i>N</i>-th argument (it is called a<i>positional format specification</i>).<br>If this is not present, arguments are taken one by one. (and it is thenan error to later supply an argument number)</li><br /><li><i>flags</i> is a sequence of any of these:<blockquote><table border="1" cellpadding="5" summary=""><tr><td><b>Flag</b></td><td><b>Meaning</b></td><td><b>effect on internal stream</b></td></tr><tr><td><b>'-'</b></td><td>left alignment</td><td>N/A (applied later on the string)</td></tr><tr><td><b>'='</b></td><td>centered alignment</td><td>N/A (applied later on the string)<br><i>- note : added feature, not in printf -</i></td></tr><tr><td><b>'_'</b></td><td>internal alignment</td><td>sets internal alignment<br><i>- note : added feature, not in printf -</i></td></tr><tr><td><b>'+'</b></td><td>show sign even for positive numbers</td><td>sets <i>showpos</i></td></tr><tr><td><b>'#'</b></td><td>show numerical base, and decimal point</td><td>sets <i>showbase</i> and <i>showpoint</i></td></tr><tr><td><b>'0'</b></td><td>pad with 0's (inserted after sign or base indicator)</td><td>if not left-aligned, calls <i>setfill('0')</i> and sets<i>internal</i><br>Extra actions are taken after stream conversion to handle<a href="#user-defined">user-defined output</a>.</td></tr><tr><td><b>' '</b></td><td>if the string does not begin with <i>+</i> or <i>-</i>,insert a <i>space</i> before the converted string</td><td>N/A (applied later on the string)<br>Different to printf's behaviour : it is not affected by internalalignment</td></tr></table></blockquote><br /></li><li><i>width</i> specifies a minimal width for the string resulting formthe conversion. If necessary, the string will be padded with alignmentand fill characters either set on the stream via manipulators, orspecified by the format-string (e.g. flags '0', '-', ..)<br>Note that width is not just set on the conversion stream. To supportoutput of <a href="#user-defined">user-defined types</a> (that might call<i>operator<<</i> many times on several members), the width ishandled after stream conversion of the whole argument object, in theformat class code.</li><br /><li><i>precision</i> (preceded by a point), sets the stream's<i>precision</i><ul><li>When outputting a floatting type number, it sets the maximumnumber of digits<ul><li>after decimal point when in fixed or scientific mode</li><li>in total when in default mode ('<i>general mode</i>', like<i>%g</i>)</li></ul></li><li>When used with type-char <b>s</b> or <b>S</b> it takes anothermeaning : the conversion string is truncated to the <i>precision</i>first chars. (Note that the eventual padding to <i>width</i> is doneafter truncation.)</li></ul><br /></li><li><i>argument-type</i> is used by the printf family to properly processthe arguments being passed in through varargs. With <code>boost::format</code>the arguments are fed into format through <code>operator %</code> whichallows the template to carry the argument type. Therefore the classicalprintf style argument type is consumed and ignored.Argument-types <code>hh</code>, <code>h</code>, <code>l</code>, <code>ll</code>, <code>j</code>,<code>z</code>, and <code>L</code> are recognized, as are the Microsoft extensions <code>w</code>,<code>I</code> (capital i), <code>I32</code>, and <code>I64</code>. Argument-type <code>t</code>from the ISO C99 standard is not recognized as an argument type, as it has been in use as aconversion specifier for tabular output for many years in <code>boost::format</code>.</li><br /><li><i>conversion-specifier</i> does <b>not</b> impose the concerned argumentto be of a restricted set of types, but merely sets the ios flags that areassociated with a type specification:<blockquote><table border="1" cellpadding="5" summary=""><tr><td><b>conversion-specifier</b></td><td><b>Meaning</b></td><td><b>effect on stream</b></td></tr><tr><td><b>b</b></td><td>boolean string output</td><td>sets <i>boolalpha</i>; only works for type <code>bool</code><br />To customize the resulting string, see<a href="http://en.cppreference.com/w/cpp/locale/numpunct/truefalsename">std::numpunct</a>.</tr><tr><td><b>p or x</b></td><td>hexadecimal output</td><td>sets <i>hex</i></td></tr><tr><td><b>o</b></td><td>octal output</td><td>sets <i>oct</i></td></tr><tr><td><b>a</b></td><td>hexadecimal exponent notation</td><td>sets floatfield bits to <i>scientific</i> | <i>fixed</i> (which is equivalent to <i>hexfloat</i>)</td></tr><tr><td><b>e</b></td><td>scientific float format</td><td>sets floatfield bits to <i>scientific</i></td></tr><tr><td><b>f</b></td><td>fixed float format</td><td>sets floatfield bits to <i>fixed</i></td></tr><tr><td><b>g</b></td><td>general -default- float format</td><td><b>unset</b> all floatfield bits</td></tr><tr><td><b>X, A, E, F</b> or <b>G</b></td><td>same effect as their lowercase counterparts, but usinguppercase letters for number outputs. (exponents, hex digits,..)</td><td>same effects as <i>'x'</i>, <i>'a'</i>, <i>'e'</i>, <i>'f'</i>, or <i>'g'</i> respectively,<b>plus</b> <i>uppercase</i></td></tr><tr><td><b>d, i</b> or <b>u</b></td><td><b>decimal</b> type output</td><td>sets basefield bits to <i>dec</i></td></tr><tr><td><b>s</b> or <b>S</b></td><td>string output</td><td><i>precision</i> specification is unset, and its value goesto an internal field for later 'truncation'. (see<i>precision</i> explanation above)</td></tr><tr><td><b>c</b> or <b>C</b></td><td>1-character output</td><td>only the first character of the conversion string isused.</td></tr><tr><td><b>%</b></td><td>print the character <i>%</i></td><td>N/A</td></tr></table></blockquote><p>Note that the 'n' conversion-specifier is ignored (and so is thecorresponding argument), because it does not fit in this context.</p></li></ul><a name="new_directives" id="new_directives"></a><h3>new format-specifications</h3><ul><li>as stated in the flags table, centered and internal alignment flags(' <i>=</i> ', and ' <i>_</i> ') were added.</li><li><i><b>%{</b>n</i><b>t}</b> , where <i>n</i> is a positive number,inserts an <i>absolute tabulation</i>. It means that format will, ifneeded, fill the string with characters, until the length of the stringcreated so far reaches <i>n</i> characters. (see <a href="#examples">examples</a> )</li><li><b>%|</b><i>n</i><b>T</b><i>X</i><b>|</b> inserts a tabulation in thesame way, but using <i>X</i> as fill character instead of the current'fill' char of the stream (which is <i>space</i> for a stream in defaultstate)</li></ul><a name="printf_differences" id="printf_differences"></a><h2>Differences of behaviour vs printf</h2>Suppose you have variables<i>x1, x2</i> (built_in types, supported by C's printf),<br>and a format string <i>s</i> intended for use with a printf function thisway :<blockquote><pre>printf(s, x1, x2);</pre></blockquote><br>In almost all cases, the result will be the same as with this command :<blockquote><pre>cout << format(s) % x1 % x2;</pre></blockquote><p>But because some printf format specifications don't translate well intostream formatting options, there are a few notable imperfections in the wayBoost.format emulates printf.<br>In any case, the <i>format</i> class should quietly ignore the unsupportedoptions, so that printf format-strings are always accepted by format andproduce almost the same output as printf.</p><br>Here is the full list of such differences :<ul><li><b>'0'</b> and <b>' '</b> options : printf ignores these options fornon numeric conversions, but format applies them to all types ofvariables. (so it is possible to use those options on user-defined types,e.g. a Rational class, etc..)</li><li><b>precision</b> for integral types arguments has a special meaningfor printf :<br><i>printf( "(%5.3d)" , 7 ) ;</i> prints « ( 007) »<br>While format, like streams, ignores the precision parameter for integraltypes conversions.</li><li>the <b>'</b> printf option (<i>format with thousands groupingcharacters)</i>) has no effect in format.</li><li>Width or precision set to asterisk (<i>*</i>) are used by printf toread this field from an argument. e.g.<i>printf("%1$d:%2$.*3$d:%4$.*3$d\n", hour, min, precision, sec);</i><br>This class does not support this mechanism for now. so such precision orwidth fields are quietly ignored by the parsing.</li><li>argument-type is ignored</li></ul>Also, note that the special <b>'n'</b> type-specification (used totell printf to save in a variable the number of characters output by theformatting) has no effect in format.<br>Thus format strings containing this type-specification should produce thesame converted string by printf or format. It will not cause differences inthe formatted strings between printf and format.<br>To get the number of characters in the formatted string using Boost.Format,you can use the <i>size()</i> member function :<blockquote><pre>format formatter("%+5d");cout << formatter % x;unsigned int n = formatter.size();</pre></blockquote><a name="user-defined" id="user-defined"></a><hr><h2>User-defined types output</h2><p>All flags which are translated into modification to the stream state actrecursively within user-defined types. ( the flags remain active, and sodoes the desired format option, for each of the '<<' operations thatmight be called by the user-defined class)</p>e.g., with a Rational class,we would have something like :<blockquote><pre>Rational ratio(16,9);cerr << format("%#x \n") % ratio; // -> "0x10/0x9 \n"</pre></blockquote><p>It's a different story for other formatting options. For example,setting width applies to the final output produced by the object, not toeach of its internal outputs, and that's fortunate :</p><blockquote><pre>cerr << format("%-8d") % ratio; // -> "16/9 " and not "16 /9 "cerr << format("%=8d") % ratio; // -> " 16/9 " and not " 16 / 9 "</pre></blockquote><p><br>But so does the 0 and ' ' options (contrarily to '+' which is directlytranslated to the stream state by <i>showpos</i>. But no such flags existfor the zero and space printf options)<br>and that is less natural :</p><blockquote><pre>cerr << format("%+08d \n") % ratio; // -> "+00016/9"cerr << format("% 08d \n") % ratio; // -> "000 16/9"</pre></blockquote>It is possible to obtain a better behaviour by carefullydesigning the Rational's <i>operator<<</i> to handle the stream'swidth, alignment and <i>showpos</i> paramaters by itself. This isdemonstrated in <a href="../example/sample_userType.cpp">sample_userType.cpp</a>. <a name="manipulators" id="manipulators"></a><hr><h3>Manipulators, and internal stream state</h3><p>The internal stream state of <b>format</b> is saved before and restoredafter output of an argument; therefore, the modifiers are not sticky andaffect only the argument they are applied to.<br>The default state for streams, as stated by the standard, is : precision 6,width 0, right alignment, and decimal flag set.</p><p>The state of the internal <b>format</b> stream can be changed bymanipulators passed along with the argument; via the <i>group</i> function,like that :</p><blockquote><pre>cout << format("%1% %2% %1%\n") % group(hex, showbase, 40) % 50; // prints "0x28 50 0x28\n"</pre></blockquote><p><br>When passing N items inside a 'group' Boost.format needs to processmanipulators diferently from regular argument, and thus using group issubject to the following constraints :</p><ol><li>the object to be printed must be passed as the last item in thegroup</li><li>the first N-1 items are treated as manipulators, and if they doproduce output, it is discarded</li></ol><p>Such manipulators are passed to the streams right before the followingargument, at every occurrence. Note that formatting options specified withinthe format string are overridden by stream state modifiers passed this way.For instance in the following code, the <i>hex</i> manipulator has priorityover the <i>d</i> type-specification in the format-string which would setdecimal output :</p><blockquote><pre>cout << format("%1$d %2% %1%\n") % group(hex, showbase, 40) % 50;// prints "0x28 50 0x28\n"</pre></blockquote><a name="alternatives" id="alternatives"></a><h2>Alternatives</h2><ul><li><b>printf</b> is the classical alternative, that is not type safe andnot extendable to user-defined types.</li><li>ofrstream.cc by Karl Nelson's design was a big source of inspirationto this format class.</li><li>James Kanze's library has a format class (in<i>srcode/Extended/format</i> ) which looks very well polished. Itsdesign has in common with this class the use of internal stream for theactual conversions, as well as using operators to pass arguments. (buthis class, as ofrstream, uses <i>operator<<</i> rather <i>thanoperator%</i> )</li><li><a href="http://groups.yahoo.com/group/boost/files/format3/">KarlNelson's library</a> was intented as demonstration of alternativesolutions in discussions on Boost's list for the design ofBoost.format.</li><li><a href="http://fmtlib.net/latest/index.html">{fmt}</a> by Victor Zverovich.</li></ul><a name="exceptions" id="exceptions"></a><hr><h2>Exceptions</h2><p>Boost.format enforces a number of rules on the usage of format objects.The format-string must obeys the syntax described above, the user mustsupply exactly the right number of arguments before outputting to the finaldestination, and if using modify_item or bind_arg, items and argumentsindex must not be out of range.<br>When format detects that one of these rules is not satisfied, it raises acorresponding exception, so that the mistakes don't go unnoticed andunhandled.<br>But the user can change this behaviour to fit his needs, and select whichtypes of errors may raise exceptions using the following functions :</p><blockquote><pre>unsigned char exceptions(unsigned char newexcept); // query and setunsigned char exceptions() const; // just query</pre></blockquote><p>The user can compute the argument <i>newexcept</i> by combining thefollowing atoms using binary arithmetic :</p><ul><li><b>boost::io::bad_format_string_bit</b> selects errors due toill-formed format-strings.</li><li><b>boost::io::too_few_args_bit</b> selects errors due to asking forthe srting result before all arguments are passed.</li><li><b>boost::io::too_many_args_bit</b> selects errors due to passing toomany arguments.</li><li><b>boost::io::out_of_range_bit</b> select errors due to out of rangeindex supplied by the user when calling <i>modify_item</i> or otherfunctions taking an item index (or an argument index)</li><li><b>boost::io::all_error_bits</b> selects all errors</li><li><b>boost::io::no_error_bits</b> selects no error.</li></ul><p>For instance, if you don't want Boost.format to detect bad number ofarguments, you can define a specific wrapper function for building formatobjects with the right exceptions settings :</p><blockquote><pre>boost::format my_fmt(const std::string & f_string) {using namespace boost::io;format fmter(f_string);fmter.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) );return fmter;}</pre></blockquote>It is then allowed to give more arguments than needed (theyare simply ignored) :<blockquote><pre>cout << my_fmt(" %1% %2% \n") % 1 % 2 % 3 % 4 % 5;</pre></blockquote>And if we ask for the result before all arguments aresupplied, the corresponding part of the result is simply empty<blockquote><pre>cout << my_fmt(" _%2%_ _%1%_ \n") % 1 ;// prints " __ _1_ \n"</pre></blockquote><a name="performance" id="performance"></a><hr><h2>A Note about performance</h2><p>The performance of boost::format for formatting a few builtin typearguments with reordering can be compared to that of Posix-printf, and ofthe equivalent stream manual operations to give a measure of the overheadincurred. The result may greatly depend on the compiler, standard libraryimplementation, and the precise choice of format-string and arguments.</p><p>Common stream implementations eventually call functions of theprintf family for the actual formatting of numbers. In general, printfwill be noticeably faster than the direct stream operations due to thereordering overhead (allocations to store the pieces of string, streaminitialisation at each item formatting, ..). The direct stream operationswould be faster than boost::format - one can expect a ratio ranging from 2to 5 or more.</p><p>When iterated formattings are a performance bottleneck, performance canbe slightly increased by parsing the format string into a format object,and copying it at each formatting, in the following way:</p><blockquote><pre>const boost::format fmter(fstring);dest << boost::format(fmter) % arg1 % arg2 % arg3 ;</pre></blockquote><p>As an example of performance results, the author measured the time ofexecution of iterated formattings with 4 different methods:</p><ol><li>posix printf</li><li>manual stream output (to a dummy <i>nullStream</i> stream sending thebytes into oblivion)</li><li>boost::format copied from a const object as shown above</li><li>the straight boost::format usage</li></ol><p>the test was compiled with g++-3.3.3 and the following timings weremeasured (in seconds, and ratios):</p><blockquote><pre>string fstring="%30ドル#6x %120ドル.10E %2$g %30ドル+5d \n";double arg1=45.23;double arg2=12.34;int arg3=23;- release mode :printf : 2.13nullStream : 3.43, = 1.61033 * printfboost::format copied : 6.77, = 3.1784 * printf , = 1.97376 * nullStreamboost::format straight :10.67, = 5.00939 * printf , = 3.11079 * nullStream- debug mode :printf : 2.12nullStream : 3.69, = 1.74057 * printfboost::format copied :10.02, = 4.72642 * printf , = 2.71545 * nullStreamboost::format straight :17.03, = 8.03302 * printf , = 4.61518 * nullStream</pre></blockquote><a name="extract" id="extract"></a><hr><h2>Class Interface Extract</h2><blockquote><pre>namespace boost {template<class charT, class Traits=std::char_traits<charT> >class basic_format{public:typedef std::basic_string<charT, Traits> string_type;typedef typename string_type::size_type size_type;basic_format(const charT* str);basic_format(const charT* str, const std::locale & loc);basic_format(const string_type& s);basic_format(const string_type& s, const std::locale & loc);basic_format& operator= (const basic_format& x);void clear(); // reset buffersbasic_format& parse(const string_type&); // clears and parse a new format stringstring_type str() const;size_type size() const;// pass arguments through those operators :template<class T> basic_format& operator%(T& x);template<class T> basic_format& operator%(const T& x);// dump buffers to ostream :friend std::basic_ostream<charT, Traits>&operator<< <> ( std::basic_ostream<charT, Traits>& , basic_format& );// Choosing which errors will throw exceptions :unsigned char exceptions() const;unsigned char exceptions(unsigned char newexcept);// ............ this is just an extract .......}; // basic_formattypedef basic_format<char > format;typedef basic_format<wchar_t > wformat;// free function for ease of use :template<class charT, class Traits>std::basic_string<charT,Traits> str(const basic_format<charT,Traits>& f) {return f.str();}} // namespace boost</pre></blockquote><hr><a name="rationale" id="rationale"></a><h2>Rationale</h2><p>This class's goal is to bring a better, C++, type-safe andtype-extendable <i>printf</i> equivalent to be used withstreams.</p>Precisely, <b>format</b> was designed to provide the followingfeatures :<ul><li>support positional arguments (required for internationalisation)</li><li>accept an unlimited number of arguments.</li><li>make formatting commands visually natural.</li><li>support the use of manipulators to modify the display of an argument.in addition to the format-string syntax.</li><li>accept any types of variables, by relying on streams for the actualconversion to string. This specifically concerns user-defined types, forwhich the formatting options effects should be intuitively natural.</li><li>provide printf-compatibility, as much as it makes sense in atype-safe and type-extendable context.</li></ul><p>In the process of the design, many issues were faced, and some choiceswere made, that might not be intuitively right. But in each case they weretaken for <a href="choices.html">some reasons</a>.</p><hr><h2>Credits</h2><p>The author of Boost format is Samuel Krempp. He used ideas fromRüdiger Loos' format.hpp and Karl Nelson's formatting classes.</p><hr><p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src="../../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"height="31" width="88"></a></p><p>Revised<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->23 October, 2017<!--webbot bot="Timestamp" endspan i-checksum="38510" --></p><p><i>Copyright © 2002 Samuel Krempp</i></p><p><i>Distributed under the Boost Software License, Version 1.0. (Seeaccompanying file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> orcopy at <a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p></body></html>
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。