Boost logo

Boost :

From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2003-02-07 10:00:03


>From: "Jason House" <jhouse_at_[hidden]>

> Jason House wrote:
>
> > Terje Slettebø wrote:
> >
> > > Another possibility might be to have a sentry object, doing automatic
state
> > > saving and restoring in the constructor and destructor. In fact, there
are
> > > already such classes in Boost: Daryle Walker's I/O state savers, which
fits
> > > this situation like a glove.
> >
> > I think that I like your solution better :) putting it
constructor/deconstructor
> > does seem better. I can't even argue that it's more typing for
multi-line
> > expressions...
>
> Well, I know at least have more fuel to think about...
> First of all, does your constructor take the stream as an argument? It
would have to
> in order to do state saving in the constructor... If so, that at least
makes prevents
> the following case (that probably needs special handling)
> {
> io_format<> var1(...);
> std::cout << var1 << stuff;
> std::cerr << var1 << more_stuff;
> }
>
> My understanding is that the constructor would not perform state saving,
but that it
> is the call to << that has to perform the locking.

Right. In the example I had, << performed the saving. In that case, it would
have to check a save-flag in the destructor. One could also pass the stream
to it in the constructor, as you say.

> So what happens when multiple streams are used?

That's no problem. The format is set for a specific stream (each stream has
its own iword/pword for the type to be output). So for the free-standing
saver, it would need to take the stream as a constructor argument.

> what happens when you have 2 or more io_formats in the same function used
on the same
> stream?
> example
> {
> io_format<T> var1(...), var2(...);
> std:: cout << var1 << stuff1;
> std::cout << var2 << stuff2;
> std::cout << var1 << stuff3;
> std::cout << var2 << stuff4;
> std::cout << io_format<T>(...) << stuff5;
> } /* deconstruct all 3 io_format<T>'s ... not necessarilly in the right
order! */

This should work just fine. When the manipulator is used, it sets the format
given by it. When a new manipulator is used, it changes the format to the
new one. Also, the language ensures that the objects are destroyed in the
reverse order of creation, so they will all be deleted after the last
statement above.

> Here, var1, var2, and the unnamed class from the last line in the function
are all
> being deconstructed at the same time. Some caution needs to occur here.

Well, as this version of them just sets the format, and doesn't do anything
in the destructor, their order of destruction doesn't matter for the output.

> Is that what the state-saver class you referred to does already?

That one does the restoring in the destructor. If we used the combined
setter/saver/restorer I mentioned in the posting I just sent, them only the
first of the above formats (var1), needed to save the format, to ensure that
the format wasn't changed by the output statements.

Regards,

Terje


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk