www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - [openmethods] Support for templatized methods

Following a request from a couple of users to make it possible to 
use open methods and templates together, I toyed with a couple of 
ideas, until I discovered that the current implementation 
supports method and override templates already...well, almost, 
because there is a need to navigate around a couple of bugs (or 
limitations) in the various D compilers.

I have an example in a branch 
(https://github.com/jll63/openmethods.d/tree/method-template-example) that adds
a new mixin for manually registering classes - to be used for class template
instantiations, which do not appear on ModuleInfo.localClasses. Apart from that
the existing machinery is up to the task - although it requires some help from
the user. Here is the gist of it (complete example here:
https://github.com/jll63/openmethods.d/blob/method-template-example/tests/methodtemplates.d):

   class Matrix(T) {}
   class DenseMatrix(T) : Matrix!(T) {}
   class DiagonalMatrix(T) : Matrix!(T) {}

   template declareMatrixMethods(T)
   {
     mixin registerClasses!(Matrix!T);
     mixin registerClasses!(DenseMatrix!T);
     mixin registerClasses!(DiagonalMatrix!T);

     Matrix!T times(virtual!(Matrix!T), T);
     Matrix!T times(T, virtual!(Matrix!T));
   }

   mixin(registerMethods("declareMatrixMethods!double"));
   mixin(registerMethods("declareMatrixMethods!int"));

   template matrixMethods(T)
   {
      method DenseMatrix!T _times(Matrix!T m, T s) { return new 
DenseMatrix!T; }
      method DenseMatrix!T _times(T s, Matrix!T m) { return new 
DenseMatrix!T; }
      method DiagonalMatrix!T _times(DiagonalMatrix!T m, T s) { 
return new DiagonalMatrix!T; }
      method DiagonalMatrix!T _times(T s, DiagonalMatrix!T m) { 
return new DiagonalMatrix!T; }
   }

   mixin(registerMethods("matrixMethods!double"));
   mixin(registerMethods("matrixMethods!int"));

Now it would be nice if we could do away with the explicit 
instantiations...in theory it could be done - any time a method 
template is called, trigger the instantiation of all the 
templatized overrides -, but this is beyond the power of a 
library. Even with support at language level, it would probably 
require a pre-link phase.

I am going to sleep on this a couple more times before 
documenting it and officially support it. I will probably add an 
overload to registerMethods so we can say 
'registerMethods!(matrixMethods!double)'; I don't like passing 
types as strings very much.

As always, comments and suggestions are encouraged.
Oct 08