www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Mixin templates as virtual function add tool

reply Voitech <woipoi gmail.com> writes:
Hi, I'm unfortunately in D this construction is not possible to 
define:

class A(T){
     abstract void method(S)(T arg1,S arg2);
}

As adding S to function declaration makes it not virtual.

But we can add this kind of functionality using mixin templates

mixin template BaseMix(T,S){
    abstract void method(T arg1,S arg2);
}

class Base{
    mixin BaseMix!(int,int);
}

//we can create now implementation by creation of other mixin
mixin template ImplMix(T,S){
    override void method(T arg1,S arg2){
     import std.stdio;
     writeln(T.strinof," ",S.stringof);
     //some dummy implementation
    }
}
//and initiate the class

class Impl:Base{
    mixin ImplMix!(int,int);
}

OK but i don't want to write each argument to mixin templates 
invocations
like:
    mixin ImplMix!(int,int);
    mixin ImplMix!(int,byte);
    mixin ImplMix!(int,string);
    mixin ImplMix!(int,Object);
    mixin ImplMix!(int,ubyte); etc.
It may produce a bug susceptible code as i would have to write it 
in two class definitions.

I created template that automatically calls mixins with PList... 
passed but i can't call it with mixins having more than one 
template param like ImplMix(T,S)


template MixinTypeIterate(alias mixinTemplate,TList...){
	static if(TList.length>0){
		mixin mixinTemplate!(TList[0]);
		static if(TList.length>1){
			mixin MixinTypeIterate!(mixinTemplate,TList[1..$]);
		}
	}
	
	
}
how to alias mixin template to be able to pass it to this one ?

class BaseClass(T){
    protected alias Types=AliasSeq!(int,string,ubyte);
    private alias WrappedMix(S)=mixin Mix!(T,S); //not compiles - 
mixins are no t regular templates
    mixin MixinTypeIterate!(WrappedImplMix,Types);
}
class ImplClass(T){
    private alias WrappedMix(T)=mixin ImplMix!(T,S); //not 
compiles - mixins are no t regular templates
    mixin MixinTypeIterate!(WrappedImplMix,Types);
}

How to make it work?

	
Apr 08 2016
parent ag0aep6g <anonymous example.com> writes:
On 08.04.2016 14:04, Voitech wrote:
 template MixinTypeIterate(alias mixinTemplate,TList...){
[...]
 }
 how to alias mixin template to be able to pass it to this one ?

 class BaseClass(T){
     protected alias Types=AliasSeq!(int,string,ubyte);
     private alias WrappedMix(S)=mixin Mix!(T,S); //not compiles - mixins
 are no t regular templates
private mixin template WrappedMix(S) {mixin BaseMix!(T, S);} Fixed a typo here: Mix -> BaseMix.
     mixin MixinTypeIterate!(WrappedImplMix,Types);
 }
 class ImplClass(T){
     private alias WrappedMix(T)=mixin ImplMix!(T,S); //not compiles -
 mixins are no t regular templates
Ditto: private mixin template WrappedMix(S) {mixin ImplMix!(T, S);} Fixed another typo here: parameter T -> parameter S. By the way, I find this very condensed style with no spaces around equals signs, after commas, or before braces quite hard to read.
     mixin MixinTypeIterate!(WrappedImplMix,Types);
 }
Here's another thing that may be interesting to you. You can a have sequence of sequences by wrapping them in a non-eponymous template: ---- template Box(stuff ...) {alias contents = stuff;} mixin template MixinTypeIterate(alias mixinTemplate, boxes ...) { static if (boxes.length > 0) { mixin mixinTemplate!(boxes[0].contents); mixin MixinTypeIterate!(mixinTemplate, boxes[1..$]); } } mixin template simpleExample(T ...) { void f(T args) {import std.stdio; writeln(args);} } mixin MixinTypeIterate!(simpleExample, Box!int, Box!(float, string)); void main() { f(42); f(42.2, "foo"); } ----
Apr 08 2016