Combining Templates While Minimizing Bloat

jmh530 john.michael.hall at
Wed Feb 15 03:14:37 UTC 2023

The code below has two `foo` functions that take slices, one 
accepts a const(T)* iterator and one accepts a generic Iterator 
with the property that the slice isn't convertible to the first 
one. The nice thing about this is that if you pass it with a 
double* or const(double)*, then it doesn't increase template 
bloat. The problem, however, is that I have to either have two 
implementations or a separate `fooImpl` function to implement the 
desired functionality. Is there any way to combine together the 
`foo` functions in a way that maintains the template bloat 
reducing behavior of the first function?

The example below uses mir, but it just as easily could be 
adapted to other types.

dependency "mir-algorithm" version="*"
import std.stdio: writeln;
import mir.ndslice.slice;

void foo(T)(Slice!(const(T)*, 1) x)
     writeln("Iterator = ", typeid(IteratorOf!(typeof(x))));

void foo(Iterator)(Slice!(Iterator, 1) x)
     if (!is(Iterator : const(U)*, U))
     writeln("Iterator = ", typeid(IteratorOf!(typeof(x))));

void main()
     double[] x = [1.0, 2, 3];
     auto y = x.sliced;
     auto z = y.toConst;
     foo(y); //prints "here" and "Iterator=const(double)*"
     foo(z); //prints "here" and "Iterator=const(double)*"
     auto a = y / 6;
     foo(a); //prints "there" and "Iterator=(some long template 

I tried something like
void foo(Iterator)(Slice!(const Iterator, 1) x) {}
but this isn't a valid mir iterator since it becomes 
const(double*) (a const pointer to a const double). What I need 
is const(double)* (a mutable pointer to a const double).

More information about the Digitalmars-d-learn mailing list