Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
April 26, 2011 Method overloading without Type2Type | ||||
---|---|---|---|---|
| ||||
I'm just reading Andreis book "Modern C++ Design" and try to translate a few examples to D 2. My most recent test looks as follows: import std.stdio; struct Type2Type(T){ typedef T OriginalType; } class foo(T,R...) : foo!(R) { public void print(){ super.print(); writefln(T.stringof); } alias foo!(R).echo echo; public void echo(Type2Type!(T)) { writefln(T.stringof); } } class foo(T){ public void print(){ writefln("end " ~ T.stringof); } public void echo(Type2Type!(T)) { writefln(T.stringof); } } void main(string[] args){ auto test = new foo!(int,float,double,short,byte)(); test.print(); test.echo(Type2Type!(double)()); test.echo(Type2Type!(short)()); } I'm wondering if there is any way in D 2 to not use Type2Type so that the calls to echo would look like: test.echo!(double)(); test.echo!(short)(); The solution does not have to use inheritance, any idea? -- Kind Regards Benjamin Thaut |
April 26, 2011 Re: Method overloading without Type2Type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Benjamin Thaut | Benjamin Thaut:
> import std.stdio;
>
> struct Type2Type(T){
> typedef T OriginalType;
> }
>
> class foo(T,R...) : foo!(R) {
> public void print(){
> super.print();
> writefln(T.stringof);
> }
>
> alias foo!(R).echo echo;
> public void echo(Type2Type!(T)) {
> writefln(T.stringof);
> }
> }
>
> class foo(T){
> public void print(){
> writefln("end " ~ T.stringof);
> }
>
> public void echo(Type2Type!(T)) {
> writefln(T.stringof);
> }
> }
>
> void main(string[] args){
> auto test = new foo!(int,float,double,short,byte)();
> test.print();
>
> test.echo(Type2Type!(double)());
> test.echo(Type2Type!(short)());
> }
Try to compile that code with "-w" (warnings).
Bye,
bearophile
|
April 26, 2011 Re: Method overloading without Type2Type | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > Try to compile that code with "-w" (warnings). http://d.puremagic.com/issues/show_bug.cgi?id=3836 Bye, bearophile |
April 26, 2011 Re: Method overloading without Type2Type | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | Am 26.04.2011 13:43, schrieb bearophile: >> Try to compile that code with "-w" (warnings). > > http://d.puremagic.com/issues/show_bug.cgi?id=3836 > > Bye, > bearophile Thanks, but that is not connected to my question at all, I want to implement the echo method so that the type is passed as a template argument, and not as a function argument. While that is happening I still want to be able to overload the function. Is this possible in D 2? -- Kind Regards Benjamin Thaut |
April 26, 2011 Re: Method overloading without Type2Type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Benjamin Thaut | On Tue, Apr 26, 2011 at 18:41, Benjamin Thaut <code@benjamin-thaut.de> wrote: > Thanks, but that is not connected to my question at all, > I want to implement the echo method so that the type is passed as a template > argument, and not as a function argument. While that is happening I still > want to be able to overload the function. > Is this possible in D 2? I'm not sure I understand what you're trying to do (didn't read "Modern C++ design"). Here is something that compiles: import std.stdio; class Foo(T,R...) : Foo!(R) { public void print(){ writeln(T.stringof); super.print(); } public void echo(U)(U u = U.init) { writeln(U.stringof); } } class Foo(T){ public void print(){ writeln("end: " ~ T.stringof); } public void echo(U)(U u = U.init) { writeln(U.stringof); } } void main(string[] args){ auto test = new Foo!(int,float,double,short,byte)(); test.print(); test.echo!double; test.echo!short; } I don't know if classes are necessary for what you've in mind. I tend to use structs: import std.stdio; struct Foo(T,R...) { void print(){ static if (R.length) { Foo!(R) fr; fr.print; } writeln(T.stringof); } void echo(U)(U u = U.init) { writefln(U.stringof);} } void main(string[] args){ Foo!(int,float,double,short,byte) test; test.print; test.echo!double; test.echo!short; } |
April 26, 2011 Re: Method overloading without Type2Type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | Am 26.04.2011 21:55, schrieb Philippe Sigaud: > On Tue, Apr 26, 2011 at 18:41, Benjamin Thaut<code@benjamin-thaut.de> wrote: >> Thanks, but that is not connected to my question at all, >> I want to implement the echo method so that the type is passed as a template >> argument, and not as a function argument. While that is happening I still >> want to be able to overload the function. >> Is this possible in D 2? > > I'm not sure I understand what you're trying to do (didn't read > "Modern C++ design"). Here is something that compiles: > > import std.stdio; > > class Foo(T,R...) : Foo!(R) { > public void print(){ > writeln(T.stringof); > super.print(); > } > > public void echo(U)(U u = U.init) { > writeln(U.stringof); > } > } > > class Foo(T){ > public void print(){ > writeln("end: " ~ T.stringof); > } > > public void echo(U)(U u = U.init) { > writeln(U.stringof); > } > } > > void main(string[] args){ > auto test = new Foo!(int,float,double,short,byte)(); > test.print(); > > test.echo!double; > test.echo!short; > } > The Problem with that version is, that the code that is generated looks like void main(string[] args){ auto test = new Foo!(int,float,double,short,byte)(); test.print(); test.echo!double(double.init); test.echo!short(short.init); } If the types that are used, are no simple data types, but rather large structs, they are copied on every function call. Thats exactly what I want to avoid. The Type2Type template has a size of 0, thats why I'm using that in the first place. -- Kind Regards Benjamin Thaut |
April 26, 2011 Re: Method overloading without Type2Type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Benjamin Thaut | On Tue, Apr 26, 2011 at 22:06, Benjamin Thaut <code@benjamin-thaut.de> wrote: > The Problem with that version is, that the code that is generated looks like > > void main(string[] args){ > auto test = new Foo!(int,float,double,short,byte)(); > test.print(); > test.echo!double(double.init); > test.echo!short(short.init); > } > > If the types that are used, are no simple data types, but rather large structs, they are copied on every function call. Thats exactly what I want to avoid. The Type2Type template has a size of 0, thats why I'm using that in the first place. In that case, just use echo(U)() { ...}, like this: import std.stdio; class Foo(T,R...) : Foo!(R) { public void print(){ writefln(T.stringof); super.print(); } public void echo(U)() { writefln(U.stringof); } } class Foo(T){ public void print(){ writefln("end: " ~ T.stringof); } public void echo(U)() { writefln(U.stringof); } } void main(string[] args){ auto test = new Foo!(int,float,double,short,byte)(); test.print(); test.echo!double; test.echo!short; } What's your global goal with this construction? What are you trying to achieve? |
April 26, 2011 Re: Method overloading without Type2Type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Benjamin Thaut | Benjamin Thaut:
> The Type2Type template has a size of 0, thats why I'm using that in the first place.
Almost. Maybe to allow addressability with pointers the minimal struct size in D is 1 byte (0-length fixed-sized arrays may require zero bytes on DMD and 1 bit on LDC):
struct Type2Type(T){
typedef T OriginalType;
}
static assert ((Type2Type!int).sizeof == 1);
void main() {}
Bye,
bearophile
|
April 27, 2011 Re: Method overloading without Type2Type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Philippe Sigaud | Am 26.04.2011 22:41, schrieb Philippe Sigaud: > On Tue, Apr 26, 2011 at 22:06, Benjamin Thaut<code@benjamin-thaut.de> wrote: >> The Problem with that version is, that the code that is generated looks like >> >> void main(string[] args){ >> auto test = new Foo!(int,float,double,short,byte)(); >> test.print(); >> test.echo!double(double.init); >> test.echo!short(short.init); >> } >> >> If the types that are used, are no simple data types, but rather large >> structs, they are copied on every function call. Thats exactly what I want >> to avoid. The Type2Type template has a size of 0, thats why I'm using that >> in the first place. > > In that case, just use echo(U)() { ...}, like this: > > import std.stdio; > > class Foo(T,R...) : Foo!(R) { > public void print(){ > writefln(T.stringof); > super.print(); > } > > public void echo(U)() { > writefln(U.stringof); > } > } > > class Foo(T){ > public void print(){ > writefln("end: " ~ T.stringof); > } > > public void echo(U)() { > writefln(U.stringof); > } > } > > void main(string[] args){ > auto test = new Foo!(int,float,double,short,byte)(); > test.print(); > > test.echo!double; > test.echo!short; > } > > What's your global goal with this construction? What are you trying to achieve? struct Foo {...} struct Bar {...} void* poolAllocate(size_t sz){...}; abstract class Allocator(T){ //needs to be implemented by user to fill obj with data public abstract void init(ref T obj); public void make(Type2Type!(T)){ void* ptr = poolAllocate(T.sizeof); T* obj = emplace!(T)(ptr[0..T.sizeof]); init(*obj); } abstract void produce(); } abstract class Allocator(T,R...) : Allocator!(R) { //needs to be implemented by user to fill obj with data public abstract void init(ref T obj); alias Allocator!(R).make make; public void make(Type2Type!(T)){ void* ptr = poolAllocate(T.sizeof); T* obj = emplace!(T)(ptr[0..T.sizeof]); init(*obj); } } class UserImpl : Allocator!(Foo,Bar){ override void init(ref Foo obj){ //fill Foo with data } override void init(ref Bar obj){ //fill Bar with data } override void produce(){ for(...){ make(Type2Type!(Foo)); } for(...){ make(Type2Type!(Bar)); } } } I do this to hide away allocation and pointer arithmetic from the user. -- Kind Regards Benjamin Thaut |
Copyright © 1999-2021 by the D Language Foundation