[openmethods] Support for templatized methods
Jean-Louis Leroy
jl at leroy.nyc
Sun Oct 8 15:56:03 UTC 2017
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.
More information about the Digitalmars-d
mailing list