Open3D (C++ API)  0.19.0
Loading...
Searching...
No Matches
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
56namespace open3d {
57namespace core {
58// from llvm/include/llvm/Support/MemAlloc.h
59inline 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
71inline 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
83template <typename IteratorT>
85
94template <class Size_T>
96protected:
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
119public:
120 size_t size() const { return Size; }
121 size_t capacity() const { return Capacity; }
122
123 LLVM_NODISCARD bool empty() const { return !Size; }
124
125protected:
130 void set_size(size_t N) {
131 assert(N <= capacity());
132 Size = N;
133 }
134};
135
136template <class T>
138 typename std::conditional<sizeof(T) < 4 && sizeof(void *) >= 8,
139 uint64_t,
140 uint32_t>::type;
141
143template <class T, typename = void>
149
153template <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
169protected:
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
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;
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
282public:
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.
316
317 size_type size_in_bytes() const { return size() * sizeof(T); }
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
365template <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
372protected:
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
459public:
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.
479template <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.
488template <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.
499template <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
513template <typename T>
515 friend class SmallVectorTemplateCommon<T>;
516
517protected:
520 static constexpr bool TakesParamByValue = sizeof(T) <= 2 * sizeof(void *);
521
525 typename std::conditional<TakesParamByValue, T, const T &>::type;
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>
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
604public:
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
616template <typename T>
618 using SuperClass = SmallVectorTemplateBase<T>;
619
620public:
625
626protected:
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
642public:
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
656private:
657 // Make set_size() private to avoid misuse in subclasses.
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
678public:
679 void resize(size_type N) { resizeImpl<false>(N); }
680
682 void resize_for_overwrite(size_type N) { resizeImpl<true>(N); }
683
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
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
812private:
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 =
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
853public:
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
1026template <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
1063template <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
1112template <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
1169template <typename T, unsigned N>
1171 alignas(T) char InlineElts[N * sizeof(T)];
1172};
1173
1177template <typename T>
1178struct alignas(T) SmallVectorStorage<T, 0> {};
1179
1183template <typename T, unsigned N>
1185
1191template <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 =
1237 static constexpr size_t NumElementsThatFit =
1238 PreferredInlineBytes / sizeof(T);
1239 static constexpr size_t value =
1241};
1242
1259template <typename T,
1262 SmallVectorStorage<T, N> {
1263public:
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
1339template <typename T, unsigned N>
1340inline size_t capacity_in_bytes(const SmallVector<T, N> &X) {
1341 return X.capacity_in_bytes();
1342}
1343
1344template <typename RangeType>
1346 typename std::remove_const<typename std::remove_reference<decltype(
1347 *std::begin(std::declval<RangeType &>()))>::type>::type;
1348
1352template <unsigned Size, typename R>
1354 return {std::begin(Range), std::end(Range)};
1355}
1356template <typename R>
1357SmallVector<ValueTypeFromRangeType<R>,
1358 CalculateSmallVectorDefaultInlinedElements<
1359 ValueTypeFromRangeType<R>>::value>
1360to_vector(R &&Range) {
1361 return {std::begin(Range), std::end(Range)};
1362}
1363
1364} // namespace core
1365} // namespace open3d
1366
1367namespace std {
1368
1370template <typename T>
1373 LHS.swap(RHS);
1374}
1375
1377template <typename T, unsigned N>
1380 LHS.swap(RHS);
1381}
1382
1383} // end namespace std
#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
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
SmallVectorSizeType< 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
SmallVectorSizeType< 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(const SmallVector &RHS)
Definition SmallVector.h:1294
SmallVector & operator=(SmallVectorImpl< T > &&RHS)
Definition SmallVector.h:1328
SmallVector & operator=(SmallVector &&RHS)
Definition SmallVector.h:1311
SmallVector(SmallVectorImpl< T > &&RHS)
Definition SmallVector.h:1307
SmallVector()
Definition SmallVector.h:1264
~SmallVector()
Definition SmallVector.h:1266
SmallVector & operator=(std::initializer_list< T > IL)
Definition SmallVector.h:1333
SmallVector(const iterator_range< RangeTy > &R)
Definition SmallVector.h:1285
SmallVector(std::initializer_list< T > IL)
Definition SmallVector.h:1290
SmallVector(SmallVector &&RHS)
Definition SmallVector.h:1303
SmallVector & operator=(const SmallVector &RHS)
Definition SmallVector.h:1298
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
typename SuperClass::ValueParamT ValueParamT
Definition SmallVector.h:628
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
typename SuperClass::reference reference
Definition SmallVector.h:623
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
typename SuperClass::const_iterator const_iterator
Definition SmallVector.h:622
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
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
typename std::conditional< TakesParamByValue, T, const T & >::type ValueParamT
Definition SmallVector.h:524
const T * reserveForParamAndGetAddress(const T &Elt, size_t N=1)
Definition SmallVector.h:571
void push_back(ValueParamT Elt)
Definition SmallVector.h:605
void grow(size_t MinSize=0)
Definition SmallVector.h:567
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 constexpr bool TakesParamByValue
Definition SmallVector.h:520
static void destroy_range(T *, T *)
Definition SmallVector.h:530
T * reserveForParamAndGetAddress(T &Elt, size_t N=1)
Definition SmallVector.h:577
T & growAndEmplaceBack(ArgTypes &&... Args)
Definition SmallVector.h:596
static void uninitialized_move(It1 I, It1 E, It2 Dest)
Definition SmallVector.h:388
SmallVectorTemplateBase(size_t Size)
Definition SmallVector.h:376
static T && forward_value_param(T &&V)
Definition SmallVector.h:433
static void destroy_range(T *S, T *E)
Definition SmallVector.h:378
T * mallocForGrow(size_t MinSize, size_t &NewCapacity)
Definition SmallVector.h:407
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
void push_back(T &&Elt)
Definition SmallVector.h:466
const T & ValueParamT
Definition SmallVector.h:374
void pop_back()
Definition SmallVector.h:472
T & growAndEmplaceBack(ArgTypes &&... Args)
Definition SmallVector.h:447
void moveElementsForGrow(T *NewElts)
Definition SmallVector.h:489
static const T & forward_value_param(const T &V)
Definition SmallVector.h:434
static constexpr bool TakesParamByValue
Definition SmallVector.h:373
void growAndAssign(size_t NumElts, const T &Elt)
Definition SmallVector.h:436
T * reserveForParamAndGetAddress(T &Elt, size_t N=1)
Definition SmallVector.h:428
void push_back(const T &Elt)
Definition SmallVector.h:460
const T * reserveForParamAndGetAddress(const T &Elt, size_t N=1)
Definition SmallVector.h:422
void grow(size_t MinSize=0)
Definition SmallVector.h:480
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
static const T * reserveForParamAndGetAddressImpl(U *This, const T &Elt, size_t N)
Definition SmallVector.h:264
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
size_t size() const
Definition SmallVector.h:120
reverse_iterator rbegin()
Definition SmallVector.h:308
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
LLVM_NODISCARD bool empty() const
Definition SmallVector.h:123
size_t capacity() const
Definition SmallVector.h:121
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
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:137
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Definition SmallVector.h:1353
size_t capacity_in_bytes(const SmallVector< T, N > &X)
Definition SmallVector.h:1340
void * safe_malloc(size_t Sz)
Definition SmallVector.h:59
typename std::remove_const< typename std::remove_reference< decltype( *std::begin(std::declval< RangeType & >()))>::type >::type ValueTypeFromRangeType
Definition SmallVector.h:1345
Definition PinholeCameraIntrinsic.cpp:16
Definition Device.h:111
void swap(open3d::core::SmallVectorImpl< T > &LHS, open3d::core::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
Definition SmallVector.h:1371
static constexpr size_t value
Definition SmallVector.h:1239
static constexpr size_t kPreferredSmallVectorSizeof
Definition SmallVector.h:1200
static constexpr size_t NumElementsThatFit
Definition SmallVector.h:1237
static constexpr size_t PreferredInlineBytes
Definition SmallVector.h:1235
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
char InlineElts[N *sizeof(T)]
Definition SmallVector.h:1171