| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 | 10 |
| 11 #ifndef SkTLazy_DEFINED | 11 #ifndef SkTLazy_DEFINED |
| 12 #define SkTLazy_DEFINED | 12 #define SkTLazy_DEFINED |
| 13 | 13 |
| 14 #include "SkTypes.h" | 14 #include "SkTypes.h" |
| 15 #include <new> | 15 #include <new> |
| 16 | 16 |
| 17 template <typename T> class SkTLazy; |
| 18 template <typename T> void* operator new(size_t, SkTLazy<T>* lazy); |
| 19 |
| 17 /** | 20 /** |
| 18 * Efficient way to defer allocating/initializing a class until it is needed | 21 * Efficient way to defer allocating/initializing a class until it is needed |
| 19 * (if ever). | 22 * (if ever). |
| 20 */ | 23 */ |
| 21 template <typename T> class SkTLazy { | 24 template <typename T> class SkTLazy { |
| 22 public: | 25 public: |
| 23 SkTLazy() : fPtr(NULL) {} | 26 SkTLazy() : fPtr(NULL) {} |
| 24 | 27 |
| 25 explicit SkTLazy(const T* src) : fPtr(NULL) { | 28 explicit SkTLazy(const T* src) : fPtr(NULL) { |
| 26 if (src) { | 29 if (src) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 37 } | 40 } |
| 38 | 41 |
| 39 ~SkTLazy() { | 42 ~SkTLazy() { |
| 40 if (this->isValid()) { | 43 if (this->isValid()) { |
| 41 fPtr->~T(); | 44 fPtr->~T(); |
| 42 } | 45 } |
| 43 } | 46 } |
| 44 | 47 |
| 45 /** | 48 /** |
| 46 * Return a pointer to a default-initialized instance of the class. If a | 49 * Return a pointer to a default-initialized instance of the class. If a |
| 47 * previous instance had been initialzied (either from init() or set()) it | 50 * previous instance had been initialized (either from init() or set()) it |
| 48 * will first be destroyed, so that a freshly initialized instance is | 51 * will first be destroyed, so that a freshly initialized instance is |
| 49 * always returned. | 52 * always returned. |
| 50 */ | 53 */ |
| 51 T* init() { | 54 T* init() { |
| 52 if (this->isValid()) { | 55 if (this->isValid()) { |
| 53 fPtr->~T(); | 56 fPtr->~T(); |
| 54 } | 57 } |
| 55 fPtr = new (SkTCast<T*>(fStorage)) T; | 58 fPtr = new (SkTCast<T*>(fStorage)) T; |
| 56 return fPtr; | 59 return fPtr; |
| 57 } | 60 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 77 */ | 80 */ |
| 78 bool isValid() const { return NULL != fPtr; } | 81 bool isValid() const { return NULL != fPtr; } |
| 79 | 82 |
| 80 /** | 83 /** |
| 81 * Returns either NULL, or a copy of the object that was passed to | 84 * Returns either NULL, or a copy of the object that was passed to |
| 82 * set() or the constructor. | 85 * set() or the constructor. |
| 83 */ | 86 */ |
| 84 T* get() const { SkASSERT(this->isValid()); return fPtr; } | 87 T* get() const { SkASSERT(this->isValid()); return fPtr; } |
| 85 | 88 |
| 86 private: | 89 private: |
| 90 friend void* operator new<T>(size_t, SkTLazy* lazy); |
| 91 |
| 87 T* fPtr; // NULL or fStorage | 92 T* fPtr; // NULL or fStorage |
| 88 char fStorage[sizeof(T)]; | 93 char fStorage[sizeof(T)]; |
| 89 }; | 94 }; |
| 90 | 95 |
| 96 // Use the below macro (SkNEW_IN_TLAZY) rather than calling this directly |
| 97 template <typename T> void* operator new(size_t, SkTLazy<T>* lazy) { |
| 98 SkASSERT(!lazy->isValid()); |
| 99 lazy->fPtr = reinterpret_cast<T*>(lazy->fStorage); |
| 100 return lazy->fPtr; |
| 101 } |
| 102 |
| 103 // Skia doesn't use C++ exceptions but it may be compiled with them enabled. Hav
ing an op delete |
| 104 // to match the op new silences warnings about missing op delete when a construc
tor throws an |
| 105 // exception. |
| 106 template <typename T> void operator delete(void*, SkTLazy<T>) { SK_CRASH(); } |
| 107 |
| 108 // Use this to construct a T inside an SkTLazy using a non-default constructor. |
| 109 #define SkNEW_IN_TLAZY(tlazy_ptr, type_name, args) (new (tlazy_ptr) type_name ar
gs) |
| 110 |
| 91 /** | 111 /** |
| 92 * A helper built on top of SkTLazy to do copy-on-first-write. The object is ini
tialized | 112 * A helper built on top of SkTLazy to do copy-on-first-write. The object is ini
tialized |
| 93 * with a const pointer but provides a non-const pointer accessor. The first tim
e the | 113 * with a const pointer but provides a non-const pointer accessor. The first tim
e the |
| 94 * accessor is called (if ever) the object is cloned. | 114 * accessor is called (if ever) the object is cloned. |
| 95 * | 115 * |
| 96 * In the following example at most one copy of constThing is made: | 116 * In the following example at most one copy of constThing is made: |
| 97 * | 117 * |
| 98 * SkTCopyOnFirstWrite<Thing> thing(&constThing); | 118 * SkTCopyOnFirstWrite<Thing> thing(&constThing); |
| 99 * ... | 119 * ... |
| 100 * function_that_takes_a_const_thing_ptr(thing); // constThing is passed | 120 * function_that_takes_a_const_thing_ptr(thing); // constThing is passed |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 operator const T*() const { return fObj; } | 167 operator const T*() const { return fObj; } |
| 148 | 168 |
| 149 const T& operator *() const { return *fObj; } | 169 const T& operator *() const { return *fObj; } |
| 150 | 170 |
| 151 private: | 171 private: |
| 152 const T* fObj; | 172 const T* fObj; |
| 153 SkTLazy<T> fLazy; | 173 SkTLazy<T> fLazy; |
| 154 }; | 174 }; |
| 155 | 175 |
| 156 #endif | 176 #endif |
| OLD | NEW |