Help with policy based design

V

Vincent R

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::eek:perator=(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::eek:perator=(wchar_t* pStringW)
{ convert_or_assign((void*)pStringW); }

IConvPtr& IConvPtr::eek:perator=(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.
 
V

Vincent R

Finally I am starting with the following code given by soemone on this ng :

class IConvPtr {
void* m_ptr;
public:
IConvPtr() : m_ptr(0) {}

operator void *() { return m_ptr; }

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);
}
}
void dealloc(void* ptr) {
...
}


IConvPtr& operator=(wchar_t* pStringW) {
#ifndef USE_NATIVE_UNICODE
int nBufLen = ::WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)pStringW, -1,
0, 0, 0, 0);
if (nBufLen) {
LPSTR buf = (LPSTR) alloc(nBufLen+1);
if (buf) {
::WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)pStringW, -1, buf,
nBufLen, 0, 0);
m_ptr = buf;
// NOW I am supposed to deallocate but
depends how original string was allocated or even if it was allocated
}
}
#else
// We are using utf16 so nothing to do - only assign
m_ptr = pStringW;
#endif
return *this;
}

template <typename T>
IConvPtr& operator=(T aptr) {
m_ptr = aptr;
return *this;
}
};


Now the question is, it is possible to add policy based designed to
choose memory allocation. I would need to have a alloc and dealloc method.
 
V

Vincent R

Vincent R a écrit :
Finally I am starting with the following code given by soemone on this ng :

class IConvPtr {
void* m_ptr;
public:
IConvPtr() : m_ptr(0) {}

operator void *() { return m_ptr; }

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);
}
}
void dealloc(void* ptr) {
...
}


IConvPtr& operator=(wchar_t* pStringW) {
#ifndef USE_NATIVE_UNICODE
int nBufLen = ::WideCharToMultiByte(CP_UTF8, 0,
(LPCWSTR)pStringW, -1, 0, 0, 0, 0);
if (nBufLen) {
LPSTR buf = (LPSTR) alloc(nBufLen+1);
if (buf) {
::WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)pStringW, -1,
buf, nBufLen, 0, 0);
m_ptr = buf;
// NOW I am supposed to deallocate but
depends how original string was allocated or even if it was allocated
}
}
#else
// We are using utf16 so nothing to do - only assign
m_ptr = pStringW;
#endif
return *this;
}

template <typename T>
IConvPtr& operator=(T aptr) {
m_ptr = aptr;
return *this;
}
};


Now the question is, it is possible to add policy based designed to
choose memory allocation. I would need to have a alloc and dealloc method.
Ok I found by myself. Sorry for the noise
 
P

Pascal J. Bourguignon

Vincent R said:
class MemPolicy_HeapAlloc {
protected:
void* alloc(size_t bytes, bool fZero = false) {
[...]
// Generic case where we only assign pointer
template
< typename T,
typename alloc_policyclass IConvPtr : public alloc_policy
{
using alloc_policy::alloc;
[...]
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

Perhaps:

using typename alloc_policy::alloc;


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

Yes, if you declare pRet to be an IConvPtr, you could have
constructors in IConvPtr to convert automatically from FILETIME or
ulong.

IConvPtr::IConvPtr(const FILETIME& ft){ ... }
IConvPtr::IConvPtr(const ulong& ul){ ... }

IConvPtr pRet;
pRet=ft;
pRet=ul;
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top