1 :
2 : /*
3 : * Copyright 2011 Google Inc.
4 : *
5 : * Use of this source code is governed by a BSD-style license that can be
6 : * found in the LICENSE file.
7 : */
8 :
9 :
10 :
11 : #ifndef SkTLazy_DEFINED
12 : #define SkTLazy_DEFINED
13 :
14 : #include "SkTypes.h"
15 : #include <new>
16 :
17 : /**
18 : * Efficient way to defer allocating/initializing a class until it is needed
19 : * (if ever).
20 : */
21 : template <typename T> class SkTLazy {
22 : public:
23 0 : SkTLazy() : fPtr(NULL) {}
24 :
25 : explicit SkTLazy(const T* src) : fPtr(NULL) {
26 : if (src) {
27 : fPtr = new (fStorage) T(*src);
28 : }
29 : }
30 :
31 : SkTLazy(const SkTLazy<T>& src) : fPtr(NULL) {
32 : if (src.isValid()) {
33 : fPtr = new (fStorage) T(*src->get());
34 : } else {
35 : fPtr = NULL;
36 : }
37 : }
38 :
39 0 : ~SkTLazy() {
40 0 : if (this->isValid()) {
41 0 : fPtr->~T();
42 : }
43 0 : }
44 :
45 : /**
46 : * 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
48 : * will first be destroyed, so that a freshly initialized instance is
49 : * always returned.
50 : */
51 0 : T* init() {
52 0 : if (this->isValid()) {
53 0 : fPtr->~T();
54 : }
55 0 : fPtr = new (SkTCast<T*>(fStorage)) T;
56 0 : return fPtr;
57 : }
58 :
59 : /**
60 : * Copy src into this, and return a pointer to a copy of it. Note this
61 : * will always return the same pointer, so if it is called on a lazy that
62 : * has already been initialized, then this will copy over the previous
63 : * contents.
64 : */
65 0 : T* set(const T& src) {
66 0 : if (this->isValid()) {
67 0 : *fPtr = src;
68 : } else {
69 0 : fPtr = new (SkTCast<T*>(fStorage)) T(src);
70 : }
71 0 : return fPtr;
72 : }
73 :
74 : /**
75 : * Returns true if a valid object has been initialized in the SkTLazy,
76 : * false otherwise.
77 : */
78 0 : bool isValid() const { return NULL != fPtr; }
79 :
80 : /**
81 : * Returns either NULL, or a copy of the object that was passed to
82 : * set() or the constructor.
83 : */
84 0 : T* get() const { SkASSERT(this->isValid()); return fPtr; }
85 :
86 : private:
87 : T* fPtr; // NULL or fStorage
88 : char fStorage[sizeof(T)];
89 : };
90 :
91 : #endif
92 :
|