| //===-- 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 <typename T> void Set(const T &vArg); |
| template <typename T> 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 <typename T> 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 <typename T> CMIUtilVariant::CDataObject<T>::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 <typename T> |
| CMIUtilVariant::CDataObject<T>::CDataObject(const T &vArg) { |
| m_dataObj = vArg; |
| } |
| |
| //++ |
| //------------------------------------------------------------------------------------ |
| // Details: CDataObject destructor. |
| // Type: Overridden. |
| // Args: T - The object's type. |
| // Return: None. |
| // Throws: None. |
| //-- |
| template <typename T> CMIUtilVariant::CDataObject<T>::~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 <typename T> T &CMIUtilVariant::CDataObject<T>::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 <typename T> |
| CMIUtilVariant::CDataObjectBase * |
| CMIUtilVariant::CDataObject<T>::CreateCopyOfSelf() { |
| CDataObject *pCopy = new CDataObject<T>(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 <typename T> |
| bool CMIUtilVariant::CDataObject<T>::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 <typename T> |
| void CMIUtilVariant::CDataObject<T>::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 <typename T> void CMIUtilVariant::CDataObject<T>::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 <typename T> void CMIUtilVariant::Set(const T &vArg) { |
| m_pDataObject = new CDataObject<T>(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 <typename T> T *CMIUtilVariant::Get() const { |
| if ((m_pDataObject != nullptr) && m_pDataObject->GetIsDerivedClass()) { |
| CDataObject<T> *pDataObj = static_cast<CDataObject<T> *>(m_pDataObject); |
| return &pDataObj->GetDataObject(); |
| } |
| |
| // Do not use a CDataObjectBase object, use only CDataObjectBase derived |
| // objects |
| return nullptr; |
| } |