101# define UPDATE_VECTOR_SIZE(ptr) (ptr)->debug_size_ = int64_t((ptr)->end_ - (ptr)->begin_)
103# define UPDATE_VECTOR_SIZE(ptr) ((void)0)
110 template<
typename OtherT,
int64_t OtherInlineBufferCapacity,
typename OtherAllocator>
114 static constexpr bool is_nothrow_move_constructible()
116 if constexpr (InlineBufferCapacity == 0) {
120 return std::is_nothrow_move_constructible_v<T>;
129 Vector(Allocator allocator = {})
noexcept : allocator_(allocator)
131 begin_ = inline_buffer_;
133 capacity_end_ = begin_ + InlineBufferCapacity;
156 this->
resize(size, value);
162 template<
typename U, BLI_ENABLE_IF((std::is_convertible_v<U, T>))>
171 template<
typename U, BLI_ENABLE_IF((std::is_convertible_v<U, T>))>
183 template<
typename U, BLI_ENABLE_IF((std::is_convertible_v<U, T>))>
190 template<
typename U,
size_t N, BLI_ENABLE_IF((std::is_convertible_v<U, T>))>
195 template<
typename InputIt,
202 for (InputIt current =
first; current !=
last; ++current) {
217 template<
int64_t OtherInlineBufferCapacity>
227 template<
int64_t OtherInlineBufferCapacity>
229 is_nothrow_move_constructible())
234 if (other.is_inline()) {
235 if (size <= InlineBufferCapacity) {
238 end_ = begin_ +
size;
243 begin_ =
static_cast<T *
>(
244 allocator_.allocate(
sizeof(T) *
size_t(
capacity),
alignof(T), AT));
247 end_ = begin_ +
size;
252 begin_ = other.begin_;
254 capacity_end_ = other.capacity_end_;
257 other.begin_ = other.inline_buffer_;
258 other.end_ = other.begin_;
259 other.capacity_end_ = other.begin_ + OtherInlineBufferCapacity;
267 if (!this->is_inline()) {
268 allocator_.deallocate(begin_);
290 return begin_[index];
297 return begin_[index];
310 template<
typename U, BLI_ENABLE_IF((is_span_convertible_po
inter_v<T, U>))>
316 template<
typename U, BLI_ENABLE_IF((is_span_convertible_po
inter_v<T, U>))>
339 if (min_capacity > this->
capacity()) {
340 this->realloc_to_at_least(min_capacity);
354 if (new_size > old_size) {
359 destruct_n(begin_ + new_size, old_size - new_size);
361 end_ = begin_ + new_size;
375 if (new_size > old_size) {
380 destruct_n(begin_ + new_size, old_size - new_size);
382 end_ = begin_ + new_size;
414 if (!this->is_inline()) {
415 allocator_.deallocate(begin_);
418 begin_ = inline_buffer_;
420 capacity_end_ = begin_ + InlineBufferCapacity;
439 template<
typename... ForwardValue>
void append_as(ForwardValue &&...value)
441 this->ensure_space_for_one();
460 this->
append_as(std::forward<ForwardValue>(value)...);
492 new (end_)
T(std::forward<ForwardT>(value)...);
544 for (
const T &value :
array) {
583 insert_index, std::make_move_iterator(&value), std::make_move_iterator(&value + 1));
589 template<
typename InputIt>
void insert(
const T *insert_position, InputIt
first, InputIt
last)
591 const int64_t insert_index = insert_position - begin_;
601 const int64_t new_size = old_size + insert_amount;
602 const int64_t move_amount = old_size - insert_index;
605 for (
int64_t i = 0; i < move_amount; i++) {
606 const int64_t src_index = insert_index + move_amount - i - 1;
607 const int64_t dst_index = new_size - i - 1;
609 new (
static_cast<void *
>(begin_ + dst_index))
T(std::move(begin_[src_index]));
614 end_ = begin_ + src_index + 1;
618 begin_[src_index].~T();
622 std::uninitialized_copy_n(
first, insert_amount, begin_ + insert_index);
626 destruct_n(begin_ + new_size - move_amount, move_amount);
627 end_ = begin_ + insert_index;
631 end_ = begin_ + new_size;
645 this->
insert(0, std::move(value));
664 return *(end_ - 1 - n);
670 return *(end_ - 1 - n);
705 return begin_ == end_;
729 T value = std::move(*(end_ - 1));
744 T *element_to_remove = begin_ + index;
745 T *last_element = end_ - 1;
746 if (element_to_remove < last_element) {
747 *element_to_remove = std::move(*last_element);
776 for (
int64_t i = index; i < last_index; i++) {
777 begin_[i] = std::move(begin_[i + 1]);
779 begin_[last_index].~T();
796 const int64_t move_amount = old_size - start_index - amount;
797 for (
int64_t i = 0; i < move_amount; i++) {
798 begin_[start_index + i] = std::move(begin_[start_index + amount + i]);
813 const T *prev_end = this->
end();
814 end_ = std::remove_if(this->
begin(), this->
end(), predicate);
817 return int64_t(prev_end - end_);
826 for (
const T *current = begin_; current != end_; current++) {
827 if (*current == value) {
828 return int64_t(current - begin_);
857 void fill(
const T &value)
const
898 return std::reverse_iterator<T *>(this->
end());
900 std::reverse_iterator<T *>
rend()
902 return std::reverse_iterator<T *>(this->
begin());
905 std::reverse_iterator<const T *>
rbegin()
const
907 return std::reverse_iterator<const T *>(this->
end());
909 std::reverse_iterator<const T *>
rend()
const
911 return std::reverse_iterator<const T *>(this->
begin());
920 return int64_t(capacity_end_ - begin_);
925 return end_ == capacity_end_;
949 return values.hash();
954 return a.as_span() ==
b.as_span();
968 name,
this, this->
size(), capacity_end_ - begin_, InlineBufferCapacity,
sizeof(*
this));
972 bool is_inline()
const
974 return begin_ == inline_buffer_;
977 void ensure_space_for_one()
979 if (
UNLIKELY(end_ >= capacity_end_)) {
980 this->realloc_to_at_least(this->
size() + 1);
986 if (this->
capacity() >= min_capacity) {
994 const int64_t new_capacity = std::max(min_capacity, min_new_capacity);
997 T *new_array =
static_cast<T *
>(
998 allocator_.allocate(
size_t(new_capacity) *
sizeof(T),
alignof(T), AT));
1003 allocator_.deallocate(new_array);
1007 if (!this->is_inline()) {
1008 allocator_.deallocate(begin_);
1012 end_ = begin_ +
size;
1013 capacity_end_ = begin_ + new_capacity;
1017#undef UPDATE_VECTOR_SIZE
1023template<
typename T,
int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T))>
#define BLI_ENABLE_IF(condition)
#define BLI_NO_UNIQUE_ADDRESS
#define UPDATE_VECTOR_SIZE(ptr)
constexpr const T * data() const
void insert(const int64_t insert_index, T &&value)
std::reverse_iterator< const T * > rbegin() const
std::reverse_iterator< T * > rbegin()
void remove_and_reorder(const int64_t index)
Vector(const Vector< T, OtherInlineBufferCapacity, Allocator > &other)
void print_stats(const char *name) const
int64_t remove_if(Predicate &&predicate)
Vector(const Vector &other)
Vector(Allocator allocator={}) noexcept
int64_t append_and_get_index(const T &value)
void prepend(const T &value)
bool contains(const T &value) const
Vector & operator=(Vector &&other)
bool is_at_capacity() const
void append(const T &value)
void insert(const int64_t insert_index, const T &value)
friend bool operator==(const Vector &a, const Vector &b)
const T & last(const int64_t n=0) const
Vector(InputIt first, InputIt last, Allocator allocator={})
void append_unchecked_as(ForwardT &&...value)
void remove(const int64_t index)
void resize(const int64_t new_size, const T &value)
void remove_first_occurrence_and_reorder(const T &value)
IndexRange index_range() const
int64_t append_and_get_index_as(ForwardValue &&...value)
void prepend(InputIt first, InputIt last)
void resize(const int64_t new_size)
int64_t first_index_of(const T &value) const
MutableSpan< T > as_mutable_span()
void extend_unchecked(Span< T > array)
T & operator[](int64_t index)
void append_unchecked(const T &value)
void prepend(Span< T > values)
static uint64_t hash_as(const Span< T > values)
Vector(NoExceptConstructor, Allocator allocator={}) noexcept
const T & operator[](int64_t index) const
Vector(Span< U > values, Allocator allocator={})
void reserve(const int64_t min_capacity)
const T & const_reference
std::reverse_iterator< T * > rend()
void remove(const int64_t start_index, const int64_t amount)
void extend(Span< T > array)
std::reverse_iterator< const T * > rend() const
void insert(const T *insert_position, InputIt first, InputIt last)
void append_unchecked(T &&value)
void extend_non_duplicates(Span< T > array)
Vector & operator=(const Vector &other)
void reinitialize(const int64_t new_size)
Vector(int64_t size, const T &value, Allocator allocator={})
void append_non_duplicates(const T &value)
void fill(const T &value) const
void insert(const int64_t insert_index, InputIt first, InputIt last)
Vector(const std::array< U, N > &values)
Span< T > as_span() const
Vector(int64_t size, Allocator allocator={})
T & last(const int64_t n=0)
void insert(const int64_t insert_index, Span< T > array)
Vector(Vector< T, OtherInlineBufferCapacity, Allocator > &&other) noexcept(is_nothrow_move_constructible())
void append_as(ForwardValue &&...value)
int64_t append_and_get_index(T &&value)
void extend(InputIt first, InputIt last)
void extend(const T *start, int64_t amount)
Vector(const std::initializer_list< U > &values)
friend bool operator!=(const Vector &a, const Vector &b)
void extend_unchecked(const T *start, int64_t amount)
void increase_size_by_unchecked(const int64_t n) noexcept
Vector(MutableSpan< U > values, Allocator allocator={})
int64_t first_index_of_try(const T &value) const
void append_n_times(const T &value, const int64_t n)
Vector(const std::initializer_list< T > &values)
local_group_size(16, 16) .push_constant(Type b
void vector_print_stats(const char *name, const void *address, int64_t size, int64_t capacity, int64_t inlineCapacity, int64_t memorySize)
void default_construct_n(T *ptr, int64_t n)
void initialized_fill_n(T *dst, int64_t n, const T &value)
Container & copy_assign_container(Container &dst, const Container &src)
Container & move_assign_container(Container &dst, Container &&src) noexcept(std::is_nothrow_move_constructible_v< Container >)
constexpr int64_t default_inline_buffer_capacity(size_t element_size)
void uninitialized_fill_n(T *dst, int64_t n, const T &value)
void uninitialized_relocate_n(T *src, int64_t n, T *dst)
void uninitialized_convert_n(const From *src, int64_t n, To *dst)
void destruct_n(T *ptr, int64_t n)
void uninitialized_copy_n(const T *src, int64_t n, T *dst)
unsigned __int64 uint64_t