diff options
author | Florin Malita <fmalita@chromium.org> | 2018-04-11 11:59:18 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-04-11 17:25:07 +0000 |
commit | 8eaf64ae12696d4189d3cea9f023658494cf82b8 (patch) | |
tree | 8709859d743611c84fbf8b7b188f0f8aa5737fb0 /include | |
parent | 2b67005be0a4b0f043b9f08784ccba813668599e (diff) |
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>
Diffstat (limited to 'include')
-rw-r--r-- | include/core/SkTLazy.h | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/include/core/SkTLazy.h b/include/core/SkTLazy.h index 39ebdbef4a..a166f05a74 100644 --- a/include/core/SkTLazy.h +++ b/include/core/SkTLazy.h @@ -148,13 +148,28 @@ private: template <typename T> class SkTCopyOnFirstWrite { public: - SkTCopyOnFirstWrite(const T& initial) : fObj(&initial) {} + explicit SkTCopyOnFirstWrite(const T& initial) : fObj(&initial) {} - SkTCopyOnFirstWrite(const T* initial) : fObj(initial) {} + explicit SkTCopyOnFirstWrite(const T* initial) : fObj(initial) {} // Constructor for delayed initialization. SkTCopyOnFirstWrite() : fObj(nullptr) {} + SkTCopyOnFirstWrite(const SkTCopyOnFirstWrite& that) { *this = that; } + SkTCopyOnFirstWrite( SkTCopyOnFirstWrite&& that) { *this = std::move(that); } + + SkTCopyOnFirstWrite& operator=(const SkTCopyOnFirstWrite& that) { + fLazy = that.fLazy; + fObj = fLazy.isValid() ? fLazy.get() : that.fObj; + return *this; + } + + SkTCopyOnFirstWrite& operator=(SkTCopyOnFirstWrite&& that) { + fLazy = std::move(that.fLazy); + fObj = fLazy.isValid() ? fLazy.get() : that.fObj; + return *this; + } + // Should only be called once, and only if the default constructor was used. void init(const T& initial) { SkASSERT(nullptr == fObj); @@ -174,6 +189,8 @@ public: return const_cast<T*>(fObj); } + const T* get() const { return fObj; } + /** * Operators for treating this as though it were a const pointer. */ |