BLI: Add utility functions to generic spans

Generally we don't want to do per-element operations on these spans
because of the overhead of the runtime type system, but these operations
on the whole span avoid ugly pointer arithmetic in other areas.
This commit is contained in:
Hans Goudey 2022-09-12 10:38:31 -05:00
parent e37f3388b1
commit 225b5a3491
1 changed files with 57 additions and 0 deletions

View File

@ -100,6 +100,34 @@ class GSpan {
{
return this->slice(range.start(), range.size());
}
GSpan drop_front(const int64_t n) const
{
BLI_assert(n >= 0);
const int64_t new_size = std::max<int64_t>(0, size_ - n);
return GSpan(*type_, POINTER_OFFSET(data_, type_->size() * n), new_size);
}
GSpan drop_back(const int64_t n) const
{
BLI_assert(n >= 0);
const int64_t new_size = std::max<int64_t>(0, size_ - n);
return GSpan(*type_, data_, new_size);
}
GSpan take_front(const int64_t n) const
{
BLI_assert(n >= 0);
const int64_t new_size = std::min<int64_t>(size_, n);
return GSpan(*type_, data_, new_size);
}
GSpan take_back(const int64_t n) const
{
BLI_assert(n >= 0);
const int64_t new_size = std::min<int64_t>(size_, n);
return GSpan(*type_, POINTER_OFFSET(data_, type_->size() * (size_ - new_size)), new_size);
}
};
/**
@ -199,6 +227,35 @@ class GMutableSpan {
return this->slice(range.start(), range.size());
}
GMutableSpan drop_front(const int64_t n) const
{
BLI_assert(n >= 0);
const int64_t new_size = std::max<int64_t>(0, size_ - n);
return GMutableSpan(*type_, POINTER_OFFSET(data_, type_->size() * n), new_size);
}
GMutableSpan drop_back(const int64_t n) const
{
BLI_assert(n >= 0);
const int64_t new_size = std::max<int64_t>(0, size_ - n);
return GMutableSpan(*type_, data_, new_size);
}
GMutableSpan take_front(const int64_t n) const
{
BLI_assert(n >= 0);
const int64_t new_size = std::min<int64_t>(size_, n);
return GMutableSpan(*type_, data_, new_size);
}
GMutableSpan take_back(const int64_t n) const
{
BLI_assert(n >= 0);
const int64_t new_size = std::min<int64_t>(size_, n);
return GMutableSpan(
*type_, POINTER_OFFSET(data_, type_->size() * (size_ - new_size)), new_size);
}
/**
* Copy all values from another span into this span. This invokes undefined behavior when the
* destination contains uninitialized data and T is not trivially copy constructible.