diff options
author | Jacques Lucke <jacques@blender.org> | 2022-02-24 16:45:41 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2022-02-24 16:50:13 +0300 |
commit | 9be720d85efb307ad37b73f0f5fffd95629c7e20 (patch) | |
tree | 8b0c0f074c9f6616ff2b79992974177b2d4215ef /source/blender/blenlib | |
parent | 7cab7eb3d6cd929f5c354416b4baa6c608f08d82 (diff) |
BLI: support accessing nth last element in Array/Span/Vector
This often helps to make the intend of code more clear compared
to computing the index manually in the caller.
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_array.hh | 18 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_span.hh | 22 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_vector.hh | 18 | ||||
-rw-r--r-- | source/blender/blenlib/tests/BLI_array_test.cc | 2 | ||||
-rw-r--r-- | source/blender/blenlib/tests/BLI_span_test.cc | 3 | ||||
-rw-r--r-- | source/blender/blenlib/tests/BLI_vector_test.cc | 3 |
6 files changed, 40 insertions, 26 deletions
diff --git a/source/blender/blenlib/BLI_array.hh b/source/blender/blenlib/BLI_array.hh index a580f12851e..91dfc81ae27 100644 --- a/source/blender/blenlib/BLI_array.hh +++ b/source/blender/blenlib/BLI_array.hh @@ -278,18 +278,20 @@ class Array { } /** - * Return a reference to the last element in the array. - * This invokes undefined behavior when the array is empty. + * Return a reference to the nth last element. + * This invokes undefined behavior when the array is too short. */ - const T &last() const + const T &last(const int64_t n = 0) const { - BLI_assert(size_ > 0); - return *(data_ + size_ - 1); + BLI_assert(n >= 0); + BLI_assert(n < size_); + return *(data_ + size_ - 1 - n); } - T &last() + T &last(const int64_t n = 0) { - BLI_assert(size_ > 0); - return *(data_ + size_ - 1); + BLI_assert(n >= 0); + BLI_assert(n < size_); + return *(data_ + size_ - 1 - n); } /** diff --git a/source/blender/blenlib/BLI_span.hh b/source/blender/blenlib/BLI_span.hh index d82f21a57ff..9ab096094de 100644 --- a/source/blender/blenlib/BLI_span.hh +++ b/source/blender/blenlib/BLI_span.hh @@ -307,13 +307,14 @@ template<typename T> class Span { } /** - * Returns a reference to the last element in the array. This invokes undefined behavior when the - * array is empty. + * Returns a reference to the nth last element. This invokes undefined behavior when the span is + * too short. */ - constexpr const T &last() const + constexpr const T &last(const int64_t n = 0) const { - BLI_assert(size_ > 0); - return data_[size_ - 1]; + BLI_assert(n >= 0); + BLI_assert(n < size_); + return data_[size_ - 1 - n]; } /** @@ -673,13 +674,14 @@ template<typename T> class MutableSpan { } /** - * Returns a reference to the last element. This invokes undefined behavior when the array is - * empty. + * Returns a reference to the nth last element. This invokes undefined behavior when the span is + * too short. */ - constexpr T &last() const + constexpr T &last(const int64_t n = 0) const { - BLI_assert(size_ > 0); - return data_[size_ - 1]; + BLI_assert(n >= 0); + BLI_assert(n < size_); + return data_[size_ - 1 - n]; } /** diff --git a/source/blender/blenlib/BLI_vector.hh b/source/blender/blenlib/BLI_vector.hh index d5d33b8a000..da9ab9c313e 100644 --- a/source/blender/blenlib/BLI_vector.hh +++ b/source/blender/blenlib/BLI_vector.hh @@ -639,18 +639,20 @@ class Vector { } /** - * Return a reference to the last element in the vector. - * This invokes undefined behavior when the vector is empty. + * Return a reference to the nth last element. + * This invokes undefined behavior when the vector is too short. */ - const T &last() const + const T &last(const int64_t n = 0) const { - BLI_assert(this->size() > 0); - return *(end_ - 1); + BLI_assert(n >= 0); + BLI_assert(n < this->size()); + return *(end_ - 1 - n); } - T &last() + T &last(const int64_t n = 0) { - BLI_assert(this->size() > 0); - return *(end_ - 1); + BLI_assert(n >= 0); + BLI_assert(n < this->size()); + return *(end_ - 1 - n); } /** diff --git a/source/blender/blenlib/tests/BLI_array_test.cc b/source/blender/blenlib/tests/BLI_array_test.cc index 6d12b54099a..74eeb5e4e5e 100644 --- a/source/blender/blenlib/tests/BLI_array_test.cc +++ b/source/blender/blenlib/tests/BLI_array_test.cc @@ -231,9 +231,11 @@ TEST(array, Last) { Array<int> array = {5, 7, 8, 9}; EXPECT_EQ(array.last(), 9); + EXPECT_EQ(array.last(1), 8); array.last() = 1; EXPECT_EQ(array[3], 1); EXPECT_EQ(const_cast<const Array<int> &>(array).last(), 1); + EXPECT_EQ(const_cast<const Array<int> &>(array).last(2), 7); } TEST(array, Reinitialize) diff --git a/source/blender/blenlib/tests/BLI_span_test.cc b/source/blender/blenlib/tests/BLI_span_test.cc index 35fb22b3257..0bd34250deb 100644 --- a/source/blender/blenlib/tests/BLI_span_test.cc +++ b/source/blender/blenlib/tests/BLI_span_test.cc @@ -247,6 +247,8 @@ TEST(span, FirstLast) Span<int> a_span(a); EXPECT_EQ(a_span.first(), 6); EXPECT_EQ(a_span.last(), 9); + EXPECT_EQ(a_span.last(1), 8); + EXPECT_EQ(a_span.last(2), 7); } TEST(span, FirstLast_OneElement) @@ -255,6 +257,7 @@ TEST(span, FirstLast_OneElement) Span<int> a_span(&a, 1); EXPECT_EQ(a_span.first(), 3); EXPECT_EQ(a_span.last(), 3); + EXPECT_EQ(a_span.last(0), 3); } TEST(span, Get) diff --git a/source/blender/blenlib/tests/BLI_vector_test.cc b/source/blender/blenlib/tests/BLI_vector_test.cc index 40cda20c395..29b6d2b41fe 100644 --- a/source/blender/blenlib/tests/BLI_vector_test.cc +++ b/source/blender/blenlib/tests/BLI_vector_test.cc @@ -447,6 +447,9 @@ TEST(vector, Last) { Vector<int> a{3, 5, 7}; EXPECT_EQ(a.last(), 7); + EXPECT_EQ(a.last(0), 7); + EXPECT_EQ(a.last(1), 5); + EXPECT_EQ(a.last(2), 3); } TEST(vector, AppendNTimes) |