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