From f6965c793aaf68a27dc6108fd74dc582c7d07407 Mon Sep 17 00:00:00 2001 From: Luis Hector Chavez Date: Mon, 26 Mar 2018 13:11:21 -0700 Subject: [PATCH] Allow android::base::ScopeGuard in STL containers This change lets android::base::ScopeGuard be useful in STL containers (e.g. std::vector>>). It also provides perfect forwarding for android::base::make_scope_guard. Bug: 34764308 Test: libbase_test Change-Id: I7d1e5494b0f0695763cff0700efdb9ec18ae85c8 Merged-In: I7d1e5494b0f0695763cff0700efdb9ec18ae85c8 (cherry picked from commit b77035b89a3e95358a1aac9e28cd61c8b256e7ae) --- base/include/android-base/scopeguard.h | 20 +++++++++++++++----- base/scopeguard_test.cpp | 13 +++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/base/include/android-base/scopeguard.h b/base/include/android-base/scopeguard.h index abcf4bca4..c314e0263 100644 --- a/base/include/android-base/scopeguard.h +++ b/base/include/android-base/scopeguard.h @@ -17,20 +17,27 @@ #ifndef ANDROID_BASE_SCOPEGUARD_H #define ANDROID_BASE_SCOPEGUARD_H -#include // for std::move +#include // for std::move, std::forward namespace android { namespace base { +// ScopeGuard ensures that the specified functor is executed no matter how the +// current scope exits. template class ScopeGuard { public: - ScopeGuard(F f) : f_(f), active_(true) {} + ScopeGuard(F&& f) : f_(std::forward(f)), active_(true) {} ScopeGuard(ScopeGuard&& that) : f_(std::move(that.f_)), active_(that.active_) { that.active_ = false; } + template + ScopeGuard(ScopeGuard&& that) : f_(std::move(that.f_)), active_(that.active_) { + that.active_ = false; + } + ~ScopeGuard() { if (active_) f_(); } @@ -45,13 +52,16 @@ class ScopeGuard { bool active() const { return active_; } private: + template + friend class ScopeGuard; + F f_; bool active_; }; -template -ScopeGuard make_scope_guard(T f) { - return ScopeGuard(f); +template +ScopeGuard make_scope_guard(F&& f) { + return ScopeGuard(std::forward(f)); } } // namespace base diff --git a/base/scopeguard_test.cpp b/base/scopeguard_test.cpp index e11154a57..9236d7b78 100644 --- a/base/scopeguard_test.cpp +++ b/base/scopeguard_test.cpp @@ -17,6 +17,7 @@ #include "android-base/scopeguard.h" #include +#include #include @@ -44,3 +45,15 @@ TEST(scopeguard, moved) { EXPECT_FALSE(scopeguard.active()); ASSERT_FALSE(guarded_var); } + +TEST(scopeguard, vector) { + int guarded_var = 0; + { + std::vector>> scopeguards; + scopeguards.emplace_back(android::base::make_scope_guard( + std::bind([](int& guarded_var) { guarded_var++; }, std::ref(guarded_var)))); + scopeguards.emplace_back(android::base::make_scope_guard( + std::bind([](int& guarded_var) { guarded_var++; }, std::ref(guarded_var)))); + } + ASSERT_EQ(guarded_var, 2); +}