1 //===-- MIUtilVariant.h -----------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #pragma once 11 12 // In-house headers: 13 #include "MIDataTypes.h" 14 15 //++ 16 //============================================================================ 17 // Details: MI common code utility class. The class implements behaviour of a 18 // variant object which holds any data object of type T. A copy of the 19 // data object specified is made and stored in *this wrapper. When the 20 // *this object is destroyed the data object hold within calls its 21 // destructor should it have one. 22 //-- 23 class CMIUtilVariant { 24 // Methods: 25 public: 26 /* ctor */ CMIUtilVariant(); 27 /* ctor */ CMIUtilVariant(const CMIUtilVariant &vrOther); 28 /* ctor */ CMIUtilVariant(CMIUtilVariant &vrOther); 29 /* ctor */ CMIUtilVariant(CMIUtilVariant &&vrwOther); 30 /* dtor */ ~CMIUtilVariant(); 31 32 template <typename T> void Set(const T &vArg); 33 template <typename T> T *Get() const; 34 35 CMIUtilVariant &operator=(const CMIUtilVariant &vrOther); 36 CMIUtilVariant &operator=(CMIUtilVariant &&vrwOther); 37 38 // Classes: 39 private: 40 //++ ---------------------------------------------------------------------- 41 // Details: Base class wrapper to hold the variant's data object when 42 // assigned to it by the Set() function. Do not use the 43 // CDataObjectBase 44 // to create objects, use only CDataObjectBase derived objects, 45 // see CDataObject() class. 46 //-- 47 class CDataObjectBase { 48 // Methods: 49 public: 50 /* ctor */ CDataObjectBase(); 51 /* ctor */ CDataObjectBase(const CDataObjectBase &vrOther); 52 /* ctor */ CDataObjectBase(CDataObjectBase &vrOther); 53 /* ctor */ CDataObjectBase(CDataObjectBase &&vrwOther); 54 // 55 CDataObjectBase &operator=(const CDataObjectBase &vrOther); 56 CDataObjectBase &operator=(CDataObjectBase &&vrwOther); 57 58 // Overrideable: 59 public: 60 virtual ~CDataObjectBase(); 61 virtual CDataObjectBase *CreateCopyOfSelf(); 62 virtual bool GetIsDerivedClass() const; 63 64 // Overrideable: 65 protected: 66 virtual void Copy(const CDataObjectBase &vrOther); 67 virtual void Destroy(); 68 }; 69 70 //++ ---------------------------------------------------------------------- 71 // Details: Derived from CDataObjectBase, this class is the wrapper for the 72 // data object as it has an aggregate of type T which is a copy 73 // of the data object assigned to the variant object. 74 //-- 75 template <typename T> class CDataObject : public CDataObjectBase { 76 // Methods: 77 public: 78 /* ctor */ CDataObject(); 79 /* ctor */ CDataObject(const T &vArg); 80 /* ctor */ CDataObject(const CDataObject &vrOther); 81 /* ctor */ CDataObject(CDataObject &vrOther); 82 /* ctor */ CDataObject(CDataObject &&vrwOther); 83 // 84 CDataObject &operator=(const CDataObject &vrOther); 85 CDataObject &operator=(CDataObject &&vrwOther); 86 // 87 T &GetDataObject(); 88 89 // Overridden: 90 public: 91 // From CDataObjectBase 92 ~CDataObject() override; 93 CDataObjectBase *CreateCopyOfSelf() override; 94 bool GetIsDerivedClass() const override; 95 96 // Overrideable: 97 private: 98 virtual void Duplicate(const CDataObject &vrOther); 99 100 // Overridden: 101 private: 102 // From CDataObjectBase 103 void Destroy() override; 104 105 // Attributes: 106 private: 107 T m_dataObj; 108 }; 109 110 // Methods 111 private: 112 void Destroy(); 113 void Copy(const CMIUtilVariant &vrOther); 114 115 // Attributes: 116 private: 117 CDataObjectBase *m_pDataObject; 118 }; 119 120 //--------------------------------------------------------------------------------------- 121 //--------------------------------------------------------------------------------------- 122 //--------------------------------------------------------------------------------------- 123 124 //++ 125 //------------------------------------------------------------------------------------ 126 // Details: CDataObject constructor. 127 // Type: Method. 128 // Args: T - The object's type. 129 // Return: None. 130 // Throws: None. 131 //-- CDataObject()132template <typename T> CMIUtilVariant::CDataObject<T>::CDataObject() {} 133 134 //++ 135 //------------------------------------------------------------------------------------ 136 // Details: CDataObject constructor. 137 // Type: Method. 138 // Args: T - The object's type. 139 // vArg - (R) The data object to be stored in the variant object. 140 // Return: None. 141 // Throws: None. 142 //-- 143 template <typename T> CDataObject(const T & vArg)144CMIUtilVariant::CDataObject<T>::CDataObject(const T &vArg) { 145 m_dataObj = vArg; 146 } 147 148 //++ 149 //------------------------------------------------------------------------------------ 150 // Details: CDataObject destructor. 151 // Type: Overridden. 152 // Args: T - The object's type. 153 // Return: None. 154 // Throws: None. 155 //-- ~CDataObject()156template <typename T> CMIUtilVariant::CDataObject<T>::~CDataObject() { 157 Destroy(); 158 } 159 160 //++ 161 //------------------------------------------------------------------------------------ 162 // Details: Retrieve the data object hold by *this object wrapper. 163 // Type: Method. 164 // Args: T - The object's type. 165 // Return: T & - Reference to the data object. 166 // Throws: None. 167 //-- GetDataObject()168template <typename T> T &CMIUtilVariant::CDataObject<T>::GetDataObject() { 169 return m_dataObj; 170 } 171 172 //++ 173 //------------------------------------------------------------------------------------ 174 // Details: Create a new copy of *this class. 175 // Type: Overridden. 176 // Args: T - The object's type. 177 // Return: CDataObjectBase * - Pointer to a new object. 178 // Throws: None. 179 //-- 180 template <typename T> 181 CMIUtilVariant::CDataObjectBase * CreateCopyOfSelf()182CMIUtilVariant::CDataObject<T>::CreateCopyOfSelf() { 183 CDataObject *pCopy = new CDataObject<T>(m_dataObj); 184 185 return pCopy; 186 } 187 188 //++ 189 //------------------------------------------------------------------------------------ 190 // Details: Determine if *this object is a derived from CDataObjectBase. 191 // Type: Overridden. 192 // Args: T - The object's type. 193 // Return: bool - True = *this is derived from CDataObjectBase 194 // - False = *this is an instance of the base class. 195 // Throws: None. 196 //-- 197 template <typename T> GetIsDerivedClass()198bool CMIUtilVariant::CDataObject<T>::GetIsDerivedClass() const { 199 return true; 200 } 201 202 //++ 203 //------------------------------------------------------------------------------------ 204 // Details: Perform a bitwise copy of *this object. 205 // Type: Overrideable. 206 // Args: T - The object's type. 207 // vrOther - (R) The other object. 208 // Return: None. 209 // Throws: None. 210 //-- 211 template <typename T> Duplicate(const CDataObject & vrOther)212void CMIUtilVariant::CDataObject<T>::Duplicate(const CDataObject &vrOther) { 213 CDataObjectBase::Copy(vrOther); 214 m_dataObj = vrOther.m_dataObj; 215 } 216 217 //++ 218 //------------------------------------------------------------------------------------ 219 // Details: Release any resources used by *this object. 220 // Type: Overridden. 221 // Args: None. 222 // Return: None. 223 // Throws: None. 224 //-- Destroy()225template <typename T> void CMIUtilVariant::CDataObject<T>::Destroy() { 226 CDataObjectBase::Destroy(); 227 } 228 229 //--------------------------------------------------------------------------------------- 230 //--------------------------------------------------------------------------------------- 231 //--------------------------------------------------------------------------------------- 232 233 //++ 234 //------------------------------------------------------------------------------------ 235 // Details: Assign to the variant an object of a specified type. 236 // Type: Template method. 237 // Args: T - The object's type. 238 // vArg - (R) The object to store. 239 // Return: None. 240 // Throws: None. 241 //-- Set(const T & vArg)242template <typename T> void CMIUtilVariant::Set(const T &vArg) { 243 m_pDataObject = new CDataObject<T>(vArg); 244 } 245 246 //++ 247 //------------------------------------------------------------------------------------ 248 // Details: Retrieve the data object from *this variant. 249 // Type: Template method. 250 // Args: T - The object's type. 251 // Return: T * - Pointer the data object, NULL = data object not assigned to 252 // *this variant. 253 // Throws: None. 254 //-- Get()255template <typename T> T *CMIUtilVariant::Get() const { 256 if ((m_pDataObject != nullptr) && m_pDataObject->GetIsDerivedClass()) { 257 CDataObject<T> *pDataObj = static_cast<CDataObject<T> *>(m_pDataObject); 258 return &pDataObj->GetDataObject(); 259 } 260 261 // Do not use a CDataObjectBase object, use only CDataObjectBase derived 262 // objects 263 return nullptr; 264 } 265