www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Idea: metastatic

I have come up with an idea that would help to generate specific reflection 
information for a class hierarchy.  Although there are a number of 
applications for this, I will focus on object factories because that is one 
of the things I need.  Now I know that D currently provides an object 
factory when classes have a default constructor.  This is neat and I'm sure 
it's useful to some people, but I need an object factory with a specific 
signature.

The solution I came up with would require a new construct called 
"metastatic" that would instantiate a static field or function on a per 
class basis.  That is, metastatic fields and functions would be instantiated 
the for the class they are defined in and each subclass.  Each metastatic 
member would result in a static member for the base class and each subclass. 
All metastatic members would be templates with one parameter: the class 
type.

 I should stop rambling and show some example code.  Lets say that A is a 
base class, and that we want an object factory that takes an integer for all 
subclasses of A.  A.getFactory is the end result.  It takes a string and 
returns a function pointer to the appropriate object factory.

class AFactory
{
public:
   char[] className;
   A function(int) factory;
}

class A
{
public:

   // Constructor taking integer required by metastatic constructor
   this(int x) { this.x = x; }

   // Will result in a unique static constructor being generated for each 
subclass
   metastatic(T) this()
   {
       static A factory(int x) { return new T(x); }
       factories ~= AFactory(typeid(T).name(), &factory);
   }

   static A function(int) getFactory(char[] className)
   {
      foreach(AFactory factory; factories)
         if(className == factory.className) return factory.factory;
      return null;
   }

private:

   int x;
   static AFactory[] factories;
}

class B : A
{
public:
   // Constructor taking integer required by metastatic constructor
   this(int x)
   {
      super(x);
      writefln("In B constructor");
   }
}

int main(char[][] args)
{
   var factory = A.getFactory("B");
   A object = factory(3); // writes "In B constructor" to the console
   return 0;
}
Dec 19 2007