Open3D (C++ API)  0.19.0
SmallVector.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - Open3D: www.open3d.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.open3d.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 //
8 // Adapted for Open3D.
9 // Commit 75e164f61d391979b4829bf2746a5d74b94e95f2 2022-01-21
10 // Documentation:
11 // https://llvm.org/docs/ProgrammersManual.html#llvm-adt-smallvector-h
12 //
13 //===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- C++ -*-===//
14 //
15 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
16 // See https://llvm.org/LICENSE.txt for license information.
17 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
18 //
19 //===----------------------------------------------------------------------===//
24 //===----------------------------------------------------------------------===//
25 
26 #pragma once
27 
28 #include <algorithm>
29 #include <cassert>
30 #include <cstddef>
31 #include <cstdint>
32 #include <cstdlib>
33 #include <cstring>
34 #include <functional>
35 #include <initializer_list>
36 #include <iterator>
37 #include <limits>
38 #include <memory>
39 #include <new>
40 #include <type_traits>
41 #include <utility>
42 
43 #ifndef LLVM_LIKELY
44 #define LLVM_LIKELY /* [[likely]] */
45 #endif
46 #ifndef LLVM_UNLIKELY
47 #define LLVM_UNLIKELY /* [[unlikely]] */
48 #endif
49 #ifndef LLVM_NODISCARD
50 #define LLVM_NODISCARD /* [[nodiscard]] */
51 #endif
52 #ifndef LLVM_GSL_OWNER
53 #define LLVM_GSL_OWNER
54 #endif
55 
56 namespace open3d {
57 namespace core {
58 // from llvm/include/llvm/Support/MemAlloc.h
59 inline void *safe_malloc(size_t Sz) {
60  void *Result = std::malloc(Sz);
61  if (Result == nullptr) {
62  // It is implementation-defined whether allocation occurs if the space
63  // requested is zero (ISO/IEC 9899:2018 7.22.3). Retry, requesting
64  // non-zero, if the space requested was zero.
65  if (Sz == 0) return safe_malloc(1);
66  throw std::bad_alloc();
67  }
68  return Result;
69 }
70 
71 inline void *safe_realloc(void *Ptr, size_t Sz) {
72  void *Result = std::realloc(Ptr, Sz);
73  if (Result == nullptr) {
74  // It is implementation-defined whether allocation occurs if the space
75  // requested is zero (ISO/IEC 9899:2018 7.22.3). Retry, requesting
76  // non-zero, if the space requested was zero.
77  if (Sz == 0) return safe_malloc(1);
78  throw std::bad_alloc();
79  }
80  return Result;
81 }
82 
83 template <typename IteratorT>
85 
94 template <class Size_T>
96 protected:
97  void *BeginX;
98  Size_T Size = 0, Capacity;
99 
101  static constexpr size_t SizeTypeMax() {
102  return std::numeric_limits<Size_T>::max();
103  }
104 
105  SmallVectorBase() = delete;
106  SmallVectorBase(void *FirstEl, size_t TotalCapacity)
107  : BeginX(FirstEl), Capacity(TotalCapacity) {}
108 
112  void *mallocForGrow(size_t MinSize, size_t TSize, size_t &NewCapacity);
113 
117  void grow_pod(void *FirstEl, size_t MinSize, size_t TSize);
118 
119 public:
120  size_t size() const { return Size; }
121  size_t capacity() const { return Capacity; }
122 
123  LLVM_NODISCARD bool empty() const { return !Size; }
124 
125 protected:
130  void set_size(size_t N) {
131  assert(N <= capacity());
132  Size = N;
133  }
134 };
135 
136 template <class T>
138  typename std::conditional<sizeof(T) < 4 && sizeof(void *) >= 8,
139  uint64_t,
141 
143 template <class T, typename = void>
147  alignas(T) char FirstEl[sizeof(T)];
148 };
149 
153 template <typename T, typename = void>
155  : public SmallVectorBase<SmallVectorSizeType<T>> {
157 
161  void *getFirstEl() const {
162  return const_cast<void *>(reinterpret_cast<const void *>(
163  reinterpret_cast<const char *>(this) +
164  offsetof(SmallVectorAlignmentAndSize<T>, FirstEl)));
165  }
166  // Space after 'FirstEl' is clobbered, do not add any instance vars after
167  // it.
168 
169 protected:
170  SmallVectorTemplateCommon(size_t Size) : Base(getFirstEl(), Size) {}
171 
172  void grow_pod(size_t MinSize, size_t TSize) {
173  Base::grow_pod(getFirstEl(), MinSize, TSize);
174  }
175 
178  bool isSmall() const { return this->BeginX == getFirstEl(); }
179 
181  void resetToSmall() {
182  this->BeginX = getFirstEl();
183  this->Size = this->Capacity =
184  0; // FIXME: Setting Capacity to 0 is suspect.
185  }
186 
188  bool isReferenceToRange(const void *V,
189  const void *First,
190  const void *Last) const {
191  // Use std::less to avoid UB.
192  std::less<> LessThan;
193  return !LessThan(V, First) && LessThan(V, Last);
194  }
195 
197  bool isReferenceToStorage(const void *V) const {
198  return isReferenceToRange(V, this->begin(), this->end());
199  }
200 
203  bool isRangeInStorage(const void *First, const void *Last) const {
204  // Use std::less to avoid UB.
205  std::less<> LessThan;
206  return !LessThan(First, this->begin()) && !LessThan(Last, First) &&
207  !LessThan(this->end(), Last);
208  }
209 
212  bool isSafeToReferenceAfterResize(const void *Elt, size_t NewSize) {
213  // Past the end.
214  if (LLVM_LIKELY(!isReferenceToStorage(Elt))) return true;
215 
216  // Return false if Elt will be destroyed by shrinking.
217  if (NewSize <= this->size()) return Elt < this->begin() + NewSize;
218 
219  // Return false if we need to grow.
220  return NewSize <= this->capacity();
221  }
222 
224  void assertSafeToReferenceAfterResize(const void *Elt, size_t NewSize) {
225  assert(isSafeToReferenceAfterResize(Elt, NewSize) &&
226  "Attempting to reference an element of the vector in an "
227  "operation "
228  "that invalidates it");
229  }
230 
233  void assertSafeToAdd(const void *Elt, size_t N = 1) {
234  this->assertSafeToReferenceAfterResize(Elt, this->size() + N);
235  }
236 
238  void assertSafeToReferenceAfterClear(const T *From, const T *To) {
239  if (From == To) return;
240  this->assertSafeToReferenceAfterResize(From, 0);
241  this->assertSafeToReferenceAfterResize(To - 1, 0);
242  }
243  template <class ItTy,
244  std::enable_if_t<
245  !std::is_same<std::remove_const_t<ItTy>, T *>::value,
246  bool> = false>
248 
250  void assertSafeToAddRange(const T *From, const T *To) {
251  if (From == To) return;
252  this->assertSafeToAdd(From, To - From);
253  this->assertSafeToAdd(To - 1, To - From);
254  }
255  template <class ItTy,
256  std::enable_if_t<
257  !std::is_same<std::remove_const_t<ItTy>, T *>::value,
258  bool> = false>
259  void assertSafeToAddRange(ItTy, ItTy) {}
260 
263  template <class U>
264  static const T *reserveForParamAndGetAddressImpl(U *This,
265  const T &Elt,
266  size_t N) {
267  size_t NewSize = This->size() + N;
268  if (LLVM_LIKELY(NewSize <= This->capacity())) return &Elt;
269 
270  bool ReferencesStorage = false;
271  int64_t Index = -1;
272  if (!U::TakesParamByValue) {
273  if (LLVM_UNLIKELY(This->isReferenceToStorage(&Elt))) {
274  ReferencesStorage = true;
275  Index = &Elt - This->begin();
276  }
277  }
278  This->grow(NewSize);
279  return ReferencesStorage ? This->begin() + Index : &Elt;
280  }
281 
282 public:
283  using size_type = size_t;
284  using difference_type = ptrdiff_t;
285  using value_type = T;
286  using iterator = T *;
287  using const_iterator = const T *;
288 
289  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
290  using reverse_iterator = std::reverse_iterator<iterator>;
291 
292  using reference = T &;
293  using const_reference = const T &;
294  using pointer = T *;
295  using const_pointer = const T *;
296 
297  using Base::capacity;
298  using Base::empty;
299  using Base::size;
300 
301  // forward iterator creation methods.
302  iterator begin() { return (iterator)this->BeginX; }
303  const_iterator begin() const { return (const_iterator)this->BeginX; }
304  iterator end() { return begin() + size(); }
305  const_iterator end() const { return begin() + size(); }
306 
307  // reverse iterator creation methods.
310  return const_reverse_iterator(end());
311  }
314  return const_reverse_iterator(begin());
315  }
316 
317  size_type size_in_bytes() const { return size() * sizeof(T); }
318  size_type max_size() const {
319  return std::min(this->SizeTypeMax(), size_type(-1) / sizeof(T));
320  }
321 
322  size_t capacity_in_bytes() const { return capacity() * sizeof(T); }
323 
325  pointer data() { return pointer(begin()); }
327  const_pointer data() const { return const_pointer(begin()); }
328 
330  assert(idx < size());
331  return begin()[idx];
332  }
334  assert(idx < size());
335  return begin()[idx];
336  }
337 
339  assert(!empty());
340  return begin()[0];
341  }
343  assert(!empty());
344  return begin()[0];
345  }
346 
348  assert(!empty());
349  return end()[-1];
350  }
352  assert(!empty());
353  return end()[-1];
354  }
355 };
356 
365 template <typename T,
366  bool = (std::is_trivially_copy_constructible<T>::value) &&
367  (std::is_trivially_move_constructible<T>::value) &&
368  std::is_trivially_destructible<T>::value>
370  friend class SmallVectorTemplateCommon<T>;
371 
372 protected:
373  static constexpr bool TakesParamByValue = false;
374  using ValueParamT = const T &;
375 
377 
378  static void destroy_range(T *S, T *E) {
379  while (S != E) {
380  --E;
381  E->~T();
382  }
383  }
384 
387  template <typename It1, typename It2>
388  static void uninitialized_move(It1 I, It1 E, It2 Dest) {
389  std::uninitialized_copy(std::make_move_iterator(I),
390  std::make_move_iterator(E), Dest);
391  }
392 
395  template <typename It1, typename It2>
396  static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
397  std::uninitialized_copy(I, E, Dest);
398  }
399 
403  void grow(size_t MinSize = 0);
404 
407  T *mallocForGrow(size_t MinSize, size_t &NewCapacity) {
408  return static_cast<T *>(
410  MinSize, sizeof(T), NewCapacity));
411  }
412 
415  void moveElementsForGrow(T *NewElts);
416 
418  void takeAllocationForGrow(T *NewElts, size_t NewCapacity);
419 
422  const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) {
423  return this->reserveForParamAndGetAddressImpl(this, Elt, N);
424  }
425 
428  T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) {
429  return const_cast<T *>(
430  this->reserveForParamAndGetAddressImpl(this, Elt, N));
431  }
432 
433  static T &&forward_value_param(T &&V) { return std::move(V); }
434  static const T &forward_value_param(const T &V) { return V; }
435 
436  void growAndAssign(size_t NumElts, const T &Elt) {
437  // Grow manually in case Elt is an internal reference.
438  size_t NewCapacity;
439  T *NewElts = mallocForGrow(NumElts, NewCapacity);
440  std::uninitialized_fill_n(NewElts, NumElts, Elt);
441  this->destroy_range(this->begin(), this->end());
442  takeAllocationForGrow(NewElts, NewCapacity);
443  this->set_size(NumElts);
444  }
445 
446  template <typename... ArgTypes>
447  T &growAndEmplaceBack(ArgTypes &&...Args) {
448  // Grow manually in case one of Args is an internal reference.
449  size_t NewCapacity;
450  T *NewElts = mallocForGrow(0, NewCapacity);
451  ::new ((void *)(NewElts + this->size()))
452  T(std::forward<ArgTypes>(Args)...);
453  moveElementsForGrow(NewElts);
454  takeAllocationForGrow(NewElts, NewCapacity);
455  this->set_size(this->size() + 1);
456  return this->back();
457  }
458 
459 public:
460  void push_back(const T &Elt) {
461  const T *EltPtr = reserveForParamAndGetAddress(Elt);
462  ::new ((void *)this->end()) T(*EltPtr);
463  this->set_size(this->size() + 1);
464  }
465 
466  void push_back(T &&Elt) {
467  T *EltPtr = reserveForParamAndGetAddress(Elt);
468  ::new ((void *)this->end()) T(::std::move(*EltPtr));
469  this->set_size(this->size() + 1);
470  }
471 
472  void pop_back() {
473  this->set_size(this->size() - 1);
474  this->end()->~T();
475  }
476 };
477 
478 // Define this out-of-line to dissuade the C++ compiler from inlining it.
479 template <typename T, bool TriviallyCopyable>
481  size_t NewCapacity;
482  T *NewElts = mallocForGrow(MinSize, NewCapacity);
483  moveElementsForGrow(NewElts);
484  takeAllocationForGrow(NewElts, NewCapacity);
485 }
486 
487 // Define this out-of-line to dissuade the C++ compiler from inlining it.
488 template <typename T, bool TriviallyCopyable>
490  T *NewElts) {
491  // Move the elements over.
492  this->uninitialized_move(this->begin(), this->end(), NewElts);
493 
494  // Destroy the original elements.
495  destroy_range(this->begin(), this->end());
496 }
497 
498 // Define this out-of-line to dissuade the C++ compiler from inlining it.
499 template <typename T, bool TriviallyCopyable>
501  T *NewElts, size_t NewCapacity) {
502  // If this wasn't grown from the inline copy, deallocate the old space.
503  if (!this->isSmall()) free(this->begin());
504 
505  this->BeginX = NewElts;
506  this->Capacity = NewCapacity;
507 }
508 
513 template <typename T>
515  friend class SmallVectorTemplateCommon<T>;
516 
517 protected:
520  static constexpr bool TakesParamByValue = sizeof(T) <= 2 * sizeof(void *);
521 
524  using ValueParamT =
526 
528 
529  // No need to do a destroy loop for POD's.
530  static void destroy_range(T *, T *) {}
531 
534  template <typename It1, typename It2>
535  static void uninitialized_move(It1 I, It1 E, It2 Dest) {
536  // Just do a copy.
537  uninitialized_copy(I, E, Dest);
538  }
539 
542  template <typename It1, typename It2>
543  static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
544  // Arbitrary iterator types; just use the basic implementation.
545  std::uninitialized_copy(I, E, Dest);
546  }
547 
550  template <typename T1, typename T2>
551  static void uninitialized_copy(
552  T1 *I,
553  T1 *E,
554  T2 *Dest,
555  std::enable_if_t<std::is_same<typename std::remove_const<T1>::type,
556  T2>::value> * = nullptr) {
557  // Use memcpy for PODs iterated by pointers (which includes SmallVector
558  // iterators): std::uninitialized_copy optimizes to memmove, but we can
559  // use memcpy here. Note that I and E are iterators and thus might be
560  // invalid for memcpy if they are equal.
561  if (I != E)
562  memcpy(reinterpret_cast<void *>(Dest), I, (E - I) * sizeof(T));
563  }
564 
567  void grow(size_t MinSize = 0) { this->grow_pod(MinSize, sizeof(T)); }
568 
571  const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) {
572  return this->reserveForParamAndGetAddressImpl(this, Elt, N);
573  }
574 
577  T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) {
578  return const_cast<T *>(
579  this->reserveForParamAndGetAddressImpl(this, Elt, N));
580  }
581 
584 
585  void growAndAssign(size_t NumElts, T Elt) {
586  // Elt has been copied in case it's an internal reference, side-stepping
587  // reference invalidation problems without losing the realloc
588  // optimization.
589  this->set_size(0);
590  this->grow(NumElts);
591  std::uninitialized_fill_n(this->begin(), NumElts, Elt);
592  this->set_size(NumElts);
593  }
594 
595  template <typename... ArgTypes>
596  T &growAndEmplaceBack(ArgTypes &&...Args) {
597  // Use push_back with a copy in case Args has an internal reference,
598  // side-stepping reference invalidation problems without losing the
599  // realloc optimization.
600  push_back(T(std::forward<ArgTypes>(Args)...));
601  return this->back();
602  }
603 
604 public:
605  void push_back(ValueParamT Elt) {
606  const T *EltPtr = reserveForParamAndGetAddress(Elt);
607  memcpy(reinterpret_cast<void *>(this->end()), EltPtr, sizeof(T));
608  this->set_size(this->size() + 1);
609  }
610 
611  void pop_back() { this->set_size(this->size() - 1); }
612 };
613 
616 template <typename T>
619 
620 public:
621  using iterator = typename SuperClass::iterator;
625 
626 protected:
629 
630  // Default ctor - Initialize to empty.
631  explicit SmallVectorImpl(unsigned N) : SmallVectorTemplateBase<T>(N) {}
632 
634  this->destroy_range(this->begin(), this->end());
635  if (!this->isSmall()) free(this->begin());
636  this->BeginX = RHS.BeginX;
637  this->Size = RHS.Size;
638  this->Capacity = RHS.Capacity;
639  RHS.resetToSmall();
640  }
641 
642 public:
643  SmallVectorImpl(const SmallVectorImpl &) = delete;
644 
646  // Subclass has already destructed this vector's elements.
647  // If this wasn't grown from the inline copy, deallocate the old space.
648  if (!this->isSmall()) free(this->begin());
649  }
650 
651  void clear() {
652  this->destroy_range(this->begin(), this->end());
653  this->Size = 0;
654  }
655 
656 private:
657  // Make set_size() private to avoid misuse in subclasses.
658  using SuperClass::set_size;
659 
660  template <bool ForOverwrite>
661  void resizeImpl(size_type N) {
662  if (N == this->size()) return;
663 
664  if (N < this->size()) {
665  this->truncate(N);
666  return;
667  }
668 
669  this->reserve(N);
670  for (auto I = this->end(), E = this->begin() + N; I != E; ++I)
671  if (ForOverwrite)
672  new (&*I) T;
673  else
674  new (&*I) T();
675  this->set_size(N);
676  }
677 
678 public:
679  void resize(size_type N) { resizeImpl<false>(N); }
680 
682  void resize_for_overwrite(size_type N) { resizeImpl<true>(N); }
683 
685  void truncate(size_type N) {
686  assert(this->size() >= N && "Cannot increase size with truncate");
687  this->destroy_range(this->begin() + N, this->end());
688  this->set_size(N);
689  }
690 
692  if (N == this->size()) return;
693 
694  if (N < this->size()) {
695  this->truncate(N);
696  return;
697  }
698 
699  // N > this->size(). Defer to append.
700  this->append(N - this->size(), NV);
701  }
702 
703  void reserve(size_type N) {
704  if (this->capacity() < N) this->grow(N);
705  }
706 
707  void pop_back_n(size_type NumItems) {
708  assert(this->size() >= NumItems);
709  truncate(this->size() - NumItems);
710  }
711 
713  T Result = ::std::move(this->back());
714  this->pop_back();
715  return Result;
716  }
717 
718  void swap(SmallVectorImpl &RHS);
719 
721  template <typename in_iter,
722  typename = std::enable_if_t<std::is_convertible<
723  typename std::iterator_traits<in_iter>::iterator_category,
724  std::input_iterator_tag>::value>>
725  void append(in_iter in_start, in_iter in_end) {
726  this->assertSafeToAddRange(in_start, in_end);
727  size_type NumInputs = std::distance(in_start, in_end);
728  this->reserve(this->size() + NumInputs);
729  this->uninitialized_copy(in_start, in_end, this->end());
730  this->set_size(this->size() + NumInputs);
731  }
732 
734  void append(size_type NumInputs, ValueParamT Elt) {
735  const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumInputs);
736  std::uninitialized_fill_n(this->end(), NumInputs, *EltPtr);
737  this->set_size(this->size() + NumInputs);
738  }
739 
740  void append(std::initializer_list<T> IL) { append(IL.begin(), IL.end()); }
741 
742  void append(const SmallVectorImpl &RHS) { append(RHS.begin(), RHS.end()); }
743 
744  void assign(size_type NumElts, ValueParamT Elt) {
745  // Note that Elt could be an internal reference.
746  if (NumElts > this->capacity()) {
747  this->growAndAssign(NumElts, Elt);
748  return;
749  }
750 
751  // Assign over existing elements.
752  std::fill_n(this->begin(), std::min(NumElts, this->size()), Elt);
753  if (NumElts > this->size())
754  std::uninitialized_fill_n(this->end(), NumElts - this->size(), Elt);
755  else if (NumElts < this->size())
756  this->destroy_range(this->begin() + NumElts, this->end());
757  this->set_size(NumElts);
758  }
759 
760  // FIXME: Consider assigning over existing elements, rather than clearing &
761  // re-initializing them - for all assign(...) variants.
762 
763  template <typename in_iter,
764  typename = std::enable_if_t<std::is_convertible<
765  typename std::iterator_traits<in_iter>::iterator_category,
766  std::input_iterator_tag>::value>>
767  void assign(in_iter in_start, in_iter in_end) {
768  this->assertSafeToReferenceAfterClear(in_start, in_end);
769  clear();
770  append(in_start, in_end);
771  }
772 
773  void assign(std::initializer_list<T> IL) {
774  clear();
775  append(IL);
776  }
777 
778  void assign(const SmallVectorImpl &RHS) { assign(RHS.begin(), RHS.end()); }
779 
781  // Just cast away constness because this is a non-const member function.
782  iterator I = const_cast<iterator>(CI);
783 
784  assert(this->isReferenceToStorage(CI) &&
785  "Iterator to erase is out of bounds.");
786 
787  iterator N = I;
788  // Shift all elts down one.
789  std::move(I + 1, this->end(), I);
790  // Drop the last elt.
791  this->pop_back();
792  return (N);
793  }
794 
796  // Just cast away constness because this is a non-const member function.
797  iterator S = const_cast<iterator>(CS);
798  iterator E = const_cast<iterator>(CE);
799 
800  assert(this->isRangeInStorage(S, E) &&
801  "Range to erase is out of bounds.");
802 
803  iterator N = S;
804  // Shift all elts down.
805  iterator I = std::move(E, this->end(), S);
806  // Drop the last elts.
807  this->destroy_range(I, this->end());
808  this->set_size(I - this->begin());
809  return (N);
810  }
811 
812 private:
813  template <class ArgType>
814  iterator insert_one_impl(iterator I, ArgType &&Elt) {
815  // Callers ensure that ArgType is derived from T.
816  static_assert(
817  std::is_same<
818  std::remove_const_t<std::remove_reference_t<ArgType>>,
819  T>::value,
820  "ArgType must be derived from T!");
821 
822  if (I == this->end()) { // Important special case for empty vector.
823  this->push_back(::std::forward<ArgType>(Elt));
824  return this->end() - 1;
825  }
826 
827  assert(this->isReferenceToStorage(I) &&
828  "Insertion iterator is out of bounds.");
829 
830  // Grow if necessary.
831  size_t Index = I - this->begin();
832  std::remove_reference_t<ArgType> *EltPtr =
833  this->reserveForParamAndGetAddress(Elt);
834  I = this->begin() + Index;
835 
836  ::new ((void *)this->end()) T(::std::move(this->back()));
837  // Push everything else over.
838  std::move_backward(I, this->end() - 1, this->end());
839  this->set_size(this->size() + 1);
840 
841  // If we just moved the element we're inserting, be sure to update
842  // the reference (never happens if TakesParamByValue).
843  static_assert(!TakesParamByValue || std::is_same<ArgType, T>::value,
844  "ArgType must be 'T' when taking by value!");
845  if (!TakesParamByValue &&
846  this->isReferenceToRange(EltPtr, I, this->end()))
847  ++EltPtr;
848 
849  *I = ::std::forward<ArgType>(*EltPtr);
850  return I;
851  }
852 
853 public:
854  iterator insert(iterator I, T &&Elt) {
855  return insert_one_impl(I, this->forward_value_param(std::move(Elt)));
856  }
857 
858  iterator insert(iterator I, const T &Elt) {
859  return insert_one_impl(I, this->forward_value_param(Elt));
860  }
861 
863  // Convert iterator to elt# to avoid invalidating iterator when we
864  // reserve()
865  size_t InsertElt = I - this->begin();
866 
867  if (I == this->end()) { // Important special case for empty vector.
868  append(NumToInsert, Elt);
869  return this->begin() + InsertElt;
870  }
871 
872  assert(this->isReferenceToStorage(I) &&
873  "Insertion iterator is out of bounds.");
874 
875  // Ensure there is enough space, and get the (maybe updated) address of
876  // Elt.
877  const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumToInsert);
878 
879  // Uninvalidate the iterator.
880  I = this->begin() + InsertElt;
881 
882  // If there are more elements between the insertion point and the end of
883  // the range than there are being inserted, we can use a simple approach
884  // to insertion. Since we already reserved space, we know that this
885  // won't reallocate the vector.
886  if (size_t(this->end() - I) >= NumToInsert) {
887  T *OldEnd = this->end();
888  append(std::move_iterator<iterator>(this->end() - NumToInsert),
889  std::move_iterator<iterator>(this->end()));
890 
891  // Copy the existing elements that get replaced.
892  std::move_backward(I, OldEnd - NumToInsert, OldEnd);
893 
894  // If we just moved the element we're inserting, be sure to update
895  // the reference (never happens if TakesParamByValue).
896  if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
897  EltPtr += NumToInsert;
898 
899  std::fill_n(I, NumToInsert, *EltPtr);
900  return I;
901  }
902 
903  // Otherwise, we're inserting more elements than exist already, and
904  // we're not inserting at the end.
905 
906  // Move over the elements that we're about to overwrite.
907  T *OldEnd = this->end();
908  this->set_size(this->size() + NumToInsert);
909  size_t NumOverwritten = OldEnd - I;
910  this->uninitialized_move(I, OldEnd, this->end() - NumOverwritten);
911 
912  // If we just moved the element we're inserting, be sure to update
913  // the reference (never happens if TakesParamByValue).
914  if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
915  EltPtr += NumToInsert;
916 
917  // Replace the overwritten part.
918  std::fill_n(I, NumOverwritten, *EltPtr);
919 
920  // Insert the non-overwritten middle part.
921  std::uninitialized_fill_n(OldEnd, NumToInsert - NumOverwritten,
922  *EltPtr);
923  return I;
924  }
925 
926  template <typename ItTy,
927  typename = std::enable_if_t<std::is_convertible<
928  typename std::iterator_traits<ItTy>::iterator_category,
929  std::input_iterator_tag>::value>>
930  iterator insert(iterator I, ItTy From, ItTy To) {
931  // Convert iterator to elt# to avoid invalidating iterator when we
932  // reserve()
933  size_t InsertElt = I - this->begin();
934 
935  if (I == this->end()) { // Important special case for empty vector.
936  append(From, To);
937  return this->begin() + InsertElt;
938  }
939 
940  assert(this->isReferenceToStorage(I) &&
941  "Insertion iterator is out of bounds.");
942 
943  // Check that the reserve that follows doesn't invalidate the iterators.
944  this->assertSafeToAddRange(From, To);
945 
946  size_t NumToInsert = std::distance(From, To);
947 
948  // Ensure there is enough space.
949  reserve(this->size() + NumToInsert);
950 
951  // Uninvalidate the iterator.
952  I = this->begin() + InsertElt;
953 
954  // If there are more elements between the insertion point and the end of
955  // the range than there are being inserted, we can use a simple approach
956  // to insertion. Since we already reserved space, we know that this
957  // won't reallocate the vector.
958  if (size_t(this->end() - I) >= NumToInsert) {
959  T *OldEnd = this->end();
960  append(std::move_iterator<iterator>(this->end() - NumToInsert),
961  std::move_iterator<iterator>(this->end()));
962 
963  // Copy the existing elements that get replaced.
964  std::move_backward(I, OldEnd - NumToInsert, OldEnd);
965 
966  std::copy(From, To, I);
967  return I;
968  }
969 
970  // Otherwise, we're inserting more elements than exist already, and
971  // we're not inserting at the end.
972 
973  // Move over the elements that we're about to overwrite.
974  T *OldEnd = this->end();
975  this->set_size(this->size() + NumToInsert);
976  size_t NumOverwritten = OldEnd - I;
977  this->uninitialized_move(I, OldEnd, this->end() - NumOverwritten);
978 
979  // Replace the overwritten part.
980  for (T *J = I; NumOverwritten > 0; --NumOverwritten) {
981  *J = *From;
982  ++J;
983  ++From;
984  }
985 
986  // Insert the non-overwritten middle part.
987  this->uninitialized_copy(From, To, OldEnd);
988  return I;
989  }
990 
991  void insert(iterator I, std::initializer_list<T> IL) {
992  insert(I, IL.begin(), IL.end());
993  }
994 
995  template <typename... ArgTypes>
996  reference emplace_back(ArgTypes &&...Args) {
997  if (LLVM_UNLIKELY(this->size() >= this->capacity()))
998  return this->growAndEmplaceBack(std::forward<ArgTypes>(Args)...);
999 
1000  ::new ((void *)this->end()) T(std::forward<ArgTypes>(Args)...);
1001  this->set_size(this->size() + 1);
1002  return this->back();
1003  }
1004 
1006 
1008 
1009  bool operator==(const SmallVectorImpl &RHS) const {
1010  if (this->size() != RHS.size()) return false;
1011  return std::equal(this->begin(), this->end(), RHS.begin());
1012  }
1013  bool operator!=(const SmallVectorImpl &RHS) const {
1014  return !(*this == RHS);
1015  }
1016 
1017  bool operator<(const SmallVectorImpl &RHS) const {
1018  return std::lexicographical_compare(this->begin(), this->end(),
1019  RHS.begin(), RHS.end());
1020  }
1021  bool operator>(const SmallVectorImpl &RHS) const { return RHS < *this; }
1022  bool operator<=(const SmallVectorImpl &RHS) const { return !(*this > RHS); }
1023  bool operator>=(const SmallVectorImpl &RHS) const { return !(*this < RHS); }
1024 };
1025 
1026 template <typename T>
1028  if (this == &RHS) return;
1029 
1030  // We can only avoid copying elements if neither vector is small.
1031  if (!this->isSmall() && !RHS.isSmall()) {
1032  std::swap(this->BeginX, RHS.BeginX);
1033  std::swap(this->Size, RHS.Size);
1034  std::swap(this->Capacity, RHS.Capacity);
1035  return;
1036  }
1037  this->reserve(RHS.size());
1038  RHS.reserve(this->size());
1039 
1040  // Swap the shared elements.
1041  size_t NumShared = this->size();
1042  if (NumShared > RHS.size()) NumShared = RHS.size();
1043  for (size_type i = 0; i != NumShared; ++i) std::swap((*this)[i], RHS[i]);
1044 
1045  // Copy over the extra elts.
1046  if (this->size() > RHS.size()) {
1047  size_t EltDiff = this->size() - RHS.size();
1048  this->uninitialized_copy(this->begin() + NumShared, this->end(),
1049  RHS.end());
1050  RHS.set_size(RHS.size() + EltDiff);
1051  this->destroy_range(this->begin() + NumShared, this->end());
1052  this->set_size(NumShared);
1053  } else if (RHS.size() > this->size()) {
1054  size_t EltDiff = RHS.size() - this->size();
1055  this->uninitialized_copy(RHS.begin() + NumShared, RHS.end(),
1056  this->end());
1057  this->set_size(this->size() + EltDiff);
1058  this->destroy_range(RHS.begin() + NumShared, RHS.end());
1059  RHS.set_size(NumShared);
1060  }
1061 }
1062 
1063 template <typename T>
1065  const SmallVectorImpl<T> &RHS) {
1066  // Avoid self-assignment.
1067  if (this == &RHS) return *this;
1068 
1069  // If we already have sufficient space, assign the common elements, then
1070  // destroy any excess.
1071  size_t RHSSize = RHS.size();
1072  size_t CurSize = this->size();
1073  if (CurSize >= RHSSize) {
1074  // Assign common elements.
1075  iterator NewEnd;
1076  if (RHSSize)
1077  NewEnd = std::copy(RHS.begin(), RHS.begin() + RHSSize,
1078  this->begin());
1079  else
1080  NewEnd = this->begin();
1081 
1082  // Destroy excess elements.
1083  this->destroy_range(NewEnd, this->end());
1084 
1085  // Trim.
1086  this->set_size(RHSSize);
1087  return *this;
1088  }
1089 
1090  // If we have to grow to have enough elements, destroy the current elements.
1091  // This allows us to avoid copying them during the grow.
1092  // FIXME: don't do this if they're efficiently moveable.
1093  if (this->capacity() < RHSSize) {
1094  // Destroy current elements.
1095  this->clear();
1096  CurSize = 0;
1097  this->grow(RHSSize);
1098  } else if (CurSize) {
1099  // Otherwise, use assignment for the already-constructed elements.
1100  std::copy(RHS.begin(), RHS.begin() + CurSize, this->begin());
1101  }
1102 
1103  // Copy construct the new elements in place.
1104  this->uninitialized_copy(RHS.begin() + CurSize, RHS.end(),
1105  this->begin() + CurSize);
1106 
1107  // Set end.
1108  this->set_size(RHSSize);
1109  return *this;
1110 }
1111 
1112 template <typename T>
1114  // Avoid self-assignment.
1115  if (this == &RHS) return *this;
1116 
1117  // If the RHS isn't small, clear this vector and then steal its buffer.
1118  if (!RHS.isSmall()) {
1119  this->assignRemote(std::move(RHS));
1120  return *this;
1121  }
1122 
1123  // If we already have sufficient space, assign the common elements, then
1124  // destroy any excess.
1125  size_t RHSSize = RHS.size();
1126  size_t CurSize = this->size();
1127  if (CurSize >= RHSSize) {
1128  // Assign common elements.
1129  iterator NewEnd = this->begin();
1130  if (RHSSize) NewEnd = std::move(RHS.begin(), RHS.end(), NewEnd);
1131 
1132  // Destroy excess elements and trim the bounds.
1133  this->destroy_range(NewEnd, this->end());
1134  this->set_size(RHSSize);
1135 
1136  // Clear the RHS.
1137  RHS.clear();
1138 
1139  return *this;
1140  }
1141 
1142  // If we have to grow to have enough elements, destroy the current elements.
1143  // This allows us to avoid copying them during the grow.
1144  // FIXME: this may not actually make any sense if we can efficiently move
1145  // elements.
1146  if (this->capacity() < RHSSize) {
1147  // Destroy current elements.
1148  this->clear();
1149  CurSize = 0;
1150  this->grow(RHSSize);
1151  } else if (CurSize) {
1152  // Otherwise, use assignment for the already-constructed elements.
1153  std::move(RHS.begin(), RHS.begin() + CurSize, this->begin());
1154  }
1155 
1156  // Move-construct the new elements in place.
1157  this->uninitialized_move(RHS.begin() + CurSize, RHS.end(),
1158  this->begin() + CurSize);
1159 
1160  // Set end.
1161  this->set_size(RHSSize);
1162 
1163  RHS.clear();
1164  return *this;
1165 }
1166 
1169 template <typename T, unsigned N>
1171  alignas(T) char InlineElts[N * sizeof(T)];
1172 };
1173 
1177 template <typename T>
1178 struct alignas(T) SmallVectorStorage<T, 0> {};
1179 
1183 template <typename T, unsigned N>
1185 
1191 template <typename T>
1193  // Parameter controlling the default number of inlined elements
1194  // for `SmallVector<T>`.
1195  //
1196  // The default number of inlined elements ensures that
1197  // 1. There is at least one inlined element.
1198  // 2. `sizeof(SmallVector<T>) <= kPreferredSmallVectorSizeof` unless
1199  // it contradicts 1.
1200  static constexpr size_t kPreferredSmallVectorSizeof = 64;
1201 
1202  // static_assert that sizeof(T) is not "too big".
1203  //
1204  // Because our policy guarantees at least one inlined element, it is
1205  // possible for an arbitrarily large inlined element to allocate an
1206  // arbitrarily large amount of inline storage. We generally consider it an
1207  // antipattern for a SmallVector to allocate an excessive amount of inline
1208  // storage, so we want to call attention to these cases and make sure that
1209  // users are making an intentional decision if they request a lot of inline
1210  // storage.
1211  //
1212  // We want this assertion to trigger in pathological cases, but otherwise
1213  // not be too easy to hit. To accomplish that, the cutoff is actually
1214  // somewhat larger than kPreferredSmallVectorSizeof (otherwise,
1215  // `SmallVector<SmallVector<T>>` would be one easy way to trip it, and that
1216  // pattern seems useful in practice).
1217  //
1218  // One wrinkle is that this assertion is in theory non-portable, since
1219  // sizeof(T) is in general platform-dependent. However, we don't expect this
1220  // to be much of an issue, because most LLVM development happens on 64-bit
1221  // hosts, and therefore sizeof(T) is expected to *decrease* when compiled
1222  // for 32-bit hosts, dodging the issue. The reverse situation, where
1223  // development happens on a 32-bit host and then fails due to sizeof(T)
1224  // *increasing* on a 64-bit host, is expected to be very rare.
1225  static_assert(
1226  sizeof(T) <= 256,
1227  "You are trying to use a default number of inlined elements for "
1228  "`SmallVector<T>` but `sizeof(T)` is really big! Please use an "
1229  "explicit number of inlined elements with `SmallVector<T, N>` to "
1230  "make "
1231  "sure you really want that much inline storage.");
1232 
1233  // Discount the size of the header itself when calculating the maximum
1234  // inline bytes.
1235  static constexpr size_t PreferredInlineBytes =
1236  kPreferredSmallVectorSizeof - sizeof(SmallVector<T, 0>);
1237  static constexpr size_t NumElementsThatFit =
1238  PreferredInlineBytes / sizeof(T);
1239  static constexpr size_t value =
1240  NumElementsThatFit == 0 ? 1 : NumElementsThatFit;
1241 };
1242 
1259 template <typename T,
1262  SmallVectorStorage<T, N> {
1263 public:
1265 
1267  // Destroy the constructed elements in the vector.
1268  this->destroy_range(this->begin(), this->end());
1269  }
1270 
1271  explicit SmallVector(size_t Size, const T &Value = T())
1272  : SmallVectorImpl<T>(N) {
1273  this->assign(Size, Value);
1274  }
1275 
1276  template <typename ItTy,
1277  typename = std::enable_if_t<std::is_convertible<
1278  typename std::iterator_traits<ItTy>::iterator_category,
1279  std::input_iterator_tag>::value>>
1280  SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) {
1281  this->append(S, E);
1282  }
1283 
1284  template <typename RangeTy>
1286  : SmallVectorImpl<T>(N) {
1287  this->append(R.begin(), R.end());
1288  }
1289 
1290  SmallVector(std::initializer_list<T> IL) : SmallVectorImpl<T>(N) {
1291  this->assign(IL);
1292  }
1293 
1295  if (!RHS.empty()) SmallVectorImpl<T>::operator=(RHS);
1296  }
1297 
1300  return *this;
1301  }
1302 
1304  if (!RHS.empty()) SmallVectorImpl<T>::operator=(::std::move(RHS));
1305  }
1306 
1308  if (!RHS.empty()) SmallVectorImpl<T>::operator=(::std::move(RHS));
1309  }
1310 
1312  if (N) {
1313  SmallVectorImpl<T>::operator=(::std::move(RHS));
1314  return *this;
1315  }
1316  // SmallVectorImpl<T>::operator= does not leverage N==0. Optimize the
1317  // case.
1318  if (this == &RHS) return *this;
1319  if (RHS.empty()) {
1320  this->destroy_range(this->begin(), this->end());
1321  this->Size = 0;
1322  } else {
1323  this->assignRemote(std::move(RHS));
1324  }
1325  return *this;
1326  }
1327 
1329  SmallVectorImpl<T>::operator=(::std::move(RHS));
1330  return *this;
1331  }
1332 
1333  SmallVector &operator=(std::initializer_list<T> IL) {
1334  this->assign(IL);
1335  return *this;
1336  }
1337 };
1338 
1339 template <typename T, unsigned N>
1340 inline size_t capacity_in_bytes(const SmallVector<T, N> &X) {
1341  return X.capacity_in_bytes();
1342 }
1343 
1344 template <typename RangeType>
1345 using ValueTypeFromRangeType = typename std::remove_const<
1346  typename std::remove_reference<decltype(*std::begin(
1347  std::declval<RangeType &>()))>::type>::type;
1348 
1352 template <unsigned Size, typename R>
1354  return {std::begin(Range), std::end(Range)};
1355 }
1356 template <typename R>
1357 SmallVector<ValueTypeFromRangeType<R>,
1358  CalculateSmallVectorDefaultInlinedElements<
1359  ValueTypeFromRangeType<R>>::value>
1360 to_vector(R &&Range) {
1361  return {std::begin(Range), std::end(Range)};
1362 }
1363 
1364 } // namespace core
1365 } // namespace open3d
1366 
1367 namespace std {
1368 
1370 template <typename T>
1373  LHS.swap(RHS);
1374 }
1375 
1377 template <typename T, unsigned N>
1380  LHS.swap(RHS);
1381 }
1382 
1383 } // end namespace std
void * X
Definition: SmallVector.cpp:45
#define LLVM_LIKELY
Definition: SmallVector.h:44
#define LLVM_GSL_OWNER
Definition: SmallVector.h:53
#define LLVM_NODISCARD
Definition: SmallVector.h:50
#define LLVM_UNLIKELY
Definition: SmallVector.h:47
bool copy
Definition: VtkUtils.cpp:74
Definition: SmallVector.h:95
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:123
size_t capacity() const
Definition: SmallVector.h:121
size_t size() const
Definition: SmallVector.h:120
static constexpr size_t SizeTypeMax()
The maximum value of the Size_T used.
Definition: SmallVector.h:101
SmallVectorBase(void *FirstEl, size_t TotalCapacity)
Definition: SmallVector.h:106
void * BeginX
Definition: SmallVector.h:97
Size_T Capacity
Definition: SmallVector.h:98
void * mallocForGrow(size_t MinSize, size_t TSize, size_t &NewCapacity)
Definition: SmallVector.cpp:125
void set_size(size_t N)
Definition: SmallVector.h:130
Size_T Size
Definition: SmallVector.h:98
void grow_pod(void *FirstEl, size_t MinSize, size_t TSize)
Definition: SmallVector.cpp:134
Definition: SmallVector.h:1262
SmallVector(size_t Size, const T &Value=T())
Definition: SmallVector.h:1271
SmallVector & operator=(SmallVector &&RHS)
Definition: SmallVector.h:1311
SmallVector & operator=(SmallVectorImpl< T > &&RHS)
Definition: SmallVector.h:1328
SmallVector(const SmallVector &RHS)
Definition: SmallVector.h:1294
SmallVector(SmallVectorImpl< T > &&RHS)
Definition: SmallVector.h:1307
SmallVector()
Definition: SmallVector.h:1264
~SmallVector()
Definition: SmallVector.h:1266
SmallVector(const iterator_range< RangeTy > &R)
Definition: SmallVector.h:1285
SmallVector(std::initializer_list< T > IL)
Definition: SmallVector.h:1290
SmallVector & operator=(const SmallVector &RHS)
Definition: SmallVector.h:1298
SmallVector & operator=(std::initializer_list< T > IL)
Definition: SmallVector.h:1333
SmallVector(SmallVector &&RHS)
Definition: SmallVector.h:1303
SmallVector(ItTy S, ItTy E)
Definition: SmallVector.h:1280
Definition: SmallVector.h:617
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:712
bool operator<(const SmallVectorImpl &RHS) const
Definition: SmallVector.h:1017
void resize_for_overwrite(size_type N)
Like resize, but T is POD, the new values won't be initialized.
Definition: SmallVector.h:682
void swap(SmallVectorImpl &RHS)
Definition: SmallVector.h:1027
void assign(const SmallVectorImpl &RHS)
Definition: SmallVector.h:778
void resize(size_type N)
Definition: SmallVector.h:679
typename SuperClass::iterator iterator
Definition: SmallVector.h:621
iterator insert(iterator I, size_type NumToInsert, ValueParamT Elt)
Definition: SmallVector.h:862
SmallVectorImpl(const SmallVectorImpl &)=delete
void assign(in_iter in_start, in_iter in_end)
Definition: SmallVector.h:767
iterator insert(iterator I, ItTy From, ItTy To)
Definition: SmallVector.h:930
void append(std::initializer_list< T > IL)
Definition: SmallVector.h:740
void insert(iterator I, std::initializer_list< T > IL)
Definition: SmallVector.h:991
SmallVectorImpl & operator=(const SmallVectorImpl &RHS)
Definition: SmallVector.h:1064
void append(size_type NumInputs, ValueParamT Elt)
Append NumInputs copies of Elt to the end.
Definition: SmallVector.h:734
void truncate(size_type N)
Like resize, but requires that N is less than size().
Definition: SmallVector.h:685
void reserve(size_type N)
Definition: SmallVector.h:703
bool operator!=(const SmallVectorImpl &RHS) const
Definition: SmallVector.h:1013
iterator insert(iterator I, const T &Elt)
Definition: SmallVector.h:858
bool operator>(const SmallVectorImpl &RHS) const
Definition: SmallVector.h:1021
void assign(size_type NumElts, ValueParamT Elt)
Definition: SmallVector.h:744
void append(const SmallVectorImpl &RHS)
Definition: SmallVector.h:742
typename SuperClass::size_type size_type
Definition: SmallVector.h:624
bool operator>=(const SmallVectorImpl &RHS) const
Definition: SmallVector.h:1023
void assign(std::initializer_list< T > IL)
Definition: SmallVector.h:773
bool operator<=(const SmallVectorImpl &RHS) const
Definition: SmallVector.h:1022
iterator erase(const_iterator CS, const_iterator CE)
Definition: SmallVector.h:795
~SmallVectorImpl()
Definition: SmallVector.h:645
void assignRemote(SmallVectorImpl &&RHS)
Definition: SmallVector.h:633
reference emplace_back(ArgTypes &&...Args)
Definition: SmallVector.h:996
iterator insert(iterator I, T &&Elt)
Definition: SmallVector.h:854
SmallVectorImpl(unsigned N)
Definition: SmallVector.h:631
iterator erase(const_iterator CI)
Definition: SmallVector.h:780
void clear()
Definition: SmallVector.h:651
void resize(size_type N, ValueParamT NV)
Definition: SmallVector.h:691
void pop_back_n(size_type NumItems)
Definition: SmallVector.h:707
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:725
bool operator==(const SmallVectorImpl &RHS) const
Definition: SmallVector.h:1009
typename std::conditional< TakesParamByValue, T, const T & >::type ValueParamT
Definition: SmallVector.h:525
SmallVectorTemplateBase(size_t Size)
Definition: SmallVector.h:527
static void uninitialized_copy(T1 *I, T1 *E, T2 *Dest, std::enable_if_t< std::is_same< typename std::remove_const< T1 >::type, T2 >::value > *=nullptr)
Definition: SmallVector.h:551
T * reserveForParamAndGetAddress(T &Elt, size_t N=1)
Definition: SmallVector.h:577
void push_back(ValueParamT Elt)
Definition: SmallVector.h:605
const T * reserveForParamAndGetAddress(const T &Elt, size_t N=1)
Definition: SmallVector.h:571
void grow(size_t MinSize=0)
Definition: SmallVector.h:567
T & growAndEmplaceBack(ArgTypes &&...Args)
Definition: SmallVector.h:596
static void uninitialized_copy(It1 I, It1 E, It2 Dest)
Definition: SmallVector.h:543
static void uninitialized_move(It1 I, It1 E, It2 Dest)
Definition: SmallVector.h:535
void growAndAssign(size_t NumElts, T Elt)
Definition: SmallVector.h:585
void pop_back()
Definition: SmallVector.h:611
static ValueParamT forward_value_param(ValueParamT V)
Copy V or return a reference, depending on ValueParamT.
Definition: SmallVector.h:583
static void destroy_range(T *, T *)
Definition: SmallVector.h:530
Definition: SmallVector.h:369
static void uninitialized_move(It1 I, It1 E, It2 Dest)
Definition: SmallVector.h:388
SmallVectorTemplateBase(size_t Size)
Definition: SmallVector.h:376
static void destroy_range(T *S, T *E)
Definition: SmallVector.h:378
static void uninitialized_copy(It1 I, It1 E, It2 Dest)
Definition: SmallVector.h:396
void takeAllocationForGrow(T *NewElts, size_t NewCapacity)
Transfer ownership of the allocation, finishing up grow().
Definition: SmallVector.h:500
T & growAndEmplaceBack(ArgTypes &&...Args)
Definition: SmallVector.h:447
void push_back(T &&Elt)
Definition: SmallVector.h:466
T * mallocForGrow(size_t MinSize, size_t &NewCapacity)
Definition: SmallVector.h:407
const T & ValueParamT
Definition: SmallVector.h:374
void pop_back()
Definition: SmallVector.h:472
void moveElementsForGrow(T *NewElts)
Definition: SmallVector.h:489
static constexpr bool TakesParamByValue
Definition: SmallVector.h:373
void growAndAssign(size_t NumElts, const T &Elt)
Definition: SmallVector.h:436
static const T & forward_value_param(const T &V)
Definition: SmallVector.h:434
const T * reserveForParamAndGetAddress(const T &Elt, size_t N=1)
Definition: SmallVector.h:422
static T && forward_value_param(T &&V)
Definition: SmallVector.h:433
void push_back(const T &Elt)
Definition: SmallVector.h:460
T * reserveForParamAndGetAddress(T &Elt, size_t N=1)
Definition: SmallVector.h:428
void grow(size_t MinSize=0)
Definition: SmallVector.h:480
Definition: SmallVector.h:155
void assertSafeToReferenceAfterClear(ItTy, ItTy)
Definition: SmallVector.h:247
const_reverse_iterator rbegin() const
Definition: SmallVector.h:309
SmallVectorTemplateCommon(size_t Size)
Definition: SmallVector.h:170
const T & const_reference
Definition: SmallVector.h:293
size_t capacity_in_bytes() const
Definition: SmallVector.h:322
const_iterator begin() const
Definition: SmallVector.h:303
bool isSafeToReferenceAfterResize(const void *Elt, size_t NewSize)
Definition: SmallVector.h:212
void assertSafeToReferenceAfterResize(const void *Elt, size_t NewSize)
Check whether Elt will be invalidated by resizing the vector to NewSize.
Definition: SmallVector.h:224
bool isRangeInStorage(const void *First, const void *Last) const
Definition: SmallVector.h:203
const T * const_iterator
Definition: SmallVector.h:287
size_type max_size() const
Definition: SmallVector.h:318
size_t size_type
Definition: SmallVector.h:283
reference operator[](size_type idx)
Definition: SmallVector.h:329
const_pointer data() const
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:327
void resetToSmall()
Put this vector in a state of being small.
Definition: SmallVector.h:181
reverse_iterator rbegin()
Definition: SmallVector.h:308
static const T * reserveForParamAndGetAddressImpl(U *This, const T &Elt, size_t N)
Definition: SmallVector.h:264
void assertSafeToReferenceAfterClear(const T *From, const T *To)
Check whether any part of the range will be invalidated by clearing.
Definition: SmallVector.h:238
const_reference operator[](size_type idx) const
Definition: SmallVector.h:333
const_iterator end() const
Definition: SmallVector.h:305
iterator begin()
Definition: SmallVector.h:302
reference front()
Definition: SmallVector.h:338
reference back()
Definition: SmallVector.h:347
T & reference
Definition: SmallVector.h:292
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: SmallVector.h:289
bool isReferenceToStorage(const void *V) const
Return true if V is an internal reference to this vector.
Definition: SmallVector.h:197
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:325
bool isSmall() const
Definition: SmallVector.h:178
void grow_pod(size_t MinSize, size_t TSize)
Definition: SmallVector.h:172
size_type size_in_bytes() const
Definition: SmallVector.h:317
const T * const_pointer
Definition: SmallVector.h:295
void assertSafeToAddRange(const T *From, const T *To)
Check whether any part of the range will be invalidated by growing.
Definition: SmallVector.h:250
const_reference front() const
Definition: SmallVector.h:342
T value_type
Definition: SmallVector.h:285
void assertSafeToAdd(const void *Elt, size_t N=1)
Definition: SmallVector.h:233
iterator end()
Definition: SmallVector.h:304
ptrdiff_t difference_type
Definition: SmallVector.h:284
bool isReferenceToRange(const void *V, const void *First, const void *Last) const
Return true if V is an internal reference to the given range.
Definition: SmallVector.h:188
T * pointer
Definition: SmallVector.h:294
const_reverse_iterator rend() const
Definition: SmallVector.h:313
std::reverse_iterator< iterator > reverse_iterator
Definition: SmallVector.h:290
T * iterator
Definition: SmallVector.h:286
reverse_iterator rend()
Definition: SmallVector.h:312
const_reference back() const
Definition: SmallVector.h:351
void assertSafeToAddRange(ItTy, ItTy)
Definition: SmallVector.h:259
Definition: SmallVector.h:84
char type
Definition: FilePCD.cpp:41
void * safe_realloc(void *Ptr, size_t Sz)
Definition: SmallVector.h:71
typename std::conditional< sizeof(T)< 4 &&sizeof(void *) >=8, uint64_t, uint32_t >::type SmallVectorSizeType
Definition: SmallVector.h:140
void * safe_malloc(size_t Sz)
Definition: SmallVector.h:59
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Definition: SmallVector.h:1353
typename std::remove_const< typename std::remove_reference< decltype(*std::begin(std::declval< RangeType & >()))>::type >::type ValueTypeFromRangeType
Definition: SmallVector.h:1347
const char const char value recording_handle imu_sample recording_handle uint8_t size_t data_size k4a_record_configuration_t config target_format k4a_capture_t capture_handle k4a_imu_sample_t imu_sample playback_handle k4a_logging_message_cb_t void min_level device_handle k4a_imu_sample_t timeout_in_ms capture_handle capture_handle capture_handle image_handle temperature_c k4a_image_t image_handle uint8_t image_handle image_handle image_handle image_handle uint32_t
Definition: K4aPlugin.cpp:548
const char const char value recording_handle imu_sample recording_handle uint8_t size_t data_size k4a_record_configuration_t config target_format k4a_capture_t capture_handle k4a_imu_sample_t imu_sample playback_handle k4a_logging_message_cb_t void min_level device_handle k4a_imu_sample_t timeout_in_ms capture_handle capture_handle capture_handle image_handle temperature_c k4a_image_t image_handle uint8_t image_handle image_handle image_handle image_handle image_handle timestamp_usec white_balance image_handle k4a_device_configuration_t config device_handle char size_t serial_number_size bool int32_t int32_t int32_t int32_t k4a_color_control_mode_t default_mode value const const k4a_calibration_t calibration char size_t
Definition: K4aPlugin.cpp:719
const char const char value recording_handle imu_sample recording_handle uint8_t size_t data_size k4a_record_configuration_t config target_format k4a_capture_t capture_handle k4a_imu_sample_t imu_sample uint64_t
Definition: K4aPlugin.cpp:343
void To(const core::Tensor &src, core::Tensor &dst, double scale, double offset)
Definition: Image.cpp:17
Definition: PinholeCameraIntrinsic.cpp:16
Definition: Device.h:111
void swap(open3d::core::SmallVector< T, N > &LHS, open3d::core::SmallVector< T, N > &RHS)
Implement std::swap in terms of SmallVector swap.
Definition: SmallVector.h:1378
void swap(open3d::core::SmallVectorImpl< T > &LHS, open3d::core::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
Definition: SmallVector.h:1371
Figure out the offset of the first element.
Definition: SmallVector.h:144
char FirstEl[sizeof(T)]
Definition: SmallVector.h:147
char Base[sizeof(SmallVectorBase< SmallVectorSizeType< T >>)]
Definition: SmallVector.h:146
Definition: SmallVector.h:1170