diff options
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_virtual_array.hh | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh index d9f83d3e1cb..b8b05e88572 100644 --- a/source/blender/blenlib/BLI_virtual_array.hh +++ b/source/blender/blenlib/BLI_virtual_array.hh @@ -1107,6 +1107,30 @@ template<typename T> class VMutableArray_Span final : public MutableSpan<T> { } }; +template<typename T> class SingleAsSpan { + private: + T value_; + int64_t size_; + + public: + SingleAsSpan(T value, int64_t size) : value_(std::move(value)), size_(size) + { + BLI_assert(size_ >= 0); + } + + SingleAsSpan(const VArray<T> &varray) : SingleAsSpan(varray.get_internal_single(), varray.size()) + { + } + + const T &operator[](const int64_t index) const + { + BLI_assert(index >= 0); + BLI_assert(index < size_); + UNUSED_VARS_NDEBUG(index); + return value_; + } +}; + /** * Generate multiple versions of the given function optimized for different virtual arrays. * One has to be careful with nesting multiple devirtualizations, because that results in an @@ -1121,14 +1145,11 @@ inline void devirtualize_varray(const VArray<T> &varray, const Func &func, bool /* Support disabling the devirtualization to simplify benchmarking. */ if (enable) { if (varray.is_single()) { - /* `VArrayImpl_For_Single` can be used for devirtualization, because it is declared `final`. - */ - func(VArray<T>::ForSingle(varray.get_internal_single(), varray.size())); + func(SingleAsSpan<T>(varray)); return; } if (varray.is_span()) { - /* `VArrayImpl_For_Span` can be used for devirtualization, because it is declared `final`. */ - func(VArray<T>::ForSpan(varray.get_internal_span())); + func(varray.get_internal_span()); return; } } @@ -1153,23 +1174,19 @@ inline void devirtualize_varray2(const VArray<T1> &varray1, const bool is_single1 = varray1.is_single(); const bool is_single2 = varray2.is_single(); if (is_span1 && is_span2) { - func(VArray<T1>::ForSpan(varray1.get_internal_span()), - VArray<T2>::ForSpan(varray2.get_internal_span())); + func(varray1.get_internal_span(), varray2.get_internal_span()); return; } if (is_span1 && is_single2) { - func(VArray<T1>::ForSpan(varray1.get_internal_span()), - VArray<T2>::ForSingle(varray2.get_internal_single(), varray2.size())); + func(varray1.get_internal_span(), SingleAsSpan(varray2)); return; } if (is_single1 && is_span2) { - func(VArray<T1>::ForSingle(varray1.get_internal_single(), varray1.size()), - VArray<T2>::ForSpan(varray2.get_internal_span())); + func(SingleAsSpan(varray1), varray2.get_internal_span()); return; } if (is_single1 && is_single2) { - func(VArray<T1>::ForSingle(varray1.get_internal_single(), varray1.size()), - VArray<T2>::ForSingle(varray2.get_internal_single(), varray2.size())); + func(SingleAsSpan(varray1), SingleAsSpan(varray2)); return; } } |