diff options
Diffstat (limited to 'source/blender/blenlib/BLI_index_range.hh')
-rw-r--r-- | source/blender/blenlib/BLI_index_range.hh | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/source/blender/blenlib/BLI_index_range.hh b/source/blender/blenlib/BLI_index_range.hh index 7d5c2400bba..a0f129c7324 100644 --- a/source/blender/blenlib/BLI_index_range.hh +++ b/source/blender/blenlib/BLI_index_range.hh @@ -90,10 +90,10 @@ class IndexRange { return *this; } - constexpr Iterator operator++(int) const + constexpr Iterator operator++(int) { Iterator copied_iterator = *this; - ++copied_iterator; + ++(*this); return copied_iterator; } @@ -186,13 +186,25 @@ class IndexRange { } /** - * Get the last element in the range. - * Asserts when the range is empty. + * Get the nth last element in the range. + * Asserts when the range is empty or when n is negative. */ - constexpr int64_t last() const + constexpr int64_t last(const int64_t n = 0) const { + BLI_assert(n >= 0); + BLI_assert(n < size_); BLI_assert(this->size() > 0); - return start_ + size_ - 1; + return start_ + size_ - 1 - n; + } + + /** + * Get the element one before the beginning. The returned value is undefined when the range is + * empty, and the range must start after zero already. + */ + constexpr int64_t one_before_start() const + { + BLI_assert(start_ > 0); + return start_ - 1; } /** @@ -280,6 +292,15 @@ class IndexRange { } /** + * Move the range forward or backward within the larger array. The amount may be negative, + * but its absolute value cannot be greater than the existing start of the range. + */ + constexpr IndexRange shift(int64_t n) const + { + return IndexRange(start_ + n, size_); + } + + /** * Get read-only access to a memory buffer that contains the range as actual numbers. */ Span<int64_t> as_span() const; @@ -297,4 +318,19 @@ class IndexRange { Span<int64_t> as_span_internal() const; }; +struct AlignedIndexRanges { + IndexRange prefix; + IndexRange aligned; + IndexRange suffix; +}; + +/** + * Split a range into three parts so that the boundaries of the middle part are aligned to some + * power of two. + * + * This can be used when an algorithm can be optimized on aligned indices/memory. The algorithm + * then needs a slow path for the beginning and end, and a fast path for the aligned elements. + */ +AlignedIndexRanges split_index_range_by_alignment(const IndexRange range, const int64_t alignment); + } // namespace blender |