WPILibC++ 2023.4.3
SmallVector.h
Go to the documentation of this file.
1//===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// /file
10/// This file defines the SmallVector class.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef WPIUTIL_WPI_SMALLVECTOR_H
15#define WPIUTIL_WPI_SMALLVECTOR_H
16
17// This file uses std::memcpy() to copy std::pair<unsigned int, unsigned int>.
18// That type is POD, but the standard doesn't guarantee that. GCC doesn't treat
19// the type as POD so it throws a warning. We want to consider this a warning
20// instead of an error.
21#if __GNUC__ >= 8
22#pragma GCC diagnostic warning "-Wclass-memaccess"
23#endif
24
25#include "wpi/Compiler.h"
26#include "wpi/type_traits.h"
27#include <algorithm>
28#include <cassert>
29#include <cstddef>
30#include <cstdlib>
31#include <cstring>
32#include <functional>
33#include <initializer_list>
34#include <iterator>
35#include <limits>
36#include <memory>
37#include <new>
38#include <type_traits>
39#include <utility>
40
41namespace wpi {
42
43template <typename IteratorT> class iterator_range;
44
45/// This is all the stuff common to all SmallVectors.
46///
47/// The template parameter specifies the type which should be used to hold the
48/// Size and Capacity of the SmallVector, so it can be adjusted.
49/// Using 32 bit size is desirable to shrink the size of the SmallVector.
50/// Using 64 bit size is desirable for cases like SmallVector<char>, where a
51/// 32 bit size would limit the vector to ~4GB. SmallVectors are used for
52/// buffering bitcode output - which can exceed 4GB.
54protected:
55 void *BeginX;
56 unsigned Size = 0, Capacity;
57
58 /// The maximum value of the Size_T used.
59 static constexpr size_t SizeTypeMax() {
61 }
62
63 SmallVectorBase() = delete;
64 SmallVectorBase(void *FirstEl, size_t TotalCapacity)
65 : BeginX(FirstEl), Capacity(static_cast<unsigned>(TotalCapacity)) {}
66
67 /// This is a helper for \a grow() that's out of line to reduce code
68 /// duplication. This function will report a fatal error if it can't grow at
69 /// least to \p MinSize.
70 void *mallocForGrow(size_t MinSize, size_t TSize, size_t &NewCapacity);
71
72 /// This is an implementation of the grow() method which only works
73 /// on POD-like data types and is out of line to reduce code duplication.
74 /// This function will report a fatal error if it cannot increase capacity.
75 void grow_pod(void *FirstEl, size_t MinSize, size_t TSize);
76
77public:
78 size_t size() const { return Size; }
79 size_t capacity() const { return Capacity; }
80
81 LLVM_NODISCARD bool empty() const { return !Size; }
82
83protected:
84 /// Set the array size to \p N, which the current array must have enough
85 /// capacity for.
86 ///
87 /// This does not construct or destroy any elements in the vector.
88 void set_size(size_t N) {
89 assert(N <= capacity());
90 Size = static_cast<unsigned>(N);
91 }
92};
93
94/// Figure out the offset of the first element.
95template <class T, typename = void> struct SmallVectorAlignmentAndSize {
96 alignas(SmallVectorBase) char Base[sizeof(
98 alignas(T) char FirstEl[sizeof(T)];
99};
100
101/// This is the part of SmallVectorTemplateBase which does not depend on whether
102/// the type T is a POD. The extra dummy template argument is used by ArrayRef
103/// to avoid unnecessarily requiring T to be complete.
104template <typename T, typename = void>
106 : public SmallVectorBase {
107 using Base = SmallVectorBase;
108
109 /// Find the address of the first element. For this pointer math to be valid
110 /// with small-size of 0 for T with lots of alignment, it's important that
111 /// SmallVectorStorage is properly-aligned even for small-size of 0.
112 void *getFirstEl() const {
113 return const_cast<void *>(reinterpret_cast<const void *>(
114 reinterpret_cast<const char *>(this) +
115 offsetof(SmallVectorAlignmentAndSize<T>, FirstEl)));
116 }
117 // Space after 'FirstEl' is clobbered, do not add any instance vars after it.
118
119protected:
120 SmallVectorTemplateCommon(size_t Size) : Base(getFirstEl(), Size) {}
121
122 void grow_pod(size_t MinSize, size_t TSize) {
123 Base::grow_pod(getFirstEl(), MinSize, TSize);
124 }
125
126 /// Return true if this is a smallvector which has not had dynamic
127 /// memory allocated for it.
128 bool isSmall() const { return this->BeginX == getFirstEl(); }
129
130 /// Put this vector in a state of being small.
132 this->BeginX = getFirstEl();
133 this->Size = this->Capacity = 0; // FIXME: Setting Capacity to 0 is suspect.
134 }
135
136 /// Return true if V is an internal reference to the given range.
137 bool isReferenceToRange(const void *V, const void *First, const void *Last) const {
138 // Use std::less to avoid UB.
139 std::less<> LessThan;
140 return !LessThan(V, First) && LessThan(V, Last);
141 }
142
143 /// Return true if V is an internal reference to this vector.
144 bool isReferenceToStorage(const void *V) const {
145 return isReferenceToRange(V, this->begin(), this->end());
146 }
147
148 /// Return true if First and Last form a valid (possibly empty) range in this
149 /// vector's storage.
150 bool isRangeInStorage(const void *First, const void *Last) const {
151 // Use std::less to avoid UB.
152 std::less<> LessThan;
153 return !LessThan(First, this->begin()) && !LessThan(Last, First) &&
154 !LessThan(this->end(), Last);
155 }
156
157 /// Return true unless Elt will be invalidated by resizing the vector to
158 /// NewSize.
159 bool isSafeToReferenceAfterResize(const void *Elt, size_t NewSize) {
160 // Past the end.
162 return true;
163
164 // Return false if Elt will be destroyed by shrinking.
165 if (NewSize <= this->size())
166 return Elt < this->begin() + NewSize;
167
168 // Return false if we need to grow.
169 return NewSize <= this->capacity();
170 }
171
172 /// Check whether Elt will be invalidated by resizing the vector to NewSize.
173 void assertSafeToReferenceAfterResize(const void *Elt, size_t NewSize) {
174 assert(isSafeToReferenceAfterResize(Elt, NewSize) &&
175 "Attempting to reference an element of the vector in an operation "
176 "that invalidates it");
177 }
178
179 /// Check whether Elt will be invalidated by increasing the size of the
180 /// vector by N.
181 void assertSafeToAdd(const void *Elt, size_t N = 1) {
182 this->assertSafeToReferenceAfterResize(Elt, this->size() + N);
183 }
184
185 /// Check whether any part of the range will be invalidated by clearing.
186 void assertSafeToReferenceAfterClear(const T *From, const T *To) {
187 if (From == To)
188 return;
190 this->assertSafeToReferenceAfterResize(To - 1, 0);
191 }
192 template <
193 class ItTy,
194 std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value,
195 bool> = false>
197
198 /// Check whether any part of the range will be invalidated by growing.
199 void assertSafeToAddRange(const T *From, const T *To) {
200 if (From == To)
201 return;
202 this->assertSafeToAdd(From, To - From);
203 this->assertSafeToAdd(To - 1, To - From);
204 }
205 template <
206 class ItTy,
207 std::enable_if_t<!std::is_same<std::remove_const_t<ItTy>, T *>::value,
208 bool> = false>
209 void assertSafeToAddRange(ItTy, ItTy) {}
210
211 /// Reserve enough space to add one element, and return the updated element
212 /// pointer in case it was a reference to the storage.
213 template <class U>
214 static const T *reserveForParamAndGetAddressImpl(U *This, const T &Elt,
215 size_t N) {
216 size_t NewSize = This->size() + N;
217 if (LLVM_LIKELY(NewSize <= This->capacity()))
218 return &Elt;
219
220 bool ReferencesStorage = false;
221 int64_t Index = -1;
222 if (!U::TakesParamByValue) {
223 if (LLVM_UNLIKELY(This->isReferenceToStorage(&Elt))) {
224 ReferencesStorage = true;
225 Index = &Elt - This->begin();
226 }
227 }
228 This->grow(NewSize);
229 return ReferencesStorage ? This->begin() + Index : &Elt;
230 }
231
232public:
233 using size_type = size_t;
234 using difference_type = ptrdiff_t;
235 using value_type = T;
236 using iterator = T *;
237 using const_iterator = const T *;
238
239 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
240 using reverse_iterator = std::reverse_iterator<iterator>;
241
242 using reference = T &;
243 using const_reference = const T &;
244 using pointer = T *;
245 using const_pointer = const T *;
246
250
251 // forward iterator creation methods.
252 iterator begin() { return (iterator)this->BeginX; }
253 const_iterator begin() const { return (const_iterator)this->BeginX; }
254 iterator end() { return begin() + size(); }
255 const_iterator end() const { return begin() + size(); }
256
257 // reverse iterator creation methods.
262
263 size_type size_in_bytes() const { return size() * sizeof(T); }
265 return (std::min)(this->SizeTypeMax(), size_type(-1) / sizeof(T));
266 }
267
268 size_t capacity_in_bytes() const { return capacity() * sizeof(T); }
269
270 /// Return a pointer to the vector's buffer, even if empty().
271 pointer data() { return pointer(begin()); }
272 /// Return a pointer to the vector's buffer, even if empty().
273 const_pointer data() const { return const_pointer(begin()); }
274
276 assert(idx < size());
277 return begin()[idx];
278 }
280 assert(idx < size());
281 return begin()[idx];
282 }
283
285 assert(!empty());
286 return begin()[0];
287 }
289 assert(!empty());
290 return begin()[0];
291 }
292
294 assert(!empty());
295 return end()[-1];
296 }
298 assert(!empty());
299 return end()[-1];
300 }
301};
302
303/// SmallVectorTemplateBase<TriviallyCopyable = false> - This is where we put
304/// method implementations that are designed to work with non-trivial T's.
305///
306/// We approximate is_trivially_copyable with trivial move/copy construction and
307/// trivial destruction. While the standard doesn't specify that you're allowed
308/// copy these types with memcpy, there is no way for the type to observe this.
309/// This catches the important case of std::pair<POD, POD>, which is not
310/// trivially assignable.
311template <typename T, bool = (is_trivially_copy_constructible<T>::value) &&
312 (is_trivially_move_constructible<T>::value) &&
313 std::is_trivially_destructible<T>::value>
315 friend class SmallVectorTemplateCommon<T>;
316
317protected:
318 static constexpr bool TakesParamByValue = false;
319 using ValueParamT = const T &;
320
322
323 static void destroy_range(T *S, T *E) {
324 while (S != E) {
325 --E;
326 E->~T();
327 }
328 }
329
330 /// Move the range [I, E) into the uninitialized memory starting with "Dest",
331 /// constructing elements as needed.
332 template<typename It1, typename It2>
333 static void uninitialized_move(It1 I, It1 E, It2 Dest) {
334 std::uninitialized_copy(std::make_move_iterator(I),
335 std::make_move_iterator(E), Dest);
336 }
337
338 /// Copy the range [I, E) onto the uninitialized memory starting with "Dest",
339 /// constructing elements as needed.
340 template<typename It1, typename It2>
341 static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
342 std::uninitialized_copy(I, E, Dest);
343 }
344
345 /// Grow the allocated memory (without initializing new elements), doubling
346 /// the size of the allocated memory. Guarantees space for at least one more
347 /// element, or MinSize more elements if specified.
348 void grow(size_t MinSize = 0);
349
350 /// Create a new allocation big enough for \p MinSize and pass back its size
351 /// in \p NewCapacity. This is the first section of \a grow().
352 T *mallocForGrow(size_t MinSize, size_t &NewCapacity) {
353 return static_cast<T *>(
355 MinSize, sizeof(T), NewCapacity));
356 }
357
358 /// Move existing elements over to the new allocation \p NewElts, the middle
359 /// section of \a grow().
360 void moveElementsForGrow(T *NewElts);
361
362 /// Transfer ownership of the allocation, finishing up \a grow().
363 void takeAllocationForGrow(T *NewElts, size_t NewCapacity);
364
365 /// Reserve enough space to add one element, and return the updated element
366 /// pointer in case it was a reference to the storage.
367 const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) {
368 return this->reserveForParamAndGetAddressImpl(this, Elt, N);
369 }
370
371 /// Reserve enough space to add one element, and return the updated element
372 /// pointer in case it was a reference to the storage.
373 T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) {
374 return const_cast<T *>(
375 this->reserveForParamAndGetAddressImpl(this, Elt, N));
376 }
377
378 static T &&forward_value_param(T &&V) { return std::move(V); }
379 static const T &forward_value_param(const T &V) { return V; }
380
381 void growAndAssign(size_t NumElts, const T &Elt) {
382 // Grow manually in case Elt is an internal reference.
383 size_t NewCapacity;
384 T *NewElts = mallocForGrow(NumElts, NewCapacity);
385 std::uninitialized_fill_n(NewElts, NumElts, Elt);
386 this->destroy_range(this->begin(), this->end());
387 takeAllocationForGrow(NewElts, NewCapacity);
388 this->set_size(NumElts);
389 }
390
391 template <typename... ArgTypes> T &growAndEmplaceBack(ArgTypes &&... Args) {
392 // Grow manually in case one of Args is an internal reference.
393 size_t NewCapacity;
394 T *NewElts = mallocForGrow(0, NewCapacity);
395 ::new ((void *)(NewElts + this->size())) T(std::forward<ArgTypes>(Args)...);
396 moveElementsForGrow(NewElts);
397 takeAllocationForGrow(NewElts, NewCapacity);
398 this->set_size(this->size() + 1);
399 return this->back();
400 }
401
402public:
403 void push_back(const T &Elt) {
404 const T *EltPtr = reserveForParamAndGetAddress(Elt);
405 ::new ((void *)this->end()) T(*EltPtr);
406 this->set_size(this->size() + 1);
407 }
408
409 void push_back(T &&Elt) {
410 T *EltPtr = reserveForParamAndGetAddress(Elt);
411 ::new ((void *)this->end()) T(::std::move(*EltPtr));
412 this->set_size(this->size() + 1);
413 }
414
415 void pop_back() {
416 this->set_size(this->size() - 1);
417 this->end()->~T();
418 }
419};
420
421// Define this out-of-line to dissuade the C++ compiler from inlining it.
422template <typename T, bool TriviallyCopyable>
424 size_t NewCapacity;
425 T *NewElts = mallocForGrow(MinSize, NewCapacity);
426 moveElementsForGrow(NewElts);
427 takeAllocationForGrow(NewElts, NewCapacity);
428}
429
430// Define this out-of-line to dissuade the C++ compiler from inlining it.
431template <typename T, bool TriviallyCopyable>
433 T *NewElts) {
434 // Move the elements over.
435 this->uninitialized_move(this->begin(), this->end(), NewElts);
436
437 // Destroy the original elements.
438 destroy_range(this->begin(), this->end());
439}
440
441// Define this out-of-line to dissuade the C++ compiler from inlining it.
442template <typename T, bool TriviallyCopyable>
444 T *NewElts, size_t NewCapacity) {
445 // If this wasn't grown from the inline copy, deallocate the old space.
446 if (!this->isSmall())
447 free(this->begin());
448
449 this->BeginX = NewElts;
450 this->Capacity = static_cast<unsigned>(NewCapacity);
451}
452
453/// SmallVectorTemplateBase<TriviallyCopyable = true> - This is where we put
454/// method implementations that are designed to work with trivially copyable
455/// T's. This allows using memcpy in place of copy/move construction and
456/// skipping destruction.
457template <typename T>
459 friend class SmallVectorTemplateCommon<T>;
460
461protected:
462 /// True if it's cheap enough to take parameters by value. Doing so avoids
463 /// overhead related to mitigations for reference invalidation.
464 static constexpr bool TakesParamByValue = sizeof(T) <= 2 * sizeof(void *);
465
466 /// Either const T& or T, depending on whether it's cheap enough to take
467 /// parameters by value.
470
472
473 // No need to do a destroy loop for POD's.
474 static void destroy_range(T *, T *) {}
475
476 /// Move the range [I, E) onto the uninitialized memory
477 /// starting with "Dest", constructing elements into it as needed.
478 template<typename It1, typename It2>
479 static void uninitialized_move(It1 I, It1 E, It2 Dest) {
480 // Just do a copy.
481 uninitialized_copy(I, E, Dest);
482 }
483
484 /// Copy the range [I, E) onto the uninitialized memory
485 /// starting with "Dest", constructing elements into it as needed.
486 template<typename It1, typename It2>
487 static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
488 // Arbitrary iterator types; just use the basic implementation.
489 std::uninitialized_copy(I, E, Dest);
490 }
491
492 /// Copy the range [I, E) onto the uninitialized memory
493 /// starting with "Dest", constructing elements into it as needed.
494 template <typename T1, typename T2>
496 T1 *I, T1 *E, T2 *Dest,
497 std::enable_if_t<std::is_same<typename std::remove_const<T1>::type,
498 T2>::value> * = nullptr) {
499 // Use memcpy for PODs iterated by pointers (which includes SmallVector
500 // iterators): std::uninitialized_copy optimizes to memmove, but we can
501 // use memcpy here. Note that I and E are iterators and thus might be
502 // invalid for memcpy if they are equal.
503 if (I != E)
504 memcpy(reinterpret_cast<void *>(Dest), I, (E - I) * sizeof(T));
505 }
506
507 /// Double the size of the allocated memory, guaranteeing space for at
508 /// least one more element or MinSize if specified.
509 void grow(size_t MinSize = 0) { this->grow_pod(MinSize, sizeof(T)); }
510
511 /// Reserve enough space to add one element, and return the updated element
512 /// pointer in case it was a reference to the storage.
513 const T *reserveForParamAndGetAddress(const T &Elt, size_t N = 1) {
514 return this->reserveForParamAndGetAddressImpl(this, Elt, N);
515 }
516
517 /// Reserve enough space to add one element, and return the updated element
518 /// pointer in case it was a reference to the storage.
519 T *reserveForParamAndGetAddress(T &Elt, size_t N = 1) {
520 return const_cast<T *>(
521 this->reserveForParamAndGetAddressImpl(this, Elt, N));
522 }
523
524 /// Copy \p V or return a reference, depending on \a ValueParamT.
526
527 void growAndAssign(size_t NumElts, T Elt) {
528 // Elt has been copied in case it's an internal reference, side-stepping
529 // reference invalidation problems without losing the realloc optimization.
530 this->set_size(0);
531 this->grow(NumElts);
532 std::uninitialized_fill_n(this->begin(), NumElts, Elt);
533 this->set_size(NumElts);
534 }
535
536 template <typename... ArgTypes> T &growAndEmplaceBack(ArgTypes &&... Args) {
537 // Use push_back with a copy in case Args has an internal reference,
538 // side-stepping reference invalidation problems without losing the realloc
539 // optimization.
540 push_back(T(std::forward<ArgTypes>(Args)...));
541 return this->back();
542 }
543
544public:
546 const T *EltPtr = reserveForParamAndGetAddress(Elt);
547 memcpy(reinterpret_cast<void *>(this->end()), EltPtr, sizeof(T));
548 this->set_size(this->size() + 1);
549 }
550
551 void pop_back() { this->set_size(this->size() - 1); }
552};
553
554/// This class consists of common code factored out of the SmallVector class to
555/// reduce code duplication based on the SmallVector 'N' template parameter.
556template <typename T>
559
560public:
565
566protected:
569
570 // Default ctor - Initialize to empty.
571 explicit SmallVectorImpl(unsigned N)
572 : SmallVectorTemplateBase<T>(N) {}
573
575 this->destroy_range(this->begin(), this->end());
576 if (!this->isSmall())
577 free(this->begin());
578 this->BeginX = RHS.BeginX;
579 this->Size = RHS.Size;
580 this->Capacity = RHS.Capacity;
581 RHS.resetToSmall();
582 }
583
584public:
586
588 // Subclass has already destructed this vector's elements.
589 // If this wasn't grown from the inline copy, deallocate the old space.
590 if (!this->isSmall())
591 free(this->begin());
592 }
593
594 void clear() {
595 this->destroy_range(this->begin(), this->end());
596 this->Size = 0;
597 }
598
599private:
600 // Make set_size() private to avoid misuse in subclasses.
602
603 template <bool ForOverwrite> void resizeImpl(size_type N) {
604 if (N == this->size())
605 return;
606
607 if (N < this->size()) {
608 this->truncate(N);
609 return;
610 }
611
612 this->reserve(N);
613 for (auto I = this->end(), E = this->begin() + N; I != E; ++I)
614 if (ForOverwrite)
615 new (&*I) T;
616 else
617 new (&*I) T();
618 this->set_size(N);
619 }
620
621public:
622 void resize(size_type N) { resizeImpl<false>(N); }
623
624 /// Like resize, but \ref T is POD, the new values won't be initialized.
625 void resize_for_overwrite(size_type N) { resizeImpl<true>(N); }
626
627 /// Like resize, but requires that \p N is less than \a size().
629 assert(this->size() >= N && "Cannot increase size with truncate");
630 this->destroy_range(this->begin() + N, this->end());
631 this->set_size(N);
632 }
633
635 if (N == this->size())
636 return;
637
638 if (N < this->size()) {
639 this->truncate(N);
640 return;
641 }
642
643 // N > this->size(). Defer to append.
644 this->append(N - this->size(), NV);
645 }
646
648 if (this->capacity() < N)
649 this->grow(N);
650 }
651
652 void pop_back_n(size_type NumItems) {
653 assert(this->size() >= NumItems);
654 truncate(this->size() - NumItems);
655 }
656
658 T Result = ::std::move(this->back());
659 this->pop_back();
660 return Result;
661 }
662
664
665 /// Add the specified range to the end of the SmallVector.
666 template <typename in_iter,
667 typename = std::enable_if_t<std::is_convertible<
668 typename std::iterator_traits<in_iter>::iterator_category,
669 std::input_iterator_tag>::value>>
670 void append(in_iter in_start, in_iter in_end) {
671 this->assertSafeToAddRange(in_start, in_end);
672 size_type NumInputs = std::distance(in_start, in_end);
673 this->reserve(this->size() + NumInputs);
674 this->uninitialized_copy(in_start, in_end, this->end());
675 this->set_size(this->size() + NumInputs);
676 }
677
678 /// Append \p NumInputs copies of \p Elt to the end.
679 void append(size_type NumInputs, ValueParamT Elt) {
680 const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumInputs);
681 std::uninitialized_fill_n(this->end(), NumInputs, *EltPtr);
682 this->set_size(this->size() + NumInputs);
683 }
684
685 void append(std::initializer_list<T> IL) {
686 append(IL.begin(), IL.end());
687 }
688
689 void append(const SmallVectorImpl &RHS) { append(RHS.begin(), RHS.end()); }
690
691 void assign(size_type NumElts, ValueParamT Elt) {
692 // Note that Elt could be an internal reference.
693 if (NumElts > this->capacity()) {
694 this->growAndAssign(NumElts, Elt);
695 return;
696 }
697
698 // Assign over existing elements.
699 std::fill_n(this->begin(), (std::min)(NumElts, this->size()), Elt);
700 if (NumElts > this->size())
701 std::uninitialized_fill_n(this->end(), NumElts - this->size(), Elt);
702 else if (NumElts < this->size())
703 this->destroy_range(this->begin() + NumElts, this->end());
704 this->set_size(NumElts);
705 }
706
707 // FIXME: Consider assigning over existing elements, rather than clearing &
708 // re-initializing them - for all assign(...) variants.
709
710 template <typename in_iter,
711 typename = std::enable_if_t<std::is_convertible<
712 typename std::iterator_traits<in_iter>::iterator_category,
713 std::input_iterator_tag>::value>>
714 void assign(in_iter in_start, in_iter in_end) {
715 this->assertSafeToReferenceAfterClear(in_start, in_end);
716 clear();
717 append(in_start, in_end);
718 }
719
720 void assign(std::initializer_list<T> IL) {
721 clear();
722 append(IL);
723 }
724
725 void assign(const SmallVectorImpl &RHS) { assign(RHS.begin(), RHS.end()); }
726
728 // Just cast away constness because this is a non-const member function.
729 iterator I = const_cast<iterator>(CI);
730
731 assert(this->isReferenceToStorage(CI) && "Iterator to erase is out of bounds.");
732
733 iterator N = I;
734 // Shift all elts down one.
735 std::move(I+1, this->end(), I);
736 // Drop the last elt.
737 this->pop_back();
738 return(N);
739 }
740
742 // Just cast away constness because this is a non-const member function.
743 iterator S = const_cast<iterator>(CS);
744 iterator E = const_cast<iterator>(CE);
745
746 assert(this->isRangeInStorage(S, E) && "Range to erase is out of bounds.");
747
748 iterator N = S;
749 // Shift all elts down.
750 iterator I = std::move(E, this->end(), S);
751 // Drop the last elts.
752 this->destroy_range(I, this->end());
753 this->set_size(I - this->begin());
754 return(N);
755 }
756
757private:
758 template <class ArgType> iterator insert_one_impl(iterator I, ArgType &&Elt) {
759 // Callers ensure that ArgType is derived from T.
760 static_assert(
761 std::is_same<std::remove_const_t<std::remove_reference_t<ArgType>>,
762 T>::value,
763 "ArgType must be derived from T!");
764
765 if (I == this->end()) { // Important special case for empty vector.
766 this->push_back(::std::forward<ArgType>(Elt));
767 return this->end()-1;
768 }
769
770 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
771
772 // Grow if necessary.
773 size_t Index = I - this->begin();
774 std::remove_reference_t<ArgType> *EltPtr =
776 I = this->begin() + Index;
777
778 ::new ((void*) this->end()) T(::std::move(this->back()));
779 // Push everything else over.
780 std::move_backward(I, this->end()-1, this->end());
781 this->set_size(this->size() + 1);
782
783 // If we just moved the element we're inserting, be sure to update
784 // the reference (never happens if TakesParamByValue).
785 static_assert(!TakesParamByValue || std::is_same<ArgType, T>::value,
786 "ArgType must be 'T' when taking by value!");
787 if (!TakesParamByValue && this->isReferenceToRange(EltPtr, I, this->end()))
788 ++EltPtr;
789
790 *I = ::std::forward<ArgType>(*EltPtr);
791 return I;
792 }
793
794public:
796 return insert_one_impl(I, this->forward_value_param(std::move(Elt)));
797 }
798
799 iterator insert(iterator I, const T &Elt) {
800 return insert_one_impl(I, this->forward_value_param(Elt));
801 }
802
804 // Convert iterator to elt# to avoid invalidating iterator when we reserve()
805 size_t InsertElt = I - this->begin();
806
807 if (I == this->end()) { // Important special case for empty vector.
808 append(NumToInsert, Elt);
809 return this->begin()+InsertElt;
810 }
811
812 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
813
814 // Ensure there is enough space, and get the (maybe updated) address of
815 // Elt.
816 const T *EltPtr = this->reserveForParamAndGetAddress(Elt, NumToInsert);
817
818 // Uninvalidate the iterator.
819 I = this->begin()+InsertElt;
820
821 // If there are more elements between the insertion point and the end of the
822 // range than there are being inserted, we can use a simple approach to
823 // insertion. Since we already reserved space, we know that this won't
824 // reallocate the vector.
825 if (size_t(this->end()-I) >= NumToInsert) {
826 T *OldEnd = this->end();
827 append(std::move_iterator<iterator>(this->end() - NumToInsert),
828 std::move_iterator<iterator>(this->end()));
829
830 // Copy the existing elements that get replaced.
831 std::move_backward(I, OldEnd-NumToInsert, OldEnd);
832
833 // If we just moved the element we're inserting, be sure to update
834 // the reference (never happens if TakesParamByValue).
835 if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
836 EltPtr += NumToInsert;
837
838 std::fill_n(I, NumToInsert, *EltPtr);
839 return I;
840 }
841
842 // Otherwise, we're inserting more elements than exist already, and we're
843 // not inserting at the end.
844
845 // Move over the elements that we're about to overwrite.
846 T *OldEnd = this->end();
847 this->set_size(this->size() + NumToInsert);
848 size_t NumOverwritten = OldEnd-I;
849 this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
850
851 // If we just moved the element we're inserting, be sure to update
852 // the reference (never happens if TakesParamByValue).
853 if (!TakesParamByValue && I <= EltPtr && EltPtr < this->end())
854 EltPtr += NumToInsert;
855
856 // Replace the overwritten part.
857 std::fill_n(I, NumOverwritten, *EltPtr);
858
859 // Insert the non-overwritten middle part.
860 std::uninitialized_fill_n(OldEnd, NumToInsert - NumOverwritten, *EltPtr);
861 return I;
862 }
863
864 template <typename ItTy,
865 typename = std::enable_if_t<std::is_convertible<
866 typename std::iterator_traits<ItTy>::iterator_category,
867 std::input_iterator_tag>::value>>
868 iterator insert(iterator I, ItTy From, ItTy To) {
869 // Convert iterator to elt# to avoid invalidating iterator when we reserve()
870 size_t InsertElt = I - this->begin();
871
872 if (I == this->end()) { // Important special case for empty vector.
873 append(From, To);
874 return this->begin()+InsertElt;
875 }
876
877 assert(this->isReferenceToStorage(I) && "Insertion iterator is out of bounds.");
878
879 // Check that the reserve that follows doesn't invalidate the iterators.
880 this->assertSafeToAddRange(From, To);
881
882 size_t NumToInsert = std::distance(From, To);
883
884 // Ensure there is enough space.
885 reserve(this->size() + NumToInsert);
886
887 // Uninvalidate the iterator.
888 I = this->begin()+InsertElt;
889
890 // If there are more elements between the insertion point and the end of the
891 // range than there are being inserted, we can use a simple approach to
892 // insertion. Since we already reserved space, we know that this won't
893 // reallocate the vector.
894 if (size_t(this->end()-I) >= NumToInsert) {
895 T *OldEnd = this->end();
896 append(std::move_iterator<iterator>(this->end() - NumToInsert),
897 std::move_iterator<iterator>(this->end()));
898
899 // Copy the existing elements that get replaced.
900 std::move_backward(I, OldEnd-NumToInsert, OldEnd);
901
902 std::copy(From, To, I);
903 return I;
904 }
905
906 // Otherwise, we're inserting more elements than exist already, and we're
907 // not inserting at the end.
908
909 // Move over the elements that we're about to overwrite.
910 T *OldEnd = this->end();
911 this->set_size(this->size() + NumToInsert);
912 size_t NumOverwritten = OldEnd-I;
913 this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
914
915 // Replace the overwritten part.
916 for (T *J = I; NumOverwritten > 0; --NumOverwritten) {
917 *J = *From;
918 ++J; ++From;
919 }
920
921 // Insert the non-overwritten middle part.
922 this->uninitialized_copy(From, To, OldEnd);
923 return I;
924 }
925
926 void insert(iterator I, std::initializer_list<T> IL) {
927 insert(I, IL.begin(), IL.end());
928 }
929
930 template <typename... ArgTypes> reference emplace_back(ArgTypes &&... Args) {
931 if (LLVM_UNLIKELY(this->size() >= this->capacity()))
932 return this->growAndEmplaceBack(std::forward<ArgTypes>(Args)...);
933
934 ::new ((void *)this->end()) T(std::forward<ArgTypes>(Args)...);
935 this->set_size(this->size() + 1);
936 return this->back();
937 }
938
940
942
943 bool operator==(const SmallVectorImpl &RHS) const {
944 if (this->size() != RHS.size()) return false;
945 return std::equal(this->begin(), this->end(), RHS.begin());
946 }
947 bool operator!=(const SmallVectorImpl &RHS) const {
948 return !(*this == RHS);
949 }
950
951 bool operator<(const SmallVectorImpl &RHS) const {
952 return std::lexicographical_compare(this->begin(), this->end(),
953 RHS.begin(), RHS.end());
954 }
955};
956
957template <typename T>
959 if (this == &RHS) return;
960
961 // We can only avoid copying elements if neither vector is small.
962 if (!this->isSmall() && !RHS.isSmall()) {
963 std::swap(this->BeginX, RHS.BeginX);
964 std::swap(this->Size, RHS.Size);
965 std::swap(this->Capacity, RHS.Capacity);
966 return;
967 }
968 this->reserve(RHS.size());
969 RHS.reserve(this->size());
970
971 // Swap the shared elements.
972 size_t NumShared = this->size();
973 if (NumShared > RHS.size()) NumShared = RHS.size();
974 for (size_type i = 0; i != NumShared; ++i)
975 std::swap((*this)[i], RHS[i]);
976
977 // Copy over the extra elts.
978 if (this->size() > RHS.size()) {
979 size_t EltDiff = this->size() - RHS.size();
980 this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end());
981 RHS.set_size(RHS.size() + EltDiff);
982 this->destroy_range(this->begin()+NumShared, this->end());
983 this->set_size(NumShared);
984 } else if (RHS.size() > this->size()) {
985 size_t EltDiff = RHS.size() - this->size();
986 this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end());
987 this->set_size(this->size() + EltDiff);
988 this->destroy_range(RHS.begin()+NumShared, RHS.end());
989 RHS.set_size(NumShared);
990 }
991}
992
993template <typename T>
995 operator=(const SmallVectorImpl<T> &RHS) {
996 // Avoid self-assignment.
997 if (this == &RHS) return *this;
998
999 // If we already have sufficient space, assign the common elements, then
1000 // destroy any excess.
1001 size_t RHSSize = RHS.size();
1002 size_t CurSize = this->size();
1003 if (CurSize >= RHSSize) {
1004 // Assign common elements.
1005 iterator NewEnd;
1006 if (RHSSize)
1007 NewEnd = std::copy(RHS.begin(), RHS.begin()+RHSSize, this->begin());
1008 else
1009 NewEnd = this->begin();
1010
1011 // Destroy excess elements.
1012 this->destroy_range(NewEnd, this->end());
1013
1014 // Trim.
1015 this->set_size(RHSSize);
1016 return *this;
1017 }
1018
1019 // If we have to grow to have enough elements, destroy the current elements.
1020 // This allows us to avoid copying them during the grow.
1021 // FIXME: don't do this if they're efficiently moveable.
1022 if (this->capacity() < RHSSize) {
1023 // Destroy current elements.
1024 this->clear();
1025 CurSize = 0;
1026 this->grow(RHSSize);
1027 } else if (CurSize) {
1028 // Otherwise, use assignment for the already-constructed elements.
1029 std::copy(RHS.begin(), RHS.begin()+CurSize, this->begin());
1030 }
1031
1032 // Copy construct the new elements in place.
1033 this->uninitialized_copy(RHS.begin()+CurSize, RHS.end(),
1034 this->begin()+CurSize);
1035
1036 // Set end.
1037 this->set_size(RHSSize);
1038 return *this;
1039}
1040
1041template <typename T>
1043 // Avoid self-assignment.
1044 if (this == &RHS) return *this;
1045
1046 // If the RHS isn't small, clear this vector and then steal its buffer.
1047 if (!RHS.isSmall()) {
1048 this->assignRemote(std::move(RHS));
1049 return *this;
1050 }
1051
1052 // If we already have sufficient space, assign the common elements, then
1053 // destroy any excess.
1054 size_t RHSSize = RHS.size();
1055 size_t CurSize = this->size();
1056 if (CurSize >= RHSSize) {
1057 // Assign common elements.
1058 iterator NewEnd = this->begin();
1059 if (RHSSize)
1060 NewEnd = std::move(RHS.begin(), RHS.end(), NewEnd);
1061
1062 // Destroy excess elements and trim the bounds.
1063 this->destroy_range(NewEnd, this->end());
1064 this->set_size(RHSSize);
1065
1066 // Clear the RHS.
1067 RHS.clear();
1068
1069 return *this;
1070 }
1071
1072 // If we have to grow to have enough elements, destroy the current elements.
1073 // This allows us to avoid copying them during the grow.
1074 // FIXME: this may not actually make any sense if we can efficiently move
1075 // elements.
1076 if (this->capacity() < RHSSize) {
1077 // Destroy current elements.
1078 this->clear();
1079 CurSize = 0;
1080 this->grow(RHSSize);
1081 } else if (CurSize) {
1082 // Otherwise, use assignment for the already-constructed elements.
1083 std::move(RHS.begin(), RHS.begin()+CurSize, this->begin());
1084 }
1085
1086 // Move-construct the new elements in place.
1087 this->uninitialized_move(RHS.begin()+CurSize, RHS.end(),
1088 this->begin()+CurSize);
1089
1090 // Set end.
1091 this->set_size(RHSSize);
1092
1093 RHS.clear();
1094 return *this;
1095}
1096
1097/// Storage for the SmallVector elements. This is specialized for the N=0 case
1098/// to avoid allocating unnecessary storage.
1099template <typename T, unsigned N>
1101 alignas(T) char InlineElts[N * sizeof(T)];
1102};
1103
1104/// We need the storage to be properly aligned even for small-size of 0 so that
1105/// the pointer math in \a SmallVectorTemplateCommon::getFirstEl() is
1106/// well-defined.
1107template <typename T> struct alignas(T) SmallVectorStorage<T, 0> {};
1108
1109/// Forward declaration of SmallVector so that
1110/// calculateSmallVectorDefaultInlinedElements can reference
1111/// `sizeof(SmallVector<T, 0>)`.
1112template <typename T, unsigned N> class LLVM_GSL_OWNER SmallVector;
1113
1114/// Helper class for calculating the default number of inline elements for
1115/// `SmallVector<T>`.
1116///
1117/// This should be migrated to a constexpr function when our minimum
1118/// compiler support is enough for multi-statement constexpr functions.
1120 // Parameter controlling the default number of inlined elements
1121 // for `SmallVector<T>`.
1122 //
1123 // The default number of inlined elements ensures that
1124 // 1. There is at least one inlined element.
1125 // 2. `sizeof(SmallVector<T>) <= kPreferredSmallVectorSizeof` unless
1126 // it contradicts 1.
1127 static constexpr size_t kPreferredSmallVectorSizeof = 64;
1128
1129 // static_assert that sizeof(T) is not "too big".
1130 //
1131 // Because our policy guarantees at least one inlined element, it is possible
1132 // for an arbitrarily large inlined element to allocate an arbitrarily large
1133 // amount of inline storage. We generally consider it an antipattern for a
1134 // SmallVector to allocate an excessive amount of inline storage, so we want
1135 // to call attention to these cases and make sure that users are making an
1136 // intentional decision if they request a lot of inline storage.
1137 //
1138 // We want this assertion to trigger in pathological cases, but otherwise
1139 // not be too easy to hit. To accomplish that, the cutoff is actually somewhat
1140 // larger than kPreferredSmallVectorSizeof (otherwise,
1141 // `SmallVector<SmallVector<T>>` would be one easy way to trip it, and that
1142 // pattern seems useful in practice).
1143 //
1144 // One wrinkle is that this assertion is in theory non-portable, since
1145 // sizeof(T) is in general platform-dependent. However, we don't expect this
1146 // to be much of an issue, because most LLVM development happens on 64-bit
1147 // hosts, and therefore sizeof(T) is expected to *decrease* when compiled for
1148 // 32-bit hosts, dodging the issue. The reverse situation, where development
1149 // happens on a 32-bit host and then fails due to sizeof(T) *increasing* on a
1150 // 64-bit host, is expected to be very rare.
1151 static_assert(
1152 sizeof(T) <= 256,
1153 "You are trying to use a default number of inlined elements for "
1154 "`SmallVector<T>` but `sizeof(T)` is really big! Please use an "
1155 "explicit number of inlined elements with `SmallVector<T, N>` to make "
1156 "sure you really want that much inline storage.");
1157
1158 // Discount the size of the header itself when calculating the maximum inline
1159 // bytes.
1160 static constexpr size_t PreferredInlineBytes =
1161 kPreferredSmallVectorSizeof - sizeof(SmallVector<T, 0>);
1162 static constexpr size_t NumElementsThatFit = PreferredInlineBytes / sizeof(T);
1163 static constexpr size_t value =
1164 NumElementsThatFit == 0 ? 1 : NumElementsThatFit;
1165};
1166
1167/// This is a 'vector' (really, a variable-sized array), optimized
1168/// for the case when the array is small. It contains some number of elements
1169/// in-place, which allows it to avoid heap allocation when the actual number of
1170/// elements is below that threshold. This allows normal "small" cases to be
1171/// fast without losing generality for large inputs.
1172///
1173/// \note
1174/// In the absence of a well-motivated choice for the number of inlined
1175/// elements \p N, it is recommended to use \c SmallVector<T> (that is,
1176/// omitting the \p N). This will choose a default number of inlined elements
1177/// reasonable for allocation on the stack (for example, trying to keep \c
1178/// sizeof(SmallVector<T>) around 64 bytes).
1179///
1180/// \warning This does not attempt to be exception safe.
1181///
1182/// \see https://llvm.org/docs/ProgrammersManual.html#llvm-adt-smallvector-h
1183template <typename T,
1186 SmallVectorStorage<T, N> {
1187public:
1189
1191 // Destroy the constructed elements in the vector.
1192 this->destroy_range(this->begin(), this->end());
1193 }
1194
1195 explicit SmallVector(size_t Size, const T &Value = T())
1196 : SmallVectorImpl<T>(N) {
1197 this->assign(Size, Value);
1198 }
1199
1200 template <typename ItTy,
1201 typename = std::enable_if_t<std::is_convertible<
1202 typename std::iterator_traits<ItTy>::iterator_category,
1203 std::input_iterator_tag>::value>>
1204 SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) {
1205 this->append(S, E);
1206 }
1207
1208 template <typename RangeTy>
1210 : SmallVectorImpl<T>(N) {
1211 this->append(R.begin(), R.end());
1212 }
1213
1214 SmallVector(std::initializer_list<T> IL) : SmallVectorImpl<T>(N) {
1215 this->assign(IL);
1216 }
1217
1219 if (!RHS.empty())
1221 }
1222
1225 return *this;
1226 }
1227
1229 if (!RHS.empty())
1230 SmallVectorImpl<T>::operator=(::std::move(RHS));
1231 }
1232
1234 if (!RHS.empty())
1235 SmallVectorImpl<T>::operator=(::std::move(RHS));
1236 }
1237
1239 if (N) {
1240 SmallVectorImpl<T>::operator=(::std::move(RHS));
1241 return *this;
1242 }
1243 // SmallVectorImpl<T>::operator= does not leverage N==0. Optimize the
1244 // case.
1245 if (this == &RHS)
1246 return *this;
1247 if (RHS.empty()) {
1248 this->destroy_range(this->begin(), this->end());
1249 this->Size = 0;
1250 } else {
1251 this->assignRemote(std::move(RHS));
1252 }
1253 return *this;
1254 }
1255
1257 SmallVectorImpl<T>::operator=(::std::move(RHS));
1258 return *this;
1259 }
1260
1261 SmallVector &operator=(std::initializer_list<T> IL) {
1262 this->assign(IL);
1263 return *this;
1264 }
1265};
1266
1267template <typename T, unsigned N>
1268inline size_t capacity_in_bytes(const SmallVector<T, N> &X) {
1269 return X.capacity_in_bytes();
1270}
1271
1272template <typename RangeType>
1274 typename std::remove_const<typename std::remove_reference<
1275 decltype(*std::begin(std::declval<RangeType &>()))>::type>::type;
1276
1277/// Given a range of type R, iterate the entire range and return a
1278/// SmallVector with elements of the vector. This is useful, for example,
1279/// when you want to iterate a range and then sort the results.
1280template <unsigned Size, typename R>
1282 return {std::begin(Range), std::end(Range)};
1283}
1284template <typename R>
1285SmallVector<ValueTypeFromRangeType<R>,
1286 CalculateSmallVectorDefaultInlinedElements<
1287 ValueTypeFromRangeType<R>>::value>
1288to_vector(R &&Range) {
1289 return {std::begin(Range), std::end(Range)};
1290}
1291
1292} // end namespace wpi
1293
1294namespace std {
1295
1296 /// Implement std::swap in terms of SmallVector swap.
1297 template<typename T>
1298 inline void
1300 LHS.swap(RHS);
1301 }
1302
1303 /// Implement std::swap in terms of SmallVector swap.
1304 template<typename T, unsigned N>
1305 inline void
1307 LHS.swap(RHS);
1308 }
1309
1310} // end namespace std
1311
1312#endif // WPIUTIL_WPI_SMALLVECTOR_H
#define LLVM_UNLIKELY(EXPR)
Definition: Compiler.h:250
#define LLVM_GSL_OWNER
LLVM_GSL_OWNER - Apply this to owning classes like SmallVector to enable lifetime warnings.
Definition: Compiler.h:338
#define LLVM_NODISCARD
LLVM_NODISCARD - Warn if a type or return value is discarded.
Definition: Compiler.h:177
#define LLVM_LIKELY(EXPR)
Definition: Compiler.h:249
and restrictions which apply to each piece of software is included later in this file and or inside of the individual applicable source files The disclaimer of warranty in the WPILib license above applies to all code in and nothing in any of the other licenses gives permission to use the names of FIRST nor the names of the WPILib contributors to endorse or promote products derived from this software The following pieces of software have additional or alternate and or Google Inc All rights reserved Redistribution and use in source and binary with or without are permitted provided that the following conditions are this list of conditions and the following disclaimer *Redistributions in binary form must reproduce the above copyright this list of conditions and the following disclaimer in the documentation and or other materials provided with the distribution *Neither the name of Google Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY OR CONSEQUENTIAL WHETHER IN STRICT OR EVEN IF ADVISED OF THE POSSIBILITY OF SUCH January AND DISTRIBUTION Definitions License shall mean the terms and conditions for and distribution as defined by Sections through of this document Licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the License Legal Entity shall mean the union of the acting entity and all other entities that control are controlled by or are under common control with that entity For the purposes of this definition control direct or to cause the direction or management of such whether by contract or including but not limited to software source documentation and configuration files Object form shall mean any form resulting from mechanical transformation or translation of a Source including but not limited to compiled object generated and conversions to other media types Work shall mean the work of whether in Source or Object made available under the as indicated by a copyright notice that is included in or attached to the whether in Source or Object that is based or other modifications as a an original work of authorship For the purposes of this Derivative Works shall not include works that remain separable or merely the Work and Derivative Works thereof Contribution shall mean any work of including the original version of the Work and any modifications or additions to that Work or Derivative Works that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner For the purposes of this submitted means any form of or written communication sent to the Licensor or its including but not limited to communication on electronic mailing source code control and issue tracking systems that are managed by
Definition: ThirdPartyNotices.txt:143
you may not use this file except in compliance with the License You may obtain a copy of the License at software distributed under the License is distributed on an AS IS WITHOUT WARRANTIES OR CONDITIONS OF ANY either express or implied See the License for the specific language governing permissions and limitations under the License LLVM Exceptions to the Apache License As an if
Definition: ThirdPartyNotices.txt:292
and restrictions which apply to each piece of software is included later in this file and or inside of the individual applicable source files The disclaimer of warranty in the WPILib license above applies to all code in and nothing in any of the other licenses gives permission to use the names of FIRST nor the names of the WPILib contributors to endorse or promote products derived from this software The following pieces of software have additional or alternate and or Google Inc All rights reserved Redistribution and use in source and binary with or without are permitted provided that the following conditions are this list of conditions and the following disclaimer *Redistributions in binary form must reproduce the above copyright this list of conditions and the following disclaimer in the documentation and or other materials provided with the distribution *Neither the name of Google Inc nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY OR CONSEQUENTIAL WHETHER IN STRICT OR EVEN IF ADVISED OF THE POSSIBILITY OF SUCH January AND DISTRIBUTION Definitions License shall mean the terms and conditions for and distribution as defined by Sections through of this document Licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the License Legal Entity shall mean the union of the acting entity and all other entities that control are controlled by or are under common control with that entity For the purposes of this definition control direct or to cause the direction or management of such whether by contract or including but not limited to software source documentation and configuration files Object form shall mean any form resulting from mechanical transformation or translation of a Source including but not limited to compiled object generated and conversions to other media types Work shall mean the work of whether in Source or Object made available under the as indicated by a copyright notice that is included in or attached to the whether in Source or Object that is based or other modifications as a an original work of authorship For the purposes of this Derivative Works shall not include works that remain separable or merely the Work and Derivative Works thereof Contribution shall mean any work of including the original version of the Work and any modifications or additions to that Work or Derivative Works that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner For the purposes of this submitted means any form of or written communication sent to the Licensor or its including but not limited to communication on electronic mailing source code control and issue tracking systems that are managed or on behalf the Licensor for the purpose of discussing and improving the but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as Not a Contribution Contributor shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work Grant of Copyright License Subject to the terms and conditions of this each Contributor hereby grants to You a non no royalty free
Definition: ThirdPartyNotices.txt:154
Definition: core.h:1240
This is all the stuff common to all SmallVectors.
Definition: SmallVector.h:53
void * BeginX
Definition: SmallVector.h:55
size_t size() const
Definition: SmallVector.h:78
unsigned Capacity
Definition: SmallVector.h:56
unsigned Size
Definition: SmallVector.h:56
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:81
size_t capacity() const
Definition: SmallVector.h:79
static constexpr size_t SizeTypeMax()
The maximum value of the Size_T used.
Definition: SmallVector.h:59
void * mallocForGrow(size_t MinSize, size_t TSize, size_t &NewCapacity)
This is a helper for grow() that's out of line to reduce code duplication.
void grow_pod(void *FirstEl, size_t MinSize, size_t TSize)
This is an implementation of the grow() method which only works on POD-like data types and is out of ...
SmallVectorBase(void *FirstEl, size_t TotalCapacity)
Definition: SmallVector.h:64
void set_size(size_t N)
Set the array size to N, which the current array must have enough capacity for.
Definition: SmallVector.h:88
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1186
SmallVector(ItTy S, ItTy E)
Definition: SmallVector.h:1204
SmallVector(const iterator_range< RangeTy > &R)
Definition: SmallVector.h:1209
~SmallVector()
Definition: SmallVector.h:1190
SmallVector(std::initializer_list< T > IL)
Definition: SmallVector.h:1214
SmallVector(SmallVectorImpl< T > &&RHS)
Definition: SmallVector.h:1233
SmallVector & operator=(SmallVectorImpl< T > &&RHS)
Definition: SmallVector.h:1256
SmallVector()
Definition: SmallVector.h:1188
SmallVector(const SmallVector &RHS)
Definition: SmallVector.h:1218
SmallVector(size_t Size, const T &Value=T())
Definition: SmallVector.h:1195
SmallVector & operator=(SmallVector &&RHS)
Definition: SmallVector.h:1238
SmallVector & operator=(const SmallVector &RHS)
Definition: SmallVector.h:1223
SmallVector(SmallVector &&RHS)
Definition: SmallVector.h:1228
SmallVector & operator=(std::initializer_list< T > IL)
Definition: SmallVector.h:1261
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:557
bool operator!=(const SmallVectorImpl &RHS) const
Definition: SmallVector.h:947
SmallVectorImpl & operator=(SmallVectorImpl &&RHS)
Definition: SmallVector.h:1042
void assign(in_iter in_start, in_iter in_end)
Definition: SmallVector.h:714
iterator erase(const_iterator CI)
Definition: SmallVector.h:727
~SmallVectorImpl()
Definition: SmallVector.h:587
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:930
void resize_for_overwrite(size_type N)
Like resize, but T is POD, the new values won't be initialized.
Definition: SmallVector.h:625
void assign(std::initializer_list< T > IL)
Definition: SmallVector.h:720
void append(std::initializer_list< T > IL)
Definition: SmallVector.h:685
iterator insert(iterator I, ItTy From, ItTy To)
Definition: SmallVector.h:868
bool operator==(const SmallVectorImpl &RHS) const
Definition: SmallVector.h:943
SmallVectorImpl(unsigned N)
Definition: SmallVector.h:571
SmallVectorImpl & operator=(const SmallVectorImpl &RHS)
Definition: SmallVector.h:995
void clear()
Definition: SmallVector.h:594
void assignRemote(SmallVectorImpl &&RHS)
Definition: SmallVector.h:574
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:670
typename SuperClass::size_type size_type
Definition: SmallVector.h:564
void swap(SmallVectorImpl &RHS)
Definition: SmallVector.h:958
iterator insert(iterator I, T &&Elt)
Definition: SmallVector.h:795
void reserve(size_type N)
Definition: SmallVector.h:647
void assign(const SmallVectorImpl &RHS)
Definition: SmallVector.h:725
void truncate(size_type N)
Like resize, but requires that N is less than size().
Definition: SmallVector.h:628
typename SuperClass::iterator iterator
Definition: SmallVector.h:561
bool operator<(const SmallVectorImpl &RHS) const
Definition: SmallVector.h:951
void assign(size_type NumElts, ValueParamT Elt)
Definition: SmallVector.h:691
iterator insert(iterator I, size_type NumToInsert, ValueParamT Elt)
Definition: SmallVector.h:803
void append(const SmallVectorImpl &RHS)
Definition: SmallVector.h:689
SmallVectorImpl(const SmallVectorImpl &)=delete
void resize(size_type N, ValueParamT NV)
Definition: SmallVector.h:634
void pop_back_n(size_type NumItems)
Definition: SmallVector.h:652
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:657
void insert(iterator I, std::initializer_list< T > IL)
Definition: SmallVector.h:926
void append(size_type NumInputs, ValueParamT Elt)
Append NumInputs copies of Elt to the end.
Definition: SmallVector.h:679
void resize(size_type N)
Definition: SmallVector.h:622
iterator insert(iterator I, const T &Elt)
Definition: SmallVector.h:799
iterator erase(const_iterator CS, const_iterator CE)
Definition: SmallVector.h:741
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)
Copy the range [I, E) onto the uninitialized memory starting with "Dest", constructing elements into ...
Definition: SmallVector.h:495
void growAndAssign(size_t NumElts, T Elt)
Definition: SmallVector.h:527
const T * reserveForParamAndGetAddress(const T &Elt, size_t N=1)
Reserve enough space to add one element, and return the updated element pointer in case it was a refe...
Definition: SmallVector.h:513
static ValueParamT forward_value_param(ValueParamT V)
Copy V or return a reference, depending on ValueParamT.
Definition: SmallVector.h:525
static void destroy_range(T *, T *)
Definition: SmallVector.h:474
SmallVectorTemplateBase(size_t Size)
Definition: SmallVector.h:471
T & growAndEmplaceBack(ArgTypes &&... Args)
Definition: SmallVector.h:536
void grow(size_t MinSize=0)
Double the size of the allocated memory, guaranteeing space for at least one more element or MinSize ...
Definition: SmallVector.h:509
typename std::conditional< TakesParamByValue, T, const T & >::type ValueParamT
Either const T& or T, depending on whether it's cheap enough to take parameters by value.
Definition: SmallVector.h:469
void push_back(ValueParamT Elt)
Definition: SmallVector.h:545
static void uninitialized_copy(It1 I, It1 E, It2 Dest)
Copy the range [I, E) onto the uninitialized memory starting with "Dest", constructing elements into ...
Definition: SmallVector.h:487
T * reserveForParamAndGetAddress(T &Elt, size_t N=1)
Reserve enough space to add one element, and return the updated element pointer in case it was a refe...
Definition: SmallVector.h:519
static void uninitialized_move(It1 I, It1 E, It2 Dest)
Move the range [I, E) onto the uninitialized memory starting with "Dest", constructing elements into ...
Definition: SmallVector.h:479
void pop_back()
Definition: SmallVector.h:551
SmallVectorTemplateBase<TriviallyCopyable = false> - This is where we put method implementations that...
Definition: SmallVector.h:314
static void uninitialized_move(It1 I, It1 E, It2 Dest)
Move the range [I, E) into the uninitialized memory starting with "Dest", constructing elements as ne...
Definition: SmallVector.h:333
void moveElementsForGrow(T *NewElts)
Move existing elements over to the new allocation NewElts, the middle section of grow().
Definition: SmallVector.h:432
SmallVectorTemplateBase(size_t Size)
Definition: SmallVector.h:321
static void uninitialized_copy(It1 I, It1 E, It2 Dest)
Copy the range [I, E) onto the uninitialized memory starting with "Dest", constructing elements as ne...
Definition: SmallVector.h:341
T * reserveForParamAndGetAddress(T &Elt, size_t N=1)
Reserve enough space to add one element, and return the updated element pointer in case it was a refe...
Definition: SmallVector.h:373
const T & ValueParamT
Definition: SmallVector.h:319
void pop_back()
Definition: SmallVector.h:415
static const T & forward_value_param(const T &V)
Definition: SmallVector.h:379
static void destroy_range(T *S, T *E)
Definition: SmallVector.h:323
void takeAllocationForGrow(T *NewElts, size_t NewCapacity)
Transfer ownership of the allocation, finishing up grow().
Definition: SmallVector.h:443
static T && forward_value_param(T &&V)
Definition: SmallVector.h:378
static constexpr bool TakesParamByValue
Definition: SmallVector.h:318
void push_back(T &&Elt)
Definition: SmallVector.h:409
T * mallocForGrow(size_t MinSize, size_t &NewCapacity)
Create a new allocation big enough for MinSize and pass back its size in NewCapacity.
Definition: SmallVector.h:352
void grow(size_t MinSize=0)
Grow the allocated memory (without initializing new elements), doubling the size of the allocated mem...
Definition: SmallVector.h:423
const T * reserveForParamAndGetAddress(const T &Elt, size_t N=1)
Reserve enough space to add one element, and return the updated element pointer in case it was a refe...
Definition: SmallVector.h:367
T & growAndEmplaceBack(ArgTypes &&... Args)
Definition: SmallVector.h:391
void push_back(const T &Elt)
Definition: SmallVector.h:403
void growAndAssign(size_t NumElts, const T &Elt)
Definition: SmallVector.h:381
This is the part of SmallVectorTemplateBase which does not depend on whether the type T is a POD.
Definition: SmallVector.h:106
ptrdiff_t difference_type
Definition: SmallVector.h:234
const T * const_pointer
Definition: SmallVector.h:245
void assertSafeToReferenceAfterClear(const T *From, const T *To)
Check whether any part of the range will be invalidated by clearing.
Definition: SmallVector.h:186
reverse_iterator rbegin()
Definition: SmallVector.h:258
const_iterator begin() const
Definition: SmallVector.h:253
reference front()
Definition: SmallVector.h:284
size_t size() const
Definition: SmallVector.h:78
size_type size_in_bytes() const
Definition: SmallVector.h:263
void resetToSmall()
Put this vector in a state of being small.
Definition: SmallVector.h:131
const_reverse_iterator rbegin() const
Definition: SmallVector.h:259
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: SmallVector.h:239
const_reference operator[](size_type idx) const
Definition: SmallVector.h:279
bool isReferenceToStorage(const void *V) const
Return true if V is an internal reference to this vector.
Definition: SmallVector.h:144
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:81
const_pointer data() const
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:273
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:271
size_t capacity() const
Definition: SmallVector.h:79
iterator begin()
Definition: SmallVector.h:252
T * iterator
Definition: SmallVector.h:236
const_reference back() const
Definition: SmallVector.h:297
const T & const_reference
Definition: SmallVector.h:243
size_t size_type
Definition: SmallVector.h:233
reference operator[](size_type idx)
Definition: SmallVector.h:275
size_t capacity_in_bytes() const
Definition: SmallVector.h:268
const_reverse_iterator rend() const
Definition: SmallVector.h:261
std::reverse_iterator< iterator > reverse_iterator
Definition: SmallVector.h:240
const_iterator end() const
Definition: SmallVector.h:255
bool isSmall() const
Return true if this is a smallvector which has not had dynamic memory allocated for it.
Definition: SmallVector.h:128
T value_type
Definition: SmallVector.h:235
iterator end()
Definition: SmallVector.h:254
static const T * reserveForParamAndGetAddressImpl(U *This, const T &Elt, size_t N)
Reserve enough space to add one element, and return the updated element pointer in case it was a refe...
Definition: SmallVector.h:214
void assertSafeToAddRange(ItTy, ItTy)
Definition: SmallVector.h:209
SmallVectorTemplateCommon(size_t Size)
Definition: SmallVector.h:120
void assertSafeToAddRange(const T *From, const T *To)
Check whether any part of the range will be invalidated by growing.
Definition: SmallVector.h:199
const_reference front() const
Definition: SmallVector.h:288
T & reference
Definition: SmallVector.h:242
const T * const_iterator
Definition: SmallVector.h:237
T * pointer
Definition: SmallVector.h:244
void assertSafeToAdd(const void *Elt, size_t N=1)
Check whether Elt will be invalidated by increasing the size of the vector by N.
Definition: SmallVector.h:181
bool isSafeToReferenceAfterResize(const void *Elt, size_t NewSize)
Return true unless Elt will be invalidated by resizing the vector to NewSize.
Definition: SmallVector.h:159
void assertSafeToReferenceAfterResize(const void *Elt, size_t NewSize)
Check whether Elt will be invalidated by resizing the vector to NewSize.
Definition: SmallVector.h:173
bool isRangeInStorage(const void *First, const void *Last) const
Return true if First and Last form a valid (possibly empty) range in this vector's storage.
Definition: SmallVector.h:150
reference back()
Definition: SmallVector.h:293
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:137
void assertSafeToReferenceAfterClear(ItTy, ItTy)
Definition: SmallVector.h:196
size_type max_size() const
Definition: SmallVector.h:264
void grow_pod(size_t MinSize, size_t TSize)
Definition: SmallVector.h:122
reverse_iterator rend()
Definition: SmallVector.h:260
A range adaptor for a pair of iterators.
Definition: iterator_range.h:30
IteratorT begin() const
Definition: iterator_range.h:44
typename std::enable_if< B, T >::type enable_if_t
Definition: core.h:298
type
Definition: core.h:575
constexpr common_t< T1, T2 > max(const T1 x, const T2 y) noexcept
Compile-time pairwise maximum function.
Definition: max.hpp:35
constexpr common_t< T1, T2 > min(const T1 x, const T2 y) noexcept
Compile-time pairwise minimum function.
Definition: min.hpp:35
::int64_t int64_t
Definition: Meta.h:59
static EIGEN_DEPRECATED const end_t end
Definition: IndexedViewHelper.h:181
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74
OutputIterator copy(const RangeT &range, OutputIterator out)
Definition: ranges.h:26
FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T &value) -> OutputIt
Definition: format.h:560
GHC_FS_API directory_iterator begin(directory_iterator iter) noexcept
Definition: filesystem.hpp:5746
Definition: StdDeque.h:50
void swap(wpi::SmallVectorImpl< T > &LHS, wpi::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
Definition: SmallVector.h:1299
static constexpr const unit_t< compound_unit< energy::joules, inverse< temperature::kelvin >, inverse< substance::moles > > > R(8.3144598)
Gas constant.
/file This file defines the SmallVector class.
Definition: AprilTagFieldLayout.h:18
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
Definition: SmallVector.h:1281
typename std::remove_const< typename std::remove_reference< decltype(*std::begin(std::declval< RangeType & >()))>::type >::type ValueTypeFromRangeType
Definition: SmallVector.h:1275
Helper class for calculating the default number of inline elements for SmallVector<T>.
Definition: SmallVector.h:1119
Figure out the offset of the first element.
Definition: SmallVector.h:95
char Base[sizeof(SmallVectorBase)]
Definition: SmallVector.h:97
char FirstEl[sizeof(T)]
Definition: SmallVector.h:98
Storage for the SmallVector elements.
Definition: SmallVector.h:1100
#define S(label, offset, message)
Definition: Errors.h:118