defer.h 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  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. #pragma once
  6. #include <functional>
  7. namespace ROCKSDB_NAMESPACE {
  8. // Defers the execution of the provided function until the Defer
  9. // object goes out of scope.
  10. //
  11. // Usage example:
  12. //
  13. // Status DeferTest() {
  14. // Status s;
  15. // Defer defer([&s]() {
  16. // if (!s.ok()) {
  17. // // do cleanups ...
  18. // }
  19. // });
  20. // // do something ...
  21. // if (!s.ok()) return;
  22. // // do some other things ...
  23. // return s;
  24. // }
  25. //
  26. // The above code ensures that cleanups will always happen on returning.
  27. //
  28. // Without the help of Defer, you can
  29. // 1. every time when !s.ok(), do the cleanup;
  30. // 2. instead of returning when !s.ok(), continue the work only when s.ok(),
  31. // but sometimes, this might lead to nested blocks of "if (s.ok()) {...}".
  32. //
  33. // With the help of Defer, you can centralize the cleanup logic inside the
  34. // lambda passed to Defer, and you can return immediately on failure when necessary.
  35. class Defer final {
  36. public:
  37. Defer(std::function<void()>&& fn) : fn_(std::move(fn)) {}
  38. ~Defer() { fn_(); }
  39. // Disallow copy.
  40. Defer(const Defer&) = delete;
  41. Defer& operator=(const Defer&) = delete;
  42. private:
  43. std::function<void()> fn_;
  44. };
  45. } // namespace ROCKSDB_NAMESPACE