diff --git a/docs/changelog/vecfromportal-operators.md b/docs/changelog/vecfromportal-operators.md new file mode 100644 index 000000000..747c34222 --- /dev/null +++ b/docs/changelog/vecfromportal-operators.md @@ -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. diff --git a/vtkm/VecFromPortal.h b/vtkm/VecFromPortal.h index 4f2330981..35cf2726b 100644 --- a/vtkm/VecFromPortal.h +++ b/vtkm/VecFromPortal.h @@ -73,10 +73,11 @@ public: index + this->Offset); } - template - VTKM_EXEC_CONT VecFromPortal& operator=(const vtkm::Vec& src) + // Only works with Vec-like objects with operator[] and GetNumberofComponents + template + 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 + 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 + 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 + 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 + 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 + VTKM_EXEC_CONT VecFromPortal& operator*=(const OtherVecType& other) + { + this->Multiply(other, typename vtkm::TypeTraits::DimensionalityTag{}); + return *this; + } + + // Only works with Vec-like objects with operator[] and GetNumberofComponents + template + 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 + 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 + 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; }