tcuMaybe.hpp revision ab2112857be486f19caf4b50e6211150bd7613b4
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
28namespace 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.
33template<typename T>
34class Maybe
35{
36public:
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	const T&	operator*		(void) const { return get(); }
48
49	const T*	operator->		(void) const;
50				operator bool	(void) const { return !!m_ptr; }
51
52private:
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
62template<typename T>
63Maybe<T> nothing (void)
64{
65	return Maybe<T>();
66}
67
68template<typename T>
69Maybe<T> just (const T& value)
70{
71	return Maybe<T>(value);
72}
73
74template<typename T>
75Maybe<T>::Maybe (void)
76	: m_ptr (DE_NULL)
77{
78}
79
80template<typename T>
81Maybe<T>::~Maybe (void)
82{
83	if (m_ptr)
84		m_ptr->~T();
85}
86
87template<typename T>
88Maybe<T>::Maybe (const T& val)
89	: m_ptr (DE_NULL)
90{
91	m_ptr = new(m_data)T(val);
92}
93
94template<typename T>
95Maybe<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
105template<typename T>
106Maybe<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
113template<typename T>
114Maybe<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
130template<typename T>
131const T* Maybe<T>::operator-> (void) const
132{
133	DE_ASSERT(m_ptr);
134	return m_ptr;
135}
136
137template<typename T>
138const 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