Merge "Always align rows to pixel size on read pixels tests."
[platform/upstream/VK-GL-CTS.git] / framework / common / tcuMaybe.hpp
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         const T&        operator*               (void) const { return get(); }
48
49         const T*        operator->              (void) const;
50                                 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 };
61
62 template<typename T>
63 Maybe<T> nothing (void)
64 {
65         return Maybe<T>();
66 }
67
68 template<typename T>
69 Maybe<T> just (const T& value)
70 {
71         return Maybe<T>(value);
72 }
73
74 template<typename T>
75 Maybe<T>::Maybe (void)
76         : m_ptr (DE_NULL)
77 {
78 }
79
80 template<typename T>
81 Maybe<T>::~Maybe (void)
82 {
83         if (m_ptr)
84                 m_ptr->~T();
85 }
86
87 template<typename T>
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>
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>
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>
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>
131 const T* Maybe<T>::operator-> (void) const
132 {
133         DE_ASSERT(m_ptr);
134         return m_ptr;
135 }
136
137 template<typename T>
138 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