#include <typeinfo>
#include <exception>
#include <iostream>

using namespace std;

struct T {virtual ~T(){}};
struct A {virtual ~A(){}};
void f () throw(std::bad_exception, A)
{
	throw T();
}

void my_unexpected ()
{
	if (!std::uncaught_exception())
		std::cerr << "my_unexpected called\n";
	throw;
}

void my_terminate ()
{
	std::cerr << "my_terminate called\n";
}

int main()
{
	T* n = 0;
	try {
		cout << typeid(*n).name() << endl;
	} catch (bad_typeid e) {
		cerr << "Type Exception " << e.what() << endl;
	}

	A * p = new A;
	n = dynamic_cast<T*> (p);
	if (n==0) cerr << "Cast Null" << endl;
	delete p;

	try {
		n = new T;
		T &c = (*n);
		A &r = dynamic_cast<A&> (c);
		delete n;
	} catch (bad_cast e) {
		cerr << "Cast Exception " << e.what() << endl;
		delete n;
	}

	std::set_unexpected (my_unexpected);
	std::set_terminate (my_terminate);
	try {
		f(); // does not meet a function's throw specification
	} catch (T e)
	{
		cerr << "Catched T" << endl;
	} catch (bad_exception e) {
		cerr << "Unexpected Exception " << e.what() << endl;
	}
	
	try {
		while (true) new char [10000];
	} catch (bad_alloc e) {
		cerr << "Alloc Exception " << e.what() << endl;
	}
}

