66 using type_at_index =
typename TypeSequence<SourceTypes...>::template at_index<I>;
67 static constexpr
size_t SourceTypesNum =
sizeof...(SourceTypes);
76 std::tuple<
const SourceTypes *...> sources_;
79 bool executed_ =
false;
82 Devirtualizer(Fn fn,
const SourceTypes *...sources) : fn_(
std::move(fn)), sources_{sources...}
109 static_assert(
sizeof...(AllowedModes) == SourceTypesNum);
120 this->try_execute_devirtualized_impl_call(
122 std::make_index_sequence<SourceTypesNum>());
138 bool try_execute_devirtualized_impl(
144 static_assert(SourceTypesNum ==
sizeof...(AllowedModes));
145 if constexpr (SourceTypesNum ==
sizeof...(Mode)) {
148 std::make_index_sequence<SourceTypesNum>());
153 constexpr
size_t I =
sizeof...(Mode);
155 using SourceType = type_at_index<I>;
157 [[maybe_unused]] constexpr
DeviMode allowed_modes =
161 if constexpr (is_VArray_v<SourceType>) {
163 const SourceType &varray = *std::get<I>(sources_);
166 if (varray.is_single()) {
167 if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Single>(),
168 DeviModeSequence<AllowedModes...>())) {
175 if (varray.is_span()) {
176 if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Span>(),
177 DeviModeSequence<AllowedModes...>())) {
184 if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Keep>(),
185 DeviModeSequence<AllowedModes...>())) {
192 else if constexpr (std::is_same_v<IndexMask, SourceType>) {
196 const IndexMask &
mask = *std::get<I>(sources_);
197 if (
mask.is_range()) {
198 if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Range>(),
199 DeviModeSequence<AllowedModes...>())) {
206 if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Span>(),
207 DeviModeSequence<AllowedModes...>())) {
215 if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Keep>(),
216 DeviModeSequence<AllowedModes...>())) {
228 void try_execute_devirtualized_impl_call(DeviModeSequence<Mode...> ,
229 std::index_sequence<I...> )
233 fn_(this->get_devirtualized_parameter<I, Mode>()...);
244 template<
size_t I, DeviMode Mode> decltype(
auto) get_devirtualized_parameter()
246 using SourceType = type_at_index<I>;
250 return *std::get<I>(sources_);
252 if constexpr (is_VArray_v<SourceType>) {
253 const SourceType &varray = *std::get<I>(sources_);
256 return SingleAsSpan(varray);
260 return varray.get_internal_span();
263 else if constexpr (std::is_same_v<IndexMask, SourceType>) {
264 const IndexMask &
mask = *std::get<I>(sources_);
271 return mask.as_range();
289 template<
typename T,
typename Func>
292 using namespace devirtualize_parameters;
294 Devirtualizer<decltype(func),
VArray<T>> devirtualizer(func, &varray);
296 devirtualizer.try_execute_devirtualized(DeviModeSequence<devi_mode>());
297 if (devirtualizer.executed()) {
309 template<
typename T1,
typename T2,
typename Func>
315 using namespace devirtualize_parameters;
319 devirtualizer.try_execute_devirtualized(DeviModeSequence<devi_mode, devi_mode>());
320 if (devirtualizer.executed()) {
324 func(varray1, varray2);
void try_execute_devirtualized(DeviModeSequence< AllowedModes... >)
Devirtualizer(Fn fn, const SourceTypes *...sources)
void execute_without_devirtualization()
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
ValueSequence< DeviMode, Mode... > DeviModeSequence
ENUM_OPERATORS(DeviMode, DeviMode::Range)
void devirtualize_varray(const VArray< T > &varray, const Func &func, bool enable=true)
void devirtualize_varray2(const VArray< T1 > &varray1, const VArray< T2 > &varray2, const Func &func, bool enable=true)
decltype(detail::make_value_sequence_impl< T, Value >(std::make_index_sequence< Size >())) make_value_sequence