Line data Source code
1 : //===- llvm/ADT/ScopeExit.h - Execute code at scope exit --------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file defines the make_scope_exit function, which executes user-defined
11 : // cleanup logic at scope exit.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #ifndef LLVM_ADT_SCOPE_EXIT_H
16 : #define LLVM_ADT_SCOPE_EXIT_H
17 :
18 : #include "llvm/Support/Compiler.h"
19 :
20 : #include <type_traits>
21 : #include <utility>
22 :
23 : namespace llvm {
24 : namespace detail {
25 :
26 : template <typename Callable> class scope_exit {
27 : Callable ExitFunction;
28 : bool Engaged = true; // False once moved-from or release()d.
29 :
30 : public:
31 : template <typename Fp>
32 35221 : explicit scope_exit(Fp &&F) : ExitFunction(std::forward<Fp>(F)) {}
33 :
34 238 : scope_exit(scope_exit &&Rhs)
35 238 : : ExitFunction(std::move(Rhs.ExitFunction)), Engaged(Rhs.Engaged) {
36 : Rhs.release();
37 : }
38 : scope_exit(const scope_exit &) = delete;
39 : scope_exit &operator=(scope_exit &&) = delete;
40 : scope_exit &operator=(const scope_exit &) = delete;
41 :
42 119 : void release() { Engaged = false; }
43 :
44 373 : ~scope_exit() {
45 35459 : if (Engaged)
46 35205 : ExitFunction();
47 373 : }
48 : };
49 :
50 : } // end namespace detail
51 :
52 : // Keeps the callable object that is passed in, and execute it at the
53 : // destruction of the returned object (usually at the scope exit where the
54 : // returned object is kept).
55 : //
56 : // Interface is specified by p0052r2.
57 : template <typename Callable>
58 : LLVM_NODISCARD detail::scope_exit<typename std::decay<Callable>::type>
59 0 : make_scope_exit(Callable &&F) {
60 : return detail::scope_exit<typename std::decay<Callable>::type>(
61 0 : std::forward<Callable>(F));
62 : }
63 :
64 : } // end namespace llvm
65 :
66 : #endif
|