The Pedigree Project 0.1
LazyEvaluate.h
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#ifndef KERNEL_UTILITIES_LAZYEVALUATE_H
21#define KERNEL_UTILITIES_LAZYEVALUATE_H
22
23#include "pedigree/kernel/compiler.h"
24#include "pedigree/kernel/utilities/utility.h" // for pedigree_std::move
25
39template <class T, class M, T* (*create)(const M&), void (*destroy)(T*)>
41 public:
42 // Default constructor builds a version that can never be evaluated.
43 LazyEvaluate() : m_Metadata(), m_Field(nullptr), m_Ok(false) {}
44 // Lazy variant (only evaluates on access)
45 LazyEvaluate(const M& metadata) : m_Metadata(metadata), m_Field(nullptr), m_Ok(true) {}
46 LazyEvaluate(M&& metadata)
47 : m_Metadata(pedigree_std::move(metadata)), m_Field(nullptr), m_Ok(true) {}
48 // Explicit variants (if the result of evaluation is known already)
49 LazyEvaluate(T* value) : m_Metadata(), m_Field(value), m_Ok(true) {}
50 LazyEvaluate(T* value, const M& metadata) : m_Metadata(metadata), m_Field(value), m_Ok(true) {}
51 LazyEvaluate(T* value, M&& metadata)
52 : m_Metadata(pedigree_std::move(metadata)), m_Field(value), m_Ok(true) {}
53 virtual ~LazyEvaluate() {
54 reset();
55 }
56
57 bool active() const {
58 return m_Ok && (m_Field != nullptr);
59 }
60
61 void reset() {
62 if (active()) {
63 destroy(m_Field);
64 m_Field = nullptr;
65 }
66 }
67
68 T* get() {
69 if (active()) {
70 return m_Field;
71 } else if (m_Ok) {
72 m_Field = create(m_Metadata);
73 }
74
75 return m_Field;
76 }
77
78 T* operator->() {
79 return get();
80 }
81
82 T& operator*() {
83 return *get();
84 }
85
86 operator bool() const {
87 // !ok = default constructed
88 return m_Ok;
89 }
90
91 operator T*() {
92 return get();
93 }
94
95 private:
96 NOT_COPYABLE_OR_ASSIGNABLE(LazyEvaluate);
97
98 M m_Metadata;
99 T* m_Field;
100 bool m_Ok;
101};
102
103#endif // KERNEL_UTILITIES_LAZYEVALUATE_H