Re: Variadic Mixin/Template classes?
On Saturday, 25 November 2017 at 10:08:36 UTC, vit wrote: On Saturday, 25 November 2017 at 09:52:01 UTC, Chirs Forest wrote: [...] import std.meta : staticMap; class Bar(T) { T bar; } class Foo(Ts...){ staticMap!(Bar, Ts) bars; this(){ static foreach(i, alias T; Ts) bars[i] = new Bar!T; } } void main(){ auto foo = new Foo!(string, int, string, ubyte[2]); foo.bars[0].bar = "hello"; foo.bars[1].bar = 23; foo.bars[2].bar = "hello"; foo.bars[3].bar[0] = 88; foo.bars[3].bar[1] = 99; auto foo2 = new Foo!(ubyte, string); foo2.bars[0].bar = 9; foo2.bars[1].bar = "world"; } thankyou!
Re: Variadic Mixin/Template classes?
On Saturday, 25 November 2017 at 09:52:01 UTC, Chirs Forest wrote: I'd like to make a class that takes multiple template types (1 - several) which can hold an array/tuple of a second class that are instantiated with those types. class Bar(T) { T bar; } class Foo(T[]){ // not sure how to take variadic types here? Bar!(?)[] bars; //not sure how I'd define an array/tuple of multiple types this(){ foreach(int i, b; bars) b = new Bar!T[i]; } } void main(){ auto foo = new Foo!(string, int, string, ubyte[2]); foo.bars[0].bar = "hello"; foo.bars[1].bar = 23; foo.bars[2].bar = "hello"; foo.bars[3].bar[0] = 88; foo.bars[3].bar[1] = 99; auto foo2 = new Foo!(ubyte, string); foo.bars[0].bar = 9; foo.bars[1].bar = "world"; } import std.meta : staticMap; class Bar(T) { T bar; } class Foo(Ts...){ staticMap!(Bar, Ts) bars; this(){ static foreach(i, alias T; Ts) bars[i] = new Bar!T; } } void main(){ auto foo = new Foo!(string, int, string, ubyte[2]); foo.bars[0].bar = "hello"; foo.bars[1].bar = 23; foo.bars[2].bar = "hello"; foo.bars[3].bar[0] = 88; foo.bars[3].bar[1] = 99; auto foo2 = new Foo!(ubyte, string); foo2.bars[0].bar = 9; foo2.bars[1].bar = "world"; }
Variadic Mixin/Template classes?
I'd like to make a class that takes multiple template types (1 - several) which can hold an array/tuple of a second class that are instantiated with those types. class Bar(T) { T bar; } class Foo(T[]){ // not sure how to take variadic types here? Bar!(?)[] bars; //not sure how I'd define an array/tuple of multiple types this(){ foreach(int i, b; bars) b = new Bar!T[i]; } } void main(){ auto foo = new Foo!(string, int, string, ubyte[2]); foo.bars[0].bar = "hello"; foo.bars[1].bar = 23; foo.bars[2].bar = "hello"; foo.bars[3].bar[0] = 88; foo.bars[3].bar[1] = 99; auto foo2 = new Foo!(ubyte, string); foo.bars[0].bar = 9; foo.bars[1].bar = "world"; }
Re: object.factory with template classes for serializing subclasses automatically
On 2012-09-11 07:57, Chris Cain wrote: Ah, I see now. Well regardless, it couldn't be done so conveniently/transparently because Serializable!B wouldn't exist in the binary unless it was actually created in code. Hence proper runtime reflection is needed. I see no way out of this. -- /Jacob Carlborg
Re: object.factory with template classes for serializing subclasses automatically
On Tuesday, 11 September 2012 at 04:47:11 UTC, timotheecour wrote: Also, now that I think about it, why couldn't you do this? (it's equivalent): auto serialize(T)(T a) { auto c = cast(SerializerBase) new Serializer!T; return c.serialize(a); } that won't work with my example: class A{} class B:A{int x;} A a=new B; auto c=serialize(a); => T is A, but we want B so that serialization includes field x. Ah, I see now. Well regardless, it couldn't be done so conveniently/transparently because Serializable!B wouldn't exist in the binary unless it was actually created in code.
Re: object.factory with template classes for serializing subclasses automatically
Also, now that I think about it, why couldn't you do this? (it's equivalent): auto serialize(T)(T a) { auto c = cast(SerializerBase) new Serializer!T; return c.serialize(a); } that won't work with my example: class A{} class B:A{int x;} A a=new B; auto c=serialize(a); => T is A, but we want B so that serialization includes field x.
Re: object.factory with template classes for serializing subclasses automatically
On Tuesday, 11 September 2012 at 03:18:40 UTC, timotheecour wrote: auto serialize(T)(T a){ auto c=cast(SerializerBase)Object.factory("Serializer!("~typeid(a).to!string~").Serializer"); return c.serialize(a); } Also, now that I think about it, why couldn't you do this? (it's equivalent): auto serialize(T)(T a) { auto c = cast(SerializerBase) new Serializer!T; return c.serialize(a); }
Re: object.factory with template classes for serializing subclasses automatically
On Tuesday, 11 September 2012 at 03:18:40 UTC, timotheecour wrote: So the question is: is that technically impossible or not to enhance Object.factory in such ways? Unless someone else wants to correct me, I'm going to say technically impossible. Object.factory constructs a class at runtime given a string of the name of the class. Templates, however, are created at compile-time only. Basically, the compiler creates a new type every time it sees a template being used with new template arguments. So, as you can imagine, there doesn't exist any object for Object.factory to find at run time. Technically, code like this MIGHT be possible: --- import std.stdio; class MyB(T) { this() { writeln("hello MyB!(" ~ T.stringof ~")"); } } void main() { // create the actual type at compile-time Object b = Object.factory(MyB!int.classinfo.name); writeln("b = ", b); } --- In this case, the type (I'd think) is actually created at compile-time, so it actually exists so that Object.factory can get it. However, the code you showed in your previous post (just purely existing in the string) could never work.
Re: object.factory with template classes for serializing subclasses automatically
I don't understand how Object.factory could help with serializing. But what would help is if we did get proper runtime reflection. All that'd be needed would be to have Object.factory working with templates, here's how: unittest{ class A{} class B{int x;} A a=new B; auto c=serialize(a);//will serialize field "x", no need to register!B } auto serialize(T)(T a){ auto c=cast(SerializerBase)Object.factory("Serializer!("~typeid(a).to!string~").Serializer"); return c.serialize(a); } class SerializerBase{//could also be an interface auto serialize(Object a){} } class Serializer(T):SerializerBase{ auto serialize(Object a){ auto b=cast(T)a; foreach (name; __traits(allMembers, T)) { //now we have access to fields of most derived type; //we can get the fields from base class as well. } } } I've left out details to focus on the key part. Deserialization is very similar. So the question is: is that technically impossible or not to enhance Object.factory in such ways?
Re: object.factory with template classes for serializing subclasses automatically
On 2012-09-10 01:27, timotheecour wrote: Is there a way to use Object.factory with template classes? eg: class A(T){ T x; } auto a=Object.factory("A!int"); Right now this fails (returns null). Use case: If we had this, it would GREATLY simplify serialization (eg as in the orange library) by not having to manually register subclasses of a given class, eg: class B{} class C:B{int x;} B c=new C; right now with orange, we need to register class C before calling serialization. If something like Object.factory("A!int") worked, this step could be made automatic. I don't understand how Object.factory could help with serializing. But what would help is if we did get proper runtime reflection. -- /Jacob Carlborg
object.factory with template classes for serializing subclasses automatically
Is there a way to use Object.factory with template classes? eg: class A(T){ T x; } auto a=Object.factory("A!int"); Right now this fails (returns null). Use case: If we had this, it would GREATLY simplify serialization (eg as in the orange library) by not having to manually register subclasses of a given class, eg: class B{} class C:B{int x;} B c=new C; right now with orange, we need to register class C before calling serialization. If something like Object.factory("A!int") worked, this step could be made automatic.
Re: Template classes
On Thu, Apr 16, 2009 at 1:14 PM, Arild Boes wrote: > Actually the f-call syntactic sugar seems like a good way to keep core > classes of any library very lean and mean, whilst maintaining the ability to > expand the module without re-compiling the original library! (just import > this guy, and the new functions will be available to you as if declared in > the original type). Unfortunately it only works with arrays and AAs at the moment, though the plan for D2 was to extend it to arbitrary types. Some libraries (like Dog) do abuse the fact that it works on arrays, though, by doing clever things like "typedef void[] Something;", and you don't even know it's an array ;)
Re: Template classes
Jarrett Billingsley skrev: On Wed, Apr 15, 2009 at 12:13 PM, Arild Boes wrote: Take a look at the 'this' of D2, it allows to create wrapper structs, so you can just add methods to the built-in arrays. Bye, bearophile Please elaborate on this. How does one do that? With the new, delicious "alias this." struct Array(T) { T[] blah; alias blah this; // woo! void print() { writefln(blah); } } void main() { Array!(int) x; // anything not defined in Array will instead be looked up in the 'alias this' member x.length = 5; x[2] = 3; x.print(); } Though actually I'm not sure why bearophile suggested this, since even in D1, you can define 'extension' methods for arrays and AAs by simply declaring a function that takes an array or AA as its first parameter. It's syntactic sugar for a normal function call. By taking advantage of templates and IFTI you can make these methods work for all kinds of arrays. void print(T)(T[] arr) { writefln(arr); } void main() { int[] x; x.length = 5; x[2] = 3; x.print(); // same as print(x); } This will work in D1 or D2. I see. Thank you very much for that answer. Actually the f-call syntactic sugar seems like a good way to keep core classes of any library very lean and mean, whilst maintaining the ability to expand the module without re-compiling the original library! (just import this guy, and the new functions will be available to you as if declared in the original type).
Re: Template classes
Jarrett Billingsley: > Though actually I'm not sure why bearophile suggested this, The original poster seems to want to add some methods to a standard array. With this you can give another module something that acts like an array that also has such methods, or replaces them. With the old way you also need to import the free functions into the other module... Bye, bearophile
Re: Template classes
On Wed, Apr 15, 2009 at 12:13 PM, Arild Boes wrote: >> Take a look at the 'this' of D2, it allows to create wrapper structs, so >> you can just add methods to the built-in arrays. >> >> Bye, >> bearophile > > Please elaborate on this. How does one do that? With the new, delicious "alias this." struct Array(T) { T[] blah; alias blah this; // woo! void print() { writefln(blah); } } void main() { Array!(int) x; // anything not defined in Array will instead be looked up in the 'alias this' member x.length = 5; x[2] = 3; x.print(); } Though actually I'm not sure why bearophile suggested this, since even in D1, you can define 'extension' methods for arrays and AAs by simply declaring a function that takes an array or AA as its first parameter. It's syntactic sugar for a normal function call. By taking advantage of templates and IFTI you can make these methods work for all kinds of arrays. void print(T)(T[] arr) { writefln(arr); } void main() { int[] x; x.length = 5; x[2] = 3; x.print(); // same as print(x); } This will work in D1 or D2.
Re: Template classes
bearophile skrev: Andrew Spott: yes, however there are going to be a few new classes that will be implemented in this (dot products, cross products, etc) You mean a few new methods. Take a look at the 'this' of D2, it allows to create wrapper structs, so you can just add methods to the built-in arrays. Bye, bearophile Please elaborate on this. How does one do that? /ab
Re: Template classes
Andrew Spott: > yes, however there are going to be a few new classes that will be implemented > in this (dot products, cross products, etc) You mean a few new methods. Take a look at the 'this' of D2, it allows to create wrapper structs, so you can just add methods to the built-in arrays. Bye, bearophile
Re: Template classes
yes, however there are going to be a few new classes that will be implemented in this (dot products, cross products, etc) Thanks for the help. -Andrew Steven Schveighoffer Wrote: > On Tue, 14 Apr 2009 17:33:29 -0400, Steven Schveighoffer > wrote: > > > e.g., the following code does almost the same thing you are doing without > > requiring a new class: > > correction, the code does *exactly* the same thing you are doing. > > -Steve
Re: Template classes
On Tue, 14 Apr 2009 17:33:29 -0400, Steven Schveighoffer wrote: e.g., the following code does almost the same thing you are doing without requiring a new class: correction, the code does *exactly* the same thing you are doing. -Steve
Re: Template classes
On Tue, 14 Apr 2009 17:01:28 -0400, Andrew Spott wrote: So, the attached is supposed to be a class that creates a vector of any type (I would like it to only take numerical values (int, float, real, double, etc), however, I am ok with it taking others (not that I see why someone would use it that way). I tried to compile it with the following, but it won't compile. I don't really understand the errors I'm getting either. Can someone tell me what I'm doing wrong? If you need more information, let me know. -Andrew void testvector() { auto v = new Vector!(float)(3, 12.0); writefln(v.toString()); int n = 0; while (n < n.size()) { v[n] = n; } writefln(v.toString()); } Try the attached (untested). You might get some insight into how d should be written by looking at the changes. BTW, if this is just an exercise fine, but your example is a completely redundant implementation of standard builtin arrays. e.g., the following code does almost the same thing you are doing without requiring a new class: void testvector() { auto v = new float[3]; v[0..$] = 12.0; writefln(v); int n = 0; while(n < v.length) { // bug in original code v[n] = n; n++; // bug in original code } writefln(v); } -Steve vector.d Description: Binary data
Re: Template classes
On Wed, 15 Apr 2009 01:01:28 +0400, Andrew Spott wrote: So, the attached is supposed to be a class that creates a vector of any type (I would like it to only take numerical values (int, float, real, double, etc), however, I am ok with it taking others (not that I see why someone would use it that way). I tried to compile it with the following, but it won't compile. I don't really understand the errors I'm getting either. Can someone tell me what I'm doing wrong? If you need more information, let me know. -Andrew void testvector() { auto v = new Vector!(float)(3, 12.0); writefln(v.toString()); int n = 0; while (n < n.size()) { v[n] = n; } writefln(v.toString()); } You've got quite a few errors in your code: module vector; private import std.string; class Vector(T) { private: T[] v; // int nn; // there is no need to store a size of array separately. It is available as v.length public: this() { } this(int n) { // nn = n; // not needed v = T[n]; // wrong, should be: v = new T[n]; } this(int n, T a) { // nn = n; v = T[n]; // same here (see above) while (n > 0) { // v[] = a; is faster and does the same as the loop below n--; v[n] = a; } } T opIndex(int n, int m) { // this won't work, because float is not an array return v[n][m]; // try this: T opIndex(int n) { return v[n]; } } opIndexAssign(T)(T a, int n, int m) { // no need for a template, also you forgot to write function return type v[n][m] = a; // should be: void opIndexAssign(int n, T a) { v[n] = a; } } int size() { return nn; // should be: return v.length; } string toString() { string s = "["; int n = 0; while ( n < nn) { s ~= v[n] ~ ", "; } return s ~ "]"; } ~this() { // no need for this one } } void testvector() { auto v = new Vector!(float)(3, 12.0); writefln(v.toString()); int n = 0; while (n < n.size()) { // infinite loop v[n] = n; } writefln(v.toString()); } Also, try using foreach instead of while and for loops. For example, string toString() { if (v.length == 0) return "[]"; string s = "["; foreach (k; v[0..$-1]) { s = std.string.format("%s, %s", s, k); } s = std.string.format("%s, %s]", s, v[$-1]); } void testvector() { // ... foreach (index, ref value; v) { value = index; } // ... } Hope that helps.
Template classes
So, the attached is supposed to be a class that creates a vector of any type (I would like it to only take numerical values (int, float, real, double, etc), however, I am ok with it taking others (not that I see why someone would use it that way). I tried to compile it with the following, but it won't compile. I don't really understand the errors I'm getting either. Can someone tell me what I'm doing wrong? If you need more information, let me know. -Andrew void testvector() { auto v = new Vector!(float)(3, 12.0); writefln(v.toString()); int n = 0; while (n < n.size()) { v[n] = n; } writefln(v.toString()); } vector.d Description: Binary data