Meta-programming: iterating over a container with different types

deed via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Sep 23 05:55:42 PDT 2016


On Friday, 23 September 2016 at 09:21:56 UTC, Claude wrote:
> ...

// Maybe you can try using std.variant?

import std.variant;
alias Component = Variant;

class Entity
{
     void register (Component v) { components ~= v; }
     void unregister (T) () {
         foreach (i, c; components) if (c.type == typeid(T))
             components = components[0..i] ~ components[i+1 .. $];
     }
     Component getComponent (T) () {
         foreach (i, c; components) if (c.type == typeid(T))
             return components[i];
     }
     Component[] components;
     // iterating over the components
     alias components this;

     // or you can provide an inputRange interface by implementing
     //
     // bool empty () {}
     // Component front () {}
     // void popFront () {}
     //
     // to support whatever type of backing data structure you 
have.
     // (see http://ddili.org/ders/d.en/ranges.html)
}

unittest
{
     import std.stdio;
     Entity e = new Entity();
     e.register(Component(42));
     e.register(Component("loire"));
     e.register(Component(3.14));
     foreach (c; e) write(c, " "); writeln;  // Prints 42 "loire" 
3.14
     e.unregister!string;
     foreach (c; e) write(c, " "); writeln;  // Prints 42 3.14
     e.unregister!double;
     foreach (c; e) write(c, " "); writeln;  // Prints 42
     e.unregister!int;
     assert(e.components.length == 0);
}


More information about the Digitalmars-d-learn mailing list