ScopeExit.h 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. #pragma once
  2. #include <type_traits>
  3. #include <utility>
  4. namespace c10 {
  5. /**
  6. * Mostly copied from https://llvm.org/doxygen/ScopeExit_8h_source.html
  7. */
  8. template <typename Callable>
  9. class scope_exit {
  10. Callable ExitFunction;
  11. bool Engaged = true; // False once moved-from or release()d.
  12. public:
  13. template <typename Fp>
  14. // constructor accepting a forwarding reference can hide the
  15. // move constructor
  16. // @lint-ignore CLANGTIDY
  17. explicit scope_exit(Fp&& F) : ExitFunction(std::forward<Fp>(F)) {}
  18. scope_exit(scope_exit&& Rhs) noexcept
  19. : ExitFunction(std::move(Rhs.ExitFunction)), Engaged(Rhs.Engaged) {
  20. Rhs.release();
  21. }
  22. scope_exit(const scope_exit&) = delete;
  23. scope_exit& operator=(scope_exit&&) = delete;
  24. scope_exit& operator=(const scope_exit&) = delete;
  25. void release() {
  26. Engaged = false;
  27. }
  28. ~scope_exit() {
  29. if (Engaged) {
  30. ExitFunction();
  31. }
  32. }
  33. };
  34. // Keeps the callable object that is passed in, and execute it at the
  35. // destruction of the returned object (usually at the scope exit where the
  36. // returned object is kept).
  37. //
  38. // Interface is specified by p0052r2.
  39. template <typename Callable>
  40. scope_exit<typename std::decay<Callable>::type> make_scope_exit(Callable&& F) {
  41. return scope_exit<typename std::decay<Callable>::type>(
  42. std::forward<Callable>(F));
  43. }
  44. } // namespace c10