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