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_vector.hh')
-rw-r--r--source/blender/blenlib/BLI_vector.hh118
1 files changed, 55 insertions, 63 deletions
diff --git a/source/blender/blenlib/BLI_vector.hh b/source/blender/blenlib/BLI_vector.hh
index 1fe38464ad0..66de8d2fbd1 100644
--- a/source/blender/blenlib/BLI_vector.hh
+++ b/source/blender/blenlib/BLI_vector.hh
@@ -70,7 +70,7 @@ template<
* When T is large, the small buffer optimization is disabled by default to avoid large
* unexpected allocations on the stack. It can still be enabled explicitly though.
*/
- uint InlineBufferCapacity = (sizeof(T) < 100) ? 4 : 0,
+ int64_t InlineBufferCapacity = (sizeof(T) < 100) ? 4 : 0,
/**
* The allocator used by this vector. Should rarely be changed, except when you don't want that
* MEM_* is used internally.
@@ -100,8 +100,8 @@ class Vector {
* annoying. Knowing the size of a vector is often quite essential when debugging some code.
*/
#ifndef NDEBUG
- uint debug_size_;
-# define UPDATE_VECTOR_SIZE(ptr) (ptr)->debug_size_ = (uint)((ptr)->end_ - (ptr)->begin_)
+ int64_t debug_size_;
+# define UPDATE_VECTOR_SIZE(ptr) (ptr)->debug_size_ = (int64_t)((ptr)->end_ - (ptr)->begin_)
#else
# define UPDATE_VECTOR_SIZE(ptr) ((void)0)
#endif
@@ -110,7 +110,7 @@ class Vector {
* Be a friend with other vector instantiations. This is necessary to implement some memory
* management logic.
*/
- template<typename OtherT, uint OtherInlineBufferCapacity, typename OtherAllocator>
+ template<typename OtherT, int64_t OtherInlineBufferCapacity, typename OtherAllocator>
friend class Vector;
public:
@@ -131,7 +131,7 @@ class Vector {
* The elements will be default constructed.
* If T is trivially constructible, the elements in the vector are not touched.
*/
- explicit Vector(uint size) : Vector()
+ explicit Vector(int64_t size) : Vector()
{
this->resize(size);
}
@@ -139,7 +139,7 @@ class Vector {
/**
* Create a vector filled with a specific value.
*/
- Vector(uint size, const T &value) : Vector()
+ Vector(int64_t size, const T &value) : Vector()
{
this->resize(size, value);
}
@@ -150,7 +150,7 @@ class Vector {
template<typename U, typename std::enable_if_t<std::is_convertible_v<U, T>> * = nullptr>
Vector(Span<U> values, Allocator allocator = {}) : Vector(allocator)
{
- const uint size = values.size();
+ const int64_t size = values.size();
this->reserve(size);
this->increase_size_by_unchecked(size);
uninitialized_convert_n<U, T>(values.data(), size, begin_);
@@ -217,7 +217,7 @@ class Vector {
* Create a copy of a vector with a different InlineBufferCapacity. This needs to be handled
* separately, so that the other one is a valid copy constructor.
*/
- template<uint OtherInlineBufferCapacity>
+ template<int64_t OtherInlineBufferCapacity>
Vector(const Vector<T, OtherInlineBufferCapacity, Allocator> &other)
: Vector(other.as_span(), other.allocator_)
{
@@ -227,11 +227,11 @@ class Vector {
* Steal the elements from another vector. This does not do an allocation. The other vector will
* have zero elements afterwards.
*/
- template<uint OtherInlineBufferCapacity>
+ template<int64_t OtherInlineBufferCapacity>
Vector(Vector<T, OtherInlineBufferCapacity, Allocator> &&other) noexcept
: allocator_(other.allocator_)
{
- const uint size = other.size();
+ const int64_t size = other.size();
if (other.is_inline()) {
if (size <= InlineBufferCapacity) {
@@ -243,8 +243,8 @@ class Vector {
}
else {
/* Copy from inline buffer to newly allocated buffer. */
- const uint capacity = size;
- begin_ = (T *)allocator_.allocate(sizeof(T) * capacity, alignof(T), AT);
+ const int64_t capacity = size;
+ begin_ = (T *)allocator_.allocate(sizeof(T) * (size_t)capacity, alignof(T), AT);
end_ = begin_ + size;
capacity_end_ = begin_ + capacity;
uninitialized_relocate_n(other.begin_, size, begin_);
@@ -302,14 +302,16 @@ class Vector {
* Get the value at the given index. 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 >= 0);
BLI_assert(index < this->size());
return begin_[index];
}
- T &operator[](uint index)
+ T &operator[](int64_t index)
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->size());
return begin_[index];
}
@@ -351,7 +353,7 @@ class Vector {
* This won't necessarily make an allocation when min_capacity is small.
* The actual size of the vector does not change.
*/
- void reserve(const uint min_capacity)
+ void reserve(const int64_t min_capacity)
{
if (min_capacity > this->capacity()) {
this->realloc_to_at_least(min_capacity);
@@ -364,9 +366,10 @@ class Vector {
* destructed. If new_size is larger than the old size, the new elements at the end are default
* constructed. If T is trivially constructible, the memory is not touched by this function.
*/
- void resize(const uint new_size)
+ void resize(const int64_t new_size)
{
- const uint old_size = this->size();
+ BLI_assert(new_size >= 0);
+ const int64_t old_size = this->size();
if (new_size > old_size) {
this->reserve(new_size);
default_construct_n(begin_ + old_size, new_size - old_size);
@@ -384,9 +387,10 @@ class Vector {
* destructed. If new_size is larger than the old size, the new elements will be copy constructed
* from the given value.
*/
- void resize(const uint new_size, const T &value)
+ void resize(const int64_t new_size, const T &value)
{
- const uint old_size = this->size();
+ BLI_assert(new_size >= 0);
+ const int64_t old_size = this->size();
if (new_size > old_size) {
this->reserve(new_size);
uninitialized_fill_n(begin_ + old_size, new_size - old_size, value);
@@ -447,9 +451,9 @@ class Vector {
* Append the value to the vector and return the index that can be used to access the newly
* added value.
*/
- uint append_and_get_index(const T &value)
+ int64_t append_and_get_index(const T &value)
{
- const uint index = this->size();
+ const int64_t index = this->size();
this->append(value);
return index;
}
@@ -490,8 +494,9 @@ class Vector {
* Insert the same element n times at the end of the vector.
* This might result in a reallocation internally.
*/
- void append_n_times(const T &value, const uint n)
+ void append_n_times(const T &value, const int64_t n)
{
+ BLI_assert(n >= 0);
this->reserve(this->size() + n);
blender::uninitialized_fill_n(end_, n, value);
this->increase_size_by_unchecked(n);
@@ -503,7 +508,7 @@ class Vector {
* useful when you want to call constructors in the vector yourself. This should only be done in
* very rare cases and has to be justified every time.
*/
- void increase_size_by_unchecked(const uint n)
+ void increase_size_by_unchecked(const int64_t n)
{
BLI_assert(end_ + n <= capacity_end_);
end_ += n;
@@ -519,7 +524,7 @@ class Vector {
{
this->extend(array.data(), array.size());
}
- void extend(const T *start, uint amount)
+ void extend(const T *start, int64_t amount)
{
this->reserve(this->size() + amount);
this->extend_unchecked(start, amount);
@@ -545,8 +550,9 @@ class Vector {
{
this->extend_unchecked(array.data(), array.size());
}
- void extend_unchecked(const T *start, uint amount)
+ void extend_unchecked(const T *start, int64_t amount)
{
+ BLI_assert(amount >= 0);
BLI_assert(begin_ + amount <= capacity_end_);
blender::uninitialized_copy_n(start, amount, end_);
end_ += amount;
@@ -569,28 +575,12 @@ class Vector {
}
/**
- * Replace every element with a new value.
- */
- void fill(const T &value)
- {
- initialized_fill_n(begin_, this->size(), value);
- }
-
- /**
- * Copy the value to all positions specified by the indices array.
- */
- void fill_indices(Span<uint> indices, const T &value)
- {
- MutableSpan<T>(*this).fill_indices(indices, value);
- }
-
- /**
* Return how many values are currently stored in the vector.
*/
- uint size() const
+ int64_t size() const
{
- BLI_assert(debug_size_ == (uint)(end_ - begin_));
- return (uint)(end_ - begin_);
+ BLI_assert(debug_size_ == (int64_t)(end_ - begin_));
+ return (int64_t)(end_ - begin_);
}
/**
@@ -635,8 +625,9 @@ class Vector {
* Delete any element in the vector. The empty space will be filled by the previously last
* element. This takes O(1) time.
*/
- void remove_and_reorder(const uint index)
+ void remove_and_reorder(const int64_t index)
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->size());
T *element_to_remove = begin_ + index;
end_--;
@@ -653,8 +644,8 @@ class Vector {
*/
void remove_first_occurrence_and_reorder(const T &value)
{
- const uint index = this->first_index_of(value);
- this->remove_and_reorder((uint)index);
+ const int64_t index = this->first_index_of(value);
+ this->remove_and_reorder(index);
}
/**
@@ -664,11 +655,12 @@ class Vector {
*
* This is similar to std::vector::erase.
*/
- void remove(const uint index)
+ void remove(const int64_t index)
{
+ BLI_assert(index >= 0);
BLI_assert(index < this->size());
- const uint last_index = this->size() - 1;
- for (uint i = index; i < last_index; i++) {
+ const int64_t last_index = this->size() - 1;
+ for (int64_t i = index; i < last_index; i++) {
begin_[i] = std::move(begin_[i + 1]);
}
begin_[last_index].~T();
@@ -680,11 +672,11 @@ class Vector {
* Do a linear search to find the value in the vector.
* When found, return the first index, otherwise return -1.
*/
- int first_index_of_try(const T &value) const
+ int64_t first_index_of_try(const T &value) const
{
for (const T *current = begin_; current != end_; current++) {
if (*current == value) {
- return (int)(current - begin_);
+ return (int64_t)(current - begin_);
}
}
return -1;
@@ -694,11 +686,11 @@ class Vector {
* Do a linear search to find the value in the vector and return the found index. This invokes
* undefined behavior when the value is not in the vector.
*/
- uint first_index_of(const T &value) const
+ int64_t first_index_of(const T &value) const
{
- const int index = this->first_index_of_try(value);
+ const int64_t index = this->first_index_of_try(value);
BLI_assert(index >= 0);
- return (uint)index;
+ return index;
}
/**
@@ -748,9 +740,9 @@ class Vector {
* Get the current capacity of the vector, i.e. the maximum number of elements the vector can
* hold, before it has to reallocate.
*/
- uint capacity() const
+ int64_t capacity() const
{
- return (uint)(capacity_end_ - begin_);
+ return (int64_t)(capacity_end_ - begin_);
}
/**
@@ -758,7 +750,7 @@ class Vector {
* Obviously, this should only be used when you actually need the index in the loop.
*
* Example:
- * for (uint i : myvector.index_range()) {
+ * for (int64_t i : myvector.index_range()) {
* do_something(i, my_vector[i]);
* }
*/
@@ -796,7 +788,7 @@ class Vector {
}
}
- BLI_NOINLINE void realloc_to_at_least(const uint min_capacity)
+ BLI_NOINLINE void realloc_to_at_least(const int64_t min_capacity)
{
if (this->capacity() >= min_capacity) {
return;
@@ -804,12 +796,12 @@ class Vector {
/* At least double the size of the previous allocation. Otherwise consecutive calls to grow can
* cause a reallocation every time even though min_capacity only increments. */
- const uint min_new_capacity = this->capacity() * 2;
+ const int64_t min_new_capacity = this->capacity() * 2;
- const uint new_capacity = std::max(min_capacity, min_new_capacity);
- const uint size = this->size();
+ const int64_t new_capacity = std::max(min_capacity, min_new_capacity);
+ const int64_t size = this->size();
- T *new_array = (T *)allocator_.allocate(new_capacity * (uint)sizeof(T), alignof(T), AT);
+ T *new_array = (T *)allocator_.allocate((size_t)new_capacity * sizeof(T), alignof(T), AT);
uninitialized_relocate_n(begin_, size, new_array);
if (!this->is_inline()) {