/* Check cf5-opt.vim defs.
VIM: let g:lcppflags="-std=c++11 -O2 -pthread"
VIM: let g:wcppflags="/O2 /EHsc /DWIN32"
VIM: let g:cppflags=g:Iboost.g:Itbb
VIM: let g:ldflags=g:Lboost.g:Ltbb.g:tbbmalloc.g:tbbmproxy
VIM: let g:ldlibpath=g:Bboost.g:Btbb
VIM: let g:argv=""
VIM-: let g:cf5output=0
*/
#include <iostream>
#include <exception>

/*
 	This experiment proves that catching an exception by reference
	is more effective since it eliminates unneeded copy.

	Also re-throwing an exception throws the original exception but not
	the exception caught.
*/
struct ex
{
	mutable int v;

	ex()
		: v(0)
	{
		std::cout << "ex::default" << std::endl;
	}
	ex( const ex& e )
		: v(e.v)
	{
		std::cout << "ex::copy" << std::endl;
	}
	
	ex& operator = ( const ex& e )
	{
		v = e.v;
		std::cout << "ex::op =" << std::endl;
	}
};

void a ()
{
	throw ex();
}

void b ()
try {
	a();
} catch(ex& e) {
	e.v |= 1;
	throw;
}

void c ()
try {
	b();
} catch(const ex& e) {
	e.v |= 2;
	throw;
}

void d ()
try {
	c();
} catch( ex e) {
	e.v |= 4;
	throw;
}


int main ( void )
{
	try
	{
		d();
	}
	catch ( const ex& e )
	{
		std::cout << e.v << std::endl;
	}

	return 0;
}

