• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Empty struct used to initialize Maybe objects without providing the type explicitly.
32 struct Nothing_T {
Nothing_Ttcu::Nothing_T33 	explicit constexpr Nothing_T (int) {}
34 };
35 constexpr Nothing_T Nothing (0);
36 
37 // \note Type T is always aligned to same alignment as deUint64.
38 // \note This type always uses at least sizeof(T*) + sizeof(deUint64) of memory.
39 template<typename T>
40 class Maybe
41 {
42 public:
43 				Maybe			(void);
44 				Maybe			(const Nothing_T&);
45 				~Maybe			(void);
46 
47 				Maybe			(const T& val);
48 	Maybe<T>&	operator=		(const T& val);
49 
50 				Maybe			(const Maybe<T>& other);
51 	Maybe<T>&	operator=		(const Maybe<T>& other);
52 
53 	const T&	get				(void) const;
54 	T&			get				(void);
operator *(void) const55 	const T&	operator*		(void) const { return get(); }
operator *(void)56 	T&			operator*		(void) { return get(); }
57 
58 	const T*	operator->		(void) const;
59 	T*			operator->		(void);
operator bool(void) const60 				operator bool	(void) const { return !!m_ptr; }
61 
62 private:
63 	T*				m_ptr;
64 
65 	union
66 	{
67 		deUint8		m_data[sizeof(T)];
68 		deUint64	m_align;
69 	};
70 } DE_WARN_UNUSED_TYPE;
71 
72 template<typename T>
nothing(void)73 Maybe<T> nothing (void)
74 {
75 	return Maybe<T>();
76 }
77 
78 template<typename T>
just(const T & value)79 Maybe<T> just (const T& value)
80 {
81 	return Maybe<T>(value);
82 }
83 
84 template<typename T>
Maybe(void)85 Maybe<T>::Maybe (void)
86 	: m_ptr (nullptr)
87 {
88 }
89 
90 template<typename T>
Maybe(const Nothing_T &)91 Maybe<T>::Maybe (const Nothing_T&)
92 	: m_ptr (nullptr)
93 {
94 }
95 
96 template<typename T>
~Maybe(void)97 Maybe<T>::~Maybe (void)
98 {
99 	if (m_ptr)
100 		m_ptr->~T();
101 }
102 
103 template<typename T>
Maybe(const T & val)104 Maybe<T>::Maybe (const T& val)
105 	: m_ptr (nullptr)
106 {
107 	m_ptr = new(m_data)T(val);
108 }
109 
110 template<typename T>
operator =(const T & val)111 Maybe<T>& Maybe<T>::operator= (const T& val)
112 {
113 	if (m_ptr)
114 		m_ptr->~T();
115 
116 	m_ptr = new(m_data)T(val);
117 
118 	return *this;
119 }
120 
121 template<typename T>
Maybe(const Maybe<T> & other)122 Maybe<T>::Maybe (const Maybe<T>& other)
123 	: m_ptr (nullptr)
124 {
125 	if (other.m_ptr)
126 		m_ptr = new(m_data)T(*other.m_ptr);
127 }
128 
129 template<typename T>
operator =(const Maybe<T> & other)130 Maybe<T>& Maybe<T>::operator= (const Maybe<T>& other)
131 {
132 	if (this == &other)
133 		return *this;
134 
135 	if (m_ptr)
136 		m_ptr->~T();
137 
138 	if (other.m_ptr)
139 		m_ptr = new(m_data)T(*other.m_ptr);
140 	else
141 		m_ptr = nullptr;
142 
143 	return *this;
144 }
145 
146 template<typename T>
operator ->(void) const147 const T* Maybe<T>::operator-> (void) const
148 {
149 	DE_ASSERT(m_ptr);
150 	return m_ptr;
151 }
152 
153 template<typename T>
operator ->(void)154 T* Maybe<T>::operator-> (void)
155 {
156 	DE_ASSERT(m_ptr);
157 	return m_ptr;
158 }
159 
160 template<typename T>
get(void) const161 const T& Maybe<T>::get (void) const
162 {
163 	DE_ASSERT(m_ptr);
164 	return *m_ptr;
165 }
166 
167 template<typename T>
get(void)168 T& Maybe<T>::get (void)
169 {
170 	DE_ASSERT(m_ptr);
171 	return *m_ptr;
172 }
173 
174 } // tcu
175 
176 #endif // _TCUMAYBE_HPP
177