There are two possible solutions. If you are processing a large output block that uses the same formatting options, you can use something like this:
class IOSave { std::ios& myStream; std::ios::fmtflags myFlags; std::streamsize myPrecision; char myFill; public: IOSave( std::ios& userStream ) : myStream( userStream ) , myFlags( userStream.flags() ) , myPrecision( userStream.precision() ) , myFill( userStream.fill() ) { } ~IOSave() { myStream.flags( myFlags ); myStream.precision( myPrecision ); myStream.fill( myFill ); } };
Just define an instance of it at the top of the block that performs the output.
In most cases, I will define my own manipulator, which comes from something like:
class StateSavingManipulator { mutable std::ios* myStream; mutable std::ios::fmtflags mySavedFlags; mutable int mySavedPrec; mutable char mySavedFill; virtual void setState( std::ios& stream ) const = 0 ; protected: StateSavingManipulator(); public: virtual ~StateSavingManipulator(); void operator()( std::ios& stream ) const ; }; inline std::ostream& operator<<( std::ostream& out, StateSavingManip const& manip) { manip( out ) ; return out ; } inline std::istream& operator>>( std::istream& in, StateSavingManip const& manip ) { manip( in ) ; return in ; }
The implementation is a bit complicated, since you have to consider that if several manipulators are used in one expression, the compiler can build them (and thus destroy them) in any order. So:
namespace { int getXAlloc() ; int ourXAlloc = getXAlloc() + 1 ; int getXAlloc() { if ( ourXAlloc == 0 ) { ourXAlloc = std::ios::xalloc() + 1 ; assert( ourXAlloc != 0 ) ; } return ourXAlloc - 1 ; } } StateSavingManipulator::StateSavingManipulator() : myStream( NULL ) { } StateSavingManipulator::~StateSavingManipulator() { if ( myStream != NULL ) { myStream->flags( mySavedFlags ) ; myStream->precision( mySavedPrec ) ; myStream->fill( mySavedFill ) ; myStream->pword( getXAlloc() ) = NULL ; } } void StateSavingManipulator::operator()( std::ios& stream ) const { void*& backptr = stream.pword( getXAlloc() ) ; if ( backptr == NULL ) { backptr = const_cast< StateSavingManip* >( this ) ; myStream = &stream ; mySavedFlags = stream.flags() ; mySavedPrec = stream.precision() ; mySavedFill = stream.fill() ; } setState( stream ) ; }
The resulting manipulator then does everything it needs when implementing setState . Given this, you can write things like:
std::cout << FFmt( 6, 2 ) << someValue << std::endl;
without worrying about saving and restoring the formatting state.
source share