How to automatically generate function overloads

Zone none at 0.0.0.0
Tue May 4 11:21:20 UTC 2021


On Tuesday, 4 May 2021 at 11:00:42 UTC, Blatnik wrote:
> I'm porting over my linear algebra library from C++, and I have 
> a bunch of functions that work on both scalars and vectors. The 
> vector versions just apply the scalar function to every element 
> of the vector, for example:
>
> ```D
> float clamp01(float x) { return x < 0 ? 0 : (x > 1 ? 1 : x); }
>
> float[N] clamp01(size_t N)(float[N] vec)
> {
>   float[N] result;
>   static foreach (i; 0 .. N)
>     result[i] = clamp01(vec[i]);
>
>   return result;
> }
> ```
>
> And this is great, I don't have to write the same function for 
> different array lengths.
>
> But I still have like 30-ish of these functions and I would 
> like to generate the array overload automatically from the 
> scalar overload.
>
> So I would like something like a mixin, that I can use like 
> this:
>
> ```D
> mixin Vectorize_Unary_Function!clamp01; // Generates the code 
> above.
> mixin Vectorize_Unary_Function!floor;
> mixin Vectorize_Unary_Function!ceil;
> ...
> ```
>
> It doesn't have to be a mixin like this. I don't really care 
> what it is as long as it works :)
>
> How could I do this?
```D
float clamp01(float x) { return x < 0 ? 0 : (x > 1 ? 1 : x); }

template Vectorize_Unary_Function(alias fun) {
     float[N] Vectorize_Unary_Function(size_t N)(float[N] vec)
     {
         float[N] result;
         static foreach (i; 0 .. N)
             result[i] = fun(vec[i]);
         return result;
     }
}

alias clamp01 = Vectorize_Unary_Function!clamp01;


void main() {
     float[5] vec = [1,2,3,4,5];
     float[5] other = clamp01(vec);
     writeln(vec);
     writeln(other);
}
```

Not exactly what you were asking for but I hope it works, tricky 
part is I'm not sure how to generate the function name without 
string mixins so that's why I used alias instead.


More information about the Digitalmars-d-learn mailing list