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:
Diffstat (limited to 'source/blender/blenlib/BLI_span.hh')
-rw-r--r--source/blender/blenlib/BLI_span.hh99
1 files changed, 63 insertions, 36 deletions
diff --git a/source/blender/blenlib/BLI_span.hh b/source/blender/blenlib/BLI_span.hh
index a2de76e080e..5b4d2769f57 100644
--- a/source/blender/blenlib/BLI_span.hh
+++ b/source/blender/blenlib/BLI_span.hh
@@ -86,7 +86,7 @@ namespace blender {
*/
template<typename T> class Span {
private:
- const T *start_ = nullptr;
+ const T *data_ = nullptr;
int64_t size_ = 0;
public:
@@ -95,13 +95,13 @@ template<typename T> class Span {
*/
Span() = default;
- Span(const T *start, int64_t size) : start_(start), size_(size)
+ Span(const T *start, int64_t size) : data_(start), size_(size)
{
BLI_assert(size >= 0);
}
template<typename U, typename std::enable_if_t<is_convertible_pointer_v<U, T>> * = nullptr>
- Span(const U *start, int64_t size) : start_((const T *)start), size_(size)
+ Span(const U *start, int64_t size) : data_(static_cast<const T *>(start)), size_(size)
{
BLI_assert(size >= 0);
}
@@ -117,11 +117,12 @@ template<typename T> class Span {
* Span<int> span = {1, 2, 3, 4};
* call_function_with_array(span);
*/
- Span(const std::initializer_list<T> &list) : Span(list.begin(), (int64_t)list.size())
+ Span(const std::initializer_list<T> &list)
+ : Span(list.begin(), static_cast<int64_t>(list.size()))
{
}
- Span(const std::vector<T> &vector) : Span(vector.data(), (int64_t)vector.size())
+ Span(const std::vector<T> &vector) : Span(vector.data(), static_cast<int64_t>(vector.size()))
{
}
@@ -132,10 +133,9 @@ template<typename T> class Span {
/**
* Support implicit conversions like the ones below:
* Span<T *> -> Span<const T *>
- * Span<Derived *> -> Span<Base *>
*/
template<typename U, typename std::enable_if_t<is_convertible_pointer_v<U, T>> * = nullptr>
- Span(Span<U> array) : start_((T *)array.data()), size_(array.size())
+ Span(Span<U> array) : data_(static_cast<const T *>(array.data())), size_(array.size())
{
}
@@ -148,7 +148,7 @@ template<typename T> class Span {
BLI_assert(start >= 0);
BLI_assert(size >= 0);
BLI_assert(start + size <= this->size() || size == 0);
- return Span(start_ + start, size);
+ return Span(data_ + start, size);
}
Span slice(IndexRange range) const
@@ -206,17 +206,25 @@ template<typename T> class Span {
*/
const T *data() const
{
- return start_;
+ return data_;
}
const T *begin() const
{
- return start_;
+ return data_;
}
-
const T *end() const
{
- return start_ + size_;
+ return data_ + size_;
+ }
+
+ std::reverse_iterator<const T *> rbegin() const
+ {
+ return std::reverse_iterator<const T *>(this->end());
+ }
+ std::reverse_iterator<const T *> rend() const
+ {
+ return std::reverse_iterator<const T *>(this->begin());
}
/**
@@ -227,7 +235,7 @@ template<typename T> class Span {
{
BLI_assert(index >= 0);
BLI_assert(index < size_);
- return start_[index];
+ return data_[index];
}
/**
@@ -299,7 +307,7 @@ template<typename T> class Span {
const T &first() const
{
BLI_assert(size_ > 0);
- return start_[0];
+ return data_[0];
}
/**
@@ -309,7 +317,7 @@ template<typename T> class Span {
const T &last() const
{
BLI_assert(size_ > 0);
- return start_[size_ - 1];
+ return data_[size_ - 1];
}
/**
@@ -319,7 +327,7 @@ template<typename T> class Span {
T get(int64_t index, const T &fallback) const
{
if (index < size_ && index >= 0) {
- return start_[index];
+ return data_[index];
}
return fallback;
}
@@ -335,9 +343,9 @@ template<typename T> class Span {
BLI_assert(size_ < 1000);
for (int64_t i = 0; i < size_; i++) {
- const T &value = start_[i];
+ const T &value = data_[i];
for (int64_t j = i + 1; j < size_; j++) {
- if (value == start_[j]) {
+ if (value == data_[j]) {
return true;
}
}
@@ -357,7 +365,7 @@ template<typename T> class Span {
BLI_assert(size_ < 1000);
for (int64_t i = 0; i < size_; i++) {
- const T &value = start_[i];
+ const T &value = data_[i];
if (other.contains(value)) {
return true;
}
@@ -373,7 +381,7 @@ template<typename T> class Span {
{
const int64_t index = this->first_index_try(search_value);
BLI_assert(index >= 0);
- return (int64_t)index;
+ return index;
}
/**
@@ -382,7 +390,7 @@ template<typename T> class Span {
int64_t first_index_try(const T &search_value) const
{
for (int64_t i = 0; i < size_; i++) {
- if (start_[i] == search_value) {
+ if (data_[i] == search_value) {
return i;
}
}
@@ -405,7 +413,7 @@ template<typename T> class Span {
{
BLI_assert((size_ * sizeof(T)) % sizeof(NewT) == 0);
int64_t new_size = size_ * sizeof(T) / sizeof(NewT);
- return Span<NewT>(reinterpret_cast<const NewT *>(start_), new_size);
+ return Span<NewT>(reinterpret_cast<const NewT *>(data_), new_size);
}
/**
@@ -438,13 +446,13 @@ template<typename T> class Span {
*/
template<typename T> class MutableSpan {
private:
- T *start_;
+ T *data_;
int64_t size_;
public:
MutableSpan() = default;
- MutableSpan(T *start, const int64_t size) : start_(start), size_(size)
+ MutableSpan(T *start, const int64_t size) : data_(start), size_(size)
{
}
@@ -458,7 +466,7 @@ template<typename T> class MutableSpan {
operator Span<T>() const
{
- return Span<T>(start_, size_);
+ return Span<T>(data_, size_);
}
/**
@@ -474,7 +482,7 @@ template<typename T> class MutableSpan {
*/
void fill(const T &value)
{
- initialized_fill_n(start_, size_, value);
+ initialized_fill_n(data_, size_, value);
}
/**
@@ -485,7 +493,7 @@ template<typename T> class MutableSpan {
{
for (int64_t i : indices) {
BLI_assert(i < size_);
- start_[i] = value;
+ data_[i] = value;
}
}
@@ -495,23 +503,31 @@ template<typename T> class MutableSpan {
*/
T *data() const
{
- return start_;
+ return data_;
}
T *begin() const
{
- return start_;
+ return data_;
}
-
T *end() const
{
- return start_ + size_;
+ return data_ + size_;
+ }
+
+ std::reverse_iterator<T *> rbegin() const
+ {
+ return std::reverse_iterator<T *>(this->end());
+ }
+ std::reverse_iterator<T *> rend() const
+ {
+ return std::reverse_iterator<T *>(this->begin());
}
T &operator[](const int64_t index) const
{
BLI_assert(index < this->size());
- return start_[index];
+ return data_[index];
}
/**
@@ -521,7 +537,7 @@ template<typename T> class MutableSpan {
MutableSpan slice(const int64_t start, const int64_t length) const
{
BLI_assert(start + length <= this->size());
- return MutableSpan(start_ + start, length);
+ return MutableSpan(data_ + start, length);
}
/**
@@ -570,7 +586,7 @@ template<typename T> class MutableSpan {
*/
Span<T> as_span() const
{
- return Span<T>(start_, size_);
+ return Span<T>(data_, size_);
}
/**
@@ -589,7 +605,7 @@ template<typename T> class MutableSpan {
T &last() const
{
BLI_assert(size_ > 0);
- return start_[size_ - 1];
+ return data_[size_ - 1];
}
/**
@@ -608,13 +624,24 @@ template<typename T> class MutableSpan {
}
/**
+ * 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.
+ * The size of both spans is expected to be the same.
+ */
+ void copy_from(Span<T> values)
+ {
+ BLI_assert(size_ == values.size());
+ initialized_copy_n(values.data(), size_, data_);
+ }
+
+ /**
* Returns a new span to the same underlying memory buffer. No conversions are done.
*/
template<typename NewT> MutableSpan<NewT> cast() const
{
BLI_assert((size_ * sizeof(T)) % sizeof(NewT) == 0);
int64_t new_size = size_ * sizeof(T) / sizeof(NewT);
- return MutableSpan<NewT>(reinterpret_cast<NewT *>(start_), new_size);
+ return MutableSpan<NewT>(reinterpret_cast<NewT *>(data_), new_size);
}
};