1*35238bceSAndroid Build Coastguard Worker #ifndef _TCUMAYBE_HPP 2*35238bceSAndroid Build Coastguard Worker #define _TCUMAYBE_HPP 3*35238bceSAndroid Build Coastguard Worker /*------------------------------------------------------------------------- 4*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program Tester Core 5*35238bceSAndroid Build Coastguard Worker * ---------------------------------------- 6*35238bceSAndroid Build Coastguard Worker * 7*35238bceSAndroid Build Coastguard Worker * Copyright 2015 The Android Open Source Project 8*35238bceSAndroid Build Coastguard Worker * 9*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 10*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 11*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at 12*35238bceSAndroid Build Coastguard Worker * 13*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 14*35238bceSAndroid Build Coastguard Worker * 15*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 16*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 17*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 19*35238bceSAndroid Build Coastguard Worker * limitations under the License. 20*35238bceSAndroid Build Coastguard Worker * 21*35238bceSAndroid Build Coastguard Worker *//*! 22*35238bceSAndroid Build Coastguard Worker * \file 23*35238bceSAndroid Build Coastguard Worker * \brief Template for values that may not exist. 24*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/ 25*35238bceSAndroid Build Coastguard Worker 26*35238bceSAndroid Build Coastguard Worker #include "tcuDefs.hpp" 27*35238bceSAndroid Build Coastguard Worker 28*35238bceSAndroid Build Coastguard Worker namespace tcu 29*35238bceSAndroid Build Coastguard Worker { 30*35238bceSAndroid Build Coastguard Worker 31*35238bceSAndroid Build Coastguard Worker // Empty struct used to initialize Maybe objects without providing the type explicitly. 32*35238bceSAndroid Build Coastguard Worker struct Nothing_T 33*35238bceSAndroid Build Coastguard Worker { Nothing_Ttcu::Nothing_T34*35238bceSAndroid Build Coastguard Worker explicit constexpr Nothing_T(int) 35*35238bceSAndroid Build Coastguard Worker { 36*35238bceSAndroid Build Coastguard Worker } 37*35238bceSAndroid Build Coastguard Worker }; 38*35238bceSAndroid Build Coastguard Worker constexpr Nothing_T Nothing(0); 39*35238bceSAndroid Build Coastguard Worker 40*35238bceSAndroid Build Coastguard Worker // \note Type T is always aligned to same alignment as uint64_t. 41*35238bceSAndroid Build Coastguard Worker // \note This type always uses at least sizeof(T*) + sizeof(uint64_t) of memory. 42*35238bceSAndroid Build Coastguard Worker template <typename T> 43*35238bceSAndroid Build Coastguard Worker class Maybe 44*35238bceSAndroid Build Coastguard Worker { 45*35238bceSAndroid Build Coastguard Worker public: 46*35238bceSAndroid Build Coastguard Worker Maybe(void); 47*35238bceSAndroid Build Coastguard Worker Maybe(const Nothing_T &); 48*35238bceSAndroid Build Coastguard Worker ~Maybe(void); 49*35238bceSAndroid Build Coastguard Worker 50*35238bceSAndroid Build Coastguard Worker Maybe(const T &val); 51*35238bceSAndroid Build Coastguard Worker Maybe<T> &operator=(const T &val); 52*35238bceSAndroid Build Coastguard Worker 53*35238bceSAndroid Build Coastguard Worker Maybe(const Maybe<T> &other); 54*35238bceSAndroid Build Coastguard Worker Maybe<T> &operator=(const Maybe<T> &other); 55*35238bceSAndroid Build Coastguard Worker 56*35238bceSAndroid Build Coastguard Worker const T &get(void) const; 57*35238bceSAndroid Build Coastguard Worker T &get(void); operator *(void) const58*35238bceSAndroid Build Coastguard Worker const T &operator*(void) const 59*35238bceSAndroid Build Coastguard Worker { 60*35238bceSAndroid Build Coastguard Worker return get(); 61*35238bceSAndroid Build Coastguard Worker } operator *(void)62*35238bceSAndroid Build Coastguard Worker T &operator*(void) 63*35238bceSAndroid Build Coastguard Worker { 64*35238bceSAndroid Build Coastguard Worker return get(); 65*35238bceSAndroid Build Coastguard Worker } 66*35238bceSAndroid Build Coastguard Worker 67*35238bceSAndroid Build Coastguard Worker const T *operator->(void) const; 68*35238bceSAndroid Build Coastguard Worker T *operator->(void); operator bool(void) const69*35238bceSAndroid Build Coastguard Worker operator bool(void) const 70*35238bceSAndroid Build Coastguard Worker { 71*35238bceSAndroid Build Coastguard Worker return !!m_ptr; 72*35238bceSAndroid Build Coastguard Worker } 73*35238bceSAndroid Build Coastguard Worker 74*35238bceSAndroid Build Coastguard Worker private: 75*35238bceSAndroid Build Coastguard Worker T *m_ptr; 76*35238bceSAndroid Build Coastguard Worker 77*35238bceSAndroid Build Coastguard Worker union 78*35238bceSAndroid Build Coastguard Worker { 79*35238bceSAndroid Build Coastguard Worker uint8_t m_data[sizeof(T)]; 80*35238bceSAndroid Build Coastguard Worker uint64_t m_align; 81*35238bceSAndroid Build Coastguard Worker }; 82*35238bceSAndroid Build Coastguard Worker } DE_WARN_UNUSED_TYPE; 83*35238bceSAndroid Build Coastguard Worker 84*35238bceSAndroid Build Coastguard Worker template <typename T> nothing(void)85*35238bceSAndroid Build Coastguard WorkerMaybe<T> nothing(void) 86*35238bceSAndroid Build Coastguard Worker { 87*35238bceSAndroid Build Coastguard Worker return Maybe<T>(); 88*35238bceSAndroid Build Coastguard Worker } 89*35238bceSAndroid Build Coastguard Worker 90*35238bceSAndroid Build Coastguard Worker template <typename T> just(const T & value)91*35238bceSAndroid Build Coastguard WorkerMaybe<T> just(const T &value) 92*35238bceSAndroid Build Coastguard Worker { 93*35238bceSAndroid Build Coastguard Worker return Maybe<T>(value); 94*35238bceSAndroid Build Coastguard Worker } 95*35238bceSAndroid Build Coastguard Worker 96*35238bceSAndroid Build Coastguard Worker template <typename T> Maybe(void)97*35238bceSAndroid Build Coastguard WorkerMaybe<T>::Maybe(void) : m_ptr(nullptr) 98*35238bceSAndroid Build Coastguard Worker { 99*35238bceSAndroid Build Coastguard Worker } 100*35238bceSAndroid Build Coastguard Worker 101*35238bceSAndroid Build Coastguard Worker template <typename T> Maybe(const Nothing_T &)102*35238bceSAndroid Build Coastguard WorkerMaybe<T>::Maybe(const Nothing_T &) : m_ptr(nullptr) 103*35238bceSAndroid Build Coastguard Worker { 104*35238bceSAndroid Build Coastguard Worker } 105*35238bceSAndroid Build Coastguard Worker 106*35238bceSAndroid Build Coastguard Worker template <typename T> ~Maybe(void)107*35238bceSAndroid Build Coastguard WorkerMaybe<T>::~Maybe(void) 108*35238bceSAndroid Build Coastguard Worker { 109*35238bceSAndroid Build Coastguard Worker if (m_ptr) 110*35238bceSAndroid Build Coastguard Worker m_ptr->~T(); 111*35238bceSAndroid Build Coastguard Worker } 112*35238bceSAndroid Build Coastguard Worker 113*35238bceSAndroid Build Coastguard Worker template <typename T> Maybe(const T & val)114*35238bceSAndroid Build Coastguard WorkerMaybe<T>::Maybe(const T &val) : m_ptr(nullptr) 115*35238bceSAndroid Build Coastguard Worker { 116*35238bceSAndroid Build Coastguard Worker m_ptr = new (m_data) T(val); 117*35238bceSAndroid Build Coastguard Worker } 118*35238bceSAndroid Build Coastguard Worker 119*35238bceSAndroid Build Coastguard Worker template <typename T> operator =(const T & val)120*35238bceSAndroid Build Coastguard WorkerMaybe<T> &Maybe<T>::operator=(const T &val) 121*35238bceSAndroid Build Coastguard Worker { 122*35238bceSAndroid Build Coastguard Worker if (m_ptr) 123*35238bceSAndroid Build Coastguard Worker m_ptr->~T(); 124*35238bceSAndroid Build Coastguard Worker 125*35238bceSAndroid Build Coastguard Worker m_ptr = new (m_data) T(val); 126*35238bceSAndroid Build Coastguard Worker 127*35238bceSAndroid Build Coastguard Worker return *this; 128*35238bceSAndroid Build Coastguard Worker } 129*35238bceSAndroid Build Coastguard Worker 130*35238bceSAndroid Build Coastguard Worker template <typename T> Maybe(const Maybe<T> & other)131*35238bceSAndroid Build Coastguard WorkerMaybe<T>::Maybe(const Maybe<T> &other) : m_ptr(nullptr) 132*35238bceSAndroid Build Coastguard Worker { 133*35238bceSAndroid Build Coastguard Worker if (other.m_ptr) 134*35238bceSAndroid Build Coastguard Worker m_ptr = new (m_data) T(*other.m_ptr); 135*35238bceSAndroid Build Coastguard Worker } 136*35238bceSAndroid Build Coastguard Worker 137*35238bceSAndroid Build Coastguard Worker template <typename T> operator =(const Maybe<T> & other)138*35238bceSAndroid Build Coastguard WorkerMaybe<T> &Maybe<T>::operator=(const Maybe<T> &other) 139*35238bceSAndroid Build Coastguard Worker { 140*35238bceSAndroid Build Coastguard Worker if (this == &other) 141*35238bceSAndroid Build Coastguard Worker return *this; 142*35238bceSAndroid Build Coastguard Worker 143*35238bceSAndroid Build Coastguard Worker if (m_ptr) 144*35238bceSAndroid Build Coastguard Worker m_ptr->~T(); 145*35238bceSAndroid Build Coastguard Worker 146*35238bceSAndroid Build Coastguard Worker if (other.m_ptr) 147*35238bceSAndroid Build Coastguard Worker m_ptr = new (m_data) T(*other.m_ptr); 148*35238bceSAndroid Build Coastguard Worker else 149*35238bceSAndroid Build Coastguard Worker m_ptr = nullptr; 150*35238bceSAndroid Build Coastguard Worker 151*35238bceSAndroid Build Coastguard Worker return *this; 152*35238bceSAndroid Build Coastguard Worker } 153*35238bceSAndroid Build Coastguard Worker 154*35238bceSAndroid Build Coastguard Worker template <typename T> operator ->(void) const155*35238bceSAndroid Build Coastguard Workerconst T *Maybe<T>::operator->(void) const 156*35238bceSAndroid Build Coastguard Worker { 157*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_ptr); 158*35238bceSAndroid Build Coastguard Worker return m_ptr; 159*35238bceSAndroid Build Coastguard Worker } 160*35238bceSAndroid Build Coastguard Worker 161*35238bceSAndroid Build Coastguard Worker template <typename T> operator ->(void)162*35238bceSAndroid Build Coastguard WorkerT *Maybe<T>::operator->(void) 163*35238bceSAndroid Build Coastguard Worker { 164*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_ptr); 165*35238bceSAndroid Build Coastguard Worker return m_ptr; 166*35238bceSAndroid Build Coastguard Worker } 167*35238bceSAndroid Build Coastguard Worker 168*35238bceSAndroid Build Coastguard Worker template <typename T> get(void) const169*35238bceSAndroid Build Coastguard Workerconst T &Maybe<T>::get(void) const 170*35238bceSAndroid Build Coastguard Worker { 171*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_ptr); 172*35238bceSAndroid Build Coastguard Worker return *m_ptr; 173*35238bceSAndroid Build Coastguard Worker } 174*35238bceSAndroid Build Coastguard Worker 175*35238bceSAndroid Build Coastguard Worker template <typename T> get(void)176*35238bceSAndroid Build Coastguard WorkerT &Maybe<T>::get(void) 177*35238bceSAndroid Build Coastguard Worker { 178*35238bceSAndroid Build Coastguard Worker DE_ASSERT(m_ptr); 179*35238bceSAndroid Build Coastguard Worker return *m_ptr; 180*35238bceSAndroid Build Coastguard Worker } 181*35238bceSAndroid Build Coastguard Worker 182*35238bceSAndroid Build Coastguard Worker } // namespace tcu 183*35238bceSAndroid Build Coastguard Worker 184*35238bceSAndroid Build Coastguard Worker #endif // _TCUMAYBE_HPP 185