Add Get<std::array<T, n>> for custom types
Desired behavior
Cannot implement custom parsing of n values in a single tag:
<gz:custom>0 0 0 0<gz:custom>
Cannot be parsed into a custom type (and can only be read as a sdf::Quaternion?). The problem comes from the fact that the parser uses an std::variant that is set on the library and cannot be extended.
An interesting solution to this would be to add a capacity to read an N valued std::array of arbitrary type
(which has operator >> defined).
Alternatives considered
1 Using multiple tags
(I ended up using this)
<gz:custom>
<gz:coeff0>0</gz:coeff0>
<gz:coeff1>0</gz:coeff1>
<gz:coeff2>0</gz:coeff2>
<gz:coeff3>0</gz:coeff3>
<gz:custom>
This can get pretty long, especially in code as more coefficients are needed.
2 Hacking predefined types
Using any of:
_Types = {bool, char, __cxx11::basic_string<char, char_traits<char>, allocator<char> >, int, long unsigned int, unsigned int, double, float, sdf::v14::Time, gz::math::v7::Angle, gz::math::v7::Color, gz::math::v7::Vector2<int>, gz::math::v7::Vector2<double>, gz::math::v7::Vector3<double>, gz::math::v7::Quaternion<double>, gz::math::v7::Pose3<double>}
But the code would not be easy to understand, and comes with issues if you are parsing uncommon data (not simple floats) that requires custom operator>>.
Implementation suggestion
Add a template that compiles when T is "parseable" and T is not in the variant.
template<typename T, unsigned int n>
bool Param::Get(std::array<T, n> &_value, sdf::Errors &_errors) const
{
std::holds_alternative<T>(this->dataPtr->value); // Check that T is parseable
T *value = std::get_if<std::vector<T>>(&this->dataPtr->value);
std::copy_n(value.begin(), n, _value.begin());
return true;
}
And add std::vector<std::variantParamVariant.