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; operator *(void) const47 const T& operator* (void) const { return get(); } 48 49 const T* operator-> (void) const; operator bool(void) const50 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 } DE_WARN_UNUSED_TYPE; 61 62 template<typename T> nothing(void)63Maybe<T> nothing (void) 64 { 65 return Maybe<T>(); 66 } 67 68 template<typename T> just(const T & value)69Maybe<T> just (const T& value) 70 { 71 return Maybe<T>(value); 72 } 73 74 template<typename T> Maybe(void)75Maybe<T>::Maybe (void) 76 : m_ptr (DE_NULL) 77 { 78 } 79 80 template<typename T> ~Maybe(void)81Maybe<T>::~Maybe (void) 82 { 83 if (m_ptr) 84 m_ptr->~T(); 85 } 86 87 template<typename T> Maybe(const T & val)88Maybe<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> operator =(const T & val)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 105 template<typename T> Maybe(const Maybe<T> & other)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 113 template<typename T> operator =(const Maybe<T> & other)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 130 template<typename T> operator ->(void) const131const T* Maybe<T>::operator-> (void) const 132 { 133 DE_ASSERT(m_ptr); 134 return m_ptr; 135 } 136 137 template<typename T> get(void) const138const 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