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