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.hh104
1 files changed, 43 insertions, 61 deletions
diff --git a/source/blender/blenlib/BLI_vector.hh b/source/blender/blenlib/BLI_vector.hh
index a06be65685f..1fe38464ad0 100644
--- a/source/blender/blenlib/BLI_vector.hh
+++ b/source/blender/blenlib/BLI_vector.hh
@@ -92,7 +92,7 @@ class Vector {
Allocator allocator_;
/** A placeholder buffer that will remain uninitialized until it is used. */
- AlignedBuffer<(uint)sizeof(T) * InlineBufferCapacity, (uint)alignof(T)> inline_buffer_;
+ TypedBuffer<T, InlineBufferCapacity> inline_buffer_;
/**
* Store the size of the vector explicitly in debug builds. Otherwise you'd always have to call
@@ -118,9 +118,9 @@ class Vector {
* Create an empty vector.
* This does not do any memory allocation.
*/
- Vector()
+ Vector(Allocator allocator = {}) : allocator_(allocator)
{
- begin_ = this->inline_buffer();
+ begin_ = inline_buffer_;
end_ = begin_;
capacity_end_ = begin_ + InlineBufferCapacity;
UPDATE_VECTOR_SIZE(this);
@@ -141,9 +141,19 @@ class Vector {
*/
Vector(uint size, const T &value) : Vector()
{
+ this->resize(size, value);
+ }
+
+ /**
+ * Create a vector from an array ref. The values in the vector are copy constructed.
+ */
+ 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();
this->reserve(size);
this->increase_size_by_unchecked(size);
- blender::uninitialized_fill_n(begin_, size, value);
+ uninitialized_convert_n<U, T>(values.data(), size, begin_);
}
/**
@@ -152,24 +162,25 @@ class Vector {
* This allows you to write code like:
* Vector<int> vec = {3, 4, 5};
*/
+ template<typename U, typename std::enable_if_t<std::is_convertible_v<U, T>> * = nullptr>
+ Vector(const std::initializer_list<U> &values) : Vector(Span<U>(values))
+ {
+ }
+
Vector(const std::initializer_list<T> &values) : Vector(Span<T>(values))
{
}
- /**
- * Create a vector from an array ref. The values in the vector are copy constructed.
- */
- Vector(Span<T> values) : Vector()
+ template<typename U,
+ size_t N,
+ typename std::enable_if_t<std::is_convertible_v<U, T>> * = nullptr>
+ Vector(const std::array<U, N> &values) : Vector(Span(values))
{
- const uint size = values.size();
- this->reserve(size);
- this->increase_size_by_unchecked(size);
- blender::uninitialized_copy_n(values.data(), size, begin_);
}
/**
- * Create a vector from any container. It must be possible to use the container in a range-for
- * loop.
+ * Create a vector from any container. It must be possible to use the container in a
+ * range-for loop.
*/
template<typename ContainerT> static Vector FromContainer(const ContainerT &container)
{
@@ -198,9 +209,8 @@ class Vector {
* Create a copy of another vector. The other vector will not be changed. If the other vector has
* less than InlineBufferCapacity elements, no allocation will be made.
*/
- Vector(const Vector &other) : allocator_(other.allocator_)
+ Vector(const Vector &other) : Vector(other.as_span(), other.allocator_)
{
- this->init_copy_from_other_vector(other);
}
/**
@@ -209,9 +219,8 @@ class Vector {
*/
template<uint OtherInlineBufferCapacity>
Vector(const Vector<T, OtherInlineBufferCapacity, Allocator> &other)
- : allocator_(other.allocator_)
+ : Vector(other.as_span(), other.allocator_)
{
- this->init_copy_from_other_vector(other);
}
/**
@@ -227,7 +236,7 @@ class Vector {
if (other.is_inline()) {
if (size <= InlineBufferCapacity) {
/* Copy between inline buffers. */
- begin_ = this->inline_buffer();
+ begin_ = inline_buffer_;
end_ = begin_ + size;
capacity_end_ = begin_ + InlineBufferCapacity;
uninitialized_relocate_n(other.begin_, size, begin_);
@@ -248,7 +257,7 @@ class Vector {
capacity_end_ = other.capacity_end_;
}
- other.begin_ = other.inline_buffer();
+ other.begin_ = other.inline_buffer_;
other.end_ = other.begin_;
other.capacity_end_ = other.begin_ + OtherInlineBufferCapacity;
UPDATE_VECTOR_SIZE(this);
@@ -315,6 +324,18 @@ class Vector {
return MutableSpan<T>(begin_, this->size());
}
+ template<typename U, typename std::enable_if_t<is_convertible_pointer_v<T, U>> * = nullptr>
+ operator Span<U>() const
+ {
+ return Span<U>(begin_, this->size());
+ }
+
+ template<typename U, typename std::enable_if_t<is_convertible_pointer_v<T, U>> * = nullptr>
+ operator MutableSpan<U>()
+ {
+ return MutableSpan<U>(begin_, this->size());
+ }
+
Span<T> as_span() const
{
return *this;
@@ -399,7 +420,7 @@ class Vector {
allocator_.deallocate(begin_);
}
- begin_ = this->inline_buffer();
+ begin_ = inline_buffer_;
end_ = begin_;
capacity_end_ = begin_ + InlineBufferCapacity;
UPDATE_VECTOR_SIZE(this);
@@ -763,14 +784,9 @@ class Vector {
}
private:
- T *inline_buffer() const
- {
- return (T *)inline_buffer_.ptr();
- }
-
bool is_inline() const
{
- return begin_ == this->inline_buffer();
+ return begin_ == inline_buffer_;
}
void ensure_space_for_one()
@@ -804,44 +820,10 @@ class Vector {
end_ = begin_ + size;
capacity_end_ = begin_ + new_capacity;
}
-
- /**
- * Initialize all properties, except for allocator_, which has to be initialized beforehand.
- */
- template<uint OtherInlineBufferCapacity>
- void init_copy_from_other_vector(const Vector<T, OtherInlineBufferCapacity, Allocator> &other)
- {
- allocator_ = other.allocator_;
-
- const uint size = other.size();
- uint capacity;
-
- if (size <= InlineBufferCapacity) {
- begin_ = this->inline_buffer();
- capacity = InlineBufferCapacity;
- }
- else {
- begin_ = (T *)allocator_.allocate(sizeof(T) * size, alignof(T), AT);
- capacity = size;
- }
-
- end_ = begin_ + size;
- capacity_end_ = begin_ + capacity;
-
- uninitialized_copy_n(other.data(), size, begin_);
- UPDATE_VECTOR_SIZE(this);
- }
};
#undef UPDATE_VECTOR_SIZE
-/**
- * Use when the vector is used in the local scope of a function. It has a larger inline storage by
- * default to make allocations less likely.
- */
-template<typename T, uint InlineBufferCapacity = 20>
-using ScopedVector = Vector<T, InlineBufferCapacity, GuardedAllocator>;
-
} /* namespace blender */
#endif /* __BLI_VECTOR_HH__ */