#pragma once

template<class TPObj>
class MyAuto
{
protected:
	TPObj m_pObj;
	const CComPtr<ITypeInfo>& m_ptr;
	HRESULT	m_hr;

	MyAuto(const CComPtr<ITypeInfo>& ptr) throw() : m_ptr(ptr){}

public:
	bool operator!() const throw()
	{
		return (m_pObj== NULL);
	}

	TPObj operator->() const throw() 
	{ 
		_ASSERTE(m_pObj); 
		return m_pObj; 
	}
};

class MyAuto_TYPEATTR : public MyAuto<TYPEATTR*>
{
public:
	MyAuto_TYPEATTR(const CComPtr<ITypeInfo>& ptr) throw() : MyAuto<TYPEATTR*>(ptr)
	{
		m_hr = m_ptr->GetTypeAttr(&m_pObj);
		if(m_hr != S_OK)
			m_pObj = NULL;
		else if(m_pObj==NULL)
			m_hr = E_FAIL;
	}

	virtual ~MyAuto_TYPEATTR() throw()
	{
		if(m_pObj != NULL) 
			m_ptr->ReleaseTypeAttr(m_pObj);
	}
};


class MyAuto_FUNCDESC : public MyAuto<FUNCDESC*>
{
public:
	MyAuto_FUNCDESC(const CComPtr<ITypeInfo>& ptr, UINT index) throw() : MyAuto<FUNCDESC*>(ptr)
	{
		m_hr = m_ptr->GetFuncDesc(index, &m_pObj);
		if(m_hr != S_OK)
			m_pObj = NULL;
		else if(m_pObj==NULL)
			m_hr = E_FAIL;
	}

	virtual ~MyAuto_FUNCDESC() throw()
	{
		if(m_pObj != NULL) 
			m_ptr->ReleaseFuncDesc(m_pObj);
	}
};