10 #ifndef vtk_m_cont_ExecutionObjectBase_h
11 #define vtk_m_cont_ExecutionObjectBase_h
41 struct CheckPrepareForExecution
44 static auto check(T* p) -> decltype(p->PrepareForExecution(vtkm::cont::DeviceAdapterTagSerial{},
45 std::declval<vtkm::cont::Token&>()),
49 static auto check(...) -> std::false_type;
55 using IsExecutionObjectBase =
56 typename std::is_base_of<vtkm::cont::ExecutionObjectBase, typename std::decay<T>::type>::type;
59 struct HasPrepareForExecution
60 : decltype(detail::CheckPrepareForExecution::check<typename std::decay<T>::type>(nullptr))
66 #define VTKM_IS_EXECUTION_OBJECT(execObject) \
67 static_assert(::vtkm::cont::internal::IsExecutionObjectBase<execObject>::value, \
68 "Provided type is not a subclass of vtkm::cont::ExecutionObjectBase."); \
69 static_assert(::vtkm::cont::internal::HasPrepareForExecution<execObject>::value, \
70 "Provided type does not have requisite PrepareForExecution method.")
80 template <
typename T,
typename Device>
82 -> decltype(execObject.PrepareForExecution(device, token))
87 return execObject.PrepareForExecution(device, token);
91 VTKM_CONT auto CallPrepareForExecution(T&& execObject,
94 -> decltype(execObject.PrepareForExecution(device, token))
98 return execObject.PrepareForExecution(device, token);
109 template <
typename ExecutionObject,
typename Device = vtkm::cont::DeviceAdapterId>
110 using ExecutionObjectType = decltype(CallPrepareForExecution(std::declval<ExecutionObject>(),
111 std::declval<Device>(),
112 std::declval<vtkm::cont::Token&>()));
118 #endif //vtk_m_cont_ExecutionObjectBase_h