diff --git a/vtkm/cont/ArrayCopy.cxx b/vtkm/cont/ArrayCopy.cxx index f417ad229..ec5c103e4 100644 --- a/vtkm/cont/ArrayCopy.cxx +++ b/vtkm/cont/ArrayCopy.cxx @@ -26,7 +26,7 @@ struct CopyWorklet : vtkm::worklet::WorkletMapField using InputDomain = _1; template - void operator()(const InType& in, OutType& out) const + VTKM_EXEC void operator()(const InType& in, OutType& out) const { out = in; } @@ -68,7 +68,7 @@ struct UnknownCopyFunctor2 struct UnknownCopyFunctor1 { template - void operator()(const InArrayType& in, const vtkm::cont::UnknownArrayHandle& out) const + void operator()(const InArrayType& in, vtkm::cont::UnknownArrayHandle& out) const { out.Allocate(in.GetNumberOfValues()); @@ -79,7 +79,7 @@ struct UnknownCopyFunctor1 } template - void DoIt(const InArrayType& in, const vtkm::cont::UnknownArrayHandle& out, std::false_type) const + void DoIt(const InArrayType& in, vtkm::cont::UnknownArrayHandle& out, std::false_type) const { // Source is not float. using BaseComponentType = typename InArrayType::ValueType::ComponentType; @@ -104,7 +104,7 @@ struct UnknownCopyFunctor1 } template - void DoIt(const InArrayType& in, const vtkm::cont::UnknownArrayHandle& out, std::true_type) const + void DoIt(const InArrayType& in, vtkm::cont::UnknownArrayHandle& out, std::true_type) const { // Source array is FloatDefault. That should be copiable to anything. out.CastAndCallWithExtractedArray(UnknownCopyFunctor2{}, in); @@ -119,9 +119,14 @@ namespace cont { void ArrayCopy(const vtkm::cont::UnknownArrayHandle& source, - const vtkm::cont::UnknownArrayHandle& destination) + vtkm::cont::UnknownArrayHandle& destination) { - destination.CastAndCallWithExtractedArray(UnknownCopyFunctor1{}, source); + if (!destination.IsValid()) + { + destination = source.NewInstanceBasic(); + } + + source.CastAndCallWithExtractedArray(UnknownCopyFunctor1{}, destination); } } diff --git a/vtkm/cont/ArrayCopy.h b/vtkm/cont/ArrayCopy.h index d077b06ad..053c93bd5 100644 --- a/vtkm/cont/ArrayCopy.h +++ b/vtkm/cont/ArrayCopy.h @@ -162,7 +162,7 @@ VTKM_CONT void ArrayCopy(const vtkm::cont::ArrayHandle& VTKM_CONT_EXPORT void ArrayCopy(const vtkm::cont::UnknownArrayHandle& source, - const vtkm::cont::UnknownArrayHandle& destination); + vtkm::cont::UnknownArrayHandle& destination); template VTKM_CONT void ArrayCopy(const vtkm::cont::UnknownArrayHandle& source, @@ -175,7 +175,10 @@ VTKM_CONT void ArrayCopy(const vtkm::cont::UnknownArrayHandle& source, } else { - ArrayCopy(source, vtkm::cont::UnknownArrayHandle(destination)); + vtkm::cont::UnknownArrayHandle destWrapper(destination); + ArrayCopy(source, destWrapper); + // Destination array should not change, but just in case. + destWrapper.AsArrayHandle(destination); } } diff --git a/vtkm/cont/UnknownArrayHandle.cxx b/vtkm/cont/UnknownArrayHandle.cxx index 6146d7f10..85b94de6c 100644 --- a/vtkm/cont/UnknownArrayHandle.cxx +++ b/vtkm/cont/UnknownArrayHandle.cxx @@ -128,6 +128,11 @@ VTKM_CONT bool UnknownArrayHandle::IsBaseComponentTypeImpl( return this->Container->BaseComponentType == type; } +VTKM_CONT bool UnknownArrayHandle::IsValid() const +{ + return static_cast(this->Container); +} + VTKM_CONT UnknownArrayHandle UnknownArrayHandle::NewInstance() const { UnknownArrayHandle newArray; diff --git a/vtkm/cont/UnknownArrayHandle.h b/vtkm/cont/UnknownArrayHandle.h index e62af9098..f996081dc 100644 --- a/vtkm/cont/UnknownArrayHandle.h +++ b/vtkm/cont/UnknownArrayHandle.h @@ -386,6 +386,14 @@ public: UnknownArrayHandle& operator=(const vtkm::cont::UnknownArrayHandle&) = default; + /// \brief Returns whether an array is stored in this `UnknownArrayHandle`. + /// + /// If the `UnknownArrayHandle` is constructed without an `ArrayHandle`, it + /// will not have an underlying type, and therefore the operations will be + /// invalid. It is still possible to set this `UnknownArrayHandle` to an + /// `ArrayHandle`. + VTKM_CONT bool IsValid() const; + /// \brief Create a new array of the same type as this array. /// /// This method creates a new array that is the same type as this one and