Re: Variadic Mixin/Template classes?

2017-11-25 Thread Chirs Forest via Digitalmars-d-learn

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?

2017-11-25 Thread vit via Digitalmars-d-learn

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?

2017-11-25 Thread Chirs Forest via Digitalmars-d-learn
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

2012-09-10 Thread Jacob Carlborg

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

2012-09-10 Thread Chris Cain

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

2012-09-10 Thread timotheecour
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

2012-09-10 Thread Chris Cain

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

2012-09-10 Thread Chris Cain

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

2012-09-10 Thread timotheecour
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

2012-09-09 Thread Jacob Carlborg

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

2012-09-09 Thread timotheecour

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

2009-04-16 Thread Jarrett Billingsley
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

2009-04-16 Thread Arild Boes

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

2009-04-15 Thread bearophile
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

2009-04-15 Thread Jarrett Billingsley
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

2009-04-15 Thread Arild Boes

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

2009-04-14 Thread bearophile
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

2009-04-14 Thread Andrew Spott
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

2009-04-14 Thread Steven Schveighoffer
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

2009-04-14 Thread Steven Schveighoffer
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

2009-04-14 Thread Denis Koroskin

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

2009-04-14 Thread Andrew Spott
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