diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2018-03-27 02:29:20 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2018-03-27 02:29:20 +0000 |
commit | 64250b5abe1daba2a49e106a71df67d2327c03d5 (patch) | |
tree | 4b6eb13c24867751785c2dc671c9a5b1605a1355 | |
parent | 42c17c8ee58fd186a5aa86108f9ea2a3f8fc7a7d (diff) | |
parent | f6965c793aaf68a27dc6108fd74dc582c7d07407 (diff) | |
download | core-64250b5abe1daba2a49e106a71df67d2327c03d5.tar.gz core-64250b5abe1daba2a49e106a71df67d2327c03d5.tar.bz2 core-64250b5abe1daba2a49e106a71df67d2327c03d5.zip |
Merge "Allow android::base::ScopeGuard in STL containers" into pi-dev
-rw-r--r-- | base/include/android-base/scopeguard.h | 20 | ||||
-rw-r--r-- | 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 <utility> // for std::move +#include <utility> // 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 <typename F> class ScopeGuard { public: - ScopeGuard(F f) : f_(f), active_(true) {} + ScopeGuard(F&& f) : f_(std::forward<F>(f)), active_(true) {} ScopeGuard(ScopeGuard&& that) : f_(std::move(that.f_)), active_(that.active_) { that.active_ = false; } + template <typename Functor> + ScopeGuard(ScopeGuard<Functor>&& 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 <typename Functor> + friend class ScopeGuard; + F f_; bool active_; }; -template <typename T> -ScopeGuard<T> make_scope_guard(T f) { - return ScopeGuard<T>(f); +template <typename F> +ScopeGuard<F> make_scope_guard(F&& f) { + return ScopeGuard<F>(std::forward<F>(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 <utility> +#include <vector> #include <gtest/gtest.h> @@ -44,3 +45,15 @@ TEST(scopeguard, moved) { EXPECT_FALSE(scopeguard.active()); ASSERT_FALSE(guarded_var); } + +TEST(scopeguard, vector) { + int guarded_var = 0; + { + std::vector<android::base::ScopeGuard<std::function<void()>>> 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); +} |