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 "SkTypes.h"
12#include <functional>
13
14/** SkScopeExit calls a std:::function<void()> in its destructor. */
15class SkScopeExit {
16public:
17    SkScopeExit(std::function<void()> f) : fFn(std::move(f)) {}
18    SkScopeExit(SkScopeExit&& that) : fFn(std::move(that.fFn)) {}
19
20    ~SkScopeExit() {
21        if (fFn) {
22            fFn();
23        }
24    }
25
26    SkScopeExit& operator=(SkScopeExit&& that) {
27        fFn = std::move(that.fFn);
28        return *this;
29    }
30
31private:
32    std::function<void()> fFn;
33
34    SkScopeExit(           const SkScopeExit& ) = delete;
35    SkScopeExit& operator=(const SkScopeExit& ) = delete;
36};
37
38/**
39 * SK_AT_SCOPE_EXIT(stmt) evaluates stmt when the current scope ends.
40 *
41 * E.g.
42 *    {
43 *        int x = 5;
44 *        {
45 *           SK_AT_SCOPE_EXIT(x--);
46 *           SkASSERT(x == 5);
47 *        }
48 *        SkASSERT(x == 4);
49 *    }
50 */
51#define SK_AT_SCOPE_EXIT(stmt)                              \
52    SkScopeExit SK_MACRO_APPEND_LINE(at_scope_exit_)([&]() { stmt; })
53
54#endif  // SkScopeExit_DEFINED
55