Improve = operators in VecFromPortal

Previously, `VecFromPortal` could only be set to a standard `Vec`.
However, because this is a `Vec`-like object with a runtime-size, it is
hard to do general arithmetic on it. It is easier to do in place so
there is some place to put the result. To make it easier to operate on
this as the result of other `Vec`-likes, extend the operators like `+=`,
`*=`, etc to support this.
This commit is contained in:
Kenneth Moreland 2023-08-04 14:03:45 -06:00
parent 5c6716f8e8
commit 508cc3accb
2 changed files with 102 additions and 3 deletions

@ -0,0 +1,8 @@
# Improved = operators in VecFromPortal
Previously, `VecFromPortal` could only be set to a standard `Vec`.
However, because this is a `Vec`-like object with a runtime-size, it is
hard to do general arithmetic on it. It is easier to do in place so
there is some place to put the result. To make it easier to operate on
this as the result of other `Vec`-likes, extend the operators like `+=`,
`*=`, etc to support this.

@ -73,10 +73,11 @@ public:
index + this->Offset);
}
template <typename T, vtkm::IdComponent N>
VTKM_EXEC_CONT VecFromPortal& operator=(const vtkm::Vec<T, N>& src)
// Only works with Vec-like objects with operator[] and GetNumberofComponents
template <typename OtherVecType>
VTKM_EXEC_CONT VecFromPortal& operator=(const OtherVecType& src)
{
vtkm::IdComponent numComponents = vtkm::Min(N, this->NumComponents);
vtkm::IdComponent numComponents = vtkm::Min(src.GetNumberOfComponents(), this->NumComponents);
for (vtkm::IdComponent index = 0; index < numComponents; ++index)
{
this->Portal.Set(index + this->Offset, src[index]);
@ -84,6 +85,96 @@ public:
return *this;
}
// Only works with Vec-like objects with operator[] and GetNumberofComponents
template <typename OtherVecType>
VTKM_EXEC_CONT VecFromPortal& operator+=(const OtherVecType& other)
{
vtkm::IdComponent numComponents = vtkm::Min(other.GetNumberOfComponents(), this->NumComponents);
for (vtkm::IdComponent index = 0; index < numComponents; ++index)
{
(*this)[index] += other[index];
}
return *this;
}
// Only works with Vec-like objects with operator[] and GetNumberofComponents
template <typename OtherVecType>
VTKM_EXEC_CONT VecFromPortal& operator-=(const OtherVecType& other)
{
vtkm::IdComponent numComponents = vtkm::Min(other.GetNumberOfComponents(), this->NumComponents);
for (vtkm::IdComponent index = 0; index < numComponents; ++index)
{
(*this)[index] -= other[index];
}
return *this;
}
private:
template <typename OtherVecType>
VTKM_EXEC_CONT void Multiply(const OtherVecType& other, vtkm::TypeTraitsVectorTag)
{
vtkm::IdComponent numComponents = vtkm::Min(other.GetNumberOfComponents(), this->NumComponents);
for (vtkm::IdComponent index = 0; index < numComponents; ++index)
{
(*this)[index] *= other[index];
}
}
template <typename ScalarType>
VTKM_EXEC_CONT void Multiply(ScalarType other, vtkm::TypeTraitsScalarTag)
{
for (vtkm::IdComponent index = 0; index < this->NumComponents; ++index)
{
(*this)[index] *= other;
}
}
public:
// Only works with Vec-like objects with operator[] and GetNumberofComponents
template <typename OtherVecType>
VTKM_EXEC_CONT VecFromPortal& operator*=(const OtherVecType& other)
{
this->Multiply(other, typename vtkm::TypeTraits<OtherVecType>::DimensionalityTag{});
return *this;
}
// Only works with Vec-like objects with operator[] and GetNumberofComponents
template <typename OtherVecType>
VTKM_EXEC_CONT VecFromPortal& operator/=(const OtherVecType& other)
{
vtkm::IdComponent numComponents = vtkm::Min(other.GetNumberOfComponents(), this->NumComponents);
for (vtkm::IdComponent index = 0; index < numComponents; ++index)
{
(*this)[index] /= other[index];
}
return *this;
}
// Only works with Vec-like objects with operator[] and GetNumberofComponents
template <typename OtherVecType>
VTKM_EXEC_CONT bool operator==(const OtherVecType& other)
{
if (this->NumComponents != other.GetNumberOfComponents())
{
return false;
}
for (vtkm::IdComponent index = 0; index < this->NumComponents; ++index)
{
if (this->Portal.Get(index + this->Offset) != other[index])
{
return false;
}
}
return true;
}
// Only works with Vec-like objects with operator[] and GetNumberofComponents
template <typename OtherVecType>
VTKM_EXEC_CONT bool operator!=(const OtherVecType& other)
{
return !(*this == other);
}
VTKM_EXEC_CONT const PortalType& GetPortal() const { return this->Portal; }
VTKM_EXEC_CONT vtkm::Id GetOffset() const { return this->Offset; }