fork download
  1. #include <exception>
  2. #include <iostream>
  3. #include <ostream>
  4. #include <string>
  5.  
  6. using namespace std;
  7.  
  8. // ________________ uncaught_exception_count implementation ________________
  9.  
  10. #if defined(_MSC_VER)
  11. extern "C" char * _getptd();
  12. int uncaught_exception_count()
  13. {
  14. // MSVC specific. Tested on MSVC2010SP1 x32 and x64.
  15. return *(static_cast<int*>(static_cast<void*>( _getptd() + (sizeof(void*)==8 ? 0x100 : 0x90) ))); // x32 offset - 0x90 , x64 - 0x100
  16. }
  17. #elif defined(__GNUG__)
  18. extern "C" char * __cxa_get_globals();
  19. int uncaught_exception_count()
  20. {
  21. return *(static_cast<int*>(static_cast<void*>( __cxa_get_globals() + (sizeof(void*)==8 ? 0x8 : 0x4) ))); // x32 offset - 0x4 , x64 - 0x8
  22. }
  23. #endif
  24.  
  25. // ________________ uncaught_exception_count test __________________________
  26. struct T800
  27. {
  28. ~T800()
  29. {
  30. cout << "uncaught_exception_count=" << uncaught_exception_count() << endl;
  31. }
  32. };
  33.  
  34. struct ThrowableDestructor
  35. {
  36. ~ThrowableDestructor()
  37. {
  38. throw 0;
  39. }
  40. };
  41.  
  42. template<typename FirstScoped, typename SecondScoped=ThrowableDestructor>
  43. struct ExptSwallower
  44. {
  45. ~ExptSwallower()
  46. {
  47. try
  48. {
  49. FirstScoped a;
  50. SecondScoped b;
  51. }catch(...){}
  52. }
  53. };
  54.  
  55. void uncaught_exception_count_demo()
  56. {
  57. T800 a;
  58. ExptSwallower<T800> b;
  59. ExptSwallower<ExptSwallower<T800> > c;
  60. ExptSwallower<ExptSwallower<ExptSwallower<T800> > > d;
  61. ExptSwallower<ExptSwallower<ExptSwallower<ExptSwallower<T800> > > > e;
  62. }
  63.  
  64. // ________________ Advanced Scope Guard ___________________________________
  65.  
  66. // Refer Andrei Alexandrescu talk at:
  67. // http://c...content-available-to-author-only...n.com/Events/Lang-NEXT/Lang-NEXT-2012/Three-Unlikely-Successful-Features-of-D
  68. class DLikeScopeGuard
  69. {
  70. int exception_enter_state;
  71. public:
  72. DLikeScopeGuard()
  73. {
  74. exception_enter_state=uncaught_exception_count();
  75. }
  76. void scope_success()
  77. {
  78. cout << "scope_success" << endl;
  79. }
  80. void scope_failure()
  81. {
  82. cout << "scope_failure" << endl;
  83. }
  84. void scope_exit()
  85. {
  86. cout << "scope_exit" << endl;
  87. }
  88. ~DLikeScopeGuard()
  89. {
  90. if(exception_enter_state==uncaught_exception_count())
  91. scope_success();
  92. else
  93. scope_failure();
  94. scope_exit();
  95. }
  96. };
  97.  
  98. void scope_guard_demo()
  99. {
  100. {
  101. cout << endl << "no exception:" << endl;
  102. DLikeScopeGuard success;
  103. }
  104. try
  105. {
  106. cout << endl << "basic throw:" << endl;
  107. DLikeScopeGuard fail;
  108. throw 0;
  109. }catch(...){}
  110. try
  111. {
  112. cout << endl << "fail in previous destructor:" << endl;
  113. DLikeScopeGuard fail;
  114. ThrowableDestructor d;
  115. }catch(...){}
  116. try
  117. {
  118. cout << endl << "fail in next destructor:" << endl;
  119. ThrowableDestructor d;
  120. DLikeScopeGuard success;
  121. }catch(...){}
  122. try
  123. {
  124. cout << endl << "ExptSwallower<DLikeScopeGuard,ThrowableDestructor> during throw:" << endl;
  125. ExptSwallower<DLikeScopeGuard,ThrowableDestructor> fail;
  126. throw 0;
  127. }catch(...){}
  128. try
  129. {
  130. cout << endl << "ExptSwallower<ThrowableDestructor,DLikeScopeGuard> during throw:" << endl;
  131. ExptSwallower<ThrowableDestructor,DLikeScopeGuard> fail;
  132. throw 0;
  133. }catch(...){}
  134. try
  135. {
  136. cout << endl << "ExptSwallower<DLikeScopeGuard,int> during throw:" << endl;
  137. ExptSwallower<DLikeScopeGuard,int> success;
  138. throw 0;
  139. }catch(...){}
  140. }
  141.  
  142. int main(int argc,char *argv[])
  143. {
  144. cout << "uncaught_exception_count demo:" << endl << endl;
  145. uncaught_exception_count_demo();
  146. cout << std::string(25,'_') << endl;
  147. cout << "scope_guard demo:" << endl;
  148. scope_guard_demo();
  149. return 0;
  150. }
  151.  
  152.  
Success #stdin #stdout 0.01s 2860KB
stdin
Standard input is empty
stdout
uncaught_exception_count demo:

uncaught_exception_count=4
uncaught_exception_count=3
uncaught_exception_count=2
uncaught_exception_count=1
uncaught_exception_count=0
_________________________
scope_guard demo:

no exception:
scope_success
scope_exit

basic throw:
scope_failure
scope_exit

fail in previous destructor:
scope_failure
scope_exit

fail in next destructor:
scope_success
scope_exit

ExptSwallower<DLikeScopeGuard,ThrowableDestructor> during throw:
scope_failure
scope_exit

ExptSwallower<ThrowableDestructor,DLikeScopeGuard> during throw:
scope_success
scope_exit

ExptSwallower<DLikeScopeGuard,int> during throw:
scope_success
scope_exit