Help with policy based design
Hi,
This question is not windows related even if it looks like so please
avoid to tell me to post on windows forum.
I want to create a policy based class that can receive any type of
pointers and that generally only assign it but in the case pointed
values is a string, there is a conversion or not depending if a define
is set or not.
so for instance I am using it like that :
void* pRet = NULL;
FILETIME ft;
ulong ulVal;
const wchar_t* wszText = L"My native unicode string";
pRet = IConvPtr<FILETIME *>( &ft ); // Do nothing only assign
pRet = IConvPtr<ulong *>( &ulong ); // Do nothing only assign
//Special case : do nothing if USE_NATIVE_UNICODE is defined or convert
// in utf8 and assign
pRet = IConvPtr<const wchar_t*>( wszText);
It was working fine but now I want to have more flexibility and to be
able to choose memory allocation policy so here is what I wrote
// Heap alloc policy
class MemPolicy_HeapAlloc {
protected:
void* alloc(size_t bytes, bool fZero = false) {
HANDLE hHeapProc = GetProcessHeap();
DWORD dwFlags = (fZero == true) ? HEAP_ZERO_MEMORY : 0;
if (hHeapProc) {
return HeapAlloc(hHeapProc,dwFlags,bytes);
}
}
};
// Generic case where we only assign pointer
template
< typename T,
typename alloc_policy
>
class IConvPtr : public alloc_policy
{
using alloc_policy::alloc;
public:
IConvPtr(T pVal) {
assign(aptr);
}
IConvPtr& IConvPtr::operator=(T aptr) {
assign(aptr);
}
inline void assign(T aptr) {
m_ptr = aptr;
}
operator void *() {
return m_ptr;
}
private:
void* m_ptr;
};
//Special case where we make conversion in utf8 if pointer is holding a
//native unicode string (utf16) and USE_NATIVE_UNICODE is not defined
template <>
class IConvPtr<wchar_t*, MemPolicy_HeapAlloc>
{
using alloc_policy::alloc;
public:
IConvPtr(wchar_t* pStringW)
{ convert_or_assign(pStringW); }
IConvPtr& IConvPtr::operator=(wchar_t* pStringW)
{ convert_or_assign((void*)pStringW); }
IConvPtr& IConvPtr::operator=(const wchar_t* pStringW)
{ convert_or_assign((void*)(pStringW)); }
void convert_or_assign(void * pStringW)
{
// if we are not using native unicode encnding(utf16) we need
// to convert pointed string into utf8
#ifndef USE_NATIVE_UNICODE
int nRet = ::WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)pStringW, -1, 0,
0, 0, 0);
if (nRet) {
LPSTR buf = (LPSTR) alloc(nRet+1);
if (buf) {
::WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)pStringW, -1, buf, nRet,
0, 0);
}
}
#else
// We are using utf16 so nothing to do - only assign
m_ptr = pStringW;
#endif
}
operator void *() {
return m_ptr;
}
private:
void* m_ptr;
};
I have the following error :
1>c:\gynoid\src\src\gynoid\src\UniConv.hxx(130) : error C2653:
'alloc_policy' : is not a class or namespace name
It seems my specialized template is not correctly declared or something
like that.
In addition I think my approach would be better if I could get rid of
templated parameters because I suppose it would be better to be able to
write :
//void* pRet = NULL;
IConvPtr pRet;
FILETIME ft;
ulong ulVal;
const wchar_t* wszText = L"My native unicode string";
pRet = &ft; // Do nothing only assign
pRet = &ulong; // Do nothing only assign
//Special case : do nothing if USE_NATIVE_UNICODE is defined or convert
// in utf8 and assign
pRet = wszText;
So from right hand side it should be possible to know type and thus to
avoid to type IConvPtr<VARTYPE> ....
Please give your opinions.