blob: b0eb9b78793ec98dbc147f57125355ce26c0e75a [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.
//
//===----------------------------------------------------------------------===//
//++
// File: MIUtilVariant.h
//
// Overview: CMIUtilVariant interface.
//
// Environment: Compilers: Visual C++ 12.
// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
// Libraries: See MIReadmetxt.
//
// Gotchas: See CMIUtilVariant class description.
//
// Copyright: None.
//--
#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.
// Gotchas: None.
// Authors: Illya Rudkin 18/06/2014.
// Changes: None.
//--
class CMIUtilVariant
{
// Methods:
public:
/* ctor */ CMIUtilVariant( void );
/* ctor */ CMIUtilVariant( const CMIUtilVariant & vrOther );
/* dtor */ ~CMIUtilVariant( void );
template< typename T >
void Set( const T & vArg );
template< typename T >
T * Get( void ) const;
CMIUtilVariant & operator= ( const CMIUtilVariant & vrOther );
// 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( void );
/* ctor */ CDataObjectBase( const CDataObjectBase & vrOther );
//
CDataObjectBase & operator= ( const CDataObjectBase & vrOther ) ;
// Overrideable:
public:
virtual ~CDataObjectBase( void );
virtual CDataObjectBase * CreateCopyOfSelf( void );
virtual bool GetIsDerivedClass( void ) const;
// Overrideable:
protected:
virtual void Copy( const CDataObjectBase & vrOther );
};
//++ ----------------------------------------------------------------------
// 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
{
// Statics:
public:
// Methods:
public:
/* ctor */ CDataObject( void );
/* ctor */ CDataObject( const T & vArg );
/* ctor */ CDataObject( const CDataObject & vrOther );
//
CDataObject & operator= ( const CDataObject & vrOther );
//
T & GetDataObject( void );
// Overridden:
public:
// From CDataObjectBase
virtual ~CDataObject( void );
virtual CDataObjectBase * CreateCopyOfSelf( void );
virtual bool GetIsDerivedClass( void ) const;
// Overridden:
private:
// From CDataObjectBase
virtual void Copy( const CDataObject & vrOther );
// Attributes:
private:
T m_dataObj;
};
// Methods
private:
void Destroy( void );
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( void )
{
}
//++ ------------------------------------------------------------------------------------
// 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( void )
{
}
//++ ------------------------------------------------------------------------------------
// 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( void )
{
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( void )
{
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( void ) const
{
return true;
}
//++ ------------------------------------------------------------------------------------
// Details: Perform a bitwise copy of *this object.
// Type: Overridden.
// Args: T - The object's type.
// vrOther - (R) The other object.
// Return: None.
// Throws: None.
//--
template< typename T >
void CMIUtilVariant::CDataObject< T >::Copy( const CDataObject & vrOther )
{
m_dataObj = vrOther.m_dataObj;
}
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------
//++ ------------------------------------------------------------------------------------
// 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( void ) 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;
}