diff options
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_index_range.hh | 52 | ||||
-rw-r--r-- | source/blender/blenlib/tests/BLI_index_range_test.cc | 73 |
2 files changed, 125 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_index_range.hh b/source/blender/blenlib/BLI_index_range.hh index 25edba8c631..832e438fa75 100644 --- a/source/blender/blenlib/BLI_index_range.hh +++ b/source/blender/blenlib/BLI_index_range.hh @@ -149,6 +149,14 @@ class IndexRange { } /** + * Returns true if the size is zero. + */ + constexpr bool is_empty() const + { + return size_ == 0; + } + + /** * Create a new range starting at the end of the current one. */ constexpr IndexRange after(int64_t n) const @@ -227,6 +235,50 @@ class IndexRange { } /** + * Returns a new IndexRange with n elements removed from the beginning. This invokes undefined + * behavior when n is negative. + */ + constexpr IndexRange drop_front(int64_t n) const + { + BLI_assert(n >= 0); + const int64_t new_size = std::max<int64_t>(0, size_ - n); + return IndexRange(start_ + n, new_size); + } + + /** + * Returns a new IndexRange with n elements removed from the beginning. This invokes undefined + * behavior when n is negative. + */ + constexpr IndexRange drop_back(int64_t n) const + { + BLI_assert(n >= 0); + const int64_t new_size = std::max<int64_t>(0, size_ - n); + return IndexRange(start_, new_size); + } + + /** + * Returns a new IndexRange that only contains the first n elements. This invokes undefined + * behavior when n is negative. + */ + constexpr IndexRange take_front(int64_t n) const + { + BLI_assert(n >= 0); + const int64_t new_size = std::min<int64_t>(size_, n); + return IndexRange(start_, new_size); + } + + /** + * Returns a new IndexRange that only contains the last n elements. This invokes undefined + * behavior when n is negative. + */ + constexpr IndexRange take_back(int64_t n) const + { + BLI_assert(n >= 0); + const int64_t new_size = std::min<int64_t>(size_, n); + return IndexRange(start_ + size_ - new_size, new_size); + } + + /** * Get read-only access to a memory buffer that contains the range as actual numbers. */ Span<int64_t> as_span() const; diff --git a/source/blender/blenlib/tests/BLI_index_range_test.cc b/source/blender/blenlib/tests/BLI_index_range_test.cc index 7f0d2e6c22a..10f6784cd44 100644 --- a/source/blender/blenlib/tests/BLI_index_range_test.cc +++ b/source/blender/blenlib/tests/BLI_index_range_test.cc @@ -129,6 +129,79 @@ TEST(index_range, SliceRange) EXPECT_EQ(slice.last(), 12); } +TEST(index_range, DropBack) +{ + IndexRange a(4, 4); + auto slice = a.drop_back(2); + EXPECT_EQ(slice.size(), 2); + EXPECT_EQ(slice.start(), 4); + EXPECT_EQ(slice[1], 5); +} + +TEST(index_range, DropBackAll) +{ + IndexRange a(4, 4); + auto slice = a.drop_back(a.size()); + EXPECT_TRUE(slice.is_empty()); +} + +TEST(index_range, DropFront) +{ + IndexRange a(4, 4); + auto slice = a.drop_front(1); + EXPECT_EQ(slice.size(), 3); + EXPECT_EQ(slice[0], 5); + EXPECT_EQ(slice[1], 6); + EXPECT_EQ(slice.last(), 7); +} + +TEST(index_range, DropFrontLargeN) +{ + IndexRange a(1, 5); + IndexRange slice = a.drop_front(100); + EXPECT_TRUE(slice.is_empty()); +} + +TEST(index_range, DropFrontAll) +{ + IndexRange a(50); + IndexRange slice = a.drop_front(a.size()); + EXPECT_TRUE(slice.is_empty()); +} + +TEST(index_range, TakeFront) +{ + IndexRange a(4, 4); + IndexRange slice = a.take_front(2); + EXPECT_EQ(slice.size(), 2); + EXPECT_EQ(slice[0], 4); + EXPECT_EQ(slice[1], 5); +} + +TEST(index_range, TakeFrontLargeN) +{ + IndexRange a(4, 4); + IndexRange slice = a.take_front(100); + EXPECT_EQ(slice.size(), 4); +} + +TEST(index_range, TakeBack) +{ + IndexRange a(4, 4); + auto slice = a.take_back(2); + EXPECT_EQ(slice.size(), 2); + EXPECT_EQ(slice[0], 6); + EXPECT_EQ(slice[1], 7); +} + +TEST(index_range, TakeBackLargeN) +{ + IndexRange a(3, 4); + IndexRange slice = a.take_back(100); + EXPECT_EQ(slice.size(), 4); + EXPECT_EQ(slice.size(), 4); +} + TEST(index_range, AsSpan) { IndexRange range = IndexRange(4, 6); |