Partial Specialization workaround

P

Philip Lawatsch

Hi

I'd like to implement some kind if type traits myself, but I have to
support broken compilers (like visual studio) that do not support
Partial Specialization.

My first shot was something like this:

----8<---
typedef char IsPODForListArrayTrue;
typedef struct {char bla[2];} IsPODForListArrayFalse;

IsPODForListArrayTrue IsPODForListArrayDummy(int);
IsPODForListArrayTrue IsPODForListArrayDummy(long);

IsPODForListArrayFalse IsPODForListArrayDummy(...);

#define IsPODForListArray(x) (sizeof(IsPODForListArrayDummy(x)) ==
sizeof(IsPODForListArrayTrue))

-----8<----

This seems to work, BUT, the problem here is that I cant just pass a
typename to IsPodForListArray but rather have to pass something real.

eg. IsPodForListArray (int) <-- wont work

int foo; IsPodForListArray(foo) <-- works

This is not acceptable, since I do want to use this in places where i
can only use types (eg template parameters).

I do want to implement it myself, and not add any non std. libs.


Any ideas of what I could do ?
I somehow have to work around the need for partial specialization ..


with kind regards Philip
 
A

Alf P. Steinbach

Hi

I'd like to implement some kind if type traits myself, but I have to
support broken compilers (like visual studio) that do not support
Partial Specialization.

My first shot was something like this:

----8<---
typedef char IsPODForListArrayTrue;
typedef struct {char bla[2];} IsPODForListArrayFalse;

IsPODForListArrayTrue IsPODForListArrayDummy(int);
IsPODForListArrayTrue IsPODForListArrayDummy(long);

IsPODForListArrayFalse IsPODForListArrayDummy(...);

#define IsPODForListArray(x) (sizeof(IsPODForListArrayDummy(x)) ==
sizeof(IsPODForListArrayTrue))

-----8<----

This seems to work, BUT, the problem here is that I cant just pass a
typename to IsPodForListArray but rather have to pass something real.

eg. IsPodForListArray (int) <-- wont work

int foo; IsPodForListArray(foo) <-- works

This is not acceptable, since I do want to use this in places where i
can only use types (eg template parameters).

I do want to implement it myself, and not add any non std. libs.


Any ideas of what I could do ?
I somehow have to work around the need for partial specialization ..

I fail to see where partial specialization enters the picture.

Off the cuff:


template< typename T >
struct IsBasicType{ enum{ value = 0 }; };

template<> struct IsBasicType<int> { enum{ value = 1 }; };
template<> struct IsBasicType<long> { enum{ value = 1 }; };


Checking for POD'ness is much more involved, but still I don't
see the partial specialization (which is a specialization where
just a subset of the template arguments are bound).
 
P

Philip Lawatsch

John Harrison wrote:

I don't understand. I understand what partial specialization, but my code
didn't use partial specialization so I don't see what the problem with it
is.

Yea, just realized this !
Sorry, i just saw "template" and didnt read much further, this was
really my fault!

Your code works fine for what i need, so thanks a lot !

with kind regards philip
 
J

John Harrison

Philip Lawatsch said:
<snip code>


Yea, like this, only that this is partial specialization ....


with kind regards Philip

I don't understand. I understand what partial specialization, but my code
didn't use partial specialization so I don't see what the problem with it
is.

Perhaps if you posted the code that needs to distinguish between POD and
non-POD. Nested template types are often a solution to the lack of partial
specialization.

john
 
P

Philip Lawatsch

John said:
I don't understand. I understand what partial specialization, but my code
didn't use partial specialization so I don't see what the problem with it
is.

Perhaps if you posted the code that needs to distinguish between POD and
non-POD. Nested template types are often a solution to the lack of partial
specialization.

One little confusion on my side though
What i have now is:

#define IsPODForListArrayDefine(x) template <>\
class IsPODForListArrayDummy<x>\
{\
public:\
enum {Result = FC_True};\
};

template <class T>
class IsPODForListArrayDummy
{
public:
enum { Result = false };
};

IsPODForListArrayDefine(FC_Int)
IsPODForListArrayDefine(FC_Uint)


#undef IsPODForListArrayDefine

#define IsPODForListArray(x) (IsPODForListArrayDummy<x>::Result)


and this works fine.

But now it will get tricky:

template <class T> class foo;

template <class T>
class IsPODForListArrayDummy < foo <T> >
{
public:
enum {result = FC_True};
};

This wont work, so what would I want to do in this case ?

with kind regards philip
 
P

Philip Lawatsch

Andrey said:
Where??? There's no partial specialization in this code. This is
_explicit_ specialization, which is supported by MSVC++ 6.0 compiler (if
that's the one you are talking about).

As I said 5 minutes later, i apologize for not thinking while reading
his code. My fault


with kind regards philip
 
A

Andrey Tarasevich

Philip said:
...
Yea, like this, only that this is partial specialization ....
...

Where??? There's no partial specialization in this code. This is
_explicit_ specialization, which is supported by MSVC++ 6.0 compiler (if
that's the one you are talking about).
 
J

John Harrison

Philip Lawatsch said:
One little confusion on my side though
What i have now is:

#define IsPODForListArrayDefine(x) template <>\
class IsPODForListArrayDummy<x>\
{\
public:\
enum {Result = FC_True};\
};

template <class T>
class IsPODForListArrayDummy
{
public:
enum { Result = false };
};

IsPODForListArrayDefine(FC_Int)
IsPODForListArrayDefine(FC_Uint)


#undef IsPODForListArrayDefine

#define IsPODForListArray(x) (IsPODForListArrayDummy<x>::Result)


and this works fine.

But now it will get tricky:

template <class T> class foo;

template <class T>
class IsPODForListArrayDummy < foo <T> >
{
public:
enum {result = FC_True};
};

This wont work, so what would I want to do in this case ?

with kind regards philip

You want to say that any foo<T> is POD? That seems strange because if T is
not POD how can foo<T> be? Indeed can any template be POD? Not sure of the
answer to that one.

In any case looks like you need partial template specialisation again.

john
 
P

Philip Lawatsch

John said:
You want to say that any foo<T> is POD? That seems strange because if T is
not POD how can foo<T> be? Indeed can any template be POD? Not sure of the
answer to that one.

Well, foo is actually a coordinate class, which only has 3 T inside.
Anything besides PODs would not make sense in this class (and only these
are used)

I know that this is not nice, but i'm currently speed hacking our array
class and got huge performance increase (>300%) when using malloc et al
for these coordinates in comparison to c++ new [newsize]and then copy.

In any case looks like you need partial template specialisation again.
Yea, but I found a workaround.
I typedef'd some of the most likely cases (like double, float and int)
and used these.

Not nice but anyway.

Btw, i've added stuff like

if (IsPOD(T))
{
// speed hack code here
}
else
{
// old code here
}

into the array.

Now the array seems to be slower than befor for the old data types, any
ideas why ?

I thought the compiler would emit the same code as befor for the non pod
types since IsPOD is a compile time decision and every normal
optimizer should get rid of that .. ?


with kind regarsd philip
 

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

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,019
Latest member
RoxannaSta

Latest Threads

Top