//============================================================================ // 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_CastAndCall_h #define vtk_m_cont_CastAndCall_h #include #include #include #include namespace vtkm { namespace cont { class CoordinateSystem; class Field; template class ArrayHandle; template class CellSetStructured; template class CellSetSingleType; template class CellSetExplicit; template class CellSetPermutation; class CellSetExtrude; class UnknownCellSet; /// A Generic interface to CastAndCall. The default implementation simply calls /// DynamicObject's CastAndCall, but specializations of this function exist for /// other classes (e.g. Field, CoordinateSystem, ArrayHandle). template void CastAndCall(const DynamicObject& dynamicObject, Functor&& f, Args&&... args) { dynamicObject.CastAndCall(std::forward(f), std::forward(args)...); } /// A specialization of CastAndCall for basic CoordinateSystem to make /// it be treated just like any other dynamic object // actually implemented in vtkm/cont/CoordinateSystem.h template void CastAndCall(const CoordinateSystem& coords, Functor&& f, Args&&... args); /// A specialization of CastAndCall for basic Field to make /// it be treated just like any other dynamic object // actually implemented in vtkm/cont/Field.h template void CastAndCall(const vtkm::cont::Field& field, Functor&& f, Args&&... args); /// A specialization of CastAndCall for unknown cell sets. // actually implemented in vtkm/cont/UnknownCellSet.h template void CastAndCall(const vtkm::cont::UnknownCellSet& cellSet, Functor&& f, Args&&... args); /// A specialization of CastAndCall for basic ArrayHandle types, /// Since the type is already known no deduction is needed. /// This specialization is used to simplify numerous worklet algorithms template void CastAndCall(const vtkm::cont::ArrayHandle& handle, Functor&& f, Args&&... args) { f(handle, std::forward(args)...); } /// A specialization of CastAndCall for UnknownArrayHandle. /// Since we have no hints on the types, use VTKM_DEFAULT_TYPE_LIST /// and VTKM_DEFAULT_STORAGE_LIST. // Implemented here to avoid circular dependencies. template void CastAndCall(const UnknownArrayHandle& handle, Functor&& f, Args&&... args) { handle.CastAndCallForTypes( std::forward(f), std::forward(args)...); } /// A specialization of CastAndCall for basic CellSetStructured types, /// Since the type is already known no deduction is needed. /// This specialization is used to simplify numerous worklet algorithms template void CastAndCall(const vtkm::cont::CellSetStructured& cellset, Functor&& f, Args&&... args) { f(cellset, std::forward(args)...); } /// A specialization of CastAndCall for basic CellSetSingleType types, /// Since the type is already known no deduction is needed. /// This specialization is used to simplify numerous worklet algorithms template void CastAndCall(const vtkm::cont::CellSetSingleType& cellset, Functor&& f, Args&&... args) { f(cellset, std::forward(args)...); } /// A specialization of CastAndCall for basic CellSetExplicit types, /// Since the type is already known no deduction is needed. /// This specialization is used to simplify numerous worklet algorithms template void CastAndCall(const vtkm::cont::CellSetExplicit& cellset, Functor&& f, Args&&... args) { f(cellset, std::forward(args)...); } /// A specialization of CastAndCall for basic CellSetPermutation types, /// Since the type is already known no deduction is needed. /// This specialization is used to simplify numerous worklet algorithms template void CastAndCall(const vtkm::cont::CellSetPermutation& cellset, Functor&& f, Args&&... args) { f(cellset, std::forward(args)...); } /// A specialization of CastAndCall for basic CellSetExtrude types, /// Since the type is already known no deduction is needed. /// This specialization is used to simplify numerous worklet algorithms template void CastAndCall(const vtkm::cont::CellSetExtrude& cellset, Functor&& f, Args&&... args) { f(cellset, std::forward(args)...); } /// CastAndCall if the condition is true. template void ConditionalCastAndCall(std::true_type, Args&&... args) { vtkm::cont::CastAndCall(std::forward(args)...); } /// No-op variant since the condition is false. template void ConditionalCastAndCall(std::false_type, Args&&...) { } namespace internal { /// Tag used to identify an object that is a dynamic object that contains a /// CastAndCall method that iterates over all possible dynamic choices to run /// templated code. /// struct DynamicTransformTagCastAndCall { }; /// Tag used to identify an object that is a static object that, when used with /// a \c DynamicTransform should just pass itself as a concrete object. /// struct DynamicTransformTagStatic { }; /// A traits class that identifies whether an object used in a \c /// DynamicTransform should use a \c CastAndCall functionality or treated as a /// static object. The default implementation identifies the object as static /// (as most objects are bound to be). Dynamic objects that implement /// \c CastAndCall should specialize (or partially specialize) this traits class /// to identify the object as dynamic. VTK-m classes like \c DynamicArray are /// already specialized. /// template struct DynamicTransformTraits { /// A type set to either \c DynamicTransformTagStatic or \c /// DynamicTransformTagCastAndCall. The default implementation is set to \c /// DynamicTransformTagStatic. Dynamic objects that implement \c CastAndCall /// should specialize this class redefine it to \c /// DynamicTransformTagCastAndCall. /// using DynamicTag = vtkm::cont::internal::DynamicTransformTagStatic; }; // Implemented here to avoid circular dependencies. template <> struct DynamicTransformTraits { using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall; }; } // namespace internal } } // namespace vtkm::cont #endif //vtk_m_cont_CastAndCall_h