Blender  V3.3
BLI_vector.hh
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #pragma once
4 
25 #include <algorithm>
26 #include <cstdlib>
27 #include <cstring>
28 #include <iostream>
29 #include <memory>
30 
31 #include "BLI_allocator.hh"
32 #include "BLI_index_range.hh"
33 #include "BLI_listbase_wrapper.hh"
34 #include "BLI_math_base.h"
35 #include "BLI_memory_utils.hh"
36 #include "BLI_span.hh"
37 #include "BLI_string.h"
38 #include "BLI_string_ref.hh"
39 #include "BLI_utildefines.h"
40 
41 #include "MEM_guardedalloc.h"
42 
43 namespace blender {
44 
45 template<
49  typename T,
58  int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T)),
63  typename Allocator = GuardedAllocator>
64 class Vector {
65  public:
66  using value_type = T;
67  using pointer = T *;
68  using const_pointer = const T *;
69  using reference = T &;
70  using const_reference = const T &;
71  using iterator = T *;
72  using const_iterator = const T *;
73  using size_type = int64_t;
74 
75  private:
82  T *begin_;
83  T *end_;
84  T *capacity_end_;
85 
87  BLI_NO_UNIQUE_ADDRESS Allocator allocator_;
88 
91 
97 #ifndef NDEBUG
98  int64_t debug_size_;
99 # define UPDATE_VECTOR_SIZE(ptr) \
100  (ptr)->debug_size_ = static_cast<int64_t>((ptr)->end_ - (ptr)->begin_)
101 #else
102 # define UPDATE_VECTOR_SIZE(ptr) ((void)0)
103 #endif
104 
109  template<typename OtherT, int64_t OtherInlineBufferCapacity, typename OtherAllocator>
110  friend class Vector;
111 
112  public:
117  Vector(Allocator allocator = {}) noexcept : allocator_(allocator)
118  {
119  begin_ = inline_buffer_;
120  end_ = begin_;
121  capacity_end_ = begin_ + InlineBufferCapacity;
122  UPDATE_VECTOR_SIZE(this);
123  }
124 
125  Vector(NoExceptConstructor, Allocator allocator = {}) noexcept : Vector(allocator)
126  {
127  }
128 
134  explicit Vector(int64_t size, Allocator allocator = {})
135  : Vector(NoExceptConstructor(), allocator)
136  {
137  this->resize(size);
138  }
139 
143  Vector(int64_t size, const T &value, Allocator allocator = {})
144  : Vector(NoExceptConstructor(), allocator)
145  {
146  this->resize(size, value);
147  }
148 
152  template<typename U, BLI_ENABLE_IF((std::is_convertible_v<U, T>))>
153  Vector(Span<U> values, Allocator allocator = {}) : Vector(NoExceptConstructor(), allocator)
154  {
155  const int64_t size = values.size();
156  this->reserve(size);
157  uninitialized_convert_n<U, T>(values.data(), size, begin_);
158  this->increase_size_by_unchecked(size);
159  }
160 
167  template<typename U, BLI_ENABLE_IF((std::is_convertible_v<U, T>))>
168  Vector(const std::initializer_list<U> &values) : Vector(Span<U>(values))
169  {
170  }
171 
172  Vector(const std::initializer_list<T> &values) : Vector(Span<T>(values))
173  {
174  }
175 
176  template<typename U, size_t N, BLI_ENABLE_IF((std::is_convertible_v<U, T>))>
177  Vector(const std::array<U, N> &values) : Vector(Span(values))
178  {
179  }
180 
181  template<typename InputIt,
182  /* This constructor should not be called with e.g. Vector(3, 10), because that is
183  * expected to produce the vector (10, 10, 10). */
184  BLI_ENABLE_IF((!std::is_convertible_v<InputIt, int>))>
185  Vector(InputIt first, InputIt last, Allocator allocator = {})
186  : Vector(NoExceptConstructor(), allocator)
187  {
188  for (InputIt current = first; current != last; ++current) {
189  this->append(*current);
190  }
191  }
192 
200  Vector(const ListBase &values, Allocator allocator = {})
201  : Vector(NoExceptConstructor(), allocator)
202  {
203  LISTBASE_FOREACH (T, value, &values) {
204  this->append(value);
205  }
206  }
207 
212  Vector(const Vector &other) : Vector(other.as_span(), other.allocator_)
213  {
214  }
215 
220  template<int64_t OtherInlineBufferCapacity>
222  : Vector(other.as_span(), other.allocator_)
223  {
224  }
225 
230  template<int64_t OtherInlineBufferCapacity>
232  std::is_nothrow_move_constructible_v<T>)
233  : Vector(NoExceptConstructor(), other.allocator_)
234  {
235  const int64_t size = other.size();
236 
237  if (other.is_inline()) {
238  if (size <= InlineBufferCapacity) {
239  /* Copy between inline buffers. */
240  uninitialized_relocate_n(other.begin_, size, begin_);
241  end_ = begin_ + size;
242  }
243  else {
244  /* Copy from inline buffer to newly allocated buffer. */
245  const int64_t capacity = size;
246  begin_ = static_cast<T *>(
247  allocator_.allocate(sizeof(T) * static_cast<size_t>(capacity), alignof(T), AT));
248  capacity_end_ = begin_ + capacity;
249  uninitialized_relocate_n(other.begin_, size, begin_);
250  end_ = begin_ + size;
251  }
252  }
253  else {
254  /* Steal the pointer. */
255  begin_ = other.begin_;
256  end_ = other.end_;
257  capacity_end_ = other.capacity_end_;
258  }
259 
260  other.begin_ = other.inline_buffer_;
261  other.end_ = other.begin_;
262  other.capacity_end_ = other.begin_ + OtherInlineBufferCapacity;
263  UPDATE_VECTOR_SIZE(this);
264  UPDATE_VECTOR_SIZE(&other);
265  }
266 
268  {
269  destruct_n(begin_, this->size());
270  if (!this->is_inline()) {
271  allocator_.deallocate(begin_);
272  }
273  }
274 
275  Vector &operator=(const Vector &other)
276  {
277  return copy_assign_container(*this, other);
278  }
279 
281  {
282  return move_assign_container(*this, std::move(other));
283  }
284 
289  const T &operator[](int64_t index) const
290  {
291  BLI_assert(index >= 0);
292  BLI_assert(index < this->size());
293  return begin_[index];
294  }
295 
297  {
298  BLI_assert(index >= 0);
299  BLI_assert(index < this->size());
300  return begin_[index];
301  }
302 
303  operator Span<T>() const
304  {
305  return Span<T>(begin_, this->size());
306  }
307 
308  operator MutableSpan<T>()
309  {
310  return MutableSpan<T>(begin_, this->size());
311  }
312 
313  template<typename U, BLI_ENABLE_IF((is_span_convertible_pointer_v<T, U>))>
314  operator Span<U>() const
315  {
316  return Span<U>(begin_, this->size());
317  }
318 
319  template<typename U, BLI_ENABLE_IF((is_span_convertible_pointer_v<T, U>))>
320  operator MutableSpan<U>()
321  {
322  return MutableSpan<U>(begin_, this->size());
323  }
324 
325  Span<T> as_span() const
326  {
327  return *this;
328  }
329 
331  {
332  return *this;
333  }
334 
340  void reserve(const int64_t min_capacity)
341  {
342  if (min_capacity > this->capacity()) {
343  this->realloc_to_at_least(min_capacity);
344  }
345  }
346 
353  void resize(const int64_t new_size)
354  {
355  BLI_assert(new_size >= 0);
356  const int64_t old_size = this->size();
357  if (new_size > old_size) {
358  this->reserve(new_size);
359  default_construct_n(begin_ + old_size, new_size - old_size);
360  }
361  else {
362  destruct_n(begin_ + new_size, old_size - new_size);
363  }
364  end_ = begin_ + new_size;
365  UPDATE_VECTOR_SIZE(this);
366  }
367 
374  void resize(const int64_t new_size, const T &value)
375  {
376  BLI_assert(new_size >= 0);
377  const int64_t old_size = this->size();
378  if (new_size > old_size) {
379  this->reserve(new_size);
380  uninitialized_fill_n(begin_ + old_size, new_size - old_size, value);
381  }
382  else {
383  destruct_n(begin_ + new_size, old_size - new_size);
384  }
385  end_ = begin_ + new_size;
386  UPDATE_VECTOR_SIZE(this);
387  }
388 
393  void reinitialize(const int64_t new_size)
394  {
395  this->clear();
396  this->resize(new_size);
397  }
398 
403  void clear()
404  {
405  destruct_n(begin_, this->size());
406  end_ = begin_;
407  UPDATE_VECTOR_SIZE(this);
408  }
409 
415  {
416  destruct_n(begin_, this->size());
417  if (!this->is_inline()) {
418  allocator_.deallocate(begin_);
419  }
420 
421  begin_ = inline_buffer_;
422  end_ = begin_;
423  capacity_end_ = begin_ + InlineBufferCapacity;
424  UPDATE_VECTOR_SIZE(this);
425  }
426 
433  void append(const T &value)
434  {
435  this->append_as(value);
436  }
437  void append(T &&value)
438  {
439  this->append_as(std::move(value));
440  }
441  /* This is similar to `std::vector::emplace_back`. */
442  template<typename... ForwardValue> void append_as(ForwardValue &&...value)
443  {
444  this->ensure_space_for_one();
445  this->append_unchecked_as(std::forward<ForwardValue>(value)...);
446  }
447 
453  {
454  return this->append_and_get_index_as(value);
455  }
457  {
458  return this->append_and_get_index_as(std::move(value));
459  }
460  template<typename... ForwardValue> int64_t append_and_get_index_as(ForwardValue &&...value)
461  {
462  const int64_t index = this->size();
463  this->append_as(std::forward<ForwardValue>(value)...);
464  return index;
465  }
466 
472  void append_non_duplicates(const T &value)
473  {
474  if (!this->contains(value)) {
475  this->append(value);
476  }
477  }
478 
484  void append_unchecked(const T &value)
485  {
486  this->append_unchecked_as(value);
487  }
488  void append_unchecked(T &&value)
489  {
490  this->append_unchecked_as(std::move(value));
491  }
492  template<typename... ForwardT> void append_unchecked_as(ForwardT &&...value)
493  {
494  BLI_assert(end_ < capacity_end_);
495  new (end_) T(std::forward<ForwardT>(value)...);
496  end_++;
497  UPDATE_VECTOR_SIZE(this);
498  }
499 
504  void append_n_times(const T &value, const int64_t n)
505  {
506  BLI_assert(n >= 0);
507  this->reserve(this->size() + n);
508  uninitialized_fill_n(end_, n, value);
510  }
511 
518  void increase_size_by_unchecked(const int64_t n) noexcept
519  {
520  BLI_assert(end_ + n <= capacity_end_);
521  end_ += n;
522  UPDATE_VECTOR_SIZE(this);
523  }
524 
531  {
532  this->extend(array.data(), array.size());
533  }
534  void extend(const T *start, int64_t amount)
535  {
536  this->reserve(this->size() + amount);
537  this->extend_unchecked(start, amount);
538  }
539 
546  {
547  for (const T &value : array) {
548  this->append_non_duplicates(value);
549  }
550  }
551 
557  {
558  this->extend_unchecked(array.data(), array.size());
559  }
560  void extend_unchecked(const T *start, int64_t amount)
561  {
562  BLI_assert(amount >= 0);
563  BLI_assert(begin_ + amount <= capacity_end_);
564  uninitialized_copy_n(start, amount, end_);
565  end_ += amount;
566  UPDATE_VECTOR_SIZE(this);
567  }
568 
569  template<typename InputIt> void extend(InputIt first, InputIt last)
570  {
571  this->insert(this->end(), first, last);
572  }
573 
579  void insert(const int64_t insert_index, const T &value)
580  {
581  this->insert(insert_index, Span<T>(&value, 1));
582  }
583  void insert(const int64_t insert_index, T &&value)
584  {
585  this->insert(
586  insert_index, std::make_move_iterator(&value), std::make_move_iterator(&value + 1));
587  }
588  void insert(const int64_t insert_index, Span<T> array)
589  {
590  this->insert(begin_ + insert_index, array.begin(), array.end());
591  }
592  template<typename InputIt> void insert(const T *insert_position, InputIt first, InputIt last)
593  {
594  const int64_t insert_index = insert_position - begin_;
595  this->insert(insert_index, first, last);
596  }
597  template<typename InputIt> void insert(const int64_t insert_index, InputIt first, InputIt last)
598  {
599  BLI_assert(insert_index >= 0);
600  BLI_assert(insert_index <= this->size());
601 
602  const int64_t insert_amount = std::distance(first, last);
603  const int64_t old_size = this->size();
604  const int64_t new_size = old_size + insert_amount;
605  const int64_t move_amount = old_size - insert_index;
606 
607  this->reserve(new_size);
608  for (int64_t i = 0; i < move_amount; i++) {
609  const int64_t src_index = insert_index + move_amount - i - 1;
610  const int64_t dst_index = new_size - i - 1;
611  try {
612  new (static_cast<void *>(begin_ + dst_index)) T(std::move(begin_[src_index]));
613  }
614  catch (...) {
615  /* Destruct all values that have been moved already. */
616  destruct_n(begin_ + dst_index + 1, i);
617  end_ = begin_ + src_index + 1;
618  UPDATE_VECTOR_SIZE(this);
619  throw;
620  }
621  begin_[src_index].~T();
622  }
623 
624  try {
625  std::uninitialized_copy_n(first, insert_amount, begin_ + insert_index);
626  }
627  catch (...) {
628  /* Destruct all values that have been moved. */
629  destruct_n(begin_ + new_size - move_amount, move_amount);
630  end_ = begin_ + insert_index;
631  UPDATE_VECTOR_SIZE(this);
632  throw;
633  }
634  end_ = begin_ + new_size;
635  UPDATE_VECTOR_SIZE(this);
636  }
637 
642  void prepend(const T &value)
643  {
644  this->insert(0, value);
645  }
646  void prepend(T &&value)
647  {
648  this->insert(0, std::move(value));
649  }
650  void prepend(Span<T> values)
651  {
652  this->insert(0, values);
653  }
654  template<typename InputIt> void prepend(InputIt first, InputIt last)
655  {
656  this->insert(0, first, last);
657  }
658 
663  const T &last(const int64_t n = 0) const
664  {
665  BLI_assert(n >= 0);
666  BLI_assert(n < this->size());
667  return *(end_ - 1 - n);
668  }
669  T &last(const int64_t n = 0)
670  {
671  BLI_assert(n >= 0);
672  BLI_assert(n < this->size());
673  return *(end_ - 1 - n);
674  }
675 
680  const T &first() const
681  {
682  BLI_assert(this->size() > 0);
683  return *begin_;
684  }
685  T &first()
686  {
687  BLI_assert(this->size() > 0);
688  return *begin_;
689  }
690 
694  int64_t size() const
695  {
696  const int64_t current_size = static_cast<int64_t>(end_ - begin_);
697  BLI_assert(debug_size_ == current_size);
698  return current_size;
699  }
700 
706  bool is_empty() const
707  {
708  return begin_ == end_;
709  }
710 
715  void remove_last()
716  {
717  BLI_assert(!this->is_empty());
718  end_--;
719  end_->~T();
720  UPDATE_VECTOR_SIZE(this);
721  }
722 
730  {
731  BLI_assert(!this->is_empty());
732  T value = std::move(*(end_ - 1));
733  end_--;
734  end_->~T();
735  UPDATE_VECTOR_SIZE(this);
736  return value;
737  }
738 
743  void remove_and_reorder(const int64_t index)
744  {
745  BLI_assert(index >= 0);
746  BLI_assert(index < this->size());
747  T *element_to_remove = begin_ + index;
748  T *last_element = end_ - 1;
749  if (element_to_remove < last_element) {
750  *element_to_remove = std::move(*last_element);
751  }
752  end_ = last_element;
753  last_element->~T();
754  UPDATE_VECTOR_SIZE(this);
755  }
756 
762  {
763  const int64_t index = this->first_index_of(value);
764  this->remove_and_reorder(index);
765  }
766 
774  void remove(const int64_t index)
775  {
776  BLI_assert(index >= 0);
777  BLI_assert(index < this->size());
778  const int64_t last_index = this->size() - 1;
779  for (int64_t i = index; i < last_index; i++) {
780  begin_[i] = std::move(begin_[i + 1]);
781  }
782  begin_[last_index].~T();
783  end_--;
784  UPDATE_VECTOR_SIZE(this);
785  }
786 
793  void remove(const int64_t start_index, const int64_t amount)
794  {
795  const int64_t old_size = this->size();
796  BLI_assert(start_index >= 0);
797  BLI_assert(amount >= 0);
798  BLI_assert(start_index + amount <= old_size);
799  const int64_t move_amount = old_size - start_index - amount;
800  for (int64_t i = 0; i < move_amount; i++) {
801  begin_[start_index + i] = std::move(begin_[start_index + amount + i]);
802  }
803  destruct_n(end_ - amount, amount);
804  end_ -= amount;
805  UPDATE_VECTOR_SIZE(this);
806  }
807 
812  int64_t first_index_of_try(const T &value) const
813  {
814  for (const T *current = begin_; current != end_; current++) {
815  if (*current == value) {
816  return static_cast<int64_t>(current - begin_);
817  }
818  }
819  return -1;
820  }
821 
826  int64_t first_index_of(const T &value) const
827  {
828  const int64_t index = this->first_index_of_try(value);
829  BLI_assert(index >= 0);
830  return index;
831  }
832 
837  bool contains(const T &value) const
838  {
839  return this->first_index_of_try(value) != -1;
840  }
841 
845  void fill(const T &value) const
846  {
847  initialized_fill_n(begin_, this->size(), value);
848  }
849 
853  T *data()
854  {
855  return begin_;
856  }
857 
861  const T *data() const
862  {
863  return begin_;
864  }
865 
866  T *begin()
867  {
868  return begin_;
869  }
870  T *end()
871  {
872  return end_;
873  }
874 
875  const T *begin() const
876  {
877  return begin_;
878  }
879  const T *end() const
880  {
881  return end_;
882  }
883 
884  std::reverse_iterator<T *> rbegin()
885  {
886  return std::reverse_iterator<T *>(this->end());
887  }
888  std::reverse_iterator<T *> rend()
889  {
890  return std::reverse_iterator<T *>(this->begin());
891  }
892 
893  std::reverse_iterator<const T *> rbegin() const
894  {
895  return std::reverse_iterator<T *>(this->end());
896  }
897  std::reverse_iterator<const T *> rend() const
898  {
899  return std::reverse_iterator<T *>(this->begin());
900  }
901 
907  {
908  return static_cast<int64_t>(capacity_end_ - begin_);
909  }
910 
921  {
922  return IndexRange(this->size());
923  }
924 
925  friend bool operator==(const Vector &a, const Vector &b)
926  {
927  return a.as_span() == b.as_span();
928  }
929 
930  friend bool operator!=(const Vector &a, const Vector &b)
931  {
932  return !(a == b);
933  }
934 
938  void print_stats(StringRef name = "") const
939  {
940  std::cout << "Vector Stats: " << name << "\n";
941  std::cout << " Address: " << this << "\n";
942  std::cout << " Elements: " << this->size() << "\n";
943  std::cout << " Capacity: " << (capacity_end_ - begin_) << "\n";
944  std::cout << " Inline Capacity: " << InlineBufferCapacity << "\n";
945 
946  char memory_size_str[15];
947  BLI_str_format_byte_unit(memory_size_str, sizeof(*this), true);
948  std::cout << " Size on Stack: " << memory_size_str << "\n";
949  }
950 
951  private:
952  bool is_inline() const
953  {
954  return begin_ == inline_buffer_;
955  }
956 
957  void ensure_space_for_one()
958  {
959  if (UNLIKELY(end_ >= capacity_end_)) {
960  this->realloc_to_at_least(this->size() + 1);
961  }
962  }
963 
964  BLI_NOINLINE void realloc_to_at_least(const int64_t min_capacity)
965  {
966  if (this->capacity() >= min_capacity) {
967  return;
968  }
969 
970  /* At least double the size of the previous allocation. Otherwise consecutive calls to grow can
971  * cause a reallocation every time even though min_capacity only increments. */
972  const int64_t min_new_capacity = this->capacity() * 2;
973 
974  const int64_t new_capacity = std::max(min_capacity, min_new_capacity);
975  const int64_t size = this->size();
976 
977  T *new_array = static_cast<T *>(
978  allocator_.allocate(static_cast<size_t>(new_capacity) * sizeof(T), alignof(T), AT));
979  try {
980  uninitialized_relocate_n(begin_, size, new_array);
981  }
982  catch (...) {
983  allocator_.deallocate(new_array);
984  throw;
985  }
986 
987  if (!this->is_inline()) {
988  allocator_.deallocate(begin_);
989  }
990 
991  begin_ = new_array;
992  end_ = begin_ + size;
993  capacity_end_ = begin_ + new_capacity;
994  }
995 };
996 
997 #undef UPDATE_VECTOR_SIZE
998 
1003 template<typename T, int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T))>
1005 
1006 } /* namespace blender */
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_NOINLINE
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void BLI_str_format_byte_unit(char dst[15], long long int bytes, bool base_10) ATTR_NONNULL()
Definition: string.c:1132
#define BLI_ENABLE_IF(condition)
#define UNLIKELY(x)
#define AT
#define BLI_NO_UNIQUE_ADDRESS
#define UPDATE_VECTOR_SIZE(ptr)
Definition: BLI_vector.hh:99
Read Guarded memory(de)allocation.
unsigned int U
Definition: btGjkEpa3.h:78
size_t size() const
constexpr const T * data() const
Definition: BLI_span.hh:203
constexpr int64_t size() const
Definition: BLI_span.hh:240
T & operator[](int64_t index)
Definition: BLI_vector.hh:296
void insert(const int64_t insert_index, T &&value)
Definition: BLI_vector.hh:583
std::reverse_iterator< T * > rbegin()
Definition: BLI_vector.hh:884
int64_t size() const
Definition: BLI_vector.hh:694
void remove_and_reorder(const int64_t index)
Definition: BLI_vector.hh:743
Vector(const Vector< T, OtherInlineBufferCapacity, Allocator > &other)
Definition: BLI_vector.hh:221
MutableSpan< T > as_mutable_span()
Definition: BLI_vector.hh:330
Vector(const Vector &other)
Definition: BLI_vector.hh:212
Vector(Allocator allocator={}) noexcept
Definition: BLI_vector.hh:117
int64_t append_and_get_index(const T &value)
Definition: BLI_vector.hh:452
void prepend(const T &value)
Definition: BLI_vector.hh:642
bool contains(const T &value) const
Definition: BLI_vector.hh:837
void append(const T &value)
Definition: BLI_vector.hh:433
void insert(const int64_t insert_index, const T &value)
Definition: BLI_vector.hh:579
const T & last(const int64_t n=0) const
Definition: BLI_vector.hh:663
friend bool operator==(const Vector &a, const Vector &b)
Definition: BLI_vector.hh:925
void prepend(T &&value)
Definition: BLI_vector.hh:646
T & last(const int64_t n=0)
Definition: BLI_vector.hh:669
Vector(InputIt first, InputIt last, Allocator allocator={})
Definition: BLI_vector.hh:185
void append_unchecked_as(ForwardT &&...value)
Definition: BLI_vector.hh:492
void remove(const int64_t index)
Definition: BLI_vector.hh:774
Span< T > as_span() const
Definition: BLI_vector.hh:325
friend class Vector
Definition: BLI_vector.hh:110
bool is_empty() const
Definition: BLI_vector.hh:706
void resize(const int64_t new_size, const T &value)
Definition: BLI_vector.hh:374
Vector(const ListBase &values, Allocator allocator={})
Definition: BLI_vector.hh:200
const T & operator[](int64_t index) const
Definition: BLI_vector.hh:289
void remove_first_occurrence_and_reorder(const T &value)
Definition: BLI_vector.hh:761
void print_stats(StringRef name="") const
Definition: BLI_vector.hh:938
std::reverse_iterator< const T * > rbegin() const
Definition: BLI_vector.hh:893
IndexRange index_range() const
Definition: BLI_vector.hh:920
int64_t append_and_get_index_as(ForwardValue &&...value)
Definition: BLI_vector.hh:460
void prepend(InputIt first, InputIt last)
Definition: BLI_vector.hh:654
void resize(const int64_t new_size)
Definition: BLI_vector.hh:353
int64_t first_index_of(const T &value) const
Definition: BLI_vector.hh:826
void clear_and_make_inline()
Definition: BLI_vector.hh:414
void extend_unchecked(Span< T > array)
Definition: BLI_vector.hh:556
void remove_last()
Definition: BLI_vector.hh:715
void append_unchecked(const T &value)
Definition: BLI_vector.hh:484
void prepend(Span< T > values)
Definition: BLI_vector.hh:650
Vector(NoExceptConstructor, Allocator allocator={}) noexcept
Definition: BLI_vector.hh:125
const T & first() const
Definition: BLI_vector.hh:680
Vector(Span< U > values, Allocator allocator={})
Definition: BLI_vector.hh:153
std::reverse_iterator< T * > rend()
Definition: BLI_vector.hh:888
void reserve(const int64_t min_capacity)
Definition: BLI_vector.hh:340
const T & const_reference
Definition: BLI_vector.hh:70
const T * end() const
Definition: BLI_vector.hh:879
int64_t size_type
Definition: BLI_vector.hh:73
void remove(const int64_t start_index, const int64_t amount)
Definition: BLI_vector.hh:793
void extend(Span< T > array)
Definition: BLI_vector.hh:530
void append(T &&value)
Definition: BLI_vector.hh:437
void insert(const T *insert_position, InputIt first, InputIt last)
Definition: BLI_vector.hh:592
void append_unchecked(T &&value)
Definition: BLI_vector.hh:488
void extend_non_duplicates(Span< T > array)
Definition: BLI_vector.hh:545
void reinitialize(const int64_t new_size)
Definition: BLI_vector.hh:393
Vector(int64_t size, const T &value, Allocator allocator={})
Definition: BLI_vector.hh:143
void append_non_duplicates(const T &value)
Definition: BLI_vector.hh:472
void fill(const T &value) const
Definition: BLI_vector.hh:845
void insert(const int64_t insert_index, InputIt first, InputIt last)
Definition: BLI_vector.hh:597
Vector(const std::array< U, N > &values)
Definition: BLI_vector.hh:177
const T * begin() const
Definition: BLI_vector.hh:875
Vector(int64_t size, Allocator allocator={})
Definition: BLI_vector.hh:134
const T * const_pointer
Definition: BLI_vector.hh:68
void insert(const int64_t insert_index, Span< T > array)
Definition: BLI_vector.hh:588
const T * data() const
Definition: BLI_vector.hh:861
void append_as(ForwardValue &&...value)
Definition: BLI_vector.hh:442
int64_t append_and_get_index(T &&value)
Definition: BLI_vector.hh:456
void extend(InputIt first, InputIt last)
Definition: BLI_vector.hh:569
void extend(const T *start, int64_t amount)
Definition: BLI_vector.hh:534
Vector & operator=(Vector &&other)
Definition: BLI_vector.hh:280
Vector(const std::initializer_list< U > &values)
Definition: BLI_vector.hh:168
friend bool operator!=(const Vector &a, const Vector &b)
Definition: BLI_vector.hh:930
void extend_unchecked(const T *start, int64_t amount)
Definition: BLI_vector.hh:560
void increase_size_by_unchecked(const int64_t n) noexcept
Definition: BLI_vector.hh:518
int64_t capacity() const
Definition: BLI_vector.hh:906
std::reverse_iterator< const T * > rend() const
Definition: BLI_vector.hh:897
Vector & operator=(const Vector &other)
Definition: BLI_vector.hh:275
int64_t first_index_of_try(const T &value) const
Definition: BLI_vector.hh:812
void append_n_times(const T &value, const int64_t n)
Definition: BLI_vector.hh:504
const T * const_iterator
Definition: BLI_vector.hh:72
Vector(Vector< T, OtherInlineBufferCapacity, Allocator > &&other) noexcept(std::is_nothrow_move_constructible_v< T >)
Definition: BLI_vector.hh:231
Vector(const std::initializer_list< T > &values)
Definition: BLI_vector.hh:172
#define T
static unsigned a[3]
Definition: RandGen.cpp:78
T distance(const T &a, const T &b)
Container & move_assign_container(Container &dst, Container &&src) noexcept(std::is_nothrow_move_constructible_v< Container >)
void default_construct_n(T *ptr, int64_t n)
Container & copy_assign_container(Container &dst, const Container &src)
void initialized_fill_n(T *dst, int64_t n, const T &value)
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 destruct_n(T *ptr, int64_t n)
void uninitialized_copy_n(const T *src, int64_t n, T *dst)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
__int64 int64_t
Definition: stdint.h:89
float max