www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Delegate or function pointer overloading?

reply Chad J <gamerchad2.no-ip.org/email.txt LeftOfAtSignForEmail.meh> writes:
So I have a bunch of function pointers, all with the same name:

public void function( ubyte[], ubyte[] ) padds;
public void function( ubyte[], ubyte ) padds;
public void function( ushort[], ushort[] ) padds;
public void function( ushort[], ushort ) padds;
public void function( byte[], byte[] ) padds;
public void function( byte[], byte ) padds;
public void function( short[], short[] ) padds;
public void function( short[], short ) padds;

Yeah, yeah... compiler errors, padds conflicts with padds.  Not what I 
want to see. :(  What I want to do is be able to do something like this:

ubyte[] ArrayOne = new ubyte[32];
ubyte[] ArrayTwo = new ubyte[32];
padds( ArrayOne, ArrayTwo );

and have it use the correct function pointer, which will be pointing to 
one of two (or more) overloaded functions.  And I'd like to use function 
pointers because I don't want to do something like:

public void padds( ubyte[] lvalue, ubyte[] rvalue )
{
	if ( mmxSupported )
		padds_MMX( lvalue, rvalue );
	else
		padds_NoMMX( lvalue, rvalue );
}

Which seems like it would slow the code down unnecessarily, especially 
if I add in other function paths like padds_whatever and have a 
switch-case or a string of else-ifs.  I'd rather line up the various 
padds overloads to the correct padds_MMX and padds_NoMMX as the program 
starts to run, if I can help it.

I tried renaming all of the padds function pointers to padds1, padds2, 
padds3, padds4, etc.  That way I could reference the individual pointers 
and point them to the correct functions at runtime.  Problem is, it is 
rather inconvenient to have to remember which one padds1 is (even if it 
was named better), so I tried aliasing them all onto padds.  Still gave 
errors.  I even tried giving each function pointer its own module, that 
way I could make a reference like paddusb.padds = &padds_MMX; while 
still being able to overload padds, but that still gave problems.

So I was wondering if there is a way around this so that I can still 
overload padds while taking advantage of function pointers, or if this 
is impossible, why it is so?
Jan 11 2006
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Chad J" <gamerchad2.no-ip.org/email.txt LeftOfAtSignForEmail.meh> wrote in 
message news:dq2o02$1598$1 digitaldaemon.com...
 So I was wondering if there is a way around this so that I can still 
 overload padds while taking advantage of function pointers, or if this is 
 impossible, why it is so?

How about something like: static this() { // determine CPU type with CPUID // padds_ubauba means padds(ubyte[], ubyte[]) if(mmxSupported) padds_ubauba = &padds_ubaubaMMX; else padds_ubauba = &padds_ubaubaNoMMX; // ... and so on, for all the other ones } void padds_ubaubaMMX(ubyte[] l, ubyte[] r) { // MMX implementation } void padds_ubabuaNoMMX(ubyte[] l, ubyte[] r) { // non-MMX implementation } void function(ubyte[], ubyte[]) padds_ubauba; void padds(ubyte[] l, ubyte[] r) { padds_ubauba(l, r); } This way, (1) The correct function is selected at module initialization, by setting padds_ubauba to point to the correct version of the padds_ubaubaXXX function. No determining which function to use every loop. (2) padds() can now be overloaded to take other param types. (3). padds() is so simple that the compiler will probably inline it, making it even faster.
Jan 11 2006
parent Chad J <gamerchad2.no-ip.org/email.txt LeftOfAtSignForEmail.meh> writes:
Jarrett Billingsley wrote:
 "Chad J" <gamerchad2.no-ip.org/email.txt LeftOfAtSignForEmail.meh> wrote in 
 message news:dq2o02$1598$1 digitaldaemon.com...
 
So I was wondering if there is a way around this so that I can still 
overload padds while taking advantage of function pointers, or if this is 
impossible, why it is so?

How about something like: static this() { // determine CPU type with CPUID // padds_ubauba means padds(ubyte[], ubyte[]) if(mmxSupported) padds_ubauba = &padds_ubaubaMMX; else padds_ubauba = &padds_ubaubaNoMMX; // ... and so on, for all the other ones } void padds_ubaubaMMX(ubyte[] l, ubyte[] r) { // MMX implementation } void padds_ubabuaNoMMX(ubyte[] l, ubyte[] r) { // non-MMX implementation } void function(ubyte[], ubyte[]) padds_ubauba; void padds(ubyte[] l, ubyte[] r) { padds_ubauba(l, r); } This way, (1) The correct function is selected at module initialization, by setting padds_ubauba to point to the correct version of the padds_ubaubaXXX function. No determining which function to use every loop. (2) padds() can now be overloaded to take other param types. (3). padds() is so simple that the compiler will probably inline it, making it even faster.

Alright I tried it out and it ran well. I tested this against direct function calls and there was little if any performance difference. Direct calls seemed about 3% faster, but that could have easily been noise in my test data. As an added bonus, I didn't have to do anything like padds_ubaubaMMX; because the compiler seems to match the function pointer to the correct overload of padds_MMX when I do padds_ubauba = &padds_MMX. Cool. Thanks for the help Jarrett.
Jan 11 2006