#include <iostream>
#include <sstream>
using namespace std;
void badFunc(std::stringstream& s)
{
int len = s.str().length();
cout << "badFunc(in operator << ) : length = " << len << " " << s.str().c_str() << endl;
if ( 20 <= len)
{
cout << " => exception!(over 20)" << endl;
throw "operator <<";
}
}
void doSomething(std::stringstream& s)
{
int len = s.str().length();
cout << "doSomething(in destructor) : length = " << len << " " << s.str().c_str() << endl;
if ( 15 <= len )
{
cout << " => exception!(over 15)" << endl;
throw "destructor";
}
}
class Temporary_t {
std::stringstream& sstr; //not own resource
bool safe;
Temporary_t(std::stringstream& s) : sstr(s), safe(false) { sstr.str(""); }
Temporary_t(const Temporary_t&);
Temporary_t& operator =(const Temporary_t&);
public:
~Temporary_t() throw(int) { if ( safe ) doSomething(sstr); }
template<typename T> Temporary_t& operator << (const T& data)
{ safe = false; sstr << data; badFunc(sstr); safe = true; return *this; }
friend Temporary_t temporary_t(std::stringstream& s);
};
Temporary_t temporary_t(std::stringstream& s) { return Temporary_t(s); }
int main()
{
std::stringstream s;
try {
temporary_t(s) << "ABCD " << 1234;
throw "other";
}
catch (const char* e) { cout << "catch " << e << endl << endl; }
try {
temporary_t(s) << "ABCDEFGHIJ " << 1234567890;
throw "other";
}
catch (const char* e) { cout << "catch " << e << endl << endl; }
try {
temporary_t(s) << "ABCDEFGHI " << 123456789;
throw "other";
}
catch (const char* e) { cout << "catch " << e << endl; }
catch (...) { cout << "catch else"; }
return 0;
}