I am trying to write a template to define a three procedures which are identical except in the number of generic arguments they take and the number of generic arguments of the types. Is there a way to do this without having to write the same procedure three times?
Specifically it would be nice if the generic parameters could be passed as an argument to the template. For example to generate the code:
proc Test*(self: var Test_Type_Zero) =
echo $self.Name
proc Test*[A](self: var Test_Type_One[A]) =
echo $self.Name
proc Test*[A, B](self: var Test_Type_Two[A, B]) =
echo $self.Name
I would like to be able to write something like the following:
template Test_Template*(vType: untyped, vGen: untyped) =
proc Test*`vGen`(self: var vType`vGen`) =
echo $self.Name
Test_Template(Test_Type_Zero, void)
Test_Template(Test_Type_One, [A])
Test_Template(Test_Type_Two, [A, B])
instead of having to write something like:
template Test_Template_Zero*(vType: untyped) =
proc Test*(self: var vType) =
echo $self.Name
template Test_Template_One*(vType: untyped) =
proc Test*[A](self: var vType[A]) =
echo $self.Name
template Test_Template_Two*(vType: untyped) =
proc Test*[A, B](self: var vType[A, B]) =
echo $self.Name
Test_Template_Zero(Test_Type_Zero)
Test_Template_One(Test_Type_One)
Test_Template_Two(Test_Type_Two)
This unfortunately seems to be right at the edge of what is possible with templates. Mostly because of the special case of having no generic arguments. However a macro is able to deal with it easily enough:
Note that I switched the syntax for
Test_Templateto just list the arguments instead of requiring them to be in a bracket. This just makes the macro a bit easier, but you could certainly makevGentake anuntypedargument and parse out the elements you need from the bracket element you would get with your initial syntax.