aboutsummaryrefslogtreecommitdiffstats
path: root/include/core/SkTLazy.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/core/SkTLazy.h')
-rw-r--r--include/core/SkTLazy.h91
1 files changed, 91 insertions, 0 deletions
diff --git a/include/core/SkTLazy.h b/include/core/SkTLazy.h
new file mode 100644
index 0000000..fecc975
--- /dev/null
+++ b/include/core/SkTLazy.h
@@ -0,0 +1,91 @@
+/*
+ Copyright 2011 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef SkTLazy_DEFINED
+#define SkTLazy_DEFINED
+
+#include "SkTypes.h"
+
+/**
+ * Efficient way to defer allocating/initializing a class until it is needed
+ * (if ever).
+ */
+template <typename T> class SkTLazy {
+public:
+ SkTLazy() : fPtr(NULL) {}
+
+ explicit SkTLazy(const T* src) : fPtr(NULL) {
+ if (src) {
+ fPtr = new (fStorage) T(*src);
+ }
+ }
+
+ SkTLazy(const SkTLazy<T>& src) : fPtr(NULL) {
+ const T* ptr = src.get();
+ if (ptr) {
+ fPtr = new (fStorage) T(*ptr);
+ }
+ }
+
+ ~SkTLazy() {
+ if (fPtr) {
+ fPtr->~T();
+ }
+ }
+
+ /**
+ * Return a pointer to a default-initialized instance of the class. If a
+ * previous instance had been initialzied (either from init() or set()) it
+ * will first be destroyed, so that a freshly initialized instance is
+ * always returned.
+ */
+ T* init() {
+ if (fPtr) {
+ fPtr->~T();
+ }
+ fPtr = new (fStorage) T;
+ return fPtr;
+ }
+
+ /**
+ * Copy src into this, and return a pointer to a copy of it. Note this
+ * will always return the same pointer, so if it is called on a lazy that
+ * has already been initialized, then this will copy over the previous
+ * contents.
+ */
+ T* set(const T& src) {
+ if (fPtr) {
+ *fPtr = src;
+ } else {
+ fPtr = new (fStorage) T(src);
+ }
+ return fPtr;
+ }
+
+ /**
+ * Returns either NULL, or a copy of the object that was passed to
+ * set() or the constructor.
+ */
+ T* get() const { return fPtr; }
+
+private:
+ T* fPtr; // NULL or fStorage
+ char fStorage[sizeof(T)];
+};
+
+#endif
+