• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
SkTLazy()23     SkTLazy() : fPtr(NULL) {}
24 
SkTLazy(const T * src)25     explicit SkTLazy(const T* src) : fPtr(NULL) {
26         if (src) {
27             fPtr = new (fStorage) T(*src);
28         }
29     }
30 
SkTLazy(const SkTLazy<T> & src)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 
~SkTLazy()39     ~SkTLazy() {
40         if (this->isValid()) {
41             fPtr->~T();
42         }
43     }
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      */
init()51     T* init() {
52         if (this->isValid()) {
53             fPtr->~T();
54         }
55         fPtr = new (SkTCast<T*>(fStorage)) T;
56         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      */
set(const T & src)65     T* set(const T& src) {
66         if (this->isValid()) {
67             *fPtr = src;
68         } else {
69             fPtr = new (SkTCast<T*>(fStorage)) T(src);
70         }
71         return fPtr;
72     }
73 
74     /**
75      *  Returns true if a valid object has been initialized in the SkTLazy,
76      *  false otherwise.
77      */
isValid()78     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      */
get()84     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 
93