|
#pragma once
//:ref_1
#include "DataClass.h"
//////////////////////////////////////////////////////////////// template specificator
//:ref_1_definition any changes ��� ���� ��������� must be reflected in all following references
//
// #include "DataClass.h" include file with new ret type
// here add new enum value for new ret type
// bool ExtractValue(Base_Value_Storage * pBase, T & rT) check type while extracting
// RetTypeSpecificator(int, RET_INT) declare corresponding store-check type
// IntHandler void operator()(int iVal) declare handler for particular type
enum RetType{RET_VOID, RET_T, RET_INT, RET_DOUBLE, RET_P_DATACLASS};
struct Base_Value_Storage
{
RetType m_RetType;
virtual ~Base_Value_Storage(){}
};
//////////////////////////////////////////////////////////////////////////////////
template<typename T>
struct RetValueStorage : public Base_Value_Storage
{
T m_tData;
RetValueStorage() { m_RetType = RET_T; }
};
template<>
struct RetValueStorage<void> : public Base_Value_Storage
{
int m_tData;
RetValueStorage<void>() : m_tData(0){ m_RetType = RET_VOID; }
};
/////////////////////////////////
#define RetTypeSpecificator(TYPE, iVal) \
template<>\
struct RetValueStorage<TYPE> : public Base_Value_Storage\
{\
TYPE m_tData;\
RetValueStorage<TYPE>(){ m_RetType = iVal; }\
};
/////////////////////////////
//:ref_1
RetTypeSpecificator(int, RET_INT)
RetTypeSpecificator(double, RET_DOUBLE)
RetTypeSpecificator(DataClass *, RET_P_DATACLASS)
/////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
// class for deducing if returned value is void
template<typename T>
class TypeDeductor
{
public:
bool operator == (const TypeDeductor<T> & Right)
{
cout<<typeid(T).name()<<" T T "<<typeid(T).name()<<endl;
return true;
}
template<typename T2>
bool operator == (const TypeDeductor<T2> & Right)
{
cout<<typeid(T).name()<<" T T2 "<<typeid(T).name()<<endl;
return false;
}
};
//:ref_1
template<typename T>
bool ExtractValue(Base_Value_Storage * pBase, T & rT)
{
bool bOK = false;
switch(pBase->m_RetType)
{
//case RET_VOID: bOK = false;
case RET_T: // on user consideration
rT = static_cast<RetValueStorage<T>* >(pBase)->m_tData;
bOK = true;
break;
// but type can be checked. This is better;
case RET_INT:
if(TypeDeductor<int>() == TypeDeductor<T>())
{
rT = static_cast<RetValueStorage<T>* >(pBase)->m_tData;
bOK = true;
}
break;
case RET_DOUBLE:
if(TypeDeductor<double>() == TypeDeductor<T>())
{
rT = static_cast<RetValueStorage<T>* >(pBase)->m_tData;
bOK = true;
}
break;
case RET_P_DATACLASS:
if(TypeDeductor<DataClass*>() == TypeDeductor<T>())
{
rT = static_cast<RetValueStorage<T>* >(pBase)->m_tData;
bOK = true;
}
break;
}
return bOK;
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.