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 T& get (void); operator *(void) const48 const T& operator* (void) const { return get(); } operator *(void)49 T& operator* (void) { return get(); } 50 51 const T* operator-> (void) const; 52 T* operator-> (void); operator bool(void) const53 operator bool (void) const { return !!m_ptr; } 54 55 private: 56 T* m_ptr; 57 58 union 59 { 60 deUint8 m_data[sizeof(T)]; 61 deUint64 m_align; 62 }; 63 } DE_WARN_UNUSED_TYPE; 64 65 template<typename T> nothing(void)66Maybe<T> nothing (void) 67 { 68 return Maybe<T>(); 69 } 70 71 template<typename T> just(const T & value)72Maybe<T> just (const T& value) 73 { 74 return Maybe<T>(value); 75 } 76 77 template<typename T> Maybe(void)78Maybe<T>::Maybe (void) 79 : m_ptr (DE_NULL) 80 { 81 } 82 83 template<typename T> ~Maybe(void)84Maybe<T>::~Maybe (void) 85 { 86 if (m_ptr) 87 m_ptr->~T(); 88 } 89 90 template<typename T> Maybe(const T & val)91Maybe<T>::Maybe (const T& val) 92 : m_ptr (DE_NULL) 93 { 94 m_ptr = new(m_data)T(val); 95 } 96 97 template<typename T> operator =(const T & val)98Maybe<T>& Maybe<T>::operator= (const T& val) 99 { 100 if (m_ptr) 101 m_ptr->~T(); 102 103 m_ptr = new(m_data)T(val); 104 105 return *this; 106 } 107 108 template<typename T> Maybe(const Maybe<T> & other)109Maybe<T>::Maybe (const Maybe<T>& other) 110 : m_ptr (DE_NULL) 111 { 112 if (other.m_ptr) 113 m_ptr = new(m_data)T(*other.m_ptr); 114 } 115 116 template<typename T> operator =(const Maybe<T> & other)117Maybe<T>& Maybe<T>::operator= (const Maybe<T>& other) 118 { 119 if (this == &other) 120 return *this; 121 122 if (m_ptr) 123 m_ptr->~T(); 124 125 if (other.m_ptr) 126 m_ptr = new(m_data)T(*other.m_ptr); 127 else 128 m_ptr = DE_NULL; 129 130 return *this; 131 } 132 133 template<typename T> operator ->(void) const134const T* Maybe<T>::operator-> (void) const 135 { 136 DE_ASSERT(m_ptr); 137 return m_ptr; 138 } 139 140 template<typename T> operator ->(void)141T* Maybe<T>::operator-> (void) 142 { 143 DE_ASSERT(m_ptr); 144 return m_ptr; 145 } 146 147 template<typename T> get(void) const148const T& Maybe<T>::get (void) const 149 { 150 DE_ASSERT(m_ptr); 151 return *m_ptr; 152 } 153 154 template<typename T> get(void)155T& Maybe<T>::get (void) 156 { 157 DE_ASSERT(m_ptr); 158 return *m_ptr; 159 } 160 161 } // tcu 162 163 #endif // _TCUMAYBE_HPP 164