Add sk_sp make variant to SkArenaAlloc.
authorHerb Derby <herb@google.com>
Mon, 6 Feb 2017 18:03:49 +0000 (13:03 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Mon, 6 Feb 2017 19:27:14 +0000 (19:27 +0000)
R=bungeman@google.com
BUG=skia:

Change-Id: Iec588cb6946f0230ff3d3ec46499c365aa6b8d09
Reviewed-on: https://skia-review.googlesource.com/8067
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Herb Derby <herb@google.com>

src/core/SkArenaAlloc.h
tests/ArenaAllocTest.cpp

index b2e81e2..84e77f0 100644 (file)
@@ -8,6 +8,7 @@
 #ifndef SkFixedAlloc_DEFINED
 #define SkFixedAlloc_DEFINED
 
+#include "SkRefCnt.h"
 #include "SkTFitsIn.h"
 #include "SkTypes.h"
 #include <cstddef>
@@ -93,6 +94,15 @@ public:
         return new(objStart) T(std::forward<Args>(args)...);
     }
 
+    template <typename T, typename... Args>
+    sk_sp<T> makeSkSp(Args&&... args) {
+        SkASSERT(SkTFitsIn<uint32_t>(sizeof(T)));
+
+        // The arena takes a ref for itself to account for the destructor. The sk_sp count can't
+        // become zero or the sk_sp will try to call free on the pointer.
+        return sk_sp<T>(SkRef(this->make<T>(std::forward<Args>(args)...)));
+    }
+
     template <typename T>
     T* makeArrayDefault(size_t count) {
         T* array = (T*)this->commonArrayAlloc<T>(count);
index 0836b0c..c27c202 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "Test.h"
 #include "SkArenaAlloc.h"
+#include "SkRefCnt.h"
 
 namespace {
 
@@ -46,6 +47,15 @@ namespace {
         Node* start;
     };
 
+    struct FooRefCnt : public SkRefCnt {
+        FooRefCnt() : x(-2), y(-3.0f) { created++; }
+        FooRefCnt(int X, float Y) : x(X), y(Y) { created++; }
+        ~FooRefCnt() { destroyed++; }
+
+        int x;
+        float y;
+    };
+
 }
 
 struct WithDtor {
@@ -159,4 +169,19 @@ DEF_TEST(ArenaAlloc, r) {
 
     REPORTER_ASSERT(r, created == 128);
     REPORTER_ASSERT(r, destroyed == 128);
+
+    {
+        created = 0;
+        destroyed = 0;
+        char storage[64];
+        SkArenaAlloc arena{storage};
+
+        sk_sp<FooRefCnt> f = arena.makeSkSp<FooRefCnt>(4, 5.0f);
+        REPORTER_ASSERT(r, f->x == 4);
+        REPORTER_ASSERT(r, f->y == 5.0f);
+        REPORTER_ASSERT(r, created == 1);
+        REPORTER_ASSERT(r, destroyed == 0);
+    }
+    REPORTER_ASSERT(r, created == 1);
+    REPORTER_ASSERT(r, destroyed == 1);
 }