1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> 2<html> 3<head> 4<title>I/O Stream-State Saver Library</title> 5</head> 6<body text="black" bgcolor="white" link="blue" vlink="purple" alink="red"> 7<h1><img src="../../../boost.png" alt="boost.png (6897 bytes)" 8align="middle" width="277" height="86">Header <<cite><a 9href="../../../boost/io/ios_state.hpp">boost/io/ios_state.hpp</a></cite> 10></h1> 11 12<p>The header <cite><a 13href="../../../boost/io/ios_state.hpp">boost/io/ios_state.hpp</a></cite> 14covers saving the stream state of objects in the C++ IOStreams 15system.</p> 16 17<h2><a name="contents">Contents</a></h2> 18 19<ol> 20 <li><a href="#contents">Contents</a></li> 21 <li><a href="#rationale">Rationale</a></li> 22 <li><a href="#header">Header Synopsis</a></li> 23 <li><a href="#base_savers">Savers for Basic Standard Attributes</a></li> 24 <li><a href="#adv_savers">Savers for Advanced Standard Attributes</a></li> 25 <li><a href="#user_savers">Savers for User-Defined Attributes</a></li> 26 <li><a href="#combo_savers">Savers for Combined Attributes</a></li> 27 <li><a href="#example">Example</a></li> 28 <li><a href="#refer">References</a></li> 29 <li><a href="#credits">Credits</a> 30 <ul> 31 <li><a href="#contributors">Contributors</a></li> 32 <li><a href="#history">History</a></li> 33 </ul></li> 34</ol> 35 36<h2><a name="rationale">Rationale</a></h2> 37 38<p>Sometimes a certain value has to change only for a limited scope. 39Saver classes save a copy of the current state of some object (or an 40aspect of an object), and reset the object's state at destruction time, 41undoing any change the object may have gone through.</p> 42 43<p>The saver class strategy is helpful when using I/O stream objects. 44Manipulator objects can change some aspect of a stream during input or 45output. The state changed by the manipulator usually sticks to its new 46value after the I/O transaction. This can be a problem if manipulators 47are used in a function that is not supposed to externally change a 48stream's state.</p> 49 50<blockquote><pre>#include <ostream> 51#include <ios> 52 53void hex_my_byte( std::ostream &os, char byte ) 54{ 55 os << std::hex << static_cast<unsigned>(byte); 56} 57</pre></blockquote> 58 59<p>The <var>os</var> stream will retain its new hexadecimal printing 60mode after the call to <code>hex_my_byte</code>. The stream's printing 61mode can be saved and restored with manual calls to the stream's state 62inspecting and mutating member functions. The manual method becomes 63unwieldy if the main functionality is complex and/or needs to be 64exception safe. A saver class can implement the better "resource 65acquisition is initialization" strategy.</p> 66 67<p>See the <a href="#example">example</a> below for better code, using 68saver classes.</p> 69 70<h2><a name="header">Header Synopsis</a></h2> 71 72<blockquote><pre>#include <iosfwd> <i>// for std::char_traits (declaration)</i> 73 74namespace boost 75{ 76namespace io 77{ 78 79class ios_flags_saver; 80class ios_precision_saver; 81class ios_width_saver; 82class ios_base_all_saver; 83 84template < typename Ch, class Tr = ::std::char_traits<Ch> > 85 class basic_ios_iostate_saver; 86template < typename Ch, class Tr = ::std::char_traits<Ch> > 87 class basic_ios_exception_saver; 88template < typename Ch, class Tr = ::std::char_traits<Ch> > 89 class basic_ios_tie_saver; 90template < typename Ch, class Tr = ::std::char_traits<Ch> > 91 class basic_ios_rdbuf_saver; 92template < typename Ch, class Tr = ::std::char_traits<Ch> > 93 class basic_ios_fill_saver; 94template < typename Ch, class Tr = ::std::char_traits<Ch> > 95 class basic_ios_locale_saver; 96template < typename Ch, class Tr = ::std::char_traits<Ch> > 97 class basic_ios_all_saver; 98 99typedef basic_ios_iostate_saver<char> ios_iostate_saver; 100typedef basic_ios_iostate_saver<wchar_t> wios_iostate_saver; 101typedef basic_ios_exception_saver<char> ios_exception_saver; 102typedef basic_ios_exception_saver<wchar_t> wios_exception_saver; 103typedef basic_ios_tie_saver<char> ios_tie_saver; 104typedef basic_ios_tie_saver<wchar_t> wios_tie_saver; 105typedef basic_ios_rdbuf_saver<char> ios_rdbuf_saver; 106typedef basic_ios_rdbuf_saver<wchar_t> wios_rdbuf_saver; 107typedef basic_ios_fill_saver<char> ios_fill_saver; 108typedef basic_ios_fill_saver<wchar_t> wios_fill_saver; 109typedef basic_ios_locale_saver<char> ios_locale_saver; 110typedef basic_ios_locale_saver<wchar_t> wios_locale_saver; 111typedef basic_ios_all_saver<char> ios_all_saver; 112typedef basic_ios_all_saver<wchar_t> wios_all_saver; 113 114class ios_iword_saver; 115class ios_pword_saver; 116class ios_all_word_saver; 117 118} 119} 120</pre></blockquote> 121 122<h2><a name="base_savers">Savers for Basic Standard Attributes</a></h2> 123 124<p>The basic saver classes have this format:</p> 125 126<blockquote><pre>class <var>saver_class</var> 127{ 128 typedef std::ios_base state_type; 129 typedef <i>implementation_defined</i> aspect_type; 130 131 explicit saver_class( state_type &s ); 132 saver_class( state_type &s, <var>aspect_type</var> const &new_value ); 133 ~saver_class(); 134 135 void restore(); 136}; 137</pre></blockquote> 138 139<p>The <var>state_type</var> is the IOStreams base class 140<code>std::ios_base</code>. The user would usually place an actual 141input, output, or combined stream object for the state-type parameter, 142and not a base class object. The first constructor takes a stream 143object and saves a reference to the stream and the current value of a 144particular stream attribute. The second constructor works like the 145first, and uses its second argument to change the stream's attribute to 146the new <var>aspect_type</var> value given. The destructor restores the 147stream's attribute to the saved value. The restoration can be activated 148early (and often) with the <code>restore</code> member function.</p> 149 150<table border="1" align="center"> 151 <caption>Basic IOStreams State Saver Classes</caption> 152 <tr> 153 <th>Class</th> 154 <th>Saved Attribute</th> 155 <th>Attribute Type</th> 156 <th>Reading Method</th> 157 <th>Writing Method</th> 158 </tr> 159 <tr> 160 <td><code>boost::io::ios_flags_saver</code></td> 161 <td>Format control flags</td> 162 <td><code>std::ios_base::fmtflags</code></td> 163 <td><code>flags</code></td> 164 <td><code>flags</code></td> 165 </tr> 166 <tr> 167 <td><code>boost::io::ios_precision_saver</code></td> 168 <td>Number of digits to print after decimal point</td> 169 <td><code>std::streamsize</code></td> 170 <td><code>precision</code></td> 171 <td><code>precision</code></td> 172 </tr> 173 <tr> 174 <td><code>boost::io::ios_width_saver</code></td> 175 <td>Minimum field width for printing objects</td> 176 <td><code>std::streamsize</code></td> 177 <td><code>width</code></td> 178 <td><code>width</code></td> 179 </tr> 180</table> 181 182<h2><a name="adv_savers">Savers for Advanced Standard Attributes</a></h2> 183 184<p>The saver class templates have this format:</p> 185 186<blockquote><pre>template < typename Ch, class Tr > 187class <var>saver_class</var> 188{ 189 typedef std::basic_ios<Ch, Tr> state_type; 190 typedef <i>implementation_defined</i> aspect_type; 191 192 explicit saver_class( state_type &s ); 193 saver_class( state_type &s, <var>aspect_type</var> const &new_value ); 194 ~saver_class(); 195 196 void restore(); 197}; 198</pre></blockquote> 199 200<p>The <var>state_type</var> is a version of the IOStreams base class 201template <code>std::basic_ios<Ch, Tr></code>, where 202<code>Ch</code> is a character type and <code>Tr</code> is a character 203traits class. The user would usually place an actual input, output, or 204combined stream object for the state-type parameter, and not a base 205class object. The first constructor takes a stream object and saves a 206reference to the stream and the current value of a particular stream 207attribute. The second constructor works like the first, and uses its 208second argument to change the stream's attribute to the new 209<var>aspect_type</var> value given. The destructor restores the stream's 210attribute to the saved value. The restoration can be activated 211early (and often) with the <code>restore</code> member function.</p> 212 213<table border="1" align="center"> 214 <caption>Advanced IOStreams State Saver Class Templates</caption> 215 <tr> 216 <th>Class Template</th> 217 <th>Saved Attribute</th> 218 <th>Attribute Type</th> 219 <th>Reading Method</th> 220 <th>Writing Method</th> 221 </tr> 222 <tr> 223 <td><code>boost::io::basic_ios_iostate_saver<Ch, Tr></code></td> 224 <td>Failure state of the stream <a href="#Note1">[1]</a>, <a href="#Note2">[2]</a></td> 225 <td><code>std::ios_base::iostate</code></td> 226 <td><code>rdstate</code></td> 227 <td><code>clear</code></td> 228 </tr> 229 <tr> 230 <td><code>boost::io::basic_ios_exception_saver<Ch, Tr></code></td> 231 <td>Which failure states trigger an exception <a href="#Note1">[1]</a></td> 232 <td><code>std::ios_base::iostate</code></td> 233 <td><code>exceptions</code></td> 234 <td><code>exceptions</code></td> 235 </tr> 236 <tr> 237 <td><code>boost::io::basic_ios_tie_saver<Ch, Tr></code></td> 238 <td>Output stream synchronized with the stream</td> 239 <td><code>std::basic_ostream<Ch, Tr> *</code></td> 240 <td><code>tie</code></td> 241 <td><code>tie</code></td> 242 </tr> 243 <tr> 244 <td><code>boost::io::basic_ios_rdbuf_saver<Ch, Tr></code></td> 245 <td>Stream buffer associated with the stream <a href="#Note2">[2]</a></td> 246 <td><code>std::basic_streambuf<Ch, Tr> *</code></td> 247 <td><code>rdbuf</code></td> 248 <td><code>rdbuf</code></td> 249 </tr> 250 <tr> 251 <td><code>boost::io::basic_ios_fill_saver<Ch, Tr></code></td> 252 <td>Character used to pad oversized field widths</td> 253 <td><code>Ch</code></td> 254 <td><code>fill</code></td> 255 <td><code>fill</code></td> 256 </tr> 257 <tr> 258 <td><code>boost::io::basic_ios_locale_saver<Ch, Tr></code></td> 259 <td>Locale information associated with the stream <a href="#Note3">[3]</a></td> 260 <td><code>std::locale</code></td> 261 <td><code>getloc</code> (from <code>std::ios_base</code>)</td> 262 <td><code>imbue</code> (from <code>std::basic_ios<Ch, Tr></code>)</td> 263 </tr> 264</table> 265 266<h3>Notes</h3> 267 268<ol> 269 <li>When the failure state flags and/or the failure state exception 270 watching flags are changed, an exception is thrown if a match 271 occurs among the two sets of flags. This could mean that 272 the <a name="Note1">constructor or destructor of these class 273 templates may throw</a>.</li> 274 <li>When the associated stream buffer is changed, the stream's 275 failure state set is reset to "good" if the given stream 276 buffer's address is non-NULL, but the "bad" failure 277 state is set if that address is NULL. This means that a saved 278 failure state of "good" may be restored as "bad" 279 if the stream is stripped of an associated stream buffer. Worse, 280 given a NULL stream buffer address, an exception is thrown if the 281 "bad" failure state is being watched. This could mean 282 that the <a name="Note2">constructor or destructor of these class 283 templates may throw</a>.</li> 284 <li>The <a name="Note3">saver for the locale uses the 285 <code>std::basic_ios<Ch, Tr></code> class to extract their 286 information</a>, although it could have used the functionality 287 in <code>std::ios_base</code>. The problem is that the versions 288 of the needed member functions in <code>ios_base</code> are not 289 polymorphically related to the ones in <code>basic_ios</code>. 290 The stream classes that will be used with the saver classes 291 should use the versions of the member functions closest to them 292 by inheritance, which means the ones in 293 <code>basic_ios</code>.</li> 294</ol> 295 296<h2><a name="user_savers">Savers for User-Defined Attributes</a></h2> 297 298<p>The saver classes for user-defined formatting information have this 299format:</p> 300 301<blockquote><pre>#include <iosfwd> <i>// for std::ios_base (declaration)</i> 302 303class <var>saver_class</var> 304{ 305 typedef std::ios_base state_type; 306 typedef int index_type; 307 typedef <i>implementation_defined</i> aspect_type; 308 309 explicit saver_class( state_type &s, index_type i ); 310 saver_class( state_type &s, index_type i, <var>aspect_type</var> const &new_value ); 311 ~saver_class(); 312 313 void restore(); 314}; 315</pre></blockquote> 316 317<p>The index <var>i</var> differentiates between specific user-defined 318formatting attributes. The index can only be determined at run-time 319(most likely with the class-static <code>std::ios_base::xalloc</code> 320member function).</p> 321 322<p>The <var>state_type</var> is the base class of the IOStreams system, 323<code>std::ios_base</code>. The user would usually place an actual 324input, output, or combined stream object for the state-type parameter, 325and not a base class object. The first constructor takes a stream 326object and index and saves a reference to the stream and the current 327value of a particular stream attribute. The second constructor works 328like the first, and uses its third argument to change the stream's 329attribute to the new <var>aspect_type</var> value given. The destructor 330restores the stream's attribute to the saved value. The restoration can 331be activated early (and often) with the <code>restore</code> member 332function.</p> 333 334<table border="1" align="center"> 335 <caption>IOStream User-Defined State Saver Classes</caption> 336 <tr> 337 <th>Class</th> 338 <th>Saved Attribute</th> 339 <th>Attribute Type</th> 340 <th>Reference Method</th> 341 </tr> 342 <tr> 343 <td><code>boost::io::ios_iword_saver</code></td> 344 <td>Numeric user-defined format flag</td> 345 <td><code>long</code></td> 346 <td><code>iword</code></td> 347 </tr> 348 <tr> 349 <td><code>boost::io::ios_pword_saver</code></td> 350 <td>Pointer user-defined format flag</td> 351 <td><code>void *</code></td> 352 <td><code>pword</code></td> 353 </tr> 354</table> 355 356<h2><a name="combo_savers">Savers for Combined Attributes</a></h2> 357 358<p>There are three class (templates) for combined attribute savers. The 359<code>boost:io::ios_base_all_saver</code> saver class combines the 360functionality of all the basic attribute saver classes. It has a 361constructor that takes the stream to have its state preserved. The 362<code>boost::io::basic_ios_all_saver</code> combines the functionality 363of all the advanced attribute saver class templates and the combined 364basic attribute saver class. It has a constructor that takes the stream 365to have its state preserved. The 366<code>boost::io::ios_all_word_saver</code> saver class combines the 367saver classes that preserve user-defined formatting information. Its 368constructor takes the stream to have its attributes saved and the index 369of the user-defined attributes. The destructor for each class restores 370the saved state. Restoration can be activated early (and often) for a 371class with the <code>restore</code> member function.</p> 372 373<h2><a name="example">Example</a></h2> 374 375<p>The code used in the <a href="#rationale">rationale</a> can be 376improved at two places. The printing function could use a saver around 377the code that changes the formatting state. Or the calling function can 378surround the call with a saver. Or both can be done, especially if the 379user does not know if the printing function uses a state saver. If the 380user wants a series of changes back & forth, without surrounding each 381change within a separate block, the <code>restore</code> member function 382can be called between each trial.</p> 383 384<blockquote><pre>#include <boost/io/ios_state.hpp> 385#include <ios> 386#include <iostream> 387#include <ostream> 388 389void new_hex_my_byte( std::ostream &os, char byte ) 390{ 391 boost::io::ios_flags_saver ifs( os ); 392 393 os << std::hex << static_cast<unsigned>(byte); 394} 395 396int main() 397{ 398 using std::cout; 399 using std::cerr; 400 401 //... 402 403 { 404 boost::io::ios_all_saver ias( cout ); 405 406 new_hex_my_byte( cout, 'A' ); 407 } 408 409 //... 410 411 { 412 boost::io::ios_all_saver ias( cerr ); 413 414 new_hex_my_byte( cerr, 'b' ); 415 ias.restore(); 416 new_hex_my_byte( cerr, 'C' ); 417 } 418 419 //... 420} 421</pre></blockquote> 422 423<h2><a name="refer">References</a></h2> 424 425<ul> 426 <li>The I/O state saver library header itself: <cite><a 427 href="../../../boost/io/ios_state.hpp">boost/io/ios_state.hpp</a></cite></li> 428 <li>Some test/example code: <cite><a 429 href="../test/ios_state_test.cpp">ios_state_test.cpp</a></cite></li> 430</ul> 431 432<h2><a name="credits">Credits</a></h2> 433 434<h3><a name="contributors">Contributors</a></h3> 435 436<dl> 437 <dt><a href="http://www.boost.org/people/daryle_walker.html">Daryle Walker</a> 438 <dd>Started the library. Contributed the initial versions of the 439 format flags, precision, width, and user-defined format flags 440 saver classes. Contributed the initial versions of the success 441 state, success state exception flags, output stream tie, stream 442 buffer, character fill, and locale saver class templates. 443 Contributed the combined attribute classes and class template. 444 Contributed the test file <cite><a 445 href="../test/ios_state_test.cpp">ios_state_test.cpp</a></cite>. 446</dl> 447 448<h3><a name="history">History</a></h3> 449 450<dl> 451 <dt>28 Feb 2005, Daryle Walker 452 <dd>Added the <code>restore</code> member functions, based on suggestions 453 by Gennadiy Rozental and Rob Stewart 454 455 <dt>13 Mar 2002, Daryle Walker 456 <dd>Initial version 457</dl> 458 459<hr> 460 461<p>Revised: 28 February 2005</p> 462 463<p>Copyright 2002, 2005 Daryle Walker. Use, modification, and distribution 464are subject to the Boost Software License, Version 1.0. (See accompanying 465file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a copy at 466<<a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>>.)</p> 467</body> 468</html> 469