sdformat icon indicating copy to clipboard operation
sdformat copied to clipboard

Add Get<std::array<T, n>> for custom types

Open EmmanuelMess opened this issue 10 months ago • 0 comments

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::variant> to the ParamVariant.

EmmanuelMess avatar Mar 09 '25 13:03 EmmanuelMess