diff options
author | 2012-10-11 19:32:32 +0000 | |
---|---|---|
committer | 2012-10-11 19:32:32 +0000 | |
commit | 5dc26b97366934ba0f896cea02a3fec027d5d5c1 (patch) | |
tree | f9be03e4ed22947191a696269d4d735d0a06a52e /include/core/SkTLazy.h | |
parent | b364eb6c871c88710534c444cc4f075fcb9e3c02 (diff) |
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
Diffstat (limited to 'include/core/SkTLazy.h')
-rw-r--r-- | include/core/SkTLazy.h | 54 |
1 files changed, 54 insertions, 0 deletions
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> 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 <typename T> +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<T*>(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<T> fLazy; +}; + #endif |