Added 'restore' member function to recover state (multiple times) within a code block

[SVN r27520]
This commit is contained in:
Daryle Walker
2005-02-28 19:41:10 +00:00
parent 84d932365a
commit 3bcf03e985
2 changed files with 85 additions and 13 deletions

View File

@@ -131,6 +131,8 @@ class ios_all_word_saver;
explicit saver_class( state_type &s ); explicit saver_class( state_type &s );
saver_class( state_type &amp;s, <var>aspect_type</var> const &amp;new_value ); saver_class( state_type &amp;s, <var>aspect_type</var> const &amp;new_value );
~saver_class(); ~saver_class();
void restore();
}; };
</pre></blockquote> </pre></blockquote>
@@ -141,8 +143,9 @@ and not a base class object. The first constructor takes a stream
object and saves a reference to the stream and the current value of a object and saves a reference to the stream and the current value of a
particular stream attribute. The second constructor works like the particular stream attribute. The second constructor works like the
first, and uses its second argument to change the stream's attribute to first, and uses its second argument to change the stream's attribute to
the new <var>aspect_type</var> value given. The destructor changes the the new <var>aspect_type</var> value given. The destructor restores the
stream's attribute back to the saved value.</p> stream's attribute to the saved value. The restoration can be activated
early (and often) with the <code>restore</code> member function.</p>
<table border="1" align="center"> <table border="1" align="center">
<caption>Basic IOStreams State Saver Classes</caption> <caption>Basic IOStreams State Saver Classes</caption>
@@ -189,6 +192,8 @@ class <var>saver_class</var>
explicit saver_class( state_type &amp;s ); explicit saver_class( state_type &amp;s );
saver_class( state_type &amp;s, <var>aspect_type</var> const &amp;new_value ); saver_class( state_type &amp;s, <var>aspect_type</var> const &amp;new_value );
~saver_class(); ~saver_class();
void restore();
}; };
</pre></blockquote> </pre></blockquote>
@@ -201,8 +206,9 @@ class object. The first constructor takes a stream object and saves a
reference to the stream and the current value of a particular stream reference to the stream and the current value of a particular stream
attribute. The second constructor works like the first, and uses its attribute. The second constructor works like the first, and uses its
second argument to change the stream's attribute to the new second argument to change the stream's attribute to the new
<var>aspect_type</var> value given. The destructor changes the stream's <var>aspect_type</var> value given. The destructor restores the stream's
attribute back to the saved value.</p> attribute to the saved value. The restoration can be activated
early (and often) with the <code>restore</code> member function.</p>
<table border="1" align="center"> <table border="1" align="center">
<caption>Advanced IOStreams State Saver Class Templates</caption> <caption>Advanced IOStreams State Saver Class Templates</caption>
@@ -303,6 +309,8 @@ class <var>saver_class</var>
explicit saver_class( state_type &amp;s, index_type i ); explicit saver_class( state_type &amp;s, index_type i );
saver_class( state_type &amp;s, index_type i, <var>aspect_type</var> const &amp;new_value ); saver_class( state_type &amp;s, index_type i, <var>aspect_type</var> const &amp;new_value );
~saver_class(); ~saver_class();
void restore();
}; };
</pre></blockquote> </pre></blockquote>
@@ -319,7 +327,9 @@ object and index and saves a reference to the stream and the current
value of a particular stream attribute. The second constructor works value of a particular stream attribute. The second constructor works
like the first, and uses its third argument to change the stream's like the first, and uses its third argument to change the stream's
attribute to the new <var>aspect_type</var> value given. The destructor attribute to the new <var>aspect_type</var> value given. The destructor
changes the stream's attribute back to the saved value.</p> restores the stream's attribute to the saved value. The restoration can
be activated early (and often) with the <code>restore</code> member
function.</p>
<table border="1" align="center"> <table border="1" align="center">
<caption>IOStream User-Defined State Saver Classes</caption> <caption>IOStream User-Defined State Saver Classes</caption>
@@ -356,15 +366,20 @@ to have its state preserved. The
<code>boost::io::ios_all_word_saver</code> saver class combines the <code>boost::io::ios_all_word_saver</code> saver class combines the
saver classes that preserve user-defined formatting information. Its saver classes that preserve user-defined formatting information. Its
constructor takes the stream to have its attributes saved and the index constructor takes the stream to have its attributes saved and the index
of the user-defined attributes.</p> of the user-defined attributes. The destructor for each class restores
the saved state. Restoration can be activated early (and often) for a
class with the <code>restore</code> member function.</p>
<h2><a name="example">Example</a></h2> <h2><a name="example">Example</a></h2>
<p>The code used in the <a href="#rationale">rationale</a> can be <p>The code used in the <a href="#rationale">rationale</a> can be
improved at two places. The printing function could use a saver around improved at two places. The printing function could use a saver around
the code that changes the formatting state. Or the calling function can the code that changes the formatting state. Or the calling function can
surround the call with a saver. Or both can be done for paranoia's surround the call with a saver. Or both can be done, especially if the
sake.</p> user does not know if the printing function uses a state saver. If the
user wants a series of changes back &amp; forth, without surrounding each
change within a separate block, the <code>restore</code> member function
can be called between each trial.</p>
<blockquote><pre>#include &lt;boost/io/ios_state.hpp&gt; <blockquote><pre>#include &lt;boost/io/ios_state.hpp&gt;
#include &lt;ios&gt; #include &lt;ios&gt;
@@ -381,6 +396,7 @@ void new_hex_my_byte( std::ostream &amp;os, char byte )
int main() int main()
{ {
using std::cout; using std::cout;
using std::cerr;
//... //...
@@ -391,6 +407,16 @@ int main()
} }
//... //...
{
boost::io::ios_all_saver ias( cerr );
new_hex_my_byte( cerr, 'b' );
ias.restore();
new_hex_my_byte( cerr, 'C' );
}
//...
} }
</pre></blockquote> </pre></blockquote>
@@ -422,15 +448,19 @@ int main()
<h3><a name="history">History</a></h3> <h3><a name="history">History</a></h3>
<dl> <dl>
<dt>28 Feb 2005, Daryle Walker
<dd>Added the <code>restore</code> member functions, based on suggestions
by Gennadiy Rozental and Rob Stewart
<dt>13 Mar 2002, Daryle Walker <dt>13 Mar 2002, Daryle Walker
<dd>Initial version <dd>Initial version
</dl> </dl>
<hr> <hr>
<p>Revised: 13 March 2002</p> <p>Revised: 28 February 2005</p>
<p>Copyright 2002 Daryle Walker. Use, modification, and distribution <p>Copyright 2002, 2005 Daryle Walker. Use, modification, and distribution
are subject to the Boost Software License, Version 1.0. (See accompanying are subject to the Boost Software License, Version 1.0. (See accompanying
file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a copy at file <a href="../../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or a copy at
&lt;<a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>&gt;.)</p> &lt;<a href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>&gt;.)</p>

