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

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: 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<T>& src)
mtklein 2016/08/10 18:59:46 It can be reassuring to see the copy constructor i
f(malita) 2016/08/10 20:01:01 Done. This does add a couple of redundant isValid
31 if (src.isValid()) { 28 : fPtr(src.isValid() ? new (fStorage.get()) T(*src.get()) : nullptr) {}
32 fPtr = new (fStorage.get()) T(*src.get());
33 } else {
34 fPtr = NULL;
35 }
36 }
37 29
38 ~SkTLazy() { 30 ~SkTLazy() {
39 if (this->isValid()) { 31 if (this->isValid()) {
40 fPtr->~T(); 32 fPtr->~T();
41 } 33 }
42 } 34 }
43 35
36 SkTLazy& operator=(const SkTLazy<T>& src) {
mtklein 2016/08/10 18:59:46 I think there's no need for the <T> in these argum
f(malita) 2016/08/10 20:01:01 Done.
37 if (src.isValid()) {
38 this->set(*src.get());
39 } else {
40 this->reset();
41 }
42 return *this;
43 }
44
44 /** 45 /**
45 * Return a pointer to an instance of the class initialized with 'args'. 46 * Return a pointer to an instance of the class initialized with 'args'.
46 * If a previous instance had been initialized (either from init() or 47 * If a previous instance had been initialized (either from init() or
47 * set()) it will first be destroyed, so that a freshly initialized 48 * set()) it will first be destroyed, so that a freshly initialized
48 * instance is always returned. 49 * instance is always returned.
49 */ 50 */
50 template <typename... Args> T* init(Args&&... args) { 51 template <typename... Args> T* init(Args&&... args) {
51 if (this->isValid()) { 52 if (this->isValid()) {
52 fPtr->~T(); 53 fPtr->~T();
53 } 54 }
(...skipping 15 matching lines...) Expand all
69 } 70 }
70 return fPtr; 71 return fPtr;
71 } 72 }
72 73
73 /** 74 /**
74 * Destroy the lazy object (if it was created via init() or set()) 75 * Destroy the lazy object (if it was created via init() or set())
75 */ 76 */
76 void reset() { 77 void reset() {
77 if (this->isValid()) { 78 if (this->isValid()) {
78 fPtr->~T(); 79 fPtr->~T();
79 fPtr = NULL; 80 fPtr = nullptr;
80 } 81 }
81 } 82 }
82 83
83 /** 84 /**
84 * Returns true if a valid object has been initialized in the SkTLazy, 85 * Returns true if a valid object has been initialized in the SkTLazy,
85 * false otherwise. 86 * false otherwise.
86 */ 87 */
87 bool isValid() const { return SkToBool(fPtr); } 88 bool isValid() const { return SkToBool(fPtr); }
88 89
89 /** 90 /**
90 * Returns the object. This version should only be called when the caller 91 * Returns the object. This version should only be called when the caller
91 * knows that the object has been initialized. 92 * knows that the object has been initialized.
92 */ 93 */
93 T* get() const { SkASSERT(this->isValid()); return fPtr; } 94 T* get() const { SkASSERT(this->isValid()); return fPtr; }
94 95
95 /** 96 /**
96 * Like above but doesn't assert if object isn't initialized (in which case 97 * Like above but doesn't assert if object isn't initialized (in which case
97 * NULL is returned). 98 * nullptr is returned).
98 */ 99 */
99 T* getMaybeNull() const { return fPtr; } 100 T* getMaybeNull() const { return fPtr; }
100 101
101 private: 102 private:
102 T* fPtr; // NULL or fStorage 103 T* fPtr; // nullptr or fStorage
103 SkAlignedSTStorage<1, T> fStorage; 104 SkAlignedSTStorage<1, T> fStorage;
104 }; 105 };
105 106
106 /** 107 /**
107 * A helper built on top of SkTLazy to do copy-on-first-write. The object is ini tialized 108 * 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 109 * 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. 110 * accessor is called (if ever) the object is cloned.
110 * 111 *
111 * In the following example at most one copy of constThing is made: 112 * In the following example at most one copy of constThing is made:
112 * 113 *
(...skipping 14 matching lines...) Expand all
127 * consume_a_thing(thing); // could be constThing or a modified copy. 128 * consume_a_thing(thing); // could be constThing or a modified copy.
128 */ 129 */
129 template <typename T> 130 template <typename T>
130 class SkTCopyOnFirstWrite { 131 class SkTCopyOnFirstWrite {
131 public: 132 public:
132 SkTCopyOnFirstWrite(const T& initial) : fObj(&initial) {} 133 SkTCopyOnFirstWrite(const T& initial) : fObj(&initial) {}
133 134
134 SkTCopyOnFirstWrite(const T* initial) : fObj(initial) {} 135 SkTCopyOnFirstWrite(const T* initial) : fObj(initial) {}
135 136
136 // Constructor for delayed initialization. 137 // Constructor for delayed initialization.
137 SkTCopyOnFirstWrite() : fObj(NULL) {} 138 SkTCopyOnFirstWrite() : fObj(nullptr) {}
138 139
139 // Should only be called once, and only if the default constructor was used. 140 // Should only be called once, and only if the default constructor was used.
140 void init(const T& initial) { 141 void init(const T& initial) {
141 SkASSERT(NULL == fObj); 142 SkASSERT(nullptr == fObj);
142 SkASSERT(!fLazy.isValid()); 143 SkASSERT(!fLazy.isValid());
143 fObj = &initial; 144 fObj = &initial;
144 } 145 }
145 146
146 /** 147 /**
147 * Returns a writable T*. The first time this is called the initial object i s cloned. 148 * Returns a writable T*. The first time this is called the initial object i s cloned.
148 */ 149 */
149 T* writable() { 150 T* writable() {
150 SkASSERT(fObj); 151 SkASSERT(fObj);
151 if (!fLazy.isValid()) { 152 if (!fLazy.isValid()) {
(...skipping 12 matching lines...) Expand all
164 operator const T*() const { return fObj; } 165 operator const T*() const { return fObj; }
165 166
166 const T& operator *() const { return *fObj; } 167 const T& operator *() const { return *fObj; }
167 168
168 private: 169 private:
169 const T* fObj; 170 const T* fObj;
170 SkTLazy<T> fLazy; 171 SkTLazy<T> fLazy;
171 }; 172 };
172 173
173 #endif 174 #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