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.hh230
1 files changed, 123 insertions, 107 deletions
diff --git a/source/blender/blenlib/BLI_span.hh b/source/blender/blenlib/BLI_span.hh
index ce4e90d5e16..81b86f647f6 100644
--- a/source/blender/blenlib/BLI_span.hh
+++ b/source/blender/blenlib/BLI_span.hh
@@ -87,8 +87,8 @@ namespace blender {
*/
template<typename T> class Span {
private:
- const T *m_start = nullptr;
- uint m_size = 0;
+ const T *data_ = nullptr;
+ int64_t size_ = 0;
public:
/**
@@ -96,8 +96,15 @@ template<typename T> class Span {
*/
Span() = default;
- Span(const T *start, uint size) : m_start(start), m_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) : data_((const T *)start), size_(size)
+ {
+ BLI_assert(size >= 0);
}
/**
@@ -111,11 +118,11 @@ 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(), (uint)list.size())
+ Span(const std::initializer_list<T> &list) : Span(list.begin(), (int64_t)list.size())
{
}
- Span(const std::vector<T> &vector) : Span(vector.data(), (uint)vector.size())
+ Span(const std::vector<T> &vector) : Span(vector.data(), (int64_t)vector.size())
{
}
@@ -128,9 +135,8 @@ template<typename T> class Span {
* Span<T *> -> Span<const T *>
* Span<Derived *> -> Span<Base *>
*/
- template<typename U,
- typename std::enable_if<std::is_convertible<U *, T>::value>::type * = nullptr>
- Span(Span<U *> array) : Span((T *)array.data(), array.size())
+ template<typename U, typename std::enable_if_t<is_convertible_pointer_v<U, T>> * = nullptr>
+ Span(Span<U> array) : data_((T *)array.data()), size_(array.size())
{
}
@@ -138,10 +144,12 @@ template<typename T> class Span {
* Returns a contiguous part of the array. This invokes undefined behavior when the slice does
* not stay within the bounds of the array.
*/
- Span slice(uint start, uint size) const
+ Span slice(int64_t start, int64_t size) const
{
+ BLI_assert(start >= 0);
+ BLI_assert(size >= 0);
BLI_assert(start + size <= this->size() || size == 0);
- return Span(m_start + start, size);
+ return Span(data_ + start, size);
}
Span slice(IndexRange range) const
@@ -153,8 +161,9 @@ template<typename T> class Span {
* Returns a new Span with n elements removed from the beginning. This invokes undefined
* behavior when the array is too small.
*/
- Span drop_front(uint n) const
+ Span drop_front(int64_t n) const
{
+ BLI_assert(n >= 0);
BLI_assert(n <= this->size());
return this->slice(n, this->size() - n);
}
@@ -163,8 +172,9 @@ template<typename T> class Span {
* Returns a new Span with n elements removed from the beginning. This invokes undefined
* behavior when the array is too small.
*/
- Span drop_back(uint n) const
+ Span drop_back(int64_t n) const
{
+ BLI_assert(n >= 0);
BLI_assert(n <= this->size());
return this->slice(0, this->size() - n);
}
@@ -173,8 +183,9 @@ template<typename T> class Span {
* Returns a new Span that only contains the first n elements. This invokes undefined
* behavior when the array is too small.
*/
- Span take_front(uint n) const
+ Span take_front(int64_t n) const
{
+ BLI_assert(n >= 0);
BLI_assert(n <= this->size());
return this->slice(0, n);
}
@@ -183,8 +194,9 @@ template<typename T> class Span {
* Returns a new Span that only contains the last n elements. This invokes undefined
* behavior when the array is too small.
*/
- Span take_back(uint n) const
+ Span take_back(int64_t n) const
{
+ BLI_assert(n >= 0);
BLI_assert(n <= this->size());
return this->slice(this->size() - n, n);
}
@@ -195,35 +207,36 @@ template<typename T> class Span {
*/
const T *data() const
{
- return m_start;
+ return data_;
}
const T *begin() const
{
- return m_start;
+ return data_;
}
const T *end() const
{
- return m_start + m_size;
+ return data_ + size_;
}
/**
* Access an element in the array. This invokes undefined behavior when the index is out of
* bounds.
*/
- const T &operator[](uint index) const
+ const T &operator[](int64_t index) const
{
- BLI_assert(index < m_size);
- return m_start[index];
+ BLI_assert(index >= 0);
+ BLI_assert(index < size_);
+ return data_[index];
}
/**
* Returns the number of elements in the referenced array.
*/
- uint size() const
+ int64_t size() const
{
- return m_size;
+ return size_;
}
/**
@@ -231,15 +244,15 @@ template<typename T> class Span {
*/
bool is_empty() const
{
- return m_size == 0;
+ return size_ == 0;
}
/**
* Returns the number of bytes referenced by this Span.
*/
- uint size_in_bytes() const
+ int64_t size_in_bytes() const
{
- return sizeof(T) * m_size;
+ return sizeof(T) * size_;
}
/**
@@ -269,9 +282,9 @@ template<typename T> class Span {
* Does a linear search to count how often the value is in the array.
* Returns the number of occurrences.
*/
- uint count(const T &value) const
+ int64_t count(const T &value) const
{
- uint counter = 0;
+ int64_t counter = 0;
for (const T &element : *this) {
if (element == value) {
counter++;
@@ -286,8 +299,8 @@ template<typename T> class Span {
*/
const T &first() const
{
- BLI_assert(m_size > 0);
- return m_start[0];
+ BLI_assert(size_ > 0);
+ return data_[0];
}
/**
@@ -296,18 +309,18 @@ template<typename T> class Span {
*/
const T &last() const
{
- BLI_assert(m_size > 0);
- return m_start[m_size - 1];
+ BLI_assert(size_ > 0);
+ return data_[size_ - 1];
}
/**
* Returns the element at the given index. If the index is out of range, return the fallback
* value.
*/
- T get(uint index, const T &fallback) const
+ T get(int64_t index, const T &fallback) const
{
- if (index < m_size) {
- return m_start[index];
+ if (index < size_ && index >= 0) {
+ return data_[index];
}
return fallback;
}
@@ -320,12 +333,12 @@ template<typename T> class Span {
{
/* The size should really be smaller than that. If it is not, the calling code should be
* changed. */
- BLI_assert(m_size < 1000);
+ BLI_assert(size_ < 1000);
- for (uint i = 0; i < m_size; i++) {
- const T &value = m_start[i];
- for (uint j = i + 1; j < m_size; j++) {
- if (value == m_start[j]) {
+ for (int64_t i = 0; i < size_; i++) {
+ const T &value = data_[i];
+ for (int64_t j = i + 1; j < size_; j++) {
+ if (value == data_[j]) {
return true;
}
}
@@ -342,10 +355,10 @@ template<typename T> class Span {
{
/* The size should really be smaller than that. If it is not, the calling code should be
* changed. */
- BLI_assert(m_size < 1000);
+ BLI_assert(size_ < 1000);
- for (uint i = 0; i < m_size; i++) {
- const T &value = m_start[i];
+ for (int64_t i = 0; i < size_; i++) {
+ const T &value = data_[i];
if (other.contains(value)) {
return true;
}
@@ -357,20 +370,20 @@ template<typename T> class Span {
* Returns the index of the first occurrence of the given value. This invokes undefined behavior
* when the value is not in the array.
*/
- uint first_index(const T &search_value) const
+ int64_t first_index(const T &search_value) const
{
- int index = this->first_index_try(search_value);
+ const int64_t index = this->first_index_try(search_value);
BLI_assert(index >= 0);
- return (uint)index;
+ return (int64_t)index;
}
/**
* Returns the index of the first occurrence of the given value or -1 if it does not exist.
*/
- int first_index_try(const T &search_value) const
+ int64_t first_index_try(const T &search_value) const
{
- for (uint i = 0; i < m_size; i++) {
- if (m_start[i] == search_value) {
+ for (int64_t i = 0; i < size_; i++) {
+ if (data_[i] == search_value) {
return i;
}
}
@@ -383,7 +396,7 @@ template<typename T> class Span {
*/
IndexRange index_range() const
{
- return IndexRange(m_size);
+ return IndexRange(size_);
}
/**
@@ -391,9 +404,9 @@ template<typename T> class Span {
*/
template<typename NewT> Span<NewT> cast() const
{
- BLI_assert((m_size * sizeof(T)) % sizeof(NewT) == 0);
- uint new_size = m_size * sizeof(T) / sizeof(NewT);
- return Span<NewT>(reinterpret_cast<const NewT *>(m_start), new_size);
+ BLI_assert((size_ * sizeof(T)) % sizeof(NewT) == 0);
+ int64_t new_size = size_ * sizeof(T) / sizeof(NewT);
+ return Span<NewT>(reinterpret_cast<const NewT *>(data_), new_size);
}
/**
@@ -402,7 +415,7 @@ template<typename T> class Span {
*/
template<typename PrintLineF> void print_as_lines(std::string name, PrintLineF print_line) const
{
- std::cout << "Span: " << name << " \tSize:" << m_size << '\n';
+ std::cout << "Span: " << name << " \tSize:" << size_ << '\n';
for (const T &value : *this) {
std::cout << " ";
print_line(value);
@@ -426,28 +439,13 @@ template<typename T> class Span {
*/
template<typename T> class MutableSpan {
private:
- T *m_start;
- uint m_size;
+ T *data_;
+ int64_t size_;
public:
MutableSpan() = default;
- MutableSpan(T *start, uint size) : m_start(start), m_size(size)
- {
- }
-
- /**
- * Reference an initializer_list. Note that the data in the initializer_list is only valid until
- * the expression containing it is fully computed.
- *
- * Do:
- * call_function_with_array({1, 2, 3, 4});
- *
- * Don't:
- * MutableSpan<int> span = {1, 2, 3, 4};
- * call_function_with_array(span);
- */
- MutableSpan(std::initializer_list<T> &list) : MutableSpan(list.begin(), list.size())
+ MutableSpan(T *start, const int64_t size) : data_(start), size_(size)
{
}
@@ -461,15 +459,15 @@ template<typename T> class MutableSpan {
operator Span<T>() const
{
- return Span<T>(m_start, m_size);
+ return Span<T>(data_, size_);
}
/**
* Returns the number of elements in the array.
*/
- uint size() const
+ int64_t size() const
{
- return m_size;
+ return size_;
}
/**
@@ -477,18 +475,18 @@ template<typename T> class MutableSpan {
*/
void fill(const T &value)
{
- initialized_fill_n(m_start, m_size, value);
+ initialized_fill_n(data_, size_, value);
}
/**
* Replace a subset of all elements with the given value. This invokes undefined behavior when
* one of the indices is out of bounds.
*/
- void fill_indices(Span<uint> indices, const T &value)
+ void fill_indices(Span<int64_t> indices, const T &value)
{
- for (uint i : indices) {
- BLI_assert(i < m_size);
- m_start[i] = value;
+ for (int64_t i : indices) {
+ BLI_assert(i < size_);
+ data_[i] = value;
}
}
@@ -498,40 +496,40 @@ template<typename T> class MutableSpan {
*/
T *data() const
{
- return m_start;
+ return data_;
}
T *begin() const
{
- return m_start;
+ return data_;
}
T *end() const
{
- return m_start + m_size;
+ return data_ + size_;
}
- T &operator[](uint index) const
+ T &operator[](const int64_t index) const
{
BLI_assert(index < this->size());
- return m_start[index];
+ return data_[index];
}
/**
* Returns a contiguous part of the array. This invokes undefined behavior when the slice would
* go out of bounds.
*/
- MutableSpan slice(uint start, uint length) const
+ MutableSpan slice(const int64_t start, const int64_t length) const
{
BLI_assert(start + length <= this->size());
- return MutableSpan(m_start + start, length);
+ return MutableSpan(data_ + start, length);
}
/**
* Returns a new MutableSpan with n elements removed from the beginning. This invokes
* undefined behavior when the array is too small.
*/
- MutableSpan drop_front(uint n) const
+ MutableSpan drop_front(const int64_t n) const
{
BLI_assert(n <= this->size());
return this->slice(n, this->size() - n);
@@ -541,7 +539,7 @@ template<typename T> class MutableSpan {
* Returns a new MutableSpan with n elements removed from the end. This invokes undefined
* behavior when the array is too small.
*/
- MutableSpan drop_back(uint n) const
+ MutableSpan drop_back(const int64_t n) const
{
BLI_assert(n <= this->size());
return this->slice(0, this->size() - n);
@@ -551,7 +549,7 @@ template<typename T> class MutableSpan {
* Returns a new MutableSpan that only contains the first n elements. This invokes undefined
* behavior when the array is too small.
*/
- MutableSpan take_front(uint n) const
+ MutableSpan take_front(const int64_t n) const
{
BLI_assert(n <= this->size());
return this->slice(0, n);
@@ -561,7 +559,7 @@ template<typename T> class MutableSpan {
* Return a new MutableSpan that only contains the last n elements. This invokes undefined
* behavior when the array is too small.
*/
- MutableSpan take_back(uint n) const
+ MutableSpan take_back(const int64_t n) const
{
BLI_assert(n <= this->size());
return this->slice(this->size() - n, n);
@@ -573,7 +571,7 @@ template<typename T> class MutableSpan {
*/
Span<T> as_span() const
{
- return Span<T>(m_start, m_size);
+ return Span<T>(data_, size_);
}
/**
@@ -582,7 +580,7 @@ template<typename T> class MutableSpan {
*/
IndexRange index_range() const
{
- return IndexRange(m_size);
+ return IndexRange(size_);
}
/**
@@ -591,8 +589,34 @@ template<typename T> class MutableSpan {
*/
T &last() const
{
- BLI_assert(m_size > 0);
- return m_start[m_size - 1];
+ BLI_assert(size_ > 0);
+ return data_[size_ - 1];
+ }
+
+ /**
+ * Does a linear search to count how often the value is in the array.
+ * Returns the number of occurrences.
+ */
+ int64_t count(const T &value) const
+ {
+ int64_t counter = 0;
+ for (const T &element : *this) {
+ if (element == value) {
+ counter++;
+ }
+ }
+ return counter;
+ }
+
+ /**
+ * 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_);
}
/**
@@ -600,28 +624,20 @@ template<typename T> class MutableSpan {
*/
template<typename NewT> MutableSpan<NewT> cast() const
{
- BLI_assert((m_size * sizeof(T)) % sizeof(NewT) == 0);
- uint new_size = m_size * sizeof(T) / sizeof(NewT);
- return MutableSpan<NewT>(reinterpret_cast<NewT *>(m_start), new_size);
+ BLI_assert((size_ * sizeof(T)) % sizeof(NewT) == 0);
+ int64_t new_size = size_ * sizeof(T) / sizeof(NewT);
+ return MutableSpan<NewT>(reinterpret_cast<NewT *>(data_), new_size);
}
};
/**
- * Shorthand to make use of automatic template parameter deduction.
- */
-template<typename T> Span<T> ref_c_array(const T *array, uint size)
-{
- return Span<T>(array, size);
-}
-
-/**
* Utilities to check that arrays have the same size in debug builds.
*/
template<typename T1, typename T2> void assert_same_size(const T1 &v1, const T2 &v2)
{
UNUSED_VARS_NDEBUG(v1, v2);
#ifdef DEBUG
- uint size = v1.size();
+ int64_t size = v1.size();
BLI_assert(size == v1.size());
BLI_assert(size == v2.size());
#endif
@@ -632,7 +648,7 @@ void assert_same_size(const T1 &v1, const T2 &v2, const T3 &v3)
{
UNUSED_VARS_NDEBUG(v1, v2, v3);
#ifdef DEBUG
- uint size = v1.size();
+ int64_t size = v1.size();
BLI_assert(size == v1.size());
BLI_assert(size == v2.size());
BLI_assert(size == v3.size());