ScopeExit.h 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. //===- llvm/ADT/ScopeExit.h - Execute code at scope exit --------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file defines the make_scope_exit function, which executes user-defined
  10. // cleanup logic at scope exit.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_ADT_SCOPEEXIT_H
  14. #define LLVM_ADT_SCOPEEXIT_H
  15. #include "llvm/Support/Compiler.h"
  16. #include <type_traits>
  17. #include <utility>
  18. namespace llvm {
  19. namespace detail {
  20. template <typename Callable> class scope_exit {
  21. Callable ExitFunction;
  22. bool Engaged = true; // False once moved-from or release()d.
  23. public:
  24. template <typename Fp>
  25. explicit scope_exit(Fp &&F) : ExitFunction(std::forward<Fp>(F)) {}
  26. scope_exit(scope_exit &&Rhs)
  27. : ExitFunction(std::move(Rhs.ExitFunction)), Engaged(Rhs.Engaged) {
  28. Rhs.release();
  29. }
  30. scope_exit(const scope_exit &) = delete;
  31. scope_exit &operator=(scope_exit &&) = delete;
  32. scope_exit &operator=(const scope_exit &) = delete;
  33. void release() { Engaged = false; }
  34. ~scope_exit() {
  35. if (Engaged)
  36. ExitFunction();
  37. }
  38. };
  39. } // end namespace detail
  40. // Keeps the callable object that is passed in, and execute it at the
  41. // destruction of the returned object (usually at the scope exit where the
  42. // returned object is kept).
  43. //
  44. // Interface is specified by p0052r2.
  45. template <typename Callable>
  46. LLVM_NODISCARD detail::scope_exit<typename std::decay<Callable>::type>
  47. make_scope_exit(Callable &&F) {
  48. return detail::scope_exit<typename std::decay<Callable>::type>(
  49. std::forward<Callable>(F));
  50. }
  51. } // end namespace llvm
  52. #endif