From a4027658eeaff868a68675594bf774a87454344e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Sat, 17 Sep 2022 12:26:28 +0200 Subject: IndexRange: Add new `intersect` method Returns a new range, that contains the intersection of the current one with the given range. This is helpful to select a portion of a range without having to deal with all the asserts of other functions. The resulting range being always a valid subrange, it can be used to iterate or copy a part of a vector. --- source/blender/blenlib/BLI_index_range.hh | 17 +++++++++++++++++ source/blender/blenlib/tests/BLI_index_range_test.cc | 11 +++++++++++ 2 files changed, 28 insertions(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_index_range.hh b/source/blender/blenlib/BLI_index_range.hh index a0f129c7324..ba49664e91f 100644 --- a/source/blender/blenlib/BLI_index_range.hh +++ b/source/blender/blenlib/BLI_index_range.hh @@ -140,6 +140,10 @@ class IndexRange { { return (a.size_ == b.size_) && (a.start_ == b.start_ || a.size_ == 0); } + constexpr friend bool operator!=(IndexRange a, IndexRange b) + { + return !(a == b); + } /** * Get the amount of numbers in the range. @@ -247,6 +251,19 @@ class IndexRange { return this->slice(range.start(), range.size()); } + /** + * Returns a new range, that contains the intersection of the current one with the given range. + * Returns empty range is no intersection exists. + * Returned range is always a valid slice of this range. + */ + constexpr IndexRange intersect(IndexRange other) const + { + const int64_t old_end = start_ + size_; + const int64_t new_start = std::min(old_end, std::max(start_, other.start_)); + const int64_t new_end = std::max(new_start, std::min(old_end, other.start_ + other.size_)); + return IndexRange(new_start, new_end - new_start); + } + /** * Returns a new IndexRange with n elements removed from the beginning of the range. * This invokes undefined behavior when n is negative. diff --git a/source/blender/blenlib/tests/BLI_index_range_test.cc b/source/blender/blenlib/tests/BLI_index_range_test.cc index 955691b3430..8ec7ad85d9c 100644 --- a/source/blender/blenlib/tests/BLI_index_range_test.cc +++ b/source/blender/blenlib/tests/BLI_index_range_test.cc @@ -126,6 +126,17 @@ TEST(index_range, Slice) EXPECT_EQ(slice.last(), 12); } +TEST(index_range, Intersect) +{ + IndexRange range = IndexRange(5, 15); + EXPECT_EQ(range.intersect(IndexRange(2, 2)), IndexRange(5, 0)); + EXPECT_EQ(range.intersect(IndexRange(4, 2)), IndexRange(5, 1)); + EXPECT_EQ(range.intersect(IndexRange(3, 20)), IndexRange(5, 15)); + EXPECT_EQ(range.intersect(IndexRange(5, 15)), IndexRange(5, 15)); + EXPECT_EQ(range.intersect(IndexRange(15, 10)), IndexRange(15, 5)); + EXPECT_EQ(range.intersect(IndexRange(22, 2)), IndexRange(20, 0)); +} + TEST(index_range, SliceRange) { IndexRange range = IndexRange(5, 15); -- cgit v1.2.3