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
}

Reply via email to