www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - store template value

reply maarten van damme via Digitalmars-d-learn writes:
I have a class that creates a task in it's constructor. How do I store this
created task as one of it's value members and later on call .yieldForce()?
Aug 01 2015
next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Saturday, 1 August 2015 at 15:37:46 UTC, maarten van damme 
wrote:
 I have a class that creates a task in it's constructor. How do 
 I store this created task as one of it's value members and 
 later on call .yieldForce()?
If the class itself isn't templated on the type, you'll want to use something like std.variant.Variant to store it.
Aug 01 2015
parent reply maarten van damme via Digitalmars-d-learn writes:
I was afraid I would have to do that. Templatizing the class on the value
doesn't work as I later on want to create a hashmap of these classes.
When I assign a task to a variant, how do I call .yieldForce later on?

2015-08-01 18:28 GMT+02:00 Adam D. Ruppe via Digitalmars-d-learn <
digitalmars-d-learn puremagic.com>:

 On Saturday, 1 August 2015 at 15:37:46 UTC, maarten van damme wrote:

 I have a class that creates a task in it's constructor. How do I store
 this created task as one of it's value members and later on call
 .yieldForce()?
If the class itself isn't templated on the type, you'll want to use something like std.variant.Variant to store it.
Aug 01 2015
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Saturday, 1 August 2015 at 16:41:54 UTC, maarten van damme 
wrote:
 I was afraid I would have to do that. Templatizing the class on 
 the value doesn't work as I later on want to create a hashmap 
 of these classes. When I assign a task to a variant, how do I 
 call .yieldForce later on?
You can get a type from a Variant with the get!T method then call it. But actually, maybe Task should just be an interface with the yieldForce method then you create classes that implement it and pass them to the constructor. Then there's no need for templates or casting at all.
Aug 01 2015
parent maarten van damme via Digitalmars-d-learn writes:
But it's std.parallelism's task...
And how can I use get!T if I don't know the type of the task?

2015-08-01 19:02 GMT+02:00 Adam D. Ruppe via Digitalmars-d-learn <
digitalmars-d-learn puremagic.com>:

 On Saturday, 1 August 2015 at 16:41:54 UTC, maarten van damme wrote:

 I was afraid I would have to do that. Templatizing the class on the value
 doesn't work as I later on want to create a hashmap of these classes. When
 I assign a task to a variant, how do I call .yieldForce later on?
You can get a type from a Variant with the get!T method then call it. But actually, maybe Task should just be an interface with the yieldForce method then you create classes that implement it and pass them to the constructor. Then there's no need for templates or casting at all.
Aug 01 2015
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 08/01/2015 08:37 AM, maarten van damme via Digitalmars-d-learn wrote:
 I have a class that creates a task in it's constructor. How do I store this
 created task as one of it's value members and later on call .yieldForce()?
Tasks can be created with a function pointer 'function parameter' as well. (This has already been added to "Programming in D" but it is not available on the web site yet.) I learned the exact type by the help of pragma(msg) below and used it to create MyTask and myTasks: import std.parallelism; double foo(int i) { return i * 1.5; } double bar(int i) { return i * 2.5; } void main() { auto tasks = [ task(&foo, 1), task(&bar, 2) ]; // ← compiles pragma(msg, typeof(tasks[0])); alias MyTask = Task!(run, double function(int), int)*; MyTask[] myTasks; myTasks ~= task(&foo, 1); myTasks ~= task(&bar, 2); } Ali
Aug 01 2015
parent reply maarten van damme via Digitalmars-d-learn writes:
Oh, neat. This saves the day :)

2015-08-01 23:22 GMT+02:00 Ali =C3=87ehreli <digitalmars-d-learn puremagic.=
com>:

 On 08/01/2015 08:37 AM, maarten van damme via Digitalmars-d-learn wrote:

 I have a class that creates a task in it's constructor. How do I store
 this
 created task as one of it's value members and later on call .yieldForce(=
)?

 Tasks can be created with a function pointer 'function parameter' as well=
.
 (This has already been added to "Programming in D" but it is not availabl=
e
 on the web site yet.)

 I learned the exact type by the help of pragma(msg) below and used it to
 create MyTask and myTasks:

 import std.parallelism;

 double foo(int i)
 {
     return i * 1.5;
 }

 double bar(int i)
 {
     return i * 2.5;
 }

 void main()
 {
     auto tasks =3D [ task(&foo, 1),
                    task(&bar, 2) ];    // =E2=86=90 compiles

     pragma(msg, typeof(tasks[0]));

     alias MyTask =3D Task!(run, double function(int), int)*;

     MyTask[] myTasks;
     myTasks ~=3D task(&foo, 1);
     myTasks ~=3D task(&bar, 2);
 }

 Ali
Aug 02 2015
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 08/02/2015 05:15 AM, maarten van damme via Digitalmars-d-learn wrote:

 Oh, neat. This saves the day :)
Awesome! :) However, that solution depends on the implementation details of std.parallelism. It is possible to do the same thing by inheriting from an 'interface' and "hiding" the templated type under there. The following program need not spell out the template instance: import std.parallelism; double foo(int i) { return i * 1.5; } double bar(int i) { return i * 2.5; } /* This is what the user code will need to know about. */ interface MyTask { void executeInNewThread(); void yieldForce(); } /* This subclass hides the actual templated Task type. */ class MyTaskImpl(TaskType) : MyTask { TaskType t; this(TaskType t) { this.t = t; } /* These two are to satisfy the interface requirements. */ void executeInNewThread() { t.executeInNewThread(); } void yieldForce() { t.yieldForce(); } } /* A convenience function to hide the Task template instance. */ auto newMyTask(TaskType)(TaskType taskObject) { return new MyTaskImpl!TaskType(taskObject); } void main() { /* Populate */ MyTask[] myTasks; myTasks ~= newMyTask(task!foo(1)); myTasks ~= newMyTask(task!bar(2)); import std.algorithm; /* Execute */ myTasks.each!(t => t.executeInNewThread); /* Wait */ myTasks.each!(t => t.yieldForce); } Ali
Aug 02 2015