ScopeExit.h 2.0 KB

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