digitalmars.D - [openmethods] Support for templatized methods
- Jean-Louis Leroy (46/46) Oct 08 2017 Following a request from a couple of users to make it possible to
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 2017