//============================================================================ // Copyright (c) Kitware, Inc. // All rights reserved. // See LICENSE.txt for details. // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ #ifndef vtk_m_cont_StorageImplicit #define vtk_m_cont_StorageImplicit #include #include #include #include #include namespace vtkm { namespace cont { /// \brief An implementation for read-only implicit arrays. /// /// It is sometimes the case that you want VTK-m to operate on an array of /// implicit values. That is, rather than store the data in an actual array, it /// is gerenated on the fly by a function. This is handled in VTK-m by creating /// an ArrayHandle in VTK-m with a StorageTagImplicit type of \c Storage. This /// tag itself is templated to specify an ArrayPortal that generates the /// desired values. An ArrayHandle created with this tag will raise an error on /// any operation that tries to modify it. /// template struct VTKM_ALWAYS_EXPORT StorageTagImplicit { using PortalType = ArrayPortalType; }; namespace internal { template class VTKM_ALWAYS_EXPORT Storage> { using ClassType = Storage>; public: using ValueType = typename ArrayPortalType::ValueType; using PortalConstType = ArrayPortalType; // This is meant to be invalid. Because implicit arrays are read only, you // should only be able to use the const version. struct PortalType { using ValueType = void*; using IteratorType = void*; }; VTKM_CONT Storage(const PortalConstType& portal = PortalConstType()) : Portal(portal) , NumberOfValues(portal.GetNumberOfValues()) { } VTKM_CONT Storage(const ClassType&) = default; VTKM_CONT Storage(ClassType&&) = default; VTKM_CONT ClassType& operator=(const ClassType&) = default; VTKM_CONT ClassType& operator=(ClassType&&) = default; // All these methods do nothing but raise errors. VTKM_CONT PortalType GetPortal() { throw vtkm::cont::ErrorBadValue("Implicit arrays are read-only."); } VTKM_CONT PortalConstType GetPortalConst() const { return this->Portal; } VTKM_CONT vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; } VTKM_CONT void Allocate(vtkm::Id numberOfValues) { VTKM_ASSERT(numberOfValues <= this->Portal.GetNumberOfValues()); this->NumberOfValues = numberOfValues; } VTKM_CONT void Shrink(vtkm::Id numberOfValues) { VTKM_ASSERT(numberOfValues <= this->Portal.GetNumberOfValues()); this->NumberOfValues = numberOfValues; } VTKM_CONT void ReleaseResources() {} private: PortalConstType Portal; vtkm::Id NumberOfValues; }; template class ArrayTransfer, DeviceAdapterTag> { public: using StorageTag = StorageTagImplicit; using StorageType = vtkm::cont::internal::Storage; using ValueType = T; using PortalControl = typename StorageType::PortalType; using PortalConstControl = typename StorageType::PortalConstType; using PortalExecution = PortalControl; using PortalConstExecution = PortalConstControl; VTKM_CONT ArrayTransfer(StorageType* storage) : Storage(storage) { } VTKM_CONT vtkm::Id GetNumberOfValues() const { return this->Storage->GetNumberOfValues(); } VTKM_CONT PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData)) { return this->Storage->GetPortalConst(); } VTKM_CONT PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData)) { throw vtkm::cont::ErrorBadValue("Implicit arrays cannot be used for output or in place."); } VTKM_CONT PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues)) { throw vtkm::cont::ErrorBadValue("Implicit arrays cannot be used for output."); } VTKM_CONT void RetrieveOutputData(StorageType* vtkmNotUsed(controlArray)) const { throw vtkm::cont::ErrorBadValue("Implicit arrays cannot be used for output."); } VTKM_CONT void Shrink(vtkm::Id vtkmNotUsed(numberOfValues)) { throw vtkm::cont::ErrorBadValue("Implicit arrays cannot be resized."); } VTKM_CONT void ReleaseResources() {} private: StorageType* Storage; }; } // namespace internal } } // namespace vtkm::cont #endif //vtk_m_cont_StorageImplicit