1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 
6 #pragma once
7 
8 #include <functional>
9 
10 namespace ROCKSDB_NAMESPACE {
11 
12 // Defers the execution of the provided function until the Defer
13 // object goes out of scope.
14 //
15 // Usage example:
16 //
17 // Status DeferTest() {
18 //   Status s;
19 //   Defer defer([&s]() {
20 //     if (!s.ok()) {
21 //       // do cleanups ...
22 //     }
23 //   });
24 //   // do something ...
25 //   if (!s.ok()) return;
26 //   // do some other things ...
27 //   return s;
28 // }
29 //
30 // The above code ensures that cleanups will always happen on returning.
31 //
32 // Without the help of Defer, you can
33 // 1. every time when !s.ok(), do the cleanup;
34 // 2. instead of returning when !s.ok(), continue the work only when s.ok(),
35 //    but sometimes, this might lead to nested blocks of "if (s.ok()) {...}".
36 //
37 // With the help of Defer, you can centralize the cleanup logic inside the
38 // lambda passed to Defer, and you can return immediately on failure when necessary.
39 class Defer final {
40  public:
Defer(std::function<void ()> && fn)41   Defer(std::function<void()>&& fn) : fn_(std::move(fn)) {}
~Defer()42   ~Defer() { fn_(); }
43 
44   // Disallow copy.
45   Defer(const Defer&) = delete;
46   Defer& operator=(const Defer&) = delete;
47 
48  private:
49   std::function<void()> fn_;
50 };
51 
52 }  // namespace ROCKSDB_NAMESPACE
53