Home | History | Annotate | Download | only in common
      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 } DE_WARN_UNUSED_TYPE;
     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
    147