Skia
2DGraphicsLibrary
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SkTLazy.h
1 /*
2  * Copyright 2011 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkTLazy_DEFINED
9 #define SkTLazy_DEFINED
10 
11 #include "../private/SkTemplates.h"
12 #include "SkTypes.h"
13 #include <new>
14 #include <utility>
15 
20 template <typename T> class SkTLazy {
21 public:
22  SkTLazy() : fPtr(nullptr) {}
23 
24  explicit SkTLazy(const T* src)
25  : fPtr(src ? new (fStorage.get()) T(*src) : nullptr) {}
26 
27  SkTLazy(const SkTLazy& src) : fPtr(nullptr) { *this = src; }
28 
29  ~SkTLazy() {
30  if (this->isValid()) {
31  fPtr->~T();
32  }
33  }
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 
50  template <typename... Args> T* init(Args&&... args) {
51  if (this->isValid()) {
52  fPtr->~T();
53  }
54  fPtr = new (SkTCast<T*>(fStorage.get())) T(std::forward<Args>(args)...);
55  return fPtr;
56  }
57 
64  T* set(const T& src) {
65  if (this->isValid()) {
66  *fPtr = src;
67  } else {
68  fPtr = new (SkTCast<T*>(fStorage.get())) T(src);
69  }
70  return fPtr;
71  }
72 
76  void reset() {
77  if (this->isValid()) {
78  fPtr->~T();
79  fPtr = nullptr;
80  }
81  }
82 
87  bool isValid() const { return SkToBool(fPtr); }
88 
93  T* get() const { SkASSERT(this->isValid()); return fPtr; }
94 
99  T* getMaybeNull() const { return fPtr; }
100 
101 private:
102  SkAlignedSTStorage<1, T> fStorage;
103  T* fPtr; // nullptr or fStorage
104 };
105 
129 template <typename T>
131 public:
132  SkTCopyOnFirstWrite(const T& initial) : fObj(&initial) {}
133 
134  SkTCopyOnFirstWrite(const T* initial) : fObj(initial) {}
135 
136  // Constructor for delayed initialization.
137  SkTCopyOnFirstWrite() : fObj(nullptr) {}
138 
139  // Should only be called once, and only if the default constructor was used.
140  void init(const T& initial) {
141  SkASSERT(nullptr == fObj);
142  SkASSERT(!fLazy.isValid());
143  fObj = &initial;
144  }
145 
149  T* writable() {
150  SkASSERT(fObj);
151  if (!fLazy.isValid()) {
152  fLazy.set(*fObj);
153  fObj = fLazy.get();
154  }
155  return const_cast<T*>(fObj);
156  }
157 
162  const T *operator->() const { return fObj; }
163 
164  operator const T*() const { return fObj; }
165 
166  const T& operator *() const { return *fObj; }
167 
168 private:
169  const T* fObj;
170  SkTLazy<T> fLazy;
171 };
172 
173 #endif
A helper built on top of SkTLazy to do copy-on-first-write.
Definition: SkTLazy.h:130
Efficient way to defer allocating/initializing a class until it is needed (if ever).
Definition: SkTLazy.h:20
T * writable()
Returns a writable T*.
Definition: SkTLazy.h:149
void reset()
Destroy the lazy object (if it was created via init() or set())
Definition: SkTLazy.h:76
bool isValid() const
Returns true if a valid object has been initialized in the SkTLazy, false otherwise.
Definition: SkTLazy.h:87
const T * operator->() const
Operators for treating this as though it were a const pointer.
Definition: SkTLazy.h:162
T * get() const
Returns the object.
Definition: SkTLazy.h:93
#define SkToBool(cond)
Returns 0 or 1 based on the condition.
Definition: SkTypes.h:227
T * getMaybeNull() const
Like above but doesn't assert if object isn't initialized (in which case nullptr is returned)...
Definition: SkTLazy.h:99
T * init(Args &&...args)
Return a pointer to an instance of the class initialized with 'args'.
Definition: SkTLazy.h:50
T * set(const T &src)
Copy src into this, and return a pointer to a copy of it.
Definition: SkTLazy.h:64