1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkScopeExit_DEFINED
9 #define SkScopeExit_DEFINED
10 
11 #include "include/core/SkTypes.h"
12 #include "include/private/SkMacros.h"
13 
14 #include <functional>
15 
16 /** SkScopeExit calls a std:::function<void()> in its destructor. */
17 class SkScopeExit {
18 public:
19     SkScopeExit() = default;
SkScopeExit(std::function<void ()> f)20     SkScopeExit(std::function<void()> f) : fFn(std::move(f)) {}
SkScopeExit(SkScopeExit && that)21     SkScopeExit(SkScopeExit&& that) : fFn(std::move(that.fFn)) {}
22 
~SkScopeExit()23     ~SkScopeExit() {
24         if (fFn) {
25             fFn();
26         }
27     }
28 
clear()29     void clear() { fFn = {}; }
30 
31     SkScopeExit& operator=(SkScopeExit&& that) {
32         fFn = std::move(that.fFn);
33         return *this;
34     }
35 
36 private:
37     std::function<void()> fFn;
38 
39     SkScopeExit(           const SkScopeExit& ) = delete;
40     SkScopeExit& operator=(const SkScopeExit& ) = delete;
41 };
42 
43 /**
44  * SK_AT_SCOPE_EXIT(stmt) evaluates stmt when the current scope ends.
45  *
46  * E.g.
47  *    {
48  *        int x = 5;
49  *        {
50  *           SK_AT_SCOPE_EXIT(x--);
51  *           SkASSERT(x == 5);
52  *        }
53  *        SkASSERT(x == 4);
54  *    }
55  */
56 #define SK_AT_SCOPE_EXIT(stmt)                              \
57     SkScopeExit SK_MACRO_APPEND_LINE(at_scope_exit_)([&]() { stmt; })
58 
59 #endif  // SkScopeExit_DEFINED
60