diff options
author | Luis Hector Chavez | 2018-03-26 15:11:21 -0500 |
---|---|---|
committer | Luis Hector Chavez | 2018-03-26 15:30:09 -0500 |
commit | b77035b89a3e95358a1aac9e28cd61c8b256e7ae (patch) | |
tree | 0cd8a03f13e82ce1d510e993979d429fad5d0831 | |
parent | e8d1b75c0c9384d476dd929b7215d9d121775081 (diff) | |
download | platform-system-core-b77035b89a3e95358a1aac9e28cd61c8b256e7ae.tar.gz platform-system-core-b77035b89a3e95358a1aac9e28cd61c8b256e7ae.tar.xz platform-system-core-b77035b89a3e95358a1aac9e28cd61c8b256e7ae.zip |
Allow android::base::ScopeGuard in STL containers
This change lets android::base::ScopeGuard be useful in STL containers
(e.g. std::vector<android::base::ScopeGuard<std::function<void()>>>). It
also provides perfect forwarding for android::base::make_scope_guard.
Bug: 34764308
Test: libbase_test
Change-Id: I7d1e5494b0f0695763cff0700efdb9ec18ae85c8
-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 @@ | |||
17 | #ifndef ANDROID_BASE_SCOPEGUARD_H | 17 | #ifndef ANDROID_BASE_SCOPEGUARD_H |
18 | #define ANDROID_BASE_SCOPEGUARD_H | 18 | #define ANDROID_BASE_SCOPEGUARD_H |
19 | 19 | ||
20 | #include <utility> // for std::move | 20 | #include <utility> // for std::move, std::forward |
21 | 21 | ||
22 | namespace android { | 22 | namespace android { |
23 | namespace base { | 23 | namespace base { |
24 | 24 | ||
25 | // ScopeGuard ensures that the specified functor is executed no matter how the | ||
26 | // current scope exits. | ||
25 | template <typename F> | 27 | template <typename F> |
26 | class ScopeGuard { | 28 | class ScopeGuard { |
27 | public: | 29 | public: |
28 | ScopeGuard(F f) : f_(f), active_(true) {} | 30 | ScopeGuard(F&& f) : f_(std::forward<F>(f)), active_(true) {} |
29 | 31 | ||
30 | ScopeGuard(ScopeGuard&& that) : f_(std::move(that.f_)), active_(that.active_) { | 32 | ScopeGuard(ScopeGuard&& that) : f_(std::move(that.f_)), active_(that.active_) { |
31 | that.active_ = false; | 33 | that.active_ = false; |
32 | } | 34 | } |
33 | 35 | ||
36 | template <typename Functor> | ||
37 | ScopeGuard(ScopeGuard<Functor>&& that) : f_(std::move(that.f_)), active_(that.active_) { | ||
38 | that.active_ = false; | ||
39 | } | ||
40 | |||
34 | ~ScopeGuard() { | 41 | ~ScopeGuard() { |
35 | if (active_) f_(); | 42 | if (active_) f_(); |
36 | } | 43 | } |
@@ -45,13 +52,16 @@ class ScopeGuard { | |||
45 | bool active() const { return active_; } | 52 | bool active() const { return active_; } |
46 | 53 | ||
47 | private: | 54 | private: |
55 | template <typename Functor> | ||
56 | friend class ScopeGuard; | ||
57 | |||
48 | F f_; | 58 | F f_; |
49 | bool active_; | 59 | bool active_; |
50 | }; | 60 | }; |
51 | 61 | ||
52 | template <typename T> | 62 | template <typename F> |
53 | ScopeGuard<T> make_scope_guard(T f) { | 63 | ScopeGuard<F> make_scope_guard(F&& f) { |
54 | return ScopeGuard<T>(f); | 64 | return ScopeGuard<F>(std::forward<F>(f)); |
55 | } | 65 | } |
56 | 66 | ||
57 | } // namespace base | 67 | } // 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 @@ | |||
17 | #include "android-base/scopeguard.h" | 17 | #include "android-base/scopeguard.h" |
18 | 18 | ||
19 | #include <utility> | 19 | #include <utility> |
20 | #include <vector> | ||
20 | 21 | ||
21 | #include <gtest/gtest.h> | 22 | #include <gtest/gtest.h> |
22 | 23 | ||
@@ -44,3 +45,15 @@ TEST(scopeguard, moved) { | |||
44 | EXPECT_FALSE(scopeguard.active()); | 45 | EXPECT_FALSE(scopeguard.active()); |
45 | ASSERT_FALSE(guarded_var); | 46 | ASSERT_FALSE(guarded_var); |
46 | } | 47 | } |
48 | |||
49 | TEST(scopeguard, vector) { | ||
50 | int guarded_var = 0; | ||
51 | { | ||
52 | std::vector<android::base::ScopeGuard<std::function<void()>>> scopeguards; | ||
53 | scopeguards.emplace_back(android::base::make_scope_guard( | ||
54 | std::bind([](int& guarded_var) { guarded_var++; }, std::ref(guarded_var)))); | ||
55 | scopeguards.emplace_back(android::base::make_scope_guard( | ||
56 | std::bind([](int& guarded_var) { guarded_var++; }, std::ref(guarded_var)))); | ||
57 | } | ||
58 | ASSERT_EQ(guarded_var, 2); | ||
59 | } | ||