X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2FScopeGuard.h;h=410dc6f7fd1451182aa164c0ed507b067703c3e2;hp=8d8e420d04b41ce56304b93a6992117a7b6eec92;hb=653053aa7a270129b35d405e3d196210c44ec6e2;hpb=46563373196cb85c0b8130149bfa2abedaa2b0c5 diff --git a/folly/ScopeGuard.h b/folly/ScopeGuard.h index 8d8e420d..410dc6f7 100644 --- a/folly/ScopeGuard.h +++ b/folly/ScopeGuard.h @@ -28,47 +28,8 @@ namespace folly { -/** - * ScopeGuard is a general implementation of the "Initialization is - * Resource Acquisition" idiom. Basically, it guarantees that a function - * is executed upon leaving the currrent scope unless otherwise told. - * - * The makeGuard() function is used to create a new ScopeGuard object. - * It can be instantiated with a lambda function, a std::function, - * a functor, or a void(*)() function pointer. - * - * - * Usage example: Add a friend to memory if and only if it is also added - * to the db. - * - * void User::addFriend(User& newFriend) { - * // add the friend to memory - * friends_.push_back(&newFriend); - * - * // If the db insertion that follows fails, we should - * // remove it from memory. - * auto guard = makeGuard([&] { friends_.pop_back(); }); - * - * // this will throw an exception upon error, which - * // makes the ScopeGuard execute UserCont::pop_back() - * // once the Guard's destructor is called. - * db_->addFriend(GetName(), newFriend.GetName()); - * - * // an exception was not thrown, so don't execute - * // the Guard. - * guard.dismiss(); - * } - * - * Examine ScopeGuardTest.cpp for some more sample usage. - * - * Stolen from: - * Andrei's and Petru Marginean's CUJ article: - * http://drdobbs.com/184403758 - * and the loki library: - * http://loki-lib.sourceforge.net/index.php?n=Idioms.ScopeGuardPointer - * and triendl.kj article: - * http://www.codeproject.com/KB/cpp/scope_guard.aspx - */ +namespace detail { + class ScopeGuardImplBase { public: void dismiss() noexcept { @@ -172,19 +133,57 @@ class ScopeGuardImpl : public ScopeGuardImplBase { FunctionType function_; }; -template -ScopeGuardImpl::type> -makeGuard(FunctionType&& fn) noexcept( - std::is_nothrow_constructible::type, - FunctionType>::value) { - return ScopeGuardImpl::type>( - std::forward(fn)); -} +template +using ScopeGuardImplDecay = ScopeGuardImpl::type>; + +} // namespace detail /** - * This is largely unneeded if you just use auto for your guards. + * ScopeGuard is a general implementation of the "Initialization is + * Resource Acquisition" idiom. Basically, it guarantees that a function + * is executed upon leaving the currrent scope unless otherwise told. + * + * The makeGuard() function is used to create a new ScopeGuard object. + * It can be instantiated with a lambda function, a std::function, + * a functor, or a void(*)() function pointer. + * + * + * Usage example: Add a friend to memory if and only if it is also added + * to the db. + * + * void User::addFriend(User& newFriend) { + * // add the friend to memory + * friends_.push_back(&newFriend); + * + * // If the db insertion that follows fails, we should + * // remove it from memory. + * auto guard = makeGuard([&] { friends_.pop_back(); }); + * + * // this will throw an exception upon error, which + * // makes the ScopeGuard execute UserCont::pop_back() + * // once the Guard's destructor is called. + * db_->addFriend(GetName(), newFriend.GetName()); + * + * // an exception was not thrown, so don't execute + * // the Guard. + * guard.dismiss(); + * } + * + * Examine ScopeGuardTest.cpp for some more sample usage. + * + * Stolen from: + * Andrei's and Petru Marginean's CUJ article: + * http://drdobbs.com/184403758 + * and the loki library: + * http://loki-lib.sourceforge.net/index.php?n=Idioms.ScopeGuardPointer + * and triendl.kj article: + * http://www.codeproject.com/KB/cpp/scope_guard.aspx */ -typedef ScopeGuardImplBase&& ScopeGuard; +template +detail::ScopeGuardImplDecay makeGuard(F&& f) noexcept( + noexcept(detail::ScopeGuardImplDecay(static_cast(f)))) { + return detail::ScopeGuardImplDecay(static_cast(f)); +} namespace detail {