www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Mixin virtual functions -- overloads

reply Justin <mrjnewt gmail.com> writes:
I'm having some trouble getting mixed-in functions to override each other
properly. Here's the function I've templated:
private template tRegister(T) {
	static public BindableProperty Register(string propName, TypeInfo ti,
BindableObject owner, T defaultValue) {
		return _Register(propName, ti, owner, (cast(void*)defaultValue));
	}
}

Then, in a class, I'm mixing it in numerous times:
mixin tRegister!(bool) tm_bool;
mixin tRegister!(byte) tm_byte;
mixin tRegister!(ubyte) tm_ubyte;	
mixin tRegister!(int) tm_int;
mixin tRegister!(uint) tm_uint;
mixin tRegister!(long) tm_long;
mixin tRegister!(ulong) tm_ulong;
mixin tRegister!(float) tm_float;
mixin tRegister!(double) tm_double;
mixin tRegister!(real) tm_real;
mixin tRegister!(char) tm_char;
mixin tRegister!(char[]) tm_string;
mixin tRegister!(Object) tm_Object;

I then have a bunch of aliases like so:
alias tm_bool.Register Register;
alias tm_byte.Register Register;
alias tm_ubyte.Register Register;
...etc.

In a unittest, I try making these calls:
NameProperty = BindableProperty.Register("Name", typeid(string), this,
"Donald");
AngerProperty = BindableProperty.Register("Anger", typeid(uint), this,
cast(uint)(0));

Compilation breaks at the second line with these errors:
A.d(122): function alias A.BindableProperty.Register called with argument types:
	(char[5u],TypeInfo,Duck,uint)
matches both:
	A.BindableProperty.tRegister!(bool).Register(char[],TypeInfo,BindableObject,bool)
and:
	A.BindableProperty.tRegister!(char).Register(char[],TypeInfo,BindableObject,char)

It shouldn't match either of these, only the uint overload.
Feb 23 2009
next sibling parent reply Justin <mrjnewt gmail.com> writes:
I can probably figure out the bulk of the problem if someone can direct me to
the correct way of mixing in a bunch of functions and having them overload each
other properly. I'm using D 1.39 and the documentation indicated that I needed
to use the MixinDeclaration and aliases, so this is what I have:
        mixin tSetValue!(bool) tm_bool;
	mixin tSetValue!(byte) tm_byte;
	mixin tSetValue!(ubyte) tm_ubyte;	
	mixin tSetValue!(int) tm_int;
	mixin tSetValue!(uint) tm_uint;
	mixin tSetValue!(long) tm_long;
	mixin tSetValue!(ulong) tm_ulong;
	mixin tSetValue!(float) tm_float;
	mixin tSetValue!(double) tm_double;
	mixin tSetValue!(real) tm_real;
	mixin tSetValue!(char) tm_char;
	mixin tSetValue!(Object) tm_Object;

	alias tm_bool.SetValue SetValue;
	alias tm_byte.SetValue SetValue;
	alias tm_ubyte.SetValue SetValue;
	alias tm_int.SetValue SetValue;
	alias tm_uint.SetValue SetValue;
	alias tm_long.SetValue SetValue;
	alias tm_ulong.SetValue SetValue;
	alias tm_float.SetValue SetValue;
	alias tm_double.SetValue SetValue;
	alias tm_real.SetValue SetValue;
	alias tm_char.SetValue SetValue;
	alias tm_Object.SetValue SetValue;

But it seems that only the first use is recognized and the compiler tries to
match all uses of the function to that first signature (bool).
Feb 24 2009
next sibling parent "Tim M" <a b.com> writes:
On Wed, 25 Feb 2009 06:31:37 +1300, Justin <mrjnewt gmail.com> wrote:

 I can probably figure out the bulk of the problem if someone can direct  
 me to the correct way of mixing in a bunch of functions and having them  
 overload each other properly. I'm using D 1.39 and the documentation  
 indicated that I needed to use the MixinDeclaration and aliases, so this  
 is what I have:
         mixin tSetValue!(bool) tm_bool;
 	mixin tSetValue!(byte) tm_byte;
 	mixin tSetValue!(ubyte) tm_ubyte;	
 	mixin tSetValue!(int) tm_int;
 	mixin tSetValue!(uint) tm_uint;
 	mixin tSetValue!(long) tm_long;
 	mixin tSetValue!(ulong) tm_ulong;
 	mixin tSetValue!(float) tm_float;
 	mixin tSetValue!(double) tm_double;
 	mixin tSetValue!(real) tm_real;
 	mixin tSetValue!(char) tm_char;
 	mixin tSetValue!(Object) tm_Object;

 	alias tm_bool.SetValue SetValue;
 	alias tm_byte.SetValue SetValue;
 	alias tm_ubyte.SetValue SetValue;
 	alias tm_int.SetValue SetValue;
 	alias tm_uint.SetValue SetValue;
 	alias tm_long.SetValue SetValue;
 	alias tm_ulong.SetValue SetValue;
 	alias tm_float.SetValue SetValue;
 	alias tm_double.SetValue SetValue;
 	alias tm_real.SetValue SetValue;
 	alias tm_char.SetValue SetValue;
 	alias tm_Object.SetValue SetValue;

 But it seems that only the first use is recognized and the compiler  
 tries to match all uses of the function to that first signature (bool).

