diff options
author | Jacques Lucke <jacques@blender.org> | 2022-04-26 18:40:53 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2022-04-26 18:41:16 +0300 |
commit | d8ef52ca47e0cf65f7dbcf4dd111ee840d0fcb06 (patch) | |
tree | 1b66a93c563ddeaeab27e88fca8442e8d6c10375 /source/blender/blenlib/BLI_devirtualize_parameters.hh | |
parent | 3e7ee3f3bcd61a1fb1395683ba7ecc430c9932db (diff) |
Fix: some multi-functions are executed more than once
The good thing is that this fix also makes function evaluation a bit faster.
Diffstat (limited to 'source/blender/blenlib/BLI_devirtualize_parameters.hh')
-rw-r--r-- | source/blender/blenlib/BLI_devirtualize_parameters.hh | 47 |
1 files changed, 32 insertions, 15 deletions
diff --git a/source/blender/blenlib/BLI_devirtualize_parameters.hh b/source/blender/blenlib/BLI_devirtualize_parameters.hh index bf4f6c47cfe..ca11ec2e579 100644 --- a/source/blender/blenlib/BLI_devirtualize_parameters.hh +++ b/source/blender/blenlib/BLI_devirtualize_parameters.hh @@ -107,8 +107,8 @@ template<typename Fn, typename... SourceTypes> class Devirtualizer { { BLI_assert(!executed_); static_assert(sizeof...(AllowedModes) == SourceTypesNum); - return this->try_execute_devirtualized_impl(DeviModeSequence<>(), - DeviModeSequence<AllowedModes...>()); + this->try_execute_devirtualized_impl(DeviModeSequence<>(), + DeviModeSequence<AllowedModes...>()); } /** @@ -131,9 +131,11 @@ template<typename Fn, typename... SourceTypes> class Devirtualizer { * At every recursive step, the #DeviMode of one parameter is determined. This is achieved by * extending #DeviModeSequence<Mode...> by one element in each step. The recursion ends once all * parameters are handled. + * + * \return True when the function has been executed. */ template<DeviMode... Mode, DeviMode... AllowedModes> - void try_execute_devirtualized_impl( + bool try_execute_devirtualized_impl( /* Initially empty, but then extended by one element in each recursive step. */ DeviModeSequence<Mode...> /* modes */, /* Bit flag for every parameter. */ @@ -144,6 +146,7 @@ template<typename Fn, typename... SourceTypes> class Devirtualizer { /* End of recursion, now call the function with the determined #DeviModes. */ this->try_execute_devirtualized_impl_call(DeviModeSequence<Mode...>(), std::make_index_sequence<SourceTypesNum>()); + return true; } else { /* Index of the parameter that is checked in the current recursive step. */ @@ -160,21 +163,27 @@ template<typename Fn, typename... SourceTypes> class Devirtualizer { /* Check if the virtual array is a single value. */ if constexpr ((allowed_modes & DeviMode::Single) != DeviMode::None) { if (varray.is_single()) { - this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Single>(), - DeviModeSequence<AllowedModes...>()); + if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Single>(), + DeviModeSequence<AllowedModes...>())) { + return true; + } } } /* Check if the virtual array is a span. */ if constexpr ((allowed_modes & DeviMode::Span) != DeviMode::None) { if (varray.is_span()) { - this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Span>(), - DeviModeSequence<AllowedModes...>()); + if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Span>(), + DeviModeSequence<AllowedModes...>())) { + return true; + } } } /* Check if it is ok if the virtual array is not devirtualized. */ if constexpr ((allowed_modes & DeviMode::Keep) != DeviMode::None) { - this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Keep>(), - DeviModeSequence<AllowedModes...>()); + if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Keep>(), + DeviModeSequence<AllowedModes...>())) { + return true; + } } } @@ -185,23 +194,30 @@ template<typename Fn, typename... SourceTypes> class Devirtualizer { /* The actual mask used for dynamic dispatch at run-time. */ const IndexMask &mask = *std::get<I>(sources_); if (mask.is_range()) { - this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Range>(), - DeviModeSequence<AllowedModes...>()); + if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Range>(), + DeviModeSequence<AllowedModes...>())) { + return true; + } } } /* Check if mask is also allowed to stay a span. */ if constexpr ((allowed_modes & DeviMode::Span) != DeviMode::None) { - this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Span>(), - DeviModeSequence<AllowedModes...>()); + if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Span>(), + DeviModeSequence<AllowedModes...>())) { + return true; + } } } /* Handle unknown types. */ else { - this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Keep>(), - DeviModeSequence<AllowedModes...>()); + if (this->try_execute_devirtualized_impl(DeviModeSequence<Mode..., DeviMode::Keep>(), + DeviModeSequence<AllowedModes...>())) { + return true; + } } } + return false; } /** @@ -212,6 +228,7 @@ template<typename Fn, typename... SourceTypes> class Devirtualizer { std::index_sequence<I...> /* indices */) { + BLI_assert(!executed_); fn_(this->get_devirtualized_parameter<I, Mode>()...); executed_ = true; } |