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;
operator *(void) const47 	const T&	operator*		(void) const { return get(); }
48 
49 	const T*	operator->		(void) const;
operator bool(void) const50 				operator bool	(void) const { return !!m_ptr; }
51 
52 private:
53 	T*				m_ptr;
54 
55 	union
56 	{
57 		deUint8		m_data[sizeof(T)];
58 		deUint64	m_align;
59 	};
60 } DE_WARN_UNUSED_TYPE;
61 
62 template<typename T>
nothing(void)63 Maybe<T> nothing (void)
64 {
65 	return Maybe<T>();
66 }
67 
68 template<typename T>
just(const T & value)69 Maybe<T> just (const T& value)
70 {
71 	return Maybe<T>(value);
72 }
73 
74 template<typename T>
Maybe(void)75 Maybe<T>::Maybe (void)
76 	: m_ptr (DE_NULL)
77 {
78 }
79 
80 template<typename T>
~Maybe(void)81 Maybe<T>::~Maybe (void)
82 {
83 	if (m_ptr)
84 		m_ptr->~T();
85 }
86 
87 template<typename T>
Maybe(const T & val)88 Maybe<T>::Maybe (const T& val)
89 	: m_ptr (DE_NULL)
90 {
91 	m_ptr = new(m_data)T(val);
92 }
93 
94 template<typename T>
operator =(const T & val)95 Maybe<T>& Maybe<T>::operator= (const T& val)
96 {
97 	if (m_ptr)
98 		m_ptr->~T();
99 
100 	m_ptr = new(m_data)T(val);
101 
102 	return *this;
103 }
104 
105 template<typename T>
Maybe(const Maybe<T> & other)106 Maybe<T>::Maybe (const Maybe<T>& other)
107 	: m_ptr (DE_NULL)
108 {
109 	if (other.m_ptr)
110 		m_ptr = new(m_data)T(*other.m_ptr);
111 }
112 
113 template<typename T>
operator =(const Maybe<T> & other)114 Maybe<T>& Maybe<T>::operator= (const Maybe<T>& other)
115 {
116 	if (this == &other)
117 		return *this;
118 
119 	if (m_ptr)
120 		m_ptr->~T();
121 
122 	if (other.m_ptr)
123 		m_ptr = new(m_data)T(*other.m_ptr);
124 	else
125 		m_ptr = DE_NULL;
126 
127 	return *this;
128 }
129 
130 template<typename T>
operator ->(void) const131 const T* Maybe<T>::operator-> (void) const
132 {
133 	DE_ASSERT(m_ptr);
134 	return m_ptr;
135 }
136 
137 template<typename T>
get(void) const138 const T& Maybe<T>::get (void) const
139 {
140 	DE_ASSERT(m_ptr);
141 	return *m_ptr;
142 }
143 
144 } // tcu
145 
146 #endif // _TCUMAYBE_HPP
147