Low-overhead components

Vladimir Panteleev vladimir at thecybershadow.net
Tue Jul 30 08:22:24 PDT 2013


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
}


More information about the Digitalmars-d mailing list