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// Details: MI common code utility class. The class implements behaviour of a 17// variant object which holds any data object of type T. A copy of the 18// data object specified is made and stored in *this wrapper. When the 19// *this object is destroyed the data object hold within calls its 20// destructor should it have one. 21//-- 22class CMIUtilVariant 23{ 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 CDataObjectBase 43 // to create objects, use only CDataObjectBase derived objects, 44 // see CDataObject() class. 45 //-- 46 class CDataObjectBase 47 { 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 { 77 // Methods: 78 public: 79 /* ctor */ CDataObject(); 80 /* ctor */ CDataObject(const T &vArg); 81 /* ctor */ CDataObject(const CDataObject &vrOther); 82 /* ctor */ CDataObject(CDataObject &vrOther); 83 /* ctor */ CDataObject(CDataObject &&vrwOther); 84 // 85 CDataObject &operator=(const CDataObject &vrOther); 86 CDataObject &operator=(CDataObject &&vrwOther); 87 // 88 T &GetDataObject(); 89 90 // Overridden: 91 public: 92 // From CDataObjectBase 93 ~CDataObject() override; 94 CDataObjectBase *CreateCopyOfSelf() override; 95 bool GetIsDerivedClass() const override; 96 97 // Overrideable: 98 private: 99 virtual void Duplicate(const CDataObject &vrOther); 100 101 // Overridden: 102 private: 103 // From CDataObjectBase 104 void Destroy() override; 105 106 // Attributes: 107 private: 108 T m_dataObj; 109 }; 110 111 // Methods 112 private: 113 void Destroy(); 114 void Copy(const CMIUtilVariant &vrOther); 115 116 // Attributes: 117 private: 118 CDataObjectBase *m_pDataObject; 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//-- 132template <typename T> CMIUtilVariant::CDataObject<T>::CDataObject() 133{ 134} 135 136//++ ------------------------------------------------------------------------------------ 137// Details: CDataObject constructor. 138// Type: Method. 139// Args: T - The object's type. 140// vArg - (R) The data object to be stored in the variant object. 141// Return: None. 142// Throws: None. 143//-- 144template <typename T> CMIUtilVariant::CDataObject<T>::CDataObject(const T &vArg) 145{ 146 m_dataObj = vArg; 147} 148 149//++ ------------------------------------------------------------------------------------ 150// Details: CDataObject destructor. 151// Type: Overridden. 152// Args: T - The object's type. 153// Return: None. 154// Throws: None. 155//-- 156template <typename T> CMIUtilVariant::CDataObject<T>::~CDataObject() 157{ 158 Destroy(); 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//-- 168template <typename T> 169T & 170CMIUtilVariant::CDataObject<T>::GetDataObject() 171{ 172 return m_dataObj; 173} 174 175//++ ------------------------------------------------------------------------------------ 176// Details: Create a new copy of *this class. 177// Type: Overridden. 178// Args: T - The object's type. 179// Return: CDataObjectBase * - Pointer to a new object. 180// Throws: None. 181//-- 182template <typename T> 183CMIUtilVariant::CDataObjectBase * 184CMIUtilVariant::CDataObject<T>::CreateCopyOfSelf() 185{ 186 CDataObject *pCopy = new CDataObject<T>(m_dataObj); 187 188 return pCopy; 189} 190 191//++ ------------------------------------------------------------------------------------ 192// Details: Determine if *this object is a derived from CDataObjectBase. 193// Type: Overridden. 194// Args: T - The object's type. 195// Return: bool - True = *this is derived from CDataObjectBase 196// - False = *this is an instance of the base class. 197// Throws: None. 198//-- 199template <typename T> 200bool 201CMIUtilVariant::CDataObject<T>::GetIsDerivedClass() const 202{ 203 return true; 204} 205 206//++ ------------------------------------------------------------------------------------ 207// Details: Perform a bitwise copy of *this object. 208// Type: Overrideable. 209// Args: T - The object's type. 210// vrOther - (R) The other object. 211// Return: None. 212// Throws: None. 213//-- 214template <typename T> 215void 216CMIUtilVariant::CDataObject<T>::Duplicate(const CDataObject &vrOther) 217{ 218 CDataObjectBase::Copy(vrOther); 219 m_dataObj = vrOther.m_dataObj; 220} 221 222//++ ------------------------------------------------------------------------------------ 223// Details: Release any resources used by *this object. 224// Type: Overridden. 225// Args: None. 226// Return: None. 227// Throws: None. 228//-- 229template <typename T> 230void 231CMIUtilVariant::CDataObject<T>::Destroy() 232{ 233 CDataObjectBase::Destroy(); 234} 235 236//--------------------------------------------------------------------------------------- 237//--------------------------------------------------------------------------------------- 238//--------------------------------------------------------------------------------------- 239 240//++ ------------------------------------------------------------------------------------ 241// Details: Assign to the variant an object of a specified type. 242// Type: Template method. 243// Args: T - The object's type. 244// vArg - (R) The object to store. 245// Return: None. 246// Throws: None. 247//-- 248template <typename T> 249void 250CMIUtilVariant::Set(const T &vArg) 251{ 252 m_pDataObject = new CDataObject<T>(vArg); 253} 254 255//++ ------------------------------------------------------------------------------------ 256// Details: Retrieve the data object from *this variant. 257// Type: Template method. 258// Args: T - The object's type. 259// Return: T * - Pointer the data object, NULL = data object not assigned to *this variant. 260// Throws: None. 261//-- 262template <typename T> 263T * 264CMIUtilVariant::Get() const 265{ 266 if ((m_pDataObject != nullptr) && m_pDataObject->GetIsDerivedClass()) 267 { 268 CDataObject<T> *pDataObj = static_cast<CDataObject<T> *>(m_pDataObject); 269 return &pDataObj->GetDataObject(); 270 } 271 272 // Do not use a CDataObjectBase object, use only CDataObjectBase derived objects 273 return nullptr; 274} 275