xref: /aosp_15_r20/external/deqp/framework/common/tcuMaybe.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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
33 {
Nothing_Ttcu::Nothing_T34     explicit constexpr Nothing_T(int)
35     {
36     }
37 };
38 constexpr Nothing_T Nothing(0);
39 
40 // \note Type T is always aligned to same alignment as uint64_t.
41 // \note This type always uses at least sizeof(T*) + sizeof(uint64_t) of memory.
42 template <typename T>
43 class Maybe
44 {
45 public:
46     Maybe(void);
47     Maybe(const Nothing_T &);
48     ~Maybe(void);
49 
50     Maybe(const T &val);
51     Maybe<T> &operator=(const T &val);
52 
53     Maybe(const Maybe<T> &other);
54     Maybe<T> &operator=(const Maybe<T> &other);
55 
56     const T &get(void) const;
57     T &get(void);
operator *(void) const58     const T &operator*(void) const
59     {
60         return get();
61     }
operator *(void)62     T &operator*(void)
63     {
64         return get();
65     }
66 
67     const T *operator->(void) const;
68     T *operator->(void);
operator bool(void) const69     operator bool(void) const
70     {
71         return !!m_ptr;
72     }
73 
74 private:
75     T *m_ptr;
76 
77     union
78     {
79         uint8_t m_data[sizeof(T)];
80         uint64_t m_align;
81     };
82 } DE_WARN_UNUSED_TYPE;
83 
84 template <typename T>
nothing(void)85 Maybe<T> nothing(void)
86 {
87     return Maybe<T>();
88 }
89 
90 template <typename T>
just(const T & value)91 Maybe<T> just(const T &value)
92 {
93     return Maybe<T>(value);
94 }
95 
96 template <typename T>
Maybe(void)97 Maybe<T>::Maybe(void) : m_ptr(nullptr)
98 {
99 }
100 
101 template <typename T>
Maybe(const Nothing_T &)102 Maybe<T>::Maybe(const Nothing_T &) : m_ptr(nullptr)
103 {
104 }
105 
106 template <typename T>
~Maybe(void)107 Maybe<T>::~Maybe(void)
108 {
109     if (m_ptr)
110         m_ptr->~T();
111 }
112 
113 template <typename T>
Maybe(const T & val)114 Maybe<T>::Maybe(const T &val) : m_ptr(nullptr)
115 {
116     m_ptr = new (m_data) T(val);
117 }
118 
119 template <typename T>
operator =(const T & val)120 Maybe<T> &Maybe<T>::operator=(const T &val)
121 {
122     if (m_ptr)
123         m_ptr->~T();
124 
125     m_ptr = new (m_data) T(val);
126 
127     return *this;
128 }
129 
130 template <typename T>
Maybe(const Maybe<T> & other)131 Maybe<T>::Maybe(const Maybe<T> &other) : m_ptr(nullptr)
132 {
133     if (other.m_ptr)
134         m_ptr = new (m_data) T(*other.m_ptr);
135 }
136 
137 template <typename T>
operator =(const Maybe<T> & other)138 Maybe<T> &Maybe<T>::operator=(const Maybe<T> &other)
139 {
140     if (this == &other)
141         return *this;
142 
143     if (m_ptr)
144         m_ptr->~T();
145 
146     if (other.m_ptr)
147         m_ptr = new (m_data) T(*other.m_ptr);
148     else
149         m_ptr = nullptr;
150 
151     return *this;
152 }
153 
154 template <typename T>
operator ->(void) const155 const T *Maybe<T>::operator->(void) const
156 {
157     DE_ASSERT(m_ptr);
158     return m_ptr;
159 }
160 
161 template <typename T>
operator ->(void)162 T *Maybe<T>::operator->(void)
163 {
164     DE_ASSERT(m_ptr);
165     return m_ptr;
166 }
167 
168 template <typename T>
get(void) const169 const T &Maybe<T>::get(void) const
170 {
171     DE_ASSERT(m_ptr);
172     return *m_ptr;
173 }
174 
175 template <typename T>
get(void)176 T &Maybe<T>::get(void)
177 {
178     DE_ASSERT(m_ptr);
179     return *m_ptr;
180 }
181 
182 } // namespace tcu
183 
184 #endif // _TCUMAYBE_HPP
185