View File

@@ -1,8 +1,8 @@
// Boost io/ios_state.hpp header file --------------------------------------// // Boost io/ios_state.hpp header file --------------------------------------//
// Copyright 2002 Daryle Walker. Use, modification, and distribution are // Copyright 2002, 2005 Daryle Walker. Use, modification, and distribution
// subject to the Boost Software License, Version 1.0. (See accompanying file // are subject to the Boost Software License, Version 1.0. (See accompanying
// LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.) // file LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
// See <http://www.boost.org/libs/io/> for the library's home page. // See <http://www.boost.org/libs/io/> for the library's home page.
@@ -39,6 +39,9 @@ public:
: s_save_( s ), a_save_( s.flags(a) ) : s_save_( s ), a_save_( s.flags(a) )
{} {}
~ios_flags_saver() ~ios_flags_saver()
{ this->restore(); }
void restore()
{ s_save_.flags( a_save_ ); } { s_save_.flags( a_save_ ); }
private: private:
@@ -59,6 +62,9 @@ public:
: s_save_( s ), a_save_( s.precision(a) ) : s_save_( s ), a_save_( s.precision(a) )
{} {}
~ios_precision_saver() ~ios_precision_saver()
{ this->restore(); }
void restore()
{ s_save_.precision( a_save_ ); } { s_save_.precision( a_save_ ); }
private: private:
@@ -79,6 +85,9 @@ public:
: s_save_( s ), a_save_( s.width(a) ) : s_save_( s ), a_save_( s.width(a) )
{} {}
~ios_width_saver() ~ios_width_saver()
{ this->restore(); }
void restore()
{ s_save_.width( a_save_ ); } { s_save_.width( a_save_ ); }
private: private:
@@ -103,6 +112,9 @@ public:
: s_save_( s ), a_save_( s.rdstate() ) : s_save_( s ), a_save_( s.rdstate() )
{ s.clear(a); } { s.clear(a); }
~basic_ios_iostate_saver() ~basic_ios_iostate_saver()
{ this->restore(); }
void restore()
{ s_save_.clear( a_save_ ); } { s_save_.clear( a_save_ ); }
private: private:
@@ -124,6 +136,9 @@ public:
: s_save_( s ), a_save_( s.exceptions() ) : s_save_( s ), a_save_( s.exceptions() )
{ s.exceptions(a); } { s.exceptions(a); }
~basic_ios_exception_saver() ~basic_ios_exception_saver()
{ this->restore(); }
void restore()
{ s_save_.exceptions( a_save_ ); } { s_save_.exceptions( a_save_ ); }
private: private:
@@ -145,6 +160,9 @@ public:
: s_save_( s ), a_save_( s.tie(a) ) : s_save_( s ), a_save_( s.tie(a) )
{} {}
~basic_ios_tie_saver() ~basic_ios_tie_saver()
{ this->restore(); }
void restore()
{ s_save_.tie( a_save_ ); } { s_save_.tie( a_save_ ); }
private: private:
@@ -166,6 +184,9 @@ public:
: s_save_( s ), a_save_( s.rdbuf(a) ) : s_save_( s ), a_save_( s.rdbuf(a) )
{} {}
~basic_ios_rdbuf_saver() ~basic_ios_rdbuf_saver()
{ this->restore(); }
void restore()
{ s_save_.rdbuf( a_save_ ); } { s_save_.rdbuf( a_save_ ); }
private: private:
@@ -187,6 +208,9 @@ public:
: s_save_( s ), a_save_( s.fill(a) ) : s_save_( s ), a_save_( s.fill(a) )
{} {}
~basic_ios_fill_saver() ~basic_ios_fill_saver()
{ this->restore(); }
void restore()
{ s_save_.fill( a_save_ ); } { s_save_.fill( a_save_ ); }
private: private:
@@ -208,6 +232,9 @@ public:
: s_save_( s ), a_save_( s.imbue(a) ) : s_save_( s ), a_save_( s.imbue(a) )
{} {}
~basic_ios_locale_saver() ~basic_ios_locale_saver()
{ this->restore(); }
void restore()
{ s_save_.imbue( a_save_ ); } { s_save_.imbue( a_save_ ); }
private: private:
@@ -232,6 +259,9 @@ public:
: s_save_( s ), a_save_( s.iword(i) ), i_save_( i ) : s_save_( s ), a_save_( s.iword(i) ), i_save_( i )
{ s.iword(i) = a; } { s.iword(i) = a; }
~ios_iword_saver() ~ios_iword_saver()
{ this->restore(); }
void restore()
{ s_save_.iword( i_save_ ) = a_save_; } { s_save_.iword( i_save_ ) = a_save_; }
private: private:
@@ -254,6 +284,9 @@ public:
: s_save_( s ), a_save_( s.pword(i) ), i_save_( i ) : s_save_( s ), a_save_( s.pword(i) ), i_save_( i )
{ s.pword(i) = a; } { s.pword(i) = a; }
~ios_pword_saver() ~ios_pword_saver()
{ this->restore(); }
void restore()
{ s_save_.pword( i_save_ ) = a_save_; } { s_save_.pword( i_save_ ) = a_save_; }
private: private:
@@ -276,6 +309,9 @@ public:
{} {}
~ios_base_all_saver() ~ios_base_all_saver()
{ this->restore(); }
void restore()
{ {
s_save_.width( a3_save_ ); s_save_.width( a3_save_ );
s_save_.precision( a2_save_ ); s_save_.precision( a2_save_ );
@@ -303,6 +339,9 @@ public:
{} {}
~basic_ios_all_saver() ~basic_ios_all_saver()
{ this->restore(); }
void restore()
{ {
s_save_.imbue( a9_save_ ); s_save_.imbue( a9_save_ );
s_save_.fill( a8_save_ ); s_save_.fill( a8_save_ );
@@ -340,6 +379,9 @@ public:
{} {}
~ios_all_word_saver() ~ios_all_word_saver()
{ this->restore(); }
void restore()
{ {
s_save_.pword( i_save_ ) = a2_save_; s_save_.pword( i_save_ ) = a2_save_;
s_save_.iword( i_save_ ) = a1_save_; s_save_.iword( i_save_ ) = a1_save_;