265 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			265 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===-- 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;
 | |
| }
 |