Index: include/private/SkTemplates.h |
diff --git a/include/private/SkTemplates.h b/include/private/SkTemplates.h |
index 01a8ec0c3bd90ddc9fcfb3bc0863f0db29b1693c..d5d75e13642a9663cddede054b2de31ac502a98c 100644 |
--- a/include/private/SkTemplates.h |
+++ b/include/private/SkTemplates.h |
@@ -489,4 +489,44 @@ private: |
SkAlignedSStorage<sizeof(T)*N> fStorage; |
}; |
+/** |
+ * sk_at_scope_end(stmt) evaluates stmt when the current scope ends. |
+ * |
+ * E.g. |
+ * |
+ * int x = 5; |
+ * { |
+ * sk_at_scope_end(x--); |
+ * SkASSERT(x == 5); |
+ * } |
+ * SkASSERT(x == 4); |
+ */ |
+ |
+template <typename Fn> |
+class SkScoped { |
bungeman-skia
2016/08/24 21:39:49
As far as naming goes, the current proposal (p0052
|
+public: |
+ SkScoped(Fn&& fn) : fFn(std::move(fn)) {} |
+ ~SkScoped() { fFn(); } |
+ |
+private: |
+ // It makes no sense to copy SkScoped. |
+ SkScoped (const SkScoped&) = delete; |
+ SkScoped& operator=(const SkScoped&) = delete; |
+ |
+ // We could potentially make moving SkScoped work. |
+ SkScoped (SkScoped&&) = delete; |
+ SkScoped& operator=(SkScoped&&) = delete; |
+ |
+ Fn fFn; |
+}; |
+ |
+template <typename Fn> |
+static inline SkScoped<Fn> sk_make_scoped(Fn&& fn) { return { std::move(fn) }; } |
+ |
+#define SCOPED_NAMEx(n) scoped_ ## n |
+#define SCOPED_NAME(n) SCOPED_NAMEx(n) |
bungeman-skia
2016/08/24 21:39:49
These names seem a bit generic for something that
|
+ |
+#define sk_at_scope_end(stmt) \ |
bungeman-skia
2016/08/24 21:39:49
You evil person making this define look like a fun
|
+ SK_UNUSED auto&& SCOPED_NAME(__COUNTER__) = sk_make_scoped([&] { stmt; }) |
bungeman-skia
2016/08/24 21:39:49
Looks like we've been using SK_MACRO_APPEND_LINE f
|
+ |
#endif |