3 /*-------------------------------------------------------------------------
4 * drawElements Quality Program Tester Core
5 * ----------------------------------------
7 * Copyright 2015 The Android Open Source Project
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 * \brief Template class that is either type of First or Second.
24 *//*--------------------------------------------------------------------*/
26 #include "tcuDefs.hpp"
31 /*--------------------------------------------------------------------*//*!
32 * \brief Object containing Either First or Second type of object
34 * \note Type First and Second are always aligned to same alignment as
36 * \note This type always uses at least sizeof(bool) + max(sizeof(First*),
37 * sizeof(Second*)) + sizeof(deUint64) of memory.
38 *//*--------------------------------------------------------------------*/
39 template<typename First, typename Second>
43 Either (const First& first);
44 Either (const Second& second);
47 Either (const Either<First, Second>& other);
48 Either& operator= (const Either<First, Second>& other);
50 Either& operator= (const First& first);
51 Either& operator= (const Second& second);
53 bool isFirst (void) const;
54 bool isSecond (void) const;
56 const First& getFirst (void) const;
57 const Second& getSecond (void) const;
59 template<typename Type>
60 const Type& get (void) const;
62 template<typename Type>
78 deUint8 m_data[sizeof(First) > sizeof(Second) ? sizeof(First) : sizeof(Second)];
81 } DE_WARN_UNUSED_TYPE;
83 namespace EitherDetail
86 template<typename Type, typename First, typename Second>
89 template<typename First, typename Second>
90 struct Get<First, First, Second>
92 static const First& get (const Either<First, Second>& either)
94 return either.getFirst();
98 template<typename First, typename Second>
99 struct Get<Second, First, Second>
101 static const Second& get (const Either<First, Second>& either)
103 return either.getSecond();
107 template<typename Type, typename First, typename Second>
108 const Type& get (const Either<First, Second>& either)
110 return Get<Type, First, Second>::get(either);
113 template<typename Type, typename First, typename Second>
116 template<typename First, typename Second>
117 struct Is<First, First, Second>
119 static bool is (const Either<First, Second>& either)
121 return either.isFirst();
125 template<typename First, typename Second>
126 struct Is<Second, First, Second>
128 static bool is (const Either<First, Second>& either)
130 return either.isSecond();
134 template<typename Type, typename First, typename Second>
135 bool is (const Either<First, Second>& either)
137 return Is<Type, First, Second>::is(either);
142 template<typename First, typename Second>
143 void Either<First, Second>::release (void)
154 template<typename First, typename Second>
155 Either<First, Second>::Either (const First& first)
158 m_first = new(m_data)First(first);
161 template<typename First, typename Second>
162 Either<First, Second>::Either (const Second& second)
165 m_second = new(m_data)Second(second);
168 template<typename First, typename Second>
169 Either<First, Second>::~Either (void)
174 template<typename First, typename Second>
175 Either<First, Second>::Either (const Either<First, Second>& other)
176 : m_isFirst (other.m_isFirst)
179 m_first = new(m_data)First(*other.m_first);
181 m_second = new(m_data)Second(*other.m_second);
184 template<typename First, typename Second>
185 Either<First, Second>& Either<First, Second>::operator= (const Either<First, Second>& other)
192 m_isFirst = other.m_isFirst;
195 m_first = new(m_data)First(*other.m_first);
197 m_second = new(m_data)Second(*other.m_second);
202 template<typename First, typename Second>
203 Either<First, Second>& Either<First, Second>::operator= (const First& first)
208 m_first = new(m_data)First(first);
213 template<typename First, typename Second>
214 Either<First, Second>& Either<First, Second>::operator= (const Second& second)
219 m_second = new(m_data)Second(second);
224 template<typename First, typename Second>
225 bool Either<First, Second>::isFirst (void) const
230 template<typename First, typename Second>
231 bool Either<First, Second>::isSecond (void) const
236 template<typename First, typename Second>
237 const First& Either<First, Second>::getFirst (void) const
239 DE_ASSERT(isFirst());
243 template<typename First, typename Second>
244 const Second& Either<First, Second>::getSecond (void) const
246 DE_ASSERT(isSecond());
250 template<typename First, typename Second>
251 template<typename Type>
252 const Type& Either<First, Second>::get (void) const
254 return EitherDetail::get<Type, First, Second>(*this);
257 template<typename First, typename Second>
258 template<typename Type>
259 bool Either<First, Second>::is (void) const
261 return EitherDetail::is<Type, First, Second>(*this);
264 void Either_selfTest (void);
268 #endif // _TCUEITHER_HPP