On 30-7-2013 17:22, Vladimir Panteleev wrote:
On Tuesday, 30 July 2013 at 14:33:59 UTC, Faux Amis wrote:
like this:?

struct LAYER(BASE)
{
    BASE base;
    // ... use base ...
    void func(){};
}

struct Base
{
    alias LAYER!(Base) Layer;
    Layer layer;
    layer.base = this;
    layer.func();
    // ...
}

Not quite.

Let's say that, for the sake of example, we want to create a pipeline
for doing simple operations for integers using this technique.

First, let's define an interface by convention. Each layer will have a
method that handles the int value. Let's call that method "process". It
will take one int argument and return void.

So, one layer to add 1 to the result and pass it to the next layer would
look like this:

struct Incrementer(BASE)
{
     BASE next;

     void process(int value)
     {
         next.process(value + 1);
     }
}

If we want to multiply numbers by 2, same thing:

struct Doubler(BASE)
{
     BASE next;

     void process(int value)
     {
         next.process(value * 2);
     }
}

At the end of the chain, we'll want to save or print the result. This
layer does not have a BASE, so it doesn't even need to be a template:

struct Printer
{
     void process(int value)
     {
         writeln(value);
     }
}

And here's how to use everything together, if we want to print x*2+1:

import std.stdio;

alias Printer Layer0;
alias Incrementer!Layer0 Layer1;
alias Doubler!Layer1 Layer2;

void main()
{
     Layer2 chain;
     chain.process(3); // will print 7
}

Thanks!

For teaching purposes I would suggest to make the flow more obvious by writing it like this:

struct Incrementer(BASE)
{
    BASE next;

    void process(int value)
    {
        value += 1;
        next.process(value);
    }
}



Reply via email to