From c55afdf30b33fbea9b30afe199f61951345576f4 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 29 Mar 2022 10:07:18 +0200 Subject: BLI: add utility to convert IndexMask to best mask type --- source/blender/blenlib/BLI_index_mask.hh | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'source') diff --git a/source/blender/blenlib/BLI_index_mask.hh b/source/blender/blenlib/BLI_index_mask.hh index 3decd8b9441..b87ab0afc98 100644 --- a/source/blender/blenlib/BLI_index_mask.hh +++ b/source/blender/blenlib/BLI_index_mask.hh @@ -163,16 +163,30 @@ class IndexMask { */ template void foreach_index(const CallbackT &callback) const { - if (this->is_range()) { - IndexRange range = this->as_range(); - for (int64_t i : range) { + this->to_best_mask_type([&](const auto &mask) { + for (const int64_t i : mask) { callback(i); } + }); + } + + /** + * Often an #IndexMask wraps a range of indices without any gaps. In this case, it is more + * efficient to compute the indices in a loop on-the-fly instead of reading them from memory. + * This method makes it easy to generate code for both cases. + * + * The given function is expected to take one parameter that can either be of type #IndexRange or + * #Span. + */ + template void to_best_mask_type(const Fn &fn) const + { + if (this->is_range()) { + const IndexRange masked_range = this->as_range(); + fn(masked_range); } else { - for (int64_t i : indices_) { - callback(i); - } + const Span masked_indices = indices_; + fn(masked_indices); } } -- cgit v1.2.3