ScopeExit.h 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  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. // NOLINTNEXTLINE(bugprone-forwarding-reference-overload)
  15. explicit scope_exit(Fp&& F) : ExitFunction(std::forward<Fp>(F)) {}
  16. scope_exit(scope_exit&& Rhs) noexcept
  17. : ExitFunction(std::move(Rhs.ExitFunction)), Engaged(Rhs.Engaged) {
  18. Rhs.release();
  19. }
  20. scope_exit(const scope_exit&) = delete;
  21. scope_exit& operator=(scope_exit&&) = delete;
  22. scope_exit& operator=(const scope_exit&) = delete;
  23. void release() {
  24. Engaged = false;
  25. }
  26. ~scope_exit() {
  27. if (Engaged) {
  28. ExitFunction();
  29. }
  30. }
  31. };
  32. // Keeps the callable object that is passed in, and execute it at the
  33. // destruction of the returned object (usually at the scope exit where the
  34. // returned object is kept).
  35. //
  36. // Interface is specified by p0052r2.
  37. template <typename Callable>
  38. scope_exit<std::decay_t<Callable>> make_scope_exit(Callable&& F) {
  39. return scope_exit<std::decay_t<Callable>>(std::forward<Callable>(F));
  40. }
  41. } // namespace c10