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