1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /* RAII class for executing arbitrary actions at scope end. */
9 #ifndef mozilla_ScopeExit_h
10 #define mozilla_ScopeExit_h
13 * See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4189.pdf for a
14 * standards-track version of this.
16 * Error handling can be complex when various actions need to be performed that
17 * need to be undone if an error occurs midway. This can be handled with a
18 * collection of boolean state variables and gotos, which can get clunky and
41 * ScopeExit is a mechanism to simplify this pattern by keeping an RAII guard
42 * class that will perform the teardown on destruction, unless released. So the
49 * auto guardA = MakeScopeExit([&] {
56 * auto guardB = MakeScopeExit([&] {
66 * This header provides:
68 * - |ScopeExit| - a container for a cleanup call, automically called at the
70 * - |MakeScopeExit| - a convenience function for constructing a |ScopeExit|
71 * with a given cleanup routine, commonly used with a lambda function.
73 * Note that the RAII classes defined in this header do _not_ perform any form
74 * of reference-counting or garbage-collection. These classes have exactly two
77 * - if |release()| has not been called, the cleanup is always performed at
78 * the end of the scope;
79 * - if |release()| has been called, nothing will happen at the end of the
85 #include "mozilla/Attributes.h"
86 #include "mozilla/GuardObjects.h"
90 template <typename ExitFunction
>
91 class MOZ_STACK_CLASS ScopeExit
{
92 ExitFunction mExitFunction
;
93 bool mExecuteOnDestruction
;
94 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
97 explicit ScopeExit(ExitFunction
&& cleanup MOZ_GUARD_OBJECT_NOTIFIER_PARAM
)
98 : mExitFunction(cleanup
), mExecuteOnDestruction(true) {
99 MOZ_GUARD_OBJECT_NOTIFIER_INIT
;
102 ScopeExit(ScopeExit
&& rhs MOZ_GUARD_OBJECT_NOTIFIER_PARAM
)
103 : mExitFunction(std::move(rhs
.mExitFunction
)),
104 mExecuteOnDestruction(rhs
.mExecuteOnDestruction
) {
105 MOZ_GUARD_OBJECT_NOTIFIER_INIT
;
110 if (mExecuteOnDestruction
) {
115 void release() { mExecuteOnDestruction
= false; }
118 explicit ScopeExit(const ScopeExit
&) = delete;
119 ScopeExit
& operator=(const ScopeExit
&) = delete;
120 ScopeExit
& operator=(ScopeExit
&&) = delete;
123 template <typename ExitFunction
>
124 MOZ_MUST_USE ScopeExit
<ExitFunction
> MakeScopeExit(
125 ExitFunction
&& exitFunction
) {
126 return ScopeExit
<ExitFunction
>(std::move(exitFunction
));
129 } /* namespace mozilla */
131 #endif /* mozilla_ScopeExit_h */