This complier is making my hair gray. Fortunately the out-of-class
operator doesn't conflict with the in-class one, so it's purely an
additive workaround. Adding extra checks to all subclasses to be sure
this works correctly in all cases and not just in the base class.
Except for a vector and a row matrix multiplication operator, which
doesn't make sense to be a member. These are all now significantly
shorter thanks to not having to repeat that many template parameters,
and they can make use of direct access into the _data array for better
debug perf.
Despite what the standard tries to say. I bet a large portion of
<type_traits> is impossible to implement without it, which is why all
STL implementations define it there already.
I spent a significant amount of time reinventing the wheel, i.e.
figuring out how to use a cross product to calculate distance of a point
to a line. Only to subseqently have a breakthrough discovery of
Distance::linePoint() that actually does the same.
The distance APIs and 2D and 3D cross-products are now linked together
the math snippet is clarified, and both the 2D and 3D distance use the
same equation, saving one unnecessary vector subtraction. The
equivalence of the two equations is listed directly on that Wolfram
link.
The old one is deprecated, and will be removed in a future release.
Unfortunately, to avoid deprecation warnings, all use of NoInit in the
Math library temporarily have to be Magnum::NoInit This will be cleaned
up when the deprecated alias is removed.
And the Vector3 version 5% slower in Release, on GCC at least. FFS,
what was I thinking with the gather() things. Nice in user code,
extremely bad in library code.
The compiler does that for us. Probably a brain fart from 2010. On the
other hand, the ConfigurationValue specializations need to be there,
because the type is used explicitly as template parameter.
Useful for squeezing out last bits of performance, e.g. in this case:
Vector3 a;
a[0] = something++;
a[1] = something++;
a[2] = something++;
In the code all elements are first zeroed out and then overwritten
later, thus it might be good to avoid the zero-initialization:
Vector3 a{Math::NoInit};
a[0] = something++;
a[1] = something++;
a[2] = something++;
This will of course be more useful in far larger data types and arrays
of these.