Description
(I scanned the issue list briefly but couldn't find any discussion of this so sorry if it's already been raised.) It's quite a tall ask (especially if you wish to keep the library compatible with C++98) but have you considered that the results of many GLM functions may not be composed of the same scalar type as the inputs?
For built-ins such as float
, this generally isn't the case. For char
and short
, you can effectively ignore the promotion that occurs with little performance loss. But for some types (e.g. Boost.Units and some fixed-point types such as this one), the result is a different type to the input.
It is often possible to support such types simply by improving the genericity of your function template signatures. This example is in pseudo-C++14 and is a simplification of a function from GLM.
// This function only works when the result of `operator*` is the same as the operands, i.e. `T`
template <typename T>
tvec3<T> operator*(tvec3<T> const & v, T const & s) {
return tvec3<T>{v.x * s, v.y * s, v.z * s};
}
// but this function is more flexible.
template <typename T, typename S>
auto operator*(tvec3<T> const & v, S const & s) {
return tvec3<decltype(v.x*s)>{v.x * s, v.y * s, v.z * s};
}
The same function can be written in C++11 in a more verbose style (using decltype
in the signature) and in C++17 in a more concise style (using Template argument deduction for class templates).
Consider a unit-aware type system where T
is velocity in m/s and S
is time in s. The result of the above multiply operation is displacement in meters. But to encode the dimensions, the components of the result must be a different type from both T
and S
. The compiled code is the same as would currently be produced by GLM, but the program now offers greater safety checks.
That's just one example of where a more general function template signature would allow use of GLM in combination with a far wider range of scalar types.
Thanks
John