Coverage Report

Created: 2024-07-27 06:53

/src/rocksdb/util/defer.h
Line
Count
Source
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
#include "rocksdb/rocksdb_namespace.h"
11
12
namespace ROCKSDB_NAMESPACE {
13
14
// Defers the execution of the provided function until the Defer
15
// object goes out of scope.
16
//
17
// Usage example:
18
//
19
// Status DeferTest() {
20
//   Status s;
21
//   Defer defer([&s]() {
22
//     if (!s.ok()) {
23
//       // do cleanups ...
24
//     }
25
//   });
26
//   // do something ...
27
//   if (!s.ok()) return;
28
//   // do some other things ...
29
//   return s;
30
// }
31
//
32
// The above code ensures that cleanups will always happen on returning.
33
//
34
// Without the help of Defer, you can
35
// 1. every time when !s.ok(), do the cleanup;
36
// 2. instead of returning when !s.ok(), continue the work only when s.ok(),
37
//    but sometimes, this might lead to nested blocks of "if (s.ok()) {...}".
38
//
39
// With the help of Defer, you can centralize the cleanup logic inside the
40
// lambda passed to Defer, and you can return immediately on failure when
41
// necessary.
42
class Defer final {
43
 public:
44
38.6k
  explicit Defer(std::function<void()>&& fn) : fn_(std::move(fn)) {}
45
38.6k
  ~Defer() { fn_(); }
46
47
  // Disallow copy.
48
  Defer(const Defer&) = delete;
49
  Defer& operator=(const Defer&) = delete;
50
51
 private:
52
  std::function<void()> fn_;
53
};
54
55
// An RAII utility object that saves the current value of an object so that
56
// it can be overwritten, and restores it to the saved value when the
57
// SaveAndRestore object goes out of scope.
58
template <typename T>
59
class SaveAndRestore {
60
 public:
61
  // obj is non-null pointer to value to be saved and later restored.
62
9.03k
  explicit SaveAndRestore(T* obj) : obj_(obj), saved_(*obj) {}
63
  // new_value is stored in *obj
64
  SaveAndRestore(T* obj, const T& new_value)
65
      : obj_(obj), saved_(std::move(*obj)) {
66
    *obj = new_value;
67
  }
68
  SaveAndRestore(T* obj, T&& new_value) : obj_(obj), saved_(std::move(*obj)) {
69
    *obj = std::move(new_value);
70
  }
71
9.03k
  ~SaveAndRestore() { *obj_ = std::move(saved_); }
72
73
  // No copies
74
  SaveAndRestore(const SaveAndRestore&) = delete;
75
  SaveAndRestore& operator=(const SaveAndRestore&) = delete;
76
77
 private:
78
  T* const obj_;
79
  T saved_;
80
};
81
82
}  // namespace ROCKSDB_NAMESPACE