#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;
}

