fork download
  1. #include <iostream>
  2. #include <string>
  3. #include <exception>
  4. #include <stdexcept>
  5. using namespace std;
  6.  
  7.  
  8. template<class F> class ScopeGuard
  9. {
  10. private:
  11. F f;
  12. bool active;
  13. public:
  14. ScopeGuard(F f) :f(::std::move(f)), active(true) {}
  15. ScopeGuard(ScopeGuard&& rhs) :f(::std::move(rhs.f)), active(rhs.active) { rhs.dismiss();}
  16. ~ScopeGuard() { if (active) f(); }
  17.  
  18. void dismiss() { active = false; }
  19.  
  20. ScopeGuard() = delete;
  21. ScopeGuard(const ScopeGuard&) = delete;
  22. ScopeGuard& operator=(const ScopeGuard&) = delete;
  23. };
  24.  
  25. template<class FF> static ScopeGuard<FF> makeScopeGuard(FF f) { return ScopeGuard<FF>(f); }
  26.  
  27. #define CONCAT_IMPL(s1, s2) s1##s2
  28. #define CONCAT(s1, s2) CONCAT_IMPL(s1, s2)
  29.  
  30. #define SCOPE_GUARD(lambda) \
  31.   auto CONCAT(scope_guard_, __LINE__)(makeScopeGuard(lambda)); \
  32.   (void)CONCAT(scope_guard_, __LINE__);
  33.  
  34.  
  35. void scopeExit(const string& name)
  36. {
  37. cout << "Exiting " << name << " scope "
  38. << (uncaught_exception() ? "(there was an exception)" : "(no exception)") << endl;
  39. }
  40.  
  41. int main()
  42. {
  43. SCOPE_GUARD([](){ scopeExit("main"); })
  44.  
  45. try
  46. {
  47. SCOPE_GUARD([](){ scopeExit("try"); })
  48. throw runtime_error("Spectacular failure!");
  49. }
  50. catch (const exception& e)
  51. {
  52. cout << e.what() << endl;
  53. }
  54.  
  55. return 0;
  56. }
  57.  
Success #stdin #stdout 0s 3232KB
stdin
Standard input is empty
stdout
Exiting try scope (there was an exception)
Spectacular failure!
Exiting main scope (no exception)