50template<
typename T,
typename Allocator>
struct VectorData {
112# define UPDATE_VECTOR_SIZE(ptr) (ptr)->debug_size_ = int64_t((ptr)->end_ - (ptr)->begin_)
114# define UPDATE_VECTOR_SIZE(ptr) ((void)0)
121 template<
typename OtherT,
int64_t OtherInlineBufferCapacity,
typename OtherAllocator>
125 static constexpr bool is_nothrow_move_constructible()
127 if constexpr (InlineBufferCapacity == 0) {
131 return std::is_nothrow_move_constructible_v<T>;
140 Vector(Allocator allocator = {})
noexcept : allocator_(allocator)
142 begin_ = inline_buffer_;
144 capacity_end_ = begin_ + InlineBufferCapacity;
167 this->
resize(size, value);
173 template<
typename U, BLI_ENABLE_IF((std::is_convertible_v<U, T>))>
182 template<
typename U, BLI_ENABLE_IF((std::is_convertible_v<U, T>))>
194 template<
typename U, BLI_ENABLE_IF((std::is_convertible_v<U, T>))>
201 template<
typename U,
size_t N, BLI_ENABLE_IF((std::is_convertible_v<U, T>))>
206 template<
typename InputIt,
213 for (InputIt current =
first; current !=
last; ++current) {
228 template<
int64_t OtherInlineBufferCapacity>
238 template<
int64_t OtherInlineBufferCapacity>
240 is_nothrow_move_constructible())
243 if (other.is_inline()) {
244 const int64_t size = other.size();
247 constexpr bool other_is_same_type = std::is_same_v<Vector, std::decay_t<decltype(other)>>;
248 constexpr size_t max_full_copy_size = 32;
249 if constexpr (other_is_same_type && std::is_trivial_v<T> &&
250 sizeof(inline_buffer_) <= max_full_copy_size)
259 memcpy(inline_buffer_, other.inline_buffer_, sizeof(inline_buffer_));
260 this->increase_size_by_unchecked(size);
262 other.end_ = other.inline_buffer_;
268 if (OtherInlineBufferCapacity <= InlineBufferCapacity || size <= InlineBufferCapacity) {
270 uninitialized_relocate_n(other.begin_, size, begin_);
271 end_ = begin_ + size;
275 const int64_t capacity = size;
276 begin_ = static_cast<T *>(
277 allocator_.allocate(sizeof(T) * size_t(capacity), alignof(T), AT));
278 capacity_end_ = begin_ + capacity;
279 uninitialized_relocate_n(other.begin_, size, begin_);
280 end_ = begin_ + size;
283 other.end_ = other.inline_buffer_;
288 begin_ = other.begin_;
290 capacity_end_ = other.capacity_end_;
293 other.begin_ = other.inline_buffer_;
294 other.end_ = other.inline_buffer_;
295 other.capacity_end_ = other.inline_buffer_ + OtherInlineBufferCapacity;
314 if (
data.data !=
nullptr) {
318 capacity_end_ =
data.data +
data.capacity;
327 allocator_.deallocate(begin_);
349 return begin_[index];
356 return begin_[index];
369 template<
typename U, BLI_ENABLE_IF((is_span_convertible_po
inter_v<T, U>))>
375 template<
typename U, BLI_ENABLE_IF((is_span_convertible_po
inter_v<T, U>))>
398 if (min_capacity > this->
capacity()) {
399 this->realloc_to_at_least(min_capacity);
413 if (new_size > old_size) {
418 destruct_n(begin_ + new_size, old_size - new_size);
420 end_ = begin_ + new_size;
434 if (new_size > old_size) {
439 destruct_n(begin_ + new_size, old_size - new_size);
441 end_ = begin_ + new_size;
474 allocator_.deallocate(begin_);
477 begin_ = inline_buffer_;
479 capacity_end_ = begin_ + InlineBufferCapacity;
498 template<
typename... ForwardValue>
void append_as(ForwardValue &&...value)
500 this->ensure_space_for_one();
519 this->
append_as(std::forward<ForwardValue>(value)...);
551 new (end_)
T(std::forward<ForwardT>(value)...);
604 template<
int64_t OtherInlineBufferCapacity>
608 this->
extend(std::make_move_iterator(other.begin()), std::make_move_iterator(other.end()));
619 for (
const T &value :
array) {
658 insert_index, std::make_move_iterator(&value), std::make_move_iterator(&value + 1));
664 template<
typename InputIt>
void insert(
const T *insert_position, InputIt
first, InputIt
last)
666 const int64_t insert_index = insert_position - begin_;
676 const int64_t new_size = old_size + insert_amount;
677 const int64_t move_amount = old_size - insert_index;
681 const int64_t src_index = insert_index + move_amount -
i - 1;
682 const int64_t dst_index = new_size -
i - 1;
684 new (
static_cast<void *
>(begin_ + dst_index))
T(std::move(begin_[src_index]));
689 end_ = begin_ + src_index + 1;
693 begin_[src_index].~T();
697 if constexpr (std::is_rvalue_reference_v<
decltype(*first)>) {
698 std::uninitialized_move_n(
first, insert_amount, begin_ + insert_index);
701 std::uninitialized_copy_n(
first, insert_amount, begin_ + insert_index);
706 destruct_n(begin_ + new_size - move_amount, move_amount);
707 end_ = begin_ + insert_index;
711 end_ = begin_ + new_size;
725 this->
insert(0, std::move(value));
744 return *(end_ - 1 - n);
750 return *(end_ - 1 - n);
785 return begin_ == end_;
809 T value = std::move(*(end_ - 1));
824 T *element_to_remove = begin_ + index;
825 T *last_element = end_ - 1;
826 if (element_to_remove < last_element) {
827 *element_to_remove = std::move(*last_element);
856 for (
int64_t i = index;
i < last_index;
i++) {
857 begin_[
i] = std::move(begin_[
i + 1]);
859 begin_[last_index].~T();
876 const int64_t move_amount = old_size - start_index - amount;
878 begin_[start_index +
i] = std::move(begin_[start_index + amount +
i]);
893 const T *prev_end = this->
end();
894 end_ = std::remove_if(this->
begin(), this->
end(), predicate);
897 return int64_t(prev_end - end_);
906 for (
const T *current = begin_; current != end_; current++) {
907 if (*current == value) {
908 return int64_t(current - begin_);
978 return std::reverse_iterator<T *>(this->
end());
980 std::reverse_iterator<T *>
rend()
982 return std::reverse_iterator<T *>(this->
begin());
985 std::reverse_iterator<const T *>
rbegin()
const
987 return std::reverse_iterator<const T *>(this->
end());
989 std::reverse_iterator<const T *>
rend()
const
991 return std::reverse_iterator<const T *>(this->
begin());
1000 return int64_t(capacity_end_ - begin_);
1005 return end_ == capacity_end_;
1024 return this->
as_span().hash();
1029 return values.
hash();
1061 T *
data =
static_cast<T *
>(
1062 allocator_.allocate(
size_t(
size) *
sizeof(
T),
alignof(
T), __func__));
1067 allocator_.deallocate(
data);
1071 end_ = begin_ +
size;
1072 capacity_end_ = end_;
1077 data.size = end_ - begin_;
1078 data.capacity = capacity_end_ - begin_;
1079 data.allocator = allocator_;
1082 begin_ = inline_buffer_;
1084 capacity_end_ = begin_ + InlineBufferCapacity;
1096 name,
this, this->
size(), capacity_end_ - begin_, InlineBufferCapacity,
sizeof(*
this));
1101 return begin_ == inline_buffer_;
1105 void ensure_space_for_one()
1107 if (
UNLIKELY(end_ >= capacity_end_)) {
1108 this->realloc_to_at_least(this->
size() + 1);
1114 if (this->
capacity() >= min_capacity) {
1122 const int64_t new_capacity = std::max(min_capacity, min_new_capacity);
1125 T *new_array =
static_cast<T *
>(
1126 allocator_.allocate(
size_t(new_capacity) *
sizeof(
T),
alignof(
T),
AT));
1131 allocator_.deallocate(new_array);
1136 allocator_.deallocate(begin_);
1140 end_ = begin_ +
size;
1141 capacity_end_ = begin_ + new_capacity;
1145#undef UPDATE_VECTOR_SIZE
1151template<
typename T,
int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T))>
1155template<
typename T,
int64_t InlineBufferCapacity,
typename Allocator>
void BLI_kdtree_nd_ insert(KDTree *tree, int index, const float co[KD_DIMS]) ATTR_NONNULL(1
#define BLI_ENABLE_IF(condition)
#define BLI_NO_UNIQUE_ADDRESS
#define UPDATE_VECTOR_SIZE(ptr)
unsigned long long int uint64_t
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
void remove_and_reorder(const int64_t index)
bool contains(const T &value) const
void append(const T &value)
void append_unchecked_as(ForwardT &&...value)
int64_t append_and_get_index_as(ForwardValue &&...value)
void resize(const int64_t new_size)
int64_t first_index_of(const T &value) const
void extend_unchecked(Span< T > array)
void reserve(const int64_t min_capacity)
void extend(Span< T > array)
void append_non_duplicates(const T &value)
Span< T > as_span() const
void append_as(ForwardValue &&...value)
void increase_size_by_unchecked(const int64_t n) noexcept
int64_t first_index_of_try(const T &value) const
constexpr const T * data() const
constexpr int64_t size() const
constexpr uint64_t hash() 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 SubdivCCGCoord & 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)
GuardedAllocator allocator_type
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)
Vector(const VectorData< T, Allocator > &data)
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)
void extend(Vector< T, OtherInlineBufferCapacity, Allocator > &&other)
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 SubdivCCGCoord & const_reference
SubdivCCGCoord * iterator
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={})
const SubdivCCGCoord * const_pointer
const SubdivCCGCoord & first() const
T & last(const int64_t n=0)
SubdivCCGCoord & reference
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)
VectorData< T, Allocator > release()
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={})
SubdivCCGCoord value_type
int64_t first_index_of_try(const T &value) const
void append_n_times(const T &value, const int64_t n)
const SubdivCCGCoord * const_iterator
Vector(const std::initializer_list< T > &values)
static void clear(Message &msg)
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 >)
Vector< T, InlineBufferCapacity, RawAllocator > RawVector
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)
static constexpr bool is_Vector_v
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)
BLI_NO_UNIQUE_ADDRESS Allocator allocator