124 lines
4.1 KiB
C++
124 lines
4.1 KiB
C++
/**************************************************************************
|
|
*
|
|
* fmtflags_manip.cpp - Example program demonstrating the implementation
|
|
* of a user-defined manipulator for convenient and exception-safe setting
|
|
* and restoring of stream formatting flags.
|
|
*
|
|
* $Id: fmtflags_manip.cpp 648752 2008-04-16 17:01:56Z faridz $
|
|
*
|
|
***************************************************************************
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* permissions and limitations under the License.
|
|
*
|
|
**************************************************************************/
|
|
|
|
#include <ios> // for hex
|
|
#include <iomanip> // for __rw_smanip
|
|
#include <iostream> // for cout
|
|
|
|
#include <examples.h>
|
|
|
|
|
|
// implementation class of the fmtflags manipulator that saves
|
|
// a stream object's fmtflags state before optionally setting
|
|
// their new value and restores the saved state when destroyed
|
|
// uses ios::basefield as an invalid flags value (it's a valid
|
|
// mask but not a valid flags value)
|
|
class fmtflags_manip
|
|
{
|
|
std::ios_base *strm_;
|
|
std::ios_base::fmtflags saved_;
|
|
|
|
public:
|
|
fmtflags_manip (): strm_ (), saved_ (std::ios_base::basefield) { }
|
|
|
|
void operator() (std::ios_base &strm,
|
|
std::ios_base::fmtflags flags) const {
|
|
|
|
const_cast<fmtflags_manip*>(this)->strm_ = &strm;
|
|
const_cast<fmtflags_manip*>(this)->saved_ = strm.flags ();
|
|
|
|
if (flags != std::ios_base::basefield)
|
|
strm.flags (flags);
|
|
}
|
|
|
|
~fmtflags_manip () {
|
|
if (strm_)
|
|
strm_->flags (saved_);
|
|
}
|
|
};
|
|
|
|
|
|
// saveflags manipulator to temporarily set formatting flags and
|
|
// restore their initial value at the end of an insertion statement
|
|
inline std::__rw_smanip<fmtflags_manip, std::ios_base::fmtflags>
|
|
saveflags (std::ios_base::fmtflags flags = std::ios_base::basefield)
|
|
{
|
|
typedef std::__rw_smanip<fmtflags_manip, std::ios_base::fmtflags> Manip;
|
|
|
|
return Manip (flags);
|
|
}
|
|
|
|
|
|
// dummy class whose insertion operator always throws
|
|
struct BadClass { };
|
|
|
|
|
|
inline std::ostream&
|
|
operator<< (std::ostream &strm, BadClass&)
|
|
{
|
|
// inserter that always throws an exception
|
|
return throw "exception", strm;
|
|
|
|
}
|
|
|
|
|
|
int main ()
|
|
{
|
|
try {
|
|
BadClass throw_exception;
|
|
|
|
// use the saveflags manipulator to set the formatting flags
|
|
// for the rest of this insertion statement only and have it
|
|
// restore the previous flags at the end of the statement
|
|
// or on exception
|
|
std::cout << saveflags (std::cout.hex)
|
|
<< std::showbase
|
|
<< "hex 1234: " << 0x1234 << '\n'
|
|
<< "hex 2345: " << 0x2345 << '\n'
|
|
<< throw_exception // inserting will throw
|
|
<< "never output!"; // this string is never output
|
|
}
|
|
catch (...) {
|
|
// show that default formatting flags (decimal output and no
|
|
// showbase) have been restored during stack unwinding above
|
|
std::cout << "dec 3456: " << 3456 << '\n'
|
|
<< std::oct
|
|
<< "oct 4567: " << 04567 << '\n';
|
|
}
|
|
|
|
// use ordinary manipulators to set hex output with base prefix
|
|
std::cout << std::hex << std::showbase
|
|
<< "hex 5678: " << 0x5678 << '\n'
|
|
<< "hex 6789: " << 0x6789 << '\n';
|
|
|
|
// the same flags set above are still in effect
|
|
std::cout << "hex 789a: " << 0x789a << '\n';
|
|
|
|
return 0;
|
|
}
|