ScopeExit.h 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. #if !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION)
  2. #pragma once
  3. #include <type_traits>
  4. #include <utility>
  5. namespace c10 {
  6. /**
  7. * Mostly copied from https://llvm.org/doxygen/ScopeExit_8h_source.html
  8. */
  9. template <typename Callable>
  10. class scope_exit {
  11. Callable ExitFunction;
  12. bool Engaged = true; // False once moved-from or release()d.
  13. public:
  14. template <typename Fp>
  15. // NOLINTNEXTLINE(bugprone-forwarding-reference-overload)
  16. explicit scope_exit(Fp&& F) : ExitFunction(std::forward<Fp>(F)) {}
  17. scope_exit(scope_exit&& Rhs) noexcept
  18. : ExitFunction(std::move(Rhs.ExitFunction)), Engaged(Rhs.Engaged) {
  19. Rhs.release();
  20. }
  21. scope_exit(const scope_exit&) = delete;
  22. scope_exit& operator=(scope_exit&&) = delete;
  23. scope_exit& operator=(const scope_exit&) = delete;
  24. void release() {
  25. Engaged = false;
  26. }
  27. ~scope_exit() {
  28. if (Engaged) {
  29. ExitFunction();
  30. }
  31. }
  32. };
  33. // Keeps the callable object that is passed in, and execute it at the
  34. // destruction of the returned object (usually at the scope exit where the
  35. // returned object is kept).
  36. //
  37. // Interface is specified by p0052r2.
  38. template <typename Callable>
  39. scope_exit<std::decay_t<Callable>> make_scope_exit(Callable&& F) {
  40. return scope_exit<std::decay_t<Callable>>(std::forward<Callable>(F));
  41. }
  42. } // namespace c10
  43. #else
  44. #error "This file should not be included when either TORCH_STABLE_ONLY or TORCH_TARGET_VERSION is defined."
  45. #endif // !defined(TORCH_STABLE_ONLY) && !defined(TORCH_TARGET_VERSION)