diff options
Diffstat (limited to 'source/blender/blenlib/BLI_vector.hh')
-rw-r--r-- | source/blender/blenlib/BLI_vector.hh | 104 |
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__ */ |