Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2022-02-24 16:45:41 +0300
committerJacques Lucke <jacques@blender.org>2022-02-24 16:50:13 +0300
commit9be720d85efb307ad37b73f0f5fffd95629c7e20 (patch)
tree8b0c0f074c9f6616ff2b79992974177b2d4215ef /source/blender/blenlib
parent7cab7eb3d6cd929f5c354416b4baa6c608f08d82 (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.hh18
-rw-r--r--source/blender/blenlib/BLI_span.hh22
-rw-r--r--source/blender/blenlib/BLI_vector.hh18
-rw-r--r--source/blender/blenlib/tests/BLI_array_test.cc2
-rw-r--r--source/blender/blenlib/tests/BLI_span_test.cc3
-rw-r--r--source/blender/blenlib/tests/BLI_vector_test.cc3
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)