//============================================================================ // 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_internal_ArrayPortalVirtual_h #define vtk_m_internal_ArrayPortalVirtual_h #include #ifdef VTKM_NO_DEPRECATED_VIRTUAL #error "This header should not be included when VTKM_NO_DEPRECATED_VIRTUAL is set." #endif //VTKM_NO_DEPRECATED_VIRTUAL #include #include #include #include namespace vtkm { namespace internal { class VTKM_ALWAYS_EXPORT PortalVirtualBase { public: VTKM_EXEC_CONT PortalVirtualBase() noexcept {} VTKM_EXEC_CONT virtual ~PortalVirtualBase() noexcept { //we implement this as we need a destructor with cuda markup. //Using =default causes cuda free errors inside VirtualObjectTransferCuda }; }; } // namespace internal template class VTKM_ALWAYS_EXPORT ArrayPortalVirtual : public internal::PortalVirtualBase { public: using ValueType = T; //use parents constructor using PortalVirtualBase::PortalVirtualBase; VTKM_EXEC_CONT virtual ~ArrayPortalVirtual(){}; VTKM_EXEC_CONT virtual T Get(vtkm::Id index) const noexcept = 0; VTKM_EXEC_CONT virtual void Set(vtkm::Id, const T&) const noexcept {} }; template class VTKM_ALWAYS_EXPORT ArrayPortalWrapper final : public vtkm::ArrayPortalVirtual { using T = typename PortalT::ValueType; public: ArrayPortalWrapper(const PortalT& p) noexcept : ArrayPortalVirtual() , Portal(p) { } VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT ~ArrayPortalWrapper() {} VTKM_EXEC_CONT T Get(vtkm::Id index) const noexcept { using call_supported_t = typename internal::PortalSupportsGets::type; return this->Get(call_supported_t(), index); } VTKM_EXEC_CONT void Set(vtkm::Id index, const T& value) const noexcept { using call_supported_t = typename internal::PortalSupportsSets::type; this->Set(call_supported_t(), index, value); } private: // clang-format off VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT inline T Get(std::true_type, vtkm::Id index) const noexcept { return this->Portal.Get(index); } VTKM_EXEC_CONT inline T Get(std::false_type, vtkm::Id) const noexcept { return T{}; } VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT inline void Set(std::true_type, vtkm::Id index, const T& value) const noexcept { this->Portal.Set(index, value); } VTKM_EXEC_CONT inline void Set(std::false_type, vtkm::Id, const T&) const noexcept {} // clang-format on PortalT Portal; }; template class VTKM_ALWAYS_EXPORT ArrayPortalRef { public: using ValueType = T; VTKM_EXEC_CONT ArrayPortalRef() noexcept : Portal(nullptr) , NumberOfValues(0) { } VTKM_EXEC_CONT ArrayPortalRef(const ArrayPortalVirtual* portal, vtkm::Id numValues) noexcept : Portal(portal) , NumberOfValues(numValues) { } //Currently this needs to be valid on both the host and device for cuda, so we can't //call the underlying portal as that uses device virtuals and the method will fail. //We need to seriously look at the interaction of portals and iterators for device //adapters and determine a better approach as iterators are really fat VTKM_EXEC_CONT inline vtkm::Id GetNumberOfValues() const noexcept { return this->NumberOfValues; } //This isn't valid on the host for cuda VTKM_EXEC_CONT inline T Get(vtkm::Id index) const noexcept { return this->Portal->Get(index); } //This isn't valid on the host for VTKM_EXEC_CONT inline void Set(vtkm::Id index, const T& t) const noexcept { this->Portal->Set(index, t); } const ArrayPortalVirtual* Portal; vtkm::Id NumberOfValues; }; template inline ArrayPortalRef make_ArrayPortalRef(const ArrayPortalVirtual* portal, vtkm::Id numValues) noexcept { return ArrayPortalRef(portal, numValues); } } // namespace vtkm #endif