slang
slang copied to clipboard
Generic functions with array types
Is it possible to define generic functions in Slang with array types?
I want to define a function that concatenates two arrays of any size, but this would require generics:
T3 array_concat<T1,T2,T3>(T1 a1, T2 a2)
{
T3 result;
for(int i = 0; i < length(a1), i++){
result[i] = a1[i];
}
for(int j = 0; j < length(a2);j++){
result[j] = a2[j + length(a1)];
}
return result;
}
vec4 example_use(vec2 a, vec2 b){
return array_concat(a,b);
}
The operation you are trying to write there wouldn't work today, although I see what you mean.
You can write functions that operate generically over vectors of different sizes, but you need them to have both an explicit parameter for the element type of the array, and a generic value parameter for the element count:
T getElementAtIndex<T, let N : int>(vector<T,N> v, int index)
{
return v[index];
}
The same basic idea could in theory apply to your array_concat
example (which is really more of a vector_concat
):
vector<T, N+M> concat<T, let N : int, let M : int>(vector<T,N> left, vector<T,M> right)
{ ... }
The main reason the function isn't possible today is the N+M
in the result type. Right now the Slang compiler can only handle it when the arguments to a generic (or the sizes of an array, etc.) are either true compile-time constants (e.g., 10
or 99
) or are direct references to a generic value parameter (e.g., N
or M
in this example). A more complicated expression using generic value parameters, like N+M
or even just N+1
is not (yet) supported.
Out of curiosity, what is the problem you are working on that needs this concat
sort of function? In the worst case, you can just write explicit overloads for a few sizes:
vector<T,2> concat<T>(T left, T right); { ... }
vector<T,3> concat<T>(vector<T,2> left, T right) { ... }
vector<T,3> concast<T>(T left, vector<T,2> right) { ... }
vector<T,4> concat<T>(vector<T,3> left, T right) { ... }
vector<T,4> concast<T>(T left, vector<T,3> right) { ... }
vector<T,4> concat<T>(vector<T,2> left, vector<T,2> right) { ... }
I believe those cases would cover all of what you'd need, given that Slang currently only supports vectors of 2-4 elements.
@tfoleyNV Generics would also be useful for operations involving matrices: for instance, I'd want to define a function that performs Gaussian elimination on a matrix of any size. I'm not sure if this is possible yet, due to the compiler's current limitations.
This is supported now. You can now define functions like
vector<T, N+M> concat<T, let N : int, let M : int>(vector<T,N> left, vector<T,M> right)
{ ... }