blob: 01dd615aad675568cc26f449ba58972a2f77ec77 [file] [log] [blame]
//===-- 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;
}