//===-- MIUtilVariant.h -----------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #pragma once // In-house headers: #include "MIDataTypes.h" //++ //============================================================================ // Details: MI common code utility class. The class implements behaviour of a // variant object which holds any data object of type T. A copy of the // data object specified is made and stored in *this wrapper. When the // *this object is destroyed the data object hold within calls its // destructor should it have one. //-- class CMIUtilVariant { // Methods: public: /* ctor */ CMIUtilVariant(); /* ctor */ CMIUtilVariant(const CMIUtilVariant &vrOther); /* ctor */ CMIUtilVariant(CMIUtilVariant &vrOther); /* ctor */ CMIUtilVariant(CMIUtilVariant &&vrwOther); /* dtor */ ~CMIUtilVariant(); template void Set(const T &vArg); template T *Get() const; CMIUtilVariant &operator=(const CMIUtilVariant &vrOther); CMIUtilVariant &operator=(CMIUtilVariant &&vrwOther); // Classes: private: //++ ---------------------------------------------------------------------- // Details: Base class wrapper to hold the variant's data object when // assigned to it by the Set() function. Do not use the // CDataObjectBase // to create objects, use only CDataObjectBase derived objects, // see CDataObject() class. //-- class CDataObjectBase { // Methods: public: /* ctor */ CDataObjectBase(); /* ctor */ CDataObjectBase(const CDataObjectBase &vrOther); /* ctor */ CDataObjectBase(CDataObjectBase &vrOther); /* ctor */ CDataObjectBase(CDataObjectBase &&vrwOther); // CDataObjectBase &operator=(const CDataObjectBase &vrOther); CDataObjectBase &operator=(CDataObjectBase &&vrwOther); // Overrideable: public: virtual ~CDataObjectBase(); virtual CDataObjectBase *CreateCopyOfSelf(); virtual bool GetIsDerivedClass() const; // Overrideable: protected: virtual void Copy(const CDataObjectBase &vrOther); virtual void Destroy(); }; //++ ---------------------------------------------------------------------- // Details: Derived from CDataObjectBase, this class is the wrapper for the // data object as it has an aggregate of type T which is a copy // of the data object assigned to the variant object. //-- template class CDataObject : public CDataObjectBase { // Methods: public: /* ctor */ CDataObject(); /* ctor */ CDataObject(const T &vArg); /* ctor */ CDataObject(const CDataObject &vrOther); /* ctor */ CDataObject(CDataObject &vrOther); /* ctor */ CDataObject(CDataObject &&vrwOther); // CDataObject &operator=(const CDataObject &vrOther); CDataObject &operator=(CDataObject &&vrwOther); // T &GetDataObject(); // Overridden: public: // From CDataObjectBase ~CDataObject() override; CDataObjectBase *CreateCopyOfSelf() override; bool GetIsDerivedClass() const override; // Overrideable: private: virtual void Duplicate(const CDataObject &vrOther); // Overridden: private: // From CDataObjectBase void Destroy() override; // Attributes: private: T m_dataObj; }; // Methods private: void Destroy(); void Copy(const CMIUtilVariant &vrOther); // Attributes: private: CDataObjectBase *m_pDataObject; }; //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //++ //------------------------------------------------------------------------------------ // Details: CDataObject constructor. // Type: Method. // Args: T - The object's type. // Return: None. // Throws: None. //-- template CMIUtilVariant::CDataObject::CDataObject() {} //++ //------------------------------------------------------------------------------------ // Details: CDataObject constructor. // Type: Method. // Args: T - The object's type. // vArg - (R) The data object to be stored in the variant object. // Return: None. // Throws: None. //-- template CMIUtilVariant::CDataObject::CDataObject(const T &vArg) { m_dataObj = vArg; } //++ //------------------------------------------------------------------------------------ // Details: CDataObject destructor. // Type: Overridden. // Args: T - The object's type. // Return: None. // Throws: None. //-- template CMIUtilVariant::CDataObject::~CDataObject() { Destroy(); } //++ //------------------------------------------------------------------------------------ // Details: Retrieve the data object hold by *this object wrapper. // Type: Method. // Args: T - The object's type. // Return: T & - Reference to the data object. // Throws: None. //-- template T &CMIUtilVariant::CDataObject::GetDataObject() { return m_dataObj; } //++ //------------------------------------------------------------------------------------ // Details: Create a new copy of *this class. // Type: Overridden. // Args: T - The object's type. // Return: CDataObjectBase * - Pointer to a new object. // Throws: None. //-- template CMIUtilVariant::CDataObjectBase * CMIUtilVariant::CDataObject::CreateCopyOfSelf() { CDataObject *pCopy = new CDataObject(m_dataObj); return pCopy; } //++ //------------------------------------------------------------------------------------ // Details: Determine if *this object is a derived from CDataObjectBase. // Type: Overridden. // Args: T - The object's type. // Return: bool - True = *this is derived from CDataObjectBase // - False = *this is an instance of the base class. // Throws: None. //-- template bool CMIUtilVariant::CDataObject::GetIsDerivedClass() const { return true; } //++ //------------------------------------------------------------------------------------ // Details: Perform a bitwise copy of *this object. // Type: Overrideable. // Args: T - The object's type. // vrOther - (R) The other object. // Return: None. // Throws: None. //-- template void CMIUtilVariant::CDataObject::Duplicate(const CDataObject &vrOther) { CDataObjectBase::Copy(vrOther); m_dataObj = vrOther.m_dataObj; } //++ //------------------------------------------------------------------------------------ // Details: Release any resources used by *this object. // Type: Overridden. // Args: None. // Return: None. // Throws: None. //-- template void CMIUtilVariant::CDataObject::Destroy() { CDataObjectBase::Destroy(); } //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- //++ //------------------------------------------------------------------------------------ // Details: Assign to the variant an object of a specified type. // Type: Template method. // Args: T - The object's type. // vArg - (R) The object to store. // Return: None. // Throws: None. //-- template void CMIUtilVariant::Set(const T &vArg) { m_pDataObject = new CDataObject(vArg); } //++ //------------------------------------------------------------------------------------ // Details: Retrieve the data object from *this variant. // Type: Template method. // Args: T - The object's type. // Return: T * - Pointer the data object, NULL = data object not assigned to // *this variant. // Throws: None. //-- template T *CMIUtilVariant::Get() const { if ((m_pDataObject != nullptr) && m_pDataObject->GetIsDerivedClass()) { CDataObject *pDataObj = static_cast *>(m_pDataObject); return &pDataObj->GetDataObject(); } // Do not use a CDataObjectBase object, use only CDataObjectBase derived // objects return nullptr; }