You are probably using alias and/or mixin incorrectly. It would be easier with full source but as a guess are you trying to do something like this: module main; class TypeThing(T) { T data; this() { // } void SetValue(T data) { this.data = data; } } class boolThing : TypeThing!(bool) { this() { // } } void Register(char[] t)() { mixin("class "~t~"Thing : TypeThing!("~t~") { this() { // } }"); } void main() { Register!("bool"); Register!("char"); }
Feb 24 2009
prev sibling next sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Tue, Feb 24, 2009 at 11:39 PM, Tim M <a b.com> wrote:
 On Wed, 25 Feb 2009 06:31:37 +1300, Justin <mrjnewt gmail.com> wrote:

 You are probably using alias and/or mixin incorrectly. It would be easier
 with full source but as a guess are you trying to do something like this:

What he's doing is right, ostensibly; template mixins have never cooperated with overloading.
 module main;


 class TypeThing(T)
 {
 =A0 =A0 =A0T data;
 =A0 =A0 =A0this()
 =A0 =A0 =A0{
 =A0 =A0 =A0 =A0 =A0 =A0//
 =A0 =A0 =A0}
 =A0 =A0 =A0void SetValue(T data)
 =A0 =A0 =A0{
 =A0 =A0 =A0 =A0 =A0 =A0this.data =3D data;
 =A0 =A0 =A0}
 }

 class boolThing : TypeThing!(bool)
 {
 =A0 =A0 =A0this()
 =A0 =A0 =A0{
 =A0 =A0 =A0 =A0 =A0 =A0//
 =A0 =A0 =A0}
 }

 void Register(char[] t)()
 {
 =A0 =A0 =A0mixin("class "~t~"Thing : TypeThing!("~t~")
 =A0 =A0 =A0 =A0 =A0 =A0{
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0this()
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0//
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0}
 =A0 =A0 =A0 =A0 =A0 =A0}");
 }

 void main()
 {
 =A0 =A0 =A0Register!("bool");
 =A0 =A0 =A0Register!("char");
 }

I.. really am not sure what you're trying to do there? But your idea of using string mixins instead of template mixins might be useful here. If only we didn't have to resort to string mixins at every turn :P
Feb 24 2009
prev sibling parent "Tim M" <a b.com> writes:
On Wed, 25 Feb 2009 18:02:09 +1300, Jarrett Billingsley  
<jarrett.billingsley gmail.com> wrote:

 On Tue, Feb 24, 2009 at 11:39 PM, Tim M <a b.com> wrote:
 On Wed, 25 Feb 2009 06:31:37 +1300, Justin <mrjnewt gmail.com> wrote:

 You are probably using alias and/or mixin incorrectly. It would be  
 easier
 with full source but as a guess are you trying to do something like  
 this:

What he's doing is right, ostensibly; template mixins have never cooperated with overloading.
 module main;


 class TypeThing(T)
 {
      T data;
      this()
      {
            //
      }
      void SetValue(T data)
      {
            this.data = data;
      }
 }

 class boolThing : TypeThing!(bool)
 {
      this()
      {
            //
      }
 }

 void Register(char[] t)()
 {
      mixin("class "~t~"Thing : TypeThing!("~t~")
            {
                  this()
                  {
                        //
                  }
            }");
 }

 void main()
 {
      Register!("bool");
      Register!("char");
 }

I.. really am not sure what you're trying to do there? But your idea of using string mixins instead of template mixins might be useful here. If only we didn't have to resort to string mixins at every turn :P

I dont know what I was trying to do either :). Infact the classes are defined in the wrong scope. Can you show what the actuall overload template mixin problem is?
Feb 24 2009
prev sibling parent Michel Fortin <michel.fortin michelf.com> writes:
On 2009-02-23 18:09:54 -0500, Justin <mrjnewt gmail.com> said:

 Compilation breaks at the second line with these errors:
 A.d(122): function alias A.BindableProperty.Register called with 
 argument types:
 	(char[5u],TypeInfo,Duck,uint)
 matches both:
 	A.BindableProperty.tRegister!(bool).Register(char[],TypeInfo,BindableObject,bool)

A.BindableProperty.tRegister!(char).Register(char[],TypeInfo,BindableObject,char) It
 
 shouldn't match either of these, only the uint overload.

I've had the same problem while creating wrapper classes for the D/Objective-C bridge. It'd be solved in D2 if overload sets were applying to mixed-in functions. Anyway, in my case I also had the option of writing the functions directly in the class when needed (it's more verbose, but overloading works). -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Feb 25 2009