#include <exception>
#include <iostream>
#include <ostream>
#include <string>
using namespace std;
// ________________ uncaught_exception_count implementation ________________
#if defined(_MSC_VER)
extern "C" char * _getptd();
int uncaught_exception_count()
{
// MSVC specific. Tested on MSVC2010SP1 x32 and x64.
return *(static_cast<int*>(static_cast<void*>( _getptd() + (sizeof(void*)==8 ? 0x100 : 0x90) ))); // x32 offset - 0x90 , x64 - 0x100
}
#elif defined(__GNUG__)
extern "C" char * __cxa_get_globals();
int uncaught_exception_count()
{
return *(static_cast<int*>(static_cast<void*>( __cxa_get_globals() + (sizeof(void*)==8 ? 0x8 : 0x4) ))); // x32 offset - 0x4 , x64 - 0x8
}
#endif
// ________________ uncaught_exception_count test __________________________
struct T800
{
~T800()
{
cout << "uncaught_exception_count=" << uncaught_exception_count() << endl;
}
};
struct ThrowableDestructor
{
~ThrowableDestructor()
{
throw 0;
}
};
template<typename FirstScoped, typename SecondScoped=ThrowableDestructor>
struct ExptSwallower
{
~ExptSwallower()
{
try
{
FirstScoped a;
SecondScoped b;
}catch(...){}
}
};
void uncaught_exception_count_demo()
{
T800 a;
ExptSwallower<T800> b;
ExptSwallower<ExptSwallower<T800> > c;
ExptSwallower<ExptSwallower<ExptSwallower<T800> > > d;
ExptSwallower<ExptSwallower<ExptSwallower<ExptSwallower<T800> > > > e;
}
// ________________ Advanced Scope Guard ___________________________________
// Refer Andrei Alexandrescu talk at:
// http://c...content-available-to-author-only...n.com/Events/Lang-NEXT/Lang-NEXT-2012/Three-Unlikely-Successful-Features-of-D
class DLikeScopeGuard
{
int exception_enter_state;
public:
DLikeScopeGuard()
{
exception_enter_state=uncaught_exception_count();
}
void scope_success()
{
cout << "scope_success" << endl;
}
void scope_failure()
{
cout << "scope_failure" << endl;
}
void scope_exit()
{
cout << "scope_exit" << endl;
}
~DLikeScopeGuard()
{
if(exception_enter_state==uncaught_exception_count())
scope_success();
else
scope_failure();
scope_exit();
}
};
void scope_guard_demo()
{
{
cout << endl << "no exception:" << endl;
DLikeScopeGuard success;
}
try
{
cout << endl << "basic throw:" << endl;
DLikeScopeGuard fail;
throw 0;
}catch(...){}
try
{
cout << endl << "fail in previous destructor:" << endl;
DLikeScopeGuard fail;
ThrowableDestructor d;
}catch(...){}
try
{
cout << endl << "fail in next destructor:" << endl;
ThrowableDestructor d;
DLikeScopeGuard success;
}catch(...){}
try
{
cout << endl << "ExptSwallower<DLikeScopeGuard,ThrowableDestructor> during throw:" << endl;
ExptSwallower<DLikeScopeGuard,ThrowableDestructor> fail;
throw 0;
}catch(...){}
try
{
cout << endl << "ExptSwallower<ThrowableDestructor,DLikeScopeGuard> during throw:" << endl;
ExptSwallower<ThrowableDestructor,DLikeScopeGuard> fail;
throw 0;
}catch(...){}
try
{
cout << endl << "ExptSwallower<DLikeScopeGuard,int> during throw:" << endl;
ExptSwallower<DLikeScopeGuard,int> success;
throw 0;
}catch(...){}
}
int main(int argc,char *argv[])
{
cout << "uncaught_exception_count demo:" << endl << endl;
uncaught_exception_count_demo();
cout << std::string(25,'_') << endl;
cout << "scope_guard demo:" << endl;
scope_guard_demo();
return 0;
}