18 #ifndef viskores_cont_ExecutionObjectBase_h
19 #define viskores_cont_ExecutionObjectBase_h
49 struct CheckPrepareForExecution
52 static auto check(T* p)
54 std::declval<viskores::cont::Token&>()),
58 static auto check(...) -> std::false_type;
64 using IsExecutionObjectBase =
65 typename std::is_base_of<viskores::cont::ExecutionObjectBase, typename std::decay<T>::type>::type;
68 struct HasPrepareForExecution
69 : decltype(detail::CheckPrepareForExecution::check<typename std::decay<T>::type>(nullptr))
75 #define VISKORES_IS_EXECUTION_OBJECT(execObject) \
76 static_assert(::viskores::cont::internal::IsExecutionObjectBase<execObject>::value, \
77 "Provided type is not a subclass of viskores::cont::ExecutionObjectBase."); \
78 static_assert(::viskores::cont::internal::HasPrepareForExecution<execObject>::value, \
79 "Provided type does not have requisite PrepareForExecution method.")
89 template <
typename T,
typename Device>
93 -> decltype(execObject.PrepareForExecution(device, token))
98 return execObject.PrepareForExecution(device, token);
101 template <
typename T>
105 -> decltype(execObject.PrepareForExecution(device, token))
109 return execObject.PrepareForExecution(device, token);
120 template <
typename ExecutionObject,
typename Device = viskores::cont::DeviceAdapterId>
121 using ExecutionObjectType =
122 decltype(CallPrepareForExecution(std::declval<ExecutionObject>(),
123 std::declval<Device>(),
124 std::declval<viskores::cont::Token&>()));
130 #endif //viskores_cont_ExecutionObjectBase_h