Fix SkTCopyOnFirstWrite copy semantics

The implicit SkTCopyOnFirstWrite copy-ctor and assignment operator are
incorrect: fObj must point to the local copy, not to the source copy
(when a copy has been made).

Add corrected explicit copy (and move) ctor + assignment operator.

Also add a get() helper to facilitate rawptr access.

Change-Id: Ie3983e12c04eae4f32c40e3e267618cf02008c20
Reviewed-on: https://skia-review.googlesource.com/120442
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/tests/TLazyTest.cpp b/tests/TLazyTest.cpp
new file mode 100644
index 0000000..7be514f
--- /dev/null
+++ b/tests/TLazyTest.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkTLazy.h"
+#include "Test.h"
+
+DEF_TEST(TLazy_copy, r) {
+    SkTLazy<int> lazy;
+
+    REPORTER_ASSERT(r, !lazy.isValid());
+    REPORTER_ASSERT(r, lazy.getMaybeNull() == nullptr);
+
+    {
+        SkTLazy<int> lazy_copy(lazy);
+        REPORTER_ASSERT(r, !lazy_copy.isValid());
+        REPORTER_ASSERT(r, lazy_copy.getMaybeNull() == nullptr);
+    }
+
+    lazy.init(42);
+
+    REPORTER_ASSERT(r, lazy.isValid());
+    REPORTER_ASSERT(r, 42 == *lazy.get());
+
+    {
+        SkTLazy<int> lazy_copy(lazy);
+        REPORTER_ASSERT(r, lazy_copy.isValid());
+        REPORTER_ASSERT(r, 42 == *lazy_copy.get());
+        REPORTER_ASSERT(r, lazy.get() != lazy_copy.get());
+    }
+}
+
+DEF_TEST(TCopyOnFirstWrite_copy, r) {
+    const int v = 42;
+
+    SkTCopyOnFirstWrite<int> cow(v);
+
+    REPORTER_ASSERT(r, 42 == *cow);
+    REPORTER_ASSERT(r, &v ==  cow.get());
+
+    {
+        SkTCopyOnFirstWrite<int> cow_copy(cow);
+        REPORTER_ASSERT(r, 42 == *cow_copy);
+        REPORTER_ASSERT(r, &v ==  cow_copy.get());
+        REPORTER_ASSERT(r, cow.get() ==  cow_copy.get());
+
+        *cow_copy.writable() = 43;
+        REPORTER_ASSERT(r, 42 == *cow);
+        REPORTER_ASSERT(r, &v ==  cow.get());
+        REPORTER_ASSERT(r, 43 == *cow_copy);
+        REPORTER_ASSERT(r, &v !=  cow_copy.get());
+        REPORTER_ASSERT(r, cow.get() !=  cow_copy.get());
+    }
+
+    *cow.writable() = 43;
+
+    REPORTER_ASSERT(r, 43 == *cow);
+    REPORTER_ASSERT(r, &v !=  cow.get());
+
+    {
+        SkTCopyOnFirstWrite<int> cow_copy(cow);
+        REPORTER_ASSERT(r, 43 == *cow_copy);
+        REPORTER_ASSERT(r, &v !=  cow_copy.get());
+        REPORTER_ASSERT(r, cow.get() !=  cow_copy.get());
+
+        *cow_copy.writable() = 44;
+
+        REPORTER_ASSERT(r, 43 == *cow);
+        REPORTER_ASSERT(r, &v !=  cow.get());
+        REPORTER_ASSERT(r, 44 == *cow_copy);
+        REPORTER_ASSERT(r, &v !=  cow_copy.get());
+        REPORTER_ASSERT(r, cow.get() !=  cow_copy.get());
+    }
+}