1 #ifndef _TCUMAYBE_HPP
2 #define _TCUMAYBE_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program Tester Core
5  * ----------------------------------------
6  *
7  * Copyright 2015 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Template for values that may not exist.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "tcuDefs.hpp"
27 
28 namespace tcu
29 {
30 
31 // \note Type T is always aligned to same alignment as deUint64.
32 // \note This type always uses at least sizeof(T*) + sizeof(deUint64) of memory.
33 template<typename T>
34 class Maybe
35 {
36 public:
37 				Maybe			(void);
38 				~Maybe			(void);
39 
40 				Maybe			(const T& val);
41 	Maybe<T>&	operator=		(const T& val);
42 
43 				Maybe			(const Maybe<T>& other);
44 	Maybe<T>&	operator=		(const Maybe<T>& other);
45 
46 	const T&	get				(void) const;
47 	T&			get				(void);
operator *(void) const48 	const T&	operator*		(void) const { return get(); }
operator *(void)49 	T&			operator*		(void) { return get(); }
50 
51 	const T*	operator->		(void) const;
52 	T*			operator->		(void);
operator bool(void) const53 				operator bool	(void) const { return !!m_ptr; }
54 
55 private:
56 	T*				m_ptr;
57 
58 	union
59 	{
60 		deUint8		m_data[sizeof(T)];
61 		deUint64	m_align;
62 	};
63 } DE_WARN_UNUSED_TYPE;
64 
65 template<typename T>
nothing(void)66 Maybe<T> nothing (void)
67 {
68 	return Maybe<T>();
69 }
70 
71 template<typename T>
just(const T & value)72 Maybe<T> just (const T& value)
73 {
74 	return Maybe<T>(value);
75 }
76 
77 template<typename T>
Maybe(void)78 Maybe<T>::Maybe (void)
79 	: m_ptr (DE_NULL)
80 {
81 }
82 
83 template<typename T>
~Maybe(void)84 Maybe<T>::~Maybe (void)
85 {
86 	if (m_ptr)
87 		m_ptr->~T();
88 }
89 
90 template<typename T>
Maybe(const T & val)91 Maybe<T>::Maybe (const T& val)
92 	: m_ptr (DE_NULL)
93 {
94 	m_ptr = new(m_data)T(val);
95 }
96 
97 template<typename T>
operator =(const T & val)98 Maybe<T>& Maybe<T>::operator= (const T& val)
99 {
100 	if (m_ptr)
101 		m_ptr->~T();
102 
103 	m_ptr = new(m_data)T(val);
104 
105 	return *this;
106 }
107 
108 template<typename T>
Maybe(const Maybe<T> & other)109 Maybe<T>::Maybe (const Maybe<T>& other)
110 	: m_ptr (DE_NULL)
111 {
112 	if (other.m_ptr)
113 		m_ptr = new(m_data)T(*other.m_ptr);
114 }
115 
116 template<typename T>
operator =(const Maybe<T> & other)117 Maybe<T>& Maybe<T>::operator= (const Maybe<T>& other)
118 {
119 	if (this == &other)
120 		return *this;
121 
122 	if (m_ptr)
123 		m_ptr->~T();
124 
125 	if (other.m_ptr)
126 		m_ptr = new(m_data)T(*other.m_ptr);
127 	else
128 		m_ptr = DE_NULL;
129 
130 	return *this;
131 }
132 
133 template<typename T>
operator ->(void) const134 const T* Maybe<T>::operator-> (void) const
135 {
136 	DE_ASSERT(m_ptr);
137 	return m_ptr;
138 }
139 
140 template<typename T>
operator ->(void)141 T* Maybe<T>::operator-> (void)
142 {
143 	DE_ASSERT(m_ptr);
144 	return m_ptr;
145 }
146 
147 template<typename T>
get(void) const148 const T& Maybe<T>::get (void) const
149 {
150 	DE_ASSERT(m_ptr);
151 	return *m_ptr;
152 }
153 
154 template<typename T>
get(void)155 T& Maybe<T>::get (void)
156 {
157 	DE_ASSERT(m_ptr);
158 	return *m_ptr;
159 }
160 
161 } // tcu
162 
163 #endif // _TCUMAYBE_HPP
164