vtk-m/vtkm/internal/ArrayPortalVirtual.h
Kenneth Moreland cb3bb43ff9 Completely deprecate virtual methods
Deprecate `VirtualObjectHandle` and all other classes that are used to
implement objects with virtual methods in the execution environment.

Additionally, the code is updated so that if the
`VTKm_NO_DEPRECATED_VIRTUAL` flag is set none of the code is compiled at
all. This opens us up to opportunities that do not work with virtual
methods such as backends that do not support virtual methods and dynamic
libraries for CUDA.
2021-04-28 07:28:32 -06:00

155 lines
4.3 KiB
C++

//============================================================================
// 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 <vtkm/internal/Configure.h>
#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 <vtkm/VecTraits.h>
#include <vtkm/VirtualObjectBase.h>
#include <vtkm/internal/ArrayPortalHelpers.h>
#include <vtkm/internal/ExportMacros.h>
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 <typename T>
class VTKM_ALWAYS_EXPORT ArrayPortalVirtual : public internal::PortalVirtualBase
{
public:
using ValueType = T;
//use parents constructor
using PortalVirtualBase::PortalVirtualBase;
VTKM_EXEC_CONT virtual ~ArrayPortalVirtual<T>(){};
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 <typename PortalT>
class VTKM_ALWAYS_EXPORT ArrayPortalWrapper final
: public vtkm::ArrayPortalVirtual<typename PortalT::ValueType>
{
using T = typename PortalT::ValueType;
public:
ArrayPortalWrapper(const PortalT& p) noexcept
: ArrayPortalVirtual<T>()
, 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<PortalT>::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<PortalT>::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 <typename T>
class VTKM_ALWAYS_EXPORT ArrayPortalRef
{
public:
using ValueType = T;
VTKM_EXEC_CONT
ArrayPortalRef() noexcept
: Portal(nullptr)
, NumberOfValues(0)
{
}
VTKM_EXEC_CONT
ArrayPortalRef(const ArrayPortalVirtual<T>* 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<Portal> 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<T>* Portal;
vtkm::Id NumberOfValues;
};
template <typename T>
inline ArrayPortalRef<T> make_ArrayPortalRef(const ArrayPortalVirtual<T>* portal,
vtkm::Id numValues) noexcept
{
return ArrayPortalRef<T>(portal, numValues);
}
} // namespace vtkm
#endif