On 14 February 2012 14:25, bearophile <bearophileHUGS at lycos.com> wrote:
> In D.learn there is an interesting thread ("Instance-specific unittests") about D idioms to use unittests in templated classes/structs:
>http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=32490>> A comment from Jonathan M Davis:
>>> And yes, this can be useful. The problem that you get into is when you _don't_
>> want your test to be in each instantiation of the template. In that case, you
>> either end up having to use static if or move those unit tests out of the
>> template.
>> Time ago I have suggested the "static static" idea, an usage example:
>>> auto foo(T)(T x) {
> static static arr = [1, 2, 3];
> return arr[x];
> }
>>> "static static" means that arr is not just static, but it's also created only once for all different instantiations of the foo function template. So there is only one arr (and the compiler/linker needs to work less to remove the copies).
>> A more complex idea (I have seen it in a Bjarne Stroustrup paper, here I have modified it a bit) is to use an attribute to specify a list of template argument types you are using in a declaration (the attribute name is made up on the spot, better names are possible):
>>> auto foo(T)(T x) {
> @templated() static arr = [1, 2, 3];
> return arr[x];
> }
>> class Bar(T, U, W) {
> @templated(T) void foo2() {}
> }
>> @templated(T) means that foo2() is shared across the various instantiations of Bar that share the same U and W types, so it's a template of T only. This is useful as one tool to fight template bloat, and it has other purposes too (like avoiding some template instantiation errors, because you are asserting that foo2 does not need the types U and W to be fully defined correctly).
>> So if you use that attribute with no arguments, you have a unit test that is shared across all instantiations of the Spam template class, I think this solves Jonathan problem:
>> class Spam(T) {
> @templated() unittests {}
> }
>> Bye,
> bearophile
With this:
class Bar(T, U, W) {
@templated(T) void foo2() {}
}
I assume you mean that void foo2 is only templated across different
Ts, since that is how i read it. "foo2 is only dependent on T,
therefore do not duplicate for different values of U and W"
Other than that, this would be very useful, though I'm not sure about
how easy it is to implement. Better than doubling up a keyword, I
always found that confusing in C/C++ with its long long int and
similar constructs.
James Miller