From 5dc26b97366934ba0f896cea02a3fec027d5d5c1 Mon Sep 17 00:00:00 2001 From: "bsalomon@google.com" Date: Thu, 11 Oct 2012 19:32:32 +0000 Subject: SkTCopyOnFirstWrite R=reed@google.com Review URL: https://codereview.appspot.com/6650047 git-svn-id: http://skia.googlecode.com/svn/trunk@5905 2bbb7eff-a529-9590-31e7-b0007b416f81 --- include/core/SkTLazy.h | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'include/core/SkTLazy.h') diff --git a/include/core/SkTLazy.h b/include/core/SkTLazy.h index cf2d943829..cd1e8f2b9c 100644 --- a/include/core/SkTLazy.h +++ b/include/core/SkTLazy.h @@ -88,5 +88,59 @@ private: char fStorage[sizeof(T)]; }; +/** + * A helper built on top of SkTLazy to do copy-on-first-write. The object is initialized + * with a const pointer but provides a non-const pointer accessor. The first time the + * accessor is called (if ever) the object is cloned. + * + * In the following example at most one copy of constThing is made: + * + * SkTCopyOnFirstWrite thing(&constThing); + * ... + * function_that_takes_a_const_thing_ptr(thing); // constThing is passed + * ... + * if (need_to_modify_thing()) { + * thing.writable()->modifyMe(); // makes a copy of constThing + * } + * ... + * x = thing->readSomething(); + * ... + * if (need_to_modify_thing_now()) { + * thing.writable()->changeMe(); // makes a copy of constThing if we didn't call modifyMe() + * } + * + * consume_a_thing(thing); // could be constThing or a modified copy. + */ +template +class SkTCopyOnFirstWrite { +public: + SkTCopyOnFirstWrite(const T& initial) : fObj(&initial) {} + + /** + * Returns a writable T*. The first time this is called the initial object is cloned. + */ + T* writable() { + if (!fLazy.isValid()) { + fLazy.set(*fObj); + fObj = fLazy.get(); + } + return const_cast(fObj); + } + + /** + * Operators for treating this as though it were a const pointer. + */ + + const T *operator->() const { return fObj; } + + operator const T*() const { return fObj; } + + const T& operator *() const { return *fObj; } + +private: + const T* fObj; + SkTLazy fLazy; +}; + #endif -- cgit v1.2.3