← Back to team overview

ooc-dev team mailing list archive

Re: template

 

On Wed, 1 Jul 2009 11:00:45 +0200, Amos Wenger <amoswenger@xxxxxxxxx>
wrote:
> The question is far from stupid. However, I'd need a very very good
reason
> to support templating as it can be found in C++.
> For a discussion of some issues related to templates in C++, read this
> article by Yossi Kreinin.
> <http://www.yosefk.com/blog/oo-c-is-passable.html>As for type safety
> (e.g. for collections), I'm thinking of implementing
> generics somewhat like in Java.
> What I'd be very interested in, though, is what you feel you'd need
> templates/metaprog for, so maybe we can think of another, simpler, more
> elegant way to achieve it.
> 
Axtually I like C++ templates because you only pay what you need.
A very simple example, on a private framework I am developping I want to be
able to 
accept native unicode encoding (UTF16) or more widespread UTF8 so I have
some code like that that is used
to retrieve properties from a contact (there is a switch to determine
property type then a pointer to the property
is returned)

void* 
OS_GDAbItem_GetProperty(GDAbItem* gpContact, EAbItemProp eAbPropId)
{
	ErrorCode err;
	void* pRet = NULL; // Points to all kind of properties (string, filetime,
...)
	CEPROPVAL *lpProp;


	GDPropVal* gdPropVal = NULL;
	err = GDAbItem_GetPropertyEx(gpContact, eAbPropId, &gynPropVal);
	if (err == 0)
	{
		lpProp = (CEPROPVAL *) gdPropVal->pOsPropVal;
		if (lpProp->wFlags != CEDB_PROPNOTFOUND)
		{
			switch( gdPropVal->ulPropType )
			{
			case CEVT_LPWSTR:		{ pRet  = IConvPtr<wchar_t *>	(lpProp->val.lpwstr)
;break; }
			case CEVT_FILETIME:		{ pRet  = IConvPtr<FILETIME
*>	(&(lpProp->val.filetime) ) ;break; }	
			case CEVT_UI4:			{ pRet  = IConvPtr<USHORT *>	(&(lpProp->val.uiVal))
;break; }	
			case CEVT_PIM_STREAM:	{ pRet  = IConvPtr<CEBLOB *>	(&(lpProp->val.blob))
;break; }	
			default:				{ pRet  = (void*)0 ;break; }
			}
		}
		else
		{
			pRet = (void*)0;
		}
	}

	return pRet;
}


As you can see I am using a templated class that allow me to copy a pointer
when pointer is different from a wchar_t*
and to convert it and then assign otherwise. I wrote this class a few days
ago and it might not be a good example or good sample
code but it suits my need.


template <typename T>
class IConvPtr
{
void* m_ptr;

public:
	IConvPtr(T pVal) : m_ptr(pVal)
	{}

	IConvPtr& IConvPtr::operator=(T aptr) { m_ptr = aptr; }
	
	 operator void *() { return m_ptr; }
	
};

template <>
class IConvPtr<wchar_t*>
{
void* m_ptr;
public:
	IConvPtr(wchar_t* pStringW) { convert_or_assign(pStringW); }

	IConvPtr& IConvPtr::operator=(wchar_t* pStringW) {
convert_or_assign(pStringW); }

	void convert_or_assign(void * pStringW)
	{
#ifndef USE_NATIVE_UNICODE

#else
		m_ptr = pStringW;
#endif
	}

	operator void *() { return m_ptr; }
	
};


So the alternative code not using C++ is to do the following thing : 

void* 
OS_GDAbItem_GetProperty(GDAbItem* gpContact, EAbItemProp eAbPropId)
{
	ErrorCode err;
	void* pRet = NULL;
	CEPROPVAL *lpProp;


	GDPropVal* gdPropVal = NULL;
	err = GDAbItem_GetPropertyEx(gpContact, eAbPropId, &gynPropVal);
	if (err == 0)
	{
		lpProp = (CEPROPVAL *) gdPropVal->pOsPropVal;
		if (lpProp->wFlags != CEDB_PROPNOTFOUND)
		{
			switch( gdPropVal->ulPropType )
			{
			case CEVT_LPWSTR:		
{
#ifndef USE_NATIVE_UNICODE
// do some conversion and assign
#else
only assign
#endif
break;
}
			case CEVT_FILETIME:		{ pRet  = &(lpProp->val.filetime) ;break; }	
			case CEVT_UI4:			{ pRet  = &(lpProp->val.uiVal) ;break; }	
			case CEVT_PIM_STREAM:	        { pRet  = &(lpProp->val.blob) ;break; }	
			default:		        { pRet  = (void*)0 ;break; }
			}
		}
		else
		{
			pRet = (void*)0;
		}
	}

	return pRet;
}

So now you can see ugly #ifndef USE_NATIVE_UNICODE with this C version and
I would have to put it everywhere
I need to convert in utf8. 

Then the templated version could be improved by using policy-based designed
that would allow me to choose what kind 
of allocation I want to use for my utf8 conversion (malloc, new, HeapAlloc)
and without any performance loss or
additional code.

I don't want to convince you to implement templates because average
programmer don't use them and find them tricky...
I am not even talking that it should a pain to implement .





Follow ups

References