Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(182)

Side by Side Diff: include/core/SkTLazy.h

Issue 2232913003: Add a SkTLazy copy assignment operator (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: review Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #ifndef SkTLazy_DEFINED 8 #ifndef SkTLazy_DEFINED
9 #define SkTLazy_DEFINED 9 #define SkTLazy_DEFINED
10 10
11 #include "../private/SkTemplates.h" 11 #include "../private/SkTemplates.h"
12 #include "SkTypes.h" 12 #include "SkTypes.h"
13 #include <new> 13 #include <new>
14 #include <utility> 14 #include <utility>
15 15
16 /** 16 /**
17 * Efficient way to defer allocating/initializing a class until it is needed 17 * Efficient way to defer allocating/initializing a class until it is needed
18 * (if ever). 18 * (if ever).
19 */ 19 */
20 template <typename T> class SkTLazy { 20 template <typename T> class SkTLazy {
21 public: 21 public:
22 SkTLazy() : fPtr(NULL) {} 22 SkTLazy() : fPtr(nullptr) {}
23 23
24 explicit SkTLazy(const T* src) : fPtr(NULL) { 24 explicit SkTLazy(const T* src)
25 if (src) { 25 : fPtr(src ? new (fStorage.get()) T(*src) : nullptr) {}
26 fPtr = new (fStorage.get()) T(*src);
27 }
28 }
29 26
30 SkTLazy(const SkTLazy<T>& src) : fPtr(NULL) { 27 SkTLazy(const SkTLazy& src) : fPtr(nullptr) { *this = src; }
31 if (src.isValid()) {
32 fPtr = new (fStorage.get()) T(*src.get());
33 } else {
34 fPtr = NULL;
35 }
36 }
37 28
38 ~SkTLazy() { 29 ~SkTLazy() {
39 if (this->isValid()) { 30 if (this->isValid()) {
40 fPtr->~T(); 31 fPtr->~T();
41 } 32 }
42 } 33 }
43 34
35 SkTLazy& operator=(const SkTLazy& src) {
36 if (src.isValid()) {
37 this->set(*src.get());
38 } else {
39 this->reset();
40 }
41 return *this;
42 }
43
44 /** 44 /**
45 * Return a pointer to an instance of the class initialized with 'args'. 45 * Return a pointer to an instance of the class initialized with 'args'.
46 * If a previous instance had been initialized (either from init() or 46 * If a previous instance had been initialized (either from init() or
47 * set()) it will first be destroyed, so that a freshly initialized 47 * set()) it will first be destroyed, so that a freshly initialized
48 * instance is always returned. 48 * instance is always returned.
49 */ 49 */
50 template <typename... Args> T* init(Args&&... args) { 50 template <typename... Args> T* init(Args&&... args) {
51 if (this->isValid()) { 51 if (this->isValid()) {
52 fPtr->~T(); 52 fPtr->~T();
53 } 53 }
(...skipping 15 matching lines...) Expand all
69 } 69 }
70 return fPtr; 70 return fPtr;
71 } 71 }
72 72
73 /** 73 /**
74 * Destroy the lazy object (if it was created via init() or set()) 74 * Destroy the lazy object (if it was created via init() or set())
75 */ 75 */
76 void reset() { 76 void reset() {
77 if (this->isValid()) { 77 if (this->isValid()) {
78 fPtr->~T(); 78 fPtr->~T();
79 fPtr = NULL; 79 fPtr = nullptr;
80 } 80 }
81 } 81 }
82 82
83 /** 83 /**
84 * Returns true if a valid object has been initialized in the SkTLazy, 84 * Returns true if a valid object has been initialized in the SkTLazy,
85 * false otherwise. 85 * false otherwise.
86 */ 86 */
87 bool isValid() const { return SkToBool(fPtr); } 87 bool isValid() const { return SkToBool(fPtr); }
88 88
89 /** 89 /**
90 * Returns the object. This version should only be called when the caller 90 * Returns the object. This version should only be called when the caller
91 * knows that the object has been initialized. 91 * knows that the object has been initialized.
92 */ 92 */
93 T* get() const { SkASSERT(this->isValid()); return fPtr; } 93 T* get() const { SkASSERT(this->isValid()); return fPtr; }
94 94
95 /** 95 /**
96 * Like above but doesn't assert if object isn't initialized (in which case 96 * Like above but doesn't assert if object isn't initialized (in which case
97 * NULL is returned). 97 * nullptr is returned).
98 */ 98 */
99 T* getMaybeNull() const { return fPtr; } 99 T* getMaybeNull() const { return fPtr; }
100 100
101 private: 101 private:
102 T* fPtr; // NULL or fStorage 102 T* fPtr; // nullptr or fStorage
103 SkAlignedSTStorage<1, T> fStorage; 103 SkAlignedSTStorage<1, T> fStorage;
104 }; 104 };
105 105
106 /** 106 /**
107 * A helper built on top of SkTLazy to do copy-on-first-write. The object is ini tialized 107 * A helper built on top of SkTLazy to do copy-on-first-write. The object is ini tialized
108 * with a const pointer but provides a non-const pointer accessor. The first tim e the 108 * with a const pointer but provides a non-const pointer accessor. The first tim e the
109 * accessor is called (if ever) the object is cloned. 109 * accessor is called (if ever) the object is cloned.
110 * 110 *
111 * In the following example at most one copy of constThing is made: 111 * In the following example at most one copy of constThing is made:
112 * 112 *
(...skipping 14 matching lines...) Expand all
127 * consume_a_thing(thing); // could be constThing or a modified copy. 127 * consume_a_thing(thing); // could be constThing or a modified copy.
128 */ 128 */
129 template <typename T> 129 template <typename T>
130 class SkTCopyOnFirstWrite { 130 class SkTCopyOnFirstWrite {
131 public: 131 public:
132 SkTCopyOnFirstWrite(const T& initial) : fObj(&initial) {} 132 SkTCopyOnFirstWrite(const T& initial) : fObj(&initial) {}
133 133
134 SkTCopyOnFirstWrite(const T* initial) : fObj(initial) {} 134 SkTCopyOnFirstWrite(const T* initial) : fObj(initial) {}
135 135
136 // Constructor for delayed initialization. 136 // Constructor for delayed initialization.
137 SkTCopyOnFirstWrite() : fObj(NULL) {} 137 SkTCopyOnFirstWrite() : fObj(nullptr) {}
138 138
139 // Should only be called once, and only if the default constructor was used. 139 // Should only be called once, and only if the default constructor was used.
140 void init(const T& initial) { 140 void init(const T& initial) {
141 SkASSERT(NULL == fObj); 141 SkASSERT(nullptr == fObj);
142 SkASSERT(!fLazy.isValid()); 142 SkASSERT(!fLazy.isValid());
143 fObj = &initial; 143 fObj = &initial;
144 } 144 }
145 145
146 /** 146 /**
147 * Returns a writable T*. The first time this is called the initial object i s cloned. 147 * Returns a writable T*. The first time this is called the initial object i s cloned.
148 */ 148 */
149 T* writable() { 149 T* writable() {
150 SkASSERT(fObj); 150 SkASSERT(fObj);
151 if (!fLazy.isValid()) { 151 if (!fLazy.isValid()) {
(...skipping 12 matching lines...) Expand all
164 operator const T*() const { return fObj; } 164 operator const T*() const { return fObj; }
165 165
166 const T& operator *() const { return *fObj; } 166 const T& operator *() const { return *fObj; }
167 167
168 private: 168 private:
169 const T* fObj; 169 const T* fObj;
170 SkTLazy<T> fLazy; 170 SkTLazy<T> fLazy;
171 }; 171 };
172 172
173 #endif 173 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698